package org.gcube.data.analysis.wps; import java.io.InputStream; import java.net.Inet4Address; import java.net.UnknownHostException; import java.util.Calendar; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import net.opengis.ows.x11.DomainMetadataType; import net.opengis.ows.x11.LanguageStringType; import net.opengis.wps.x100.DataInputsType; import net.opengis.wps.x100.DocumentOutputDefinitionType; import net.opengis.wps.x100.ExecuteResponseDocument; import net.opengis.wps.x100.ExecuteResponseDocument.ExecuteResponse; import net.opengis.wps.x100.OutputDefinitionType; import net.opengis.wps.x100.OutputDescriptionType; import net.opengis.wps.x100.ProcessDescriptionType; import net.opengis.wps.x100.StatusType; import org.apache.xmlbeans.XmlCursor; import org.n52.wps.commons.WPSConfig; import org.n52.wps.io.data.IBBOXData; import org.n52.wps.io.data.IData; import org.n52.wps.server.ExceptionReport; import org.n52.wps.server.RepositoryManager; import org.n52.wps.server.WebProcessingService; import org.n52.wps.server.request.Request; import org.n52.wps.server.response.OutputDataItem; import org.n52.wps.server.response.RawData; import org.n52.wps.util.XMLBeansHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * WPS Execute operation response. By default, this XML document is delivered to the client in response to an Execute request. If "status" is "false" in the Execute operation request, this document is normally returned when process execution has been completed. * If "status" in the Execute request is "true", this response shall be returned as soon as the Execute request has been accepted for processing. In this case, the same XML document is also made available as a web-accessible resource from the URL identified in the statusLocation, and the WPS server shall repopulate it once the process has completed. It may repopulate it on an ongoing basis while the process is executing. * However, the response to an Execute request will not include this element in the special case where the output is a single complex value result and the Execute request indicates that "store" is "false". * Instead, the server shall return the complex result (e.g., GIF image or GML) directly, without encoding it in the ExecuteResponse. If processing fails in this special case, the normal ExecuteResponse shall be sent, with the error condition indicated. This option is provided to simplify the programming required for simple clients and for service chaining. * @author Timon ter Braak * */ public class ExecuteResponseBuilder { private String identifier; private DataInputsType dataInputs; //private DocumentOutputDefinitionType[] outputDefs; private ExecuteRequest request; private ExecuteResponseDocument doc; private RawData rawDataHandler = null; private ProcessDescriptionType description; private static Logger LOGGER = LoggerFactory.getLogger(ExecuteResponseBuilder.class); private Calendar creationTime; String webPath; String webStatus; public ExecuteResponseBuilder(ExecuteRequest request) throws ExceptionReport{ LOGGER.debug("Building Doc"); this.request = request; doc = ExecuteResponseDocument.Factory.newInstance(); doc.addNewExecuteResponse(); XmlCursor c = doc.newCursor(); c.toFirstChild(); c.toLastAttribute(); c.setAttributeText(new QName(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "schemaLocation"), "http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_response.xsd"); String webapp = WPSConfig.getInstance().getWPSConfig().getServer().getWebappPath(); if (webapp == null) webapp = "wps"; String host = WPSConfig.getInstance().getWPSConfig().getServer().getHostname(); if (host.toLowerCase().equals("localhost")) try { host = Inet4Address.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { LOGGER.error("error",e); } String port = WPSConfig.getInstance().getWPSConfig().getServer().getHostport(); LOGGER.debug("Host: " + host + " Port: " + port + " Webapp: " + webapp + " "); webPath = "http://" + host + ":" + port + "/" + webapp + "/WebProcessingService"; webStatus = "http://" + host + ":" + port + "/" + webapp + "/RetrieveResultServlet"; //statistical-manager-new.d4science.org:8080/wps/WebProcessingService?Request=GetCapabilities&Service=WPS // doc.getExecuteResponse().setServiceInstance(webPath+"?REQUEST=GetCapabilities&SERVICE=WPS"); doc.getExecuteResponse().setServiceInstance(webPath); doc.getExecuteResponse().setLang(WebProcessingService.DEFAULT_LANGUAGE); doc.getExecuteResponse().setService("WPS"); doc.getExecuteResponse().setVersion(Request.SUPPORTED_VERSION); LOGGER.debug("Doc attributes set"); this.identifier = request.getExecute().getIdentifier().getStringValue().trim(); LOGGER.debug("Identifier: "+identifier); ExecuteResponse responseElem = doc.getExecuteResponse(); responseElem.addNewProcess().addNewIdentifier().setStringValue(identifier); LOGGER.debug("Getting description for "+identifier); description = RepositoryManager.getInstance().getProcessDescription(this.identifier); LOGGER.debug("Description "+description); if(description==null){ // throw new RuntimeException("Error while accessing the process description for "+ identifier); } responseElem.getProcess().setTitle(description.getTitle()); responseElem.getProcess().setProcessVersion(description.getProcessVersion()); creationTime = Calendar.getInstance(); LOGGER.debug("Execute Response Created!"); } public void update() throws ExceptionReport { // copying the request parameters to the response ExecuteResponse responseElem = doc.getExecuteResponse(); // if status succeeded, update reponse with result if (responseElem.getStatus().isSetProcessSucceeded()) { // the response only include dataInputs, if the property is set to true; //if(Boolean.getBoolean(WPSConfiguration.getInstance().getProperty(WebProcessingService.PROPERTY_NAME_INCLUDE_DATAINPUTS_IN_RESPONSE))) { if(new Boolean(WPSConfig.getInstance().getWPSConfig().getServer().getIncludeDataInputsInResponse())){ dataInputs = request.getExecute().getDataInputs(); responseElem.setDataInputs(dataInputs); } responseElem.addNewProcessOutputs(); // has the client specified the outputs? if (request.getExecute().isSetResponseForm()) { // Get the outputdescriptions from the algorithm OutputDescriptionType[] outputDescs = description.getProcessOutputs().getOutputArray(); if(request.isRawData()) { OutputDefinitionType rawDataOutput = request.getExecute().getResponseForm().getRawDataOutput(); String id = rawDataOutput.getIdentifier().getStringValue(); OutputDescriptionType desc = XMLBeansHelper.findOutputByID(id, outputDescs); if(desc.isSetComplexOutput()) { String encoding = ExecuteResponseBuilder.getEncoding(desc, rawDataOutput); String schema = ExecuteResponseBuilder.getSchema(desc, rawDataOutput); String responseMimeType = getMimeType(rawDataOutput); generateComplexDataOutput(id, false, true, schema, responseMimeType, encoding, null); } else if (desc.isSetLiteralOutput()) { String mimeType = null; String schema = null; String encoding = null; DomainMetadataType dataType = desc.getLiteralOutput().getDataType(); String reference = dataType != null ? dataType.getReference() : null; generateLiteralDataOutput(id, doc, true, reference, schema, mimeType, encoding, desc.getTitle()); } else if (desc.isSetBoundingBoxOutput()) { generateBBOXOutput(id, doc, true, desc.getTitle()); } return; } // Get the outputdefinitions from the clients request // For each request of output for(int i = 0; i