Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java @ 3295:4fc442f1b4f6
Refactored FLYSArtifactCollection.
flys-artifacts/trunk@4976 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Raimund Renkert <raimund.renkert@intevation.de> |
---|---|
date | Fri, 13 Jul 2012 09:33:16 +0000 |
parents | 68320805566a |
children | b92e86a78895 |
comparison
equal
deleted
inserted
replaced
3294:5e52202302e5 | 3295:4fc442f1b4f6 |
---|---|
28 import de.intevation.artifacts.common.utils.XMLUtils; | 28 import de.intevation.artifacts.common.utils.XMLUtils; |
29 | 29 |
30 import de.intevation.artifactdatabase.Backend; | 30 import de.intevation.artifactdatabase.Backend; |
31 import de.intevation.artifactdatabase.Backend.PersistentArtifact; | 31 import de.intevation.artifactdatabase.Backend.PersistentArtifact; |
32 import de.intevation.artifactdatabase.DefaultArtifactCollection; | 32 import de.intevation.artifactdatabase.DefaultArtifactCollection; |
33 import de.intevation.artifactdatabase.state.ArtifactAndFacet; | |
34 import de.intevation.artifactdatabase.state.Output; | 33 import de.intevation.artifactdatabase.state.Output; |
35 import de.intevation.artifactdatabase.state.Settings; | 34 import de.intevation.artifactdatabase.state.Settings; |
36 import de.intevation.artifactdatabase.state.StateEngine; | 35 import de.intevation.artifactdatabase.state.StateEngine; |
37 | 36 |
38 import de.intevation.flys.artifacts.context.FLYSContext; | 37 import de.intevation.flys.artifacts.context.FLYSContext; |
39 import de.intevation.flys.artifacts.FLYSArtifact; | 38 import de.intevation.flys.artifacts.FLYSArtifact; |
40 import de.intevation.flys.artifacts.model.ManagedFacet; | |
41 import de.intevation.flys.artifacts.model.ManagedDomFacet; | |
42 import de.intevation.flys.exports.OutGenerator; | 39 import de.intevation.flys.exports.OutGenerator; |
40 import de.intevation.flys.exports.OutputHelper; | |
43 import de.intevation.flys.themes.Theme; | 41 import de.intevation.flys.themes.Theme; |
44 import de.intevation.flys.themes.ThemeFactory; | 42 import de.intevation.flys.themes.ThemeFactory; |
45 | 43 |
46 import de.intevation.flys.utils.FLYSUtils; | 44 import de.intevation.flys.utils.FLYSUtils; |
47 | 45 |
269 | 267 |
270 for (Map.Entry<String, Output> entry: entries) { | 268 for (Map.Entry<String, Output> entry: entries) { |
271 String outName = entry.getKey(); | 269 String outName = entry.getKey(); |
272 Output output = entry.getValue(); | 270 Output output = entry.getValue(); |
273 | 271 |
272 if (outName.equals("sq_overview")) { | |
273 continue; | |
274 } | |
274 Settings settings = output.getSettings(); | 275 Settings settings = output.getSettings(); |
275 | 276 |
276 if (settings == null) { | 277 if (settings == null) { |
277 log.debug("No Settings set for Output '" + outName + "'."); | 278 log.debug("No Settings set for Output '" + outName + "'."); |
278 output.setSettings( | 279 output.setSettings( |
299 protected Settings createInitialOutputSettings( | 300 protected Settings createInitialOutputSettings( |
300 CallContext cc, | 301 CallContext cc, |
301 CollectionAttribute attr, | 302 CollectionAttribute attr, |
302 String out | 303 String out |
303 ) { | 304 ) { |
304 OutGenerator outGen = getOutGenerator(cc, out, null); | 305 OutGenerator outGen = FLYSContext.getOutGenerator(cc, out, null); |
305 | 306 |
306 if (outGen == null) { | 307 if (outGen == null) { |
307 return null; | 308 return null; |
308 } | 309 } |
309 | 310 |
312 outGen.init(XMLUtils.newDocument(), null, cc); | 313 outGen.init(XMLUtils.newDocument(), null, cc); |
313 prepareMasterArtifact(outGen, cc); | 314 prepareMasterArtifact(outGen, cc); |
314 | 315 |
315 try { | 316 try { |
316 Document outAttr = getAttribute(cc, attr, out); | 317 Document outAttr = getAttribute(cc, attr, out); |
317 doOut(outGen, out, out, outAttr, cc); | 318 OutputHelper helper = new OutputHelper(identifier()); |
319 helper.doOut(outGen, out, out, outAttr, cc); | |
318 } | 320 } |
319 catch (ArtifactDatabaseException adbe) { | 321 catch (ArtifactDatabaseException adbe) { |
320 log.error(adbe, adbe); | 322 log.error(adbe, adbe); |
321 } | 323 } |
322 catch (IOException ioe) { | 324 catch (IOException ioe) { |
352 OutGenerator generator = null; | 354 OutGenerator generator = null; |
353 if (type != null | 355 if (type != null |
354 && type.length() > 0 | 356 && type.length() > 0 |
355 && type.indexOf("chartinfo") > 0) | 357 && type.indexOf("chartinfo") > 0) |
356 { | 358 { |
357 generator = getOutGenerator(context, type, subtype); | 359 generator = FLYSContext.getOutGenerator(context, type, subtype); |
358 } | 360 } |
359 else { | 361 else { |
360 generator = getOutGenerator(context, name, subtype); | 362 generator = FLYSContext.getOutGenerator(context, name, subtype); |
361 } | 363 } |
362 | 364 |
363 if (generator == null) { | 365 if (generator == null) { |
364 log.error("There is no generator specified for output: " + name); | 366 log.error("There is no generator specified for output: " + name); |
365 // TODO Throw an exception. | 367 // TODO Throw an exception. |
378 generator.setSettings(settings); | 380 generator.setSettings(settings); |
379 prepareMasterArtifact(generator, context); | 381 prepareMasterArtifact(generator, context); |
380 | 382 |
381 try { | 383 try { |
382 Document attr = getAttribute(context, cAttr, name); | 384 Document attr = getAttribute(context, cAttr, name); |
383 doOut(generator, name, subtype, attr, context); | 385 OutputHelper helper = new OutputHelper(identifier()); |
386 if (name.equals("sq_overview")) { | |
387 helper.doOut(generator, name, subtype, format, context); | |
388 } | |
389 helper.doOut(generator, name, subtype, attr, context); | |
384 generator.generate(); | 390 generator.generate(); |
385 } | 391 } |
386 catch (ArtifactDatabaseException adbe) { | 392 catch (ArtifactDatabaseException adbe) { |
387 log.error(adbe, adbe); | 393 log.error(adbe, adbe); |
388 } | 394 } |
407 generator.setMasterArtifact(master); | 413 generator.setMasterArtifact(master); |
408 } | 414 } |
409 else { | 415 else { |
410 log.warn("Could not set master artifact."); | 416 log.warn("Could not set master artifact."); |
411 } | 417 } |
412 } | |
413 | |
414 | |
415 /** | |
416 * Creates the concrete output. | |
417 * | |
418 * @param generator The OutGenerator that creates the output. | |
419 * @param outputName The name of the requested output. | |
420 * @param attributes The collection's attributes for this concrete output | |
421 * type. | |
422 * @param context The context object. | |
423 */ | |
424 protected void doOut( | |
425 OutGenerator generator, | |
426 String outName, | |
427 String facet, | |
428 Document attributes, | |
429 CallContext context) | |
430 throws IOException | |
431 { | |
432 boolean debug = log.isDebugEnabled(); | |
433 | |
434 if (debug) { | |
435 log.debug("FLYSArtifactCollection.doOut: " + outName); | |
436 } | |
437 | |
438 ThemeList themeList = new ThemeList(attributes); | |
439 | |
440 int size = themeList.size(); | |
441 if (debug) { | |
442 log.debug("Output will contain " + size + " elements."); | |
443 } | |
444 | |
445 List<ArtifactAndFacet> dataProviders = | |
446 doBlackboardPass(themeList, context); | |
447 | |
448 try { | |
449 for (int i = 0; i < size; i++) { | |
450 ManagedFacet theme = themeList.get(i); | |
451 | |
452 if (theme == null) { | |
453 log.debug("Theme is empty - no output is generated."); | |
454 continue; | |
455 } | |
456 | |
457 String art = theme.getArtifact(); | |
458 String facetName = theme.getName(); | |
459 | |
460 if (debug) { | |
461 log.debug("Do output for..."); | |
462 log.debug("... artifact: " + art); | |
463 log.debug("... facet: " + facetName); | |
464 } | |
465 | |
466 if (outName.equals("export") && !facetName.equals(facet)) { | |
467 continue; | |
468 } | |
469 | |
470 // Skip invisible themes. | |
471 if (theme.getVisible() == 0) { | |
472 continue; | |
473 } | |
474 | |
475 generator.doOut( | |
476 dataProviders.get(i), | |
477 getFacetThemeFromAttribute( | |
478 art, | |
479 outName, | |
480 facetName, | |
481 theme.getDescription(), | |
482 theme.getIndex(), | |
483 context), | |
484 theme.getActive() == 1); | |
485 } | |
486 } | |
487 catch (ArtifactDatabaseException ade) { | |
488 log.error(ade, ade); | |
489 } | |
490 } | |
491 | |
492 | |
493 /** | |
494 * Show blackboard (context) to each facet and create a list of | |
495 * ArtifactAndFacets on the fly (with the same ordering as the passed | |
496 * ThemeList). | |
497 * @param themeList ThemeList to create a ArtifactAndFacetList along. | |
498 * @param context The "Blackboard". | |
499 */ | |
500 protected List<ArtifactAndFacet> doBlackboardPass( | |
501 ThemeList themeList, CallContext context | |
502 ) { | |
503 ArrayList<ArtifactAndFacet> dataProviders = | |
504 new ArrayList<ArtifactAndFacet>(); | |
505 int size = themeList.size(); | |
506 | |
507 try { | |
508 // Collect all ArtifactAndFacets for blackboard pass. | |
509 for (int i = 0; i < size; i++) { | |
510 ManagedFacet theme = themeList.get(i); | |
511 if (theme == null) { | |
512 log.warn("A ManagedFacet in ThemeList is null."); | |
513 continue; | |
514 } | |
515 String uuid = theme.getArtifact(); | |
516 Artifact artifact = getArtifact(uuid, context); | |
517 FLYSArtifact flys = (FLYSArtifact) artifact; | |
518 | |
519 ArtifactAndFacet artifactAndFacet = new ArtifactAndFacet( | |
520 artifact, | |
521 flys.getNativeFacet(theme)); | |
522 | |
523 // XXX HELP ME PLEASE | |
524 artifactAndFacet.setFacetDescription(theme.getDescription()); | |
525 | |
526 // Show blackboard to facet. | |
527 artifactAndFacet.register(context); | |
528 | |
529 // Add to themes. | |
530 dataProviders.add(i, artifactAndFacet); | |
531 } | |
532 } | |
533 catch (ArtifactDatabaseException ade) { | |
534 log.error("ArtifactDatabaseException!", ade); | |
535 } | |
536 | |
537 return dataProviders; | |
538 } | 418 } |
539 | 419 |
540 | 420 |
541 /** | 421 /** |
542 * @return masterartifact or null if exception/not found. | 422 * @return masterartifact or null if exception/not found. |
719 | 599 |
720 return persistent != null ? persistent.getArtifact() : null; | 600 return persistent != null ? persistent.getArtifact() : null; |
721 } | 601 } |
722 | 602 |
723 | 603 |
724 /** | 604 |
725 * Returns the attribute that belongs to an artifact and facet stored in | 605 |
726 * this collection. | |
727 * | |
728 * @param uuid The Artifact's uuid. | |
729 * @param outname The name of the requested output. | |
730 * @param facet The name of the requested facet. | |
731 * @param context The CallContext. | |
732 * | |
733 * @return an attribute in form of a document. | |
734 */ | |
735 protected Document getFacetThemeFromAttribute( | |
736 String uuid, | |
737 String outName, | |
738 String facet, | |
739 String pattern, | |
740 int index, | |
741 CallContext context) | |
742 throws ArtifactDatabaseException | |
743 { | |
744 boolean debug = log.isDebugEnabled(); | |
745 | |
746 if (debug) { | |
747 log.debug( | |
748 "FLYSArtifactCollection.getFacetThemeFromAttribute(facet=" | |
749 + facet + ", index=" + index); | |
750 } | |
751 | |
752 | |
753 ArtifactDatabase db = context.getDatabase(); | |
754 CallMeta meta = context.getMeta(); | |
755 | |
756 FLYSContext flysContext = context instanceof FLYSContext | |
757 ? (FLYSContext) context | |
758 : (FLYSContext) context.globalContext(); | |
759 | |
760 Document attr = db.getCollectionItemAttribute(identifier(), uuid, meta); | |
761 | |
762 if (attr == null) { | |
763 attr = initItemAttribute(uuid, facet, pattern, index, outName, context); | |
764 | |
765 if (attr == null) { | |
766 return null; | |
767 } | |
768 } | |
769 | |
770 if (debug) { | |
771 log.debug("Search attribute of collection item: " + uuid); | |
772 } | |
773 | |
774 Node tmp = (Node) XMLUtils.xpath( | |
775 attr, | |
776 "/art:attribute", | |
777 XPathConstants.NODE, | |
778 ArtifactNamespaceContext.INSTANCE); | |
779 | |
780 if (tmp == null) { | |
781 log.warn("No attribute found. Operation failed."); | |
782 return null; | |
783 } | |
784 | |
785 if (debug) { | |
786 log.debug("Search theme for facet '" + facet + "' in attribute."); | |
787 } | |
788 | |
789 Map<String, String> vars = new HashMap<String, String>(); | |
790 vars.put("facet", facet); | |
791 vars.put("index", String.valueOf(index)); | |
792 | |
793 Node theme = (Node) XMLUtils.xpath( | |
794 tmp, | |
795 "art:themes/theme[@facet=$facet and @index=$index]", | |
796 XPathConstants.NODE, | |
797 ArtifactNamespaceContext.INSTANCE, | |
798 vars); | |
799 | |
800 if (theme == null) { | |
801 log.warn("Could not find the theme in attribute of: " + facet + " " + uuid); | |
802 | |
803 Theme t = getThemeForFacet( | |
804 uuid, facet, pattern, index, outName, context); | |
805 | |
806 if (t == null) { | |
807 log.warn("No theme found for facet: " + facet); | |
808 return null; | |
809 } | |
810 | |
811 addThemeToAttribute(uuid, attr, t, context); | |
812 theme = t.toXML().getFirstChild(); | |
813 } | |
814 | |
815 Document doc = XMLUtils.newDocument(); | |
816 doc.appendChild(doc.importNode(theme, true)); | |
817 | |
818 return doc; | |
819 } | |
820 | |
821 | |
822 /** | |
823 * Adds the theme of a facet to a CollectionItem's attribute. | |
824 * | |
825 * @param uuid The uuid of the artifact. | |
826 * @param attr The current attribute of an artifact. | |
827 * @param t The theme to add. | |
828 * @param context The CallContext. | |
829 */ | |
830 protected void addThemeToAttribute( | |
831 String uuid, | |
832 Document attr, | |
833 Theme t, | |
834 CallContext context) | |
835 { | |
836 log.debug("FLYSArtifactCollection.addThemeToAttribute: " + uuid); | |
837 | |
838 if (t == null) { | |
839 log.warn("Theme is empty - cancel adding it to attribute!"); | |
840 return; | |
841 } | |
842 | |
843 XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( | |
844 attr, | |
845 ArtifactNamespaceContext.NAMESPACE_URI, | |
846 ArtifactNamespaceContext.NAMESPACE_PREFIX); | |
847 | |
848 Node tmp = (Node) XMLUtils.xpath( | |
849 attr, | |
850 "/art:attribute", | |
851 XPathConstants.NODE, | |
852 ArtifactNamespaceContext.INSTANCE); | |
853 | |
854 if (tmp == null) { | |
855 tmp = ec.create("attribute"); | |
856 attr.appendChild(tmp); | |
857 } | |
858 | |
859 Node themes = (Node) XMLUtils.xpath( | |
860 tmp, | |
861 "art:themes", | |
862 XPathConstants.NODE, | |
863 ArtifactNamespaceContext.INSTANCE); | |
864 | |
865 if (themes == null) { | |
866 themes = ec.create("themes"); | |
867 tmp.appendChild(themes); | |
868 } | |
869 | |
870 themes.appendChild(attr.importNode(t.toXML().getFirstChild(), true)); | |
871 | |
872 try { | |
873 setCollectionItemAttribute(uuid, attr, context); | |
874 } | |
875 catch (ArtifactDatabaseException e) { | |
876 // do nothing | |
877 log.warn("Cannot set attribute of item: " + uuid); | |
878 } | |
879 } | |
880 | |
881 | |
882 /** | |
883 * Initializes the attribute of an collection item with the theme of a | |
884 * specific facet. | |
885 * | |
886 * @param uuid The uuid of an artifact. | |
887 * @param facet The name of a facet. | |
888 * @param context The CallContext. | |
889 * | |
890 * @param the new attribute. | |
891 */ | |
892 protected Document initItemAttribute( | |
893 String uuid, | |
894 String facet, | |
895 String pattern, | |
896 int index, | |
897 String outName, | |
898 CallContext context) | |
899 { | |
900 boolean debug = log.isDebugEnabled(); | |
901 | |
902 if (debug) { | |
903 log.debug("FLYSArtifactCollection.initItemAttribute"); | |
904 } | |
905 | |
906 Theme t = getThemeForFacet(uuid, facet, pattern, index, outName, context); | |
907 | |
908 if (t == null) { | |
909 log.info("Could not find theme for facet. Cancel initialization."); | |
910 return null; | |
911 } | |
912 | |
913 Document attr = XMLUtils.newDocument(); | |
914 addThemeToAttribute(uuid, attr, t, context); | |
915 | |
916 if (debug) { | |
917 log.debug("initItemAttribute for facet " + facet + ": " | |
918 + XMLUtils.toString(attr)); | |
919 } | |
920 | |
921 return attr; | |
922 } | |
923 | |
924 | |
925 /** | |
926 * Sets the attribute of a CollectionItem specified by <i>uuid</i> to a new | |
927 * value <i>attr</i>. | |
928 * | |
929 * @param uuid The uuid of the CollectionItem. | |
930 * @param attr The new attribute for the CollectionItem. | |
931 * @param context The CallContext. | |
932 */ | |
933 public void setCollectionItemAttribute( | |
934 String uuid, | |
935 Document attr, | |
936 CallContext context) | |
937 throws ArtifactDatabaseException | |
938 { | |
939 Document doc = ClientProtocolUtils.newSetItemAttributeDocument( | |
940 uuid, | |
941 attr); | |
942 | |
943 if (doc == null) { | |
944 log.warn("Cannot set item attribute: No attribute found."); | |
945 return; | |
946 } | |
947 | |
948 ArtifactDatabase db = context.getDatabase(); | |
949 CallMeta meta = context.getMeta(); | |
950 | |
951 db.setCollectionItemAttribute(identifier(), uuid, doc, meta); | |
952 } | |
953 | |
954 | |
955 /** | |
956 * Returns the theme of a specific facet. | |
957 * | |
958 * @param uuid The uuid of an artifact. | |
959 * @param facet The name of the facet. | |
960 * @param context The CallContext object. | |
961 * | |
962 * @return the desired theme. | |
963 */ | |
964 protected Theme getThemeForFacet( | |
965 String uuid, | |
966 String facet, | |
967 String pattern, | |
968 int index, | |
969 String outName, | |
970 CallContext context) | |
971 { | |
972 log.info("FLYSArtifactCollection.getThemeForFacet: " + facet); | |
973 | |
974 FLYSContext flysContext = context instanceof FLYSContext | |
975 ? (FLYSContext) context | |
976 : (FLYSContext) context.globalContext(); | |
977 | |
978 // Push artifact in flysContext. | |
979 ArtifactDatabase db = context.getDatabase(); | |
980 try { | |
981 FLYSArtifact artifact = (FLYSArtifact) db.getRawArtifact(uuid); | |
982 log.debug("Got raw artifact"); | |
983 flysContext.put(FLYSContext.ARTIFACT_KEY, artifact); | |
984 } | |
985 catch (ArtifactDatabaseException dbe) { | |
986 log.error("Exception caught when trying to get art.", dbe); | |
987 } | |
988 | |
989 Theme t = ThemeFactory.getTheme( | |
990 flysContext, | |
991 facet, | |
992 pattern, | |
993 outName, | |
994 "default"); | |
995 | |
996 if (t != null) { | |
997 t.setFacet(facet); | |
998 t.setIndex(index); | |
999 } | |
1000 | |
1001 return t; | |
1002 } | |
1003 | |
1004 | |
1005 /** | |
1006 * Returns the OutGenerator for a specified <i>type</i>. | |
1007 * | |
1008 * @param name The name of the output type. | |
1009 * @param type Defines the type of the desired OutGenerator. | |
1010 * | |
1011 * @return Instance of an OutGenerator for specified <i>type</i>. | |
1012 */ | |
1013 protected OutGenerator getOutGenerator( | |
1014 CallContext context, | |
1015 String name, | |
1016 String type) | |
1017 { | |
1018 log.debug("Search OutGenerator for Output '" + name + "'"); | |
1019 | |
1020 FLYSContext flysContext = context instanceof FLYSContext | |
1021 ? (FLYSContext) context | |
1022 : (FLYSContext) context.globalContext(); | |
1023 | |
1024 Map<String, Class> generators = (Map<String, Class>) | |
1025 flysContext.get(FLYSContext.OUTGENERATORS_KEY); | |
1026 | |
1027 if (generators == null) { | |
1028 log.error("No output generators found in the running application!"); | |
1029 return null; | |
1030 } | |
1031 | |
1032 Class clazz = generators.get(name); | |
1033 | |
1034 try { | |
1035 return clazz != null ? (OutGenerator) clazz.newInstance() : null; | |
1036 } | |
1037 catch (InstantiationException ie) { | |
1038 log.error(ie, ie); | |
1039 } | |
1040 catch (IllegalAccessException iae) { | |
1041 log.error(iae, iae); | |
1042 } | |
1043 | |
1044 return null; | |
1045 } | |
1046 | |
1047 | |
1048 /** | |
1049 * Inner class to structure/order the themes of a chart. | |
1050 */ | |
1051 private static class ThemeList { | |
1052 private Logger logger = Logger.getLogger(ThemeList.class); | |
1053 protected Map<Integer, ManagedFacet> themes; | |
1054 | |
1055 public ThemeList(Document output) { | |
1056 themes = new HashMap<Integer, ManagedFacet>(); | |
1057 parse(output); | |
1058 } | |
1059 | |
1060 protected void parse(Document output) { | |
1061 NodeList themeList = (NodeList) XMLUtils.xpath( | |
1062 output, | |
1063 "art:output/art:facet", | |
1064 XPathConstants.NODESET, | |
1065 ArtifactNamespaceContext.INSTANCE); | |
1066 | |
1067 int num = themeList != null ? themeList.getLength() : 0; | |
1068 | |
1069 logger.debug("Output has " + num + " elements."); | |
1070 | |
1071 if (num == 0) { | |
1072 return; | |
1073 } | |
1074 | |
1075 String uri = ArtifactNamespaceContext.NAMESPACE_URI; | |
1076 | |
1077 for (int i = 0; i < num; i++) { | |
1078 Element theme = (Element) themeList.item(i); | |
1079 | |
1080 ManagedDomFacet facet = new ManagedDomFacet(theme); | |
1081 themes.put(Integer.valueOf(facet.getPosition()-1), facet); | |
1082 } | |
1083 } | |
1084 | |
1085 public ManagedFacet get(int idx) { | |
1086 return themes.get(Integer.valueOf(idx)); | |
1087 } | |
1088 | |
1089 public int size() { | |
1090 return themes.size(); | |
1091 } | |
1092 } | |
1093 } | 606 } |
1094 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : | 607 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |