view gnv-artifacts/src/main/java/de/intevation/gnv/utils/MetaWriter.java @ 1030:c07d9f9a738c

Removed bugs that existed in the caching mechanism (issue264, issue268). gnv-artifacts/trunk@1067 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 06 May 2010 08:32:56 +0000
parents dfd02f8d3602
children 04967dc9c83f
line wrap: on
line source
package de.intevation.gnv.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import de.intevation.artifactdatabase.XMLUtils;
import de.intevation.artifacts.ArtifactNamespaceContext;
import de.intevation.artifacts.CallContext;
import de.intevation.gnv.artifacts.context.GNVArtifactContext;
import de.intevation.gnv.wms.LayerInfo;

/**
 * This class provides some methods to create files storing meta information
 * about wms layers and a map service which serves these layers.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class MetaWriter {

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

    public static final String NODE_MAPSERVER = "mapserver";
    public static final String NODE_SERVER    = "server";
    public static final String NODE_MAP       = "map";
    public static final String NODE_TTL       = "ttl";

    public static final String META_FILE_NAME = "meta.xml";
    public static final String ISOLINES_NAME  = "isolines.shp";
    public static final String POLYGON_NAME   = "polygons.shp";


    public static final String CONTEXT_LAYER_TITLE = "wms.title";

    /**
     * Constructor.
     */
    private MetaWriter() {
    }

    /**
     * Writes a meta information file for product type 'Layer'.
     *
     * @param context CallContext object.
     * @param meta the document where the information should be placed in.
     * @return the meta document.
     */
    public static Node writeLayerMeta(CallContext context, Document meta){
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            meta,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);
        Element root = creator.create("meta");
        meta.appendChild(root);

        writeAbstractMeta(context, meta, root);
        return root;
    }


    /**
     * Writes a meta information file for product type 'Horizontalschnitt'.
     *
     * @param context The CallContext object.
     * @param uuid The UUID of the current artifact.
     * @param path The destination of the meta file.
     * @param paramType The parameter type.
     * @return the meta document.
     */
    public static Document writeHorizontalcrosssectionMeta(
        CallContext context,
        String      uuid,
        String      path,
        String      paramType)
    {
        Document meta = XMLUtils.newDocument();
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            meta,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        Element root = creator.create("meta");
        meta.appendChild(root);

        writeAbstractMeta(context, meta, root);
        writePolygonMeta(context, meta, root, uuid, paramType);
        writeIsolineMeta(context, meta, root, uuid, paramType);

        boolean success = writeMetaFile(path, meta);

        if (success){
            return meta;
        }else{
            return null;
        }
    }

    /**
     * Method to write the <i>meta</i> document down to a file.
     *
     * @param path The destination of the file.
     * @param meta The xml document storing the meta information.
     */
    public static boolean writeMetaFile(String path, Document meta) {
        try {
            File metaFile = new File(path, META_FILE_NAME);

            if (metaFile.exists()) {
                logger.info("Delete old meta information file.");
                metaFile.delete();
            }

            if (!metaFile.createNewFile() || !metaFile.canWrite()) {
                logger.error("Error while writing meta file: "+metaFile.toString());
                return false;
            }

            OutputStream out = null;
            boolean success = false;
            try {
                out = new FileOutputStream(metaFile);
                success = XMLUtils.toStream(meta, out);
            }
            finally {
                if (out != null) {
                    try { out.close(); }
                    catch (IOException ioe) {}
                }
            }

            if (!success && metaFile.exists()) {
                metaFile.delete();
            }

            return success;
        }
        catch (FileNotFoundException fnfe) {
            logger.error(fnfe);
            return false;
        }
        catch (IOException ioe) {
            logger.error(ioe, ioe);
            return false;
        }
    }


    /**
     * Append meta information about the mapservice itself.
     *
     * @param callContext The CallContext object.
     * @param document The meta information document.
     * @param meta The element where the new information need to be appended to.
     */
    public static void writeAbstractMeta(
        CallContext callContext,
        Document    document,
        Element     meta
    ) {
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        GNVArtifactContext context =
            (GNVArtifactContext) callContext.globalContext();

        String server = (String)
            context.get(GNVArtifactContext.MAPSERVER_SERVER_PATH_KEY);

        String map = (String)
            context.get(GNVArtifactContext.MAPSERVER_MAP_PATH_KEY);

        if (logger.isDebugEnabled()) {
            logger.debug("MAPSERVER PATH: " + server);
            logger.debug("MAP PATH: " + map);
        }

        Element mapserver  = creator.create(NODE_MAPSERVER);
        Element serverPath = creator.create(NODE_SERVER);
        Element mapPath    = creator.create(NODE_MAP);

        mapPath.setTextContent(map);
        serverPath.setTextContent(server);

        mapserver.appendChild(serverPath);
        mapserver.appendChild(mapPath);
        meta.appendChild(mapserver);
    }

    /**
     * Append layer information to the meta document.
     *
     * @param callContext The CallContext object.
     * @param document The meta document.
     * @param root The element where the new information need to be appended to.
     * @param uuid The UUID of the current artifact.
     * @param paramType The parameter type (e.g. salinity).
     * @param layerType The layer type.
     * @param shapefileName the name of the Shapefile
     * @param shapefileName the Title of the Layer
     */
    public static void writeLayerMeta(
        CallContext callContext,
        Document    document,
        Node        root,
        String      uuid,
        String      paramType,
        String      layerType,
        String      shapefileName,
        String      layerTitle
    ) {
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        Long time  = callContext.getTimeToLive();
        time       = time != null ? time + new Date().getTime() : null;
        String ttl = time != null ? time.toString() : null;

        logger.debug("Artifacts time to live: " + ttl);

        Element layer      = creator.create(LayerInfo.LAYER);
        Element model      = creator.create(LayerInfo.LAYER_MODEL);
        Element name       = creator.create(LayerInfo.LAYER_NAME);
        Element title  = creator.create(LayerInfo.LAYER_TITLE);
        Element type       = creator.create(LayerInfo.LAYER_TYPE);
        Element status     = creator.create(LayerInfo.LAYER_STATUS);
        Element data       = creator.create(LayerInfo.LAYER_DATA);
        Element timeToLive = creator.create(NODE_TTL);

        model.setTextContent(paramType);
        name.setTextContent(uuid);
        type.setTextContent(layerType);
        status.setTextContent("OFF");
        data.setTextContent(shapefileName);
        timeToLive.setTextContent(ttl);

        title.setTextContent(layerTitle);

        layer.appendChild(model);
        layer.appendChild(name);
        layer.appendChild(title);
        layer.appendChild(type);
        layer.appendChild(status);
        layer.appendChild(data);
        layer.appendChild(timeToLive);

        root.appendChild(layer);
    }


    /**
     * Append polygon layer information to meta document.
     *
     * @param context
     * @param document The meta document.
     * @param meta The element where the new information need to be appended to.
     * @param uuid The UUID of the current artifact.
     * @param paramType The parameter type (e.g. salinity).
     */
    public static void writePolygonMeta(
        CallContext context,
        Document    document,
        Element     meta,
        String      uuid,
        String      paramType
    ) {
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        Long time  = context.getTimeToLive();
        time       = time != null ? time + new Date().getTime() : null;
        String ttl = time != null ? time.toString() : null;

        logger.debug("Artifacts time to live: " + ttl);

        Element layer  = creator.create(LayerInfo.LAYER);
        Element model  = creator.create(LayerInfo.LAYER_MODEL);
        Element name   = creator.create(LayerInfo.LAYER_NAME);
        Element title  = creator.create(LayerInfo.LAYER_TITLE);
        Element type   = creator.create(LayerInfo.LAYER_TYPE);
        Element status = creator.create(LayerInfo.LAYER_STATUS);
        Element data   = creator.create(LayerInfo.LAYER_DATA);
        Element timeToLive = creator.create(NODE_TTL);

        model.setTextContent(paramType);
        name.setTextContent(uuid);
        title.setTextContent(
            (String) context.getContextValue(CONTEXT_LAYER_TITLE));
        type.setTextContent("POLYGON");
        status.setTextContent("OFF");
        data.setTextContent(POLYGON_NAME);
        timeToLive.setTextContent(ttl);

        layer.appendChild(model);
        layer.appendChild(name);
        layer.appendChild(title);
        layer.appendChild(type);
        layer.appendChild(status);
        layer.appendChild(data);
        layer.appendChild(timeToLive);

        meta.appendChild(layer);
    }


    /**
     * Append isoline layer information to meta document.
     *
     * @param context
     * @param document The meta document.
     * @param meta The element where the new information need to be appended to.
     * @param uuid The UUID of the current artifact.
     * @param paramType The parameter type (e.g. salinity).
     */
    public static void writeIsolineMeta(
        CallContext context,
        Document    document,
        Element     meta,
        String      uuid,
        String      paramType
    ) {
        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
            document,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        Long time  = context.getTimeToLive();
        time       = time != null ? time + new Date().getTime() : null;
        String ttl = time != null ? time.toString() : null;

        logger.debug("Artifacts time to live: " + ttl);

        Element layer  = creator.create(LayerInfo.LAYER);
        Element model  = creator.create(LayerInfo.LAYER_MODEL);
        Element name   = creator.create(LayerInfo.LAYER_NAME);
        Element title  = creator.create(LayerInfo.LAYER_TITLE);
        Element type   = creator.create(LayerInfo.LAYER_TYPE);
        Element status = creator.create(LayerInfo.LAYER_STATUS);
        Element data   = creator.create(LayerInfo.LAYER_DATA);
        Element timeToLive = creator.create(NODE_TTL);

        model.setTextContent(paramType+"_isolines");
        name.setTextContent(uuid);
        title.setTextContent(
            (String) context.getContextValue(CONTEXT_LAYER_TITLE));
        type.setTextContent("LINE");
        status.setTextContent("OFF");
        data.setTextContent(ISOLINES_NAME);
        timeToLive.setTextContent(ttl);

        layer.appendChild(model);
        layer.appendChild(name);
        layer.appendChild(title);
        layer.appendChild(type);
        layer.appendChild(status);
        layer.appendChild(data);
        layer.appendChild(timeToLive);

        meta.appendChild(layer);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org