view flys-artifacts/src/main/java/de/intevation/flys/utils/ArtifactMapfileGenerator.java @ 5779:ebec12def170

Datacage: Add a pool of builders to make it multi threadable. XML DOM is not thread safe. Therefore the old implementation only allowed one thread to use the builder at a time. As the complexity of the configuration has increased over time this has become a bottleneck of the whole application because it took quiet some time to build a result. Furthermore the builder code path is visited very frequent. So many concurrent requests were piled up resulting in long waits for the users. To mitigate this problem a round robin pool of builders is used now. Each of the pooled builders has an independent copy of the XML template and can be run in parallel. The number of builders is determined by the system property 'flys.datacage.pool.size'. It defaults to 4.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sun, 21 Apr 2013 12:48:09 +0200
parents b55975761708
children
line wrap: on
line source
package de.intevation.flys.utils;

import de.intevation.artifacts.CallContext;
import de.intevation.flys.artifacts.FLYSArtifact;
import de.intevation.flys.artifacts.access.RiverAccess;
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.IOException;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.geotools.data.shapefile.ShpFiles;
import org.geotools.data.shapefile.shp.ShapefileHeader;
import org.geotools.data.shapefile.shp.ShapefileReader;

public class ArtifactMapfileGenerator extends MapfileGenerator {

    private static Logger logger = Logger.getLogger(ArtifactMapfileGenerator.class);

    @Override
    protected String getVelocityLogfile() {
        return FLYSUtils.getXPathString(FLYSUtils.XPATH_FLOODMAP_VELOCITY_LOGFILE);
    }

    @Override
    protected String getMapserverTemplatePath() {
        return FLYSUtils.getXPathString(FLYSUtils.XPATH_FLOODMAP_MAPSERVER_TEMPLATE_PATH);
    }

    @Override
    public String getMapserverUrl() {
        return FLYSUtils.getXPathString(FLYSUtils.XPATH_FLOODMAP_MAPSERVER_URL);
    }

    /**
     * Method which starts searching for meta information file and mapfile
     * generation.
     */
    @Override
    public void generate() throws IOException
    {
        File[] userDirs = getUserDirs();
        List<String> layers = parseLayers(userDirs);
        logger.info("Found " + layers.size() + " layers for user mapfile.");

        writeMapfile(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);
        RiverAccess access = new RiverAccess(flys);
        String river = access.getRiver();
        layerinfo.setSrid(FLYSUtils.getRiverDGMSrid(river));

        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, new File(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, new File(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, new File(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, new File(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, new File(dir, name), template);
            }
            catch (FileNotFoundException fnfe) {
                logger.error(fnfe, fnfe);
                logger.warn("Unable to write layer: " + name);
            }
        }

        @Override
        protected String getMapfilePath() {
            return FLYSUtils.getXPathString(FLYSUtils.XPATH_FLOODMAP_MAPFILE_PATH);
        }

        @Override
        protected String getMapfileTemplate() {
            return FLYSUtils.getXPathString(FLYSUtils.XPATH_FLOODMAP_MAPFILE_TEMPLATE);
        }

}

http://dive4elements.wald.intevation.org