felix@1026: package de.intevation.flys.artifacts;
felix@1026: 
felix@1026: import java.util.ArrayList;
felix@1026: import java.util.List;
felix@1026: 
felix@1026: import org.w3c.dom.Document;
felix@1026: import org.w3c.dom.Element;
felix@1026: 
felix@1026: import org.apache.log4j.Logger;
felix@1026: 
felix@1026: import de.intevation.artifacts.Artifact;
felix@1026: import de.intevation.artifacts.ArtifactNamespaceContext;
felix@1026: import de.intevation.artifacts.CallContext;
felix@1026: import de.intevation.artifacts.CallMeta;
felix@1026: 
felix@1026: import de.intevation.artifactdatabase.ProtocolUtils;
felix@1026: import de.intevation.artifactdatabase.state.Facet;
felix@1026: import de.intevation.artifactdatabase.state.Output;
felix@1026: import de.intevation.artifactdatabase.state.State;
felix@1026: import de.intevation.artifactdatabase.state.StateEngine;
felix@1026: 
felix@1026: import de.intevation.artifacts.common.utils.XMLUtils;
felix@1026: 
felix@1026: import de.intevation.flys.artifacts.states.DefaultState;
felix@1026: import de.intevation.flys.artifacts.context.FLYSContext;
sascha@1055: 
felix@1099: import de.intevation.flys.utils.FLYSUtils;
felix@1026: 
felix@1026: /**
felix@1026:  * Artifact to access names of Points Of Interest along a segment of a river.
felix@1026:  */
felix@1026: public class AnnotationArtifact extends StaticFLYSArtifact {
felix@1026: 
felix@1026:     /** The logger for this class. */
ingo@1675:     private static Logger logger = Logger.getLogger(AnnotationArtifact.class);
felix@1026: 
felix@1026:     /** The name of the artifact. */
felix@1026:     public static final String ARTIFACT_NAME = "annotation";
felix@1026: 
felix@2112:     /** Get river, setup Facets. */
felix@1026:     @Override
felix@1077:     protected void initialize(Artifact artifact, Object context,
felix@1077:             CallMeta meta) {
felix@1077:         logger.debug("AnnotationArtifact.initialize, id: "
felix@2112:             + artifact.identifier());
felix@1026: 
felix@1026:         FLYSArtifact flys = (FLYSArtifact) artifact;
felix@2112:         importData(flys, "river");
felix@1026: 
felix@1026:         List<Facet> fs = new ArrayList<Facet>();
felix@1026: 
felix@1026:         // TODO Add CallMeta (duplicate TODO in RiverAxisArtifact.java).
felix@1026:         DefaultState state = (DefaultState) getCurrentState(context);
felix@1026:         state.computeInit(this, hash(), context, meta, fs);
felix@1026: 
felix@1026:         if (!fs.isEmpty()) {
felix@1026:             logger.debug("Facets to add in AnnotationsArtifact.initialize .");
felix@1771:             facets.put(getCurrentStateId(), fs);
felix@1026:         }
felix@1026:         else {
felix@1026:             logger.debug("No facets to add in AnnotationsArtifact.initialize .");
felix@1026:         }
felix@1026:     }
felix@1026: 
felix@1026: 
felix@1026:     public double[] getDistance() {
felix@1032:         /** TODO In initialize(), access maximal range of river (via
sascha@3076:          * AnnotationFactory) instead of overriding getDistance,
felix@1032:          * important for diagram generation. */
felix@1026:         return new double[] {0f, 1000f};
felix@1026:     }
felix@1026: 
felix@1026: 
felix@1026:     /**
felix@1026:      * Create the description of this AnnotationArtifact-instance.
felix@1026:      *
felix@1026:      * @param data Some data.
felix@1026:      * @param context The CallContext.
felix@1026:      *
felix@1026:      * @return the description of this artifact.
felix@1026:      */
felix@1070:     @Override
felix@1026:     public Document describe(Document data, CallContext context) {
felix@1026:         logger.debug("Describe: the current state is: " + getCurrentStateId());
felix@1026: 
felix@1026:         if (logger.isDebugEnabled()) {
felix@1026:             dumpArtifact();
felix@1026:         }
felix@1026: 
felix@1777:         FLYSContext flysContext = FLYSUtils.getFlysContext(context);
felix@1026:         StateEngine stateEngine = (StateEngine) flysContext.get(
felix@1026:             FLYSContext.STATE_ENGINE_KEY);
felix@1026: 
felix@1026:         Document description            = XMLUtils.newDocument();
felix@1026:         XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
felix@1026:             description,
felix@1026:             ArtifactNamespaceContext.NAMESPACE_URI,
felix@1026:             ArtifactNamespaceContext.NAMESPACE_PREFIX);
felix@1026: 
felix@1026:         Element root = ProtocolUtils.createRootNode(creator);
felix@1026:         description.appendChild(root);
felix@1026: 
felix@1026:         State current = getCurrentState(context);
felix@1026: 
felix@1026:         ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash());
felix@1026:         ProtocolUtils.appendState(creator, root, current);
felix@1026: 
felix@1026:         Element name = ProtocolUtils.createArtNode(
felix@1026:             creator, "name",
felix@1026:             new String[] { "value" },
felix@1026:             new String[] { getName() });
felix@1026: 
felix@1026:         Element outs = ProtocolUtils.createArtNode(
felix@1026:             creator, "outputmodes", null, null);
felix@1026:         appendOutputModes(description, outs, context);
felix@1026: 
felix@1026:         root.appendChild(name);
felix@1026:         root.appendChild(outs);
felix@1026: 
felix@1026:         return description;
felix@1026:     }
felix@1026: 
felix@1026: 
felix@1026:     /**
felix@1026:      * Returns the name of the concrete artifact.
felix@1026:      *
felix@1026:      * @return the name of the concrete artifact.
felix@1026:      */
felix@1026:     public String getName() {
felix@1026:         return ARTIFACT_NAME;
felix@1026:     }
felix@1026: 
felix@1026: 
felix@1026:     /**
felix@1026:      * Append outputmode elements to given document.
felix@1026:      *
felix@1026:      * @param doc Document to add outputmodes to.
felix@1026:      * @param outs Element to add outputmode elements to.
felix@1026:      * @param context The given CallContext (mostly for internationalization).
felix@1026:      */
felix@1070:     //@Override
felix@1026:     protected void appendOutputModes(
felix@1026:         Document    doc,
felix@1026:         Element     outs,
felix@1026:         CallContext context)
felix@1026:     {
felix@1026:         List<String> stateIds = getPreviousStateIds();
felix@1026: 
felix@1026:         XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
felix@1026:             doc,
felix@1026:             ArtifactNamespaceContext.NAMESPACE_URI,
felix@1026:             ArtifactNamespaceContext.NAMESPACE_PREFIX);
felix@1026: 
felix@1777:         FLYSContext flysContext = FLYSUtils.getFlysContext(context);
felix@1026:         StateEngine engine      = (StateEngine) flysContext.get(
felix@1026:             FLYSContext.STATE_ENGINE_KEY);
felix@1026: 
felix@1026:         for (String stateId: stateIds) {
felix@1026:             logger.debug("Append output modes for state: " + stateId);
felix@1026:             DefaultState state = (DefaultState) engine.getState(stateId);
felix@1026: 
felix@1026:             List<Output> list = state.getOutputs();
sascha@3555:             if (list == null || list.isEmpty()) {
felix@1026:                 logger.debug("-> No output modes for this state.");
felix@1026:                 continue;
felix@1026:             }
felix@1026: 
felix@1771:             List<Facet> fs = facets.get(stateId);
sascha@3555:             if (fs == null || fs.isEmpty()) {
felix@1026:                 logger.debug("No facets found.");
felix@1026:                 continue;
felix@1026:             }
felix@1026: 
felix@1771:             logger.debug("Found " + fs.size() + " facets in previous states.");
felix@1026: 
felix@1771:             List<Output> generated = generateOutputs(list, fs);
felix@1026: 
felix@1026:             ProtocolUtils.appendOutputModes(doc, outs, generated);
felix@1026:         }
felix@1026: 
felix@1026:         try {
felix@1026:             DefaultState cur = (DefaultState) getCurrentState(context);
sascha@1050:             if (cur.validate(this)) {
felix@1026:                 List<Output> list = cur.getOutputs();
felix@1026:                 if (list != null && list.size() > 0) {
felix@1026:                     logger.debug(
felix@1026:                         "Append output modes for state: " + cur.getID());
felix@1026: 
felix@1771:                     List<Facet> fs = facets.get(cur.getID());
felix@1771:                     if (fs != null && fs.size() > 0) {
felix@1771:                         List<Output> generated = generateOutputs(list, fs);
felix@1026: 
felix@1771:                         logger.debug("Found " + fs.size() + " current facets.");
felix@1026:                         if (!generated.isEmpty()) {
felix@1026:                             ProtocolUtils.appendOutputModes(
felix@1026:                                 doc, outs, generated);
felix@1026:                         }
felix@1026:                         else{
felix@1026:                             logger.debug("Cannot append output to generated document.");
felix@1026:                         }
felix@1026:                     }
felix@1026:                     else {
felix@1026:                         logger.debug("No facets found for the current state.");
felix@1026:                     }
felix@1026:                 }
felix@1026:             }
felix@1026:         }
felix@1026:         catch (IllegalArgumentException iae) {
felix@1026:             // state is not valid, so we do not append its outputs.
felix@1026:         }
sascha@3076:     }
felix@1026: }
felix@1026: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :