ingo@1115: /* ingo@1115: * Copyright (c) 2010 by Intevation GmbH ingo@1115: * ingo@1115: * This program is free software under the LGPL (>=v2.1) ingo@1115: * Read the file LGPL.txt coming with the software for details ingo@1115: * or visit http://www.gnu.org/licenses/ if it does not exist. ingo@1115: */ ingo@1115: tim@616: package de.intevation.gnv.state.layer; tim@616: tim@799: import java.io.File; tim@799: import java.io.IOException; tim@799: import java.io.OutputStream; tim@859: import java.util.ArrayList; tim@799: import java.util.Collection; tim@799: import java.util.Iterator; tim@799: tim@799: import org.apache.log4j.Logger; tim@799: import org.w3c.dom.Document; tim@799: import org.w3c.dom.Node; tim@799: tim@1070: import com.vividsolutions.jts.geom.Envelope; sascha@779: import com.vividsolutions.jts.geom.Geometry; tim@649: import com.vividsolutions.jts.io.ParseException; tim@649: import com.vividsolutions.jts.io.WKTReader; tim@649: sascha@1117: import de.intevation.artifacts.common.utils.Config; sascha@1117: import de.intevation.artifacts.common.utils.XMLUtils; tim@616: import de.intevation.artifacts.ArtifactNamespaceContext; tim@616: import de.intevation.artifacts.CallContext; tim@649: import de.intevation.gnv.artifacts.context.GNVArtifactContext; tim@616: import de.intevation.gnv.geobackend.base.Result; tim@649: import de.intevation.gnv.geobackend.base.query.QueryExecutor; tim@649: import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; tim@649: import de.intevation.gnv.geobackend.base.query.exception.QueryException; tim@616: import de.intevation.gnv.state.InputData; tim@616: import de.intevation.gnv.state.OutputStateBase; tim@616: import de.intevation.gnv.state.exception.StateException; tim@723: import de.intevation.gnv.utils.ArtifactXMLUtilities; tim@828: import de.intevation.gnv.utils.ExclusiveExec; tim@649: import de.intevation.gnv.utils.FileUtils; tim@649: import de.intevation.gnv.utils.MapfileGenerator; tim@655: import de.intevation.gnv.utils.MetaWriter; tim@649: import de.intevation.gnv.utils.ShapeFileWriter; tim@616: tim@616: /** tim@822: * This OutputState is used for Layer-Products. sascha@780: * @author Tim Englich tim@616: * tim@616: */ tim@616: public class LayerOutputState extends OutputStateBase { tim@616: tim@616: /** tim@616: * the logger, used to log exceptions and additonaly information tim@616: */ tim@616: private static Logger log = Logger.getLogger(LayerOutputState.class); sascha@778: tim@616: /** tim@616: * The UID of this Class. tim@616: */ tim@616: private static final long serialVersionUID = 9180957321704424049L; sascha@778: tim@822: /** tim@822: * The Basename of the Templates for the WMS-Exports tim@822: */ tim@655: public static final String LAYER_MODEL = "layer"; sascha@835: tim@822: /** tim@822: * The Name of the Shapefile which will be generated. tim@822: */ tim@859: public static final String SHAPEFILE_NAME = "data"; tim@616: tim@616: /** tim@616: * The ID for the Query fetching the Layer from the DB tim@616: */ sascha@778: private String dataQueryID = null; sascha@778: tim@649: /** tim@649: * The ID for the Query fetching the Geometry from the DB tim@649: * which should be used to Clip the Layerdata tim@649: */ tim@649: private String geometryQueryID = null; sascha@778: tim@822: /** sascha@835: * The ID of the Query for fetching the Columnnames of the Table which tim@822: * should put into the Shapefile. tim@822: */ tim@728: private String columnQueryID = null; sascha@778: tim@822: /** sascha@835: * The ID of the Query for fetching the Information which kind of Geometry tim@822: * should be put into the Shapefile. tim@822: */ tim@799: private String geometryTypeQueryID = null; tim@799: tim@649: /** tim@822: * The ID for the Value which will hold the Geometry-Value tim@649: */ tim@649: private String geometryID = null; sascha@778: tim@822: /** tim@822: * Flag for synchronized Access of the Shapefile. tim@822: */ tim@649: private Boolean shapeFileLock = new Boolean(true); sascha@778: tim@822: /** tim@822: * The Path where the Shapefile is stored. tim@822: */ tim@649: private String shapeFilePath; sascha@778: tim@822: /** tim@616: * Constructor tim@616: */ tim@616: public LayerOutputState() { tim@616: super(); tim@616: } tim@616: tim@616: public void out(Document format, Collection inputData, tim@616: OutputStream outputStream, String uuid, tim@616: CallContext callContext) throws StateException { tim@616: log.debug("LayerOutputState.out"); tim@616: String outputMode = XMLUtils.xpathString( tim@616: format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE); tim@616: if (outputMode.equalsIgnoreCase("wms")) { ingo@870: ingo@870: Collection layerMetaData = tim@859: this.getRequestedLayerMetadata(); tim@859: if (layerMetaData != null && !layerMetaData.isEmpty()){ tim@799: XMLUtils.toStream(this.getWMS(uuid, callContext, tim@859: layerMetaData,inputData), tim@723: outputStream); tim@723: }else{ tim@723: this.writeExceptionReport2Stream(outputStream); tim@723: } tim@616: }else if (outputMode.equalsIgnoreCase("zip")){ ingo@870: Collection layerMetaData = tim@859: this.getRequestedLayerMetadata(); tim@859: tim@859: if (layerMetaData != null && !layerMetaData.isEmpty()){ ingo@870: this.writeZip(uuid, callContext, tim@859: outputStream, layerMetaData); tim@723: }else{ tim@723: this.writeExceptionReport2Stream(outputStream); tim@723: } sascha@778: tim@616: } tim@616: } tim@723: tim@723: /** ingo@813: * Writes an exception to an output stream. ingo@813: * ingo@813: * @param outputStream The output stream used to write the exception to. tim@723: */ tim@723: private void writeExceptionReport2Stream(OutputStream outputStream) { tim@723: Document document = XMLUtils.newDocument(); ingo@813: ArtifactXMLUtilities. tim@723: createExceptionReport("No Data to Export", document); tim@723: XMLUtils.toStream(document,outputStream); tim@723: } sascha@778: tim@649: /** ingo@870: * Returns the Metadata for the requested Layers for fetching the data tim@859: * of the Layer and generating the Layer and WMS. tim@859: * @return the Metadata for the requested Layers tim@649: */ tim@859: private Collection getRequestedLayerMetadata(){ tim@859: log.debug("LayerOutputState.getRequestedLayerMetadata"); tim@616: Collection result = this.getData(this.queryID); tim@859: Collection returnValue = null; tim@616: if (result != null){ tim@649: QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() tim@649: .getQueryExecutor(); tim@616: Iterator it = result.iterator(); tim@859: returnValue = new ArrayList(result.size()); tim@859: while (it.hasNext()){ tim@616: Result resultValue = it.next(); tim@649: String table = resultValue.getString(0); tim@859: String geometryType = this.getGeometryType(table, queryExecutor); tim@649: String where = resultValue.getString(1); tim@728: String columns = this.fetchColumns(table); tim@859: String templateID = resultValue.getString(2); ingo@1057: String layername = resultValue.getString(3); tim@859: String[] queryValues = null; tim@859: String geometryWKT = null; tim@649: if (this.geometryID != null){ sascha@778: InputData geometryInputData = tim@649: this.inputData.get(this.geometryID); tim@649: if (geometryInputData != null){ tim@649: try { ingo@870: tim@649: Collection geometryData = queryExecutor tim@649: .executeQuery(this.geometryQueryID, tim@649: new String[]{geometryInputData.getValue()}); tim@649: Iterator git = geometryData.iterator(); tim@649: if (git.hasNext()){ tim@649: Result geometryValue = git.next(); tim@649: geometryWKT = geometryValue.getString(0); tim@649: } tim@649: } catch (QueryException e) { tim@649: log.error(e,e); tim@649: } tim@728: queryValues = new String[]{columns, tim@728: table, tim@649: where, tim@649: geometryWKT}; tim@649: }else{ tim@729: //Look into the presetting for an WKT sascha@778: InputData geometryWKTData = this.preSettings != null ? tim@742: this.preSettings.get("geometry") : tim@742: null ; tim@729: if (geometryWKTData != null){ tim@729: queryValues = new String[]{columns, tim@729: table, tim@729: where, tim@729: geometryWKTData.getValue()}; tim@1103: geometryWKT = geometryWKTData.getValue(); tim@729: }else{ tim@729: queryValues = new String[]{columns,table,where}; tim@729: } tim@729: } tim@729: }else{ tim@729: //Look into the presetting for an WKT sascha@778: InputData geometryWKTData = this.preSettings != null ? tim@742: this.preSettings.get("geometry") : tim@742: null ; tim@729: if (geometryWKTData != null){ tim@729: queryValues = new String[]{columns, tim@729: table, tim@729: where, tim@729: geometryWKTData.getValue()}; tim@729: }else{ tim@728: queryValues = new String[]{columns,table,where}; tim@649: } tim@649: } ingo@1057: returnValue.add(new LayerMetaData( ingo@1057: table, geometryType, where, columns, ingo@1057: templateID, queryValues, geometryWKT, layername)); tim@616: } tim@859: } tim@859: return returnValue; tim@859: } sascha@778: tim@859: /** tim@859: * Fetches the Data from the Databasebackend. tim@859: * tim@859: * @return the resultdata. tim@859: */ tim@1070: protected Collection fetchData(LayerMetaData layerMetaData, Envelope mbr){ tim@859: log.debug("LayerOutputState.fetchData"); tim@859: Collection data = null; tim@859: QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() tim@859: .getQueryExecutor(); tim@859: try { tim@859: data = queryExecutor.executeQuery(dataQueryID, tim@859: layerMetaData.getQueryValues()); tim@1070: if (data != null){ tim@859: WKTReader wktReader = new WKTReader(); tim@1070: Geometry border = null; tim@1070: if (layerMetaData.getGeometryWKT() != null){ tim@1070: border = wktReader.read(layerMetaData.getGeometryWKT()); tim@1070: } tim@859: Iterator dataIt = data.iterator(); tim@859: while (dataIt.hasNext()){ tim@859: // Trim the Geometries using the tim@859: // Geometry if one is available. tim@859: Result current = dataIt.next(); tim@859: String currentWKT = current.getString(0); tim@859: Geometry currentGeometry = null; tim@859: try { tim@859: currentGeometry = wktReader.read(currentWKT); tim@859: } catch (Exception e) { tim@859: log.error("Error parsing Geometry "+ currentWKT); tim@859: log.error(e,e); tim@859: } tim@859: if (currentGeometry != null){ tim@1070: if (border != null){ tim@1070: currentGeometry = currentGeometry.intersection(border); tim@1070: current.addColumnValue(0, currentGeometry.toText()); tim@1070: } tim@1070: if (mbr.isNull()){ tim@1070: mbr.init(currentGeometry.getEnvelopeInternal()); tim@1070: }else{ tim@1070: mbr.expandToInclude(currentGeometry.getEnvelopeInternal()); tim@1070: } tim@649: } tim@649: } tim@649: } tim@859: } catch (QueryException e) { tim@859: log.error(e,e); tim@859: } catch (ParseException e){ tim@859: log.error(e,e); tim@616: } tim@616: return data; tim@616: } tim@616: ingo@813: ingo@813: /** ingo@813: * This method determines the geometry type on basis of a table name. ingo@813: * ingo@813: * @param tableName Name of the table in the database. ingo@813: * @param queryExecutor The QueryExecutor. ingo@813: * @return the geometry type as string (e.g. MultiPolygon, Polygon, etc). ingo@813: */ tim@799: private String getGeometryType(String tableName, tim@799: QueryExecutor queryExecutor){ tim@799: String returnValue = null; tim@799: String[] tables = tableName.toUpperCase().split(","); tim@799: String[] filter = tables[0].split("\\."); tim@799: try { sascha@803: Collection result = tim@799: queryExecutor.executeQuery(this.geometryTypeQueryID, filter); tim@799: if (result != null && !result.isEmpty()) tim@799: { tim@799: int geometryCode = result.iterator().next().getInteger(0); sascha@803: if (geometryCode == 11 || tim@799: geometryCode == 10){ tim@799: returnValue = "MultiPolygon"; sascha@803: }else if (geometryCode == 9 || tim@799: geometryCode == 8){ tim@799: returnValue = "MultiLineString"; tim@799: }else if (geometryCode == 7){ tim@799: returnValue = "MultiPoint"; tim@799: }else if (geometryCode == 6){ tim@799: returnValue = "GeometryCollection"; sascha@803: }else if (geometryCode == 5 || tim@799: geometryCode == 4){ tim@799: returnValue = "Polygon"; sascha@803: }else if (geometryCode == 3 || tim@799: geometryCode == 2){ tim@799: returnValue = "LineString"; tim@799: }else if (geometryCode == 1){ tim@799: returnValue = "Point"; tim@799: }else if (geometryCode == 0){ tim@799: returnValue = "Geometry"; tim@799: } tim@799: } tim@799: } catch (QueryException e) { tim@799: log.error(e,e); tim@799: } tim@799: return returnValue; tim@799: } ingo@813: ingo@813: ingo@813: /** ingo@813: * Fetch the columns of a specific table. ingo@813: * ingo@813: * @param tableName The name of the table. ingo@813: * @return the columns as string. ingo@813: */ tim@728: private String fetchColumns(String tableName){ tim@728: String returnValue = null; tim@728: try { tim@756: String[] tables = tableName.toUpperCase().split(","); tim@756: String[] filter = tables[0].split("\\."); tim@756: // Only use the first Table the second one will be ignored. tim@728: QueryExecutor queryExecutor = QueryExecutorFactory.getInstance() tim@859: .getQueryExecutor(); tim@728: Collection columnData = queryExecutor. sascha@778: executeQuery(this.columnQueryID, tim@728: filter); tim@728: if (columnData != null && !columnData.isEmpty()){ tim@728: StringBuffer sb = new StringBuffer(); tim@728: synchronized (sb) { tim@728: Iterator it = columnData.iterator(); tim@728: while(it.hasNext()){ tim@728: Result current = it.next(); tim@728: sb.append(current.getString(0)); tim@728: if (it.hasNext()){ tim@728: sb.append(" , "); tim@728: } tim@728: } tim@728: } tim@728: returnValue = sb.toString(); tim@728: } tim@728: } catch (QueryException e) { tim@728: log.error(e,e); tim@728: } tim@728: return returnValue; tim@728: } ingo@813: ingo@813: tim@616: @Override tim@616: public void setup(Node configuration) { tim@616: log.debug("LayerOutputState.setup"); tim@616: super.setup(configuration); tim@649: this.dataQueryID = Config.getStringXPath(configuration, tim@649: "queryID-layerdata"); tim@649: this.geometryID = Config.getStringXPath(configuration, tim@649: "inputvalue-geometry"); tim@649: this.geometryQueryID = Config.getStringXPath(configuration, tim@649: "queryID-geometry"); sascha@778: tim@728: this.columnQueryID = "layer_colums"; //Config.getStringXPath(configuration, tim@728: // "queryID-columns"); tim@799: this.geometryTypeQueryID = "geometry_type"; tim@616: } sascha@778: ingo@813: ingo@813: /** tim@822: * Write the resultdata to shapefiles. ingo@813: * ingo@813: * @param uuid The UUID of the current artifact. ingo@813: * @param data The finalized data used for shapefile creation. ingo@813: * @param callContext The CallContext object. ingo@813: * @param geometryType The geometry type. ingo@813: * @return the shapefile path. ingo@813: */ tim@649: protected String writeToShapeFile( tim@649: String uuid, tim@649: Collection data, tim@799: CallContext callContext, tim@859: String geometryType, tim@859: int layerNumber tim@649: ) { tim@649: boolean success = false; tim@859: if (data != null && !data.isEmpty()){ tim@859: File shapeDir = new File(shapeFilePath); tim@859: try { tim@859: File shapeFile = new File(shapeDir, createShapeFileName(layerNumber)); tim@859: if (!ShapeFileWriter.writeDataToFile(shapeFile, "data", data,geometryType)){ tim@859: log.error("writing data into shapefile failed"); tim@649: return null; tim@649: } tim@859: success = true; tim@859: callContext.afterCall(CallContext.STORE); tim@859: return shapeFilePath; tim@649: } tim@859: finally { tim@859: if (!success) { tim@859: FileUtils.deleteRecursive(shapeDir); tim@859: } tim@649: } tim@859: }else{ tim@859: return null; tim@649: } tim@649: } sascha@778: tim@859: /** tim@859: * Check if the ShapeDir exists and if it exists delete all Contents tim@859: * in it. If it not exists the Director will be created. tim@859: * @param baseDir the BaseDirectory for all ShapeDirs tim@859: * @param uuid the UUID which is used to create the Directory ingo@870: * @return true if the directory exists or could be created. tim@859: * false if the directory could not be created. tim@859: */ tim@859: private boolean createShapeDir(File baseDir, String uuid){ tim@859: File shapeDir = new File(baseDir, uuid); tim@859: boolean createdDir = false; tim@859: synchronized (shapeFileLock) { tim@859: if (shapeDir.exists()) { tim@859: FileUtils.deleteContent(shapeDir); // TODO Place on getZip and getWMS tim@859: } tim@859: else if (!shapeDir.mkdirs()) { tim@859: log.error("cannot create directory '" tim@859: + shapeDir.getAbsolutePath() + "'"); tim@859: return false; tim@859: } tim@859: createdDir = true; tim@859: } tim@859: shapeFilePath = shapeDir.getAbsolutePath(); tim@859: return createdDir; tim@859: } ingo@813: ingo@813: /** ingo@813: * Create a zip archive with the shapefiles of the given shapefiles path and ingo@813: * write it to output. ingo@813: * ingo@813: * @param uuid The UUID of the current artifact. ingo@813: * @param callContext The CallContext object. ingo@813: * @param output The output stream. ingo@813: * @param data The data to be written to shapefile. ingo@813: * @param geometryType The geometry type. ingo@813: * @throws StateException if an error occured while zipfile creation. ingo@813: */ tim@649: protected void writeZip( tim@649: String uuid, tim@649: CallContext callContext, tim@649: OutputStream output, tim@859: Collection layerMetaData sascha@778: ) tim@649: throws StateException tim@649: { tim@649: try { tim@649: String p = getShapeFilePath(); tim@649: if (p != null) { tim@649: File dir = new File(p); tim@649: if (dir.isDirectory()) { tim@649: FileUtils.createZipArchive(dir, output); tim@649: } tim@649: } tim@649: else { tim@859: File baseDir = shapefileDirectory(callContext); tim@859: if (!this.createShapeDir(baseDir, uuid)){ tim@859: return; tim@859: } tim@859: Iterator it = layerMetaData.iterator(); tim@859: int i = 1; tim@1070: Envelope mbr = new Envelope(); tim@859: while(it.hasNext()){ tim@859: LayerMetaData lmd = it.next(); tim@1070: Collection data = this.fetchData(lmd, mbr); tim@859: p = writeToShapeFile(uuid, data, callContext,lmd.getGeometryType(),i++); tim@859: } tim@859: if (p != null) { tim@649: FileUtils.createZipArchive(new File(p), output); tim@649: } tim@649: } tim@649: } tim@649: catch (IOException ioe) { tim@649: log.error(ioe.getLocalizedMessage(), ioe); tim@649: } tim@649: } sascha@778: ingo@813: /** ingo@813: * Returns the shapefile path. ingo@813: * ingo@813: * @return the shapefile path. ingo@813: */ tim@649: public String getShapeFilePath() { tim@649: synchronized (shapeFileLock) { tim@649: return shapeFilePath; tim@649: } tim@649: } sascha@778: ingo@1044: ingo@1044: /** ingo@1044: * Set the shapefile path. ingo@1044: */ ingo@1044: public void setShapeFilePath(String shapeFilePath) { ingo@1044: synchronized (shapeFileLock) { ingo@1044: this.shapeFilePath = shapeFilePath; ingo@1044: } ingo@1044: } ingo@1044: tim@859: /** tim@859: * Returns the basic-directory where the Shapefiles should be placed in. tim@859: * @param callContext the Context of this Call tim@859: * @return the Directory where the Shapefiles could be placed in. tim@859: * (Please create an own directory in this dir and not put the tim@859: * Files directly in it) tim@859: */ tim@649: private static File shapefileDirectory(CallContext callContext) { tim@859: // Code was taken from HorizontalCrossSectionMeshOutputState tim@649: GNVArtifactContext context = tim@649: (GNVArtifactContext)callContext.globalContext(); tim@649: File dir = (File)context.get( tim@649: GNVArtifactContext.HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY); tim@649: return dir != null tim@649: ? dir tim@649: : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH; tim@649: } sascha@778: ingo@813: tim@649: @Override tim@649: public void endOfLife(Object globalContext) { tim@649: super.endOfLife(globalContext); tim@649: // do it in background tim@649: new Thread() { ingo@813: @Override tim@649: public void run() { tim@649: String path = resetShapeFilePath(); tim@649: if (path == null) { tim@649: return; tim@649: } tim@649: File dir = new File(path); tim@649: for (int i = 0; i < 10; ++i) { tim@649: if (!dir.exists() || FileUtils.deleteRecursive(dir)) { tim@649: MapfileGenerator.getInstance().update(); tim@649: return; tim@649: } tim@649: try { tim@649: Thread.sleep(10000L); tim@649: } tim@649: catch (InterruptedException ie) { tim@649: } tim@649: } tim@649: tim@649: log.error("failed to remove directory '" + path + "'"); tim@649: } // run tim@649: }.start(); tim@649: } sascha@778: tim@822: /** tim@822: * Resets the Settings e.g shapeFilePath and templateID tim@822: * @return tim@822: */ tim@822: private String resetShapeFilePath() { tim@649: synchronized (shapeFileLock) { tim@649: String path = shapeFilePath; tim@649: shapeFilePath = null; tim@649: return path; tim@649: } tim@649: } ingo@813: ingo@813: ingo@813: /** ingo@813: * Write data to shapefiles and feed a map service with information about ingo@813: * these shapefiles. The map service can be queried for displaying ingo@813: * corresponding layers as WMS. ingo@813: * ingo@813: * @param uuid The UUID of the current artifact. ingo@813: * @param callContext The CallContext object. tim@859: * @param layerMetaData The Metadata which is required to create the tim@859: * different Layers. tim@828: * @param inputData the Parameters which are send by the out-Call. ingo@813: * @return a document with some meta information (shapefile path, geometry ingo@813: * type, time to live of the current artifact, etc). ingo@813: * @throws StateException if an error occured while shapefile writing. ingo@813: */ ingo@1044: protected Document getWMS( ingo@1044: String uuid, ingo@1044: CallContext callContext, ingo@1044: Collection layerMetaData, ingo@1044: Collection inputData) tim@655: throws StateException tim@655: { ingo@1044: Document document = XMLUtils.newDocument(); ingo@1044: ingo@1044: File baseDir = shapefileDirectory(callContext); ingo@1044: File shapeDir = new File(baseDir, uuid); ingo@1044: ingo@1044: boolean success = false; ingo@1044: boolean createdDir = false; ingo@1044: ingo@1044: try { ingo@1044: // create shapefile directory or delete content if it already exists ingo@1044: synchronized (shapeFileLock) { ingo@1044: if (shapeDir.exists()) { ingo@1044: FileUtils.deleteContent(shapeDir); tim@859: } ingo@1044: else if (!shapeDir.mkdirs()) { ingo@1044: log.error("cannot create directory '" ingo@1044: + shapeDir.getAbsolutePath() + "'"); ingo@1044: return null; ingo@1044: } ingo@1044: setShapeFilePath(shapeDir.getAbsolutePath()); ingo@1044: createdDir = true; tim@859: } ingo@1044: ingo@1044: // process data tim@859: Iterator it = layerMetaData.iterator(); ingo@1057: ingo@1057: // create meta file ingo@1057: Document meta = MetaWriter.initMeta(); ingo@1057: MetaWriter.insertAbstractMeta(callContext, meta); ingo@1057: ingo@1057: String path = getShapeFilePath(); ingo@1057: String prefix = getLayerPrefix(inputData); ingo@1057: ingo@1057: if (prefix == null) { ingo@1057: prefix = uuid; ingo@1057: } ingo@1057: tim@859: int layerNumber = 0; tim@1070: Envelope mbr = new Envelope(); tim@859: while (it.hasNext()){ tim@859: LayerMetaData lmd = it.next(); tim@859: layerNumber ++; ingo@1057: tim@859: String geometryType = lmd.getGeometryType(); ingo@1057: String templateId = lmd.getTemplateID(); ingo@1057: tim@859: ExclusiveExec.UniqueKey key = ExclusiveExec.INSTANCE.acquire(uuid); tim@859: try{ tim@1070: Collection results = this.fetchData(lmd,mbr); ingo@1057: if (results != null && writeToShapeFile(uuid, results, ingo@1057: callContext, ingo@1057: geometryType, ingo@1057: layerNumber) != null) { ingo@1057: String name = getLayerName(uuid, layerNumber); ingo@1057: String base = lmd.getLayertitle(); ingo@1057: String title = getLayerTitle(prefix, base); ingo@1057: String data = getLayerData( ingo@1057: uuid, createShapeFileName(layerNumber)); ingo@1057: String type = determineGeometryType(geometryType); ingo@1057: String status = "OFF"; ingo@1057: String model = findParameterTitle( ingo@1057: geometryType, templateId); ingo@1057: ingo@1057: MetaWriter.insertLayer( ingo@1057: callContext, meta, name, title, ingo@1057: data, model, type, status); tim@859: } ingo@1044: ingo@1044: success = true; ingo@1044: tim@859: if (meta != null && !it.hasNext()) { tim@1070: MetaWriter.insertMbr(mbr, "EPSG:4326",meta); ingo@1057: MetaWriter.writeMetaFile(path, meta); tim@859: MapfileGenerator.getInstance().update(); ingo@1057: return meta; tim@859: } tim@859: }finally{ tim@859: ExclusiveExec.INSTANCE.release(key); tim@859: } tim@859: } tim@1070: tim@859: return document; tim@859: } ingo@1044: finally { ingo@1044: if (!success && createdDir) { ingo@1044: FileUtils.deleteRecursive(shapeDir); ingo@1044: } ingo@1044: } tim@859: } tim@655: tim@859: /** tim@859: * Creates the name of the Shapefile tim@859: * @param layerNumber the Number of the Layer tim@859: * @return the create name of the Shapefile. tim@859: */ tim@859: private String createShapeFileName(int layerNumber) { tim@859: return SHAPEFILE_NAME+"_"+layerNumber+".shp"; tim@859: } tim@655: sascha@778: ingo@1057: protected String getLayerName(String uuid, int idx) { ingo@1111: return "GNV_" + uuid + "_" + idx; ingo@1057: } ingo@1057: ingo@1057: ingo@1057: protected String getLayerTitle(String prefix, String base) { ingo@1111: return "GNV_" + prefix + "_" + base; ingo@1057: } ingo@1057: ingo@1057: ingo@1057: protected String getLayerData(String shapeDir, String filename) { ingo@1057: File path = new File(shapeDir, filename); ingo@1057: ingo@1057: return path.toString(); ingo@1057: } ingo@1057: ingo@1057: tim@828: /** tim@828: * Returns the parameterType for the Layer. tim@828: * @param geometryType tim@828: * @return tim@828: */ tim@859: private String findParameterTitle(String geometryType, String templateID) { tim@828: String paramType = LAYER_MODEL+"_"+templateID; tim@828: if (!MapfileGenerator.getInstance().templateExists(paramType)){ tim@828: // If the template doesn't exist the Defaulttemplates will be used. tim@828: paramType = LAYER_MODEL+"_"+ tim@828: this.determineDefaultTemplateName(geometryType); tim@828: } tim@828: return paramType; tim@828: } tim@828: tim@828: /** tim@828: * Find the title for a wms layer specified by the user. tim@828: * tim@828: * @param inputData A collection with InputData objects. tim@828: * @return the title. tim@828: */ ingo@1057: protected String getLayerPrefix(Collection inputData) { tim@828: for (InputData data: inputData) { tim@828: String name = data.getName(); tim@828: if (name != null && name.equals("title")) { tim@828: return (String) data.getValue(); tim@828: } tim@828: } tim@828: return null; tim@828: } tim@828: ingo@813: ingo@813: /** ingo@813: * Turns the geometry type into a form used for the templating mechanism ingo@813: * while mapfile generation. sascha@835: * ingo@813: * @param geometryType The original geometry type. ingo@813: * @return a valid geometry type fpr the template mechanism. ingo@813: */ tim@799: private String determineGeometryType(String geometryType){ tim@799: String returnValue = geometryType.toLowerCase(); tim@655: if (returnValue.equalsIgnoreCase("linestring")){ tim@655: returnValue = "Line"; tim@799: }else if (returnValue.equalsIgnoreCase("multilinestring")){ tim@799: returnValue ="Line"; tim@799: }else if (returnValue.equalsIgnoreCase("multipolygon")){ tim@799: returnValue = "Polygon"; tim@799: } tim@799: return returnValue; tim@799: } sascha@803: ingo@813: ingo@813: /** ingo@813: * Determine the default template name if no special template is existing ingo@813: * for this layer. ingo@813: * ingo@813: * @param geometryType The geometry type. ingo@813: * @return a default geometry fitting to the original geometry type. ingo@813: */ tim@799: private String determineDefaultTemplateName(String geometryType){ tim@799: String returnValue = geometryType.toLowerCase(); tim@799: if (returnValue.equalsIgnoreCase("multilinestring")){ tim@799: returnValue ="linestring"; tim@799: }else if (returnValue.equalsIgnoreCase("multipolygon")){ tim@799: returnValue = "polygon"; tim@799: }else if (returnValue.equalsIgnoreCase("multipoint")){ tim@799: returnValue = "point"; tim@655: } tim@655: return returnValue; tim@655: } tim@616: } sascha@836: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :