ingo@1129: package de.intevation.flys.utils;
ingo@1129: 
ingo@1129: import java.io.File;
ingo@1781: import java.io.FilenameFilter;
ingo@1129: import java.io.FileNotFoundException;
ingo@1129: import java.io.FileWriter;
ingo@1129: import java.io.IOException;
ingo@1129: import java.io.Writer;
ingo@1129: 
ingo@1129: import java.util.ArrayList;
ingo@1129: import java.util.Date;
ingo@1129: import java.util.List;
ingo@1129: 
ingo@1129: import org.apache.log4j.Logger;
ingo@1129: 
raimund@2639: import org.geotools.data.shapefile.ShpFiles;
raimund@2639: import org.geotools.data.shapefile.shp.ShapefileReader;
raimund@2639: import org.geotools.data.shapefile.shp.ShapefileHeader;
raimund@2639: 
ingo@1129: import org.apache.velocity.Template;
ingo@1129: import org.apache.velocity.VelocityContext;
ingo@1129: import org.apache.velocity.app.VelocityEngine;
ingo@1129: 
raimund@2637: import de.intevation.artifacts.CallContext;
ingo@1710: import de.intevation.artifacts.common.utils.Config;
ingo@1710: 
ingo@1775: import de.intevation.flys.artifacts.FLYSArtifact;
ingo@1129: import de.intevation.flys.artifacts.model.LayerInfo;
ingo@1775: import de.intevation.flys.artifacts.model.WMSLayerFacet;
raimund@2638: import de.intevation.flys.artifacts.model.WSPLGENLayerFacet;
ingo@1792: import de.intevation.flys.artifacts.model.WMSDBLayerFacet;
raimund@2637: import de.intevation.flys.artifacts.resources.Resources;
ingo@1129: 
ingo@1129: /**
ingo@1129:  * This class iterates over a bunch of directories, searches for meta
ingo@1129:  * information coresponding to shapefiles and creates a mapfile which is used by
ingo@1129:  * a <i>MapServer</i>.
ingo@1129:  *
ingo@1129:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@1129:  */
ingo@1129: public class MapfileGenerator
ingo@1129: extends Thread
ingo@1129: {
ingo@1134:     public static final String WSPLGEN_RESULT_SHAPE   = "wsplgen.shp";
ingo@1134:     public static final String WSPLGEN_LINES_SHAPE    = "barrier_lines.shp";
ingo@1134:     public static final String WSPLGEN_POLYGONS_SHAPE = "barrier_polygons.shp";
raimund@2639:     public static final String WSPLGEN_USER_SHAPE     = "user-rgd.shp";
ingo@1134: 
raimund@2637:     public static final String WSPLGEN_LAYER_TEMPLATE = "wsplgen_layer.vm";
ingo@1775:     public static final String SHP_LAYER_TEMPLATE = "shapefile_layer.vm";
ingo@1792:     public static final String DB_LAYER_TEMPLATE  = "db_layer.vm";
ingo@1775: 
raimund@2639:     public static final String MS_WSPLGEN_PREFIX   = "wsplgen-";
raimund@2639:     public static final String MS_BARRIERS_PREFIX  = "barriers-";
raimund@2639:     public static final String MS_LINE_PREFIX      = "lines-";
raimund@2639:     public static final String MS_POLYGONS_PREFIX  = "polygons-";
raimund@2639:     public static final String MS_LAYER_PREFIX     = "ms_layer-";
raimund@2639:     public static final String MS_USERSHAPE_PREFIX = "user-";
ingo@1129: 
ingo@1129:     protected static final long SLEEPTIME = 10 * 1000L; // 10 seconds
ingo@1129: 
ingo@1129:     private static Logger logger = Logger.getLogger(MapfileGenerator.class);
ingo@1129: 
ingo@1129:     private static MapfileGenerator instance;
ingo@1129: 
ingo@1129:     private File mapfile;
ingo@1129:     private File shapefileDirectory;
ingo@1129: 
ingo@1129:     private String mapServerUrl;
ingo@1129:     private String templatePath;
ingo@1129:     private String velocityLogfile;
ingo@1129: 
ingo@1129:     private VelocityEngine velocityEngine;
ingo@1129:     private boolean lock[];
ingo@1129: 
ingo@1129: 
ingo@1129: 
ingo@1129:     private MapfileGenerator() {
ingo@1129:         lock = new boolean[1];
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * A main method which can be used to create a mapfile without a running
ingo@1129:      * artifact server.<br>
ingo@1129:      * <b>NOTE:</b> This method is not implemented yet!
ingo@1129:      *
ingo@1129:      * @param args Arguments.
ingo@1129:      */
ingo@1129:     public static void main(String[] args) {
ingo@1129:         throw new Error("MapfileGenerator.main() is CURRENTLY NOT IMPLEMENTED!");
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Returns the instance of this generator.
ingo@1129:      *
ingo@1129:      * @return the instance.
ingo@1129:      */
ingo@1129:     public static synchronized MapfileGenerator getInstance() {
ingo@1129:         if (instance == null) {
ingo@1129:             instance = new MapfileGenerator();
ingo@1129:             instance.setDaemon(true);
ingo@1129:             instance.start();
ingo@1129:         }
ingo@1129: 
ingo@1129:         return instance;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Triggers the mapfile generation process.
ingo@1129:      */
ingo@1129:     public void update() {
ingo@1129:         synchronized (lock) {
ingo@1129:             logger.debug("update");
ingo@1129:             lock[0] = true;
ingo@1129:             lock.notify();
ingo@1129:         }
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Thread to generate a mapfile.
ingo@1129:      */
ingo@1129:     @Override
ingo@1129:     public void run() {
ingo@1129:         logger.debug("Start MapfileGenerator thread...");
ingo@1129:         try {
ingo@1129:             for (;;) {
ingo@1129:                 synchronized (lock) {
ingo@1129:                     while (!lock[0]) {
ingo@1129:                         lock.wait(SLEEPTIME);
ingo@1129:                     }
ingo@1129:                     lock[0] = false;
ingo@1129:                 }
ingo@1129: 
ingo@1129:                 logger.debug("Start sync process now...");
ingo@1129:                 generate();
ingo@1129:             }
ingo@1129:         }
ingo@1129:         catch (InterruptedException ie) {
ingo@1129:             logger.debug("MapfileGenerator thread got an interrupt.");
ingo@1129:         }
ingo@1129:         catch (FileNotFoundException fnfe) {
ingo@1129:             logger.debug("Error while mapfile creation: " + fnfe.getMessage());
ingo@1129:         }
ingo@1775:         catch (IOException ioe) {
ingo@1775:             logger.error(ioe, ioe);
ingo@1775:         }
ingo@1129:         finally {
ingo@1129:             logger.debug("THREAD END");
ingo@1129:         }
ingo@1129:     }
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Method to check the existance of a template file.
ingo@1129:      *
ingo@1129:      * @param templateID The name of a template.
ingo@1129:      * @return true, of the template exists - otherwise false.
ingo@1129:      */
ingo@1129:     public boolean templateExists(String templateID){
ingo@1129:         Template template = getTemplateByName(templateID);
ingo@1129:         return template != null;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Method which starts searching for meta information file and mapfile
ingo@1129:      * generation.
ingo@1129:      */
ingo@1129:     protected void generate()
ingo@1775:     throws    FileNotFoundException, IOException
ingo@1129:     {
ingo@1129:         File[]        userDirs = getUserDirs();
ingo@1781: 
ingo@1781:         List<String> layers = parseLayers(userDirs);
ingo@1129: 
ingo@1129:         logger.info("Found " + layers.size() + " layers for user mapfile.");
ingo@1129: 
ingo@1129:         writeMapfile(layers);
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Returns the VelocityEngine used for the template mechanism.
ingo@1129:      *
ingo@1129:      * @return the velocity engine.
ingo@1129:      */
ingo@1129:     protected VelocityEngine getVelocityEngine() {
ingo@1129:         if (velocityEngine == null) {
ingo@1129:             velocityEngine = new VelocityEngine();
ingo@1129:             try {
ingo@1129:                 setupVelocity(velocityEngine);
ingo@1129:             }
ingo@1129:             catch (Exception e) {
ingo@1129:                 logger.error(e, e);
ingo@1129:                 return null;
ingo@1129:             }
ingo@1129:         }
ingo@1129:         return velocityEngine;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Initialize velocity.
ingo@1129:      *
ingo@1129:      * @param engine Velocity engine.
ingo@1129:      * @throws Exception if an error occured while initializing velocity.
ingo@1129:      */
ingo@1129:     protected void setupVelocity(VelocityEngine engine)
ingo@1129:     throws Exception
ingo@1129:     {
ingo@1129:         engine.setProperty(
ingo@1129:             "input.encoding",
ingo@1129:             "UTF-8");
ingo@1129: 
ingo@1129:         engine.setProperty(
ingo@1129:             VelocityEngine.RUNTIME_LOG,
ingo@1129:             FLYSUtils.getXPathString(FLYSUtils.XPATH_VELOCITY_LOGFILE));
ingo@1129: 
ingo@1129:         engine.setProperty(
ingo@1129:             "resource.loader",
ingo@1129:             "file");
ingo@1129: 
ingo@1129:         engine.setProperty(
ingo@1129:             "file.resource.loader.path",
ingo@1129:             FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPSERVER_TEMPLATE_PATH));
ingo@1129: 
ingo@1129:         engine.init();
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1792:     protected VelocityContext getVelocityContext() {
ingo@1792:         VelocityContext context = new VelocityContext();
ingo@1792: 
ingo@1792:         try {
ingo@1792:             context.put("MAPSERVERURL",
ingo@1792:                 FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPSERVER_URL));
ingo@1792:             context.put("SHAPEFILEPATH",
ingo@1792:                 getShapefileBaseDir().getCanonicalPath());
ingo@1792:             context.put("CONFIGDIR",
ingo@1792:                 Config.getConfigDirectory().getCanonicalPath());
ingo@1792:         }
ingo@1792:         catch (FileNotFoundException fnfe) {
ingo@1792:             // this is bad
ingo@1792:         }
ingo@1792:         catch (IOException ioe) {
ingo@1792:             // this is also bad
ingo@1792:         }
ingo@1792: 
ingo@1792:         return context;
ingo@1792:     }
ingo@1792: 
ingo@1792: 
ingo@1129:     /**
ingo@1129:      * Returns a template specified by <i>model</i>.
ingo@1129:      *
ingo@1129:      * @param model The name of the template.
ingo@1129:      * @return a template.
ingo@1129:      */
ingo@1129:     protected Template getTemplateByName(String model) {
ingo@1129:         if (model.indexOf(".vm") < 0) {
ingo@1129:             model = model.concat(".vm");
ingo@1129:         }
ingo@1129: 
ingo@1129:         try {
ingo@1129:             VelocityEngine engine = getVelocityEngine();
ingo@1129:             if (engine == null) {
ingo@1129:                 logger.error("Error while fetching VelocityEngine.");
ingo@1129:                 return null;
ingo@1129:             }
ingo@1129: 
ingo@1129:             return engine.getTemplate(model);
ingo@1129:         }
ingo@1129:         catch (Exception e) {
ingo@1129:             logger.warn(e, e);
ingo@1129:         }
ingo@1129: 
ingo@1129:         return null;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Returns the mapfile  template.
ingo@1129:      *
ingo@1129:      * @return the mapfile template.
ingo@1129:      * @throws Exception if an error occured while reading the configuration.
ingo@1129:      */
ingo@1129:     protected Template getMapfileTemplate()
ingo@1129:     throws Exception
ingo@1129:     {
ingo@1129:         String mapfileName = FLYSUtils.getXPathString(
ingo@1129:             FLYSUtils.XPATH_MAPFILE_TEMPLATE);
ingo@1129: 
ingo@1129:         return getTemplateByName(mapfileName);
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     /**
ingo@1129:      * Returns the base directory storing the shapefiles.
ingo@1129:      *
ingo@1129:      * @return the shapefile base directory.
ingo@1129:      *
ingo@1129:      * @throws FileNotFoundException if no shapefile path is found or
ingo@1129:      * configured.
ingo@1129:      */
ingo@1792:     public File getShapefileBaseDir()
ingo@1775:     throws    FileNotFoundException, IOException
ingo@1129:     {
ingo@1129:         if (shapefileDirectory == null) {
ingo@1129:             String path = FLYSUtils.getXPathString(
ingo@1129:                 FLYSUtils.XPATH_SHAPEFILE_DIR);
ingo@1129: 
ingo@1129:             if (path != null) {
ingo@1129:                 shapefileDirectory = new File(path);
ingo@1129:             }
ingo@1129: 
ingo@1775:             if (shapefileDirectory == null) {
ingo@1129:                 throw new FileNotFoundException("No shapefile directory given");
ingo@1129:             }
ingo@1775: 
ingo@1775:             if (!shapefileDirectory.exists()) {
ingo@1775:                 shapefileDirectory.createNewFile();
ingo@1775:             }
ingo@1129:         }
ingo@1129: 
ingo@1129:         return shapefileDirectory;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129:     protected File[] getUserDirs()
ingo@1775:     throws    FileNotFoundException, IOException
ingo@1129:     {
ingo@1129:         File   baseDir      = getShapefileBaseDir();
ingo@1129:         File[] artifactDirs = baseDir.listFiles();
ingo@1129: 
ingo@1129:         // TODO ONLY RETURN DIRECTORIES OF THE SPECIFIED USER
ingo@1129: 
ingo@1129:         return artifactDirs;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1129: 
ingo@1781:     protected List<String> parseLayers(File[] dirs) {
ingo@1781:         List<String> layers = new ArrayList<String>();
ingo@1129: 
ingo@1129:         for (File dir: dirs) {
ingo@1781:             File[] layerFiles = dir.listFiles(new FilenameFilter() {
ingo@1781:                 @Override
ingo@1781:                 public boolean accept(File directory, String name) {
ingo@1781:                     return name.startsWith(MS_LAYER_PREFIX);
ingo@1781:                 }
ingo@1781:             });
ingo@1129: 
ingo@1781:             for (File layer: layerFiles) {
ingo@1781:                 try {
ingo@1781:                     layers.add(layer.getCanonicalPath());
ingo@1781:                 }
ingo@1781:                 catch (IOException ioe) {
ingo@1781:                     logger.warn(ioe, ioe);
ingo@1134:                 }
ingo@1129:             }
ingo@1129:         }
ingo@1129: 
ingo@1129:         return layers;
ingo@1129:     }
ingo@1129: 
ingo@1129: 
ingo@1775:     /**
ingo@1775:      * Creates a layer file used for Mapserver's mapfile which represents the
ingo@1775:      * floodmap.
ingo@1775:      *
ingo@1775:      * @param flys The FLYSArtifact that owns <i>wms</i>.
ingo@1775:      * @param wms The WMSLayerFacet that contains information for the layer.
ingo@1775:      */
ingo@2616:     public void createUeskLayer(
ingo@2616:         FLYSArtifact  flys,
raimund@2638:         WSPLGENLayerFacet wms,
raimund@2637:         String        style,
raimund@2637:         CallContext context
ingo@2616:     ) throws FileNotFoundException, IOException
ingo@1775:     {
ingo@1775:         logger.debug("createUeskLayer");
ingo@1775: 
ingo@1816:         LayerInfo layerinfo = new LayerInfo();
ingo@1956:         layerinfo.setName(MS_WSPLGEN_PREFIX + flys.identifier());
ingo@1816:         layerinfo.setType("POLYGON");
ingo@1816:         layerinfo.setDirectory(flys.identifier());
ingo@1816:         layerinfo.setData(WSPLGEN_RESULT_SHAPE);
raimund@2637:         layerinfo.setTitle(Resources.getMsg(Resources.getLocale(context.getMeta()),
raimund@2637:                                             "floodmap.uesk",
raimund@2637:                                             "Floodmap"));
ingo@2616:         layerinfo.setStyle(style);
ingo@2669:         layerinfo.setSrid(wms.getSrid());
ingo@1775: 
ingo@1775:         String name = MS_LAYER_PREFIX + wms.getName();
ingo@1775: 
raimund@2637:         Template template = getTemplateByName(WSPLGEN_LAYER_TEMPLATE);
ingo@1775:         if (template == null) {
raimund@2637:             logger.warn("Template '" + WSPLGEN_LAYER_TEMPLATE + "' found.");
ingo@1775:             return;
ingo@1775:         }
ingo@1775: 
ingo@1775:         try {
ingo@1775:             File dir = new File(getShapefileBaseDir(), flys.identifier());
ingo@1775:             writeLayer(layerinfo, dir, name, template);
ingo@1775:         }
ingo@1775:         catch (FileNotFoundException fnfe) {
ingo@1775:             logger.error(fnfe, fnfe);
ingo@1775:             logger.warn("Unable to write layer: " + name);
ingo@1775:         }
ingo@1775:     }
ingo@1775: 
ingo@1775: 
ingo@1775:     /**
ingo@1775:      * Creates a layer file used for Mapserver's mapfile which represents the
ingo@1775:      * user defined barriers.
ingo@1775:      *
ingo@1775:      * @param flys The FLYSArtifact that owns <i>wms</i>.
ingo@1775:      * @param wms The WMSLayerFacet that contains information for the layer.
ingo@1775:      */
ingo@1775:     public void createBarriersLayer(FLYSArtifact flys, WMSLayerFacet wms)
ingo@1775:     throws FileNotFoundException, IOException
ingo@1775:     {
ingo@1775:         logger.debug("createBarriersLayer");
ingo@1775: 
ingo@1775:         String uuid = flys.identifier();
ingo@1775:         File   dir  = new File(getShapefileBaseDir(), uuid);
ingo@1775: 
ingo@1830:         createBarriersLineLayer(flys, wms);
ingo@1830:         createBarriersPolygonLayer(flys, wms);
ingo@1830:     }
ingo@1830: 
ingo@1830: 
ingo@1830:     protected void createBarriersLineLayer(
ingo@1830:         FLYSArtifact  flys,
ingo@1830:         WMSLayerFacet wms
ingo@1830:     )
ingo@1830:     throws FileNotFoundException, IOException
ingo@1830:     {
ingo@1830:         String uuid       = flys.identifier();
ingo@1956:         String group      = MS_BARRIERS_PREFIX + uuid;
ingo@1775:         String groupTitle = "I18N_BARRIERS_TITLE";
ingo@1775: 
ingo@1830:         File dir  = new File(getShapefileBaseDir(), uuid);
ingo@1830:         File test = new File(dir, WSPLGEN_LINES_SHAPE);
ingo@1830: 
ingo@1830:         if (!test.exists() || !test.canRead()) {
ingo@1830:             logger.debug("No barrier line layer existing.");
ingo@1830:             return;
ingo@1830:         }
ingo@1830: 
ingo@1816:         LayerInfo lineInfo = new LayerInfo();
ingo@1956:         lineInfo.setName(MS_LINE_PREFIX + uuid);
ingo@1816:         lineInfo.setType("LINE");
ingo@1816:         lineInfo.setDirectory(uuid);
ingo@1816:         lineInfo.setData(WSPLGEN_LINES_SHAPE);
ingo@1816:         lineInfo.setTitle("I18N_LINE_SHAPE");
ingo@1816:         lineInfo.setGroup(group);
ingo@1816:         lineInfo.setGroupTitle(groupTitle);
ingo@2669:         lineInfo.setSrid(wms.getSrid());
ingo@1775: 
ingo@1830:         String nameLines = MS_LAYER_PREFIX + wms.getName() + "-lines";
ingo@1775: 
ingo@1775:         Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE);
ingo@1775:         if (tpl == null) {
ingo@1775:             logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found.");
ingo@1775:             return;
ingo@1775:         }
ingo@1775: 
ingo@1775:         try {
ingo@1775:             writeLayer(lineInfo, dir, nameLines, tpl);
ingo@1775:         }
ingo@1775:         catch (FileNotFoundException fnfe) {
ingo@1775:             logger.error(fnfe, fnfe);
ingo@1775:             logger.warn("Unable to write layer: " + nameLines);
ingo@1775:         }
ingo@1830:     }
ingo@1830: 
ingo@1830: 
ingo@1830:     protected void createBarriersPolygonLayer(
ingo@1830:         FLYSArtifact  flys,
ingo@1830:         WMSLayerFacet wms
ingo@1830:     )
ingo@1830:     throws FileNotFoundException, IOException
ingo@1830:     {
ingo@1830:         String uuid       = flys.identifier();
ingo@1956:         String group      = uuid + MS_BARRIERS_PREFIX;
ingo@1830:         String groupTitle = "I18N_BARRIERS_TITLE";
ingo@1830: 
ingo@1830:         File dir  = new File(getShapefileBaseDir(), uuid);
ingo@1830:         File test = new File(dir, WSPLGEN_POLYGONS_SHAPE);
ingo@1830: 
ingo@1830:         if (!test.exists() || !test.canRead()) {
ingo@1830:             logger.debug("No barrier line layer existing.");
ingo@1830:             return;
ingo@1830:         }
ingo@1830: 
ingo@1830:         LayerInfo polygonInfo = new LayerInfo();
ingo@1956:         polygonInfo.setName(MS_POLYGONS_PREFIX + uuid);
ingo@1830:         polygonInfo.setType("POLYGON");
ingo@1830:         polygonInfo.setDirectory(uuid);
ingo@1830:         polygonInfo.setData(WSPLGEN_POLYGONS_SHAPE);
ingo@1830:         polygonInfo.setTitle("I18N_POLYGON_SHAPE");
ingo@1830:         polygonInfo.setGroup(group);
ingo@1830:         polygonInfo.setGroupTitle(groupTitle);
ingo@2669:         polygonInfo.setSrid(wms.getSrid());
ingo@1830: 
ingo@1830:         String namePolygons = MS_LAYER_PREFIX + wms.getName() + "-polygons";
ingo@1830: 
ingo@1830:         Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE);
ingo@1830:         if (tpl == null) {
ingo@1830:             logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found.");
ingo@1830:             return;
ingo@1830:         }
ingo@1775: 
ingo@1775:         try {
ingo@1775:             writeLayer(polygonInfo, dir, namePolygons, tpl);
ingo@1775:         }
ingo@1775:         catch (FileNotFoundException fnfe) {
ingo@1775:             logger.error(fnfe, fnfe);
ingo@1830:             logger.warn("Unable to write layer: " + namePolygons);
ingo@1775:         }
ingo@1775:     }
ingo@1775: 
ingo@1775: 
ingo@1781:     /**
raimund@2639:      * Creates a layer file used for Mapserver's mapfile which represents the
raimund@2639:      * shape files uploaded by the user.
raimund@2639:      *
raimund@2639:      * @param flys The FLYSArtifact that owns <i>wms</i>.
raimund@2639:      * @param wms The WMSLayerFacet that contains information for the layer.
raimund@2639:      */
raimund@2639:     public void createUserShapeLayer(FLYSArtifact flys, WMSLayerFacet wms)
raimund@2639:     throws FileNotFoundException, IOException
raimund@2639:     {
raimund@2639:         logger.debug("createUserShapeLayer");
raimund@2639: 
raimund@2639:         String uuid = flys.identifier();
raimund@2639:         File   dir  = new File(getShapefileBaseDir(), uuid);
raimund@2639:         File   test = new File(dir, WSPLGEN_USER_SHAPE);
raimund@2639: 
raimund@2639:         if (!test.exists() || !test.canRead()) {
raimund@2639:             logger.debug("No user layer existing.");
raimund@2639:             return;
raimund@2639:         }
raimund@2639: 
raimund@2639:         File userShape = new File(dir, WSPLGEN_USER_SHAPE);
raimund@2639:         ShpFiles sf = new ShpFiles(userShape);
raimund@2639:         ShapefileReader sfr = new ShapefileReader(sf, true, false, null);
raimund@2639:         ShapefileHeader sfh = sfr.getHeader();
raimund@2639: 
raimund@2639:         String group      = uuid + MS_USERSHAPE_PREFIX;
raimund@2639:         String groupTitle = "I18N_USER_SHAPE_TITLE";
raimund@2639: 
raimund@2639:         LayerInfo info = new LayerInfo();
raimund@2639:         info.setName(MS_USERSHAPE_PREFIX + uuid);
raimund@2639:         if (sfh.getShapeType().isLineType()) {
raimund@2639:             info.setType("LINE");
raimund@2639:         }
raimund@2639:         else if (sfh.getShapeType().isPolygonType()) {
raimund@2639:             info.setType("POLYGON");
raimund@2639:         }
raimund@2639:         else {
raimund@2639:             return;
raimund@2639:         }
raimund@2639:         info.setDirectory(uuid);
raimund@2639:         info.setData(WSPLGEN_USER_SHAPE);
raimund@2639:         info.setTitle("I18N_USER_SHAPE");
raimund@2639:         info.setGroup(group);
raimund@2639:         info.setGroupTitle(groupTitle);
ingo@2669:         info.setSrid(wms.getSrid());
raimund@2639: 
raimund@2639:         String nameUser = MS_LAYER_PREFIX + wms.getName();
raimund@2639: 
raimund@2639:         Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE);
raimund@2639:         if (tpl == null) {
raimund@2639:             logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found.");
raimund@2639:             return;
raimund@2639:         }
raimund@2639: 
raimund@2639:         try {
raimund@2639:             writeLayer(info, dir, nameUser, tpl);
raimund@2639:         }
raimund@2639:         catch (FileNotFoundException fnfe) {
raimund@2639:             logger.error(fnfe, fnfe);
raimund@2639:             logger.warn("Unable to write layer: " + nameUser);
raimund@2639:         }
raimund@2639: 
raimund@2639:     }
raimund@2639: 
raimund@2639: 
raimund@2639:     /**
ingo@1792:      * Creates a layer file used for Mapserver's mapfile which represents
ingo@1792:      * geometries from database.
ingo@1792:      *
ingo@1792:      * @param flys The FLYSArtifact that owns <i>wms</i>.
ingo@1792:      * @param wms The WMSLayerFacet that contains information for the layer.
ingo@1792:      */
ingo@1793:     public void createDatabaseLayer(
ingo@1793:         FLYSArtifact    flys,
ingo@1793:         WMSDBLayerFacet wms,
ingo@1793:         String          style
ingo@1793:     )
ingo@1792:     throws FileNotFoundException, IOException
ingo@1792:     {
ingo@1792:         logger.debug("createDatabaseLayer");
ingo@1792: 
ingo@1816:         LayerInfo layerinfo = new LayerInfo();
ingo@1917:         layerinfo.setName(wms.getName() + "-" + flys.identifier());
ingo@1816:         layerinfo.setType(wms.getGeometryType());
ingo@1816:         layerinfo.setFilter(wms.getFilter());
ingo@1816:         layerinfo.setData(wms.getData());
ingo@1816:         layerinfo.setTitle(wms.getDescription());
ingo@1793:         layerinfo.setStyle(style);
ingo@1816:         layerinfo.setExtent(GeometryUtils.jtsBoundsToOLBounds(wms.getExtent()));
ingo@1854:         layerinfo.setConnection(wms.getConnection());
ingo@1854:         layerinfo.setConnectionType(wms.getConnectionType());
ingo@1876:         layerinfo.setLabelItem(wms.getLabelItem());
ingo@2669:         layerinfo.setSrid(wms.getSrid());
ingo@1792: 
ingo@1792:         String name = MS_LAYER_PREFIX + wms.getName();
ingo@1792: 
ingo@1792:         Template template = getTemplateByName(DB_LAYER_TEMPLATE);
ingo@1792:         if (template == null) {
ingo@1792:             logger.warn("Template '" + DB_LAYER_TEMPLATE + "' found.");
ingo@1792:             return;
ingo@1792:         }
ingo@1792: 
ingo@1792:         try {
ingo@1792:             File dir = new File(getShapefileBaseDir(), flys.identifier());
ingo@1792:             writeLayer(layerinfo, dir, name, template);
ingo@1792:         }
ingo@1792:         catch (FileNotFoundException fnfe) {
ingo@1792:             logger.error(fnfe, fnfe);
ingo@1792:             logger.warn("Unable to write layer: " + name);
ingo@1792:         }
ingo@1792:     }
ingo@1792: 
ingo@1792: 
ingo@1792:     /**
ingo@1781:      * Creates a layer snippet which might be included in the mapfile.
ingo@1781:      *
ingo@1781:      * @param layerinfo A LayerInfo object that contains all necessary
ingo@1781:      * information to build a Mapserver LAYER section.
ingo@1781:      * @param dir The base dir for the LAYER snippet.
ingo@1781:      * @param filename The name of the file that is written.
ingo@1781:      * @param tpl The Velocity template which is used to create the LAYER
ingo@1781:      * section.
ingo@1781:      */
ingo@1775:     protected void writeLayer(
ingo@1775:         LayerInfo layerinfo,
ingo@1775:         File      dir,
ingo@1781:         String    filename,
ingo@1775:         Template  tpl
ingo@1775:     )
ingo@1775:     throws    FileNotFoundException
ingo@1775:     {
ingo@1775:         if (logger.isDebugEnabled()) {
ingo@1775:             logger.debug("Write layer for:");
ingo@1775:             logger.debug("   directory: " + dir.getName());
ingo@1781:             logger.debug("   name:      " + filename);
ingo@1775:         }
ingo@1775: 
ingo@1781:         File   layer  = new File(dir, filename);
ingo@1775:         Writer writer = null;
ingo@1775: 
ingo@1775:         try {
ingo@1775:             writer = new FileWriter(layer);
ingo@1775: 
ingo@1792:             VelocityContext context = getVelocityContext();
ingo@1775:             context.put("LAYER", layerinfo);
ingo@1775: 
ingo@1775:             tpl.merge(context, writer);
ingo@1775:         }
ingo@1775:         catch (FileNotFoundException fnfe) {
ingo@1775:             logger.error(fnfe, fnfe);
ingo@1775:         }
ingo@1775:         catch (IOException ioe) {
ingo@1775:             logger.error(ioe, ioe);
ingo@1775:         }
ingo@1775:         catch (Exception e) {
ingo@1775:             logger.error(e, e);
ingo@1775:         }
ingo@1775:         finally {
ingo@1775:             try {
ingo@1775:                 if (writer != null) {
ingo@1775:                     writer.close();
ingo@1775:                 }
ingo@1775:             }
ingo@1775:             catch (IOException ioe) {
ingo@1775:                 logger.debug(ioe, ioe);
ingo@1775:             }
ingo@1775:         }
ingo@1775:     }
ingo@1775: 
ingo@1775: 
ingo@1129:     /**
ingo@1129:      * Creates a mapfile with the layer information stored in <i>layers</i>.
ingo@1129:      *
ingo@1129:      * @param layers Layer information.
ingo@1129:      */
ingo@1781:     protected void writeMapfile(List<String> layers) {
ingo@1129:         String tmpMapName = "mapfile" + new Date().getTime();
ingo@1129: 
ingo@1129:         File mapfile = new File(
ingo@1129:             FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPFILE_PATH));
ingo@1129: 
ingo@1129:         File   tmp     = null;
ingo@1129:         Writer writer  = null;
ingo@1129: 
ingo@1129:         try {
ingo@1129:             tmp = new File(mapfile.getParent(), tmpMapName);
ingo@1129:             tmp.createNewFile();
ingo@1129: 
ingo@1129:             writer = new FileWriter(tmp);
ingo@1129: 
ingo@1792:             VelocityContext context = getVelocityContext();
ingo@1781:             context.put("LAYERS", layers);
ingo@1129: 
ingo@1129:             Template mapTemplate = getMapfileTemplate();
ingo@1129:             if (mapTemplate == null) {
ingo@1129:                 logger.warn("No mapfile template found.");
ingo@1129:                 return;
ingo@1129:             }
ingo@1129: 
ingo@1129:             mapTemplate.merge(context, writer);
ingo@1129: 
ingo@1129:             // we need to create a temporary mapfile first und rename it into
ingo@1129:             // real mapfile because we don't run into race conditions on this
ingo@1129:             // way. (iw)
ingo@1129:             tmp.renameTo(mapfile);
ingo@1129:         }
ingo@1129:         catch (FileNotFoundException fnfe) {
ingo@1129:             logger.error(fnfe, fnfe);
ingo@1129:         }
ingo@1129:         catch (IOException ioe) {
ingo@1129:             logger.error(ioe, ioe);
ingo@1129:         }
ingo@1129:         catch (Exception e) {
ingo@1129:             logger.error(e, e);
ingo@1129:         }
ingo@1129:         finally {
ingo@1129:             try {
ingo@1129:                 if (writer != null) {
ingo@1129:                     writer.close();
ingo@1129:                 }
ingo@1129: 
ingo@1129:                 if (tmp.exists()) {
ingo@1129:                     tmp.delete();
ingo@1129:                 }
ingo@1129:             }
ingo@1129:             catch (IOException ioe) {
ingo@1129:                 logger.debug(ioe, ioe);
ingo@1129:             }
ingo@1129:         }
ingo@1129:     }
ingo@1129: }
ingo@1129: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :