ingo@301: package de.intevation.flys.artifacts.services; ingo@301: ingo@301: import java.math.BigDecimal; sascha@644: import java.util.Iterator; ingo@301: ingo@301: import org.apache.log4j.Logger; ingo@301: ingo@301: import org.w3c.dom.Document; ingo@301: import org.w3c.dom.Element; ingo@301: ingo@301: import de.intevation.artifacts.CallMeta; ingo@301: ingo@301: import de.intevation.artifacts.common.ArtifactNamespaceContext; ingo@301: import de.intevation.artifacts.common.utils.XMLUtils; ingo@301: import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; ingo@301: ingo@301: import de.intevation.artifactdatabase.DefaultService; ingo@301: ingo@316: import de.intevation.flys.backend.SessionHolder; ingo@301: import de.intevation.flys.model.Annotation; ingo@301: import de.intevation.flys.model.Attribute; ingo@301: import de.intevation.flys.model.Position; ingo@301: import de.intevation.flys.model.Range; sascha@680: import de.intevation.flys.model.Edge; ingo@301: ingo@301: import de.intevation.flys.artifacts.model.AnnotationsFactory; ingo@301: sascha@314: import org.hibernate.Session; ingo@301: sascha@644: import de.intevation.flys.artifacts.cache.CacheFactory; sascha@644: sascha@644: import net.sf.ehcache.Cache; sascha@644: ingo@301: /** ingo@301: * This service provides information about distances of a specified river. ingo@301: * ingo@301: * @author Ingo Weinzierl ingo@301: */ ingo@301: public class DistanceInfoService extends DefaultService { ingo@301: ingo@301: /** The logger used in this service.*/ ingo@301: private static Logger logger = Logger.getLogger(DistanceInfoService.class); ingo@301: sascha@644: public static final String CACHE_NAME = "service-distanceinfo"; sascha@644: sascha@644: public static final String RIVER_XPATH = "/art:river/text()"; sascha@644: ingo@301: ingo@301: /** ingo@301: * The default constructor. ingo@301: */ ingo@301: public DistanceInfoService() { ingo@301: } ingo@301: ingo@301: ingo@301: public Document process( ingo@301: Document data, ingo@301: Object globalContext, ingo@301: CallMeta callMeta) ingo@301: { ingo@301: logger.debug("DistanceInfoService.process"); ingo@301: ingo@301: String river = XMLUtils.xpathString( sascha@644: data, RIVER_XPATH, ArtifactNamespaceContext.INSTANCE); ingo@301: sascha@644: if (river == null || (river = river.trim()).length() == 0) { ingo@301: logger.warn("No river specified. Cannot return distance info!"); sascha@644: return XMLUtils.newDocument(); ingo@301: } ingo@301: ingo@301: logger.debug("Search distances for river: " + river); ingo@301: sascha@644: Cache cache = CacheFactory.getCache(CACHE_NAME); sascha@644: sascha@644: if (cache == null) { sascha@644: logger.debug("no cache configured for distance info"); sascha@644: return getUncached(river); sascha@644: } sascha@644: sascha@644: net.sf.ehcache.Element element = cache.get(river); sascha@644: sascha@644: if (element != null) { sascha@644: logger.debug("distance info found in cache"); sascha@644: return (Document)element.getValue(); sascha@644: } sascha@644: sascha@644: Document result = getUncached(river); sascha@644: sascha@644: element = new net.sf.ehcache.Element(river, result); sascha@644: sascha@644: logger.debug("store distance info found into cache"); sascha@644: sascha@644: cache.put(element); sascha@644: sascha@644: return result; sascha@644: } sascha@644: sascha@644: protected Document getUncached(String river) { sascha@644: sascha@644: Document result = XMLUtils.newDocument(); sascha@644: ingo@301: ElementCreator ec = new ElementCreator( ingo@301: result, ingo@301: ArtifactNamespaceContext.NAMESPACE_URI, ingo@301: ArtifactNamespaceContext.NAMESPACE_PREFIX); ingo@301: sascha@314: Session session = SessionHolder.acquire(); ingo@301: sascha@644: try { sascha@644: Iterator iter = sascha@644: AnnotationsFactory.getAnnotationsIterator(river); ingo@301: sascha@314: Element all = ec.create("distances"); sascha@314: sascha@644: while (iter.hasNext()) { sascha@644: Annotation a = iter.next(); sascha@314: Element distance = buildDistanceNode(ec, a); sascha@644: all.appendChild(distance); ingo@301: } sascha@314: sascha@314: result.appendChild(all); ingo@301: } sascha@314: finally { sascha@314: session.close(); sascha@314: SessionHolder.release(); sascha@314: } ingo@301: ingo@301: return result; ingo@301: } ingo@301: ingo@301: ingo@301: /** ingo@301: * This method build an Element for a distance info. ingo@301: * ingo@301: * @param ec The ElementCreator. ingo@301: * @param anno The Annotation that provides information about the distance. ingo@301: * ingo@301: * @return an Element that contains information about a distance. ingo@301: */ sascha@644: protected static Element buildDistanceNode(ElementCreator ec, Annotation anno) { ingo@301: Position pos = anno.getPosition(); ingo@301: Range range = anno.getRange(); ingo@301: Attribute attr = anno.getAttribute(); sascha@680: Edge edge = anno.getEdge(); ingo@301: ingo@301: BigDecimal a = range.getA(); ingo@301: BigDecimal b = range.getB(); ingo@301: ingo@301: Element distance = ec.create("distance"); ingo@301: ec.addAttr(distance, "description", pos.getValue(), true); ingo@301: ec.addAttr(distance, "riverside", attr.getValue(), true); ingo@301: sascha@680: if (a != null) { sascha@680: ec.addAttr(distance, "from", a.toString(), true); sascha@680: } sascha@680: if (b != null) { sascha@680: ec.addAttr(distance, "to", b.toString(), true); sascha@680: } sascha@680: if (edge != null) { sascha@680: BigDecimal bottom = edge.getBottom(); sascha@680: BigDecimal top = edge.getTop(); sascha@680: if (bottom != null) { sascha@680: ec.addAttr(distance, "bottom", bottom.toString(), true); sascha@680: } sascha@680: if (top != null) { sascha@680: ec.addAttr(distance, "top", top.toString(), true); sascha@680: } sascha@680: } sascha@680: ingo@301: return distance; ingo@301: } ingo@301: } ingo@301: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :