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 }

http://dive4elements.wald.intevation.org