Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/utils/MapfileGenerator.java @ 5379:61bf64b102bc mapgenfix
Merge with default branch
author | Christian Lins <christian.lins@intevation.de> |
---|---|
date | Fri, 22 Mar 2013 11:25:54 +0100 |
parents | b55975761708 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/MapfileGenerator.java Fri Mar 22 11:25:54 2013 +0100 @@ -0,0 +1,384 @@ +package de.intevation.flys.utils; + +import de.intevation.artifacts.common.utils.Config; +import de.intevation.flys.artifacts.model.LayerInfo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.log4j.Logger; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.RuntimeConstants; + +/** + * This class iterates over a bunch of directories, searches for meta + * information coresponding to shapefiles and creates a mapfile which is used by + * a <i>MapServer</i>. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public abstract class MapfileGenerator +{ + public static final String WSPLGEN_RESULT_SHAPE = "wsplgen.shp"; + public static final String WSPLGEN_LINES_SHAPE = "barrier_lines.shp"; + public static final String WSPLGEN_POLYGONS_SHAPE = "barrier_polygons.shp"; + public static final String WSPLGEN_USER_SHAPE = "user-rgd.shp"; + + public static final String WSPLGEN_LAYER_TEMPLATE = "wsplgen_layer.vm"; + public static final String SHP_LAYER_TEMPLATE = "shapefile_layer.vm"; + public static final String DB_LAYER_TEMPLATE = "db_layer.vm"; + public static final String RIVERAXIS_LAYER_TEMPLATE = "riveraxis-layer.vm"; + + public static final String MS_WSPLGEN_PREFIX = "wsplgen-"; + public static final String MS_BARRIERS_PREFIX = "barriers-"; + public static final String MS_LINE_PREFIX = "lines-"; + public static final String MS_POLYGONS_PREFIX = "polygons-"; + public static final String MS_LAYER_PREFIX = "ms_layer-"; + public static final String MS_USERSHAPE_PREFIX = "user-"; + + private static Logger logger = Logger.getLogger(MapfileGenerator.class); + + private File shapefileDirectory; + + private VelocityEngine velocityEngine; + + + protected MapfileGenerator() { + } + + + /** + * Method to check the existance of a template file. + * + * @param templateID The name of a template. + * @return true, of the template exists - otherwise false. + */ + public boolean templateExists(String templateID){ + Template template = getTemplateByName(templateID); + return template != null; + } + + + public abstract void generate() throws Exception; + + + /** + * Returns the VelocityEngine used for the template mechanism. + * + * @return the velocity engine. + */ + protected VelocityEngine getVelocityEngine() { + if (velocityEngine == null) { + velocityEngine = new VelocityEngine(); + try { + setupVelocity(velocityEngine); + } + catch (Exception e) { + logger.error(e, e); + return null; + } + } + return velocityEngine; + } + + + /** + * Initialize velocity. + * + * @param engine Velocity engine. + * @throws Exception if an error occured while initializing velocity. + */ + protected void setupVelocity(VelocityEngine engine) + throws Exception + { + engine.setProperty( + "input.encoding", + "UTF-8"); + + engine.setProperty( + RuntimeConstants.RUNTIME_LOG, + getVelocityLogfile()); + + engine.setProperty( + "resource.loader", + "file"); + + engine.setProperty( + "file.resource.loader.path", + getMapserverTemplatePath()); + + engine.init(); + } + + protected abstract String getVelocityLogfile(); + + protected abstract String getMapserverTemplatePath(); + + public abstract String getMapserverUrl(); + + protected VelocityContext getVelocityContext() { + VelocityContext context = new VelocityContext(); + + try { + context.put("MAPSERVERURL", + getMapserverUrl()); + context.put("SHAPEFILEPATH", + getShapefileBaseDir().getCanonicalPath()); + context.put("CONFIGDIR", + Config.getConfigDirectory().getCanonicalPath()); + } + catch (FileNotFoundException fnfe) { + // this is bad + logger.warn(fnfe, fnfe); + } + catch (IOException ioe) { + // this is also bad + logger.warn(ioe, ioe); + } + + return context; + } + + + /** + * Returns a template specified by <i>model</i>. + * + * @param model The name of the template. + * @return a template. + */ + public 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; + } + + + /** + * Returns the mapfile template. + * + * @return the mapfile template. + * @throws Exception if an error occured while reading the configuration. + */ + protected Template getMapfileTemplateObj() + throws Exception + { + String mapfileName = getMapfileTemplate(); + return getTemplateByName(mapfileName); + } + + protected abstract String getMapfilePath(); + + protected abstract String getMapfileTemplate(); + + + /** + * Returns the base directory storing the shapefiles. + * + * @return the shapefile base directory. + * + * @throws FileNotFoundException if no shapefile path is found or + * configured. + */ + public File getShapefileBaseDir() + throws FileNotFoundException, IOException + { + if (shapefileDirectory == null) { + String path = FLYSUtils.getXPathString( + FLYSUtils.XPATH_FLOODMAP_SHAPEFILE_DIR); + + if (path != null) { + shapefileDirectory = new File(path); + } + + if (shapefileDirectory == null) { + throw new FileNotFoundException("No shapefile directory given"); + } + + if (!shapefileDirectory.exists()) { + shapefileDirectory.mkdirs(); + } + } + + return shapefileDirectory; + } + + + protected File[] getUserDirs() + throws FileNotFoundException, IOException + { + File baseDir = getShapefileBaseDir(); + File[] artifactDirs = baseDir.listFiles(); + + // TODO ONLY RETURN DIRECTORIES OF THE SPECIFIED USER + + return artifactDirs; + } + + + + protected List<String> parseLayers(File[] dirs) { + List<String> layers = new ArrayList<String>(); + + for (File dir: dirs) { + File[] layerFiles = dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File directory, String name) { + return name.startsWith(MS_LAYER_PREFIX); + } + }); + + for (File layer: layerFiles) { + try { + layers.add(layer.getCanonicalPath()); + } + catch (IOException ioe) { + logger.warn(ioe, ioe); + } + } + } + + return layers; + } + + + + + /** + * Creates a layer snippet which might be included in the mapfile. + * + * @param layerinfo A LayerInfo object that contains all necessary + * information to build a Mapserver LAYER section. + * @param dir The base dir for the LAYER snippet. + * @param filename The name of the file that is written. + * @param tpl The Velocity template which is used to create the LAYER + * section. + */ + public void writeLayer( + LayerInfo layerInfo, + File layerFile, + Template tpl + ) + throws FileNotFoundException + { + if (logger.isDebugEnabled()) { + logger.debug("Write layer for:"); + logger.debug(" directory/file: " + layerFile.getName()); + } + + Writer writer = null; + + try { + writer = new FileWriter(layerFile); + + VelocityContext context = getVelocityContext(); + context.put("LAYER", layerInfo); + + tpl.merge(context, writer); + } + catch (FileNotFoundException fnfe) { + logger.error(fnfe, fnfe); + } + catch (IOException ioe) { + logger.error(ioe, ioe); + } + catch (Exception e) { + logger.error(e, e); + } + finally { + try { + if (writer != null) { + writer.close(); + } + } + catch (IOException ioe) { + logger.debug(ioe, ioe); + } + } + } + + + /** + * Creates a mapfile with the layer information stored in <i>layers</i>. + * + * @param layers Layer information. + */ + public void writeMapfile(List<String> layers) { + String tmpMapName = "mapfile" + new Date().getTime(); + + File mapfile = new File(getMapfilePath()); + + File tmp = null; + Writer writer = null; + + try { + tmp = new File(mapfile.getParent(), tmpMapName); + tmp.createNewFile(); + + writer = new FileWriter(tmp); + + VelocityContext context = getVelocityContext(); + context.put("LAYERS", layers); + + Template mapTemplate = getMapfileTemplateObj(); + 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(mapfile); + } + catch (FileNotFoundException fnfe) { + logger.error(fnfe, fnfe); + } + catch (IOException ioe) { + logger.error(ioe, ioe); + } + catch (Exception e) { + logger.error(e, e); + } + finally { + try { + if (writer != null) { + writer.close(); + } + + 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 :