Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/collections/AttributeWriter.java @ 5818:a4ff4167be1e
Request feature info on all layers and show it as html if
the server does not return valid gml.
Non queryable layers produce an error message when the request
fails. This is good enough
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Wed, 24 Apr 2013 17:33:27 +0200 |
parents | 345f3bba6f15 |
children |
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.FacetActivity; 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. * @param matrix Compatibility matrix, mapping output names to list of * facet names that can be included in this out. */ 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() { boolean debug = logger.isDebugEnabled(); for (Map.Entry<String, Output> entry: newAttr.entrySet()) { String outName = entry.getKey(); Output a = entry.getValue(); if (!attribute.hasOutput(outName)) { attribute.addOutput(outName, a); } attribute.clearFacets(outName); if (debug) { logger.debug("Merge Output: " + outName); logger.debug(" old Facets: " + oldFacets.size()); logger.debug(" new Facets: " + newFacets.size()); } 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); if (logger.isDebugEnabled() && compatFacets != null) { logger.debug("Compabitle Facets:"); for (String compatible: compatFacets) { logger.debug( "- " + compatible); } } 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 " + outputName + "."); 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>(); boolean debug = logger.isDebugEnabled(); if (debug) { logger.debug("Compatible facets are " + compatibleFacets); } for (int i = 0; i < num; i++) { ManagedFacet facet = (ManagedFacet) newFacets.get(i); if (debug) { logger.debug("Try to add Facet: " + facet.getName()); } if (!compatibleFacets.contains(facet.getName())) { logger.warn("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); } } FacetActivity.Registry registry = FacetActivity.Registry.getInstance(); // With each genuinely new Facet, figure out whether it comes to live // in/activate. for (ManagedFacet newMF: genuinelyNewFacets) { FLYSArtifact flys = (FLYSArtifact)db.getRawArtifact(newMF.getArtifact()); boolean isActive = registry.isInitialActive( flys.getName(), flys, newMF, outputName); newMF.setActive(isActive ? 1 : 0); } // 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; if (debug) { 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.isEmpty(); } /** * 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 :