/* Copyright (c) 2001 - 2013 OpenPlans - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.executor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.opengis.wps10.DocumentOutputDefinitionType;
import net.opengis.wps10.ExecuteType;
import net.opengis.wps10.InputType;
import net.opengis.wps10.OutputDefinitionType;
import net.opengis.wps10.ResponseDocumentType;
import net.opengis.wps10.ResponseFormType;
import org.eclipse.emf.common.util.EList;
import org.geoserver.ows.Ows11Util;
import org.geoserver.wps.WPSException;
import org.geoserver.wps.ppio.ProcessParameterIO;
import org.geoserver.wps.process.AbstractRawData;
import org.geoserver.wps.process.GeoServerProcessors;
import org.geotools.data.Parameter;
import org.geotools.process.ProcessFactory;
import org.opengis.feature.type.Name;
/**
* Centralizes some common request parsing activities
*
* @author Andrea Aime - GeoSolutions
*
*/
public class ExecuteRequest {
ExecuteType request;
public ExecuteRequest(ExecuteType request) {
this.request = request;
}
/**
* The wrapped WPS 1.0 request
*
* @return
*/
public ExecuteType getRequest() {
return request;
}
/**
* True if the request is asynchronous
*
* @return
*/
public boolean isAsynchronous() {
return request.getResponseForm() != null
&& request.getResponseForm().getResponseDocument() != null
&& request.getResponseForm().getResponseDocument().isStoreExecuteResponse();
}
/**
* Returns true if status update is requested
*
* @return
*/
public boolean isStatusEnabled() {
return isAsynchronous() && request.getResponseForm().getResponseDocument().isStatus();
}
/**
* Returns the process name according to the GeoTools API
*
* @return
*/
public Name getProcessName() {
return Ows11Util.name(request.getIdentifier());
}
/**
* Returns the process inputs according to the GeoTools API expectations
*
* @param request
* @return
*/
public LazyInputMap getProcessInputs(WPSExecutionManager manager) {
// get the input descriptors
Name processName = Ows11Util.name(request.getIdentifier());
ProcessFactory pf = GeoServerProcessors.createProcessFactory(processName);
if(pf == null) {
throw new WPSException("Unknown process " + processName);
}
final Map<String, Parameter<?>> parameters = pf.getParameterInfo(processName);
Map<String, InputProvider> providers = new HashMap<String, InputProvider>();
// see what output raw data we have that need the user chosen mime type to be
// sent back to the process as an input
Map<String, String> outputMimeParameters = AbstractRawData.getOutputMimeParameters(
processName, pf);
if (!outputMimeParameters.isEmpty()) {
Map<String, String> requestedRawDataMimeTypes = getRequestedRawDataMimeTypes(outputMimeParameters.keySet(), processName, pf);
for (Map.Entry<String, String> param : outputMimeParameters.entrySet()) {
String outputName = param.getKey();
String inputParameter = param.getValue();
String mime = requestedRawDataMimeTypes.get(outputName);
StringInputProvider provider = new StringInputProvider(mime, inputParameter);
providers.put(inputParameter, provider);
}
}
// turn them into a map of input providers
for (Iterator i = request.getDataInputs().getInput().iterator(); i.hasNext();) {
InputType input = (InputType) i.next();
String inputId = input.getIdentifier().getValue();
// locate the parameter for this request
Parameter p = parameters.get(inputId);
if (p == null) {
throw new WPSException("No such parameter: " + inputId);
}
// find the ppio
String mime = null;
if (input.getData() != null && input.getData().getComplexData() != null) {
mime = input.getData().getComplexData().getMimeType();
} else if (input.getReference() != null) {
mime = input.getReference().getMimeType();
}
ProcessParameterIO ppio = ProcessParameterIO.find(p, manager.applicationContext, mime);
if (ppio == null) {
throw new WPSException("Unable to decode input: " + inputId);
}
// build the provider
InputProvider provider = new SimpleInputProvider(input, ppio, manager,
manager.applicationContext);
// store the input
if (p.maxOccurs > 1) {
ListInputProvider lp = (ListInputProvider) providers.get(p.key);
if (lp == null) {
lp = new ListInputProvider(provider);
providers.put(p.key, lp);
} else {
lp.add(provider);
}
} else {
providers.put(p.key, provider);
}
}
return new LazyInputMap(providers);
}
private Map<String, String> getRequestedRawDataMimeTypes(Collection<String> rawResults, Name name,
ProcessFactory pf) {
Map<String, String> result = new HashMap<String, String>();
ResponseFormType form = request.getResponseForm();
OutputDefinitionType raw = form.getRawDataOutput();
ResponseDocumentType document = form.getResponseDocument();
if (form == null || (raw == null && document == null)) {
// all outputs using their default mime
for (String rawResult : rawResults) {
String mime = AbstractRawData.getDefaultMime(name, pf, rawResult);
result.put(rawResult, mime);
}
} else if (raw != null) {
// just one output type
String output = raw.getIdentifier().getValue();
String mime;
if (raw.getMimeType() != null) {
mime = raw.getMimeType();
} else {
mime = AbstractRawData.getDefaultMime(name, pf, output);
}
result.put(output, mime);
} else {
// the response document form
for (Iterator it = document.getOutput().iterator(); it.hasNext();) {
OutputDefinitionType out = (OutputDefinitionType) it.next();
String outputName = out.getIdentifier().getValue();
if(rawResults.contains(outputName)) {
// was the output mime specified?
String mime = out.getMimeType();
if(mime == null || mime.trim().isEmpty()) {
mime = AbstractRawData.getDefaultMime(name, pf, outputName);
}
result.put(outputName, mime);
}
}
}
return result;
}
public boolean isLineageRequested() {
return request.getResponseForm() != null
&& request.getResponseForm().getResponseDocument() != null
&& request.getResponseForm().getResponseDocument().isLineage();
}
/**
* Returns null if nothing specific was requested, the list otherwise
* @return
*/
public List<DocumentOutputDefinitionType> getRequestedOutputs() {
// in case nothing specific was requested
if (request.getResponseForm() == null
|| request.getResponseForm().getResponseDocument() == null
|| request.getResponseForm().getResponseDocument().getOutput() == null) {
return null;
}
List<DocumentOutputDefinitionType> result = new ArrayList<DocumentOutputDefinitionType>();
EList outputs = request.getResponseForm().getResponseDocument().getOutput();
for (Object output : outputs) {
result.add((DocumentOutputDefinitionType) output);
}
return result;
}
}