# HG changeset patch # User Sascha L. Teichmann # Date 1263746051 0 # Node ID 20dde2b6f1b529bd279dbd1bba00363aed68ddaf # Parent 211cad2fb5baae492542f71fb23d118c122cedc6 Added end of life support for artifact states. Implemented ZIP download for "Horizontalschnitte". Laid some tracks for WMS (un-)publishing. gnv-artifacts/trunk@554 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 211cad2fb5ba -r 20dde2b6f1b5 gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Sun Jan 17 12:22:56 2010 +0000 +++ b/gnv-artifacts/ChangeLog Sun Jan 17 16:34:11 2010 +0000 @@ -1,3 +1,24 @@ +2010-01-17 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/state/State.java: Added + support for end of life. + + * src/main/java/de/intevation/gnv/state/StateBase.java: Implemented + end of life trivial. + + * src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java: + call end of life when leaving state. + + * src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java: + Used XMLUtils.toStream() instead of own tranformer code. Removed + dead code. + + * src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java: + Implemented end of life. Remove shapefile directory from + file system belonging to concrete artifact. + Implemented download as ZIP file. Offer some link for + WMS integration. TODO: implement the real WMS publishing here. + 2010-01-17 Sascha L. Teichmann * doc/conf/products/horizontalcrosssection/conf_mesh.xml: diff -r 211cad2fb5ba -r 20dde2b6f1b5 gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Sun Jan 17 12:22:56 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Sun Jan 17 16:34:11 2010 +0000 @@ -61,9 +61,9 @@ import org.w3c.dom.NodeList; /** - * @author Tim Englich - * @author Ingo Weinzierl - * + * @author Tim Englich (tim.englich@intevation.de) + * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) + * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) */ public abstract class GNVArtifactBase extends DefaultArtifact { /** @@ -170,6 +170,10 @@ next.putInputData(current.getInputData(), identifier); next.setParent(current); + if (current != null) { + current.endOfLife(context.globalContext()); + } + // 3. Switch to next State current = next; @@ -190,6 +194,10 @@ // remove data from future states from cache resetDescribeData(current, identifier, targetState); + if (current != null) { + current.endOfLife(context.globalContext()); + } + current = next; result = createReport( @@ -814,7 +822,7 @@ } } - protected String readOutputType(Document document) { + protected static String readOutputType(Document document) { String value = XMLUtils.xpathString( document, XPATH_OUTPUT_NAME, ArtifactNamespaceContext.INSTANCE); return value; @@ -824,5 +832,13 @@ public void setProduct(Product product) { this.product = product; } + + public void endOfLife(Object globalContext) { + super.endOfLife(globalContext); + + if (current != null) { + current.endOfLife(globalContext); + } + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: diff -r 211cad2fb5ba -r 20dde2b6f1b5 gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java Sun Jan 17 12:22:56 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/State.java Sun Jan 17 16:34:11 2010 +0000 @@ -3,19 +3,22 @@ */ package de.intevation.gnv.state; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.state.exception.StateException; + import java.io.Serializable; + import java.util.Collection; import java.util.Map; import org.w3c.dom.Document; import org.w3c.dom.Node; -import de.intevation.artifacts.CallMeta; -import de.intevation.gnv.state.exception.StateException; - /** - * @author Tim Englich - * + * @author Tim Englich (tim.englich@intevation.de) + * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) + * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) */ public interface State extends Serializable { @@ -47,4 +50,6 @@ throws StateException; public void reset(String uuid); + + public void endOfLife(Object globalContext); } diff -r 211cad2fb5ba -r 20dde2b6f1b5 gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java Sun Jan 17 12:22:56 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/StateBase.java Sun Jan 17 16:34:11 2010 +0000 @@ -3,6 +3,38 @@ */ package de.intevation.gnv.state; +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; + +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.gnv.artifacts.GNVArtifactBase; + +import de.intevation.gnv.artifacts.cache.CacheFactory; + +import de.intevation.gnv.artifacts.ressource.RessourceFactory; + +import de.intevation.gnv.geobackend.base.Result; + +import de.intevation.gnv.geobackend.base.query.QueryExecutor; +import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; + +import de.intevation.gnv.geobackend.base.query.exception.QueryException; + +import de.intevation.gnv.geobackend.util.DateUtils; + +import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; +import de.intevation.gnv.state.describedata.KeyValueDescibeData; +import de.intevation.gnv.state.describedata.MinMaxDescribeData; +import de.intevation.gnv.state.describedata.NamedArrayList; +import de.intevation.gnv.state.describedata.NamedCollection; +import de.intevation.gnv.state.describedata.SingleValueDescribeData; + +import de.intevation.gnv.state.exception.StateException; + +import de.intevation.gnv.utils.InputValidator; + import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -15,36 +47,16 @@ import java.util.Set; import org.apache.log4j.Logger; + import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import de.intevation.artifactdatabase.Config; -import de.intevation.artifactdatabase.XMLUtils; -import de.intevation.artifacts.ArtifactNamespaceContext; -import de.intevation.artifacts.CallMeta; -import de.intevation.gnv.artifacts.GNVArtifactBase; -import de.intevation.gnv.artifacts.cache.CacheFactory; -import de.intevation.gnv.artifacts.ressource.RessourceFactory; -import de.intevation.gnv.geobackend.base.Result; -import de.intevation.gnv.geobackend.base.query.QueryExecutor; -import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; -import de.intevation.gnv.geobackend.base.query.exception.QueryException; -import de.intevation.gnv.geobackend.util.DateUtils; -import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData; -import de.intevation.gnv.state.describedata.KeyValueDescibeData; -import de.intevation.gnv.state.describedata.MinMaxDescribeData; -import de.intevation.gnv.state.describedata.NamedArrayList; -import de.intevation.gnv.state.describedata.NamedCollection; -import de.intevation.gnv.state.describedata.SingleValueDescribeData; -import de.intevation.gnv.state.exception.StateException; -import de.intevation.gnv.utils.InputValidator; - /** - * @author Tim Englich - * @author Ingo Weinzierl - * + * @author Tim Englich (tim.englich@intevation.de) + * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) + * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) */ public abstract class StateBase implements State { @@ -860,5 +872,8 @@ public Collection getInputData() throws StateException { return this.inputData != null ? this.inputData.values() : null; } + + public void endOfLife(Object globalContext) { + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: diff -r 211cad2fb5ba -r 20dde2b6f1b5 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java Sun Jan 17 12:22:56 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java Sun Jan 17 16:34:11 2010 +0000 @@ -1,6 +1,3 @@ -/** - * - */ package de.intevation.gnv.state.profile.horizontalcrosssection; import com.vividsolutions.jts.geom.Coordinate; @@ -36,6 +33,7 @@ import de.intevation.gnv.state.timeseries.TimeSeriesOutputState; +import de.intevation.gnv.utils.FileUtils; import de.intevation.gnv.utils.StringUtils; import de.intevation.gnv.utils.WKTUtils; @@ -48,6 +46,7 @@ import org.apache.log4j.Logger; import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.w3c.dom.Node; /** @@ -65,7 +64,11 @@ */ private static final long serialVersionUID = 3233620652465061860L; - private String ijkQueryID = null; + private String ijkQueryID; + + private Boolean shapeFileLock = new Boolean(true); + + private String shapeFilePath; /** * Constructor @@ -73,6 +76,57 @@ public HorizontalCrossSectionMeshOutputState() { } + public String getShapeFilePath() { + synchronized (shapeFileLock) { + return shapeFilePath; + } + } + + public void setShapeFilePath(String shapeFilePath) { + synchronized (shapeFileLock) { + this.shapeFilePath = shapeFilePath; + } + } + + public String resetShapeFilePath() { + synchronized (shapeFileLock) { + String path = shapeFilePath; + shapeFilePath = null; + return path; + } + } + + public void endOfLife(Object globalContext) { + super.endOfLife(globalContext); + + // do it in background + new Thread() { + public void run() { + // TODO: Do the un-publishing WMS stuff. + String path = resetShapeFilePath(); + + if (path == null) { + return; + } + + File dir = new File(path); + + for (int i = 0; i < 10; ++i) { + if (!dir.exists() || FileUtils.deleteRecursive(dir)) { + return; + } + try { + Thread.sleep(10000L); + } + catch (InterruptedException ie) { + } + } + + log.error("failed to remove directory '" + path + "'"); + } // run + }.start(); + } + public void out( Document format, Collection inputData, @@ -97,23 +151,105 @@ log.debug("---- asking for: " + outputMode); if ("zip".equals(outputMode)) { + writeZip(uuid, callContext, outputStream); } else if ("wms".equals(outputMode)) { + XMLUtils.toStream( + getWMS(uuid, callContext), + outputStream); } else if ("statistics".equals(outputMode)) { // TODO: REMOVE THIS! - try { - outputStream.write("\n".getBytes()); - } - catch (IOException ioe) { - } + try { outputStream.write("\n".getBytes()); } + catch (IOException ioe) {} } else { throw new StateException("unsupported output mode"); } } - protected Object getResult(String uuid, CallContext callContext) + protected void writeZip( + String uuid, + CallContext callContext, + OutputStream output + ) + throws StateException + { + try { + String p = getShapeFilePath(); + if (p != null) { + File dir = new File(p); + if (dir.isDirectory()) { + FileUtils.createZipArchive(dir, output); + } + } + AttributedPoint2ds result = getResult(uuid, callContext); + if (result != null + && (p = writeToShapeFile(uuid, result, callContext)) != null) { + FileUtils.createZipArchive(new File(p), output); + } + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + } + + protected Document getWMS(String uuid, CallContext callContext) + throws StateException + { + // TODO: Do the real WMS publishing here! + Document document = XMLUtils.newDocument(); + + Element pathElement = document.createElement("path"); + document.appendChild(pathElement); + + String path = getShapeFilePath(); + + if (path != null && new File(path).isDirectory()) { + pathElement.setTextContent(path); + } + else { + AttributedPoint2ds result = getResult(uuid, callContext); + if (result != null + && (path = writeToShapeFile(uuid, result, callContext)) != null) { + pathElement.setTextContent(path); + } + } + + return document; + } + + protected String writeToShapeFile( + String uuid, + AttributedPoint2ds result, + CallContext callContext + ) { + File baseDir = shapefileDirectory(callContext); + + File shapeDir = new File(baseDir, uuid); + + int count = 0; + + synchronized (shapeFileLock) { + while (shapeDir.exists()) { + shapeDir = new File(baseDir, uuid + "-" + count); + ++count; + } + + if (!shapeDir.mkdirs()) { + log.error("cannot create directory '" + + shapeDir.getAbsolutePath() + "'"); + return null; + } + shapeFilePath = shapeDir.getAbsolutePath(); + } + + // TODO: Do the writing + + return shapeFilePath; + } + + protected AttributedPoint2ds getResult(String uuid, CallContext callContext) throws StateException { CacheFactory cf = CacheFactory.getInstance(); @@ -122,11 +258,11 @@ if (cf.isInitialized()) { net.sf.ehcache.Element value = cf.getCache().get(key); if (value != null) { - return value.getObjectValue(); + return (AttributedPoint2ds)value.getObjectValue(); } } - Object result = produceResult(callContext); + AttributedPoint2ds result = produceResult(callContext); if (result != null && cf.isInitialized()) { cf.getCache().put(new net.sf.ehcache.Element(key, result)); @@ -135,7 +271,7 @@ return result; } - protected Object produceResult(CallContext callContext) + protected AttributedPoint2ds produceResult(CallContext callContext) throws StateException { InputData meshPolygon = inputData.get("mesh_polygon"); @@ -218,10 +354,12 @@ } } + // TODO: do the interpolation + return ap2ds; } - public Object process( + public AttributedPoint2ds process( Envelope env, Polygon polygon, int numSamples, diff -r 211cad2fb5ba -r 20dde2b6f1b5 gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java Sun Jan 17 12:22:56 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java Sun Jan 17 16:34:11 2010 +0000 @@ -68,16 +68,6 @@ import java.util.Locale; import java.util.Vector; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; - -import javax.xml.transform.dom.DOMSource; - -import javax.xml.transform.stream.StreamResult; - import org.apache.log4j.Logger; import org.jfree.chart.ChartTheme; @@ -89,8 +79,8 @@ /** - * @author Tim Englich - * + * @author Tim Englich (tim.englich@intevation.de) + * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) */ public class TimeSeriesOutputState extends OutputStateBase { @@ -408,7 +398,7 @@ Document doc = writeStatistics2XML(statistics); - writeDocument2OutputStream(doc, outputStream); + XMLUtils.toStream(doc, outputStream); } else if (outputMode.equalsIgnoreCase("odv")) { @@ -519,24 +509,6 @@ return s; } - protected void writeDocument2OutputStream(Document document, OutputStream os) { - - try { - TransformerFactory transformerFactory = TransformerFactory - .newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - DOMSource source = new DOMSource(document); - StreamResult result = new StreamResult(os); - transformer.transform(source, result); - } catch (TransformerConfigurationException e) { - log.error(e, e); - } catch (TransformerFactoryConfigurationError e) { - log.error(e, e); - } catch (TransformerException e) { - log.error(e, e); - } - } - protected Document writeStatistics2XML( Collection statistic) { ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); Document doc = XMLUtils.newDocument(); @@ -689,21 +661,6 @@ PDF_FORMAT_LANDSCAPE, 50F, 50F, 50F, 50F ); - - /* XXX: @Ingo: What's this? Looks like dev test remains. - try { - OutputStream toFile = new FileOutputStream("/vol1/home/iweinzierl/tmp/test.svg"); - ChartExportHelper.exportSVG( - toFile, - chart.generateChart(), - null, - 600, 400 - ); - toFile.flush(); - toFile.close(); - } - catch(Exception e) { log.debug("ERROR WHLILE TEST."); } - */ }