Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/collections/AttributeWriter.java @ 2089:0da8874bd378
Added initial state to map artifact to be able to advance and step back.
The map artifact overrides describe() to have the complete UI information in the
describe response document.
flys-artifacts/trunk@3613 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Raimund Renkert <raimund.renkert@intevation.de> |
---|---|
date | Fri, 06 Jan 2012 12:02:10 +0000 |
parents | ca6ccf722c24 |
children | 22732713c54d |
line wrap: on
line source
package de.intevation.flys.collections; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import de.intevation.artifacts.ArtifactDatabase; import de.intevation.artifacts.ArtifactDatabaseException; import de.intevation.artifactdatabase.state.Facet; import de.intevation.artifactdatabase.state.Output; import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.model.ManagedFacet; /** * Create attribute- element of describe document of an ArtifactCollection. * The attribute-element contains the merged output of all outputmodes and * facets that are part of the collection. */ public class AttributeWriter { /** ArtifactDatabase used to fetch Artifacts. */ protected ArtifactDatabase db = null; protected Map<String, Output> oldAttr; protected Map<String, Output> newAttr; /** List of already seen facets. */ protected List<Facet> oldFacets; /** List of "new" facets. */ protected List<Facet> newFacets; /** * "Compatibility matrix", mapws list of facet names to output names. * Any facet that is not found in the list for a specific output will * not be added to the resulting document. */ protected Map<String, List<String>> compatibilities; /** The result of the <i>write()</i> operation.*/ protected CollectionAttribute attribute; private static Logger logger = Logger.getLogger(AttributeWriter.class); /** * Create a AttributeWriter. * Attributes not present in newAttr will not be included in the document. * @param db Database to fetch artifacts. * @param oldAttr "Old" (possibly user-changed) outputs. * @param newAttr "New" (eventually re-read in its original, unchanged * form) outputs. */ public AttributeWriter( ArtifactDatabase db, CollectionAttribute attribute, Map<String, Output> oldAttr, List<Facet> oldFacets, Map<String, Output> newAttr, List<Facet> newFacets, Map<String, List<String>> matrix) { this.db = db; this.attribute = attribute; this.oldAttr = oldAttr; this.newAttr = newAttr; this.oldFacets = oldFacets; this.newFacets = newFacets; this.compatibilities = matrix; } /** * Create document by merging outputs given in * constructor. * * The "new" set rules about existance of attributes, so anything not * present in it will not be included in the resulting document. * The "old" set rules about the content of attributes (as user changes * are recorded here and not in the new set). * * @return document with merged outputs as described. */ protected CollectionAttribute write() { for (Map.Entry<String, Output> entry: newAttr.entrySet()) { String outName = entry.getKey(); Output a = entry.getValue(); Output exists = attribute.getOutput(outName); if (exists == null) { attribute.addOutput(outName, a); } attribute.clearFacets(outName); writeOutput(a.getName(), newFacets, oldFacets); } // THIS CALL IS ABSOLUTELY NECESSARY! attribute.cleanEmptyOutputs(); return attribute; } /** * @param outputName the "new" outputs name * @param newOutFacets Facets of the new outputs * @param oldOutFacets Facets of the old outputs (can be null) */ protected void writeOutput( String outputName, List<Facet> newOutFacets, List<Facet> oldOutFacets ) { List<String> compatFacets = this.compatibilities.get(outputName); try { writeFacets(outputName, newOutFacets, oldOutFacets, compatFacets); } catch (ArtifactDatabaseException ade) { logger.error(ade, ade); } } /** * @param newFacets the new facets * @param oldFacets the old facets * @param compatibleFacets List of facets to accept * @return true if any facets are written to the out. */ protected boolean writeFacets( String outputName, List<Facet> newFacets, List<Facet> oldFacets, List<String> compatibleFacets) throws ArtifactDatabaseException { if (compatibleFacets == null) { logger.warn("No compatible facets, not generating out."); return false; } int num = newFacets.size(); // Add all new Facets either in their old state or (if really // new) as they are. List<ManagedFacet> currentFacets = new ArrayList<ManagedFacet>(); List<ManagedFacet> genuinelyNewFacets = new ArrayList<ManagedFacet>(); for (int i = 0; i < num; i++) { ManagedFacet facet = (ManagedFacet) newFacets.get(i); if (!compatibleFacets.contains(facet.getName())) { //logger.debug("Have incompatible facet, skip: " + facet.getName()); continue; } //else logger.debug("Have compatible facet: " + facet.getName()); ManagedFacet picked = pickFacet(facet, oldFacets); if (facet.equals(picked)) { genuinelyNewFacets.add(picked); } else { currentFacets.add(picked); } } // With each genuinely new Facet, ask Artifact whether it comes to live // in/activate. for (ManagedFacet newMF: genuinelyNewFacets) { FLYSArtifact flys = (FLYSArtifact) db.getRawArtifact(newMF.getArtifact()); newMF.setActive(flys.getInitialFacetActivity( outputName, newMF.getName(), newMF.getIndex())); } // For each genuinely new Facet check positional conflicts. for (ManagedFacet newMF: genuinelyNewFacets) { boolean conflicts = true; // Loop until all conflicts resolved. while (conflicts) { conflicts = false; for (ManagedFacet oldMF: currentFacets) { if (newMF.getPosition() == oldMF.getPosition()) { conflicts = true; logger.debug("Positional conflict while merging " + "facets, pushing newest facet 1 up (" + newMF.getPosition() + ")"); newMF.setPosition(newMF.getPosition() + 1); break; } } } currentFacets.add(newMF); } // Fill/correct "gaps" (e.g. position 1,2,5 are taken, after gap filling // expect positions 1,2,3 [5->3]) // Preparations to be able to detect gaps. Map<Integer, ManagedFacet> mfmap = new HashMap<Integer, ManagedFacet>(); int max = 0; for (ManagedFacet mf: currentFacets) { int pos = mf.getPosition(); mfmap.put(Integer.valueOf(pos), mf); if (pos > max) max = pos; } // Finally do gap correction. if (max != currentFacets.size()) { int gap = 0; for (int i = 1; i <= max; i++) { ManagedFacet mf = mfmap.get(Integer.valueOf(i)); if (mf == null) { gap++; continue; } mf.setPosition(mf.getPosition() - gap); } } // Now add all facets. for (ManagedFacet oldMF: currentFacets) { attribute.addFacet(outputName, oldMF); } return currentFacets.size() > 0; } /** * Returns the facet to be added to Document. * Return the new facet only if the "same" facet was not present before. * Return the "old" facet otherwise (user-defined information sticks * to it). * @param facet the new facet. * @param oldFacets the old facets, new facet is compared against each of * these. * @return facet if genuinely new, matching old facet otherwise. */ protected ManagedFacet pickFacet(ManagedFacet facet, List<Facet> oldFacets) { if (oldFacets == null) { logger.debug("No old facets to compare a new to found."); return facet; } String hash = facet.getName() + facet.getIndex() + facet.getArtifact(); // Compare "new" facet with all old facets. // Take oldFacet if that facet was already present (otherwise // information is lost, the new one otherwise. for (Facet oFacet: oldFacets) { ManagedFacet oldFacet = (ManagedFacet) oFacet; String oldHash = oldFacet.getName() + oldFacet.getIndex() + oldFacet.getArtifact(); if (hash.equals(oldHash)) { return oldFacet; } } return facet; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :