comparison flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java @ 3812:f788d2d901d6

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

http://dive4elements.wald.intevation.org