Mercurial > dive4elements > http-client
comparison src/main/java/org/dive4elements/artifacts/httpclient/http/HttpClientImpl.java @ 71:a857866d162f
Moved directories to org.dive4elements
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 11:14:14 +0200 |
parents | src/main/java/de/intevation/artifacts/httpclient/http/HttpClientImpl.java@874c25363dc9 |
children | 133281653904 |
comparison
equal
deleted
inserted
replaced
70:da691e917f98 | 71:a857866d162f |
---|---|
1 /* | |
2 * Copyright (c) 2010 by Intevation GmbH | |
3 * | |
4 * This program is free software under the LGPL (>=v2.1) | |
5 * Read the file LGPL.txt coming with the software for details | |
6 * or visit http://www.gnu.org/licenses/ if it does not exist. | |
7 */ | |
8 package de.intevation.artifacts.httpclient.http; | |
9 | |
10 import java.io.InputStream; | |
11 import java.io.IOException; | |
12 import java.io.OutputStream; | |
13 import java.util.ArrayList; | |
14 import java.util.List; | |
15 | |
16 import org.apache.log4j.Logger; | |
17 | |
18 import org.restlet.Client; | |
19 import org.restlet.Request; | |
20 import org.restlet.Response; | |
21 import org.restlet.data.ClientInfo; | |
22 import org.restlet.data.Language; | |
23 import org.restlet.data.MediaType; | |
24 import org.restlet.data.Method; | |
25 import org.restlet.data.Preference; | |
26 import org.restlet.data.Protocol; | |
27 import org.restlet.data.Status; | |
28 import org.restlet.ext.xml.DomRepresentation; | |
29 import org.restlet.representation.Representation; | |
30 | |
31 import org.w3c.dom.Document; | |
32 | |
33 import de.intevation.artifacts.httpclient.exceptions.ConnectionException; | |
34 import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler; | |
35 import de.intevation.artifacts.httpclient.http.response.ResponseHandler; | |
36 import de.intevation.artifacts.httpclient.http.response.StreamResponseHandler; | |
37 import de.intevation.artifacts.httpclient.objects.Artifact; | |
38 import de.intevation.artifacts.httpclient.objects.ArtifactFactory; | |
39 import de.intevation.artifacts.httpclient.utils.ArtifactProtocolUtils; | |
40 import de.intevation.artifacts.httpclient.utils.ArtifactCreator; | |
41 | |
42 | |
43 /** | |
44 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | |
45 */ | |
46 public class HttpClientImpl implements HttpClient { | |
47 | |
48 private static final Logger logger = Logger.getLogger(HttpClient.class); | |
49 | |
50 /** The URL part of the resource to list the existing users of the server.*/ | |
51 public static final String PATH_LIST_USERS = "/list-users"; | |
52 | |
53 /** The URL part of the resource to list the Collections owned by a specific | |
54 * user.*/ | |
55 public static final String PATH_USER_COLLECTIONS = "/list-collections"; | |
56 | |
57 /** The URL part og the resource to create a new user on the server.*/ | |
58 public static final String PATH_CREATE_USER = "/create-user"; | |
59 | |
60 /** The URL part og the resource to find an existing user on the server.*/ | |
61 public static final String PATH_FIND_USER = "/find-user"; | |
62 | |
63 /** The URL part of the resource to call a specific service.*/ | |
64 public static final String PATH_SERVICE = "/service"; | |
65 | |
66 /** The URL path of the resource to create new artifact collections.*/ | |
67 public static final String PATH_CREATE_COLLECTION = "/create-collection"; | |
68 | |
69 /** The URL path of the resource to work with an artifact collections.*/ | |
70 public static final String PATH_ACTION_COLLECTION = "/collection"; | |
71 | |
72 /** The URL path of the resource to work with an artifact collections.*/ | |
73 public static final String PATH_OUT_COLLECTION = "/collection"; | |
74 | |
75 private String serverUrl; | |
76 | |
77 private String localeString; | |
78 | |
79 private static final ThreadLocal<Client> CLIENT = | |
80 new ThreadLocal<Client>() { | |
81 @Override | |
82 protected Client initialValue() { | |
83 logger.debug("create new HTTP client"); | |
84 return new Client(Protocol.HTTP); | |
85 } | |
86 }; | |
87 | |
88 public HttpClientImpl(String serverUrl) { | |
89 this.serverUrl = serverUrl; | |
90 } | |
91 | |
92 | |
93 /** | |
94 * This constructor might be used to modify the request's locale manually. | |
95 * E.g. the localization should not be based on the configured browser | |
96 * locale, but site specific configuration - than you are able to set the | |
97 * locale in this constructor. | |
98 * | |
99 * @param serverUrl The url that is used for the request. | |
100 * @param localeString The string representation of the desired locale. | |
101 */ | |
102 public HttpClientImpl(String serverUrl, String localeString) { | |
103 this(serverUrl); | |
104 | |
105 this.localeString = localeString; | |
106 } | |
107 | |
108 | |
109 @Override | |
110 public ArtifactFactory[] getArtifactFactories() | |
111 throws ConnectionException | |
112 { | |
113 ResponseHandler handler = new DocumentResponseHandler(); | |
114 | |
115 try { | |
116 String url = serverUrl + "/factories"; | |
117 Document result = (Document) handler.handle(doGet(url)); | |
118 | |
119 return ArtifactProtocolUtils.extractArtifactFactories(result); | |
120 } | |
121 catch (IOException ioe) { | |
122 throw new ConnectionException( | |
123 "Connection to server failed. No Factories recieved."); | |
124 } | |
125 } | |
126 | |
127 | |
128 /** | |
129 * This method creates a new artifact in the artifact server and returns | |
130 * this artifact. The new artifact is created using <i>creator</i>. If no | |
131 * {@link ArtifactCreator} is given (null), an {@link Artifact} is returned. | |
132 * | |
133 * @param doc The CREATE document. | |
134 * @param creator The {@link ArtifactCreator} that is used to extract the | |
135 * new artifact from response document of the server. | |
136 * | |
137 * @return the new artifact. | |
138 */ | |
139 @Override | |
140 public Object create(Document doc, ArtifactCreator creator) | |
141 throws ConnectionException | |
142 { | |
143 ResponseHandler handler = new DocumentResponseHandler(); | |
144 | |
145 try { | |
146 String url = serverUrl + "/create"; | |
147 Document result = (Document) handler.handle(doPost(url, doc)); | |
148 | |
149 return creator == null | |
150 ? ArtifactProtocolUtils.extractArtifact(result) | |
151 : creator.create(result); | |
152 } | |
153 catch (IOException ioe) { | |
154 throw new ConnectionException( | |
155 "Connection to server failed. No Artifact created."); | |
156 } | |
157 } | |
158 | |
159 | |
160 @Override | |
161 public Object describe( | |
162 Artifact artifact, | |
163 Document doc, | |
164 ResponseHandler handler) | |
165 throws ConnectionException | |
166 { | |
167 try { | |
168 String url = serverUrl + "/artifact/" + artifact.getUuid(); | |
169 return handler.handle(doPost(url, doc)); | |
170 } | |
171 catch (IOException ioe) { | |
172 throw new ConnectionException( | |
173 "Connection to server failed: " + ioe.getMessage()); | |
174 } | |
175 } | |
176 | |
177 | |
178 @Override | |
179 public Object feed(Artifact artifact, Document doc, ResponseHandler handler) | |
180 throws ConnectionException | |
181 { | |
182 try { | |
183 String url = serverUrl + "/artifact/" + artifact.getUuid(); | |
184 Document result = (Document) handler.handle(doPost(url, doc)); | |
185 | |
186 return result; | |
187 } | |
188 catch (IOException ioe) { | |
189 throw new ConnectionException( | |
190 "Connection to server failed: " + ioe.getMessage()); | |
191 } | |
192 } | |
193 | |
194 | |
195 @Override | |
196 public Object advance(Artifact artifact, Document doc, ResponseHandler handler) | |
197 throws ConnectionException | |
198 { | |
199 try { | |
200 String url = serverUrl + "/artifact/" + artifact.getUuid(); | |
201 Document result = (Document) handler.handle(doPost(url, doc)); | |
202 | |
203 return result; | |
204 } | |
205 catch (IOException ioe) { | |
206 throw new ConnectionException( | |
207 "Connection to server failed: " + ioe.getMessage()); | |
208 } | |
209 } | |
210 | |
211 | |
212 @Override | |
213 public void out( | |
214 Artifact artifact, | |
215 Document doc, | |
216 String target, | |
217 OutputStream out) | |
218 throws ConnectionException | |
219 { | |
220 try { | |
221 String url = | |
222 serverUrl | |
223 + "/artifact/" | |
224 + artifact.getUuid() | |
225 + "/" + target; | |
226 | |
227 ResponseHandler handler = new StreamResponseHandler(); | |
228 | |
229 InputStream stream = (InputStream) handler.handle(doPost(url, doc)); | |
230 try { | |
231 byte[] b = new byte[4096]; | |
232 int i; | |
233 while ((i = stream.read(b)) >= 0) { | |
234 out.write(b, 0, i); | |
235 } | |
236 } | |
237 finally { | |
238 stream.close(); | |
239 } | |
240 } | |
241 catch (IOException ioe) { | |
242 throw new ConnectionException( | |
243 "Connection to server failed: " + ioe.getMessage()); | |
244 } | |
245 } | |
246 | |
247 | |
248 //============================== | |
249 // HTTP specific methods | |
250 //============================== | |
251 | |
252 private Response doPost(String url, Document body) throws IOException { | |
253 if (logger.isDebugEnabled()) { | |
254 logger.debug("Start HTTP-POST request to: " + url); | |
255 } | |
256 | |
257 Client client = getClient(); | |
258 Request request = prepareRequest(Method.POST, url); | |
259 | |
260 Representation representation = new DomRepresentation( | |
261 MediaType.APPLICATION_XML, | |
262 body); | |
263 | |
264 request.setEntity(representation); | |
265 Response response = client.handle(request); | |
266 | |
267 Status status = response.getStatus(); | |
268 if (status.getCode() != 200) { | |
269 logger.error("Response status: " + status.getCode()); | |
270 throw new IOException(status.getDescription()); | |
271 } | |
272 | |
273 return response; | |
274 } | |
275 | |
276 | |
277 private static Client getClient() { | |
278 return CLIENT.get(); | |
279 } | |
280 | |
281 | |
282 private Response doGet(String url) throws IOException { | |
283 if (logger.isDebugEnabled()) { | |
284 logger.debug("Start HTTP-POST request to: "+ url); | |
285 } | |
286 | |
287 Client client = getClient(); | |
288 Request request = prepareRequest(Method.GET, url); | |
289 | |
290 Response response = client.handle(request); | |
291 | |
292 Status status = response.getStatus(); | |
293 if (status.getCode() != 200) { | |
294 logger.error("Response status: " + status.getCode()); | |
295 throw new IOException(status.getDescription()); | |
296 } | |
297 | |
298 return response; | |
299 } | |
300 | |
301 | |
302 /** | |
303 * This method prepares the request object. | |
304 * | |
305 * @param method The HTTP method (GET,POST). | |
306 * @param url The URL used for the request. | |
307 * | |
308 * @return the request object. | |
309 */ | |
310 private Request prepareRequest(Method method, String url) { | |
311 Request request = new Request(method, url); | |
312 | |
313 ClientInfo info = request.getClientInfo(); | |
314 | |
315 setLocale(info); | |
316 | |
317 request.setClientInfo(info); | |
318 | |
319 return request; | |
320 } | |
321 | |
322 | |
323 /** | |
324 * This method is called to set the request's locale. | |
325 * | |
326 * @param info The ClientInfo that is used to provide request information. | |
327 */ | |
328 private void setLocale(ClientInfo info) { | |
329 if (localeString == null) { | |
330 return; | |
331 } | |
332 | |
333 List<Preference<Language>> accepted = | |
334 new ArrayList<Preference<Language>>(); | |
335 | |
336 Language lang = Language.valueOf(localeString); | |
337 | |
338 if (lang != null) { | |
339 if (logger.isDebugEnabled()) { | |
340 logger.debug( | |
341 "Set locale of the request object: " + lang.toString()); | |
342 } | |
343 | |
344 Preference<Language> pref = new Preference<Language>(); | |
345 pref.setMetadata(lang); | |
346 accepted.add(pref); | |
347 | |
348 info.setAcceptedLanguages(accepted); | |
349 } | |
350 } | |
351 | |
352 | |
353 //============================== | |
354 // Collection API | |
355 //============================== | |
356 | |
357 /** | |
358 * This method triggers the artifact servers resource to create a new | |
359 * artifact collection. | |
360 * | |
361 * @param create The CREATE document for the collection. | |
362 * @param ownerId The uuid of the creator. | |
363 * @param handler The handler that is used to create the result object. | |
364 * | |
365 * @return a result object created by <i>handler</i>. | |
366 */ | |
367 public Object createCollection( | |
368 Document create, | |
369 String ownerId, | |
370 ResponseHandler handler) | |
371 throws ConnectionException | |
372 { | |
373 String url = serverUrl + PATH_CREATE_COLLECTION + "/" + ownerId; | |
374 | |
375 try { | |
376 return handler.handle(doPost(url, create)); | |
377 } | |
378 catch (IOException ioe) { | |
379 throw new ConnectionException(ioe.getMessage(), ioe); | |
380 } | |
381 } | |
382 | |
383 | |
384 /** | |
385 * This method might be used to trigger a collection specific action. The | |
386 * action that is executed depends on the document <i>actionDoc</i>. | |
387 * | |
388 * @param actionDoc The document that describes the action to be executed. | |
389 * @param uuid The uuid of the collection. | |
390 * @param handler The handler that is used to create the result object. | |
391 * | |
392 * @return a result object created by <i>handler</i>. | |
393 */ | |
394 public Object doCollectionAction( | |
395 Document actionDoc, | |
396 String uuid, | |
397 ResponseHandler handler) | |
398 throws ConnectionException | |
399 { | |
400 String url = serverUrl + PATH_ACTION_COLLECTION + "/" + uuid; | |
401 | |
402 try { | |
403 return handler.handle(doPost(url, actionDoc)); | |
404 } | |
405 catch (IOException ioe) { | |
406 throw new ConnectionException(ioe.getMessage(), ioe); | |
407 } | |
408 } | |
409 | |
410 | |
411 /** | |
412 * This method triggers the out() operation of a Collection. The result of | |
413 * this operation is written to <i>out</i> directly - there is no return | |
414 * value. | |
415 * | |
416 * @param doc The request document for the out() operation. | |
417 * @param uuid The identifier of the Collection. | |
418 * @param type The name of the output type. | |
419 * @param out The OutputStream. | |
420 */ | |
421 public void collectionOut( | |
422 Document doc, | |
423 String uuid, | |
424 String type, | |
425 OutputStream out) | |
426 throws ConnectionException | |
427 { | |
428 try { | |
429 InputStream stream = collectionOut(doc, uuid, type); | |
430 | |
431 byte[] b = new byte[4096]; | |
432 try { | |
433 int i; | |
434 while ((i = stream.read(b)) >= 0) { | |
435 out.write(b, 0, i); | |
436 } | |
437 } | |
438 finally { | |
439 stream.close(); | |
440 } | |
441 } | |
442 catch (IOException ioe) { | |
443 throw new ConnectionException(ioe.getMessage(), ioe); | |
444 } | |
445 } | |
446 | |
447 | |
448 /** | |
449 * This method triggers the out() operation of a Collection. The result of | |
450 * this operation is returned as an InputStream. | |
451 * | |
452 * @param doc The request document for the out() operation. | |
453 * @param uuid The identifier of the Collection. | |
454 * @param type The name of the output type. | |
455 * | |
456 * @return an InputStream. | |
457 */ | |
458 public InputStream collectionOut( | |
459 Document doc, | |
460 String uuid, | |
461 String type) | |
462 throws ConnectionException | |
463 { | |
464 String url = serverUrl + PATH_OUT_COLLECTION + "/" + uuid + "/" + type; | |
465 | |
466 ResponseHandler handler = new StreamResponseHandler(); | |
467 | |
468 try { | |
469 return (InputStream) handler.handle(doPost(url, doc)); | |
470 } | |
471 catch (IOException ioe) { | |
472 throw new ConnectionException(ioe.getMessage(), ioe); | |
473 } | |
474 } | |
475 | |
476 | |
477 /******************************* | |
478 * Service API | |
479 *******************************/ | |
480 | |
481 public Document callService(String url, String service, Document input) | |
482 throws ConnectionException | |
483 { | |
484 DocumentResponseHandler handler = new DocumentResponseHandler(); | |
485 | |
486 return (Document) callService(url, service, input, handler); | |
487 } | |
488 | |
489 | |
490 public Object callService( | |
491 String url, | |
492 String service, | |
493 Document input, | |
494 ResponseHandler handler) | |
495 throws ConnectionException { | |
496 if (logger.isDebugEnabled()) { | |
497 logger.debug("Start service call to '" + service + "'"); | |
498 } | |
499 | |
500 try { | |
501 String serverUrl = url + PATH_SERVICE + "/" + service; | |
502 return handler.handle(doPost(serverUrl, input)); | |
503 } | |
504 catch (IOException ioe) { | |
505 throw new ConnectionException( | |
506 "Connection to server failed: " + ioe.getMessage()); | |
507 } | |
508 } | |
509 | |
510 | |
511 /******************************* | |
512 * Users API | |
513 *******************************/ | |
514 | |
515 public Document listUsers() | |
516 throws ConnectionException | |
517 { | |
518 ResponseHandler handler = new DocumentResponseHandler(); | |
519 String url = serverUrl + PATH_LIST_USERS; | |
520 | |
521 try { | |
522 return (Document) handler.handle(doGet(url)); | |
523 } | |
524 catch (IOException ioe) { | |
525 throw new ConnectionException(ioe.getMessage(), ioe); | |
526 } | |
527 } | |
528 | |
529 | |
530 public Document listUserCollections(String userid) | |
531 throws ConnectionException | |
532 { | |
533 ResponseHandler handler = new DocumentResponseHandler(); | |
534 | |
535 String url = serverUrl + PATH_USER_COLLECTIONS + "/" + userid; | |
536 | |
537 try { | |
538 return (Document) handler.handle(doGet(url)); | |
539 } | |
540 catch (IOException ioe) { | |
541 throw new ConnectionException(ioe.getMessage(), ioe); | |
542 } | |
543 } | |
544 | |
545 @Override | |
546 public Document createUser(Document doc) | |
547 throws ConnectionException { | |
548 ResponseHandler handler = new DocumentResponseHandler(); | |
549 | |
550 String url = this.serverUrl + PATH_CREATE_USER; | |
551 | |
552 try { | |
553 return (Document) handler.handle(doPost(url, doc)); | |
554 } | |
555 catch (IOException ioe) { | |
556 throw new ConnectionException( | |
557 "Connection to server failed: " + ioe.getMessage()); | |
558 } | |
559 } | |
560 | |
561 @Override | |
562 public Document findUser(Document doc) | |
563 throws ConnectionException { | |
564 ResponseHandler handler = new DocumentResponseHandler(); | |
565 | |
566 String url = this.serverUrl + PATH_FIND_USER; | |
567 | |
568 try { | |
569 return (Document) handler.handle(doPost(url, doc)); | |
570 } | |
571 catch (IOException ioe) { | |
572 throw new ConnectionException( | |
573 "Connection to server failed: " + ioe.getMessage()); | |
574 } | |
575 } | |
576 } | |
577 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: |