Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/DistanceInfoService.java @ 2145:e92bc9b0ca1d
DistanceInfoService now uses annotations from LocationProvider.
flys-artifacts/trunk@3724 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 19 Jan 2012 15:43:57 +0000 |
parents | 26e19cdaed5e |
children | df4d6b286af8 |
comparison
equal
deleted
inserted
replaced
2144:a4bdf7d8527e | 2145:e92bc9b0ca1d |
---|---|
1 package de.intevation.flys.artifacts.services; | 1 package de.intevation.flys.artifacts.services; |
2 | 2 |
3 import java.math.BigDecimal; | |
4 import java.util.Iterator; | 3 import java.util.Iterator; |
5 | 4 |
6 import org.apache.log4j.Logger; | 5 import org.apache.log4j.Logger; |
7 | 6 |
8 import org.w3c.dom.Document; | 7 import org.w3c.dom.Document; |
12 import de.intevation.artifacts.GlobalContext; | 11 import de.intevation.artifacts.GlobalContext; |
13 | 12 |
14 import de.intevation.artifacts.common.ArtifactNamespaceContext; | 13 import de.intevation.artifacts.common.ArtifactNamespaceContext; |
15 import de.intevation.artifacts.common.utils.XMLUtils; | 14 import de.intevation.artifacts.common.utils.XMLUtils; |
16 | 15 |
17 import de.intevation.flys.model.Annotation; | 16 import de.intevation.flys.model.FastAnnotations; |
18 import de.intevation.flys.model.Attribute; | |
19 import de.intevation.flys.model.Position; | |
20 import de.intevation.flys.model.Range; | |
21 import de.intevation.flys.model.Edge; | |
22 | 17 |
23 import de.intevation.flys.artifacts.model.AnnotationsFactory; | 18 import de.intevation.flys.artifacts.model.LocationProvider; |
24 | 19 |
25 import de.intevation.flys.artifacts.cache.CacheFactory; | |
26 | |
27 import net.sf.ehcache.Cache; | |
28 | 20 |
29 /** | 21 /** |
30 * This service provides information about distances of a specified river. | 22 * This service provides information about distances of a specified river. |
31 * | 23 * |
32 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | 24 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> |
33 */ | 25 */ |
34 public class DistanceInfoService extends FLYSService { | 26 public class DistanceInfoService extends FLYSService { |
35 | 27 |
36 private static enum DistanceFilter { | |
37 NONE, LOCATIONS, DISTANCES | |
38 } | |
39 | |
40 /** The logger used in this service. */ | 28 /** The logger used in this service. */ |
41 private static Logger logger = Logger.getLogger(DistanceInfoService.class); | 29 private static Logger logger = Logger.getLogger(DistanceInfoService.class); |
42 | |
43 public static final String CACHE_NAME = "service-distanceinfo"; | |
44 | 30 |
45 public static final String RIVER_XPATH = "/art:river/text()"; | 31 public static final String RIVER_XPATH = "/art:river/text()"; |
46 | 32 |
47 public static final String FILTER_XPATH = "/art:river/art:filter/text()"; | 33 public static final String FILTER_XPATH = "/art:river/art:filter/text()"; |
48 | 34 |
63 logger.debug("DistanceInfoService.process"); | 49 logger.debug("DistanceInfoService.process"); |
64 | 50 |
65 String river = XMLUtils.xpathString( | 51 String river = XMLUtils.xpathString( |
66 data, RIVER_XPATH, ArtifactNamespaceContext.INSTANCE); | 52 data, RIVER_XPATH, ArtifactNamespaceContext.INSTANCE); |
67 | 53 |
68 String filter = XMLUtils.xpathString( | 54 String filterName = XMLUtils.xpathString( |
69 data, FILTER_XPATH, ArtifactNamespaceContext.INSTANCE); | 55 data, FILTER_XPATH, ArtifactNamespaceContext.INSTANCE); |
70 | 56 |
71 if (river == null || (river = river.trim()).length() == 0) { | 57 if (river == null || (river = river.trim()).length() == 0) { |
72 logger.warn("No river specified. Cannot return distance info!"); | 58 logger.warn("No river specified. Cannot return distance info!"); |
73 return XMLUtils.newDocument(); | 59 return XMLUtils.newDocument(); |
74 } | 60 } |
75 | 61 |
76 logger.debug("Search distances for river: " + river); | 62 logger.debug("Search distances for river: " + river); |
77 | 63 |
78 Cache cache = CacheFactory.getCache(CACHE_NAME); | 64 FastAnnotations fas = LocationProvider.getAnnotations(river); |
79 | 65 |
80 if (cache == null) { | 66 FastAnnotations.Filter filter = selectFilter(filterName); |
81 logger.debug("no cache configured for distance info"); | |
82 return getUncached(river, filter); | |
83 } | |
84 | 67 |
85 | 68 return buildDocument(fas.filter(filter)); |
86 String key = getCacheKey(river, filter); | |
87 | |
88 net.sf.ehcache.Element element = cache.get(key); | |
89 | |
90 if (element != null) { | |
91 logger.debug("distance info found in cache"); | |
92 return (Document)element.getValue(); | |
93 } | |
94 | |
95 Document result = getUncached(river, filter); | |
96 | |
97 element = new net.sf.ehcache.Element(key, result); | |
98 | |
99 logger.debug("store distance info found into cache"); | |
100 | |
101 cache.put(element); | |
102 | |
103 return result; | |
104 } | 69 } |
105 | 70 |
106 | 71 protected Document buildDocument( |
107 protected String getCacheKey(String river, String filtertype) { | 72 Iterator<FastAnnotations.Annotation> iter |
108 return filtertype != null && filtertype.length() > 0 | 73 ) { |
109 ? river + "_" + filtertype | |
110 : river; | |
111 } | |
112 | |
113 | |
114 protected Document getUncached(String river, String filtertype) { | |
115 | |
116 Document result = XMLUtils.newDocument(); | 74 Document result = XMLUtils.newDocument(); |
117 | |
118 Iterator<Annotation> iter = | |
119 AnnotationsFactory.getAnnotationsIterator(river); | |
120 | 75 |
121 Element all = result.createElement("distances"); | 76 Element all = result.createElement("distances"); |
122 | 77 |
123 DistanceFilter filter = getDistanceFilter(filtertype); | |
124 | |
125 while (iter.hasNext()) { | 78 while (iter.hasNext()) { |
126 Annotation a = iter.next(); | 79 all.appendChild(buildNode(result, iter.next())); |
127 Element distance = buildDistanceNode(result, a, filter); | |
128 | |
129 if (distance != null) { | |
130 all.appendChild(distance); | |
131 } | |
132 } | 80 } |
133 | 81 |
134 result.appendChild(all); | 82 result.appendChild(all); |
135 | 83 |
136 return result; | 84 return result; |
137 } | 85 } |
138 | 86 |
87 protected static FastAnnotations.Filter selectFilter(String name) { | |
139 | 88 |
140 protected static DistanceFilter getDistanceFilter(String type) { | 89 if (name != null) { |
141 if (type.equals("locations")) { | 90 if ("locations".equals(name)) return FastAnnotations.IS_POINT; |
142 logger.debug("Found 'location' filter."); | 91 if ("distances".equals(name)) return FastAnnotations.IS_RANGE; |
143 return DistanceFilter.LOCATIONS; | |
144 } | |
145 else if (type.equals("distances")) { | |
146 logger.debug("Found 'distances' filter."); | |
147 return DistanceFilter.DISTANCES; | |
148 } | 92 } |
149 | 93 |
150 logger.debug("Do not use any filter at all."); | 94 return FastAnnotations.ALL; |
151 | |
152 return DistanceFilter.NONE; | |
153 } | 95 } |
154 | |
155 | 96 |
156 /** | 97 /** |
157 * Builds an Element for a distance info. | 98 * Builds an Element for a distance info. |
158 * | 99 * |
159 * @param anno The Annotation that provides information about the distance. | 100 * @param an The Annotation that provides information about the distance. |
160 * | 101 * |
161 * @return an Element that contains information about a distance. | 102 * @return an Element that contains information about a distance. |
162 */ | 103 */ |
163 protected static Element buildDistanceNode( | 104 protected static Element buildNode( |
164 Document document, | 105 Document document, |
165 Annotation anno, | 106 FastAnnotations.Annotation an |
166 DistanceFilter filter | |
167 ) { | 107 ) { |
168 Position pos = anno.getPosition(); | |
169 Range range = anno.getRange(); | |
170 Attribute attr = anno.getAttribute(); | |
171 Edge edge = anno.getEdge(); | |
172 BigDecimal a = range.getA(); | |
173 BigDecimal b = range.getB(); | |
174 | |
175 if (b == null && filter == DistanceFilter.DISTANCES) { | |
176 return null; | |
177 } | |
178 | |
179 if (b != null && filter == DistanceFilter.LOCATIONS) { | |
180 return null; | |
181 } | |
182 | |
183 Element distance = document.createElement("distance"); | 108 Element distance = document.createElement("distance"); |
184 | 109 |
185 distance.setAttribute("description", pos.getValue()); | 110 distance.setAttribute("description", an.getPosition()); |
186 | 111 |
187 String riverSide = attr.getValue(); | 112 String riverSide = an.getAttribute(); |
188 | 113 |
189 if (riverSide != null && riverSide.length() > 0) { | 114 if (riverSide != null && riverSide.length() > 0) { |
190 distance.setAttribute("riverside", riverSide); | 115 distance.setAttribute("riverside", riverSide); |
191 } | 116 } |
192 | 117 |
193 if (a != null) { | 118 distance.setAttribute("from", String.valueOf(an.getA())); |
194 distance.setAttribute("from", a.toString()); | 119 |
120 double b = an.getB(); | |
121 double bottom = an.getBottom(); | |
122 double top = an.getTop(); | |
123 | |
124 if (!Double.isNaN(b)) { | |
125 distance.setAttribute("to", String.valueOf(b)); | |
195 } | 126 } |
196 if (b != null) { | 127 |
197 distance.setAttribute("to", b.toString()); | 128 if (!Double.isNaN(bottom)) { |
129 distance.setAttribute("bottom", String.valueOf(bottom)); | |
198 } | 130 } |
199 if (edge != null) { | 131 |
200 BigDecimal bottom = edge.getBottom(); | 132 if (!Double.isNaN(top)) { |
201 BigDecimal top = edge.getTop(); | 133 distance.setAttribute("top", String.valueOf(top)); |
202 if (bottom != null) { | |
203 distance.setAttribute("bottom", bottom.toString()); | |
204 } | |
205 if (top != null) { | |
206 distance.setAttribute("top", top.toString()); | |
207 } | |
208 } | 134 } |
209 | 135 |
210 return distance; | 136 return distance; |
211 } | 137 } |
212 } | 138 } |