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: 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: tim@616: import de.intevation.artifactdatabase.Config; tim@616: import de.intevation.artifactdatabase.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")) { tim@859: tim@859: 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")){ tim@859: Collection layerMetaData = tim@859: this.getRequestedLayerMetadata(); tim@859: tim@859: if (layerMetaData != null && !layerMetaData.isEmpty()){ tim@859: 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: /** tim@859: * 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); 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 { tim@859: 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@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: } tim@859: returnValue.add(new LayerMetaData(table, geometryType, tim@859: where, columns, tim@859: templateID, queryValues, tim@859: geometryWKT)); 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@859: protected Collection fetchData(LayerMetaData layerMetaData){ 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@859: if (data != null && layerMetaData.getGeometryWKT() != null){ tim@859: WKTReader wktReader = new WKTReader(); tim@859: Geometry border = wktReader.read(layerMetaData.getGeometryWKT()); 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@859: Geometry newGeometry = currentGeometry.intersection(border); tim@859: current.addColumnValue(0, newGeometry.toText()); 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 tim@859: * @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@859: while(it.hasNext()){ tim@859: LayerMetaData lmd = it.next(); tim@859: Collection data = this.fetchData(lmd); 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: 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: */ sascha@778: protected Document getWMS(String uuid, sascha@778: CallContext callContext, tim@859: Collection layerMetaData, tim@828: Collection inputData) tim@655: throws StateException tim@655: { tim@859: String path = getShapeFilePath(); tim@859: if (path != null && new File(path).isDirectory()){ tim@859: return this.refreshMetaFile(layerMetaData, inputData, tim@859: uuid, callContext); tim@859: }else{ tim@859: Document document = XMLUtils.newDocument(); tim@859: if (this.shapeFilePath == null){ tim@859: File baseDir = shapefileDirectory(callContext); tim@859: if (!this.createShapeDir(baseDir, uuid)){ tim@859: // TODO Insert Error Report tim@859: return document; tim@859: } tim@859: } tim@859: path = getShapeFilePath(); tim@859: Iterator it = layerMetaData.iterator(); tim@859: Node meta = null; tim@859: int layerNumber = 0; tim@859: while (it.hasNext()){ tim@859: LayerMetaData lmd = it.next(); tim@859: layerNumber ++; tim@859: String geometryType = lmd.getGeometryType(); tim@859: String templateId = lmd.getTemplateID(); tim@859: ExclusiveExec.UniqueKey key = ExclusiveExec.INSTANCE.acquire(uuid); tim@859: try{ tim@859: Collection data = this.fetchData(lmd); tim@859: if (data != null && tim@859: (this.writeToShapeFile(uuid, data, callContext, tim@859: geometryType,layerNumber)) != null) { tim@859: String paramType = findParameterTitle(geometryType,templateId); tim@859: String title = getLayerTitle(inputData); tim@859: if (title == null) { tim@859: title = uuid+"_"+layerNumber; tim@859: }else{ tim@859: title = title+"_"+layerNumber; tim@859: } tim@859: if (meta == null){ tim@859: meta = MetaWriter.writeLayerMeta(callContext,document); tim@859: } tim@859: MetaWriter.writeLayerMeta(callContext, document, tim@859: meta, uuid, paramType, tim@859: this.determineGeometryType(geometryType), tim@859: createShapeFileName(layerNumber), tim@859: title); tim@859: } tim@859: if (meta != null && !it.hasNext()) { tim@859: MetaWriter.writeMetaFile(path,document); tim@859: MapfileGenerator.getInstance().update(); tim@859: return document; tim@859: } tim@859: }finally{ tim@859: ExclusiveExec.INSTANCE.release(key); tim@859: } tim@859: } tim@859: return document; tim@859: } 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: tim@859: /** tim@859: * Method that refreshes the Metadatafile for publishing the WMS tim@859: * Without generating the Data ones again. tim@859: * @param layerMetaData the Metadata which is required to create the Layers tim@859: * @param inputData the Inputdata which was sent by the Client tim@859: * @param uuid the uuid of the Artifact tim@859: * @param callContext the context of this Call tim@859: * @return a refreshed Metadata-Document tim@859: */ tim@859: private Document refreshMetaFile(Collection layerMetaData, tim@859: Collection inputData, tim@859: String uuid, tim@859: CallContext callContext){ tim@859: Document document = XMLUtils.newDocument(); tim@859: Node meta = null; tim@859: int layerNumber = 0; tim@859: Iterator it = layerMetaData.iterator(); tim@859: while (it.hasNext()){ tim@859: LayerMetaData lmd = it.next(); tim@859: layerNumber ++; tim@859: String geometryType = lmd.getGeometryType(); tim@859: String templateId = lmd.getTemplateID(); tim@828: String title = getLayerTitle(inputData); tim@828: if (title == null) { tim@859: title = uuid+"_"+layerNumber; tim@859: }else{ tim@859: title = title+"_"+layerNumber; tim@828: } tim@828: callContext.putContextValue( tim@828: MetaWriter.CONTEXT_LAYER_TITLE, title); tim@859: String paramType = findParameterTitle(geometryType,templateId); tim@828: if (log.isDebugEnabled()) { tim@828: log.debug("Layer title: " + title); tim@828: log.debug("Layer type: " + paramType); tim@828: } tim@859: if (meta == null){ tim@859: meta = MetaWriter.writeLayerMeta(callContext,document); tim@828: } tim@859: MetaWriter.writeLayerMeta(callContext, document, tim@859: meta, uuid, paramType, tim@859: this.determineGeometryType(geometryType), tim@859: createShapeFileName(layerNumber), tim@859: title); tim@859: if (meta != null && !it.hasNext()) { tim@859: MetaWriter.writeMetaFile(getShapeFilePath(),document); tim@859: MapfileGenerator.getInstance().update(); tim@859: return document; tim@655: } tim@655: } tim@655: return document; tim@655: } sascha@778: 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: */ tim@828: protected String getLayerTitle(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 :