comparison gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java @ 5838:5aa05a7a34b7

Rename modules to more fitting names.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 15:23:37 +0200
parents flys-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java@821a02bbfb4e
children 172338b1407f
comparison
equal deleted inserted replaced
5837:d9901a08d0a6 5838:5aa05a7a34b7
1 package org.dive4elements.river.client.server;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Set;
8
9 import javax.xml.xpath.XPathConstants;
10
11 import org.w3c.dom.Document;
12 import org.w3c.dom.Element;
13 import org.w3c.dom.NamedNodeMap;
14 import org.w3c.dom.Node;
15 import org.w3c.dom.NodeList;
16
17 import org.apache.log4j.Logger;
18
19 import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
20 import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
21 import org.dive4elements.artifacts.common.utils.XMLUtils;
22 import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator;
23
24 import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException;
25 import org.dive4elements.artifacts.httpclient.http.HttpClient;
26 import org.dive4elements.artifacts.httpclient.http.HttpClientImpl;
27 import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler;
28
29 import org.dive4elements.river.client.shared.exceptions.ServerException;
30 import org.dive4elements.river.client.shared.model.Artifact;
31 import org.dive4elements.river.client.shared.model.AttributedTheme;
32 import org.dive4elements.river.client.shared.model.ChartMode;
33 import org.dive4elements.river.client.shared.model.Collection;
34 import org.dive4elements.river.client.shared.model.CollectionItem;
35 import org.dive4elements.river.client.shared.model.DefaultCollection;
36 import org.dive4elements.river.client.shared.model.DefaultCollectionItem;
37 import org.dive4elements.river.client.shared.model.DefaultFacet;
38 import org.dive4elements.river.client.shared.model.ExportMode;
39 import org.dive4elements.river.client.shared.model.Facet;
40 import org.dive4elements.river.client.shared.model.MapMode;
41 import org.dive4elements.river.client.shared.model.OutputMode;
42 import org.dive4elements.river.client.shared.model.OverviewMode;
43 import org.dive4elements.river.client.shared.model.ReportMode;
44 import org.dive4elements.river.client.shared.model.Recommendation;
45 import org.dive4elements.river.client.shared.model.Theme;
46 import org.dive4elements.river.client.shared.model.ThemeList;
47 import org.dive4elements.river.client.shared.model.Settings;
48 import org.dive4elements.river.client.shared.model.Property;
49 import org.dive4elements.river.client.shared.model.PropertyGroup;
50 import org.dive4elements.river.client.shared.model.PropertySetting;
51 import org.dive4elements.river.client.shared.model.StringProperty;
52 import org.dive4elements.river.client.shared.model.DoubleProperty;
53 import org.dive4elements.river.client.shared.model.IntegerProperty;
54 import org.dive4elements.river.client.shared.model.BooleanProperty;
55 import org.dive4elements.river.client.shared.model.OutputSettings;
56
57 //temporary
58
59 /**
60 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
61 */
62 public class CollectionHelper {
63
64 private static final Logger logger =
65 Logger.getLogger(CollectionHelper.class);
66
67 public static final String ERROR_ADD_ARTIFACT = "error_add_artifact";
68
69 public static final String ERROR_REMOVE_ARTIFACT = "error_remove_artifact";
70
71 public static final String XPATH_FACETS = "art:facets/art:facet";
72
73 public static final String XPATH_LOADED_RECOMMENDATIONS =
74 "/art:artifact-collection/art:attribute/art:loaded-recommendations/art:recommendation";
75
76
77 public static Document createAttribute(Collection collection) {
78 logger.debug("CollectionHelper.createAttribute");
79
80 Document doc = XMLUtils.newDocument();
81
82 ElementCreator cr = new ElementCreator(
83 doc,
84 ArtifactNamespaceContext.NAMESPACE_URI,
85 ArtifactNamespaceContext.NAMESPACE_PREFIX);
86
87 Element attr = cr.create("attribute");
88
89 doc.appendChild(attr);
90
91 Map<String, OutputMode> tmpOuts = collection.getOutputModes();
92
93 Element outs = createOutputElements(cr, collection, tmpOuts);
94 Element recs = createRecommendationsElements(cr, collection);
95
96 if (outs != null) {
97 attr.appendChild(outs);
98 }
99
100 if (recs != null) {
101 attr.appendChild(recs);
102 }
103
104 return doc;
105 }
106
107
108 /**
109 * Creates a whole block with art:output nodes.
110 *
111 * @param cr The ElementCreator used to create new elements.
112 * @param c The collection.
113 * @param modes The OutputModes that should be included.
114 *
115 * @return an element with output modes.
116 */
117 protected static Element createOutputElements(
118 ElementCreator cr,
119 Collection c,
120 Map<String, OutputMode> mmodes)
121 {
122 logger.debug("CollectionHelper.createOutputElements");
123
124 java.util.Collection<OutputMode> modes = mmodes != null
125 ? mmodes.values()
126 : null;
127
128 if (modes == null || modes.size() == 0) {
129 logger.debug("Collection has no modes: " + c.identifier());
130 return null;
131 }
132
133 Element outs = cr.create("outputs");
134
135 for (OutputMode mode: modes) {
136 Element out = createOutputElement(cr, c, mode);
137
138 if (out != null) {
139 outs.appendChild(out);
140 }
141 }
142
143 return outs;
144 }
145
146
147 /**
148 * Create a node art:output that further consist of art:theme nodes.
149 *
150 * @param cr The ElementCreator used to create new elements.
151 * @param c The collection.
152 * @param mode The OutputMode.
153 *
154 * @return an element that represents an output mode with its themes.
155 */
156 protected static Element createOutputElement(
157 ElementCreator cr,
158 Collection collection,
159 OutputMode mode)
160 {
161 logger.debug("CollectionHelper.createOutputElement");
162
163 Element out = cr.create("output");
164 cr.addAttr(out, "name", mode.getName(), false);
165
166 ThemeList themeList = collection.getThemeList(mode.getName());
167 List<Theme> themes = themeList != null ? themeList.getThemes() : null;
168
169 if (themes == null || themes.size() == 0) {
170 logger.debug("No themes for output mode: " + mode.getName());
171 return null;
172 }
173
174 for (Theme theme: themes) {
175 Element t = createThemeElement(cr, collection, theme);
176
177 if (t != null) {
178 out.appendChild(t);
179 }
180 }
181
182 Document doc = out.getOwnerDocument();
183
184 ElementCreator settingscr = new ElementCreator(doc, "", "");
185
186 Settings settings = collection.getSettings(mode.getName());
187 if (settings == null ||
188 settings.getCategories().size() == 0)
189 {
190 logger.debug("No settings for output mode: " + mode.getName());
191 }
192 else {
193 Element s = createSettingsElement(settingscr, collection, settings);
194 if (s != null) {
195 out.appendChild(s);
196 }
197 }
198 logger.info(XMLUtils.toString(out));
199 return out;
200 }
201
202
203 /**
204 * Creates a theme node art:theme that represents a curve in a chart or map.
205 *
206 * @param cr The ElementCreator used to create new elements.
207 * @param collection The collection.
208 * @param theme The theme whose attributes should be written to an element.
209 *
210 * @return an element that contains the informtion of the given theme.
211 */
212 protected static Element createThemeElement(
213 ElementCreator cr,
214 Collection collection,
215 Theme theme)
216 {
217 if (theme == null) {
218 return null;
219 }
220
221 Element t = cr.create("facet");
222
223 if (theme instanceof AttributedTheme) {
224 AttributedTheme at = (AttributedTheme) theme;
225 Set<String> keys = at.getKeys();
226
227 for (String key: keys) {
228 cr.addAttr(t, key, at.getAttr(key), true);
229 }
230 }
231 else {
232 cr.addAttr(t, "active", Integer.toString(theme.getActive()), true);
233 cr.addAttr(t, "artifact", theme.getArtifact(), true);
234 cr.addAttr(t, "facet", theme.getFacet(), true);
235 cr.addAttr(t, "pos", Integer.toString(theme.getPosition()), true);
236 cr.addAttr(t, "index", Integer.toString(theme.getIndex()), true);
237 cr.addAttr(t, "description", theme.getDescription(), true);
238 cr.addAttr(t, "visible", Integer.toString(theme.getVisible()), true);
239 }
240
241 return t;
242 }
243
244
245 /**
246 * Creates a whole block with art:loaded-recommendations nodes.
247 *
248 * @param cr The ElementCreator used to create new elements.
249 * @param c The collection.
250 *
251 * @return an element with loaded recommendations.
252 */
253 protected static Element createRecommendationsElements(
254 ElementCreator cr,
255 Collection c)
256 {
257 logger.debug("CollectionHelper.createRecommendationsElements");
258
259 List<Recommendation> rs = c.getRecommendations();
260
261 if (rs == null || rs.size() == 0) {
262 logger.debug("Collection did not load recommendations: " +
263 c.identifier());
264 return null;
265 }
266
267 Element loaded = cr.create("loaded-recommendations");
268
269 for (Recommendation r: rs) {
270 Element recommendation = createRecommendationElement(cr, c, r);
271
272 if (recommendation != null) {
273 loaded.appendChild(recommendation);
274 }
275 }
276
277 return loaded;
278 }
279
280
281 /**
282 * Create a node art:recommended.
283 *
284 * @param cr The ElementCreator used to create new elements.
285 * @param c The collection.
286 * @param r The Recommendation.
287 *
288 * @return an element that represents an output mode with its themes.
289 */
290 protected static Element createRecommendationElement(
291 ElementCreator cr,
292 Collection c,
293 Recommendation r)
294 {
295 logger.debug("CollectionHelper.createRecommendationElement");
296
297 Element recommendation = cr.create("recommendation");
298 cr.addAttr(recommendation, "factory", r.getFactory(), true);
299 cr.addAttr(recommendation, "ids", r.getIDs(), true);
300
301 return recommendation;
302 }
303
304
305 /**
306 *
307 */
308 protected static Element createSettingsElement(
309 ElementCreator cr,
310 Collection c,
311 Settings s)
312 {
313 logger.debug("CollectionHelper.createSettingsElement");
314 Element settings = cr.create("settings");
315
316 List<String> categories = s.getCategories();
317
318 for (String category: categories) {
319 Element cat =cr.create(category);
320 settings.appendChild(cat);
321 List<Property> props = s.getSettings(category);
322 for (Property p: props) {
323 if (p instanceof PropertyGroup) {
324 Element prop = createPropertyGroupElement(cr,
325 (PropertyGroup)p);
326 cat.appendChild(prop);
327 }
328 else if (p instanceof PropertySetting) {
329 Element prop = createPropertyElement (cr,
330 (PropertySetting)p);
331 cat.appendChild(prop);
332 }
333 }
334 }
335 return settings;
336 }
337
338
339 /**
340 *
341 */
342 protected static Element createPropertyGroupElement(
343 ElementCreator cr,
344 PropertyGroup pg)
345 {
346 Element e = cr.create(pg.getName());
347
348 List<Property> list = pg.getProperties();
349 for (Property p: list) {
350 Element pe = createPropertyElement(cr, (PropertySetting)p);
351 e.appendChild(pe);
352 }
353 return e;
354 }
355
356
357 /**
358 *
359 */
360 protected static Element createPropertyElement(
361 ElementCreator cr,
362 PropertySetting p)
363 {
364 Element e = cr.create(p.getName());
365
366 if(p instanceof BooleanProperty) {
367 cr.addAttr(e, "type", "boolean", false);
368 }
369 else if(p instanceof DoubleProperty) {
370 cr.addAttr(e, "type", "double", false);
371 }
372 else if(p instanceof IntegerProperty) {
373 cr.addAttr(e, "type", "integer", false);
374 }
375 else if(p instanceof StringProperty) {
376 cr.addAttr(e, "type", "string", false);
377 }
378
379 e.setTextContent(p.getValue().toString());
380 cr.addAttr(e, "display", p.getAttribute("display"), false);
381 return e;
382 }
383
384
385 /**
386 * Take the DESCRIBE document of the Collections describe()
387 * operation and extracts the information about the collection itself and
388 * the collection items.
389 *
390 * @param description The DESCRIBE document of the Collections describe()
391 * operation.
392 *
393 * @return a Collection with CollectionItems.
394 */
395 public static Collection parseCollection(Document description) {
396 logger.debug("CollectionHelper.parseCollection");
397
398 if (description == null) {
399 logger.warn("The DESCRIBE of the Collection is null!");
400 return null;
401 }
402
403 String uuid = XMLUtils.xpathString(
404 description,
405 "art:artifact-collection/@art:uuid",
406 ArtifactNamespaceContext.INSTANCE);
407
408 String ttlStr = XMLUtils.xpathString(
409 description,
410 "art:artifact-collection/@art:ttl",
411 ArtifactNamespaceContext.INSTANCE);
412
413 String name = XMLUtils.xpathString(
414 description,
415 "art:artifact-collection/@art:name",
416 ArtifactNamespaceContext.INSTANCE);
417
418 if (uuid.length() == 0) {
419 logger.warn("Found an invalid (zero length uuid) Collection!");
420 return null;
421 }
422
423 if (ttlStr.length() == 0) {
424 logger.warn("Found an invalid Collection (zero length ttl)!");
425 return null;
426 }
427
428
429 long ttl = -1;
430 try {
431 ttl = Long.valueOf(ttlStr);
432 }
433 catch (NumberFormatException nfe) {
434 // do nothing
435 }
436
437 List<Recommendation> recommended = parseRecommendations(description);
438 Map<String, CollectionItem> collectionItems =
439 new HashMap<String, CollectionItem>();
440
441 name = (name != null && name.length() > 0) ? name : uuid;
442
443 Collection c = new DefaultCollection(uuid, ttl, name, recommended);
444
445 NodeList items = (NodeList) XMLUtils.xpath(
446 description,
447 "art:artifact-collection/art:artifacts/art:artifact",
448 XPathConstants.NODESET,
449 ArtifactNamespaceContext.INSTANCE);
450
451 if (items == null || items.getLength() == 0) {
452 logger.debug("No collection item found for this collection.");
453
454 return c;
455 }
456
457 int size = items.getLength();
458
459 for (int i = 0; i < size; i++) {
460 CollectionItem item = parseCollectionItem(
461 (Element)items.item(i),
462 i == 0);
463
464 if (item != null) {
465 c.addItem(item);
466 collectionItems.put(item.identifier() ,item);
467 }
468 }
469
470 Map<String, ThemeList> themeLists = parseThemeLists(description, collectionItems);
471 c.setThemeLists(themeLists);
472
473 Map<String, Settings> outSettings = parseSettings(description);
474 c.setSettings(outSettings);
475 logger.debug(
476 "Found " + c.getItemLength() + " collection items " +
477 "for the Collection '" + c.identifier() + "'.");
478
479 return c;
480 }
481
482
483 /**
484 * @param collectionItems map to look up collection item mapping a themes
485 * (artifact) uuid.
486 */
487 protected static Map<String, ThemeList> parseThemeLists(
488 Document desc, Map<String, CollectionItem> collectionItems
489 ) {
490 logger.debug("CollectionHelper.parseThemeLists");
491
492 NodeList lists = (NodeList) XMLUtils.xpath(
493 desc,
494 "/art:artifact-collection/art:attribute/art:outputs/art:output",
495 XPathConstants.NODESET,
496 ArtifactNamespaceContext.INSTANCE);
497
498 int num = lists != null ? lists.getLength() : 0;
499
500 Map<String, ThemeList> themeList = new HashMap<String, ThemeList>(num);
501
502 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
503
504 for (int i = 0; i < num; i++) {
505 Element node = (Element)lists.item(i);
506
507 String outName = node.getAttribute("name");
508
509 if (outName.length() > 0) {
510 ThemeList list = parseThemeList(node, collectionItems);
511
512 if (list.getThemeCount() > 0) {
513 themeList.put(outName, list);
514 }
515 }
516 }
517
518 return themeList;
519 }
520
521
522 /**
523 * @param collectionItems map to look up collection item mapping a themes
524 * (artifact) uuid.
525 */
526 protected static ThemeList parseThemeList(
527 Element node, Map<String, CollectionItem> collectionItems
528 ) {
529 logger.debug("CollectionHelper.parseThemeList");
530
531 NodeList themes = node.getElementsByTagNameNS(
532 ArtifactNamespaceContext.NAMESPACE_URI,
533 "facet");
534
535 int num = themes != null ? themes.getLength() : 0;
536
537 List<Theme> themeList = new ArrayList<Theme>(num);
538
539 for (int i = 0; i < num; i++) {
540 Theme theme = parseTheme((Element)themes.item(i));
541 theme.setCollectionItem(collectionItems.get(theme.getArtifact()));
542
543 if (theme != null) {
544 themeList.add(theme);
545 }
546 }
547
548 return new ThemeList(themeList);
549 }
550
551
552 protected static Theme parseTheme(Element ele) {
553 logger.debug("CollectionHelper.parseTheme");
554
555 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
556
557 NamedNodeMap attrMap = ele.getAttributes();
558 int attrNum = attrMap != null ? attrMap.getLength() : 0;
559
560 AttributedTheme t = new AttributedTheme();
561
562 for (int i = 0; i < attrNum; i++) {
563 Node attr = attrMap.item(i);
564
565 String prefix = attr.getPrefix();
566 String name = attr.getNodeName().replace(prefix + ":", "");
567 String value = attr.getNodeValue();
568
569 t.addAttr(name, value);
570 }
571
572 return t;
573 }
574
575
576 /**
577 * Parse Settings elements.
578 *
579 * @param description The collection description.
580 *
581 * @return Map containing the settings.
582 */
583 protected static Map<String, Settings> parseSettings(Document description) {
584 logger.info("parseSettings");
585
586 NodeList lists = (NodeList) XMLUtils.xpath(
587 description,
588 "/art:artifact-collection/art:attribute/art:outputs/art:output",
589 XPathConstants.NODESET,
590 ArtifactNamespaceContext.INSTANCE);
591
592 int num = lists != null ? lists.getLength() : 0;
593
594 Map<String, Settings> list = new HashMap<String, Settings>(num);
595
596 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
597
598 for (int i = 0; i < num; i++) {
599 Element node = (Element)lists.item(i);
600 String outName = node.getAttribute("name");
601 Settings s = parseSettings(outName, node);
602 list.put(outName, s);
603 }
604
605 return list;
606 }
607
608
609 /**
610 * From a document, parse the settings for an output and create an
611 * OutputSettings object.
612 */
613 protected static Settings parseSettings(String outName, Element node) {
614 OutputSettings set = new OutputSettings(outName);
615
616 NodeList elements = node.getElementsByTagName("settings");
617
618 if (elements.getLength() == 0 || elements.getLength() > 1) {
619 return set;
620 }
621
622 Element settings = (Element)elements.item(0);
623
624 // Get the categories
625 NodeList catNodes = settings.getChildNodes();
626 for (int i = 0; i < catNodes.getLength(); i++) {
627 Element catNode = (Element)catNodes.item(i);
628
629 // The category name
630 String category = catNode.getTagName();
631
632 // list of properties or groups (groups have child nodes).
633 NodeList list = catNode.getChildNodes();
634
635 // iterate through all properties or groups.
636 List<Property> props = new ArrayList<Property> ();
637 for (int j = 0; j < list.getLength(); j++) {
638 Property p;
639 Element e = (Element)list.item(j);
640 if (e.hasChildNodes() &&
641 e.getFirstChild().getNodeType() != Node.TEXT_NODE) {
642 p = parseSettingsGroup(e);
643 }
644 else {
645 p = parseSetting(e);
646 }
647 props.add(p);
648 }
649 set.setSettings(category, props);
650 }
651 return set;
652 }
653
654
655 /**
656 *
657 */
658 protected static Property parseSettingsGroup(Element group) {
659 PropertyGroup p = new PropertyGroup();
660 p.setName(group.getTagName());
661
662 NodeList list = group.getChildNodes();
663 ArrayList<Property> props = new ArrayList<Property>();
664 for (int i = 0; i < list.getLength(); i++) {
665 props.add(parseSetting((Element)list.item(i)));
666 }
667 p.setProperties(props);
668 return p;
669 }
670
671
672 /**
673 * From a property element create a Property object.
674 */
675 protected static Property parseSetting(Element property){
676 NamedNodeMap attrMap = property.getAttributes();
677 int attrNum = attrMap != null ? attrMap.getLength() : 0;
678
679 Node type = attrMap.getNamedItem("type");
680 String t = type.getNodeValue();
681 PropertySetting ps = new PropertySetting();
682
683 if(t.equals("string")) {
684 ps = new StringProperty();
685 }
686 else if (t.equals("integer")) {
687 ps = new IntegerProperty();
688 }
689 else if (t.equals("double")) {
690 ps = new DoubleProperty();
691 }
692 else if (t.equals("boolean")) {
693 ps = new BooleanProperty();
694 }
695 ps.setName(property.getTagName());
696 ps.setValue(property.getTextContent());
697
698 for (int i = 0; i < attrNum; i++) {
699 Node attr = attrMap.item(i);
700
701 String name = attr.getNodeName();
702 String value = attr.getNodeValue();
703 if(name.equals("type")) {
704 continue;
705 }
706 ps.setAttribute(name, value);
707 }
708 return ps;
709 }
710
711
712 /**
713 * This method extracts the CollectionItem from <i>node</i> with its output
714 * modes. The output modes are parsed using the parseOutputModes() method.
715 *
716 * @param node A node that contains information about a CollectionItem.
717 *
718 * @return a CollectionItem.
719 */
720 protected static CollectionItem parseCollectionItem(
721 Element node,
722 boolean outs
723 ) {
724 logger.debug("CollectionHelper.parseCollectionItem");
725
726 if (node == null) {
727 logger.debug("The node for parsing CollectionItem is null!");
728 return null;
729 }
730
731 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
732
733 String uuid = node.getAttributeNS(uri, "uuid");
734 String hash = node.getAttributeNS(uri, "hash");
735
736 if (uuid == null || uuid.length() == 0) {
737 logger.warn("Found an invalid CollectionItem!");
738 return null;
739 }
740
741 List<OutputMode> modes = new ArrayList<OutputMode>();
742
743 if (outs) {
744 NodeList outputmodes = node.getElementsByTagNameNS(
745 uri, "outputmodes");
746
747 if (outputmodes.getLength() < 1) {
748 return null;
749 }
750
751 Element om = (Element)outputmodes.item(0);
752
753 modes = parseOutputModes(om);
754 }
755
756 HashMap<String, String> dataItems = new HashMap<String, String>();
757
758 NodeList dataItemNodes = node.getElementsByTagNameNS(
759 uri, "data-items");
760
761 Element di = (Element)dataItemNodes.item(0);
762 dataItems = parseDataItems(di);
763
764 return new DefaultCollectionItem(uuid, hash, modes, dataItems);
765 }
766
767
768 /**
769 * This method extracts the OutputModes available for a specific
770 * CollectionItem and returns them as list.
771 *
772 * @param node The root node of the outputmodes list.
773 *
774 * @return a list of OutputModes.
775 */
776 protected static List<OutputMode> parseOutputModes(Element node) {
777 logger.debug("CollectionHelper.parseOutputModes");
778
779 if (node == null) {
780 logger.debug("The node for parsing OutputModes is null!");
781 return null;
782 }
783
784 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
785
786 NodeList list = node.getElementsByTagNameNS(uri, "output");
787
788 int size = list.getLength();
789
790 if (size == 0) {
791 logger.debug("No outputmode nodes found!");
792 return null;
793 }
794
795 List<OutputMode> modes = new ArrayList<OutputMode>(size);
796
797 for (int i = 0; i < size; i++) {
798 Element tmp = (Element)list.item(i);
799
800 String name = tmp.getAttributeNS(uri, "name");
801 String desc = tmp.getAttributeNS(uri, "description");
802 String mime = tmp.getAttributeNS(uri, "mime-type");
803 String type = tmp.getAttributeNS(uri, "type");
804
805 if (name.length() == 0) {
806 logger.warn("Found an invalid output mode.");
807 continue;
808 }
809
810 OutputMode outmode = null;
811 List<Facet> fs = extractFacets(tmp);
812
813 if (type.equals("export")) {
814 outmode = new ExportMode(name, desc, mime, fs);
815 }
816 else if (type.equals("report")) {
817 outmode = new ReportMode(name, desc, mime, fs);
818 }
819 else if (type.equals("chart")){
820 outmode = new ChartMode(name, desc, mime, fs, type);
821 }
822 else if (type.equals("map")){
823 outmode = new MapMode(name, desc, mime, fs);
824 }
825 else if (type.equals("overview")) {
826 outmode = new OverviewMode(name, desc, mime, fs, type);
827 }
828 else {
829 logger.warn("Broken Output mode without type found.");
830 continue;
831 }
832
833 modes.add(outmode);
834 }
835
836 return modes;
837 }
838
839
840 /**
841 * Create a Key/Value map for data nodes of artifact/collectionitem.
842 */
843 protected static HashMap<String, String> parseDataItems(Element node) {
844 logger.debug("CollectionHelper.parseDataItems");
845
846 if (node == null) {
847 logger.debug("The node for parsing DataItems is null!");
848 return null;
849 }
850
851 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
852
853 NodeList list = node.getElementsByTagNameNS(uri, "data");
854
855 int size = list.getLength();
856
857 if (size == 0) {
858 logger.debug("No static data-item nodes found!");
859 }
860
861 HashMap<String, String> data = new HashMap<String, String>(size*2);
862
863 for (int i = 0; i < size; i++) {
864 Element tmp = (Element)list.item(i);
865
866 String key = tmp.getAttributeNS(uri, "name");
867
868 if (key.length() == 0) {
869 logger.warn("Found an invalid data item mode.");
870 continue;
871 }
872
873 // XXX We are restricted on 1/1 key/values in the data map here.
874 NodeList valueNodes = tmp.getElementsByTagName("art:item");
875
876 Element item = (Element) valueNodes.item(0);
877 String value = item.getAttributeNS(uri, "value");
878 logger.debug("Found a data item " + key + " : " + value);
879
880 data.put(key, value);
881 }
882
883
884 // Dynamic data.
885 list = node.getElementsByTagNameNS(uri, "select");
886
887 size = list.getLength();
888
889 if (size == 0) {
890 logger.debug("No dynamic data-item nodes found!");
891 }
892
893 for (int i = 0; i < size; i++) {
894 Element tmp = (Element)list.item(i);
895
896 String key = tmp.getAttributeNS(uri, "name");
897
898 if (key.length() == 0) {
899 logger.warn("Found an invalid data item node (missing key).");
900 continue;
901 }
902
903 String value = tmp.getAttributeNS(uri, "defaultValue");
904
905 if (value.length() == 0) {
906 logger.warn("Found an invalid data item node (missing value).");
907 continue;
908 }
909
910 logger.debug("Found a (dyn) data item " + key + " : " + value);
911
912 data.put(key, value);
913 }
914
915 return data;
916 }
917
918 protected static List<Facet> extractFacets(Element outmode) {
919 logger.debug("CollectionHelper - extractFacets()");
920
921 NodeList facetList = (NodeList) XMLUtils.xpath(
922 outmode,
923 XPATH_FACETS,
924 XPathConstants.NODESET,
925 ArtifactNamespaceContext.INSTANCE);
926
927 int num = facetList != null ? facetList.getLength() : 0;
928
929 List<Facet> facets = new ArrayList<Facet>(num);
930
931 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
932
933 for (int i = 0; i < num; i++) {
934 Element facetEl = (Element) facetList.item(i);
935
936 String name = facetEl.getAttributeNS(uri, "name");
937 String desc = facetEl.getAttributeNS(uri, "description");
938 String index = facetEl.getAttributeNS(uri, "index");
939
940 if (name != null && name.length() > 0 && index != null) {
941 facets.add(new DefaultFacet(name, Integer.valueOf(index),desc));
942 }
943 }
944
945 return facets;
946 }
947
948
949 public static List<Recommendation> parseRecommendations(Document doc) {
950 logger.debug("CollectionHelper.parseRecommendations");
951
952 NodeList list = (NodeList) XMLUtils.xpath(
953 doc,
954 XPATH_LOADED_RECOMMENDATIONS,
955 XPathConstants.NODESET,
956 ArtifactNamespaceContext.INSTANCE);
957
958 int num = list != null ? list.getLength() : 0;
959
960 List<Recommendation> recs = new ArrayList<Recommendation>(num);
961
962 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
963
964 for (int i = 0; i < num; i++) {
965 Element rec = (Element) list.item(i);
966
967 String factory = rec.getAttributeNS(uri, "factory");
968 String dbids = rec.getAttributeNS(uri, "ids");
969
970 if (factory != null && factory.length() > 0) {
971 recs.add(new Recommendation(factory, dbids));
972 }
973 }
974
975 return recs;
976 }
977
978
979 /**
980 * Add an artifact to a collection.
981 * @param collection Collection to add artifact to.
982 * @param artifact Artifact to add to collection
983 */
984 public static Collection addArtifact(
985 Collection collection,
986 Artifact artifact,
987 String url,
988 String locale)
989 throws ServerException
990 {
991 logger.debug("CollectionHelper.addArtifact");
992
993 if (collection == null) {
994 logger.warn("The given Collection is null!");
995 return null;
996 }
997
998 Document add = ClientProtocolUtils.newAddArtifactDocument(
999 artifact.getUuid(), null);
1000
1001 HttpClient client = new HttpClientImpl(url, locale);
1002
1003 try {
1004 logger.debug("Do HTTP request now.");
1005
1006 Document response = (Document) client.doCollectionAction(
1007 add, collection.identifier(), new DocumentResponseHandler());
1008
1009 logger.debug(
1010 "Finished HTTP request successfully. Parse Collection now.");
1011
1012 Collection c = CollectionHelper.parseCollection(response);
1013
1014 if (c == null) {
1015 throw new ServerException(ERROR_ADD_ARTIFACT);
1016 }
1017
1018 return c;
1019 }
1020 catch (ConnectionException ce) {
1021 logger.error(ce, ce);
1022 }
1023 catch (Exception e) {
1024 logger.error(e, e);
1025 }
1026
1027 throw new ServerException(ERROR_ADD_ARTIFACT);
1028 }
1029
1030
1031 /**
1032 * Remove an artifact from a collection.
1033 * @param collection Collection to remove artifact to.
1034 * @param artifact Artifact to add to collection
1035 */
1036 public static Collection removeArtifact(
1037 Collection collection,
1038 String artifactId,
1039 String url,
1040 String locale)
1041 throws ServerException
1042 {
1043 logger.debug("CollectionHelper.removeArtifact");
1044
1045 if (collection == null) {
1046 logger.warn("The given Collection is null!");
1047 return null;
1048 }
1049
1050 Document remove = ClientProtocolUtils.newRemoveArtifactDocument(
1051 artifactId);
1052
1053 HttpClient client = new HttpClientImpl(url, locale);
1054
1055 try {
1056 logger.debug("Do HTTP request now.");
1057
1058 Document response = (Document) client.doCollectionAction(
1059 remove, collection.identifier(), new DocumentResponseHandler());
1060
1061 logger.debug(
1062 "Finished HTTP request successfully. Parse Collection now.");
1063 logger.debug(XMLUtils.toString(response));
1064
1065 Collection c = CollectionHelper.parseCollection(response);
1066
1067 if (c == null) {
1068 throw new ServerException(ERROR_REMOVE_ARTIFACT);
1069 }
1070
1071 return c;
1072 }
1073 catch (ConnectionException ce) {
1074 logger.error(ce, ce);
1075 }
1076 catch (Exception e) {
1077 logger.error(e, e);
1078 }
1079 throw new ServerException(ERROR_REMOVE_ARTIFACT);
1080 }
1081 }
1082 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org