93f8a6a59875cb808e780745924689078f528f11
[cdmlib.git] / cdmlib-ext / src / main / java / eu / etaxonomy / cdm / ext / bci / BciServiceWrapper.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.ext.bci;
11
12 import java.io.BufferedReader;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.net.HttpURLConnection;
17 import java.net.MalformedURLException;
18 import java.net.URI;
19 import java.net.URISyntaxException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.http.HttpException;
28 import org.apache.http.NameValuePair;
29 import org.apache.http.message.BasicNameValuePair;
30 import org.apache.log4j.Logger;
31 import org.springframework.stereotype.Component;
32
33 import com.ibm.lsid.MalformedLSIDException;
34
35 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
36 import eu.etaxonomy.cdm.common.CdmUtils;
37 import eu.etaxonomy.cdm.common.UriUtils;
38 import eu.etaxonomy.cdm.ext.common.SchemaAdapterBase;
39 import eu.etaxonomy.cdm.ext.common.ServiceWrapperBase;
40 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
41 import eu.etaxonomy.cdm.model.common.LSID;
42 import eu.etaxonomy.cdm.model.occurrence.Collection;
43 import eu.etaxonomy.cdm.model.reference.Reference;
44 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
45
46
47 /**
48 * This service allows to query the Biodiversity collection index {@link http://www.biodiversitycollectionsindex.org}
49 * @author a.mueller
50 * @created Aug 16, 2010
51 * @version 1.0
52 *
53 */
54 @Component
55 public class BciServiceWrapper extends ServiceWrapperBase<Collection> implements IBciServiceWrapper{
56 private static final Logger logger = Logger.getLogger(BciServiceWrapper.class);
57
58 private enum ServiceType{
59 AUTHOR,
60 NAME,
61 PUBLICATION,
62 }
63
64
65 // private URL serviceUrl;
66
67 // ******************************** CONSTRUCTOR **************************************
68
69
70 // /**
71 // * Creates new instance of this factory and connects it to the given
72 // * CDM Community Stores access point.
73 // *
74 // * Typically, there is no need to instantiate this class.
75 // */
76 // protected IpniService(URL webserviceUrl){
77 // this.serviceUrl = webserviceUrl;
78 // }
79
80 // ****************************** METHODS ****************************************************/
81
82 /**
83 *
84 * @param restRequest
85 * @return
86 */
87 public List<Collection> getCollectionsByCode(String code, ICdmApplicationConfiguration appConfig){
88
89 SchemaAdapterBase<Collection> schemaAdapter = schemaAdapterMap.get("recordSchema");
90 if(schemaAdapter == null){
91 logger.error("No SchemaAdapter found for " + "recordSchema");
92 }
93
94 String SruOperation = "searchRetrieve";
95
96 List<NameValuePair> pairs = new ArrayList<NameValuePair>();
97 pairs.add(new BasicNameValuePair("code", SruOperation));
98
99 Map<String, String> requestHeaders = new HashMap<String, String>();
100 requestHeaders.put("Accept-Charset", "UTF-8");
101
102 try {
103 URI requestUri = createUri(null, pairs);
104
105
106 InputStream stream = executeHttpGet(requestUri, requestHeaders);
107 return schemaAdapter.getCmdEntities(stream);
108
109 } catch (IOException e) {
110 // thrown by doHttpGet
111 logger.error(e);
112 } catch (URISyntaxException e) {
113 // thrown by createUri
114 logger.error(e);
115 } catch (HttpException e){
116 // thrown by createUri
117 logger.error(e);
118 }
119
120 // return null;
121
122
123
124 code = normalizeParameter(code);
125 String request = code;
126
127 return (List)queryService(request, appConfig, getServiceUrl(IBciServiceWrapper.LOOKUP_CODE_REST), ServiceType.AUTHOR);
128 }
129
130
131 /**
132 *
133 * @param restRequest
134 * @return
135 */
136 private List<? extends IdentifiableEntity> queryService(String request, ICdmApplicationConfiguration appConfig, URL serviceUrl, ServiceType serviceType){
137 try {
138 // create the request url
139 URL newUrl = new URL(serviceUrl.getProtocol(),
140 serviceUrl.getHost(),
141 serviceUrl.getPort(),
142 serviceUrl.getPath()
143 + "" + request);
144 // open a connection
145 HttpURLConnection connection = (HttpURLConnection) newUrl.openConnection();
146 // set the accept property to XML so we can use jdom to handle the content
147 //connection.setRequestProperty("Accept", "text/xml");
148
149
150 logger.info("Firing request for URL: " + newUrl);
151
152 int responseCode = connection.getResponseCode();
153
154 // get the content at the resource
155 InputStream content = (InputStream) connection.getContent();
156
157 // build the result
158 List<? extends IdentifiableEntity> result;
159 if (serviceType.equals(ServiceType.AUTHOR)){
160 result = buildCollectionList(content, appConfig);
161 }else if (serviceType.equals(ServiceType.NAME)){
162 //
163 result = null;
164 }else{
165 //
166 result = null;
167 }
168 if(responseCode == HttpURLConnection.HTTP_OK){
169 return result;
170 }else if(responseCode == HttpURLConnection.HTTP_MULT_CHOICE){
171 return result;
172 }else{
173 //TODO error handling
174 logger.error("No Http_OK");
175 }
176
177 } catch (IOException e) {
178 logger.error("No content for request: " + request);
179 }
180
181 // error
182 return null;
183 }
184
185
186 private List<Collection> buildCollectionList(InputStream content, ICdmApplicationConfiguration appConfig) throws IOException {
187 List<Collection> result = new ArrayList<Collection>();
188 BufferedReader reader = new BufferedReader (new InputStreamReader(content));
189
190 String headerLine = reader.readLine();
191
192 String line = reader.readLine();
193 while (StringUtils.isNotBlank(line)){
194 Collection collection = getCollectionFromLine(line, appConfig);
195 result.add(collection);
196 line = reader.readLine();
197 }
198
199 return result;
200 }
201
202
203 private Collection getCollectionFromLine(String line, ICdmApplicationConfiguration appConfig) {
204 //urn:lsid:biocol.org:col:15727 http://biocol.org/urn:lsid:biocol.org:col:15727 University of Bergen Herbarium
205 String[] splits = line.split("\t");
206 if (splits.length != 3){
207 logger.warn("Unknwon BCI line format: " + line);
208 return null;
209 }
210 String lsidString = splits[0];
211 String urlString = splits[1];
212 String collectionName = splits[2];
213
214 Collection result = Collection.NewInstance();
215
216 //LSID
217 LSID lsid = null;
218 try {
219 lsid = new LSID(lsidString);
220 } catch (MalformedLSIDException e) {
221 logger.warn("Malformed LSID " + lsidString, e);
222 }
223
224 result.setLsid(lsid);
225 String id = getCollectionId(lsid);
226
227 result.setName(collectionName);
228
229 //id, citation
230 Reference citation = getBciCitation(appConfig);
231 result.addSource(id, null, citation, null);
232
233
234 return result;
235 }
236
237
238 private String getCollectionId(LSID lsid) {
239 String result = lsid == null? null : lsid.getObject();
240 return result;
241 }
242
243
244 private Reference getBciCitation(ICdmApplicationConfiguration appConfig) {
245 Reference bciReference;
246 if (appConfig != null){
247 bciReference = appConfig.getReferenceService().find(uuidBci);
248 if (bciReference == null){
249 bciReference = getNewBciReference();
250 bciReference.setUuid(uuidBci);
251 appConfig.getReferenceService().save(bciReference);
252 }
253 }else{
254 bciReference = getNewBciReference();
255 }
256 return bciReference;
257 }
258
259 /**
260 * @return
261 */
262 private Reference getNewBciReference() {
263 Reference bciReference;
264 bciReference = ReferenceFactory.newDatabase();
265 bciReference.setTitleCache("Biodiversity Collection Index (BCI))");
266 return bciReference;
267 }
268
269
270 /**
271 * @param parameter
272 */
273 private String normalizeParameter(String parameter) {
274 String result = CdmUtils.Nz(parameter).replace(" ", "+");
275 return result;
276 }
277
278
279
280 /**
281 * The service url
282 *
283 * @return the serviceUrl
284 */
285 public URL getServiceUrl(String url) {
286 URL serviceUrl;
287 try {
288 serviceUrl = new URL(url);
289 } catch (MalformedURLException e) {
290 throw new RuntimeException("This should not happen", e);
291 }
292 return serviceUrl;
293 }
294
295
296
297 }