comparison flys-client/src/main/java/de/intevation/flys/client/server/CollectionHelper.java @ 905:478a571f1f94

Refactored server code - HTTP related code moved to ArtifactsHelper and CollectionHelper which makes us able to combine Artifact and Collection protocol stuff in a single RPC service. flys-client/trunk@2757 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 15 Sep 2011 12:55:36 +0000
parents 0fe456332785
children ecd0243bc09e
comparison
equal deleted inserted replaced
904:1e08a5b0add9 905:478a571f1f94
1 package de.intevation.flys.client.server; 1 package de.intevation.flys.client.server;
2 2
3 import java.util.ArrayList;
4 import java.util.HashMap;
3 import java.util.List; 5 import java.util.List;
4 import java.util.Map; 6 import java.util.Map;
5 import java.util.Set; 7 import java.util.Set;
6 8
9 import javax.xml.xpath.XPathConstants;
10
7 import org.w3c.dom.Document; 11 import org.w3c.dom.Document;
8 import org.w3c.dom.Element; 12 import org.w3c.dom.Element;
13 import org.w3c.dom.NamedNodeMap;
14 import org.w3c.dom.Node;
15 import org.w3c.dom.NodeList;
9 16
10 import de.intevation.artifacts.common.ArtifactNamespaceContext; 17 import de.intevation.artifacts.common.ArtifactNamespaceContext;
18 import de.intevation.artifacts.common.utils.ClientProtocolUtils;
11 import de.intevation.artifacts.common.utils.XMLUtils; 19 import de.intevation.artifacts.common.utils.XMLUtils;
12 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; 20 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
13 21
22 import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
23 import de.intevation.artifacts.httpclient.http.HttpClient;
24 import de.intevation.artifacts.httpclient.http.HttpClientImpl;
25 import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
26
27 import de.intevation.flys.client.shared.exceptions.ServerException;
28 import de.intevation.flys.client.shared.model.Artifact;
14 import de.intevation.flys.client.shared.model.AttributedTheme; 29 import de.intevation.flys.client.shared.model.AttributedTheme;
30 import de.intevation.flys.client.shared.model.ChartMode;
15 import de.intevation.flys.client.shared.model.Collection; 31 import de.intevation.flys.client.shared.model.Collection;
32 import de.intevation.flys.client.shared.model.CollectionItem;
33 import de.intevation.flys.client.shared.model.DefaultCollection;
34 import de.intevation.flys.client.shared.model.DefaultCollectionItem;
35 import de.intevation.flys.client.shared.model.DefaultFacet;
36 import de.intevation.flys.client.shared.model.ExportMode;
37 import de.intevation.flys.client.shared.model.Facet;
38 import de.intevation.flys.client.shared.model.MapMode;
16 import de.intevation.flys.client.shared.model.OutputMode; 39 import de.intevation.flys.client.shared.model.OutputMode;
40 import de.intevation.flys.client.shared.model.ReportMode;
17 import de.intevation.flys.client.shared.model.Recommendation; 41 import de.intevation.flys.client.shared.model.Recommendation;
18 import de.intevation.flys.client.shared.model.Theme; 42 import de.intevation.flys.client.shared.model.Theme;
19 import de.intevation.flys.client.shared.model.ThemeList; 43 import de.intevation.flys.client.shared.model.ThemeList;
20 44
21 45
22 /** 46 /**
23 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> 47 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
24 */ 48 */
25 public class CollectionHelper { 49 public class CollectionHelper {
50
51 public static final String ERROR_ADD_ARTIFACT = "error_add_artifact";
52
53 public static final String XPATH_FACETS = "art:facets/art:facet";
54
55 public static final String XPATH_LOADED_RECOMMENDATIONS =
56 "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation";
57
26 58
27 public static Document createAttribute(Collection collection) { 59 public static Document createAttribute(Collection collection) {
28 System.out.println("CollectionHelper.createAttribute"); 60 System.out.println("CollectionHelper.createAttribute");
29 61
30 Document doc = XMLUtils.newDocument(); 62 Document doc = XMLUtils.newDocument();
230 cr.addAttr(recommendation, "factory", r.getFactory(), true); 262 cr.addAttr(recommendation, "factory", r.getFactory(), true);
231 cr.addAttr(recommendation, "ids", r.getIDs(), true); 263 cr.addAttr(recommendation, "ids", r.getIDs(), true);
232 264
233 return recommendation; 265 return recommendation;
234 } 266 }
267
268
269 /**
270 * This method takes the DESCRIBE document of the Collections describe()
271 * operation and extracts the information about the collection itself and
272 * the collection items.
273 *
274 * @param description The DESCRIBE document of the Collections describe()
275 * operation.
276 *
277 * @return a Collection with CollectionItems.
278 */
279 public static Collection parseCollection(Document description) {
280 System.out.println("AddArtifactServiceImpl.parseCollection");
281
282 if (description == null) {
283 System.err.println("The DESCRIBE of the Collection is null!");
284 return null;
285 }
286
287 String uuid = XMLUtils.xpathString(
288 description,
289 "art:artifact-collection/@art:uuid",
290 ArtifactNamespaceContext.INSTANCE);
291
292 String ttlStr = XMLUtils.xpathString(
293 description,
294 "art:artifact-collection/@art:ttl",
295 ArtifactNamespaceContext.INSTANCE);
296
297 String name = XMLUtils.xpathString(
298 description,
299 "art:artifact-collection/@art:name",
300 ArtifactNamespaceContext.INSTANCE);
301
302 if (uuid.length() == 0 || ttlStr.length() == 0) {
303 System.err.println("Found an invalid Collection!");
304 return null;
305 }
306
307
308 long ttl = -1;
309 try {
310 ttl = Long.valueOf(ttlStr);
311 }
312 catch (NumberFormatException nfe) {
313 // do nothing
314 }
315
316 Map<String, ThemeList> themeList = parseThemeLists(description);
317 List<Recommendation> recommended = parseRecommendations(description);
318
319 name = (name != null && name.length() > 0) ? name : uuid;
320
321 Collection c = !themeList.isEmpty()
322 ? new DefaultCollection(uuid, ttl, name, recommended, themeList)
323 : new DefaultCollection(uuid, ttl, name, recommended);
324
325 NodeList items = (NodeList) XMLUtils.xpath(
326 description,
327 "art:artifact-collection/art:artifacts/art:artifact",
328 XPathConstants.NODESET,
329 ArtifactNamespaceContext.INSTANCE);
330
331 if (items == null || items.getLength() == 0) {
332 System.out.println("No collection item found for this collection.");
333
334 return c;
335 }
336
337 int size = items.getLength();
338
339 for (int i = 0; i < size; i++) {
340 CollectionItem item = parseCollectionItem(
341 (Element)items.item(i),
342 i == 0);
343
344 if (item != null) {
345 c.addItem(item);
346 }
347 }
348
349 System.out.println(
350 "Found " + c.getItemLength() + " collection items " +
351 "for the Collection '" + c.identifier() + "'.");
352
353 return c;
354 }
355
356
357 protected static Map<String, ThemeList> parseThemeLists(Document desc) {
358 System.out.println("DescribeCollectionServiceImpl.parseThemeLists");
359
360 NodeList lists = (NodeList) XMLUtils.xpath(
361 desc,
362 "/art:artifact-collection/art:attribute/art:outputs/art:output",
363 XPathConstants.NODESET,
364 ArtifactNamespaceContext.INSTANCE);
365
366 int num = lists != null ? lists.getLength() : 0;
367
368 Map<String, ThemeList> themeList = new HashMap<String, ThemeList>(num);
369
370 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
371
372 for (int i = 0; i < num; i++) {
373 Element node = (Element)lists.item(i);
374
375 String outName = node.getAttribute("name");
376
377 if (outName.length() > 0) {
378 ThemeList list = parseThemeList(node);
379 if (list.getThemeCount() > 0) {
380 themeList.put(outName, list);
381 }
382 }
383 }
384
385 return themeList;
386 }
387
388
389 protected static ThemeList parseThemeList(Element node) {
390 System.out.println("DescribeCollectionServiceImpl.parseThemeList");
391
392 NodeList themes = node.getElementsByTagNameNS(
393 ArtifactNamespaceContext.NAMESPACE_URI,
394 "facet");
395
396 int num = themes != null ? themes.getLength() : 0;
397
398 List<Theme> themeList = new ArrayList<Theme>(num);
399
400 for (int i = 0; i < num; i++) {
401 Theme theme = parseTheme((Element)themes.item(i));
402
403 if (theme != null) {
404 themeList.add(theme);
405 }
406 }
407
408 return new ThemeList(themeList);
409 }
410
411
412 protected static Theme parseTheme(Element ele) {
413 System.out.println("DescribeCollectionServiceImpl.parseTheme");
414
415 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
416
417 NamedNodeMap attrMap = ele.getAttributes();
418 int attrNum = attrMap != null ? attrMap.getLength() : 0;
419
420 AttributedTheme t = new AttributedTheme();
421
422 for (int i = 0; i < attrNum; i++) {
423 Node attr = attrMap.item(i);
424
425 String prefix = attr.getPrefix();
426 String name = attr.getNodeName().replace(prefix + ":", "");
427 String value = attr.getNodeValue();
428
429 t.addAttr(name, value);
430 }
431
432 return t;
433 }
434
435
436 /**
437 * This method extracts the CollectionItem from <i>node</i> with its output
438 * modes. The output modes are parsed using the parseOutputModes() method.
439 *
440 * @param node A node that contains information about a CollectionItem.
441 *
442 * @return a CollectionItem.
443 */
444 protected static CollectionItem parseCollectionItem(
445 Element node,
446 boolean outs
447 ) {
448 System.out.println("AddArtifactServiceImpl.parseCollectionItem");
449
450 if (node == null) {
451 System.err.println("The node for parsing CollectionItem is null!");
452 return null;
453 }
454
455 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
456
457 String uuid = node.getAttributeNS(uri, "uuid");
458 String hash = node.getAttributeNS(uri, "hash");
459
460 if (uuid == null || uuid.length() == 0) {
461 System.err.println("Found an invalid CollectionItem!");
462 return null;
463 }
464
465 List<OutputMode> modes = new ArrayList<OutputMode>();
466
467 if (outs) {
468 NodeList outputmodes = node.getElementsByTagNameNS(
469 uri, "outputmodes");
470
471 if (outputmodes.getLength() < 1) {
472 return null;
473 }
474
475 Element om = (Element)outputmodes.item(0);
476
477 modes = parseOutputModes(om);
478 }
479
480 return new DefaultCollectionItem(uuid, hash, modes);
481 }
482
483
484 /**
485 * This method extracts the OutputModes available for a specific
486 * CollectionItem and returns them as list.
487 *
488 * @param node The root node of the outputmodes list.
489 *
490 * @return a list of OutputModes.
491 */
492 protected static List<OutputMode> parseOutputModes(Element node) {
493 System.out.println("AddArtifactServiceImpl.parseOutputModes");
494
495 if (node == null) {
496 System.err.println("The node for parsing OutputModes is null!");
497 return null;
498 }
499
500 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
501
502 NodeList list = node.getElementsByTagNameNS(uri, "output");
503
504 int size = list.getLength();
505
506 if (size == 0) {
507 System.err.println("No outputmode nodes found!");
508 return null;
509 }
510
511 List<OutputMode> modes = new ArrayList<OutputMode>(size);
512
513 for (int i = 0; i < size; i++) {
514 Element tmp = (Element)list.item(i);
515
516 String name = tmp.getAttributeNS(uri, "name");
517 String desc = tmp.getAttributeNS(uri, "description");
518 String mime = tmp.getAttributeNS(uri, "mime-type");
519 String type = tmp.getAttributeNS(uri, "type");
520
521 if (name.length() == 0) {
522 System.err.println("Found an invalid output mode.");
523 continue;
524 }
525
526 OutputMode outmode = null;
527 List<Facet> fs = extractFacets(tmp);
528
529 if (type.equals("export")) {
530 outmode = new ExportMode(name, desc, mime, fs);
531 }
532 else if (type.equals("report")) {
533 outmode = new ReportMode(name, desc, mime, fs);
534 }
535 else if (type.equals("chart")){
536 outmode = new ChartMode(name, desc, mime, fs);
537 }
538 else if (type.equals("map")){
539 outmode = new MapMode(name, desc, mime, fs);
540 }
541 else {
542 System.err.println("Broken Output mode without type found.");
543 continue;
544 }
545
546 modes.add(outmode);
547 }
548
549 return modes;
550 }
551
552
553 protected static List<Facet> extractFacets(Element outmode) {
554 System.out.println("DescribeCollectionServiceImpl - extractFacets()");
555
556 NodeList facetList = (NodeList) XMLUtils.xpath(
557 outmode,
558 XPATH_FACETS,
559 XPathConstants.NODESET,
560 ArtifactNamespaceContext.INSTANCE);
561
562 int num = facetList != null ? facetList.getLength() : 0;
563
564 List<Facet> facets = new ArrayList<Facet>(num);
565
566 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
567
568 for (int i = 0; i < num; i++) {
569 Element facetEl = (Element) facetList.item(i);
570
571 String name = facetEl.getAttributeNS(uri, "name");
572 String desc = facetEl.getAttributeNS(uri, "description");
573 String index = facetEl.getAttributeNS(uri, "index");
574
575 if (name != null && name.length() > 0 && index != null) {
576 facets.add(new DefaultFacet(name, Integer.valueOf(index),desc));
577 }
578 }
579
580 return facets;
581 }
582
583
584 public static List<Recommendation> parseRecommendations(Document doc) {
585 System.out.println("DescribeCollectionServiceImpl.parseRecommendations");
586
587 NodeList list = (NodeList) XMLUtils.xpath(
588 doc,
589 XPATH_LOADED_RECOMMENDATIONS,
590 XPathConstants.NODESET,
591 ArtifactNamespaceContext.INSTANCE);
592
593 int num = list != null ? list.getLength() : 0;
594
595 List<Recommendation> recs = new ArrayList<Recommendation>(num);
596
597 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
598
599 for (int i = 0; i < num; i++) {
600 Element rec = (Element) list.item(i);
601
602 String factory = rec.getAttributeNS(uri, "factory");
603 String dbids = rec.getAttributeNS(uri, "ids");
604
605 if (factory != null && factory.length() > 0) {
606 recs.add(new Recommendation(factory, dbids));
607 }
608 }
609
610 return recs;
611 }
612
613
614 public static Collection addArtifact(
615 Collection collection,
616 Artifact artifact,
617 String url,
618 String locale)
619 throws ServerException
620 {
621 System.out.println("Collection.addArtifact");
622
623 if (collection == null) {
624 System.err.println("The given Collection is null!");
625 return null;
626 }
627
628 Document add = ClientProtocolUtils.newAddArtifactDocument(
629 artifact.getUuid(), null);
630
631 HttpClient client = new HttpClientImpl(url, locale);
632
633 try {
634 System.out.println("Do HTTP request now.");
635
636 Document response = (Document) client.doCollectionAction(
637 add, collection.identifier(), new DocumentResponseHandler());
638
639 System.out.println(
640 "Finished HTTP request successfully. Parse Collection now.");
641
642 Collection c = CollectionHelper.parseCollection(response);
643
644 if (c == null) {
645 throw new ServerException(ERROR_ADD_ARTIFACT);
646 }
647
648 return c;
649 }
650 catch (ConnectionException ce) {
651 System.err.println(ce.getLocalizedMessage());
652 }
653 catch (Exception e) {
654 e.printStackTrace();
655 }
656
657 throw new ServerException(ERROR_ADD_ARTIFACT);
658 }
235 } 659 }
236 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 660 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org