Java tutorial
/** * Copyright (C) 2007 - 2014 52North 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.request; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; import net.opengis.ows.x11.BoundingBoxType; import net.opengis.ows.x11.ExceptionType; import net.opengis.wps.x100.ComplexDataType; import net.opengis.wps.x100.DataInputsType; import net.opengis.wps.x100.DocumentOutputDefinitionType; import net.opengis.wps.x100.ExecuteDocument; import net.opengis.wps.x100.ExecuteDocument.Execute; import net.opengis.wps.x100.InputDescriptionType; import net.opengis.wps.x100.InputReferenceType; import net.opengis.wps.x100.InputType; import net.opengis.wps.x100.LiteralDataType; import net.opengis.wps.x100.OutputDefinitionType; import net.opengis.wps.x100.OutputDescriptionType; import net.opengis.wps.x100.ProcessDescriptionType; import net.opengis.wps.x100.ResponseDocumentType; import net.opengis.wps.x100.ResponseFormType; import net.opengis.wps.x100.StatusType; import org.apache.commons.collections.map.CaseInsensitiveMap; import org.apache.commons.io.IOUtils; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.n52.wps.commons.context.ExecutionContext; import org.n52.wps.commons.context.ExecutionContextFactory; import org.n52.wps.io.data.IComplexData; import org.n52.wps.io.data.IData; import org.n52.wps.server.AbstractTransactionalAlgorithm; import org.n52.wps.server.ExceptionReport; import org.n52.wps.server.IAlgorithm; import org.n52.wps.server.RepositoryManager; import org.n52.wps.server.database.DatabaseFactory; import org.n52.wps.server.observerpattern.IObserver; import org.n52.wps.server.observerpattern.ISubject; import org.n52.wps.server.response.ExecuteResponse; import org.n52.wps.server.response.ExecuteResponseBuilder; import org.n52.wps.server.response.Response; import org.n52.wps.util.XMLBeansHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * Handles an ExecuteRequest */ public class ExecuteRequest extends Request implements IObserver { private static Logger LOGGER = LoggerFactory.getLogger(ExecuteRequest.class); private ExecuteDocument execDom; private Map<String, IData> returnResults; private ExecuteResponseBuilder execRespType; /** * Creates an ExecuteRequest based on a Document (HTTP_POST) * * @param doc * The clients submission * @throws ExceptionReport */ public ExecuteRequest(Document doc) throws ExceptionReport { super(doc); try { XmlOptions option = new XmlOptions(); option.setLoadTrimTextBuffer(); this.execDom = ExecuteDocument.Factory.parse(doc, option); if (this.execDom == null) { LOGGER.error("ExecuteDocument is null"); throw new ExceptionReport("Error while parsing post data", ExceptionReport.MISSING_PARAMETER_VALUE); } } catch (XmlException e) { throw new ExceptionReport("Error while parsing post data", ExceptionReport.MISSING_PARAMETER_VALUE, e); } // validate the client input validate(); // create an initial response execRespType = new ExecuteResponseBuilder(this); storeRequest(execDom); } /* * Creates an ExecuteRequest based on a Map (HTTP_GET). NOTE: Parameters are * treated as non case sensitive. @param ciMap The client input @throws * ExceptionReport */ public ExecuteRequest(CaseInsensitiveMap ciMap) throws ExceptionReport { super(ciMap); initForGET(ciMap); // validate the client input validate(); // create an initial response execRespType = new ExecuteResponseBuilder(this); storeRequest(ciMap); } public void getKVPDataInputs() { } /** * @param ciMap */ private void initForGET(CaseInsensitiveMap ciMap) throws ExceptionReport { String version = getMapValue("version", ciMap, true); if (!version.equals(Request.SUPPORTED_VERSION)) { throw new ExceptionReport("request version is not supported: " + version, ExceptionReport.VERSION_NEGOTIATION_FAILED); } this.execDom = ExecuteDocument.Factory.newInstance(); Execute execute = execDom.addNewExecute(); String processID = getMapValue("Identifier", true); if (!RepositoryManager.getInstance().containsAlgorithm(processID)) { throw new ExceptionReport("Process does not exist", ExceptionReport.INVALID_PARAMETER_VALUE); } execute.addNewIdentifier().setStringValue(processID); DataInputsType dataInputs = execute.addNewDataInputs(); String dataInputString = getMapValue("DataInputs", true); dataInputString = dataInputString.replace("&", "&"); String[] inputs = dataInputString.split(";"); // Handle data inputs for (String inputString : inputs) { int position = inputString.indexOf("="); if (position == -1) { throw new ExceptionReport("No \"=\" supplied for attribute: " + inputString, ExceptionReport.MISSING_PARAMETER_VALUE); } //get name String key = inputString.substring(0, position); String value = null; if (key.length() + 1 < inputString.length()) { // BS int valueDelimiter = inputString.indexOf("@"); int valueDelimiter = inputString.indexOf("@"); if (valueDelimiter != -1 && position + 1 < valueDelimiter) { value = inputString.substring(position + 1, valueDelimiter); } else { value = inputString.substring(position + 1); } } ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(processID); if (description == null) { throw new ExceptionReport("Data Identifier not supported: " + key, ExceptionReport.MISSING_PARAMETER_VALUE); } InputDescriptionType inputDesc = XMLBeansHelper.findInputByID(key, description.getDataInputs()); if (inputDesc == null) { throw new ExceptionReport("Data Identifier not supported: " + key, ExceptionReport.MISSING_PARAMETER_VALUE); } InputType input = dataInputs.addNewInput(); input.addNewIdentifier().setStringValue(key); // prepare attributes String encodingAttribute = null; String mimeTypeAttribute = null; String schemaAttribute = null; String hrefAttribute = null; String uom = null; String dataType = null; String[] inputItemstemp = inputString.split("@"); String[] inputItems = null; if (inputItemstemp.length == 2) { inputItems = inputItemstemp[1].split("@"); } else { inputItems = inputString.split("@"); } if (inputItemstemp.length > 1) { for (int i = 0; i < inputItems.length; i++) { int attributePos = inputItems[i].indexOf("="); if (attributePos == -1 || attributePos + 1 >= inputItems[i].length()) { continue; } String attributeName = inputItems[i].substring(0, attributePos); String attributeValue = inputItems[i].substring(attributePos + 1); //attribute is input name if (attributeName.equals(key)) { continue; } try { attributeValue = URLDecoder.decode(attributeValue, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new ExceptionReport( "Something went wrong while trying to decode value of " + attributeName, ExceptionReport.NO_APPLICABLE_CODE, e); } if (attributeName.equalsIgnoreCase("encoding")) { encodingAttribute = attributeValue; } else if (attributeName.equalsIgnoreCase("mimeType")) { mimeTypeAttribute = attributeValue; } else if (attributeName.equalsIgnoreCase("schema")) { schemaAttribute = attributeValue; } else if (attributeName.equalsIgnoreCase("href") | attributeName.equalsIgnoreCase("xlink:href")) { hrefAttribute = attributeValue; } else if (attributeName.equalsIgnoreCase("uom")) { uom = attributeValue; } else if (attributeName.equalsIgnoreCase("datatype")) { dataType = attributeValue; } else { throw new ExceptionReport("Attribute is not supported: " + attributeName, ExceptionReport.INVALID_PARAMETER_VALUE); } } } if (inputDesc.isSetComplexData()) { // TODO: check for different attributes // handling ComplexReference if (!(hrefAttribute == null) && !hrefAttribute.equals("")) { InputReferenceType reference = input.addNewReference(); reference.setHref(hrefAttribute); if (schemaAttribute != null) { reference.setSchema(schemaAttribute); } if (mimeTypeAttribute != null) { reference.setMimeType(mimeTypeAttribute); } if (encodingAttribute != null) { reference.setEncoding(encodingAttribute); } } // Handling ComplexData else { ComplexDataType data = input.addNewData().addNewComplexData(); InputStream stream = new ByteArrayInputStream(value.getBytes()); try { data.set(XmlObject.Factory.parse(stream)); } catch (Exception e) { LOGGER.warn( "Could not parse value: " + value + " as XMLObject. Trying to create text node."); try { Node textNode = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() .createTextNode(value); data.set(XmlObject.Factory.parse(textNode)); } catch (Exception e1) { throw new ExceptionReport("Exception while trying to parse value: " + value, ExceptionReport.NO_APPLICABLE_CODE, e1); } } if (schemaAttribute != null) { data.setSchema(schemaAttribute); } if (mimeTypeAttribute != null) { data.setMimeType(mimeTypeAttribute); } if (encodingAttribute != null) { data.setEncoding(encodingAttribute); } } } else if (inputDesc.isSetLiteralData()) { LiteralDataType data = input.addNewData().addNewLiteralData(); if (value == null) { throw new ExceptionReport( "No value provided for literal: " + inputDesc.getIdentifier().getStringValue(), ExceptionReport.MISSING_PARAMETER_VALUE); } data.setStringValue(value); if (uom != null) { data.setUom(uom); } if (dataType != null) { data.setDataType(dataType); } } else if (inputDesc.isSetBoundingBoxData()) { BoundingBoxType data = input.addNewData().addNewBoundingBoxData(); String[] values = value.split(","); if (values.length < 4) { throw new ExceptionReport( "Invalid Number of BBOX Values: " + inputDesc.getIdentifier().getStringValue(), ExceptionReport.MISSING_PARAMETER_VALUE); } List<String> lowerCorner = new ArrayList<String>(); lowerCorner.add(values[0]); lowerCorner.add(values[1]); data.setLowerCorner(lowerCorner); List<String> upperCorner = new ArrayList<String>(); upperCorner.add(values[2]); upperCorner.add(values[3]); data.setUpperCorner(upperCorner); if (values.length > 4) { data.setCrs(values[4]); } if (values.length > 5) { data.setDimensions(BigInteger.valueOf(Long.valueOf(values[5]))); } } } // retrieve status boolean status = false; String statusString = getMapValue("status", false); if (statusString != null) { status = Boolean.parseBoolean(statusString); } boolean store = false; String storeString = getMapValue("storeExecuteResponse", false); if (storeString != null) { store = Boolean.parseBoolean(storeString); } // Handle ResponseDocument option String responseDocument = getMapValue("ResponseDocument", false); if (responseDocument != null) { String[] outputs = responseDocument.split(";"); ResponseDocumentType responseDoc = execute.addNewResponseForm().addNewResponseDocument(); responseDoc.setStatus(status); responseDoc.setStoreExecuteResponse(store); for (String outputID : outputs) { String[] outputDataparameters = outputID.split("@"); String outputDataInput = ""; if (outputDataparameters.length > 0) { outputDataInput = outputDataparameters[0]; } else { outputDataInput = outputID; } outputDataInput = outputDataInput.replace("=", ""); ProcessDescriptionType description = RepositoryManager.getInstance() .getProcessDescription(processID); OutputDescriptionType outputDesc = XMLBeansHelper.findOutputByID(outputDataInput, description.getProcessOutputs().getOutputArray()); if (outputDesc == null) { throw new ExceptionReport("Data output Identifier not supported: " + outputDataInput, ExceptionReport.MISSING_PARAMETER_VALUE); } DocumentOutputDefinitionType output = responseDoc.addNewOutput(); output.addNewIdentifier().setStringValue(outputDataInput); for (int i = 1; i < outputDataparameters.length; i++) { int attributePos = outputDataparameters[i].indexOf("="); if (attributePos == -1 || attributePos + 1 >= outputDataparameters[i].length()) { continue; } String attributeName = outputDataparameters[i].substring(0, attributePos); String attributeValue = outputDataparameters[i].substring(attributePos + 1); try { attributeValue = URLDecoder.decode(attributeValue, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new ExceptionReport( "Something went wrong while trying to decode value of " + attributeName, ExceptionReport.NO_APPLICABLE_CODE, e); } if (attributeName.equalsIgnoreCase("mimeType")) { output.setMimeType(attributeValue); } else if (attributeName.equalsIgnoreCase("schema")) { output.setSchema(attributeValue); } else if (attributeName.equalsIgnoreCase("encoding")) { output.setEncoding(attributeValue); } } } } String rawData = getMapValue("RawDataOutput", false); if (rawData != null) { String[] rawDataparameters = rawData.split("@"); String rawDataInput = ""; if (rawDataparameters.length > 0) { rawDataInput = rawDataparameters[0]; } else { rawDataInput = rawData; } ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(processID); OutputDescriptionType outputDesc = XMLBeansHelper.findOutputByID(rawDataInput, description.getProcessOutputs().getOutputArray()); if (outputDesc == null) { throw new ExceptionReport("Data output Identifier not supported: " + rawData, ExceptionReport.MISSING_PARAMETER_VALUE); } ResponseFormType responseForm = execute.addNewResponseForm(); OutputDefinitionType output = responseForm.addNewRawDataOutput(); output.addNewIdentifier().setStringValue(outputDesc.getIdentifier().getStringValue()); if (rawDataparameters.length > 0) { for (int i = 0; i < rawDataparameters.length; i++) { int attributePos = rawDataparameters[i].indexOf("="); if (attributePos == -1 || attributePos + 1 >= rawDataparameters[i].length()) { continue; } String attributeName = rawDataparameters[i].substring(0, attributePos); String attributeValue = rawDataparameters[i].substring(attributePos + 1); try { attributeValue = URLDecoder.decode(attributeValue, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new ExceptionReport( "Something went wrong while trying to decode value of " + attributeName, ExceptionReport.NO_APPLICABLE_CODE, e); } if (attributeName.equalsIgnoreCase("mimeType")) { output.setMimeType(attributeValue); } else if (attributeName.equalsIgnoreCase("schema")) { output.setSchema(attributeValue); } else if (attributeName.equalsIgnoreCase("encoding")) { output.setEncoding(attributeValue); } else { throw new ExceptionReport("Attribute is not supported: " + attributeName, ExceptionReport.INVALID_PARAMETER_VALUE); } } } } } /** * Validates the client request * * @return True if the input is valid, False otherwise */ public boolean validate() throws ExceptionReport { // Identifier must be specified. /* * Only for HTTP_GET: String identifier = getMapValue("identifier"); * * try{ // Specifies if all complex valued output(s) of this process * should be stored by process // as web-accessible resources store = * getMapValue("store").equals("true"); * // Specifies if Execute operation response shall be returned quickly * with status information status = * getMapValue("status").equals("true"); }catch(ExceptionReport e){ // * if parameters "store" or "status" are not included, they default to * false; } * // just testing if the number of arguments is even... String[] * diArray = getMapValue("DataInputs").split(","); if(diArray.length % 2 != * 0) { throw new ExceptionReport("Incorrect number of arguments for * parameter dataInputs, please only a even number of parameter values", * ExceptionReport.INVALID_PARAMETER_VALUE); } * */ if (!execDom.getExecute().getVersion().equals(SUPPORTED_VERSION)) { throw new ExceptionReport("Specified version is not supported.", ExceptionReport.INVALID_PARAMETER_VALUE, "version=" + getExecute().getVersion()); } //Fix for bug https://bugzilla.52north.org/show_bug.cgi?id=906 String identifier = getAlgorithmIdentifier(); if (identifier == null) { throw new ExceptionReport("No process identifier supplied.", ExceptionReport.MISSING_PARAMETER_VALUE, "identifier"); } // check if the algorithm is in our repository if (!RepositoryManager.getInstance().containsAlgorithm(identifier)) { throw new ExceptionReport("Specified process identifier does not exist", ExceptionReport.INVALID_PARAMETER_VALUE, "identifier=" + identifier); } // validate if the process can be executed ProcessDescriptionType desc = RepositoryManager.getInstance() .getProcessDescription(getAlgorithmIdentifier()); // We need a description of the inputs for the algorithm if (desc == null) { LOGGER.warn("desc == null"); return false; } // Get the inputdescriptions of the algorithm if (desc.getDataInputs() != null) { InputDescriptionType[] inputDescs = desc.getDataInputs().getInputArray(); //prevent NullPointerException for zero input values in execute request (if only default values are used) InputType[] inputs; if (getExecute().getDataInputs() == null) inputs = new InputType[0]; else inputs = getExecute().getDataInputs().getInputArray(); // For each input supplied by the client for (InputType input : inputs) { boolean identifierMatched = false; // Try to match the input with one of the descriptions for (InputDescriptionType inputDesc : inputDescs) { // If found, then process: if (inputDesc.getIdentifier().getStringValue().equals(input.getIdentifier().getStringValue())) { identifierMatched = true; // If it is a literal value, if (input.getData() != null && input.getData().getLiteralData() != null) { // then check if the desription is also of type literal if (inputDesc.getLiteralData() == null) { throw new ExceptionReport("Inputtype LiteralData is not supported", ExceptionReport.INVALID_PARAMETER_VALUE); } // literalValue.getDataType ist optional if (input.getData().getLiteralData().getDataType() != null) { if (inputDesc.getLiteralData() != null) if (inputDesc.getLiteralData().getDataType() != null) if (inputDesc.getLiteralData().getDataType().getReference() != null) if (!input.getData().getLiteralData().getDataType().equals( inputDesc.getLiteralData().getDataType().getReference())) { throw new ExceptionReport("Specified dataType is not supported " + input.getData().getLiteralData().getDataType() + " for input " + input.getIdentifier().getStringValue(), ExceptionReport.INVALID_PARAMETER_VALUE); } } } // Excluded, because ProcessDescription validation should be // done on startup! // else if (input.getComplexValue() != null) { // if(ParserFactory.getInstance().getParser(input.getComplexValue().getSchema()) // == null) { // LOGGER.warn("Request validation message: schema attribute // null, so the simple one will be used!"); // } // } // else if (input.getComplexValueReference() != null) { // // we found a complexvalue input, try to get the parser. // if(ParserFactory.getInstance().getParser(input.getComplexValueReference().getSchema()) // == null) { // LOGGER.warn("Request validation message: schema attribute // null, so the simple one will be used!"); // } // } break; } } // if the identifier did not match one of the descriptions, it is // invalid if (!identifierMatched) { throw new ExceptionReport( "Input Identifier is not valid: " + input.getIdentifier().getStringValue(), ExceptionReport.INVALID_PARAMETER_VALUE, "input identifier"); } } } return true; } /** * Actually serves the Request. * * @throws ExceptionReport */ public Response call() throws ExceptionReport { IAlgorithm algorithm = null; Map<String, List<IData>> inputMap = null; try { ExecutionContext context; if (getExecute().isSetResponseForm()) { context = getExecute().getResponseForm().isSetRawDataOutput() ? new ExecutionContext(getExecute().getResponseForm().getRawDataOutput()) : new ExecutionContext(Arrays .asList(getExecute().getResponseForm().getResponseDocument().getOutputArray())); } else { context = new ExecutionContext(); } // register so that any function that calls ExecuteContextFactory.getContext() gets the instance registered with this thread ExecutionContextFactory.registerContext(context); LOGGER.debug("started with execution"); updateStatusStarted(); // parse the input InputType[] inputs = new InputType[0]; if (getExecute().getDataInputs() != null) { inputs = getExecute().getDataInputs().getInputArray(); } InputHandler parser = new InputHandler.Builder(inputs, getAlgorithmIdentifier()).build(); // we got so far: // get the algorithm, and run it with the clients input /* * IAlgorithm algorithm = * RepositoryManager.getInstance().getAlgorithm(getAlgorithmIdentifier()); * returnResults = algorithm.run((Map)parser.getParsedInputLayers(), * (Map)parser.getParsedInputParameters()); */ algorithm = RepositoryManager.getInstance().getAlgorithm(getAlgorithmIdentifier()); if (algorithm instanceof ISubject) { ISubject subject = (ISubject) algorithm; subject.addObserver(this); } if (algorithm instanceof AbstractTransactionalAlgorithm) { returnResults = ((AbstractTransactionalAlgorithm) algorithm).run(execDom); } else { inputMap = parser.getParsedInputData(); returnResults = algorithm.run(inputMap); } List<String> errorList = algorithm.getErrors(); if (errorList != null && !errorList.isEmpty()) { String errorMessage = errorList.get(0); LOGGER.error("Error reported while handling ExecuteRequest for " + getAlgorithmIdentifier() + ": " + errorMessage); updateStatusError(errorMessage); } else { updateStatusSuccess(); } } catch (Throwable e) { String errorMessage = null; if (algorithm != null && algorithm.getErrors() != null && !algorithm.getErrors().isEmpty()) { errorMessage = algorithm.getErrors().get(0); } if (errorMessage == null) { errorMessage = e.toString(); } if (errorMessage == null) { errorMessage = "UNKNOWN ERROR"; } LOGGER.error("Exception/Error while executing ExecuteRequest for " + getAlgorithmIdentifier() + ": " + errorMessage); updateStatusError(errorMessage); if (e instanceof Error) { // This is required when catching Error throw (Error) e; } if (e instanceof ExceptionReport) { throw (ExceptionReport) e; } else { throw new ExceptionReport( "Error while executing the embedded process for: " + getAlgorithmIdentifier(), ExceptionReport.NO_APPLICABLE_CODE, e); } } finally { // you ***MUST*** call this or else you will have a PermGen ClassLoader memory leak due to ThreadLocal use ExecutionContextFactory.unregisterContext(); if (algorithm instanceof ISubject) { ((ISubject) algorithm).removeObserver(this); } if (inputMap != null) { for (List<IData> l : inputMap.values()) { for (IData d : l) { if (d instanceof IComplexData) { ((IComplexData) d).dispose(); } } } } if (returnResults != null) { for (IData d : returnResults.values()) { if (d instanceof IComplexData) { ((IComplexData) d).dispose(); } } } } ExecuteResponse response = new ExecuteResponse(this); return response; } /** * Gets the identifier of the algorithm the client requested * * @return An identifier */ public String getAlgorithmIdentifier() { //Fix for bug https://bugzilla.52north.org/show_bug.cgi?id=906 if (getExecute().getIdentifier() != null) { return getExecute().getIdentifier().getStringValue(); } return null; } /** * Gets the Execute that is associated with this Request * * @return The Execute */ public Execute getExecute() { return execDom.getExecute(); } public Map<String, IData> getAttachedResult() { return returnResults; } public boolean isStoreResponse() { if (execDom.getExecute().getResponseForm() == null) { return false; } if (execDom.getExecute().getResponseForm().getRawDataOutput() != null) { return false; } return execDom.getExecute().getResponseForm().getResponseDocument().getStoreExecuteResponse(); } public boolean isQuickStatus() { if (execDom.getExecute().getResponseForm() == null) { return false; } if (execDom.getExecute().getResponseForm().getRawDataOutput() != null) { return false; } return execDom.getExecute().getResponseForm().getResponseDocument().getStatus(); } public ExecuteResponseBuilder getExecuteResponseBuilder() { return this.execRespType; } public boolean isRawData() { if (execDom.getExecute().getResponseForm() == null) { return false; } if (execDom.getExecute().getResponseForm().getRawDataOutput() != null) { return true; } else { return false; } } public void update(ISubject subject) { Object state = subject.getState(); LOGGER.info("Update received from Subject, state changed to : " + state); StatusType status = StatusType.Factory.newInstance(); int percentage = 0; if (state instanceof Integer) { percentage = (Integer) state; status.addNewProcessStarted().setPercentCompleted(percentage); } else if (state instanceof String) { status.addNewProcessStarted().setStringValue((String) state); } updateStatus(status); } public void updateStatusAccepted() { StatusType status = StatusType.Factory.newInstance(); status.setProcessAccepted("Process Accepted"); updateStatus(status); } public void updateStatusStarted() { StatusType status = StatusType.Factory.newInstance(); status.addNewProcessStarted().setPercentCompleted(0); updateStatus(status); } public void updateStatusSuccess() { StatusType status = StatusType.Factory.newInstance(); status.setProcessSucceeded("Process successful"); updateStatus(status); } public void updateStatusError(String errorMessage) { StatusType status = StatusType.Factory.newInstance(); net.opengis.ows.x11.ExceptionReportDocument.ExceptionReport excRep = status.addNewProcessFailed() .addNewExceptionReport(); excRep.setVersion("1.0.0"); ExceptionType excType = excRep.addNewException(); excType.addNewExceptionText().setStringValue(errorMessage); excType.setExceptionCode(ExceptionReport.NO_APPLICABLE_CODE); updateStatus(status); } private void updateStatus(StatusType status) { getExecuteResponseBuilder().setStatus(status); try { getExecuteResponseBuilder().update(); if (isStoreResponse()) { ExecuteResponse executeResponse = new ExecuteResponse(this); InputStream is = null; try { is = executeResponse.getAsStream(); DatabaseFactory.getDatabase().storeResponse(getUniqueId().toString(), is); } finally { IOUtils.closeQuietly(is); } } } catch (ExceptionReport e) { LOGGER.error("Update of process status failed.", e); throw new RuntimeException(e); } } private void storeRequest(ExecuteDocument executeDocument) { InputStream is = null; try { is = executeDocument.newInputStream(); DatabaseFactory.getDatabase().insertRequest(getUniqueId().toString(), is, true); } catch (Exception e) { LOGGER.error("Exception storing ExecuteRequest", e); } finally { IOUtils.closeQuietly(is); } } private void storeRequest(CaseInsensitiveMap map) { BufferedWriter w = null; ByteArrayOutputStream os = null; ByteArrayInputStream is = null; try { os = new ByteArrayOutputStream(); w = new BufferedWriter(new OutputStreamWriter(os)); for (Object key : map.keySet()) { Object value = map.get(key); String valueString = ""; if (value instanceof String[]) { valueString = ((String[]) value)[0]; } else { valueString = value.toString(); } w.append(key.toString()).append('=').append(valueString); w.newLine(); } w.flush(); is = new ByteArrayInputStream(os.toByteArray()); DatabaseFactory.getDatabase().insertRequest(getUniqueId().toString(), is, false); } catch (Exception e) { LOGGER.error("Exception storing ExecuteRequest", e); } finally { IOUtils.closeQuietly(w); IOUtils.closeQuietly(os); IOUtils.closeQuietly(is); } } }