comparison flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java @ 3806:881fcd01e056

merged flys-artifacts/pre2.6-2011-11-04
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:50 +0200
parents 9562ca537143
children 0585bf8af41b
comparison
equal deleted inserted replaced
3802:e831dc29e572 3806:881fcd01e056
1 package de.intevation.flys.collections;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.util.ArrayList;
6 import java.util.Date;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.xml.xpath.XPathConstants;
12
13 import org.apache.log4j.Logger;
14
15 import org.w3c.dom.Document;
16 import org.w3c.dom.Element;
17 import org.w3c.dom.Node;
18 import org.w3c.dom.NodeList;
19
20 import de.intevation.artifacts.Artifact;
21 import de.intevation.artifacts.ArtifactDatabase;
22 import de.intevation.artifacts.ArtifactDatabaseException;
23 import de.intevation.artifacts.ArtifactNamespaceContext;
24 import de.intevation.artifacts.CallContext;
25 import de.intevation.artifacts.CallMeta;
26
27 import de.intevation.artifacts.common.utils.ClientProtocolUtils;
28 import de.intevation.artifacts.common.utils.XMLUtils;
29
30 import de.intevation.artifactdatabase.Backend;
31 import de.intevation.artifactdatabase.Backend.PersistentArtifact;
32 import de.intevation.artifactdatabase.DefaultArtifactCollection;
33 import de.intevation.artifactdatabase.state.StateEngine;
34
35 import de.intevation.flys.artifacts.context.FLYSContext;
36 import de.intevation.flys.artifacts.FLYSArtifact;
37 import de.intevation.flys.artifacts.model.ManagedFacet;
38 import de.intevation.flys.artifacts.model.ManagedDomFacet;
39 import de.intevation.flys.exports.OutGenerator;
40 import de.intevation.flys.themes.Theme;
41 import de.intevation.flys.themes.ThemeFactory;
42
43 import de.intevation.flys.utils.FLYSUtils;
44
45 /**
46 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
47 */
48 public class FLYSArtifactCollection extends DefaultArtifactCollection {
49
50 /** The logger used in this class. */
51 private static Logger log = Logger.getLogger(FLYSArtifactCollection.class);
52
53 /** Constant XPath that points to the outputmodes of an artifact. */
54 public static final String XPATH_ARTIFACT_OUTPUTMODES =
55 "/art:result/art:outputmodes";
56
57 public static final String XPATH_COLLECTION_ITEMS =
58 "/art:result/art:artifact-collection/art:collection-item";
59
60 public static final String XPATH_OUT_NAME = "/art:action/@art:name";
61
62 public static final String XPATH_OUT_TYPE = "/art:action/@art:type";
63
64 /** Xpath to master artifacts uuid. */
65 public static final String XPATH_MASTER_UUID =
66 "/art:artifact-collection/art:artifact/@art:uuid";
67
68 public static final String XPATH_LOADED_RECOMMENDATIONS =
69 "/art:attribute/art:loaded-recommendations";
70
71
72 /**
73 * Return description Document for this collection.
74 */
75 @Override
76 public Document describe(CallContext context) {
77 log.debug("FLYSArtifactCollection.describe: " + identifier);
78
79 Document doc = XMLUtils.newDocument();
80
81 XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
82 doc,
83 ArtifactNamespaceContext.NAMESPACE_URI,
84 ArtifactNamespaceContext.NAMESPACE_PREFIX);
85
86 Date creationTime = getCreationTime();
87 String creation = creationTime != null
88 ? Long.toString(creationTime.getTime())
89 : "";
90
91 Element collection = ec.create("artifact-collection");
92 Element artifacts = ec.create("artifacts");
93
94 ec.addAttr(collection, "name", getName(), true);
95 ec.addAttr(collection, "uuid", identifier(), true);
96 ec.addAttr(collection, "creation", creation, true);
97 ec.addAttr(collection, "ttl", String.valueOf(getTTL()), true);
98
99 collection.appendChild(artifacts);
100 doc.appendChild(collection);
101
102 ArtifactDatabase db = context.getDatabase();
103 Document oldAttrs = getAttribute();
104
105 try {
106 String[] aUUIDs = getArtifactUUIDs(context);
107 Node newAttr = mergeAttributes(db, context, oldAttrs, aUUIDs);
108
109 collection.appendChild(doc.importNode(newAttr, true));
110
111 // Make it an empty array if null.
112 if (aUUIDs == null) {
113 aUUIDs = new String[] {};
114 }
115
116 for (String uuid: aUUIDs) {
117 try {
118 artifacts.appendChild(
119 buildArtifactNode(db, uuid, context, ec));
120 }
121 catch (ArtifactDatabaseException dbe) {
122 log.warn(dbe, dbe);
123 }
124 }
125 }
126 catch (ArtifactDatabaseException ade) {
127 log.error(ade, ade);
128
129 collection.appendChild(
130 doc.importNode(oldAttrs.getFirstChild(), true));
131 }
132
133 return doc;
134 }
135
136
137 /**
138 * Merge the current art:outputs nodes with the the outputs provided by the
139 * artifacts in the Collection.
140 *
141 * @param uuids Artifact uuids.
142 */
143 protected Node mergeAttributes(
144 ArtifactDatabase db,
145 CallContext context,
146 Document oldAttrs,
147 String[] uuids)
148 {
149 Document doc = buildOutAttributes(db, context, oldAttrs, uuids);
150 Node newAttr = doc.getFirstChild();
151
152 newAttr = mergeLoadedRecommendations(oldAttrs, newAttr);
153
154 try {
155 // Save the merged document into database.
156 db.setCollectionAttribute(identifier(), context.getMeta(), doc);
157 }
158 catch (ArtifactDatabaseException adb) {
159 log.error(adb, adb);
160 }
161
162 return newAttr;
163 }
164
165
166 /**
167 * Merge the recommendations which have already been loaded from the old
168 * attribute document into the new attribute document. This is necessary,
169 * because mergeAttributes() only merges the art:outputs nodes - all
170 * other nodes are skiped.
171 */
172 protected Node mergeLoadedRecommendations(Document oldAttrs, Node newAttrs){
173 Element loadedRecoms = (Element) XMLUtils.xpath(
174 oldAttrs,
175 XPATH_LOADED_RECOMMENDATIONS,
176 XPathConstants.NODE,
177 ArtifactNamespaceContext.INSTANCE);
178
179 if (loadedRecoms != null) {
180 Document doc = newAttrs.getOwnerDocument();
181 newAttrs.appendChild(doc.importNode(loadedRecoms, true));
182 }
183
184 return newAttrs;
185 }
186
187
188 @Override
189 public void out(
190 String type,
191 Document format,
192 OutputStream out,
193 CallContext context)
194 throws IOException
195 {
196 log.info("FLYSArtifactCollection.out");
197
198 String name = XMLUtils.xpathString(
199 format, XPATH_OUT_NAME, ArtifactNamespaceContext.INSTANCE);
200
201 String subtype = XMLUtils.xpathString(
202 format, XPATH_OUT_TYPE, ArtifactNamespaceContext.INSTANCE);
203
204 log.info("-> Output name = " + name);
205 log.info("-> Output type = " + type);
206 log.info("-> Output subtype = " + subtype);
207
208 OutGenerator generator = null;
209 if (type != null
210 && type.length() > 0
211 && type.indexOf("chartinfo") > 0)
212 {
213 generator = getOutGenerator(context, type, subtype);
214 }
215 else {
216 generator = getOutGenerator(context, name, subtype);
217 }
218
219 if (generator == null) {
220 log.error("There is no generator specified for output: " + name);
221 // TODO Throw an exception.
222
223 return;
224 }
225
226 generator.init(format, out, context);
227
228 // Get master artifact.
229 FLYSArtifact master = getMasterArtifact(context);
230 if (master != null) {
231 log.debug("Will set master Artifact to uuid: " + master.identifier());
232 generator.setMasterArtifact(master);
233 }
234 else {
235 log.warn("Could not set master artifact.");
236 }
237
238 try {
239 Document attr = getAttribute(context, name);
240 doOut(generator, name, subtype, attr, context);
241 }
242 catch (ArtifactDatabaseException adbe) {
243 log.error(adbe, adbe);
244 }
245 }
246
247
248 /**
249 * Creates the concrete output.
250 *
251 * @param generator The OutGenerator that creates the output.
252 * @param outputName The name of the requested output.
253 * @param attributes The collection's attributes for this concrete output
254 * type.
255 * @param context The context object.
256 */
257 protected void doOut(
258 OutGenerator generator,
259 String outName,
260 String facet,
261 Document attributes,
262 CallContext context)
263 throws IOException
264 {
265 log.info("FLYSArtifactCollection.doOut: " + outName);
266
267 ThemeList themeList = new ThemeList(attributes);
268
269 int size = themeList.size();
270 log.debug("Output will contain " + size + " elements.");
271
272 try {
273 for (int i = 0; i < size; i++) {
274 ManagedFacet theme = themeList.get(i);
275
276 if (theme == null) {
277 log.debug("Theme is empty - no output is generated.");
278 continue;
279 }
280
281 String art = theme.getArtifact();
282
283 if (log.isDebugEnabled()) {
284 log.debug("Do output for...");
285 log.debug("... artifact: " + art);
286 log.debug("... facet: " + theme.getName());
287 }
288
289 String facetName = theme.getName();
290
291 if (outName.equals("export") && !facetName.equals(facet)) {
292 continue;
293 }
294
295 Artifact artifact = getArtifact(art, context);
296
297 generator.doOut(
298 artifact,
299 theme,
300 getFacetThemeFromAttribute(
301 art,
302 outName,
303 facetName,
304 theme.getDescription(),
305 theme.getIndex(),
306 context),
307 theme.getActive() == 1);
308 }
309 }
310 catch (ArtifactDatabaseException ade) {
311 log.error(ade, ade);
312 }
313
314 generator.generate();
315 }
316
317
318 /**
319 * @return masterartifact or null if exception/not found.
320 */
321 protected FLYSArtifact getMasterArtifact(CallContext context)
322 {
323 try {
324 ArtifactDatabase db = context.getDatabase();
325 CallMeta callMeta = context.getMeta();
326 Document document = db.getCollectionsMasterArtifact(
327 identifier(), callMeta);
328
329 String masterUUID = XMLUtils.xpathString(
330 document, XPATH_MASTER_UUID, ArtifactNamespaceContext.INSTANCE);
331 FLYSArtifact masterArtifact =
332 (FLYSArtifact) getArtifact(masterUUID, context);
333 return masterArtifact;
334 }
335 catch (ArtifactDatabaseException ade) {
336 log.error(ade, ade);
337 }
338 return null;
339 }
340
341
342 /**
343 * Return merged output document.
344 * @param uuids List of artifact uuids.
345 */
346 protected Document buildOutAttributes(
347 ArtifactDatabase db,
348 CallContext context,
349 Document oldAttr,
350 String[] uuids)
351 {
352 Document doc = XMLUtils.newDocument();
353
354 FLYSContext flysContext = FLYSUtils.getFlysContext(context);
355 StateEngine engine = (StateEngine) flysContext.get(
356 FLYSContext.STATE_ENGINE_KEY);
357
358 FLYSArtifact masterArtifact = getMasterArtifact(context);
359
360 XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
361 doc,
362 ArtifactNamespaceContext.NAMESPACE_URI,
363 ArtifactNamespaceContext.NAMESPACE_PREFIX);
364
365 AttributeParser aParser = new AttributeParser();
366 OutputParser oParser = new OutputParser(db, context);
367
368 if (uuids != null) {
369 for (String uuid: uuids) {
370 try {
371 oParser.parse(uuid);
372 }
373 catch (ArtifactDatabaseException ade) {
374 log.warn(ade, ade);
375 }
376 }
377 }
378
379 aParser.parse(oldAttr);
380
381 return new AttributeWriter(
382 db,
383 aParser.getOuts(),
384 aParser.getFacets(),
385 oParser.getOuts(),
386 oParser.getFacets(),
387 engine.getCompatibleFacets(masterArtifact.getStateHistoryIds())
388 ).write();
389 }
390
391
392 /**
393 * Returns the "attribute" (part of description document) for a specific
394 * output type.
395 *
396 * @param output The name of the desired output type.
397 *
398 * @return the attribute for the desired output type.
399 */
400 protected Document getAttribute(CallContext context, String output)
401 throws ArtifactDatabaseException
402 {
403 Document attr = buildOutAttributes(
404 context.getDatabase(),
405 context,
406 getAttribute(),
407 getArtifactUUIDs(context));
408
409 Node out = (Node) XMLUtils.xpath(
410 attr,
411 "art:attribute/art:outputs/art:output[@name='" + output + "']",
412 XPathConstants.NODE,
413 ArtifactNamespaceContext.INSTANCE);
414
415
416 if (out != null) {
417 Document o = XMLUtils.newDocument();
418
419 o.appendChild(o.importNode(out, true));
420
421 return o;
422 }
423
424 return null;
425 }
426
427
428 /**
429 * This method returns the list of artifact UUIDs that this collections
430 * contains.
431 *
432 * @param context The CallContext that is necessary to get information about
433 * the ArtifactDatabase.
434 *
435 * @return a list of uuids.
436 */
437 protected String[] getArtifactUUIDs(CallContext context)
438 throws ArtifactDatabaseException
439 {
440 log.debug("FLYSArtifactCollection.getArtifactUUIDs");
441
442 ArtifactDatabase db = context.getDatabase();
443 CallMeta meta = context.getMeta();
444
445 Document itemList = db.listCollectionArtifacts(identifier(), meta);
446 NodeList items = (NodeList) XMLUtils.xpath(
447 itemList,
448 XPATH_COLLECTION_ITEMS,
449 XPathConstants.NODESET,
450 ArtifactNamespaceContext.INSTANCE);
451
452 if (items == null || items.getLength() == 0) {
453 log.debug("No artifacts found in this collection.");
454 return null;
455 }
456
457 int num = items.getLength();
458
459 List<String> uuids = new ArrayList<String>(num);
460
461 for (int i = 0; i < num; i++) {
462 String uuid = XMLUtils.xpathString(
463 items.item(i),
464 "@art:uuid",
465 ArtifactNamespaceContext.INSTANCE);
466
467 if (uuid != null && uuid.trim().length() != 0) {
468 uuids.add(uuid);
469 }
470 }
471
472 return (String[]) uuids.toArray(new String[uuids.size()]);
473 }
474
475
476 /**
477 * Returns a concrete Artifact of this collection specified by its uuid.
478 *
479 * @param uuid The Artifact's uuid.
480 * @param context The CallContext.
481 *
482 * @return an Artifact.
483 */
484 protected Artifact getArtifact(String uuid, CallContext context)
485 throws ArtifactDatabaseException
486 {
487 log.debug("FLYSArtifactCollection.getArtifact");
488
489 Backend backend = Backend.getInstance();
490 PersistentArtifact persistent = backend.getArtifact(uuid);
491
492 return persistent != null ? persistent.getArtifact() : null;
493 }
494
495
496 /**
497 * Returns the attribute that belongs to an artifact and facet stored in
498 * this collection.
499 *
500 * @param uuid The Artifact's uuid.
501 * @param outname The name of the requested output.
502 * @param facet The name of the requested facet.
503 * @param context The CallContext.
504 *
505 * @return an attribute in form of a document.
506 */
507 protected Document getFacetThemeFromAttribute(
508 String uuid,
509 String outName,
510 String facet,
511 String pattern,
512 int index,
513 CallContext context)
514 throws ArtifactDatabaseException
515 {
516 log.debug("FLYSArtifactCollection.getFacetThemeFromAttribute");
517
518 ArtifactDatabase db = context.getDatabase();
519 CallMeta meta = context.getMeta();
520
521 FLYSContext flysContext = context instanceof FLYSContext
522 ? (FLYSContext) context
523 : (FLYSContext) context.globalContext();
524
525 Document attr = db.getCollectionItemAttribute(identifier(), uuid, meta);
526
527 if (attr == null) {
528 attr = initItemAttribute(uuid, facet, pattern, index, outName, context);
529
530 if (attr == null) {
531 return null;
532 }
533 }
534
535 log.debug("Search attribute of collection item: " + uuid);
536
537 Node tmp = (Node) XMLUtils.xpath(
538 attr,
539 "/art:attribute",
540 XPathConstants.NODE,
541 ArtifactNamespaceContext.INSTANCE);
542
543 if (tmp == null) {
544 log.warn("No attribute found. Operation failed.");
545 return null;
546 }
547
548 log.debug("Search theme for facet '" + facet + "' in attribute.");
549
550 Node theme = (Node) XMLUtils.xpath(
551 tmp,
552 "art:themes/theme[@facet='" + facet +
553 "' and @index='" + String.valueOf(index) + "']",
554 XPathConstants.NODE,
555 ArtifactNamespaceContext.INSTANCE);
556
557 if (theme == null) {
558 log.warn("Could not find the theme in attribute of: " + uuid);
559
560 Theme t = getThemeForFacet(
561 uuid, facet, pattern, index, outName, context);
562
563 if (t == null) {
564 log.warn("No theme found for facet: " + facet);
565 return null;
566 }
567
568 addThemeToAttribute(uuid, attr, t, context);
569 theme = t.toXML().getFirstChild();
570 }
571
572 Document doc = XMLUtils.newDocument();
573 doc.appendChild(doc.importNode(theme, true));
574
575 return doc;
576 }
577
578
579 /**
580 * Adds the theme of a facet to a CollectionItem's attribute.
581 *
582 * @param uuid The uuid of the artifact.
583 * @param attr The current attribute of an artifact.
584 * @param t The theme to add.
585 * @param context The CallContext.
586 */
587 protected void addThemeToAttribute(
588 String uuid,
589 Document attr,
590 Theme t,
591 CallContext context)
592 {
593 log.debug("FLYSArtifactCollection.addThemeToAttribute: " + uuid);
594
595 if (t == null) {
596 log.warn("Theme is empty - cancel adding it to attribute!");
597 return;
598 }
599
600 XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
601 attr,
602 ArtifactNamespaceContext.NAMESPACE_URI,
603 ArtifactNamespaceContext.NAMESPACE_PREFIX);
604
605 Node tmp = (Node) XMLUtils.xpath(
606 attr,
607 "/art:attribute",
608 XPathConstants.NODE,
609 ArtifactNamespaceContext.INSTANCE);
610
611 if (tmp == null) {
612 tmp = ec.create("attribute");
613 attr.appendChild(tmp);
614 }
615
616 Node themes = (Node) XMLUtils.xpath(
617 tmp,
618 "art:themes",
619 XPathConstants.NODE,
620 ArtifactNamespaceContext.INSTANCE);
621
622 if (themes == null) {
623 themes = ec.create("themes");
624 tmp.appendChild(themes);
625 }
626
627 themes.appendChild(attr.importNode(t.toXML().getFirstChild(), true));
628
629 try {
630 setCollectionItemAttribute(uuid, attr, context);
631
632 log.debug("Successfully added theme to item attribute.");
633 }
634 catch (ArtifactDatabaseException e) {
635 // do nothing
636 log.warn("Cannot set attribute of item: " + uuid);
637 }
638 }
639
640
641 /**
642 * Initializes the attribute of an collection item with the theme of a
643 * specific facet.
644 *
645 * @param uuid The uuid of an artifact.
646 * @param facet The name of a facet.
647 * @param context The CallContext.
648 *
649 * @param the new attribute.
650 */
651 protected Document initItemAttribute(
652 String uuid,
653 String facet,
654 String pattern,
655 int index,
656 String outName,
657 CallContext context)
658 {
659 log.info("FLYSArtifactCollection.initItemAttribute");
660
661 Theme t = getThemeForFacet(uuid, facet, pattern, index, outName, context);
662
663 if (t == null) {
664 log.info("Could not find theme for facet. Cancel initialization.");
665 return null;
666 }
667
668 Document attr = XMLUtils.newDocument();
669
670 addThemeToAttribute(uuid, attr, t, context);
671
672 return attr;
673 }
674
675
676 /**
677 * Sets the attribute of a CollectionItem specified by <i>uuid</i> to a new
678 * value <i>attr</i>.
679 *
680 * @param uuid The uuid of the CollectionItem.
681 * @param attr The new attribute for the CollectionItem.
682 * @param context The CallContext.
683 */
684 public void setCollectionItemAttribute(
685 String uuid,
686 Document attr,
687 CallContext context)
688 throws ArtifactDatabaseException
689 {
690 Document doc = ClientProtocolUtils.newSetItemAttributeDocument(
691 uuid,
692 attr);
693
694 if (doc == null) {
695 log.warn("Cannot set item attribute: No attribute found.");
696 return;
697 }
698
699 ArtifactDatabase db = context.getDatabase();
700 CallMeta meta = context.getMeta();
701
702 db.setCollectionItemAttribute(identifier(), uuid, doc, meta);
703 }
704
705
706 /**
707 * Returns the theme of a specific facet.
708 *
709 * @param uuid The uuid of an artifact.
710 * @param facet The name of the facet.
711 * @param context The CallContext object.
712 *
713 * @return the desired theme.
714 */
715 protected Theme getThemeForFacet(
716 String uuid,
717 String facet,
718 String pattern,
719 int index,
720 String outName,
721 CallContext context)
722 {
723 log.info("FLYSArtifactCollection.getThemeForFacet: " + facet);
724
725 FLYSContext flysContext = context instanceof FLYSContext
726 ? (FLYSContext) context
727 : (FLYSContext) context.globalContext();
728
729 // Push artifact in flysContext.
730 ArtifactDatabase db = context.getDatabase();
731 try {
732 FLYSArtifact artifact = (FLYSArtifact) db.getRawArtifact(uuid);
733 log.debug("Got raw artifact");
734 flysContext.put(flysContext.ARTIFACT_KEY, artifact);
735 }
736 catch (Exception e) {
737 log.error("Exception caught when trying to get art.", e);
738 }
739
740 Theme t = ThemeFactory.getTheme(flysContext, facet, pattern, outName);
741
742 if (t != null) {
743 t.setFacet(facet);
744 t.setIndex(index);
745 }
746
747 return t;
748 }
749
750
751 /**
752 * Returns the OutGenerator for a specified <i>type</i>.
753 *
754 * @param name The name of the output type.
755 * @param type Defines the type of the desired OutGenerator.
756 *
757 * @return Instance of an OutGenerator for specified <i>type</i>.
758 */
759 protected OutGenerator getOutGenerator(
760 CallContext context,
761 String name,
762 String type)
763 {
764 FLYSContext flysContext = context instanceof FLYSContext
765 ? (FLYSContext) context
766 : (FLYSContext) context.globalContext();
767
768 Map<String, Class> generators = (Map<String, Class>)
769 flysContext.get(FLYSContext.OUTGENERATORS_KEY);
770
771 if (generators == null) {
772 log.error("No output generators found in the running application!");
773 return null;
774 }
775
776 Class clazz = generators.get(name);
777
778 try {
779 return clazz != null ? (OutGenerator) clazz.newInstance() : null;
780 }
781 catch (InstantiationException ie) {
782 log.error(ie, ie);
783 }
784 catch (IllegalAccessException iae) {
785 log.error(iae, iae);
786 }
787
788 return null;
789 }
790
791
792 protected Element buildArtifactNode(
793 ArtifactDatabase database,
794 String uuid,
795 CallContext context,
796 XMLUtils.ElementCreator ec)
797 throws ArtifactDatabaseException
798 {
799 log.debug("Append artifact '" + uuid + "' to collection description");
800
801 // TODO
802 String hash = "MYHASH";
803
804 Element ci = ec.create("artifact");
805 ec.addAttr(ci, "uuid", uuid, true);
806 ec.addAttr(ci, "hash", hash, true);
807
808 // XXX I am not sure if it works well every time with an empty document
809 // in the describe operation of an artifact.
810 Document description = database.describe(uuid, null, context.getMeta());
811
812 Node outputModes = (Node) XMLUtils.xpath(
813 description,
814 XPATH_ARTIFACT_OUTPUTMODES,
815 XPathConstants.NODE,
816 ArtifactNamespaceContext.INSTANCE);
817
818 if (outputModes != null) {
819 Document doc = ci.getOwnerDocument();
820 ci.appendChild(doc.importNode(outputModes, true));
821 }
822
823 return ci;
824 }
825
826
827 /**
828 * Inner class to structure/order the themes of a chart.
829 */
830 private static class ThemeList {
831 private Logger logger = Logger.getLogger(ThemeList.class);
832 protected Map<Integer, ManagedFacet> themes;
833
834 public ThemeList(Document output) {
835 themes = new HashMap<Integer, ManagedFacet>();
836 parse(output);
837 }
838
839 protected void parse(Document output) {
840 NodeList themeList = (NodeList) XMLUtils.xpath(
841 output,
842 "art:output/art:facet",
843 XPathConstants.NODESET,
844 ArtifactNamespaceContext.INSTANCE);
845
846 int num = themeList != null ? themeList.getLength() : 0;
847
848 logger.debug("Output has " + num + " elements.");
849
850 if (num == 0) {
851 return;
852 }
853
854 String uri = ArtifactNamespaceContext.NAMESPACE_URI;
855
856 for (int i = 0; i < num; i++) {
857 Element theme = (Element) themeList.item(i);
858
859 ManagedDomFacet facet = new ManagedDomFacet(theme);
860 themes.put(Integer.valueOf(facet.getPosition()-1), facet);
861 }
862 }
863
864 public ManagedFacet get(int idx) {
865 return themes.get(Integer.valueOf(idx));
866 }
867
868 public int size() {
869 return themes.size();
870 }
871 }
872 }
873 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org