Mercurial > dive4elements > river
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 : |