/* (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.wps;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import org.geoserver.script.ScriptHook;
import org.geoserver.script.ScriptPlugin;
import org.geotools.data.Parameter;
import org.geotools.util.SimpleInternationalString;
import org.opengis.util.InternationalString;
/**
* Handles wps / process requests.
* <p>
* This class is a bridge between the GeoTools/GeoServer process api and the api for process
* scripts.
* </p>
* <p>
* All the methods on this interface take a {@link ScriptEngine} instance that is already "loaded"
* with the current version of the process script.
* </p>
* <p>
* Instances of this class must be thread safe.
* </p>
* @author Justin Deoliveira, OpenGeo
*
*/
public class WpsHook extends ScriptHook {
public WpsHook(ScriptPlugin plugin) {
super(plugin);
}
/**
* The title of the process.
* <p>
* Subclasses may override this method, the default behavior is to look for a defined object
* named "title" in the script engine and return its string representation.
* </p>
*/
public String getTitle(ScriptEngine engine) throws ScriptException {
return lookup(engine, "title", Object.class, true).toString();
}
/**
* The description of the process.
* <p>
* Subclasses may override this method, the default behavior is to look for a defined object
* named "description" in the script engine and return its string representation. If no such
* object exists {@link #getTitle(ScriptEngine)} is returned.
* </p>
*/
public String getDescription(ScriptEngine engine) throws ScriptException{
Object d = engine.get("description");
if (d != null) {
return d.toString();
}
return getTitle(engine);
}
/**
* The version of the process.
* <p>
* Subclasses should override this method, the default behavior is simply to return "1.0.0".
* </p>
*/
public String getVersion(ScriptEngine engine) throws ScriptException{
return "1.0.0";
}
/**
* The process inputs.
* <p>
* Subclasses may override this method, the default behavior is to look for a defined object
* named "inputs" in the script engine and assume it is a map of the following structure:
* <pre>
* {
* 'arg1': {
* 'title', ...
* 'type': ...,
* },
* 'arg2: {
* 'title', ...
* 'type': ...,
* }
* }
* </pre>
* </p>
*/
public Map<String, Parameter<?>> getInputs(ScriptEngine engine) throws ScriptException {
return params(lookup(engine, "inputs", Map.class, true));
}
/**
* The process outputs.
* <p>
* Subclasses may override this method, the default behavior is to look for a defined object
* named "outputs" in the script engine and assume it is a map of the following structure:
* <pre>
* {
* 'result1': {
* 'title', ...
* 'type': ...,
* },
* 'result2: {
* 'title', ...
* 'type': ...,
* }
* }
* </pre>
* </p>
*/
public Map<String, Parameter<?>> getOutputs(ScriptEngine engine) throws ScriptException {
return params(lookup(engine, "outputs", Map.class, true));
}
/**
* Helper method to create parameter map.
*/
protected Map<String, Parameter<?>> params(Map map) {
Map params = new HashMap();
for (Map.Entry e : (Set<Map.Entry>) map.entrySet()) {
params.put(e.getKey(), param((String)e.getKey(), e.getValue()));
}
return params;
}
/**
* Helper method to morph input into a Parameter instance, will throw exception if can't
* convert.
*/
protected Parameter<?> param(String name, Object o) {
if (o instanceof Parameter) {
return (Parameter) o;
}
if (o instanceof Map) {
Map m = (Map) o;
InternationalString title = null, desc = null;
boolean required = true;
int min = 1, max = 1;
Object sample = null;
if (m.containsKey("title")) {
title = new SimpleInternationalString((String)m.get("title"));
}
if (m.containsKey("description")) {
desc = new SimpleInternationalString((String)m.get("description"));
}
else {
desc = title;
}
if (m.containsKey("required")) {
required = (Boolean) m.get("required");
}
if (m.containsKey("min")) {
min = (Integer) m.get("min");
}
if (m.containsKey("max")) {
max = (Integer) m.get("max");
}
sample = m.get("default");
return new Parameter(
name, (Class)m.get("type"), title, desc, required, min, max, sample, null);
}
throw new IllegalArgumentException("Unable to turn " + o + " into " + Parameter.class.getName());
}
/**
* Executes the process.
*/
public Map<String, Object> run(Map<String, Object> input, ScriptEngine engine)
throws ScriptException {
return (Map<String, Object>) invoke(engine, "run", input);
}
}