view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MetaDataService.java @ 974:30c85cb33a50

meta data service: made artifact optional and allow passing extra parameters. flys-artifacts/trunk@2400 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 25 Jul 2011 11:05:33 +0000
parents e456aca4eb7b
children a111f0984706
line wrap: on
line source
package de.intevation.flys.artifacts.services;

import java.sql.Connection;
import java.sql.SQLException;

import org.w3c.dom.Document;

import org.apache.log4j.Logger;

import java.util.Map;
import java.util.HashMap;

import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.CallMeta;
import de.intevation.artifacts.GlobalContext;
import de.intevation.artifacts.ArtifactDatabase;
import de.intevation.artifacts.ArtifactDatabaseException;

import de.intevation.artifactdatabase.DefaultService;

import de.intevation.artifacts.common.utils.XMLUtils;
import de.intevation.artifacts.common.utils.StringUtils;

import de.intevation.artifacts.common.ArtifactNamespaceContext;

import de.intevation.flys.artifacts.services.meta.Builder;
import de.intevation.flys.artifacts.services.meta.DataCage;

import de.intevation.flys.artifacts.FLYSArtifact;

import de.intevation.flys.backend.SessionHolder;

import org.hibernate.Session;

import org.hibernate.jdbc.Work;

public class MetaDataService
extends      DefaultService
{
    private static Logger log = Logger.getLogger(MetaDataService.class);

    // old service. To be removed
    public static final String XPATH_RIVER = "/art:river/text()";

    public static final String XPATH_UUID       = "/art:meta/art:uuid/@value";
    public static final String XPATH_OUTS       = "/art:meta/art:outs/@value";
    public static final String XPATH_PARAMETERS = "/art:meta/art:parameters/@value";
    public static final String XPATH_FILTERS    = "/art:meta/art:filters/@value";

    /** The global context key of the artifact database */
    public static final String ARTIFACT_DATA_BASE_KEY =
        "global.artifact.database";

    public MetaDataService() {
    }

    protected static Map<String, Object> extractParameters(Document data) {
        HashMap<String, Object> parameters = new HashMap<String, Object>();

        String river = XMLUtils.xpathString(
            data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE);

        if (river == null || (river = river.trim()).length() == 0) {
            river = "%"; // matches all rivers
        }

        parameters.put("river", river);

        return parameters;
    }

    /** The old service. To be removed. */
    protected Document oldService(Document data) {

        final Document result = XMLUtils.newDocument();

        final Builder builder = DataCage.getInstance().getBuilder();

        if (builder == null) {
            log.error("MetaDataService is not setup properly.");
            return result;
        }

        final Map<String, Object> parameters = extractParameters(data);

        Session session = SessionHolder.acquire();
        try {
            session.doWork(new Work() {
                @Override
                public void execute(Connection connection)
                throws SQLException
                {
                    log.debug("MetaDataService.execute");
                    builder.build(connection, result, parameters);
                }
            });
        }
        finally {
            session.close();
            SessionHolder.release();
        }

        return result;
    }

    protected static Map<String, Object> parameters(
        String              parameters,
        Map<String, Object> data
    ) {
        if (parameters != null) {
            String [] parts = parameters.split("\\s*;\\s*");
            for (String part: parts) {
                String [] kv = part.split("\\s*:\\s*");
                if (kv.length < 2 || (kv[0] = kv[0].trim()).length() == 0) {
                    continue;
                }
                String [] values = kv[1].split("\\s*,\\s*");
                data.put(kv[0], values.length == 1 ? values[0] : values);
            }
        }
        return data;
    }

    protected static Map<String, Object> filters(
        String              filters,
        Map<String, Object> data
    ) {
        if (filters != null) {
            for (String filter: filters.split("\\s*,\\*s")) {
                data.put(filter, "true");
            }
        }
        return data;
    }

    protected Document newService(
        String        uuid,
        String        outsString,
        String        parameters,
        String        filters,
        GlobalContext globalContext
    ) {
        Document result = XMLUtils.newDocument();

        FLYSArtifact flysArtifact;

        log.debug("uuid: " + uuid);
        log.debug("outs: " + outsString);
        log.debug("filters: " + filters);

        if (uuid != null && uuid.length() != 0) {
            if (!StringUtils.checkUUID(uuid)) {
                log.warn("'" + uuid + "' is not a UUID");
                return result;
            }

            Object dbObject =
                (ArtifactDatabase)globalContext.get(ARTIFACT_DATA_BASE_KEY);

            if (!(dbObject instanceof ArtifactDatabase)) {
                log.error("Cannot find artifact database");
                return result;
            }

            ArtifactDatabase db = (ArtifactDatabase)dbObject;

            Artifact artifact;

            try {
                artifact = db.getRawArtifact(uuid);
            }
            catch (ArtifactDatabaseException adbe) {
                log.warn("fetching artifact failed", adbe);
                return result;
            }

            if (!(artifact instanceof FLYSArtifact)) {
                log.warn("artifact is not a FLYS artifact.");
                return result;
            }

            flysArtifact = (FLYSArtifact)artifact;
        }
        else {
            flysArtifact = null;
        }

        Map<String, Object> data =
            filters(filters,
                parameters(parameters, 
                    new HashMap<String, Object>()));

        String [] outs = outsString.split("\\s*,\\s*");
        
        DataCage dc = DataCage.getInstance();

        dc.recommend(flysArtifact, outs, data, result);

        return result;
    }

    @Override
    public Document process(
        Document      data,
        GlobalContext globalContext,
        CallMeta      callMeta
    ) {
        log.debug("MetaDataService.process");

        String uuid = XMLUtils.xpathString(
            data, XPATH_UUID, ArtifactNamespaceContext.INSTANCE);

        String outs = XMLUtils.xpathString(
            data, XPATH_OUTS, ArtifactNamespaceContext.INSTANCE);

        String parameters = XMLUtils.xpathString(
            data, XPATH_PARAMETERS, ArtifactNamespaceContext.INSTANCE);

        String filters = XMLUtils.xpathString(
            data, XPATH_FILTERS, ArtifactNamespaceContext.INSTANCE);

        return outs != null
            ? newService(uuid, outs, parameters, filters, globalContext)
            : oldService(data);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org