Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/state/layer/LayerOutputState.java @ 875:5e9efdda6894
merged gnv-artifacts/1.0
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:56 +0200 |
parents | dfd02f8d3602 |
children | 461d4489705c |
comparison
equal
deleted
inserted
replaced
722:bb3ffe7d719e | 875:5e9efdda6894 |
---|---|
1 package de.intevation.gnv.state.layer; | |
2 | |
3 import java.io.File; | |
4 import java.io.IOException; | |
5 import java.io.OutputStream; | |
6 import java.util.ArrayList; | |
7 import java.util.Collection; | |
8 import java.util.Iterator; | |
9 | |
10 import org.apache.log4j.Logger; | |
11 import org.w3c.dom.Document; | |
12 import org.w3c.dom.Node; | |
13 | |
14 import com.vividsolutions.jts.geom.Geometry; | |
15 import com.vividsolutions.jts.io.ParseException; | |
16 import com.vividsolutions.jts.io.WKTReader; | |
17 | |
18 import de.intevation.artifactdatabase.Config; | |
19 import de.intevation.artifactdatabase.XMLUtils; | |
20 import de.intevation.artifacts.ArtifactNamespaceContext; | |
21 import de.intevation.artifacts.CallContext; | |
22 import de.intevation.gnv.artifacts.context.GNVArtifactContext; | |
23 import de.intevation.gnv.geobackend.base.Result; | |
24 import de.intevation.gnv.geobackend.base.query.QueryExecutor; | |
25 import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; | |
26 import de.intevation.gnv.geobackend.base.query.exception.QueryException; | |
27 import de.intevation.gnv.state.InputData; | |
28 import de.intevation.gnv.state.OutputStateBase; | |
29 import de.intevation.gnv.state.exception.StateException; | |
30 import de.intevation.gnv.utils.ArtifactXMLUtilities; | |
31 import de.intevation.gnv.utils.ExclusiveExec; | |
32 import de.intevation.gnv.utils.FileUtils; | |
33 import de.intevation.gnv.utils.MapfileGenerator; | |
34 import de.intevation.gnv.utils.MetaWriter; | |
35 import de.intevation.gnv.utils.ShapeFileWriter; | |
36 | |
37 /** | |
38 * This <code>OutputState</code> is used for Layer-Products. | |
39 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a> | |
40 * | |
41 */ | |
42 public class LayerOutputState extends OutputStateBase { | |
43 | |
44 /** | |
45 * the logger, used to log exceptions and additonaly information | |
46 */ | |
47 private static Logger log = Logger.getLogger(LayerOutputState.class); | |
48 | |
49 /** | |
50 * The UID of this Class. | |
51 */ | |
52 private static final long serialVersionUID = 9180957321704424049L; | |
53 | |
54 /** | |
55 * The Basename of the Templates for the WMS-Exports | |
56 */ | |
57 public static final String LAYER_MODEL = "layer"; | |
58 | |
59 /** | |
60 * The Name of the Shapefile which will be generated. | |
61 */ | |
62 public static final String SHAPEFILE_NAME = "data"; | |
63 | |
64 /** | |
65 * The ID for the Query fetching the Layer from the DB | |
66 */ | |
67 private String dataQueryID = null; | |
68 | |
69 /** | |
70 * The ID for the Query fetching the Geometry from the DB | |
71 * which should be used to Clip the Layerdata | |
72 */ | |
73 private String geometryQueryID = null; | |
74 | |
75 /** | |
76 * The ID of the Query for fetching the Columnnames of the Table which | |
77 * should put into the Shapefile. | |
78 */ | |
79 private String columnQueryID = null; | |
80 | |
81 /** | |
82 * The ID of the Query for fetching the Information which kind of Geometry | |
83 * should be put into the Shapefile. | |
84 */ | |
85 private String geometryTypeQueryID = null; | |
86 | |
87 /** | |
88 * The ID for the Value which will hold the Geometry-Value | |
89 */ | |
90 private String geometryID = null; | |
91 | |
92 /** | |
93 * Flag for synchronized Access of the Shapefile. | |
94 */ | |
95 private Boolean shapeFileLock = new Boolean(true); | |
96 | |
97 /** | |
98 * The Path where the Shapefile is stored. | |
99 */ | |
100 private String shapeFilePath; | |
101 | |
102 /** | |
103 * Constructor | |
104 */ | |
105 public LayerOutputState() { | |
106 super(); | |
107 } | |
108 | |
109 public void out(Document format, Collection<InputData> inputData, | |
110 OutputStream outputStream, String uuid, | |
111 CallContext callContext) throws StateException { | |
112 log.debug("LayerOutputState.out"); | |
113 String outputMode = XMLUtils.xpathString( | |
114 format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); | |
115 if (outputMode.equalsIgnoreCase("wms")) { | |
116 | |
117 Collection<LayerMetaData> layerMetaData = | |
118 this.getRequestedLayerMetadata(); | |
119 if (layerMetaData != null && !layerMetaData.isEmpty()){ | |
120 XMLUtils.toStream(this.getWMS(uuid, callContext, | |
121 layerMetaData,inputData), | |
122 outputStream); | |
123 }else{ | |
124 this.writeExceptionReport2Stream(outputStream); | |
125 } | |
126 }else if (outputMode.equalsIgnoreCase("zip")){ | |
127 Collection<LayerMetaData> layerMetaData = | |
128 this.getRequestedLayerMetadata(); | |
129 | |
130 if (layerMetaData != null && !layerMetaData.isEmpty()){ | |
131 this.writeZip(uuid, callContext, | |
132 outputStream, layerMetaData); | |
133 }else{ | |
134 this.writeExceptionReport2Stream(outputStream); | |
135 } | |
136 | |
137 } | |
138 } | |
139 | |
140 /** | |
141 * Writes an exception to an output stream. | |
142 * | |
143 * @param outputStream The output stream used to write the exception to. | |
144 */ | |
145 private void writeExceptionReport2Stream(OutputStream outputStream) { | |
146 Document document = XMLUtils.newDocument(); | |
147 ArtifactXMLUtilities. | |
148 createExceptionReport("No Data to Export", document); | |
149 XMLUtils.toStream(document,outputStream); | |
150 } | |
151 | |
152 /** | |
153 * Returns the Metadata for the requested Layers for fetching the data | |
154 * of the Layer and generating the Layer and WMS. | |
155 * @return the Metadata for the requested Layers | |
156 */ | |
157 private Collection<LayerMetaData> getRequestedLayerMetadata(){ | |
158 log.debug("LayerOutputState.getRequestedLayerMetadata"); | |
159 Collection<Result> result = this.getData(this.queryID); | |
160 Collection<LayerMetaData> returnValue = null; | |
161 if (result != null){ | |
162 QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() | |
163 .getQueryExecutor(); | |
164 Iterator<Result> it = result.iterator(); | |
165 returnValue = new ArrayList<LayerMetaData>(result.size()); | |
166 while (it.hasNext()){ | |
167 Result resultValue = it.next(); | |
168 String table = resultValue.getString(0); | |
169 String geometryType = this.getGeometryType(table, queryExecutor); | |
170 String where = resultValue.getString(1); | |
171 String columns = this.fetchColumns(table); | |
172 String templateID = resultValue.getString(2); | |
173 String[] queryValues = null; | |
174 String geometryWKT = null; | |
175 if (this.geometryID != null){ | |
176 InputData geometryInputData = | |
177 this.inputData.get(this.geometryID); | |
178 if (geometryInputData != null){ | |
179 try { | |
180 | |
181 Collection<Result> geometryData = queryExecutor | |
182 .executeQuery(this.geometryQueryID, | |
183 new String[]{geometryInputData.getValue()}); | |
184 Iterator<Result> git = geometryData.iterator(); | |
185 if (git.hasNext()){ | |
186 Result geometryValue = git.next(); | |
187 geometryWKT = geometryValue.getString(0); | |
188 } | |
189 } catch (QueryException e) { | |
190 log.error(e,e); | |
191 } | |
192 queryValues = new String[]{columns, | |
193 table, | |
194 where, | |
195 geometryWKT}; | |
196 }else{ | |
197 //Look into the presetting for an WKT | |
198 InputData geometryWKTData = this.preSettings != null ? | |
199 this.preSettings.get("geometry") : | |
200 null ; | |
201 if (geometryWKTData != null){ | |
202 queryValues = new String[]{columns, | |
203 table, | |
204 where, | |
205 geometryWKTData.getValue()}; | |
206 }else{ | |
207 queryValues = new String[]{columns,table,where}; | |
208 } | |
209 } | |
210 }else{ | |
211 //Look into the presetting for an WKT | |
212 InputData geometryWKTData = this.preSettings != null ? | |
213 this.preSettings.get("geometry") : | |
214 null ; | |
215 if (geometryWKTData != null){ | |
216 queryValues = new String[]{columns, | |
217 table, | |
218 where, | |
219 geometryWKTData.getValue()}; | |
220 }else{ | |
221 queryValues = new String[]{columns,table,where}; | |
222 } | |
223 } | |
224 returnValue.add(new LayerMetaData(table, geometryType, | |
225 where, columns, | |
226 templateID, queryValues, | |
227 geometryWKT)); | |
228 } | |
229 } | |
230 return returnValue; | |
231 } | |
232 | |
233 /** | |
234 * Fetches the Data from the Databasebackend. | |
235 * | |
236 * @return the resultdata. | |
237 */ | |
238 protected Collection<Result> fetchData(LayerMetaData layerMetaData){ | |
239 log.debug("LayerOutputState.fetchData"); | |
240 Collection<Result> data = null; | |
241 QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() | |
242 .getQueryExecutor(); | |
243 try { | |
244 data = queryExecutor.executeQuery(dataQueryID, | |
245 layerMetaData.getQueryValues()); | |
246 if (data != null && layerMetaData.getGeometryWKT() != null){ | |
247 WKTReader wktReader = new WKTReader(); | |
248 Geometry border = wktReader.read(layerMetaData.getGeometryWKT()); | |
249 Iterator<Result> dataIt = data.iterator(); | |
250 while (dataIt.hasNext()){ | |
251 // Trim the Geometries using the | |
252 // Geometry if one is available. | |
253 Result current = dataIt.next(); | |
254 String currentWKT = current.getString(0); | |
255 Geometry currentGeometry = null; | |
256 try { | |
257 currentGeometry = wktReader.read(currentWKT); | |
258 } catch (Exception e) { | |
259 log.error("Error parsing Geometry "+ currentWKT); | |
260 log.error(e,e); | |
261 } | |
262 if (currentGeometry != null){ | |
263 Geometry newGeometry = currentGeometry.intersection(border); | |
264 current.addColumnValue(0, newGeometry.toText()); | |
265 } | |
266 } | |
267 } | |
268 } catch (QueryException e) { | |
269 log.error(e,e); | |
270 } catch (ParseException e){ | |
271 log.error(e,e); | |
272 } | |
273 return data; | |
274 } | |
275 | |
276 | |
277 /** | |
278 * This method determines the geometry type on basis of a table name. | |
279 * | |
280 * @param tableName Name of the table in the database. | |
281 * @param queryExecutor The QueryExecutor. | |
282 * @return the geometry type as string (e.g. MultiPolygon, Polygon, etc). | |
283 */ | |
284 private String getGeometryType(String tableName, | |
285 QueryExecutor queryExecutor){ | |
286 String returnValue = null; | |
287 String[] tables = tableName.toUpperCase().split(","); | |
288 String[] filter = tables[0].split("\\."); | |
289 try { | |
290 Collection<Result> result = | |
291 queryExecutor.executeQuery(this.geometryTypeQueryID, filter); | |
292 if (result != null && !result.isEmpty()) | |
293 { | |
294 int geometryCode = result.iterator().next().getInteger(0); | |
295 if (geometryCode == 11 || | |
296 geometryCode == 10){ | |
297 returnValue = "MultiPolygon"; | |
298 }else if (geometryCode == 9 || | |
299 geometryCode == 8){ | |
300 returnValue = "MultiLineString"; | |
301 }else if (geometryCode == 7){ | |
302 returnValue = "MultiPoint"; | |
303 }else if (geometryCode == 6){ | |
304 returnValue = "GeometryCollection"; | |
305 }else if (geometryCode == 5 || | |
306 geometryCode == 4){ | |
307 returnValue = "Polygon"; | |
308 }else if (geometryCode == 3 || | |
309 geometryCode == 2){ | |
310 returnValue = "LineString"; | |
311 }else if (geometryCode == 1){ | |
312 returnValue = "Point"; | |
313 }else if (geometryCode == 0){ | |
314 returnValue = "Geometry"; | |
315 } | |
316 } | |
317 } catch (QueryException e) { | |
318 log.error(e,e); | |
319 } | |
320 return returnValue; | |
321 } | |
322 | |
323 | |
324 /** | |
325 * Fetch the columns of a specific table. | |
326 * | |
327 * @param tableName The name of the table. | |
328 * @return the columns as string. | |
329 */ | |
330 private String fetchColumns(String tableName){ | |
331 String returnValue = null; | |
332 try { | |
333 String[] tables = tableName.toUpperCase().split(","); | |
334 String[] filter = tables[0].split("\\."); | |
335 // Only use the first Table the second one will be ignored. | |
336 QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() | |
337 .getQueryExecutor(); | |
338 Collection<Result> columnData = queryExecutor. | |
339 executeQuery(this.columnQueryID, | |
340 filter); | |
341 if (columnData != null && !columnData.isEmpty()){ | |
342 StringBuffer sb = new StringBuffer(); | |
343 synchronized (sb) { | |
344 Iterator<Result> it = columnData.iterator(); | |
345 while(it.hasNext()){ | |
346 Result current = it.next(); | |
347 sb.append(current.getString(0)); | |
348 if (it.hasNext()){ | |
349 sb.append(" , "); | |
350 } | |
351 } | |
352 } | |
353 returnValue = sb.toString(); | |
354 } | |
355 } catch (QueryException e) { | |
356 log.error(e,e); | |
357 } | |
358 return returnValue; | |
359 } | |
360 | |
361 | |
362 @Override | |
363 public void setup(Node configuration) { | |
364 log.debug("LayerOutputState.setup"); | |
365 super.setup(configuration); | |
366 this.dataQueryID = Config.getStringXPath(configuration, | |
367 "queryID-layerdata"); | |
368 this.geometryID = Config.getStringXPath(configuration, | |
369 "inputvalue-geometry"); | |
370 this.geometryQueryID = Config.getStringXPath(configuration, | |
371 "queryID-geometry"); | |
372 | |
373 this.columnQueryID = "layer_colums"; //Config.getStringXPath(configuration, | |
374 // "queryID-columns"); | |
375 this.geometryTypeQueryID = "geometry_type"; | |
376 } | |
377 | |
378 | |
379 /** | |
380 * Write the resultdata to shapefiles. | |
381 * | |
382 * @param uuid The UUID of the current artifact. | |
383 * @param data The finalized data used for shapefile creation. | |
384 * @param callContext The CallContext object. | |
385 * @param geometryType The geometry type. | |
386 * @return the shapefile path. | |
387 */ | |
388 protected String writeToShapeFile( | |
389 String uuid, | |
390 Collection<Result> data, | |
391 CallContext callContext, | |
392 String geometryType, | |
393 int layerNumber | |
394 ) { | |
395 boolean success = false; | |
396 if (data != null && !data.isEmpty()){ | |
397 File shapeDir = new File(shapeFilePath); | |
398 try { | |
399 File shapeFile = new File(shapeDir, createShapeFileName(layerNumber)); | |
400 if (!ShapeFileWriter.writeDataToFile(shapeFile, "data", data,geometryType)){ | |
401 log.error("writing data into shapefile failed"); | |
402 return null; | |
403 } | |
404 success = true; | |
405 callContext.afterCall(CallContext.STORE); | |
406 return shapeFilePath; | |
407 } | |
408 finally { | |
409 if (!success) { | |
410 FileUtils.deleteRecursive(shapeDir); | |
411 } | |
412 } | |
413 }else{ | |
414 return null; | |
415 } | |
416 } | |
417 | |
418 /** | |
419 * Check if the ShapeDir exists and if it exists delete all Contents | |
420 * in it. If it not exists the Director will be created. | |
421 * @param baseDir the BaseDirectory for all ShapeDirs | |
422 * @param uuid the UUID which is used to create the Directory | |
423 * @return true if the directory exists or could be created. | |
424 * false if the directory could not be created. | |
425 */ | |
426 private boolean createShapeDir(File baseDir, String uuid){ | |
427 File shapeDir = new File(baseDir, uuid); | |
428 boolean createdDir = false; | |
429 synchronized (shapeFileLock) { | |
430 if (shapeDir.exists()) { | |
431 FileUtils.deleteContent(shapeDir); // TODO Place on getZip and getWMS | |
432 } | |
433 else if (!shapeDir.mkdirs()) { | |
434 log.error("cannot create directory '" | |
435 + shapeDir.getAbsolutePath() + "'"); | |
436 return false; | |
437 } | |
438 createdDir = true; | |
439 } | |
440 shapeFilePath = shapeDir.getAbsolutePath(); | |
441 return createdDir; | |
442 } | |
443 | |
444 /** | |
445 * Create a zip archive with the shapefiles of the given shapefiles path and | |
446 * write it to <code>output</code>. | |
447 * | |
448 * @param uuid The UUID of the current artifact. | |
449 * @param callContext The CallContext object. | |
450 * @param output The output stream. | |
451 * @param data The data to be written to shapefile. | |
452 * @param geometryType The geometry type. | |
453 * @throws StateException if an error occured while zipfile creation. | |
454 */ | |
455 protected void writeZip( | |
456 String uuid, | |
457 CallContext callContext, | |
458 OutputStream output, | |
459 Collection<LayerMetaData> layerMetaData | |
460 ) | |
461 throws StateException | |
462 { | |
463 try { | |
464 String p = getShapeFilePath(); | |
465 if (p != null) { | |
466 File dir = new File(p); | |
467 if (dir.isDirectory()) { | |
468 FileUtils.createZipArchive(dir, output); | |
469 } | |
470 } | |
471 else { | |
472 File baseDir = shapefileDirectory(callContext); | |
473 if (!this.createShapeDir(baseDir, uuid)){ | |
474 return; | |
475 } | |
476 Iterator<LayerMetaData> it = layerMetaData.iterator(); | |
477 int i = 1; | |
478 while(it.hasNext()){ | |
479 LayerMetaData lmd = it.next(); | |
480 Collection<Result> data = this.fetchData(lmd); | |
481 p = writeToShapeFile(uuid, data, callContext,lmd.getGeometryType(),i++); | |
482 } | |
483 if (p != null) { | |
484 FileUtils.createZipArchive(new File(p), output); | |
485 } | |
486 } | |
487 } | |
488 catch (IOException ioe) { | |
489 log.error(ioe.getLocalizedMessage(), ioe); | |
490 } | |
491 } | |
492 | |
493 /** | |
494 * Returns the shapefile path. | |
495 * | |
496 * @return the shapefile path. | |
497 */ | |
498 public String getShapeFilePath() { | |
499 synchronized (shapeFileLock) { | |
500 return shapeFilePath; | |
501 } | |
502 } | |
503 | |
504 /** | |
505 * Returns the basic-directory where the Shapefiles should be placed in. | |
506 * @param callContext the Context of this Call | |
507 * @return the Directory where the Shapefiles could be placed in. | |
508 * (Please create an own directory in this dir and not put the | |
509 * Files directly in it) | |
510 */ | |
511 private static File shapefileDirectory(CallContext callContext) { | |
512 // Code was taken from HorizontalCrossSectionMeshOutputState | |
513 GNVArtifactContext context = | |
514 (GNVArtifactContext)callContext.globalContext(); | |
515 File dir = (File)context.get( | |
516 GNVArtifactContext.HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY); | |
517 return dir != null | |
518 ? dir | |
519 : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH; | |
520 } | |
521 | |
522 | |
523 @Override | |
524 public void endOfLife(Object globalContext) { | |
525 super.endOfLife(globalContext); | |
526 // do it in background | |
527 new Thread() { | |
528 @Override | |
529 public void run() { | |
530 String path = resetShapeFilePath(); | |
531 if (path == null) { | |
532 return; | |
533 } | |
534 File dir = new File(path); | |
535 for (int i = 0; i < 10; ++i) { | |
536 if (!dir.exists() || FileUtils.deleteRecursive(dir)) { | |
537 MapfileGenerator.getInstance().update(); | |
538 return; | |
539 } | |
540 try { | |
541 Thread.sleep(10000L); | |
542 } | |
543 catch (InterruptedException ie) { | |
544 } | |
545 } | |
546 | |
547 log.error("failed to remove directory '" + path + "'"); | |
548 } // run | |
549 }.start(); | |
550 } | |
551 | |
552 /** | |
553 * Resets the Settings e.g shapeFilePath and templateID | |
554 * @return | |
555 */ | |
556 private String resetShapeFilePath() { | |
557 synchronized (shapeFileLock) { | |
558 String path = shapeFilePath; | |
559 shapeFilePath = null; | |
560 return path; | |
561 } | |
562 } | |
563 | |
564 | |
565 /** | |
566 * Write data to shapefiles and feed a map service with information about | |
567 * these shapefiles. The map service can be queried for displaying | |
568 * corresponding layers as WMS. | |
569 * | |
570 * @param uuid The UUID of the current artifact. | |
571 * @param callContext The CallContext object. | |
572 * @param layerMetaData The Metadata which is required to create the | |
573 * different Layers. | |
574 * @param inputData the Parameters which are send by the out-Call. | |
575 * @return a document with some meta information (shapefile path, geometry | |
576 * type, time to live of the current artifact, etc). | |
577 * @throws StateException if an error occured while shapefile writing. | |
578 */ | |
579 protected Document getWMS(String uuid, | |
580 CallContext callContext, | |
581 Collection<LayerMetaData> layerMetaData, | |
582 Collection<InputData> inputData) | |
583 throws StateException | |
584 { | |
585 String path = getShapeFilePath(); | |
586 if (path != null && new File(path).isDirectory()){ | |
587 return this.refreshMetaFile(layerMetaData, inputData, | |
588 uuid, callContext); | |
589 }else{ | |
590 Document document = XMLUtils.newDocument(); | |
591 if (this.shapeFilePath == null){ | |
592 File baseDir = shapefileDirectory(callContext); | |
593 if (!this.createShapeDir(baseDir, uuid)){ | |
594 // TODO Insert Error Report | |
595 return document; | |
596 } | |
597 } | |
598 path = getShapeFilePath(); | |
599 Iterator<LayerMetaData> it = layerMetaData.iterator(); | |
600 Node meta = null; | |
601 int layerNumber = 0; | |
602 while (it.hasNext()){ | |
603 LayerMetaData lmd = it.next(); | |
604 layerNumber ++; | |
605 String geometryType = lmd.getGeometryType(); | |
606 String templateId = lmd.getTemplateID(); | |
607 ExclusiveExec.UniqueKey key = ExclusiveExec.INSTANCE.acquire(uuid); | |
608 try{ | |
609 Collection<Result> data = this.fetchData(lmd); | |
610 if (data != null && | |
611 (this.writeToShapeFile(uuid, data, callContext, | |
612 geometryType,layerNumber)) != null) { | |
613 String paramType = findParameterTitle(geometryType,templateId); | |
614 String title = getLayerTitle(inputData); | |
615 if (title == null) { | |
616 title = uuid+"_"+layerNumber; | |
617 }else{ | |
618 title = title+"_"+layerNumber; | |
619 } | |
620 if (meta == null){ | |
621 meta = MetaWriter.writeLayerMeta(callContext,document); | |
622 } | |
623 MetaWriter.writeLayerMeta(callContext, document, | |
624 meta, uuid, paramType, | |
625 this.determineGeometryType(geometryType), | |
626 createShapeFileName(layerNumber), | |
627 title); | |
628 } | |
629 if (meta != null && !it.hasNext()) { | |
630 MetaWriter.writeMetaFile(path,document); | |
631 MapfileGenerator.getInstance().update(); | |
632 return document; | |
633 } | |
634 }finally{ | |
635 ExclusiveExec.INSTANCE.release(key); | |
636 } | |
637 } | |
638 return document; | |
639 } | |
640 } | |
641 | |
642 /** | |
643 * Creates the name of the Shapefile | |
644 * @param layerNumber the Number of the Layer | |
645 * @return the create name of the Shapefile. | |
646 */ | |
647 private String createShapeFileName(int layerNumber) { | |
648 return SHAPEFILE_NAME+"_"+layerNumber+".shp"; | |
649 } | |
650 | |
651 /** | |
652 * Method that refreshes the Metadatafile for publishing the WMS | |
653 * Without generating the Data ones again. | |
654 * @param layerMetaData the Metadata which is required to create the Layers | |
655 * @param inputData the Inputdata which was sent by the Client | |
656 * @param uuid the uuid of the Artifact | |
657 * @param callContext the context of this Call | |
658 * @return a refreshed Metadata-Document | |
659 */ | |
660 private Document refreshMetaFile(Collection<LayerMetaData> layerMetaData, | |
661 Collection<InputData> inputData, | |
662 String uuid, | |
663 CallContext callContext){ | |
664 Document document = XMLUtils.newDocument(); | |
665 Node meta = null; | |
666 int layerNumber = 0; | |
667 Iterator<LayerMetaData> it = layerMetaData.iterator(); | |
668 while (it.hasNext()){ | |
669 LayerMetaData lmd = it.next(); | |
670 layerNumber ++; | |
671 String geometryType = lmd.getGeometryType(); | |
672 String templateId = lmd.getTemplateID(); | |
673 String title = getLayerTitle(inputData); | |
674 if (title == null) { | |
675 title = uuid+"_"+layerNumber; | |
676 }else{ | |
677 title = title+"_"+layerNumber; | |
678 } | |
679 callContext.putContextValue( | |
680 MetaWriter.CONTEXT_LAYER_TITLE, title); | |
681 String paramType = findParameterTitle(geometryType,templateId); | |
682 if (log.isDebugEnabled()) { | |
683 log.debug("Layer title: " + title); | |
684 log.debug("Layer type: " + paramType); | |
685 } | |
686 if (meta == null){ | |
687 meta = MetaWriter.writeLayerMeta(callContext,document); | |
688 } | |
689 MetaWriter.writeLayerMeta(callContext, document, | |
690 meta, uuid, paramType, | |
691 this.determineGeometryType(geometryType), | |
692 createShapeFileName(layerNumber), | |
693 title); | |
694 if (meta != null && !it.hasNext()) { | |
695 MetaWriter.writeMetaFile(getShapeFilePath(),document); | |
696 MapfileGenerator.getInstance().update(); | |
697 return document; | |
698 } | |
699 } | |
700 return document; | |
701 } | |
702 | |
703 /** | |
704 * Returns the parameterType for the Layer. | |
705 * @param geometryType | |
706 * @return | |
707 */ | |
708 private String findParameterTitle(String geometryType, String templateID) { | |
709 String paramType = LAYER_MODEL+"_"+templateID; | |
710 if (!MapfileGenerator.getInstance().templateExists(paramType)){ | |
711 // If the template doesn't exist the Defaulttemplates will be used. | |
712 paramType = LAYER_MODEL+"_"+ | |
713 this.determineDefaultTemplateName(geometryType); | |
714 } | |
715 return paramType; | |
716 } | |
717 | |
718 /** | |
719 * Find the title for a wms layer specified by the user. | |
720 * | |
721 * @param inputData A collection with InputData objects. | |
722 * @return the title. | |
723 */ | |
724 protected String getLayerTitle(Collection<InputData> inputData) { | |
725 for (InputData data: inputData) { | |
726 String name = data.getName(); | |
727 if (name != null && name.equals("title")) { | |
728 return (String) data.getValue(); | |
729 } | |
730 } | |
731 return null; | |
732 } | |
733 | |
734 | |
735 /** | |
736 * Turns the geometry type into a form used for the templating mechanism | |
737 * while mapfile generation. | |
738 * | |
739 * @param geometryType The original geometry type. | |
740 * @return a valid geometry type fpr the template mechanism. | |
741 */ | |
742 private String determineGeometryType(String geometryType){ | |
743 String returnValue = geometryType.toLowerCase(); | |
744 if (returnValue.equalsIgnoreCase("linestring")){ | |
745 returnValue = "Line"; | |
746 }else if (returnValue.equalsIgnoreCase("multilinestring")){ | |
747 returnValue ="Line"; | |
748 }else if (returnValue.equalsIgnoreCase("multipolygon")){ | |
749 returnValue = "Polygon"; | |
750 } | |
751 return returnValue; | |
752 } | |
753 | |
754 | |
755 /** | |
756 * Determine the default template name if no special template is existing | |
757 * for this layer. | |
758 * | |
759 * @param geometryType The geometry type. | |
760 * @return a default geometry fitting to the original geometry type. | |
761 */ | |
762 private String determineDefaultTemplateName(String geometryType){ | |
763 String returnValue = geometryType.toLowerCase(); | |
764 if (returnValue.equalsIgnoreCase("multilinestring")){ | |
765 returnValue ="linestring"; | |
766 }else if (returnValue.equalsIgnoreCase("multipolygon")){ | |
767 returnValue = "polygon"; | |
768 }else if (returnValue.equalsIgnoreCase("multipoint")){ | |
769 returnValue = "point"; | |
770 } | |
771 return returnValue; | |
772 } | |
773 } | |
774 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |