Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java @ 597:cf38b983d1f3
Added the Implementation of the MetaDataService which will deliver FIS and Parameters that match to Mapservices, Region and Layers that were sent to the Service.
gnv-artifacts/trunk@653 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Mon, 01 Feb 2010 14:52:05 +0000 |
parents | |
children | 938ce81a6bd0 |
comparison
equal
deleted
inserted
replaced
596:75ef37387e84 | 597:cf38b983d1f3 |
---|---|
1 /** | |
2 * | |
3 */ | |
4 package de.intevation.gnv.artifacts.services; | |
5 | |
6 import java.util.ArrayList; | |
7 import java.util.Collection; | |
8 import java.util.Iterator; | |
9 | |
10 import javax.xml.xpath.XPathConstants; | |
11 | |
12 import org.apache.log4j.Logger; | |
13 import org.w3c.dom.Document; | |
14 import org.w3c.dom.Element; | |
15 import org.w3c.dom.Node; | |
16 import org.w3c.dom.NodeList; | |
17 | |
18 import com.vividsolutions.jts.geom.Geometry; | |
19 import com.vividsolutions.jts.io.ParseException; | |
20 import com.vividsolutions.jts.io.WKTReader; | |
21 | |
22 import de.intevation.artifactdatabase.DefaultService; | |
23 import de.intevation.artifactdatabase.XMLUtils; | |
24 import de.intevation.artifacts.ArtifactNamespaceContext; | |
25 import de.intevation.artifacts.CallMeta; | |
26 import de.intevation.artifacts.ServiceFactory; | |
27 import de.intevation.gnv.artifacts.services.requestobjects.DefaultFIS; | |
28 import de.intevation.gnv.artifacts.services.requestobjects.DefaultLayer; | |
29 import de.intevation.gnv.artifacts.services.requestobjects.DefaultMapService; | |
30 import de.intevation.gnv.artifacts.services.requestobjects.FIS; | |
31 import de.intevation.gnv.artifacts.services.requestobjects.Layer; | |
32 import de.intevation.gnv.artifacts.services.requestobjects.MapService; | |
33 import de.intevation.gnv.artifacts.services.requestobjects.Parameter; | |
34 import de.intevation.gnv.geobackend.base.Result; | |
35 import de.intevation.gnv.geobackend.base.query.QueryExecutor; | |
36 import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; | |
37 import de.intevation.gnv.geobackend.base.query.exception.QueryException; | |
38 import de.intevation.gnv.utils.ArtifactXMLUtilities; | |
39 | |
40 /** | |
41 * @author Tim Englich <tim.englich@intevation.de> | |
42 * | |
43 */ | |
44 public class MetaDataService extends DefaultService { | |
45 | |
46 /** | |
47 * the logger, used to log exceptions and additionally information | |
48 */ | |
49 private static Logger log = Logger.getLogger(MetaDataService.class); | |
50 | |
51 | |
52 private final static String FIS_REGION_QUERY_ID = "fis_region"; | |
53 private final static String MAPSERVICES_HAS_FIS_QUERY_ID = | |
54 "mapservices_has_fis"; | |
55 | |
56 private static String ATTRIBUTE_ID = "id"; | |
57 private static String ATTRIBUTE_NAME = "name"; | |
58 private static String ATTRIBUTE_TYPE = "type"; | |
59 private static String ATTRIBUTE_URL = "url"; | |
60 private static String ATTRIBUTE_GROUPLAYER = "isgrouplayer"; | |
61 private static String ATTRIBUTE_PARENTID = "parentid"; | |
62 private static String ATTRIBUTE_SRS = "srs"; | |
63 | |
64 | |
65 private static String XPATH_LOACTION_NODE = "art:GetMetaData/art:location"; | |
66 private static String XPATH_MAPSERVICES_NODESET = "art:GetMetaData/" + | |
67 "art:mapservices/" + | |
68 "art:mapservice"; | |
69 private static String XPATH_LAYER_NODESET = "art:layer"; | |
70 | |
71 /** | |
72 * The UID of this Class. | |
73 */ | |
74 private static final long serialVersionUID = -8446483887497236372L; | |
75 | |
76 /** | |
77 * Constructor | |
78 */ | |
79 public MetaDataService() { | |
80 super(); | |
81 } | |
82 | |
83 /** | |
84 * @see de.intevation.artifactdatabase.DefaultService#process(org.w3c.dom.Document, java.lang.Object, de.intevation.artifacts.CallMeta) | |
85 */ | |
86 @Override | |
87 public Document process(Document data, Object globalContext, | |
88 CallMeta callMeta) { | |
89 log.debug("MetaDataService.process"); | |
90 Document document = null; | |
91 try { | |
92 Geometry g = this.parseGeometry(data); | |
93 Collection<MapService> mapServices = this.parseMapServices(data); | |
94 Collection<FIS> resultFIS = this.unionFIS(this.getFIS(g), | |
95 this.getFIS(mapServices)); | |
96 document = XMLUtils.newDocument(); | |
97 this.writeFIS2Document(document, resultFIS); | |
98 } catch (MetaDataServiceException e) { | |
99 log.error(e,e); | |
100 document = new ArtifactXMLUtilities() | |
101 .createExceptionReport(e.getMessage(), document); | |
102 } | |
103 return document; | |
104 } | |
105 | |
106 private Geometry parseGeometry(Document data) | |
107 throws MetaDataServiceException{ | |
108 log.debug("MetaDataService.parseGeometry"); | |
109 | |
110 Element locationNode = (Element) XMLUtils.xpath( | |
111 data, | |
112 XPATH_LOACTION_NODE, | |
113 XPathConstants.NODE, | |
114 ArtifactNamespaceContext.INSTANCE | |
115 ); | |
116 Geometry returnValue = null; | |
117 if (locationNode != null) { | |
118 String srs = locationNode.getAttribute(ATTRIBUTE_SRS); | |
119 // TODO: use SRS to transform the Geometry to target-System. | |
120 String geometryValue = locationNode.getTextContent(); | |
121 if (geometryValue != null){ | |
122 try { | |
123 returnValue = new WKTReader().read(geometryValue); | |
124 } catch (ParseException e) { | |
125 log.error(e,e); | |
126 throw new MetaDataServiceException("The given Geometry" + | |
127 "String is not a " + | |
128 "valid WKT."); | |
129 } | |
130 } | |
131 } | |
132 return returnValue; | |
133 } | |
134 | |
135 private Collection<MapService> parseMapServices(Document data){ | |
136 log.debug("MetaDataService.parseMapServices"); | |
137 | |
138 NodeList mapServices = (NodeList) XMLUtils.xpath(data, | |
139 XPATH_MAPSERVICES_NODESET, | |
140 XPathConstants.NODESET, | |
141 ArtifactNamespaceContext.INSTANCE); | |
142 Collection<MapService> returnValue = null; | |
143 if (mapServices != null){ | |
144 returnValue = new ArrayList<MapService>(mapServices.getLength()); | |
145 for (int i = 0; i < mapServices.getLength(); i++){ | |
146 Element mapServiceNode = (Element)mapServices.item(i); | |
147 String id = mapServiceNode.getAttribute(ATTRIBUTE_ID); | |
148 String type = mapServiceNode.getAttribute(ATTRIBUTE_TYPE); | |
149 String url = mapServiceNode.getAttribute(ATTRIBUTE_URL); | |
150 Collection<Layer> layer = null; | |
151 | |
152 NodeList layerNodes = (NodeList) XMLUtils.xpath(mapServiceNode, | |
153 XPATH_LAYER_NODESET, | |
154 XPathConstants.NODESET, | |
155 ArtifactNamespaceContext.INSTANCE); | |
156 if (layerNodes != null){ | |
157 layer = new ArrayList<Layer>(layerNodes.getLength()); | |
158 for (int j = 0; j < layerNodes.getLength(); j++){ | |
159 Element layerNode = (Element)layerNodes.item(j); | |
160 String layerId = layerNode.getAttribute(ATTRIBUTE_ID); | |
161 String layerName = layerNode.getAttribute(ATTRIBUTE_NAME); | |
162 boolean isGroupLayer = | |
163 Boolean.parseBoolean(layerNode | |
164 .getAttribute( | |
165 ATTRIBUTE_GROUPLAYER)); | |
166 String parentId = layerNode | |
167 .getAttribute(ATTRIBUTE_PARENTID); | |
168 | |
169 layer.add(new DefaultLayer(layerId, | |
170 layerName, | |
171 isGroupLayer, | |
172 parentId)); | |
173 } | |
174 } | |
175 MapService mapService = new DefaultMapService(id, layer, | |
176 type, url); | |
177 returnValue.add(mapService); | |
178 | |
179 } | |
180 } | |
181 return returnValue; | |
182 } | |
183 | |
184 private Collection<FIS> unionFIS(Collection<FIS> fromGeometry, | |
185 Collection<FIS> fromMapservices){ | |
186 log.debug("MetaDataService.unionFIS"); | |
187 Collection<FIS> returnValue = null; | |
188 if (fromGeometry == null || fromGeometry.isEmpty()){ | |
189 returnValue = fromMapservices; | |
190 }else if (fromMapservices == null || fromMapservices.isEmpty()){ | |
191 returnValue = fromGeometry; | |
192 }else{ | |
193 | |
194 returnValue = new ArrayList<FIS>(); | |
195 Iterator<FIS> it = fromMapservices.iterator(); | |
196 while (it.hasNext()){ | |
197 FIS fis = it.next(); | |
198 if (fromGeometry.contains(fis)){ | |
199 returnValue.add(fis); | |
200 } | |
201 } | |
202 } | |
203 return returnValue; | |
204 } | |
205 | |
206 /** | |
207 * Puts the retrieved FIS into the given XML-Document. | |
208 * @param document the Document where the FIS should be put in. | |
209 * @param fis the retrieved FIS which should be written into | |
210 * the XML-Document. | |
211 */ | |
212 private void writeFIS2Document(Document document, Collection<FIS> fis){ | |
213 | |
214 if (fis != null){ | |
215 Iterator<FIS> it = fis.iterator(); | |
216 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( | |
217 document, | |
218 ArtifactNamespaceContext.NAMESPACE_URI, | |
219 ArtifactNamespaceContext.NAMESPACE_PREFIX | |
220 ); | |
221 Node rootNode = creator.create("result"); | |
222 document.appendChild(rootNode); | |
223 | |
224 Node factoriesNode = creator.create("factories"); | |
225 rootNode.appendChild(factoriesNode); | |
226 while (it.hasNext()){ | |
227 FIS tmpFIS = it.next(); | |
228 Element fisNode = creator.create("factory"); | |
229 fisNode.setAttribute("art:name",tmpFIS.getID()); | |
230 | |
231 Collection<Parameter> parameter = tmpFIS.getParameter(); | |
232 | |
233 if(parameter != null){ | |
234 Iterator<Parameter> pit = parameter.iterator(); | |
235 while (pit.hasNext()){ | |
236 Parameter p = pit.next(); | |
237 Element parameterNode = creator.create("parameter"); | |
238 parameterNode.setAttribute(ATTRIBUTE_ID, p.getID()); | |
239 parameterNode.setAttribute(ATTRIBUTE_NAME, p.getName()); | |
240 fisNode.appendChild(parameterNode); | |
241 } | |
242 } | |
243 factoriesNode.appendChild(fisNode); | |
244 } | |
245 } | |
246 } | |
247 | |
248 /** | |
249 * Returns all FIS which Areas is intersected by this given Geometry | |
250 * @param g the Geometry which should be used to determine the FIS. | |
251 * @return all FIS which Areas is intersected by this given Geometry | |
252 */ | |
253 protected Collection<FIS> getFIS(Geometry g) | |
254 throws MetaDataServiceException{ | |
255 log.debug("MetaDataService.getFIS ==> Geometry"); | |
256 Collection<FIS> resultValue = null; | |
257 if (g != null){ | |
258 try { | |
259 QueryExecutor queryExecutor = QueryExecutorFactory | |
260 .getInstance() | |
261 .getQueryExecutor(); | |
262 Collection<Result> result = queryExecutor.executeQuery(FIS_REGION_QUERY_ID, | |
263 new String[]{g.toString()}); | |
264 | |
265 if (result != null){ | |
266 resultValue = new ArrayList<FIS>(result.size()); | |
267 Iterator<Result> it = result.iterator(); | |
268 while (it.hasNext()){ | |
269 Result value = it.next(); | |
270 String fis_id = value.getString(0); | |
271 resultValue.add(new DefaultFIS(fis_id)); | |
272 } | |
273 } | |
274 } catch (QueryException e) { | |
275 log.error(e,e); | |
276 throw new MetaDataServiceException("Cannot Query FIS from DB."); | |
277 } | |
278 } | |
279 return resultValue; | |
280 } | |
281 | |
282 /** | |
283 * Returns all FIS which were represented by the given Mapservices | |
284 * @param mapServices the Mapservices which should determine the FIS. | |
285 * @return all FIS which where represented my the given Mapservices. | |
286 */ | |
287 protected Collection<FIS> getFIS(Collection<MapService> mapServices) | |
288 throws MetaDataServiceException{ | |
289 log.debug("MetaDataService.getFIS ==> MapServices"); | |
290 Collection<FIS> resultValue = null; | |
291 if (mapServices != null && !mapServices.isEmpty()){ | |
292 try { | |
293 | |
294 String mapServiceNames = ""; | |
295 Iterator<MapService> mit = mapServices.iterator(); | |
296 while(mit.hasNext()){ | |
297 if (mapServiceNames.length() > 0){ | |
298 mapServiceNames += " , "; | |
299 } | |
300 mapServiceNames += "\""+mit.next().getID()+"\""; | |
301 } | |
302 | |
303 QueryExecutor queryExecutor = QueryExecutorFactory | |
304 .getInstance() | |
305 .getQueryExecutor(); | |
306 Collection<Result> result = queryExecutor.executeQuery( | |
307 MAPSERVICES_HAS_FIS_QUERY_ID, | |
308 new String[]{mapServiceNames}); | |
309 if (result != null){ | |
310 resultValue = new ArrayList<FIS>(result.size()); | |
311 Iterator<Result> it = result.iterator(); | |
312 while (it.hasNext()){ | |
313 Result value = it.next(); | |
314 String fis_id = value.getString(0); | |
315 | |
316 // TODO: QUERY PARAMS | |
317 // FIRST LOOK IF ONE MAPSERVICE REPRESENTS ONLY ONE PARAM | |
318 // IF FALSE LOOK IF THE GIVEN LAYERs TO AN MAPSERVICE | |
319 // REPRESENTS DIFFERENT PARAMS | |
320 Collection<Parameter> parameter = null; | |
321 resultValue.add(new DefaultFIS(fis_id, parameter)); | |
322 } | |
323 } | |
324 } catch (QueryException e) { | |
325 log.error(e,e); | |
326 throw new MetaDataServiceException("Cannot Query FIS from DB."); | |
327 } | |
328 | |
329 } | |
330 return resultValue; | |
331 } | |
332 | |
333 /** | |
334 * @see de.intevation.artifactdatabase.DefaultService#setup(de.intevation.artifacts.ServiceFactory, java.lang.Object) | |
335 */ | |
336 @Override | |
337 public void setup(ServiceFactory factory, Object globalContext) { | |
338 log.debug("MetaDataService.setup"); | |
339 super.setup(factory, globalContext); | |
340 // TODO: Perhaps it is necessary to init the QueryIds here. | |
341 } | |
342 | |
343 } |