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:

http://dive4elements.wald.intevation.org