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 :

http://dive4elements.wald.intevation.org