/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2005 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/exse/
lat/lon GmbH
http://www.lat-lon.de
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; either
version 2.1 of the License, or (at your option) any later version.
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.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstraße 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.ogcwebservices.wps.execute;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.deegree.datatypes.Code;
import org.deegree.datatypes.values.TypedLiteral;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.ogcwebservices.InvalidParameterValueException;
import org.deegree.ogcwebservices.MissingParameterValueException;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.wps.ServerBusyException;
import org.deegree.ogcwebservices.wps.WPService;
import org.deegree.ogcwebservices.wps.configuration.WPSConfiguration;
import org.deegree.ogcwebservices.wps.describeprocess.ComplexData;
import org.deegree.ogcwebservices.wps.describeprocess.InputDescription;
import org.deegree.ogcwebservices.wps.describeprocess.OutputDescription;
import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription;
import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription.DataInputs;
import org.deegree.ogcwebservices.wps.describeprocess.ProcessDescription.ProcessOutputs;
import org.deegree.ogcwebservices.wps.execute.IOValue.ComplexValueReference;
/**
* WPSExecuteRequestHandler.java
*
* Created on 10.03.2006. 12:11:28h
*
* @author <a href="mailto:christian@kiehle.org">Christian Kiehle</a>
* @author <a href="mailto:christian.heier@gmx.de">Christian Heier</a>
*
* @version 1.0.
*
* @since 2.0
*/
public class ExecuteRequestHandler {
private static final ILogger LOG = LoggerFactory.getLogger( ExecuteRequestHandler.class );
private WPService wpService = null;
private static WPSConfiguration wpsConfiguration = null;
/**
*
* @param wpService
*/
public ExecuteRequestHandler( WPService wpService ) {
this.wpService = wpService;
// Get configuration from current wps instance
wpsConfiguration = this.wpService.getConfiguration();
}
/**
*
* @param executeRequest
* @return
* @throws OGCWebServiceException
*/
public ExecuteResponse handleRequest( ExecuteRequest executeRequest )
throws OGCWebServiceException {
// Get the map of registered Processes from wps configuration
Map<String, Process> registeredProcessesMap = wpsConfiguration.getRegisteredProcesses();
// Get the identifier of the process to be executed from the
// ExecuteRequest
Code executeProcessIdentifier = executeRequest.getIdentifier();
// Get the requested process from the registered processes
Process process = registeredProcessesMap.get( executeProcessIdentifier.getCode().toUpperCase() );
if ( null == process ) {
// Unknown process was requested
String msg = "A process with identifier '" + executeRequest.getIdentifier().getCode()
+ "' is not known to this wpserver.";
LOG.logDebug( msg );
throw new InvalidParameterValueException( getClass().getName(), msg );
}
// Get request queue manager from configuration
RequestQueueManager requestQueueManager =
wpsConfiguration.getDeegreeParams().getRequestQueueManager();
// add current request to queue
boolean success = requestQueueManager.addRequestToQueue( executeRequest );
Status status = null;
if ( success ) {
status = new Status();
String msg = "Your execute request has been successfully added to the RequestQueue. The current length of the RequestQueue is "
+ requestQueueManager.getLengthOfQueue();
LOG.logDebug( msg );
status.setProcessAccepted( msg );
} else {
String msg = "The server is too busy to accept and queue the request at this time.";
LOG.logError( msg );
throw new ServerBusyException( msg );
}
// TODO implement multiple threads handling
if ( 0 < requestQueueManager.getLengthOfQueue() ) {
executeRequest = requestQueueManager.getRequestFromQueue();
}
// Instantiate new execute response
// this response will be populated during the following workflow
ExecuteResponse executeResponse = new ExecuteResponse();
// Set identifier in response according to requested process
executeResponse.setIdentifier( process.getProcessDescription().getIdentifier() );
// Add current status to response
executeResponse.setStatus( status );
// Set version in response according to configuration
executeResponse.setVersion( wpsConfiguration.getVersion() );
// Copy inputs from request to response
ExecuteDataInputs executeDataInputs = executeRequest.getDataInputs();
if ( null != executeDataInputs ) {
executeResponse.setDataInputs( executeDataInputs );
}
// Copy outputdefinitions from request to response
OutputDefinitions outputDefinitions = executeRequest.getOutputDefinitions();
if ( null != outputDefinitions ) {
executeResponse.setOutputDefinitions( outputDefinitions );
}
handleStoreParameter( process, executeRequest, executeResponse );
return executeResponse;
}
/**
*
* @param process
* @param executeRequest
* @param executeResponse
* @throws OGCWebServiceException
*/
private static void handleStoreParameter( Process process, ExecuteRequest executeRequest,
ExecuteResponse executeResponse ) throws OGCWebServiceException {
boolean store = executeRequest.isStore();
if ( store ) {
// TODO store (optional) currently not supported
// @see OGC 05-007r4 Table 27
// @see OGC 05-007r4 Subclauses 10.3.1 and 10.3.2
throw new InvalidParameterValueException( "store",
"Store is not supported by this WPServer instance." );
// handleStatusParameter(process, executeRequest, executeResponse);
}
// Get configured process outputs
ProcessOutputs configuredProcessOutputs =
process.getProcessDescription().getProcessOutputs();
// Get list of outputdescriptions from configured process outputs
List<OutputDescription> outputDescriptionsList = configuredProcessOutputs.getOutput();
/*
* @see OGC 05-007r4 Subclauses 10.3.1 and 10.3.2
* @see OGC 05-007r4 Table 27: If the store parameter is false,
* there is only one output, and that output has a
* ComplexValue, then this ComplexValue shall be returned to
* the client outside of any ExecuteResponse document.
*
*/
if ( 1 == outputDescriptionsList.size() ) {
OutputDescription outputDescription = outputDescriptionsList.get( 0 );
ComplexData complexOutput = outputDescription.getComplexOutput();
if ( null != complexOutput ) {
executeResponse.setDirectResponse( true );
startProcess( process, executeRequest, executeResponse );
} else {
handleStatusParameter( process, executeRequest, executeResponse );
}
} else {
handleStatusParameter( process, executeRequest, executeResponse );
}
}
/**
*
* @param process
* @param executeRequest
* @param executeResponse
* @throws OGCWebServiceException
*/
private static void handleStatusParameter( Process process, ExecuteRequest executeRequest,
ExecuteResponse executeResponse ) throws OGCWebServiceException {
boolean status = executeRequest.isStatus();
if ( status ) {
// TODO status currently not supported (optional)
// @see OGC 05-007r4 Table 27
// @see OGC 05-007r4 Subclauses 10.3.1 and 10.3.2
throw new InvalidParameterValueException( "status",
"Status is not supported by this WPServer instance." );
// save passed response at web accessible location, get full path
// and add it as statuslocation to response
// saveExecuteResponse();
// executeResponse.setStatusLocation(fullpath);
// return response to client
// startProcess(process, executeRequest, executeResponse);
// update status to process started
// updateSavedExecuteResponse();
}
startProcess( process, executeRequest, executeResponse );
}
/**
*
* @param process
* @param executeRequest
* @param executeResponse
* @throws OGCWebServiceException
*/
private static void startProcess( Process process, ExecuteRequest executeRequest,
ExecuteResponse executeResponse ) throws OGCWebServiceException {
// Extract map of provided inputs from request
Map<String, IOValue> inputs =
extractProcessInputs( process.getProcessDescription(), executeRequest );
// Extract outputDefinitions from request
OutputDefinitions outputDefinitions = executeRequest.getOutputDefinitions();
ExecuteResponse.ProcessOutputs processOutputs =
process.execute( inputs, outputDefinitions );
if ( null != processOutputs ) {
// Update status in response to successfull
Status status = executeResponse.getStatus();
status.setProcessSucceeded( "The "
+ process.getProcessDescription().getIdentifier().getCode()
+ " process has been successfully completed" );
executeResponse.setStatus( status );
// Add processOutputs to response
executeResponse.setProcessOutputs( processOutputs );
}
}
/**
* Extract required process inputs from <code>ExecuteRequest</code>
*
* @param executeRequest
* @return
* @throws MissingParameterValueException
* @throws InvalidParameterValueException
*/
private static Map<String, IOValue> extractProcessInputs(
ProcessDescription processDescription, ExecuteRequest executeRequest )
throws MissingParameterValueException, InvalidParameterValueException {
// TODO if complexvaluereferences are included --> load data via a new
// threaded method
// Get inputs provided in executerequest
ExecuteDataInputs executeDataInputs = executeRequest.getDataInputs();
Map<String, IOValue> providedInputs = executeDataInputs.getInputs();
// Prepare result map
Map<String, IOValue> processInputs = null;
// Get required process inputs from processDescription
DataInputs configuredDataInputs = processDescription.getDataInputs();
List<InputDescription> inputDescriptions = configuredDataInputs.getInputDescriptions();
// Get inputDescription for each configured input
int size = inputDescriptions.size();
if ( 0 < size ) {
processInputs = new HashMap<String, IOValue>( size );
for ( int i = 0; i < size; i++ ) {
InputDescription inputDescription = inputDescriptions.get( i );
String identifier = inputDescription.getIdentifier().getCode();
int minOccurs = inputDescription.getMinimumOccurs();
IOValue ioValue = providedInputs.get( identifier );
if ( null == ioValue && 1 == minOccurs ) {
throw new MissingParameterValueException( identifier,
"A required process input is missing" );
}
if ( inputDescription.isBoundingBoxData() ) {
Envelope boundingBoxValue = ioValue.getBoundingBoxValue();
if ( null == boundingBoxValue ) {
throw new InvalidParameterValueException( identifier,
"The type of the provided process input is wrong" );
}
} else if ( inputDescription.isLiteralData() ) {
TypedLiteral literalValue = ioValue.getLiteralValue();
if ( null == literalValue ) {
throw new InvalidParameterValueException( identifier,
"The type of the provided process input is wrong" );
}
} else if ( inputDescription.isComplexData() ) {
ComplexValue complexValue = ioValue.getComplexValue();
ComplexValueReference complexValuereference = ioValue
.getComplexValueReference();
if ( null == complexValue && null == complexValuereference ) {
throw new InvalidParameterValueException( identifier,
"The type of the provided process input is wrong" );
}
}
// TODO load complexvaluereference, add as IOValue to
// ProcessInputsmap
LOG.logDebug( "Found required process input '" + identifier
+ "' in execute request." );
processInputs.put( identifier, ioValue );
}
}
return processInputs;
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: ExecuteRequestHandler.java,v $
Revision 1.4 2006/08/24 06:42:16 poth
File header corrected
Revision 1.3 2006/05/25 14:47:44 poth
LiteralValue substituted by TypedLiteral
Revision 1.2 2006/05/25 14:34:30 poth
sychronous process performing simplified
********************************************************************** */