Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/utils/MapfileGenerator.java @ 4488:5041105d2edd
Check if response code from GGInA is 200 OK
Only parse the GGInA response if the status code is 200 OK. This improves the
error message if GGInA is not available and shows the real reason instead of a
JDOM error while parsing the response.
author | Björn Ricks <bjoern.ricks@intevation.de> |
---|---|
date | Wed, 14 Nov 2012 10:36:21 +0100 |
parents | 3dc26ec2558d |
children | fc52ee878412 |
line wrap: on
line source
package de.intevation.flys.utils; import de.intevation.artifacts.CallContext; import de.intevation.artifacts.common.utils.Config; import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.model.LayerInfo; import de.intevation.flys.artifacts.model.map.WMSDBLayerFacet; import de.intevation.flys.artifacts.model.map.WMSLayerFacet; import de.intevation.flys.artifacts.model.map.WSPLGENLayerFacet; import de.intevation.flys.artifacts.resources.Resources; 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.geotools.data.shapefile.ShpFiles; import org.geotools.data.shapefile.shp.ShapefileHeader; import org.geotools.data.shapefile.shp.ShapefileReader; /** * 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 class MapfileGenerator extends Thread { 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 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-"; protected static final long SLEEPTIME = 10 * 1000L; // 10 seconds private static Logger logger = Logger.getLogger(MapfileGenerator.class); private static MapfileGenerator instance; private File shapefileDirectory; private VelocityEngine velocityEngine; private final boolean lock[]; private MapfileGenerator() { lock = new boolean[1]; } /** * A main method which can be used to create a mapfile without a running * artifact server.<br> * <b>NOTE:</b> This method is not implemented yet! * * @param args Arguments. */ public static void main(String[] args) { throw new Error("MapfileGenerator.main() is CURRENTLY NOT IMPLEMENTED!"); } /** * Returns the instance of this generator. * * @return the instance. */ public static synchronized MapfileGenerator getInstance() { if (instance == null) { instance = new MapfileGenerator(); instance.setDaemon(true); instance.start(); } return instance; } /** * Triggers the mapfile generation process. */ public void update() { synchronized (lock) { logger.debug("update"); lock[0] = true; lock.notify(); } } /** * Thread to generate a mapfile. */ @Override 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."); } catch (FileNotFoundException fnfe) { logger.debug("Error while mapfile creation: " + fnfe.getMessage()); } catch (IOException ioe) { logger.error(ioe, ioe); } finally { logger.debug("THREAD END"); } } /** * 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; } /** * Method which starts searching for meta information file and mapfile * generation. */ protected void generate() throws FileNotFoundException, IOException { File[] userDirs = getUserDirs(); List<String> layers = parseLayers(userDirs); logger.info("Found " + layers.size() + " layers for user mapfile."); writeMapfile(layers); } /** * 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( VelocityEngine.RUNTIME_LOG, FLYSUtils.getXPathString(FLYSUtils.XPATH_VELOCITY_LOGFILE)); engine.setProperty( "resource.loader", "file"); engine.setProperty( "file.resource.loader.path", FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPSERVER_TEMPLATE_PATH)); engine.init(); } protected VelocityContext getVelocityContext() { VelocityContext context = new VelocityContext(); try { context.put("MAPSERVERURL", FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPSERVER_URL)); context.put("SHAPEFILEPATH", getShapefileBaseDir().getCanonicalPath()); context.put("CONFIGDIR", Config.getConfigDirectory().getCanonicalPath()); } catch (FileNotFoundException fnfe) { // this is bad } catch (IOException ioe) { // this is also bad } return context; } /** * Returns a template specified by <i>model</i>. * * @param model The name of the template. * @return a template. */ 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; } /** * Returns the mapfile template. * * @return the mapfile template. * @throws Exception if an error occured while reading the configuration. */ protected Template getMapfileTemplate() throws Exception { String mapfileName = FLYSUtils.getXPathString( FLYSUtils.XPATH_MAPFILE_TEMPLATE); return getTemplateByName(mapfileName); } /** * 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_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 file used for Mapserver's mapfile which represents the * floodmap. * * @param flys The FLYSArtifact that owns <i>wms</i>. * @param wms The WMSLayerFacet that contains information for the layer. */ public void createUeskLayer( FLYSArtifact flys, WSPLGENLayerFacet wms, String style, CallContext context ) throws FileNotFoundException, IOException { logger.debug("createUeskLayer"); LayerInfo layerinfo = new LayerInfo(); layerinfo.setName(MS_WSPLGEN_PREFIX + flys.identifier()); layerinfo.setType("POLYGON"); layerinfo.setDirectory(flys.identifier()); layerinfo.setData(WSPLGEN_RESULT_SHAPE); layerinfo.setTitle(Resources.getMsg(Resources.getLocale(context.getMeta()), "floodmap.uesk", "Floodmap")); layerinfo.setStyle(style); layerinfo.setSrid(wms.getSrid()); String name = MS_LAYER_PREFIX + wms.getName(); Template template = getTemplateByName(WSPLGEN_LAYER_TEMPLATE); if (template == null) { logger.warn("Template '" + WSPLGEN_LAYER_TEMPLATE + "' found."); return; } try { File dir = new File(getShapefileBaseDir(), flys.identifier()); writeLayer(layerinfo, dir, name, template); } catch (FileNotFoundException fnfe) { logger.error(fnfe, fnfe); logger.warn("Unable to write layer: " + name); } } /** * Creates a layer file used for Mapserver's mapfile which represents the * user defined barriers. * * @param flys The FLYSArtifact that owns <i>wms</i>. * @param wms The WMSLayerFacet that contains information for the layer. */ public void createBarriersLayer(FLYSArtifact flys, WMSLayerFacet wms) throws FileNotFoundException, IOException { logger.debug("createBarriersLayer"); //String uuid = flys.identifier(); //File dir = new File(getShapefileBaseDir(), uuid); createBarriersLineLayer(flys, wms); createBarriersPolygonLayer(flys, wms); } protected void createBarriersLineLayer( FLYSArtifact flys, WMSLayerFacet wms ) throws FileNotFoundException, IOException { String uuid = flys.identifier(); String group = MS_BARRIERS_PREFIX + uuid; String groupTitle = "I18N_BARRIERS_TITLE"; File dir = new File(getShapefileBaseDir(), uuid); File test = new File(dir, WSPLGEN_LINES_SHAPE); if (!test.exists() || !test.canRead()) { logger.debug("No barrier line layer existing."); return; } LayerInfo lineInfo = new LayerInfo(); lineInfo.setName(MS_LINE_PREFIX + uuid); lineInfo.setType("LINE"); lineInfo.setDirectory(uuid); lineInfo.setData(WSPLGEN_LINES_SHAPE); lineInfo.setTitle("I18N_LINE_SHAPE"); lineInfo.setGroup(group); lineInfo.setGroupTitle(groupTitle); lineInfo.setSrid(wms.getSrid()); String nameLines = MS_LAYER_PREFIX + wms.getName() + "-lines"; Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE); if (tpl == null) { logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found."); return; } try { writeLayer(lineInfo, dir, nameLines, tpl); } catch (FileNotFoundException fnfe) { logger.error(fnfe, fnfe); logger.warn("Unable to write layer: " + nameLines); } } protected void createBarriersPolygonLayer( FLYSArtifact flys, WMSLayerFacet wms ) throws FileNotFoundException, IOException { String uuid = flys.identifier(); String group = uuid + MS_BARRIERS_PREFIX; String groupTitle = "I18N_BARRIERS_TITLE"; File dir = new File(getShapefileBaseDir(), uuid); File test = new File(dir, WSPLGEN_POLYGONS_SHAPE); if (!test.exists() || !test.canRead()) { logger.debug("No barrier line layer existing."); return; } LayerInfo polygonInfo = new LayerInfo(); polygonInfo.setName(MS_POLYGONS_PREFIX + uuid); polygonInfo.setType("POLYGON"); polygonInfo.setDirectory(uuid); polygonInfo.setData(WSPLGEN_POLYGONS_SHAPE); polygonInfo.setTitle("I18N_POLYGON_SHAPE"); polygonInfo.setGroup(group); polygonInfo.setGroupTitle(groupTitle); polygonInfo.setSrid(wms.getSrid()); String namePolygons = MS_LAYER_PREFIX + wms.getName() + "-polygons"; Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE); if (tpl == null) { logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found."); return; } try { writeLayer(polygonInfo, dir, namePolygons, tpl); } catch (FileNotFoundException fnfe) { logger.error(fnfe, fnfe); logger.warn("Unable to write layer: " + namePolygons); } } /** * Creates a layer file used for Mapserver's mapfile which represents the * shape files uploaded by the user. * * @param flys The FLYSArtifact that owns <i>wms</i>. * @param wms The WMSLayerFacet that contains information for the layer. */ public void createUserShapeLayer(FLYSArtifact flys, WMSLayerFacet wms) throws FileNotFoundException, IOException { logger.debug("createUserShapeLayer"); String uuid = flys.identifier(); File dir = new File(getShapefileBaseDir(), uuid); File test = new File(dir, WSPLGEN_USER_SHAPE); if (!test.exists() || !test.canRead()) { logger.debug("No user layer existing."); return; } File userShape = new File(dir, WSPLGEN_USER_SHAPE); ShpFiles sf = new ShpFiles(userShape); ShapefileReader sfr = new ShapefileReader(sf, true, false, null); ShapefileHeader sfh = sfr.getHeader(); String group = uuid + MS_USERSHAPE_PREFIX; String groupTitle = "I18N_USER_SHAPE_TITLE"; LayerInfo info = new LayerInfo(); info.setName(MS_USERSHAPE_PREFIX + uuid); if (sfh.getShapeType().isLineType()) { info.setType("LINE"); } else if (sfh.getShapeType().isPolygonType()) { info.setType("POLYGON"); } else { return; } info.setDirectory(uuid); info.setData(WSPLGEN_USER_SHAPE); info.setTitle("I18N_USER_SHAPE"); info.setGroup(group); info.setGroupTitle(groupTitle); info.setSrid(wms.getSrid()); String nameUser = MS_LAYER_PREFIX + wms.getName(); Template tpl = getTemplateByName(SHP_LAYER_TEMPLATE); if (tpl == null) { logger.warn("Template '" + SHP_LAYER_TEMPLATE + "' found."); return; } try { writeLayer(info, dir, nameUser, tpl); } catch (FileNotFoundException fnfe) { logger.error(fnfe, fnfe); logger.warn("Unable to write layer: " + nameUser); } } /** * Creates a layer file used for Mapserver's mapfile which represents * geometries from database. * * @param flys The FLYSArtifact that owns <i>wms</i>. * @param wms The WMSLayerFacet that contains information for the layer. */ public void createDatabaseLayer( FLYSArtifact flys, WMSDBLayerFacet wms, String style ) throws FileNotFoundException, IOException { logger.debug("createDatabaseLayer"); LayerInfo layerinfo = new LayerInfo(); layerinfo.setName(wms.getName() + "-" + flys.identifier()); layerinfo.setType(wms.getGeometryType()); layerinfo.setFilter(wms.getFilter()); layerinfo.setData(wms.getData()); layerinfo.setTitle(wms.getDescription()); layerinfo.setStyle(style); if(wms.getExtent() != null) { layerinfo.setExtent(GeometryUtils.jtsBoundsToOLBounds(wms.getExtent())); } layerinfo.setConnection(wms.getConnection()); layerinfo.setConnectionType(wms.getConnectionType()); layerinfo.setLabelItem(wms.getLabelItem()); layerinfo.setSrid(wms.getSrid()); String name = MS_LAYER_PREFIX + wms.getName(); Template template = getTemplateByName(DB_LAYER_TEMPLATE); if (template == null) { logger.warn("Template '" + DB_LAYER_TEMPLATE + "' found."); return; } try { File dir = new File(getShapefileBaseDir(), flys.identifier()); writeLayer(layerinfo, dir, name, template); } catch (FileNotFoundException fnfe) { logger.error(fnfe, fnfe); logger.warn("Unable to write layer: " + name); } } /** * 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. */ protected void writeLayer( LayerInfo layerinfo, File dir, String filename, Template tpl ) throws FileNotFoundException { if (logger.isDebugEnabled()) { logger.debug("Write layer for:"); logger.debug(" directory: " + dir.getName()); logger.debug(" name: " + filename); } File layer = new File(dir, filename); Writer writer = null; try { writer = new FileWriter(layer); 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. */ protected void writeMapfile(List<String> layers) { String tmpMapName = "mapfile" + new Date().getTime(); File mapfile = new File( FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPFILE_PATH)); 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 = 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(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 :