1 | /* |
---|
2 | * Copyright (C) 2014 CLARIN |
---|
3 | * |
---|
4 | * This program is free software: you can redistribute it and/or modify |
---|
5 | * it under the terms of the GNU General Public License as published by |
---|
6 | * the Free Software Foundation, either version 3 of the License, or |
---|
7 | * (at your option) any later version. |
---|
8 | * |
---|
9 | * This program is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | * GNU General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU General Public License |
---|
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
16 | */ |
---|
17 | package eu.clarin.cmdi.vlo.service.handle.impl; |
---|
18 | |
---|
19 | import com.sun.jersey.api.client.Client; |
---|
20 | import com.sun.jersey.api.client.ClientHandlerException; |
---|
21 | import com.sun.jersey.api.client.ClientResponse; |
---|
22 | import com.sun.jersey.api.client.UniformInterfaceException; |
---|
23 | import com.sun.jersey.api.client.WebResource; |
---|
24 | import eu.clarin.cmdi.vlo.service.handle.HandleClient; |
---|
25 | import javax.ws.rs.core.MediaType; |
---|
26 | import javax.ws.rs.core.Response; |
---|
27 | import org.apache.wicket.ajax.json.JSONArray; |
---|
28 | import org.apache.wicket.ajax.json.JSONException; |
---|
29 | import org.apache.wicket.ajax.json.JSONObject; |
---|
30 | import org.slf4j.Logger; |
---|
31 | import org.slf4j.LoggerFactory; |
---|
32 | |
---|
33 | /** |
---|
34 | * Service that connects to the handle.net REST API and retrieves the URL for a |
---|
35 | * given handle. |
---|
36 | * |
---|
37 | * Consider re-implementing using the handle API |
---|
38 | * |
---|
39 | * @author twagoo |
---|
40 | */ |
---|
41 | public class HandleRestApiClient implements HandleClient { |
---|
42 | |
---|
43 | private final static Logger logger = LoggerFactory.getLogger(HandleRestApiClient.class); |
---|
44 | |
---|
45 | private final String handleApiBaseUrl; |
---|
46 | |
---|
47 | /** |
---|
48 | * constructs a client with the default handle REST API base URL |
---|
49 | */ |
---|
50 | public HandleRestApiClient() { |
---|
51 | //TODO: get from config |
---|
52 | this("http://hdl.handle.net/api/handles/"); |
---|
53 | } |
---|
54 | |
---|
55 | /** |
---|
56 | * |
---|
57 | * @param handleApiBaseUrl base URL of the handle REST API (handle will be |
---|
58 | * directly appended to this) |
---|
59 | */ |
---|
60 | public HandleRestApiClient(String handleApiBaseUrl) { |
---|
61 | this.handleApiBaseUrl = handleApiBaseUrl; |
---|
62 | } |
---|
63 | |
---|
64 | /** |
---|
65 | * |
---|
66 | * @param handle handle to resolve |
---|
67 | * @return the ULR provided by the handle server or null if it could not be |
---|
68 | * retrieved or is not available |
---|
69 | */ |
---|
70 | @Override |
---|
71 | public String getUrl(String handle) { |
---|
72 | final String requestUrl = handleApiBaseUrl + handle; |
---|
73 | logger.debug("Making request to {}", requestUrl); |
---|
74 | |
---|
75 | final Client client = Client.create(); |
---|
76 | final WebResource resource = client.resource(requestUrl); |
---|
77 | |
---|
78 | try { |
---|
79 | final ClientResponse response = resource |
---|
80 | .accept(MediaType.APPLICATION_JSON_TYPE) |
---|
81 | .get(ClientResponse.class); |
---|
82 | |
---|
83 | if (Response.Status.OK.getStatusCode() != response.getStatus()) { |
---|
84 | final Response.StatusType statusInfo = response.getStatusInfo(); |
---|
85 | logger.error("Unexpected response status {} - {} for {}", statusInfo.getStatusCode(), statusInfo.getReasonPhrase(), requestUrl); |
---|
86 | } else { |
---|
87 | final String responseString = response.getEntity(String.class); |
---|
88 | return getUrlFromJson(responseString); |
---|
89 | } |
---|
90 | } catch (UniformInterfaceException ex) { |
---|
91 | logger.error("Could not communicate with Handle API", ex); |
---|
92 | } catch (ClientHandlerException ex) { |
---|
93 | logger.error("Could not communicate with Handle API", ex); |
---|
94 | } catch (JSONException ex) { |
---|
95 | logger.error("Could not parse Handle API response", ex); |
---|
96 | } |
---|
97 | return null; |
---|
98 | } |
---|
99 | |
---|
100 | public String getUrlFromJson(final String jsonString) throws JSONException { |
---|
101 | // The handle API returns a JSON structure with a number of handle |
---|
102 | // record fields. We are only interested in the value at |
---|
103 | // values[x].data.value where values[x].type == 'URL' |
---|
104 | |
---|
105 | final JSONObject jsonResponse = new JSONObject(jsonString); |
---|
106 | final JSONArray valuesArray = jsonResponse.getJSONArray("values"); |
---|
107 | for (int i = 0; i < valuesArray.length(); i++) { |
---|
108 | final JSONObject object = valuesArray.getJSONObject(i); |
---|
109 | final String type = object.getString("type"); |
---|
110 | if ("URL".equals(type) && object.has("data")) { |
---|
111 | final JSONObject data = object.getJSONObject("data"); |
---|
112 | if (data.has("value")) { |
---|
113 | // the field we were looking for |
---|
114 | return data.getString("value"); |
---|
115 | } |
---|
116 | } |
---|
117 | } |
---|
118 | // no URL field?? |
---|
119 | logger.error("Handle API response did not incude a URL field"); |
---|
120 | return null; |
---|
121 | } |
---|
122 | |
---|
123 | /** |
---|
124 | * { |
---|
125 | * "responseCode":1, "handle":"1839/00-0000-0000-0000-0000-4", "values": [{ |
---|
126 | * "index":6, "type":"FILETIME", "data":"2014-03-25 08:35:11.0", |
---|
127 | * "ttl":86400, "timestamp":"1970-01-01T00:00:00Z" }, { "index":5, |
---|
128 | * "type":"CHECKSUM", "data":"696d818e19744f9f0290125e6385fa77", |
---|
129 | * "ttl":86400, "timestamp":"1970-01-01T00:00:00Z" }, { "index":4, |
---|
130 | * "type":"ONSITE", "data":"true", "ttl":86400, |
---|
131 | * "timestamp":"1970-01-01T00:00:00Z" }, { "index":3, "type":"FILESIZE", |
---|
132 | * "data":"6550", "ttl":86400, "timestamp":"1970-01-01T00:00:00Z"}, |
---|
133 | * {"index":2,"type":"CRAWLTIME","data":"2014-03-25 |
---|
134 | * 08:35:11.39","ttl":86400,"timestamp":"1970-01-01T00:00:00Z"}, |
---|
135 | * {"index":1,"type":"URL","data":"http://corpus1.mpi.nl/IMDI/metadata/IMDI.imdi","ttl":86400,"timestamp":"1970-01-01T00:00:00Z"}, |
---|
136 | * {"index":100,"type":"HS_ADMIN","data":{"format":"admin","value":{"handle":"0.NA/1839","index":200,"permissions":"010001110000"}},"ttl":86400,"timestamp":"1970-01-01T00:00:00Z"} |
---|
137 | * ] } |
---|
138 | */ |
---|
139 | } |
---|