Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/services/MetaDataService.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | 9efc1c256dbb |
children | 9a828e5a2390 |
comparison
equal
deleted
inserted
replaced
590:5f5f273c8566 | 657:af3f56758f59 |
---|---|
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.DefaultParameter; | |
31 import de.intevation.gnv.artifacts.services.requestobjects.FIS; | |
32 import de.intevation.gnv.artifacts.services.requestobjects.Layer; | |
33 import de.intevation.gnv.artifacts.services.requestobjects.MapService; | |
34 import de.intevation.gnv.artifacts.services.requestobjects.Parameter; | |
35 import de.intevation.gnv.geobackend.base.Result; | |
36 import de.intevation.gnv.geobackend.base.query.QueryExecutor; | |
37 import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; | |
38 import de.intevation.gnv.geobackend.base.query.exception.QueryException; | |
39 import de.intevation.gnv.utils.ArtifactXMLUtilities; | |
40 | |
41 /** | |
42 * @author Tim Englich <tim.englich@intevation.de> | |
43 * | |
44 */ | |
45 public class MetaDataService extends DefaultService { | |
46 | |
47 /** | |
48 * the logger, used to log exceptions and additionally information | |
49 */ | |
50 private static Logger log = Logger.getLogger(MetaDataService.class); | |
51 | |
52 | |
53 private final static String FIS_REGION_QUERY_ID = | |
54 "mapviewer_interface_fis_region"; | |
55 private final static String MAPSERVICES_HAS_FIS_QUERY_ID = | |
56 "mapviewer_interface_mapservices_has_fis"; | |
57 private final static String MAPSERVICES_HAS_PARAMETER_QUERY_ID = | |
58 "mapviewer_interface_mapservices_has_parameter"; | |
59 | |
60 private final static String MAPSERVICES_HAS_PARAMETER_USING_LAYER_QUERY_ID = | |
61 "mapviewer_interface_mapservices_has_parameter_using_layer"; | |
62 | |
63 private static String ATTRIBUTE_ID = "id"; | |
64 private static String ATTRIBUTE_NAME = "name"; | |
65 private static String ATTRIBUTE_TYPE = "type"; | |
66 private static String ATTRIBUTE_URL = "url"; | |
67 private static String ATTRIBUTE_GROUPLAYER = "isgrouplayer"; | |
68 private static String ATTRIBUTE_PARENTID = "parentid"; | |
69 private static String ATTRIBUTE_SRS = "srs"; | |
70 | |
71 | |
72 private static String XPATH_LOACTION_NODE = "art:GetMetaData/art:location"; | |
73 private static String XPATH_MAPSERVICES_NODESET = "art:GetMetaData/" + | |
74 "art:mapservices/" + | |
75 "art:mapservice"; | |
76 private static String XPATH_LAYER_NODESET = "art:layer"; | |
77 | |
78 /** | |
79 * The UID of this Class. | |
80 */ | |
81 private static final long serialVersionUID = -8446483887497236372L; | |
82 | |
83 /** | |
84 * Constructor | |
85 */ | |
86 public MetaDataService() { | |
87 super(); | |
88 } | |
89 | |
90 /** | |
91 * @see de.intevation.artifactdatabase.DefaultService#process(org.w3c.dom.Document, java.lang.Object, de.intevation.artifacts.CallMeta) | |
92 */ | |
93 @Override | |
94 public Document process(Document data, Object globalContext, | |
95 CallMeta callMeta) { | |
96 log.debug("MetaDataService.process"); | |
97 Document document = null; | |
98 try { | |
99 Geometry g = this.parseGeometry(data); | |
100 Collection<MapService> mapServices = this.parseMapServices(data); | |
101 Collection<FIS> resultFIS = this.unionFIS(this.getFIS(g), | |
102 this.getFIS(mapServices)); | |
103 document = XMLUtils.newDocument(); | |
104 this.writeFIS2Document(document, resultFIS); | |
105 log.debug(new ArtifactXMLUtilities().writeDocument2String(document)); | |
106 } catch (MetaDataServiceException e) { | |
107 log.error(e,e); | |
108 document = new ArtifactXMLUtilities() | |
109 .createExceptionReport(e.getMessage(), document); | |
110 } | |
111 return document; | |
112 } | |
113 | |
114 private Geometry parseGeometry(Document data) | |
115 throws MetaDataServiceException{ | |
116 log.debug("MetaDataService.parseGeometry"); | |
117 | |
118 Element locationNode = (Element) XMLUtils.xpath( | |
119 data, | |
120 XPATH_LOACTION_NODE, | |
121 XPathConstants.NODE, | |
122 ArtifactNamespaceContext.INSTANCE | |
123 ); | |
124 Geometry returnValue = null; | |
125 if (locationNode != null) { | |
126 String srs = locationNode.getAttribute(ATTRIBUTE_SRS); | |
127 // TODO: use SRS to transform the Geometry to target-System. | |
128 String geometryValue = locationNode.getTextContent(); | |
129 if (geometryValue != null){ | |
130 try { | |
131 returnValue = new WKTReader().read(geometryValue); | |
132 } catch (ParseException e) { | |
133 log.error(e,e); | |
134 throw new MetaDataServiceException("The given Geometry" + | |
135 "String is not a " + | |
136 "valid WKT."); | |
137 } | |
138 } | |
139 } | |
140 return returnValue; | |
141 } | |
142 | |
143 private Collection<MapService> parseMapServices(Document data){ | |
144 log.debug("MetaDataService.parseMapServices"); | |
145 | |
146 NodeList mapServices = (NodeList) XMLUtils.xpath(data, | |
147 XPATH_MAPSERVICES_NODESET, | |
148 XPathConstants.NODESET, | |
149 ArtifactNamespaceContext.INSTANCE); | |
150 Collection<MapService> returnValue = null; | |
151 if (mapServices != null){ | |
152 returnValue = new ArrayList<MapService>(mapServices.getLength()); | |
153 for (int i = 0; i < mapServices.getLength(); i++){ | |
154 Element mapServiceNode = (Element)mapServices.item(i); | |
155 String id = mapServiceNode.getAttribute(ATTRIBUTE_ID); | |
156 String type = mapServiceNode.getAttribute(ATTRIBUTE_TYPE); | |
157 String url = mapServiceNode.getAttribute(ATTRIBUTE_URL); | |
158 Collection<Layer> layer = null; | |
159 | |
160 NodeList layerNodes = (NodeList) XMLUtils.xpath(mapServiceNode, | |
161 XPATH_LAYER_NODESET, | |
162 XPathConstants.NODESET, | |
163 ArtifactNamespaceContext.INSTANCE); | |
164 if (layerNodes != null){ | |
165 layer = new ArrayList<Layer>(layerNodes.getLength()); | |
166 for (int j = 0; j < layerNodes.getLength(); j++){ | |
167 Element layerNode = (Element)layerNodes.item(j); | |
168 String layerId = layerNode.getAttribute(ATTRIBUTE_ID); | |
169 String layerName = layerNode.getAttribute(ATTRIBUTE_NAME); | |
170 boolean isGroupLayer = | |
171 Boolean.parseBoolean(layerNode | |
172 .getAttribute( | |
173 ATTRIBUTE_GROUPLAYER)); | |
174 String parentId = layerNode | |
175 .getAttribute(ATTRIBUTE_PARENTID); | |
176 | |
177 layer.add(new DefaultLayer(layerId, | |
178 layerName, | |
179 isGroupLayer, | |
180 parentId)); | |
181 } | |
182 } | |
183 MapService mapService = new DefaultMapService(id, layer, | |
184 type, url); | |
185 returnValue.add(mapService); | |
186 | |
187 } | |
188 } | |
189 return returnValue; | |
190 } | |
191 | |
192 private Collection<FIS> unionFIS(Collection<FIS> fromGeometry, | |
193 Collection<FIS> fromMapservices){ | |
194 log.debug("MetaDataService.unionFIS"); | |
195 Collection<FIS> returnValue = null; | |
196 if (fromGeometry == null || fromGeometry.isEmpty()){ | |
197 returnValue = fromMapservices; | |
198 }else if (fromMapservices == null || fromMapservices.isEmpty()){ | |
199 returnValue = fromGeometry; | |
200 }else{ | |
201 | |
202 returnValue = new ArrayList<FIS>(); | |
203 Iterator<FIS> it = fromMapservices.iterator(); | |
204 while (it.hasNext()){ | |
205 FIS fis = it.next(); | |
206 if (fromGeometry.contains(fis)){ | |
207 returnValue.add(fis); | |
208 } | |
209 } | |
210 } | |
211 return returnValue; | |
212 } | |
213 | |
214 /** | |
215 * Puts the retrieved FIS into the given XML-Document. | |
216 * @param document the Document where the FIS should be put in. | |
217 * @param fis the retrieved FIS which should be written into | |
218 * the XML-Document. | |
219 */ | |
220 private void writeFIS2Document(Document document, Collection<FIS> fis){ | |
221 | |
222 if (fis != null){ | |
223 Iterator<FIS> it = fis.iterator(); | |
224 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( | |
225 document, | |
226 ArtifactNamespaceContext.NAMESPACE_URI, | |
227 ArtifactNamespaceContext.NAMESPACE_PREFIX | |
228 ); | |
229 Node rootNode = creator.create("result"); | |
230 document.appendChild(rootNode); | |
231 | |
232 Node factoriesNode = creator.create("factories"); | |
233 rootNode.appendChild(factoriesNode); | |
234 while (it.hasNext()){ | |
235 FIS tmpFIS = it.next(); | |
236 Element fisNode = creator.create("factory"); | |
237 fisNode.setAttribute("art:name",tmpFIS.getID()); | |
238 | |
239 Collection<Parameter> parameter = tmpFIS.getParameter(); | |
240 | |
241 if(parameter != null){ | |
242 Iterator<Parameter> pit = parameter.iterator(); | |
243 while (pit.hasNext()){ | |
244 Parameter p = pit.next(); | |
245 Element parameterNode = creator.create("parameter"); | |
246 parameterNode.setAttribute(ATTRIBUTE_ID, p.getID()); | |
247 parameterNode.setAttribute(ATTRIBUTE_NAME, p.getName()); | |
248 fisNode.appendChild(parameterNode); | |
249 } | |
250 } | |
251 factoriesNode.appendChild(fisNode); | |
252 } | |
253 } | |
254 } | |
255 | |
256 /** | |
257 * Returns all FIS which Areas is intersected by this given Geometry | |
258 * @param g the Geometry which should be used to determine the FIS. | |
259 * @return all FIS which Areas is intersected by this given Geometry | |
260 */ | |
261 protected Collection<FIS> getFIS(Geometry g) | |
262 throws MetaDataServiceException{ | |
263 log.debug("MetaDataService.getFIS ==> Geometry"); | |
264 Collection<FIS> resultValue = null; | |
265 if (g != null){ | |
266 try { | |
267 QueryExecutor queryExecutor = QueryExecutorFactory | |
268 .getInstance() | |
269 .getQueryExecutor(); | |
270 Collection<Result> result = queryExecutor.executeQuery(FIS_REGION_QUERY_ID, | |
271 new String[]{g.toString()}); | |
272 | |
273 if (result != null){ | |
274 resultValue = new ArrayList<FIS>(result.size()); | |
275 Iterator<Result> it = result.iterator(); | |
276 while (it.hasNext()){ | |
277 Result value = it.next(); | |
278 String fis_id = value.getString(0).trim(); | |
279 resultValue.add(new DefaultFIS(fis_id)); | |
280 } | |
281 } | |
282 } catch (QueryException e) { | |
283 log.error(e,e); | |
284 throw new MetaDataServiceException("Cannot Query FIS from DB."); | |
285 } | |
286 } | |
287 return resultValue; | |
288 } | |
289 | |
290 /** | |
291 * Returns all FIS which were represented by the given Mapservices | |
292 * @param mapServices the Mapservices which should determine the FIS. | |
293 * @return all FIS which where represented my the given Mapservices. | |
294 */ | |
295 protected Collection<FIS> getFIS(Collection<MapService> mapServices) | |
296 throws MetaDataServiceException{ | |
297 log.debug("MetaDataService.getFIS ==> MapServices"); | |
298 Collection<FIS> resultValue = null; | |
299 if (mapServices != null && !mapServices.isEmpty()){ | |
300 try { | |
301 | |
302 String mapServiceNames = ""; | |
303 Iterator<MapService> mit = mapServices.iterator(); | |
304 while(mit.hasNext()){ | |
305 if (mapServiceNames.length() > 0){ | |
306 mapServiceNames += " , "; | |
307 } | |
308 mapServiceNames += "'"+mit.next().getID()+"'"; | |
309 } | |
310 | |
311 QueryExecutor queryExecutor = QueryExecutorFactory | |
312 .getInstance() | |
313 .getQueryExecutor(); | |
314 Collection<Result> result = queryExecutor.executeQuery( | |
315 MAPSERVICES_HAS_FIS_QUERY_ID, | |
316 new String[]{mapServiceNames}); | |
317 if (result != null){ | |
318 resultValue = new ArrayList<FIS>(result.size()); | |
319 Iterator<Result> it = result.iterator(); | |
320 while (it.hasNext()){ | |
321 Result value = it.next(); | |
322 String fisId = value.getString(0).trim(); | |
323 String mapServiceID = value.getString(1).trim(); | |
324 | |
325 // FIRST LOOK IF ONE MAPSERVICE REPRESENTS ONLY ONE PARAM | |
326 Collection<Result> result2 = queryExecutor.executeQuery( | |
327 MAPSERVICES_HAS_PARAMETER_QUERY_ID, | |
328 new String[]{"'"+mapServiceID+"'"}); | |
329 Collection<Parameter> parameter = null; | |
330 if (result2 != null && result2.size() == 1){ | |
331 Iterator<Result> it2 = result2.iterator(); | |
332 parameter = new ArrayList<Parameter>(1); | |
333 while (it2.hasNext()){ | |
334 Result parameterValue = it2.next(); | |
335 String parameterID = parameterValue.getString(0) | |
336 .trim(); | |
337 parameter.add(new DefaultParameter(parameterID, | |
338 parameterID)); | |
339 } | |
340 }else{ | |
341 // IF FALSE LOOK IF THE GIVEN LAYERs TO AN MAPSERVICE | |
342 // REPRESENTS DIFFERENT PARAMS | |
343 MapService service = this.getMapService(mapServices, | |
344 mapServiceID); | |
345 Collection<Layer> layer = service.getLayer(); | |
346 if (layer != null && !layer.isEmpty()){ | |
347 String layerQueryString = | |
348 this.createLayerQueryString(layer); | |
349 Collection<Result> parameterResult = | |
350 queryExecutor.executeQuery( | |
351 MAPSERVICES_HAS_PARAMETER_USING_LAYER_QUERY_ID, | |
352 new String[]{"'"+mapServiceID+"'", | |
353 layerQueryString}); | |
354 if (parameterResult != null && | |
355 !parameterResult.isEmpty()){ | |
356 Iterator<Result> it2 = parameterResult.iterator(); | |
357 parameter = new ArrayList<Parameter>(parameterResult.size()); | |
358 while (it2.hasNext()){ | |
359 Result parameterValue = it2.next(); | |
360 String parameterID = parameterValue.getString(0) | |
361 .trim(); | |
362 parameter.add(new DefaultParameter(parameterID, | |
363 parameterID)); | |
364 } | |
365 } | |
366 } | |
367 | |
368 } | |
369 | |
370 FIS fis = this.getFIS(resultValue, fisId); | |
371 if (fis != null){ | |
372 if (parameter != null){ | |
373 fis.addParameter(parameter); | |
374 } | |
375 }else{ | |
376 resultValue.add(new DefaultFIS(fisId, parameter)); | |
377 } | |
378 } | |
379 } | |
380 } catch (QueryException e) { | |
381 log.error(e,e); | |
382 throw new MetaDataServiceException("Cannot Query FIS from DB."); | |
383 } | |
384 | |
385 } | |
386 return resultValue; | |
387 } | |
388 | |
389 | |
390 private FIS getFIS (Collection<FIS> fis, String fisId){ | |
391 | |
392 Iterator<FIS> it = fis.iterator(); | |
393 while(it.hasNext()){ | |
394 FIS tmpFIS = it.next(); | |
395 if (tmpFIS.getID().equals(fisId)){ | |
396 return tmpFIS; | |
397 } | |
398 } | |
399 return null; | |
400 } | |
401 | |
402 private MapService getMapService(Collection<MapService> mapServices, | |
403 String mapServiceID){ | |
404 log.debug("MetaDataService.getMapService"); | |
405 Iterator<MapService> it = mapServices.iterator(); | |
406 while (it.hasNext()){ | |
407 MapService service = it.next(); | |
408 if (service.getID().equals(mapServiceID)){ | |
409 return service; | |
410 } | |
411 } | |
412 return null; | |
413 } | |
414 | |
415 private String createLayerQueryString(Collection<Layer> layer){ | |
416 log.debug("MetaDataService.createLayerQueryString"); | |
417 StringBuffer sb = new StringBuffer();; | |
418 Iterator<Layer> it = layer.iterator(); | |
419 synchronized (sb) { | |
420 while (it.hasNext()){ | |
421 Layer l = it.next(); | |
422 if (!l.isGroupLayer()){ | |
423 sb.append(l.getID()); | |
424 if (it.hasNext()){ | |
425 sb.append(" , "); | |
426 } | |
427 } | |
428 | |
429 } | |
430 } | |
431 String returnValue = sb.toString(); | |
432 if (returnValue.endsWith(" , ")){ | |
433 returnValue = returnValue.substring(0,returnValue | |
434 .lastIndexOf(",")) | |
435 .trim(); | |
436 } | |
437 return returnValue; | |
438 } | |
439 | |
440 /** | |
441 * @see de.intevation.artifactdatabase.DefaultService#setup(de.intevation.artifacts.ServiceFactory, java.lang.Object) | |
442 */ | |
443 @Override | |
444 public void setup(ServiceFactory factory, Object globalContext) { | |
445 log.debug("MetaDataService.setup"); | |
446 super.setup(factory, globalContext); | |
447 // TODO: Perhaps it is necessary to init the QueryIds here. | |
448 } | |
449 | |
450 } |