Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | 40ead2d2a08d |
children | 9ba6bb85d6dd |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java Fri Sep 28 12:13:53 2012 +0200 @@ -0,0 +1,417 @@ +package de.intevation.gnv.utils; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.gnv.wms.LayerInfo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +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; + + +/** + * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) + */ +public class MapfileGenerator +extends Thread +{ + public static final String TEMPLATE_PATH = + "/artifact-database/gnv/map-generator/templates/path/text()"; + + public static final String TEMPLATE_MAPFILE = + "/artifact-database/gnv/map-generator/templates/maptemplate/text()"; + + public static final String MAPFILE_PATH = + "/artifact-database/gnv/map-generator/mapfile/@path"; + + public static final String SHAPEFILE_BASE_DIR = + "/artifact-database/gnv/shapefile-directory/@path"; + + public static final String VELOCITY_LOGFILE = + "/artifact-database/velocity/logfile/@path"; + + 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 + + private static Logger logger = Logger.getLogger(MapfileGenerator.class); + + private static MapfileGenerator instance; + + private File mapfile; + private String shapefileDirectory; + private String templatePath; + private String velocityLogfile; + + private VelocityEngine velocityEngine; + private boolean lock[]; + + + + private MapfileGenerator() { + lock = new boolean[1]; + } + + + public static void main(String[] args) { + // TODO IMPLEMENT ME + } + + + public static synchronized MapfileGenerator getInstance() { + if (instance == null) { + instance = new MapfileGenerator(); + instance.setDaemon(true); + instance.start(); + } + + return instance; + } + + + public void update() { + synchronized (lock) { + logger.debug("update"); + lock[0] = true; + lock.notify(); + } + } + + + public void run() { + logger.debug("Start MapfileGenerator thread..."); + try { + for (;;) { + synchronized (lock) { + while (!lock[0]) { + lock.wait(SLEEPTIME); + } + lock[0] = false; + } + + logger.debug("Start sync process now..."); + generate(); + } + } + catch (InterruptedException ie) { + logger.debug("MapfileGenerator thread got an interrupt."); + } + finally { + logger.debug("THREAD END"); + } + } + + + 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 + { + engine.setProperty( + "input.encoding", + "UTF-8"); + + engine.setProperty( + VelocityEngine.RUNTIME_LOG, + getVelocityLogfile()); + + engine.setProperty( + "resource.loader", + "file"); + + engine.setProperty( + "file.resource.loader.path", + getTemplateBaseDir()); + + engine.init(); + } + + + protected String getVelocityLogfile() { + if (velocityLogfile == null) + velocityLogfile = Config.getStringXPath(VELOCITY_LOGFILE); + + return velocityLogfile; + } + + + protected String getTemplateBaseDir() { + if (templatePath == null) { + templatePath = Config.getStringXPath(TEMPLATE_PATH); + templatePath = Config.replaceConfigDir(templatePath); + } + + return templatePath; + } + + + protected Template getTemplateByName(String model) { + if (model.indexOf(".vm") < 0) { + model = model.concat(".vm"); + } + + try { + VelocityEngine engine = getVelocityEngine(); + if (engine == null) { + logger.error("Error while fetching VelocityEngine."); + return null; + } + + return engine.getTemplate(model); + } + 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() { + if (shapefileDirectory == null) { + shapefileDirectory = Config.getStringXPath(SHAPEFILE_BASE_DIR); + shapefileDirectory = Config.replaceConfigDir(shapefileDirectory); + } + + return shapefileDirectory; + } + + + protected File getMapfile() { + if (mapfile == null) { + String tmp = Config.getStringXPath(MAPFILE_PATH); + tmp = Config.replaceConfigDir(tmp); + mapfile = new File(tmp); + } + + return mapfile; + } + + + 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 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); + } + } + + File map = getMapfile(); + Writer writer = null; + File tmp = null; + + try { + tmp = new File(map.getParent(), tmpMapName); + + 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: