Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/collections/AttributeWriter.java @ 1675:19d0eb41e923
AnnotationArtifact: Bugfixes and enabled cache support.
flys-artifacts/trunk@2892 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Wed, 05 Oct 2011 10:26:54 +0000 |
parents | 12235a2ace21 |
children | f643ea084213 |
line wrap: on
line source
package de.intevation.flys.collections; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import de.intevation.artifacts.ArtifactNamespaceContext; import de.intevation.artifactdatabase.state.Facet; import de.intevation.artifactdatabase.state.Output; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; 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 { protected Map<String, Output> oldAttr; protected Map<String, Output> newAttr; private static Logger logger = Logger.getLogger(AttributeWriter.class); /** * Create a AttributeWriter. * Attributes not present in newAttr will not be included in the document. * @param oldAttr "Old" (possibly user-changed) outputs. * @param newAttr "New" (eventually re-read in its original, unchagnged * form) outputs. */ public AttributeWriter( Map<String, Output> oldAttr, Map<String, Output> newAttr) { this.oldAttr = oldAttr; this.newAttr = newAttr; } /** * 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 Document write() { Document doc = XMLUtils.newDocument(); ElementCreator cr = new ElementCreator( doc, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); Element attribute = cr.create("attribute"); Element outs = cr.create("outputs"); attribute.appendChild(outs); doc.appendChild(attribute); for (String outName: newAttr.keySet()) { Output a = newAttr.get(outName); Output b = oldAttr.get(outName); writeOutput(doc, outs, cr, a, b); } return doc; } /** * @param doc Document to add output nodes to * @param outs Node in Document to add output nodes to * @param a the new output * @param b the old output */ protected void writeOutput( Document doc, Node outs, ElementCreator cr, Output a, /* new output */ Output b) /* old output */ { Element output = cr.create("output"); cr.addAttr(output, "name", a.getName()); outs.appendChild(output); List<Facet> facetsA = a.getFacets(); List<Facet> facetsB = null; if (b != null) { facetsB = b.getFacets(); } writeFacets(doc, cr, output, facetsA, facetsB); } /** * @param doc Document to add facet nodes to * @param output Node in Document to add facet nodes to * @param a the new facets * @param b the old facets */ protected void writeFacets( Document doc, ElementCreator cr, Element output, List<Facet> newFacets, List<Facet> oldFacets) { 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); ManagedFacet picked = pickFacet(facet, oldFacets); if (facet.equals(picked)) { genuinelyNewFacets.add(picked); } else { currentFacets.add(picked); } } // 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); } // Now add all facets. for (ManagedFacet oldMF: currentFacets) { Node node = oldMF.toXML(doc); if (node != null) { output.appendChild(node); } } } /** * 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 :