Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/collections/AttributeWriter.java @ 1755:f7072039ad84
Added default diff theme, avoid possible NPE.
flys-artifacts/trunk@3058 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Mon, 24 Oct 2011 09:50:11 +0000 |
parents | f643ea084213 |
children | b503d92dd709 |
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.ArtifactDatabase; import de.intevation.artifacts.ArtifactDatabaseException; 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.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; 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, unchagnged * form) outputs. */ public AttributeWriter( ArtifactDatabase db, Map<String, Output> oldAttr, Map<String, Output> newAttr) { this.db = db; 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(); } try { writeFacets(doc, cr, output, facetsA, facetsB); } catch (ArtifactDatabaseException ade) { logger.error(ade, ade); } } /** * @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) throws ArtifactDatabaseException { 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); } } // 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( 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); } // 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 :