/** * Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * If the program is linked with libraries which are licensed under one of * the following licenses, the combination of the program with the linked * library is not considered a "derivative work" of the program: * * • Apache License, version 2.0 * • Apache Software License, version 1.0 * • GNU Lesser General Public License, version 3 * • Mozilla Public License, versions 1.0, 1.1 and 2.0 * • Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed * under the aforementioned licenses, is permitted by the copyright holders * if the distribution is compliant with both the GNU General Public * License version 2 and the aforementioned licenses. * * This program 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 General * Public License for more details. */ package org.n52.wps.server.response; import java.io.InputStream; 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.slf4j.Logger; import org.slf4j.LoggerFactory; 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.CapabilitiesConfiguration; import org.n52.wps.server.ExceptionReport; import org.n52.wps.server.RepositoryManager; import org.n52.wps.server.WebProcessingService; import org.n52.wps.server.database.DatabaseFactory; import org.n52.wps.server.request.ExecuteRequest; import org.n52.wps.server.request.Request; import org.n52.wps.util.XMLBeansHelper; /** * 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; public ExecuteResponseBuilder(ExecuteRequest request) throws ExceptionReport{ 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"); doc.getExecuteResponse().setServiceInstance(CapabilitiesConfiguration.ENDPOINT_URL+"?REQUEST=GetCapabilities&SERVICE=WPS"); doc.getExecuteResponse().setLang(WebProcessingService.DEFAULT_LANGUAGE); doc.getExecuteResponse().setService("WPS"); doc.getExecuteResponse().setVersion(Request.SUPPORTED_VERSION); this.identifier = request.getExecute().getIdentifier().getStringValue().trim(); ExecuteResponse responseElem = doc.getExecuteResponse(); responseElem.addNewProcess().addNewIdentifier().setStringValue(identifier); description = RepositoryManager.getInstance().getProcessDescription(this.identifier); 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(); } 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