view flys-artifacts/src/main/java/de/intevation/flys/artifacts/AnnotationArtifact.java @ 2096:bf598599782a

Made old calculation results available for floodmaps. flys-artifacts/trunk@3644 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 11 Jan 2012 10:17:16 +0000
parents a8aa343799a2
children 2d0b22602fc2
line wrap: on
line source
package de.intevation.flys.artifacts;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.log4j.Logger;

import net.sf.ehcache.Cache;

import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.ArtifactNamespaceContext;
import de.intevation.artifacts.CallContext;
import de.intevation.artifacts.CallMeta;

import de.intevation.artifactdatabase.ProtocolUtils;
import de.intevation.artifactdatabase.state.Facet;
import de.intevation.artifactdatabase.state.Output;
import de.intevation.artifactdatabase.state.State;
import de.intevation.artifactdatabase.state.StateEngine;

import de.intevation.artifacts.common.utils.XMLUtils;

import de.intevation.flys.artifacts.states.DefaultState;
import de.intevation.flys.artifacts.cache.CacheFactory;
import de.intevation.flys.artifacts.context.FLYSContext;
import de.intevation.flys.artifacts.model.AnnotationsFactory;

import de.intevation.flys.model.Annotation;

import de.intevation.flys.utils.FLYSUtils;

/**
 * Artifact to access names of Points Of Interest along a segment of a river.
 */
public class AnnotationArtifact extends StaticFLYSArtifact {

    /** The logger for this class. */
    private static Logger logger = Logger.getLogger(AnnotationArtifact.class);

    /** The name of the artifact. */
    public static final String ARTIFACT_NAME = "annotation";

    /* Name of cache. */
    public static final String CACHE_NAME = "annotations";

    @Override
    protected void initialize(Artifact artifact, Object context,
            CallMeta meta) {
        logger.debug("AnnotationArtifact.initialize, id: "
                + artifact.identifier());

        FLYSArtifact flys = (FLYSArtifact) artifact;
        addData("river", flys.getData("river"));

        List<Facet> fs = new ArrayList<Facet>();

        // TODO Add CallMeta (duplicate TODO in RiverAxisArtifact.java).
        DefaultState state = (DefaultState) getCurrentState(context);
        state.computeInit(this, hash(), context, meta, fs);

        if (!fs.isEmpty()) {
            logger.debug("Facets to add in AnnotationsArtifact.initialize .");
            facets.put(getCurrentStateId(), fs);
        }
        else {
            logger.debug("No facets to add in AnnotationsArtifact.initialize .");
        }
    }


    public double[] getDistance() {
        /** TODO In initialize(), access maximal range of river (via
         * AnnotationFactory) instead of overriding getDistance, 
         * important for diagram generation. */
        return new double[] {0f, 1000f};
    }


    /**
     * Create the description of this AnnotationArtifact-instance.
     *
     * @param data Some data.
     * @param context The CallContext.
     *
     * @return the description of this artifact.
     */
    @Override
    public Document describe(Document data, CallContext context) {
        logger.debug("Describe: the current state is: " + getCurrentStateId());

        if (logger.isDebugEnabled()) {
            dumpArtifact();
        }

        FLYSContext flysContext = FLYSUtils.getFlysContext(context);
        StateEngine stateEngine = (StateEngine) flysContext.get(
            FLYSContext.STATE_ENGINE_KEY);

        Document description            = XMLUtils.newDocument();
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            description,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        Element root = ProtocolUtils.createRootNode(creator);
        description.appendChild(root);

        State current = getCurrentState(context);

        ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash());
        ProtocolUtils.appendState(creator, root, current);

        Element name = ProtocolUtils.createArtNode(
            creator, "name",
            new String[] { "value" },
            new String[] { getName() });

        Element outs = ProtocolUtils.createArtNode(
            creator, "outputmodes", null, null);
        appendOutputModes(description, outs, context);

        root.appendChild(name);
        root.appendChild(outs);

        return description;
    }


    /**
     * Returns the name of the concrete artifact.
     *
     * @return the name of the concrete artifact.
     */
    public String getName() {
        return ARTIFACT_NAME;
    }


    /**
     * Append outputmode elements to given document.
     *
     * @param doc Document to add outputmodes to.
     * @param outs Element to add outputmode elements to.
     * @param context The given CallContext (mostly for internationalization).
     */
    //@Override
    protected void appendOutputModes(
        Document    doc,
        Element     outs,
        CallContext context)
    {
        List<String> stateIds = getPreviousStateIds();

        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            doc,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        FLYSContext flysContext = FLYSUtils.getFlysContext(context);
        StateEngine engine      = (StateEngine) flysContext.get(
            FLYSContext.STATE_ENGINE_KEY);

        for (String stateId: stateIds) {
            logger.debug("Append output modes for state: " + stateId);
            DefaultState state = (DefaultState) engine.getState(stateId);

            List<Output> list = state.getOutputs();
            if (list == null || list.size() == 0) {
                logger.debug("-> No output modes for this state.");
                continue;
            }

            List<Facet> fs = facets.get(stateId);
            if (fs == null || fs.size() == 0) {
                logger.debug("No facets found.");
                continue;
            }

            logger.debug("Found " + fs.size() + " facets in previous states.");

            List<Output> generated = generateOutputs(list, fs);

            ProtocolUtils.appendOutputModes(doc, outs, generated);
        }

        try {
            DefaultState cur = (DefaultState) getCurrentState(context);
            if (cur.validate(this)) {
                List<Output> list = cur.getOutputs();
                if (list != null && list.size() > 0) {
                    logger.debug(
                        "Append output modes for state: " + cur.getID());

                    List<Facet> fs = facets.get(cur.getID());
                    if (fs != null && fs.size() > 0) {
                        List<Output> generated = generateOutputs(list, fs);

                        logger.debug("Found " + fs.size() + " current facets.");
                        if (!generated.isEmpty()) {
                            ProtocolUtils.appendOutputModes(
                                doc, outs, generated);
                        }
                        else{
                            logger.debug("Cannot append output to generated document.");
                        }
                    }
                    else {
                        logger.debug("No facets found for the current state.");
                    }
                }
            }
        }
        catch (IllegalArgumentException iae) {
            // state is not valid, so we do not append its outputs.
        }
    } 


    /**
     * Get Annotations for Points (opposed to segments) in river in range.
     *
     * @return list of Annotations.
     */
    public List<Annotation> getAnnotations() {
        String river = FLYSUtils.getRiver(this).getName();
        logger.debug("Search annotations for river: " + river);

        Cache cache = CacheFactory.getCache(CACHE_NAME);
        String  key = river;
        Object  old = null;

        if (cache != null) {
            logger.debug("We are using a cache for annotations.");

            net.sf.ehcache.Element element = cache.get(key);
            if (element != null) {
                logger.info("Fetched annotations from cache.");
                old = element.getValue();
            }
        }

        if (old == null) {
            old = getAnnotationsUncached(river);
        }

        if (cache != null && old != null) {
            cache.put(new net.sf.ehcache.Element(key, old));
        }

        return old != null
            ? (List<Annotation>) old
            : new ArrayList<Annotation>();
    }

    /**
     * Gets Annotations from Session/Database.
     *
     * @return List of Annotations fetched fresh from session/database.
     * @see DistanceInfoService to access cached documents.
     */
    protected List<Annotation> getAnnotationsUncached(String river) {
        logger.info("Fetch annotations from database.");

        List<Annotation> annotations = new ArrayList<Annotation>();
        annotations = AnnotationsFactory.getPointAnnotations(river);

        return annotations;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org