Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java @ 622:89aca25642d6
Implemented method stubs of MapfileGenerator. Mapfiles are successfully created corresponding meta.xml files.
gnv-artifacts/trunk@693 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Fri, 19 Feb 2010 13:28:34 +0000 |
parents | 567216b56983 |
children | 65f09139e9b3 |
line wrap: on
line diff
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java Wed Feb 17 09:40:15 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java Fri Feb 19 13:28:34 2010 +0000 @@ -1,6 +1,36 @@ package de.intevation.gnv.utils; +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.wms.LayerInfo; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import javax.xml.xpath.XPathConstants; + import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** @@ -9,9 +39,29 @@ public class MapfileGenerator extends Thread { + public static final String TEMPLATE_PATH = + "/artifact-database/map-generator/templates/path/text()"; + + public static final String TEMPLATE_MAPFILE = + "/artifact-database/map-generator/templates/maptemplate/text()"; public static final String MAPFILE_PATH = - "/artifact-database/map-generator/mapfile/@path"; + "/artifact-database/map-generator/mapfile/path/text()"; + + public static final String MAPFILE_NAME = + "/artifact-database/map-generator/mapfile/name/text()"; + + public static final String SHAPEFILE_BASE_DIR = + "/artifact-database/map-generator/mapfile/shapefiles/text()"; + + public static final String META_FILE_NAME = "meta.xml"; + + public static final String XPATH_LAYER = "/art:meta/art:layer"; + public static final String XPATH_LAYER_NAME = "art:name"; + public static final String XPATH_LAYER_TYPE = "art:type"; + public static final String XPATH_LAYER_DATA = "art:data"; + public static final String XPATH_LAYER_STATUS = "art:status"; + public static final String XPATH_LAYER_MODEL = "art:model"; protected static final long SLEEPTIME = 10 * 1000L; // 10 seconds @@ -19,6 +69,7 @@ private static MapfileGenerator instance; + private VelocityEngine velocityEngine; private boolean lock[]; @@ -29,7 +80,7 @@ public static void main(String[] args) { - // TODO Implement me + // TODO IMPLEMENT ME } @@ -46,6 +97,7 @@ public void update() { synchronized (lock) { + logger.debug("update"); lock[0] = true; lock.notify(); } @@ -53,27 +105,292 @@ public void run() { + logger.debug("Start MapfileGenerator thread..."); try { for (;;) { synchronized (lock) { while (!lock[0]) { lock.wait(SLEEPTIME); } - lock[0] = false; } - - logger.info("Update mapfile for MapServer."); + + logger.debug("Start sync process now..."); generate(); } } catch (InterruptedException ie) { + logger.debug("MapfileGenerator thread got an interrupt."); + } + finally { + logger.debug("THREAD END"); } } - private void generate() { - logger.debug("IMPLEMENT ME"); + protected void generate() { + File basedir = new File(getShapefileBaseDir()); + List layers = new ArrayList(); + searchMetaInformation(basedir, layers); + writeMapfile(layers); + } + + + protected VelocityEngine getVelocityEngine() { + if (velocityEngine == null) { + velocityEngine = new VelocityEngine(); + try { + setupVelocity(velocityEngine); + } + catch (Exception e) { + logger.error(e, e); + return null; + } + } + return velocityEngine; + } + + + protected void setupVelocity(VelocityEngine engine) + throws Exception + { + Properties ps = new Properties(); + + ps.setProperty( + "input.encoding", + "UTF-8"); + + ps.setProperty( + "resource.loader", + "class"); + + ps.setProperty( + "class.resource.loader.class", + "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + + engine.init(ps); + } + + + protected String getTemplateBaseDir() { + return Config.getStringXPath(TEMPLATE_PATH); + } + + + protected Template getTemplateByName(String model) { + String templatePath = getTemplateBaseDir(); + if (model.indexOf(".vm") < 0) { + model = model.concat(".vm"); + } + + File file = new File(templatePath, model); + if (!file.exists() || !file.canRead()) { + logger.warn("Can't find template file: " + file.getAbsolutePath()); + return null; + } + + try { + VelocityEngine engine = getVelocityEngine(); + if (engine == null) { + logger.error("Error while fetching VelocityEngine."); + return null; + } + + return engine.getTemplate(file.getAbsolutePath()); + } + catch (Exception e) { + logger.warn(e, e); + } + + return null; + } + + + protected Template getMapfileTemplate() + throws Exception + { + String mapfileName = Config.getStringXPath(TEMPLATE_MAPFILE); + return getTemplateByName(mapfileName); + } + + + protected String getShapefileBaseDir() { + return Config.getStringXPath(SHAPEFILE_BASE_DIR); + } + + + protected void searchMetaInformation(File file, List store) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + + if (files != null && files.length != 0) { + int size = files.length; + for (File tmp: files) { + searchMetaInformation(tmp, store); + } + } + } + else if (file.getName().equals(META_FILE_NAME)) { + LayerInfo[] info = parseMeta(file); + + int infoSize = info.length; + for (int j = 0; j < infoSize; j++) { + if (info[j] != null) { + store.add(info[j]); + } + } + } + } + + + protected LayerInfo[] parseMeta(File file) { + Document meta = XMLUtils.parseDocument(file); + List layers = new ArrayList(); + + NodeList layerset = (NodeList) XMLUtils.xpath( + meta, + XPATH_LAYER, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + + int size = layerset.getLength(); + for (int i = 0; i < size; i++) { + LayerInfo info = parseLayer(layerset.item(i)); + + if (info != null && !info.isEmpty() && !info.isBroken()) { + layers.add(info); + } + else { + logger.warn("Found broken LayerInfo object."); + } + } + + return (LayerInfo[]) layers.toArray(new LayerInfo[layers.size()]); + } + + + protected LayerInfo parseLayer(Node layer) { + LayerInfo info = new LayerInfo(); + + String name = parseLayerAttr(layer, XPATH_LAYER_NAME); + if (name != null && !name.equals("")) { + info.setName(name); + } + + String model = parseLayerAttr(layer, XPATH_LAYER_MODEL); + if (model != null && !model.equals("")) { + info.setModel(model); + } + + String type = parseLayerAttr(layer, XPATH_LAYER_TYPE); + if (type != null && !type.equals("")) { + info.setType(type); + } + + String data = parseLayerAttr(layer, XPATH_LAYER_DATA); + if (data != null && !data.equals("")) { + info.setData(data); + } + + String status = parseLayerAttr(layer, XPATH_LAYER_STATUS); + if (status != null && !status.equals("")) { + info.setStatus(status); + } + + return info; + } + + + protected String parseLayerAttr(Node node, String xpath) { + return (String) XMLUtils.xpath( + node, + xpath, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + protected void writeMapfile(List layers) { + String pathName = Config.getStringXPath(MAPFILE_PATH); + String mapName = Config.getStringXPath(MAPFILE_NAME); + String tmpMapName = "mapfile" + new Date().getTime(); + + int layersize = layers.size(); + StringBuilder sb = new StringBuilder(); + StringWriter sw = null; + LayerInfo info = null; + + for (int i = 0; i < layersize; i++) { + sw = new StringWriter(); + info = (LayerInfo) layers.get(i); + + Template layerTemplate = getTemplateByName(info.getModel()); + VelocityContext context = new VelocityContext(); + context.put("info", info); + + try { + layerTemplate.merge(context, sw); + sb.append(sw.toString()); + } + catch (IOException ioe) { + logger.warn("Error while filling layer template."); + logger.warn(ioe, ioe); + } + } + + Writer writer = null; + File tmp = null; + File map = null; + + try { + tmp = new File(pathName, tmpMapName); + map = new File(pathName, mapName); + + tmp.createNewFile(); + writer = new FileWriter(tmp); + + VelocityContext context = new VelocityContext(); + context.put("LAYERS", sb.toString()); + + Template mapTemplate = getMapfileTemplate(); + if (mapTemplate == null) { + logger.warn("No mapfile template found."); + return; + } + + mapTemplate.merge(context, writer); + + // we need to create a temporary mapfile first und rename it into + // real mapfile because we don't run into race conditions on this + // way. (iw) + tmp.renameTo(map); + } + catch (FileNotFoundException fnfe) { + logger.error(fnfe, fnfe); + } + catch (IOException ioe) { + logger.error(ioe, ioe); + } + catch (Exception e) { + logger.error(e, e); + } + finally { + try { + // close file writer + if (writer != null) { + writer.close(); + } + + // remove temporary mapfile if an error occured and it still + // exists + if (tmp.exists()) { + tmp.delete(); + } + } + catch (IOException ioe) { + logger.debug(ioe, ioe); + } + } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: