/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.wps;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import net.opengis.wps10.DataType;
import net.opengis.wps10.ExecuteResponseType;
import net.opengis.wps10.InputDescriptionType;
import net.opengis.wps10.ProcessDescriptionType;
import org.eclipse.emf.common.util.EList;
import org.geotools.data.wps.request.ExecuteProcessRequest;
import org.geotools.data.wps.response.ExecuteProcessResponse;
import org.geotools.ows.ServiceException;
import org.geotools.process.ProcessFactory;
import org.geotools.process.impl.AbstractProcess;
import org.opengis.util.ProgressListener;
/**
* This is a representation of a process built from the WPSFactory class.
* It is not a real process, but a representation of a process that can
* be executed on the server, as described in the process' describeprocess.
*
* @author GDavis
*
*
* @source $URL$
*/
public class WPSProcess extends AbstractProcess {
protected WPSProcess(ProcessFactory factory) {
super(factory);
}
/**
* Since this is not a real process, but a representation of one,
* this method doesn't actually execute the process. Instead it
* builds a request to send to the server to execute the
* process. The response is parsed and returned as a map just like
* a process would return locally. The inputs are not validated, they are just
* built and sent to the server in a request. If they result in a bad request,
* the request system will handle the returned error.
*
* @param input the map of inputs to process
* @param monitor currently this is not used for this process reprensentation but
* it could be implemented in some form in the future.
*/
@SuppressWarnings("unchecked")
public Map<String, Object> execute(Map<String, Object> input,
ProgressListener monitor) {
// Get the describeprocess object so we can use it to build up a request and
// get the server url to send the request to.
WPSFactory wpsfactory = (WPSFactory) this.factory;
ProcessDescriptionType pdt = wpsfactory.getProcessDescriptionType();
URL url = wpsfactory.getServerURL();
WebProcessingService wps;
try {
wps = new WebProcessingService(url);
} catch (ServiceException e) {
return null;
} catch (IOException e) {
return null;
}
// create the execute request object
ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest();
exeRequest.setIdentifier(wpsfactory.getIdentifier());
// loop through each expected input in the describeprocess, and set it
// based on what we have in the provided input map.
EList inputs = pdt.getDataInputs().getInput();
Iterator iterator = inputs.iterator();
while (iterator.hasNext()) {
InputDescriptionType idt = (InputDescriptionType) iterator.next();
String identifier = idt.getIdentifier().getValue();
Object inputValue = input.get(identifier);
if (inputValue != null) {
// if our value is some sort of collection, then created multiple
// dataTypes for this inputdescriptiontype.
List<DataType> list = new ArrayList<DataType>();
if (inputValue instanceof Map) {
for (Object inVal : ((Map)inputValue).values()) {
DataType createdInput = WPSUtils.createInputDataType(inVal, idt);
list.add(createdInput);
}
} else if (inputValue instanceof Collection) {
for (Object inVal : (Collection)inputValue) {
DataType createdInput = WPSUtils.createInputDataType(inVal, idt);
list.add(createdInput);
}
} else {
// our value is a single object so create a single datatype for it
DataType createdInput = WPSUtils.createInputDataType(inputValue, idt);
list.add(createdInput);
}
// add the input to the execute request
exeRequest.addInput(identifier, list);
}
}
// send the request and get the response
ExecuteProcessResponse response;
try {
response = wps.issueRequest(exeRequest);
} catch (ServiceException e) {
return null;
} catch (IOException e) {
return null;
}
// if there is an exception in the response, return null
// TODO: properly handle the exception?
if (response.getExceptionResponse() != null || response.getExecuteResponse() == null) {
return null;
}
// get response object and create a map of outputs from it
ExecuteResponseType executeResponse = response.getExecuteResponse();
// create the result map of outputs
Map<String, Object> results = new TreeMap<String, Object>();
results = WPSUtils.createResultMap(executeResponse, results);
return results;
}
}