/* (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.script.groovy;
import java.util.Map;
import java.util.HashMap;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import org.geoserver.script.ScriptPlugin;
import org.geoserver.script.wps.WpsHook;
import org.geotools.data.Parameter;
/**
* The GroovyWpsHook converts GeoScript input and output types into
* GeoTools types, converts input parameters from GeoTools to GeoScript values,
* and then converts results from GeoScript to GeoTools values.
*/
public class GroovyWpsHook extends WpsHook {
public GroovyWpsHook(ScriptPlugin plugin) {
super(plugin);
}
@Override
public Map<String, Object> run(Map<String, Object> input,
ScriptEngine engine) throws ScriptException {
// Convert GeoTools input values into GeoScript values
Map<String, Object> newInput = new HashMap<String,Object>();
for(Map.Entry<String,Object> entry : input.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
Object newValue = convertGeoToolsToGeoScript(value);
newInput.put(key, newValue);
}
// The Script expects GeoScript values
Map<String, Object> results = super.run(newInput, engine);
// Convert GeoScript result values into GeoTools values
Map<String,Object> newResults = new HashMap<String,Object>();
try {
for(Map.Entry<String,Object> entry : results.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
Object newValue = convertGeoScriptToGeoTools(value);
newResults.put(key, newValue);
}
} catch(Exception ex) {
throw new ScriptException(ex);
}
return newResults;
}
@Override
public Map<String, Parameter<?>> getInputs(ScriptEngine engine)
throws ScriptException {
Map<String, Parameter<?>> inputs = super.getInputs(engine);
// Convert all input Parameters from GeoScript types to GeoTools Types
for(Map.Entry<String,Parameter<?>> entry : inputs.entrySet()) {
String key = entry.getKey();
Parameter param = entry.getValue();
Class clazz = geoscript.process.Process.convertGeoScriptToGeoToolsClass(param.getType());
param = changeParamType(param, clazz);
inputs.put(key, param);
}
return inputs;
}
@Override
public Map<String, Parameter<?>> getOutputs(ScriptEngine engine)
throws ScriptException {
Map<String, Parameter<?>> outputs = super.getOutputs(engine);
// Convert all output Parameters from GeoScript types to GeoTools Types
for(Map.Entry<String,Parameter<?>> entry : outputs.entrySet()) {
String key = entry.getKey();
Parameter param = entry.getValue();
Class clazz = geoscript.process.Process.convertGeoScriptToGeoToolsClass(param.getType());
param = changeParamType(param, clazz);
outputs.put(key, param);
}
return outputs;
}
/**
* Convert a GeoTools object to a GeoScript object.
* @param value The Object
* @return A GeoScript object if it is possible
*/
protected Object convertGeoToolsToGeoScript(Object value) {
if (value instanceof com.vividsolutions.jts.geom.Geometry) {
return geoscript.geom.Geometry.wrap((com.vividsolutions.jts.geom.Geometry) value);
}
else if (value instanceof org.geotools.geometry.jts.ReferencedEnvelope) {
return new geoscript.geom.Bounds((org.geotools.geometry.jts.ReferencedEnvelope) value);
}
else if (value instanceof org.geotools.feature.FeatureCollection) {
return new geoscript.layer.Layer((org.geotools.feature.FeatureCollection) value);
}
else {
return value;
}
}
/**
* Convert a GeoScript object to a GeoTools object.
* @param value The Object
* @return A GeoTools object if it is possible
*/
protected Object convertGeoScriptToGeoTools(Object value) throws Exception {
if (value instanceof geoscript.geom.Geometry) {
// com.vividsolutions.jts.geom.Geometry
return ((geoscript.geom.Geometry) value).getG();
}
else if (value instanceof geoscript.geom.Bounds) {
// org.geotools.geometry.jts.ReferencedEnvelope
return ((geoscript.geom.Bounds) value).getEnv();
}
else if (value instanceof geoscript.layer.Layer) {
// org.geotools.data.FeatureSource
return ((geoscript.layer.Layer) value).getFs().getFeatures();
}
else if (value instanceof geoscript.layer.Cursor) {
// org.geotools.feature.FeatureCollection
return ((geoscript.layer.Cursor) value).getCol();
}
else {
return value;
}
}
/**
* Create a new Parameter with all of the values of the given Parameter except for it's Type
* @param param A Parameter
* @param type The new Class type
* @return A new Parameter
*/
private Parameter changeParamType(Parameter param, Class type) {
return new Parameter(param.getName(), type, param.getTitle(),
param.getDescription(), param.isRequired(), param.getMinOccurs(),
param.getMaxOccurs(), param.getDefaultValue(), null);
}
}