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: ingo@1675: import net.sf.ehcache.Cache; 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@1099: import de.intevation.flys.artifacts.cache.CacheFactory; felix@1026: import de.intevation.flys.artifacts.context.FLYSContext; felix@1099: import de.intevation.flys.artifacts.model.AnnotationsFactory; felix@1026: felix@1026: import de.intevation.flys.model.Annotation; 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: /** Name of cache. */ ingo@1675: public static final String CACHE_NAME = "annotations"; 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 fs = new ArrayList(); 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 felix@1032: * 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 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 list = state.getOutputs(); felix@1026: if (list == null || list.size() == 0) { felix@1026: logger.debug("-> No output modes for this state."); felix@1026: continue; felix@1026: } felix@1026: felix@1771: List fs = facets.get(stateId); felix@1771: if (fs == null || fs.size() == 0) { 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 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 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 fs = facets.get(cur.getID()); felix@1771: if (fs != null && fs.size() > 0) { felix@1771: List 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: } felix@1026: } felix@1026: felix@1026: felix@1026: /** felix@1026: * Get Annotations for Points (opposed to segments) in river in range. felix@1026: * felix@1026: * @return list of Annotations. felix@1026: */ felix@1026: public List getAnnotations() { felix@1099: String river = FLYSUtils.getRiver(this).getName(); ingo@1675: logger.debug("Search annotations for river: " + river); felix@1026: ingo@1675: Cache cache = CacheFactory.getCache(CACHE_NAME); ingo@1675: String key = river; ingo@1675: Object old = null; felix@1026: ingo@1675: if (cache != null) { ingo@1675: logger.debug("We are using a cache for annotations."); ingo@1675: ingo@1675: net.sf.ehcache.Element element = cache.get(key); ingo@1675: if (element != null) { ingo@1675: logger.info("Fetched annotations from cache."); ingo@1675: old = element.getValue(); ingo@1675: } ingo@1675: } ingo@1675: ingo@1675: if (old == null) { ingo@1675: old = getAnnotationsUncached(river); ingo@1675: } ingo@1675: ingo@1675: if (cache != null && old != null) { ingo@1675: cache.put(new net.sf.ehcache.Element(key, old)); ingo@1675: } ingo@1675: ingo@1675: return old != null ingo@1675: ? (List) old ingo@1675: : new ArrayList(); felix@1032: } felix@1032: felix@2112: felix@1032: /** felix@1032: * Gets Annotations from Session/Database. felix@1032: * felix@1032: * @return List of Annotations fetched fresh from session/database. felix@1032: * @see DistanceInfoService to access cached documents. felix@1032: */ felix@1032: protected List getAnnotationsUncached(String river) { ingo@1675: logger.info("Fetch annotations from database."); ingo@1675: felix@1032: List annotations = new ArrayList(); ingo@1631: annotations = AnnotationsFactory.getPointAnnotations(river); ingo@1631: felix@1026: return annotations; felix@1026: } felix@1026: } felix@1026: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :