Package org.geoserver.wps

Source Code of org.geoserver.wps.DataTransformer

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/

package org.geoserver.wps;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.opengis.wps10.ComplexDataType;
import net.opengis.wps10.DataType;
import net.opengis.wps10.InputReferenceType;
import net.opengis.wps10.InputType;
import net.opengis.wps10.LiteralDataType;

import org.geoserver.wps.transmute.ComplexTransmuter;
import org.geoserver.wps.transmute.DoubleTransmuter;
import org.geoserver.wps.transmute.GML2LineStringTransmuter;
import org.geoserver.wps.transmute.GML2LinearRingTransmuter;
import org.geoserver.wps.transmute.GML2MultiLineStringTransmuter;
import org.geoserver.wps.transmute.GML2MultiPointTransmuter;
import org.geoserver.wps.transmute.GML2MultiPolygonTransmuter;
import org.geoserver.wps.transmute.GML2PointTransmuter;
import org.geoserver.wps.transmute.GML2PolygonTransmuter;
import org.geoserver.wps.transmute.LiteralTransmuter;
import org.geoserver.wps.transmute.Transmuter;
import org.geotools.data.Parameter;
import org.geotools.process.ProcessFactory;
import org.opengis.feature.type.Name;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;

/**
* Class for parsing and encoding inputs and results to processes
*
* @author Lucas Reed, Refractions Research Inc
*/
public class DataTransformer {
    private List<Transmuter>            transmuters        = new ArrayList<Transmuter>();
    private Map<Class<?>, Transmuter>   defaultTransmuters = new HashMap<Class<?>, Transmuter>();
    private Map<String,   Parameter<?>> inputParameters;
    private String                      urlBase            = null;

    /**
     * Constructor takes server base URL
     *
     * @param urlBase
     */
    public DataTransformer(String urlBase) {
        this.urlBase = urlBase;

        /* In order to allow true multiple output formats the container for the transmuters needs to
         * be changed to allow many-to-many Class <-> Transmuter mappings.
         */

        // Map Java types to transmuters
        this.defaultTransmuters.put(Double.class,          new DoubleTransmuter());
        this.defaultTransmuters.put(MultiPolygon.class,    new GML2MultiPolygonTransmuter());
        this.defaultTransmuters.put(Polygon.class,         new GML2PolygonTransmuter());
        this.defaultTransmuters.put(Geometry.class,        new GML2PolygonTransmuter());
        this.defaultTransmuters.put(MultiPoint.class,      new GML2MultiPointTransmuter());
        this.defaultTransmuters.put(Point.class,           new GML2PointTransmuter());
        this.defaultTransmuters.put(LinearRing.class,      new GML2LinearRingTransmuter());
        this.defaultTransmuters.put(LineString.class,      new GML2LineStringTransmuter());
        this.defaultTransmuters.put(MultiLineString.class, new GML2MultiLineStringTransmuter());

        // Add all default transmuters to master transmuters list
        this.transmuters.addAll(this.defaultTransmuters.values());
    }

    /**
     * Returns Map of parsed inputs ready for execution
     *
     * @param inputs
     * @param parameters
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> decodeInputs(final List<InputType> inputs,
        final Map<String, Parameter<?>> parameters) {
        Map<String, Object> inputMap = new HashMap<String, Object>();

        this.inputParameters = parameters;

        for(InputType input : inputs) {
            String identifier = input.getIdentifier().getValue();

            Object decoded = null;

            if (null != input.getData()) {
                // Decode inline data
                decoded = this.decodeInputData(input);
            }

            if (null != input.getReference()) {
                // Fetch external resource
                decoded = this.decodeReferenceData(identifier, input.getReference());
            }

            if (inputMap.containsKey(identifier)) {
                if (inputMap.get(identifier) instanceof List) {
                    List<Object> list = (List<Object>)inputMap.get(identifier);
                    list.add(decoded);
                } else {
                    List<Object> list = new ArrayList<Object>();
                    list.add(inputMap.get(identifier));
                    inputMap.put(identifier, list);
                }
            } else {
                inputMap.put(identifier, decoded);
            }
        }

        return inputMap;
    }

    /**
     * Fetches and decodes external data references
     *
     * @param identifier
     * @param reference
     * @return
     */
    private Object decodeReferenceData(final String identifier, final InputReferenceType reference) {
        Object            data       = null;
        URL               url        = null;
        Parameter<?>      param      = this.inputParameters.get(identifier);
        ComplexTransmuter transmuter = (ComplexTransmuter)this.getDefaultTransmuter(param.type);

        try {
            url = new URL(reference.getHref());
        } catch(MalformedURLException e) {
            throw new WPSException("NoApplicableCode", "Malformed parameter URL.");
        }

        try {
            data = transmuter.decode(url.openStream());
        } catch(IOException e) {
            throw new WPSException("NoApplicableCode", "IOException.");
        }

        return data;
    }

    private Object decodeInputData(final InputType input) {
        Object   output = null;
        DataType data   = input.getData();

        String       parameterName = input.getIdentifier().getValue();
        Parameter<?> parameter     = this.inputParameters.get(parameterName);

        try {
            if (null != data.getLiteralData()) {
                output = this.decodeLiteralData(data.getLiteralData(), parameter.type);
            }

            if (null != data.getComplexData()) {
                output = this.decodeComplexData(data.getComplexData(), parameter.type);
            }
        } catch(Exception e) {
            throw new WPSException("InvalidParameterValue", parameterName);
        }

        if (null != data.getBoundingBoxData()) {
            // Parse bounding box data
            throw new WPSException("NoApplicableCode", "Unimplemented");
        }

        return output;
    }

    private Object decodeComplexData(final ComplexDataType input, final Class<?> type) {
        Object data = input.getData().get(0);

        return data;
    }

    private Object decodeLiteralData(final LiteralDataType input, final Class<?> type) {
        Object data = null;

        LiteralTransmuter transmuter = (LiteralTransmuter)this.getDefaultTransmuter(type);

        data = transmuter.decode(input.getValue());

        return data;
    }

    /**
     * Attempt to find ComplexTransmuter for given Java type and schema
     *
     * @param type
     * @param schema
     * @return
     */
    public ComplexTransmuter getComplexTransmuter(final Class<?> type, final String schema) {
        for(Transmuter transmuter : this.transmuters) {
            if (false == transmuter instanceof ComplexTransmuter) {
                continue;
            }

            if (false == ((ComplexTransmuter)transmuter).getSchema(this.urlBase)
                .equalsIgnoreCase(schema)) {
                continue;
            }

            if (type != transmuter.getType()) {
                continue;
            }

            return (ComplexTransmuter)transmuter;
        }

        throw new WPSException("NoApplicableCode", "Could not find ComplexTransmuter for '" +
            schema + "'.");
    }

    /**
     * Return default a transmuter for a given Java type
     *
     * @param type
     * @return
     */
    public Transmuter getDefaultTransmuter(final Class<?> type) {
        Transmuter transmuter = this.defaultTransmuters.get(type);

        if (null == transmuter) {
            throw new WPSException("NoApplicableCode", "No default transmuter registered for type "
                + type.toString() + "'.");
        }

        return transmuter;
    }

    /**
     * Tests if all inputs and outputs of a Process are transmutable
     *
     * @param pf
     * @return
     */
    public boolean isTransmutable(ProcessFactory pf, Name name) {
        for(Parameter<?> param : pf.getParameterInfo(name).values()) {
            try {
                this.getDefaultTransmuter(param.type);
            } catch(Exception e) {
                return false;
            }
        }

        for(Parameter<?> param : pf.getResultInfo(name, null).values()) {
            try {
                this.getDefaultTransmuter(param.type);
            } catch(Exception e) {
                return false;
            }
        }

        return true;
    }
}
TOP

Related Classes of org.geoserver.wps.DataTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.