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 }

http://dive4elements.wald.intevation.org