branch for release 4.6.1

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/branches/data-analysis/52n-wps-server-d4s/3.6@151433 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Lucio Lelii 2017-07-28 16:00:48 +00:00
commit a307d80a4f
68 changed files with 11337 additions and 0 deletions

31
.classpath Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

23
.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>52n-wps-server-d4s</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

1
distro/LICENSE Normal file
View File

@ -0,0 +1 @@
${gcube.license}

69
distro/README Normal file
View File

@ -0,0 +1,69 @@
The gCube System - ${name}
--------------------------------------------------
${description}
${gcube.description}
${gcube.funding}
Version
--------------------------------------------------
${version} (${buildDate})
Please see the file named "changelog.xml" in this directory for the release notes.
Authors
--------------------------------------------------
* Gianpaolo Coro (gianpaolo.coro-AT-isti.cnr.it),
Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" CNR, Pisa IT
Maintainers
-----------
* Gianpaolo Coro (gianpaolo.coro-AT-isti.cnr.it),
Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo" CNR, Pisa IT
Download information
--------------------------------------------------
Source code is available from SVN:
${scm.url}
Binaries can be downloaded from the gCube website:
${gcube.website}
Installation
--------------------------------------------------
Installation documentation is available on-line in the gCube Wiki:
https://wiki.gcube-system.org/gcube/DataMiner_Installation
Documentation
--------------------------------------------------
Documentation is available on-line in the gCube Wiki:
https://wiki.gcube-system.org/gcube/DataMiner_Installation
Support
--------------------------------------------------
Bugs and support requests can be reported in the gCube issue tracking tool:
${gcube.issueTracking}
Licensing
--------------------------------------------------
This software is licensed under the terms you may find in the file named "LICENSE" in this directory.

5
distro/changelog.xml Normal file
View File

@ -0,0 +1,5 @@
<ReleaseNotes>
<Changeset component="${groupId}.${artifactId}.3-6-1" date="2017-07-05">
<Change>First Release</Change>
</Changeset>
</ReleaseNotes>

32
distro/descriptor.xml Normal file
View File

@ -0,0 +1,32 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>servicearchive</id>
<formats>
<format>tar.gz</format>
</formats>
<baseDirectory>/</baseDirectory>
<fileSets>
<fileSet>
<directory>${distroDirectory}</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>
<include>README</include>
<include>LICENSE</include>
<include>changelog.xml</include>
<include>profile.xml</include>
</includes>
<fileMode>755</fileMode>
<filtered>true</filtered>
</fileSet>
</fileSets>
<files>
<file>
<source>target/${build.finalName}.${project.packaging}</source>
<outputDirectory>/${artifactId}</outputDirectory>
</file>
</files>
</assembly>

30
distro/profile.xml Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<Resource>
<ID></ID>
<Type>Service</Type>
<Profile>
<Description>${project.description}</Description>
<Class>DataAnalysis</Class>
<Name>${project.name}</Name>
<Version>1.0.0</Version>
<Packages>
<Software>
<Name>${project.name}</Name>
<Description>${project.description}</Description>
<Version>${version}</Version>
<MavenCoordinates>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</MavenCoordinates>
<Type>Service</Type>
<Files>
<File>${project.build.finalName}.${project.packaging}</File>
</Files>
</Software>
</Packages>
</Profile>
</Resource>

196
pom.xml Normal file
View File

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>maven-parent</artifactId>
<groupId>org.gcube.tools</groupId>
<version>1.0.0</version>
<relativePath />
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.gcube.dataanalysis</groupId>
<artifactId>52n-wps-server-gcube</artifactId>
<version>3.6.1-SNAPSHOT</version>
<name>52North WPS Server - modified for gcube</name>
<description>Server frontend implementation (Servlet) of GET and POX binding for the 52 North WPS</description>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<configuration>
<header>../misc/licenses/license_header.txt</header>
</configuration>
</plugin>
<plugin>
<groupId>org.jasig.maven</groupId>
<artifactId>maven-notice-plugin</artifactId>
<executions>
<execution>
<id>check-licenses</id>
<phase />
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-commons</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-config</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.gcube.dataanalysis</groupId>
<artifactId>52n-wps-algorithm-gcube</artifactId>
<version>[3.6.1-SNAPSHOT,3.7.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-database</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-io</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-io-impl</artifactId>
<version>3.6.1</version>
</dependency>
<!-- START J2EE -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
<version>2.1</version>
</dependency>
<!-- END J2EE -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>13.0.1</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<!--<version>1.3.1</version> -->
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-algorithm-geotools</artifactId>
<version>3.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-algorithm-impl</artifactId>
<version>3.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.n52.wps</groupId>
<artifactId>52n-wps-io-geotools</artifactId>
<version>3.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.2</version>
<scope>test</scope>
</dependency>
<!-- <dependency> -->
<!-- <groupId>${project.groupId}</groupId> -->
<!-- <artifactId>52n-wps-mc</artifactId> -->
<!-- </dependency> -->
</dependencies>
<repositories>
<repository>
<id>n52-releases</id>
<name>52n Releases</name>
<url>http://52north.org/maven/repo/releases</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@ -0,0 +1,51 @@
# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
#-------------------------------------------------------------------------------
# Already used licenses in project :
# - Apache 2
# - Apache License
# - Apache-Style with the acknowledgment clause removed
# - BSD
# - BSD License
# - BSD License for HSQL
# - Common Development and Distribution License 1.0
# - Common Public License Version 1.0
# - EPSG database distribution license
# - Eclipse Public License 1.0
# - GNU GENERAL PUBLIC LICENSE Version 2, June 1991
# - HSQLDB License
# - Lesser General Public License (LGPL)
# - Lesser General Public License (LGPL), Version 2.1
# - MIT License
# - New BSD License
# - OGC copyright
# - Simplified BSD
# - Sun Binary Code License Agreement
# - The Apache Software License, Version 2.0
# - The BSD 2-Clause License
# - The BSD License
# - The GNU General Public License (GPL)
#-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies :
#
#
#Wed Jan 08 13:06:02 CET 2014
axis--axis-jaxrpc--1.4=The Apache Software License, Version 2.0
axis--axis-saaj--1.4=The Apache Software License, Version 2.0
axis--axis-wsdl4j--1.5.1=Common Public License Version 1.0
commons-discovery--commons-discovery--0.2=The Apache Software License, Version 2.0
edu.umn.gis--mapscript--6.0.3=
java3d--vecmath--1.3.2=The GNU General Public License (GPL)
javax.media--jai_codec--1.1.3=Sun Binary Code License Agreement
javax.media--jai_core--1.1.3=Sun Binary Code License Agreement
javax.media--jai_imageio--1.1=Sun Binary Code License Agreement
javax.servlet--servlet-api--2.5=Common Development and Distribution License 1.0
jdom--jdom--1.0=Apache-Style with the acknowledgment clause removed
jgridshift--jgridshift--1.0=Lesser General Public License (LGPL), Version 2.1
org.apache.derby--derby--10.2.2.0=The Apache Software License, Version 2.0
org.eclipse.emf--common--2.6.0=Eclipse Public License 1.0
org.eclipse.emf--ecore--2.6.1=Eclipse Public License 1.0
org.eclipse.xsd--xsd--2.6.0=Eclipse Public License 1.0
org.n52.wps--gmlpacket-2.0--0.4=GNU GENERAL PUBLIC LICENSE Version 2, June 1991
org.n52.wps--ogckml2.2--1.0.0=GNU GENERAL PUBLIC LICENSE Version 2, June 1991
picocontainer--picocontainer--1.2=The BSD 2-Clause License
xerces--xercesImpl--2.7.1=The Apache Software License, Version 2.0

View File

@ -0,0 +1,465 @@
/**
* 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;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.concurrent.locks.ReentrantLock;
import net.opengis.ows.x11.CodeType;
import net.opengis.ows.x11.DCPDocument.DCP;
import net.opengis.ows.x11.LanguageStringType;
import net.opengis.ows.x11.OperationDocument.Operation;
import net.opengis.ows.x11.RequestMethodType;
import net.opengis.wps.x100.CapabilitiesDocument;
import net.opengis.wps.x100.ProcessBriefType;
import net.opengis.wps.x100.ProcessDescriptionType;
import net.opengis.wps.x100.ProcessOfferingsDocument.ProcessOfferings;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.n52.wps.commons.WPSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
/**
* Encapsulation of the WPS Capabilities document. This class has to be initialized with either a
* {@linkplain #getInstance(java.io.File) file}, {@linkplain #getInstance(java.net.URL) URL},
* {@linkplain #getInstance(java.lang.String) path} or
* {@linkplain #getInstance(net.opengis.wps.x100.CapabilitiesDocument) instance}.
*
* @author foerster
* @author Christian Autermann
*
*/
public class CapabilitiesConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(CapabilitiesConfiguration.class);
private static final ReentrantLock lock = new ReentrantLock();
private static CapabilitiesDocument capabilitiesDocumentObj;
private static CapabilitiesSkeletonLoadingStrategy loadingStrategy;
public static String ENDPOINT_URL;
private CapabilitiesConfiguration() {
/* nothing here */
}
/**
* Gets the WPS Capabilities using the specified file to obtain the skeleton. All future calls to
* {@link #getInstance()} and {@link #getInstance(boolean)
* } will use this file to obtain the skeleton.
*
* @param filePath
* the File pointing to a skeleton
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static CapabilitiesDocument getInstance(String filePath) throws XmlException, IOException {
return getInstance(new FileLoadingStrategy(filePath));
}
/**
* Gets the WPS Capabilities using the specified file to obtain the skeleton. All future calls to
* {@link #getInstance()} and {@link #getInstance(boolean)
* } will use this file to obtain the skeleton.
*
* @param file
* the File pointing to a skeleton
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static CapabilitiesDocument getInstance(File file) throws XmlException, IOException {
return getInstance(new FileLoadingStrategy(file));
}
/**
* Gets the WPS Capabilities using the specified URL to obtain the skeleton. All future calls to
* {@link #getInstance()} and {@link #getInstance(boolean)
* } will use this URL to obtain the skeleton.
*
* @param url
* the URL pointing to a skeleton
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static CapabilitiesDocument getInstance(URL url) throws XmlException, IOException {
return getInstance(new URLLoadingStrategy(url));
}
/**
* Gets the WPS Capabilities using the specified skeleton. All future calls to {@link #getInstance()} and
* {@link #getInstance(boolean) } will use this skeleton.
*
* @param skel
* the skeleton
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static CapabilitiesDocument getInstance(CapabilitiesDocument skel) throws XmlException, IOException {
return getInstance(new InstanceStrategy(skel));
}
/**
* Gets the WPS Capabilities using the specified strategy. All future calls to {@link #getInstance()} and
* {@link #getInstance(boolean) } will use this strategy.
*
* @param strategy
* the strategy to load the skeleton
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
private static CapabilitiesDocument getInstance(CapabilitiesSkeletonLoadingStrategy strategy) throws XmlException,
IOException {
Preconditions.checkNotNull(strategy);
lock.lock();
try {
if (strategy.equals(loadingStrategy)) {
return getInstance(false);
}
else {
loadingStrategy = strategy;
return getInstance(true);
}
}
finally {
lock.unlock();
}
}
/**
* Get the WPS Capabilities for this service. The capabilities are reloaded if caching is not enabled in
* the WPS configuration.
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static CapabilitiesDocument getInstance() throws XmlException, IOException {
return getInstance( !WPSConfig.getInstance().getWPSConfig().getServer().getCacheCapabilites());
}
/**
* Get the WPS Capabilities for this service and optionally force a reload.
*
* @param reload
* if the capabilities should be reloaded
*
* @return the capabilities document
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static CapabilitiesDocument getInstance(boolean reload) throws XmlException, IOException {
lock.lock();
try {
if (capabilitiesDocumentObj == null || reload) {
capabilitiesDocumentObj = loadingStrategy.loadSkeleton();
initSkeleton(capabilitiesDocumentObj);
}
return capabilitiesDocumentObj;
}
finally {
lock.unlock();
}
}
/**
* Enriches a capabilities skeleton by adding the endpoint URL and creating the process offerings.
*
* @param skel
* the skeleton to enrich
*
* @throws UnknownHostException
* if the local host name can not be obtained
*/
private static void initSkeleton(CapabilitiesDocument skel) throws UnknownHostException {
ENDPOINT_URL = WPSConfig.getServerBaseURL() + "/" + WebProcessingService.SERVLET_PATH;
if (skel.getCapabilities() == null) {
skel.addNewCapabilities();
}
initOperationsMetadata(skel, ENDPOINT_URL);
initProcessOfferings(skel);
}
/**
* Enriches the capabilities skeleton by creating the process offerings.
*
* @param skel
* the skeleton to enrich
*/
private static void initProcessOfferings(CapabilitiesDocument skel) {
ProcessOfferings processes = skel.getCapabilities()
.addNewProcessOfferings();
for (String algorithmName : RepositoryManager.getInstance()
.getAlgorithms()) {
try {
ProcessDescriptionType description = RepositoryManager
.getInstance().getProcessDescription(algorithmName);
if (description != null) {
ProcessBriefType process = processes.addNewProcess();
CodeType ct = process.addNewIdentifier();
ct.setStringValue(algorithmName);
LanguageStringType title = description.getTitle();
String processVersion = description.getProcessVersion();
process.setProcessVersion(processVersion);
process.setTitle(title);
}
}
catch (RuntimeException e) {
LOG.warn("Exception during instantiation of process {}", algorithmName, e);
}
}
}
/**
* Enriches a capabilities skeleton by adding the endpoint URL to the operations meta data.
*
* @param skel
* the skeleton to enrich
* @param endpointUrl
* the endpoint URL of the service
*
*/
private static void initOperationsMetadata(CapabilitiesDocument skel, String endpointUrl) {
if (skel.getCapabilities().getOperationsMetadata() != null) {
String endpointUrlGet = endpointUrl + "?";
for (Operation op : skel.getCapabilities().getOperationsMetadata().getOperationArray()) {
for (DCP dcp : op.getDCPArray()) {
for (RequestMethodType get : dcp.getHTTP().getGetArray()) {
get.setHref(endpointUrlGet);
}
for (RequestMethodType post : dcp.getHTTP().getPostArray()) {
post.setHref(endpointUrl);
}
}
}
}
}
/**
* Force a reload of the capabilities skeleton.
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
public static void reloadSkeleton() throws XmlException, IOException {
getInstance(true);
}
/**
* Checks if the capabilities document is loaded.
*
* @return if the capabilities are ready.
*/
public static boolean ready() {
lock.lock();
try {
return capabilitiesDocumentObj != null;
}
finally {
lock.unlock();
}
}
/**
* Strategy to load a capabilities skeleton from a URL.
*/
private static class URLLoadingStrategy implements CapabilitiesSkeletonLoadingStrategy {
private final URL url;
/**
* Creates a new strategy using the specified URL.
*
* @param file
* the file
*/
URLLoadingStrategy(URL url) {
this.url = Preconditions.checkNotNull(url);
}
@Override
public CapabilitiesDocument loadSkeleton() throws XmlException, IOException {
XmlOptions options = new XmlOptions().setLoadStripComments();
return CapabilitiesDocument.Factory.parse(getUrl(), options);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof URLLoadingStrategy) {
URLLoadingStrategy that = (URLLoadingStrategy) obj;
return this.getUrl().equals(that.getUrl());
}
return false;
}
@Override
public int hashCode() {
return getUrl().hashCode();
}
/**
* Gets the URL of this strategy.
*
* @return the URL;
*/
public URL getUrl() {
return url;
}
}
/**
* Strategy to load a capabilities skeleton from a file.
*/
private static class FileLoadingStrategy extends URLLoadingStrategy {
/**
* Creates a new strategy using the specified file.
*
* @param file
* the file
*/
FileLoadingStrategy(File file) throws MalformedURLException {
super(file.toURI().toURL());
}
/**
* Creates a new strategy using the specified file.
*
* @param file
* the path to the file
*/
FileLoadingStrategy(String file) throws MalformedURLException {
this(new File(Preconditions.checkNotNull(file)));
}
}
/**
* Strategy to obtain the capabilities skeleton from an existing instance.
*/
private static class InstanceStrategy implements CapabilitiesSkeletonLoadingStrategy {
private final CapabilitiesDocument instance;
/**
* Creates a new strategy using the specified instance.
*
* @param instance
* the instance
*/
InstanceStrategy(CapabilitiesDocument instance) {
this.instance = Preconditions.checkNotNull(instance);
}
@Override
public CapabilitiesDocument loadSkeleton() {
return (CapabilitiesDocument) getInstance().copy();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof InstanceStrategy) {
InstanceStrategy that = (InstanceStrategy) obj;
return this.getInstance().equals(that.getInstance());
}
return false;
}
@Override
public int hashCode() {
return getInstance().hashCode();
}
/**
* Gets the instance of this strategy.
*
* @return the instance
*/
public CapabilitiesDocument getInstance() {
return instance;
}
}
/**
* Strategy to load a capabilities skeleton.
*/
private interface CapabilitiesSkeletonLoadingStrategy {
/**
* Loads a CapabilitiesDocument skeleton. Every call to this method should return another instance.
*
* @return the capabilities skeleton
*
* @throws XmlException
* if the Capabilities skeleton is not valid
* @throws IOException
* if an IO error occurs
*/
CapabilitiesDocument loadSkeleton() throws XmlException, IOException;
}
}

View File

@ -0,0 +1,223 @@
/**
* 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;
// import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.wps.io.LargeBufferStream;
class ResponseSizeInfoStream extends ServletOutputStream {
private OutputStream intStream;
private LargeBufferStream baStream;
private boolean closed = false;
private long streamSize = 0;
public ResponseSizeInfoStream(OutputStream outStream) {
this.intStream = outStream;
// baStream = new ByteArrayOutputStream();
}
public void write(int i) throws java.io.IOException {
this.streamSize++;
this.intStream.write(i);
}
public void close() throws java.io.IOException {
if (!this.closed) {
this.intStream.close();
this.closed = true;
}
}
/* public void flush() throws java.io.IOException {
if (baStream.size() != 0) {
if (! closed) {
// processStream(); // need to synchronize the flush!
// baStream = new ByteArrayOutputStream();
}
}
}
*/
public void processStream() throws java.io.IOException {
baStream.close();
baStream.writeTo(intStream);
this.intStream.flush();
}
public byte [] countBytes(byte [] inBytes) {
//streamSize = streamSize + inBytes.length;
return inBytes;
}
public long getSize() {
if(this.closed) {
return streamSize;
} else
return -1;
}
}
class ResponseSizeInfoWrapper extends HttpServletResponseWrapper {
private PrintWriter tpWriter;
private ResponseSizeInfoStream tpStream;
public ResponseSizeInfoWrapper(ServletResponse inResp) throws java.io.IOException {
super((HttpServletResponse) inResp);
tpStream = new ResponseSizeInfoStream(inResp.getOutputStream());
tpWriter = new PrintWriter(tpStream);
}
public ServletOutputStream getOutputStream() throws java.io.IOException {
return tpStream;
}
public PrintWriter getWriter() throws java.io.IOException {
return tpWriter;
}
}
class RequestSizeInfoStream extends ServletInputStream {
// private BufferedInputStream buStream;
private boolean closed = false;
private long streamSize = 0;
private InputStream inputStream;
public RequestSizeInfoStream(InputStream inStream) {
this.inputStream = inStream;
// buStream = new BufferedInputStream(inStream);
}
@Override
public int read() throws IOException {
this.streamSize++;
return this.inputStream.read();
}
public void close() throws java.io.IOException {
if (!this.closed) {
// processStream();
this.inputStream.close();
this.closed = true;
}
}
/* public void processStream() throws IOException {
byte[] bytes = new byte[8096];
int length = buStream.read(bytes, 0 , 8096);
while(length != -1) {
length = buStream.read(bytes, 0 , 8096);
streamSize = streamSize + length;
}
}*/
public long getSize() {
if(this.closed) {
return this.streamSize;
}
else
return -1;
}
}
class RequestSizeInfoWrapper extends HttpServletRequestWrapper {
private BufferedReader tpReader;
private RequestSizeInfoStream tpStream;
public RequestSizeInfoWrapper(ServletRequest req) throws java.io.IOException {
super((HttpServletRequest) req);
this.tpStream = new RequestSizeInfoStream(req.getInputStream());
this.tpReader = new BufferedReader(new InputStreamReader(this.tpStream));
}
public ServletInputStream getInputStream() throws java.io.IOException {
return this.tpStream;
}
public BufferedReader getReader() throws IOException {
return this.tpReader;
}
}
/** This class measures the payload of the post data
*
* @author foerster
*
*/
public final class CommunicationSizeLogFilter implements Filter {
private static Logger LOGGER = LoggerFactory.getLogger(CommunicationSizeLogFilter.class);
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
RequestSizeInfoWrapper myWrappedReq = new RequestSizeInfoWrapper(request);
ResponseSizeInfoWrapper myWrappedResp = new ResponseSizeInfoWrapper(response);
chain.doFilter(myWrappedReq, myWrappedResp);
myWrappedReq.getInputStream().close();
myWrappedResp.getOutputStream().close();
long requestSize = ((RequestSizeInfoStream)myWrappedReq.getInputStream()).getSize();
long responseSize = ((ResponseSizeInfoStream)myWrappedResp.getOutputStream()).getSize();
if(requestSize == 0) {
return;
}
BigDecimal result = new BigDecimal((double)responseSize/(double)requestSize).setScale(4, BigDecimal.ROUND_HALF_UP);
result = result.movePointRight(2);
LOGGER.info("Simplification ratio " + result);
}
public void destroy() {
}
public void init(FilterConfig filterConfig) {
}
}

View File

@ -0,0 +1,103 @@
/**
* 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;
import java.util.ArrayList;
/**
* @author Matthias Mueller, TU Dresden
*
*/
public class ProcessIDRegistry {
private static ProcessIDRegistry instance = new ProcessIDRegistry();
private volatile boolean lock = false;
private static ArrayList<String> idList = new ArrayList<String>();
private ProcessIDRegistry(){
//empty private constructor
}
public static ProcessIDRegistry getInstance(){
return instance;
}
public boolean addID(String id){
while (lock){
//spin
}
try{
lock = true;
boolean retval = idList.add(id);
lock = false;
return retval;
}
finally{
lock = false;
}
}
public synchronized boolean removeID(String id){
while (lock){
//spin
}
try{
lock = true;
boolean retval = idList.remove(id);
lock = false;
return retval;
}
finally{
lock = false;
}
}
public boolean containsID(String id){
return idList.contains(id);
}
public String[] getIDs(){
return idList.toArray(new String[idList.size()]);
}
protected void clearRegistry(){
while (lock){
//spin
}
try{
lock = true;
idList.clear();
lock = false;
}
finally{
lock = false;
}
}
}

View File

@ -0,0 +1,345 @@
/**
* 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;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.n52.wps.PropertyDocument.Property;
import org.n52.wps.RepositoryDocument.Repository;
import org.n52.wps.commons.WPSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Bastian Schaeffer, University of Muenster
*
*/
public class RepositoryManager {
private static RepositoryManager instance;
private static Logger LOGGER = LoggerFactory.getLogger(RepositoryManager.class);
private List<IAlgorithmRepository> repositories;
private ProcessIDRegistry globalProcessIDs = ProcessIDRegistry.getInstance();
private UpdateThread updateThread;
private RepositoryManager(){
// clear registry
globalProcessIDs.clearRegistry();
// initialize all Repositories
loadAllRepositories();
// FvK: added Property Change Listener support
// creates listener and register it to the wpsConfig instance.
WPSConfig.getInstance().addPropertyChangeListener(WPSConfig.WPSCONFIG_PROPERTY_EVENT_NAME, new PropertyChangeListener() {
public void propertyChange(
final PropertyChangeEvent propertyChangeEvent) {
LOGGER.info("Received Property Change Event: {}",
propertyChangeEvent.getPropertyName());
loadAllRepositories();
}
});
Double updateHours = WPSConfig.getInstance().getWPSConfig().getServer().getRepoReloadInterval();
if (updateHours != 0){
LOGGER.info("Setting repository update period to {} hours.", updateHours);
updateHours = updateHours * 3600 * 1000; // make milliseconds
long updateInterval = updateHours.longValue();
this.updateThread = new UpdateThread(updateInterval);
updateThread.start();
}
}
private void loadAllRepositories(){
repositories = new ArrayList<IAlgorithmRepository>();
LOGGER.debug("Loading all repositories: {} (doing a gc beforehand...)", repositories);
System.gc();
Repository[] repositoryList = WPSConfig.getInstance().getRegisterdAlgorithmRepositories();
for(Repository repository : repositoryList){
if(repository.getActive()==false){
continue;
}
String repositoryClassName = repository.getClassName();
try {
IAlgorithmRepository algorithmRepository = null;
Class repositoryClass = RepositoryManager.class.getClassLoader().loadClass(repositoryClassName);
Constructor[] constructors = repositoryClass.getConstructors();
for(Constructor constructor : constructors){
if(constructor.getParameterTypes().length==1 && constructor.getParameterTypes()[0].equals(String.class)){
Property[] properties = repository.getPropertyArray();
Property formatProperty = WPSConfig.getInstance().getPropertyForKey(properties, "supportedFormat");
String format = formatProperty.getStringValue();
algorithmRepository = (IAlgorithmRepository) repositoryClass.getConstructor(String.class).newInstance(format);
}else{
algorithmRepository = (IAlgorithmRepository) repositoryClass.newInstance();
}
}
repositories.add(algorithmRepository);
LOGGER.info("Algorithm Repository {} initialized", repositoryClassName);
} catch (InstantiationException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}", repositoryClassName);
} catch (IllegalAccessException e) {
//in case of an singleton
// try {
//
// IAlgorithmRepository algorithmRepository = (IAlgorithmRepository)RepositoryManager.class.getClassLoader().loadClass(repositoryClassName).getMethod("getInstance", new Class[0]).invoke(null, new Object[0]);
// repositories.add(algorithmRepository);
// } catch (IllegalArgumentException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (SecurityException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (IllegalAccessException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (InvocationTargetException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (NoSuchMethodException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// } catch (ClassNotFoundException e1) {
// LOGGER.warn("An error occured while registering AlgorithmRepository: " + repositoryClassName);
// }
LOGGER.warn("An error occured while registering AlgorithmRepository: {}", repositoryClassName);
} catch (ClassNotFoundException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (IllegalArgumentException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (SecurityException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (InvocationTargetException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
} catch (NoSuchMethodException e) {
LOGGER.warn("An error occured while registering AlgorithmRepository: {}",
repositoryClassName,
e.getMessage());
}
}
}
public static RepositoryManager getInstance(){
if(instance==null){
instance = new RepositoryManager();
}
return instance;
}
/**
* Allows to reInitialize the RepositoryManager... This should not be called to often.
*
*/
public static void reInitialize() {
instance = new RepositoryManager();
}
/**
* Allows to reInitialize the Repositories
*
*/
protected void reloadRepositories() {
loadAllRepositories();
}
/**
* Methods looks for Algorithm in all Repositories.
* The first match is returned.
* If no match could be found, null is returned
*
* @param className
* @return IAlgorithm or null
* @throws Exception
*/
public IAlgorithm getAlgorithm(String className){
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(className)){
return repository.getAlgorithm(className);
}
}
return null;
}
/**
*
* @return allAlgorithms
*/
public List<String> getAlgorithms(){
List<String> allAlgorithmNamesCollection = new ArrayList<String>();
for(IAlgorithmRepository repository : repositories){
allAlgorithmNamesCollection.addAll(repository.getAlgorithmNames());
}
return allAlgorithmNamesCollection;
}
public boolean containsAlgorithm(String algorithmName) {
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(algorithmName)){
return true;
}
}
return false;
}
public IAlgorithmRepository getRepositoryForAlgorithm(String algorithmName){
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(algorithmName)){
return repository;
}
}
return null;
}
public Class getInputDataTypeForAlgorithm(String algorithmIdentifier, String inputIdentifier){
IAlgorithm algorithm = getAlgorithm(algorithmIdentifier);
return algorithm.getInputDataType(inputIdentifier);
}
public Class getOutputDataTypeForAlgorithm(String algorithmIdentifier, String inputIdentifier){
IAlgorithm algorithm = getAlgorithm(algorithmIdentifier);
return algorithm.getOutputDataType(inputIdentifier);
}
public boolean registerAlgorithm(String id, IAlgorithmRepository repository){
if (globalProcessIDs.addID(id)){
return true;
}
else return false;
}
public boolean unregisterAlgorithm(String id){
if (globalProcessIDs.removeID(id)){
return true;
}
else return false;
}
public IAlgorithmRepository getAlgorithmRepository(String name){
for (IAlgorithmRepository repo : repositories ){
if(repo.getClass().getName().equals(name)){
return repo;
}
}
return null;
}
public IAlgorithmRepository getRepositoryForClassName(
String className) {
for(IAlgorithmRepository repository : repositories){
if(repository.getClass().getName().equals(className)){
return repository;
}
}
return null;
}
public ProcessDescriptionType getProcessDescription(String processClassName){
for(IAlgorithmRepository repository : repositories){
if(repository.containsAlgorithm(processClassName)){
return repository.getProcessDescription(processClassName);
}
}
return null;
}
static class UpdateThread extends Thread {
private final long interval;
private boolean firstrun = true;
public UpdateThread (long interval){
this.interval = interval;
}
@Override
public void run() {
LOGGER.debug("UpdateThread started");
try {
// never terminate the run method
while (true){
// do not update on first run!
if (!firstrun){
LOGGER.info("Reloading repositories - this might take a while ...");
long timestamp = System.currentTimeMillis();
RepositoryManager.getInstance().reloadRepositories();
LOGGER.info("Repositories reloaded - going to sleep. Took {} seconds.",
(System.currentTimeMillis() - timestamp) / 1000);
} else {
firstrun = false;
}
// sleep for a given INTERVAL
sleep(interval);
}
} catch (InterruptedException e) {
LOGGER.debug("Interrupt received - Terminating the UpdateThread.");
}
}
}
// shut down the update thread
public void finalize(){
if (updateThread != null){
updateThread.interrupt();
}
}
public void shutdown() {
LOGGER.debug("Shutting down all repositories..");
for (IAlgorithmRepository repo : repositories) {
repo.shutdown();
}
}
}

View File

@ -0,0 +1,233 @@
/**
* 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;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.n52.wps.PropertyDocument.Property;
import org.n52.wps.ServerDocument.Server;
import org.n52.wps.commons.WPSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author tkunicki
*/
public class ResponseURLFilter implements Filter {
private final static Logger LOGGER = LoggerFactory.getLogger(ResponseURLFilter.class);
public final static String PROP_responseURLFilterEnabled = "responseURLFilterEnabled";
private String configURLString;
private boolean enabled;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Server server = WPSConfig.getInstance().getWPSConfig().getServer();
// Build URL from WPS configuration. This is the
// hardcoded URL that we expect to see in reponses and would like to
// replace with the URL from the HTTP request.
configURLString = server.getProtocol() + "://" +
server.getHostname() + ":" +
server.getHostport() + "/" +
server.getWebappPath();
// Is filtering enabled in WPS configuration?
Property[] serverProperties = server.getPropertyArray();
for (Property serverProperty : serverProperties) {
if (/* serverProperty.getActive() && */ PROP_responseURLFilterEnabled.equals(serverProperty.getName())) {
enabled = Boolean.parseBoolean(serverProperty.getStringValue());
}
}
if (enabled) {
LOGGER.info("Response URL filtering enabled using base URL of {}", configURLString);
} else {
LOGGER.info("Response URL filtering disabled.");
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest requestHTTP = (request instanceof HttpServletRequest) ?
(HttpServletRequest) request : null;
HttpServletResponse responseHTTP = (response instanceof HttpServletResponse) ?
(HttpServletResponse) response : null;
if (enabled && requestHTTP != null && responseHTTP != null) {
String requestURLString = extractRequestURLString(requestHTTP);
// extract servlet path from request URL
String baseURLString = requestURLString.replaceAll("/[^/]*$", "");
LOGGER.info("Wrapping response for URL filtering");
chain.doFilter(request, new BaseURLFilterHttpServletResponse(
responseHTTP, configURLString, baseURLString));
} else {
LOGGER.warn("Unable to to wrap response for URL filtering");
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
// nothing to do yet
}
protected static String extractRequestURLString(HttpServletRequest request) {
return request.getRequestURL().toString();
}
private static class BaseURLFilterHttpServletResponse extends HttpServletResponseWrapper {
private final String configURLString;
public final String requestURLString;
public BaseURLFilterHttpServletResponse(HttpServletResponse response, String configURLString, String requestURLString) {
super(response);
this.configURLString = configURLString;
this.requestURLString = requestURLString;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
String contentType = getResponse().getContentType();
if (contentType == null || contentType.startsWith("text/xml") || contentType.startsWith("application/xml")) {
LOGGER.info("Content-type: {}, response URL filtering enabled for response to {}", contentType, requestURLString);
return new ServletOutputStreamWrapper(
getResponse().getOutputStream(),
configURLString,
requestURLString);
} else {
LOGGER.info("Content-type: {}, response URL filtering disabled for response to {}", contentType, requestURLString);
return getResponse().getOutputStream();
}
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(getOutputStream());
}
}
private static class ServletOutputStreamWrapper extends ServletOutputStream {
private final ServletOutputStream outputStream;
private ByteBuffer find;
private ByteBuffer replace;
private boolean match;
public ServletOutputStreamWrapper(ServletOutputStream outputStream, String find, String replace) {
this.outputStream = outputStream;
this.find = ByteBuffer.wrap(find.getBytes());
this.replace = ByteBuffer.wrap(replace.getBytes());
}
@Override
public void write(int i) throws IOException {
byte b = (byte)(i & 0xff);
if (match) {
if(find.get() == b) {
if (!find.hasRemaining()) {
// COMPLETE MATCH
// 1) write out replacement buffer
// 2) unset 'match' flag
outputStream.write(replace.array());
match = false;
} // else { /* POTENTIAL MATCH ongoing, writes deferred */ }
} else {
// FAILED MATCH
// 1) write out portion of 'find' buffer that matched
// 2) write out the current byte that caused mismatch
// 3) unset 'match' flag
outputStream.write(find.array(), 0, find.position() - 1);
outputStream.write(b);
match = false;
}
} else {
if (b == find.get(0)) {
// POTENTIAL MATCH started, write deferred
// - set 'match' flag to true for next write call
// - position 'find' buffer at next byte for next check
match = true;
find.position(1);
} else {
// NO MATCH, just pass byte through to underlying outputstream
outputStream.write(b);
}
}
}
@Override
public void write(byte[] bytes) throws IOException {
write(bytes, 0, bytes.length);
}
@Override
public void write(byte[] b, int o, int l) throws IOException {
for (int i = 0; i < l; ++i) { write(b[o + i]); }
}
@Override
public void close() throws IOException {
if (match) {
// FAILED MATCH, complete deferred writes
outputStream.write(find.array(), 0, find.position());
match = false;
}
super.close();
outputStream.close();
}
@Override
public void flush() throws IOException {
super.flush();
outputStream.flush();
}
}
}

View File

@ -0,0 +1,260 @@
/**
* 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;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.UUID;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.n52.wps.server.database.DatabaseFactory;
import org.n52.wps.server.database.IDatabase;
import org.n52.wps.commons.MIMEUtil;
import org.n52.wps.commons.XMLUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RetrieveResultServlet extends HttpServlet {
private final static Logger LOGGER = LoggerFactory.getLogger(RetrieveResultServlet.class);
private static final long serialVersionUID = -268198171054599696L;
// This is required for URL generation for response documents.
public final static String SERVLET_PATH = "RetrieveResultServlet";
// in future parameterize
private final boolean indentXML = false;
private final int uuid_length = 36;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// id of result to retrieve.
String id = request.getParameter("id");
// optional alternate name for filename (rename the file when retrieving
// if requested)
boolean altName = false;
String alternateFilename = request.getParameter("filename");
if (!StringUtils.isEmpty(alternateFilename)) {
altName = true;
}
// return result as attachment (instructs browser to offer user "Save" dialog)
String attachment = request.getParameter("attachment");
if (StringUtils.isEmpty(id)) {
errorResponse("id parameter missing", response);
} else {
if(!isIDValid(id)){
errorResponse("id parameter not valid", response);
}
IDatabase db = DatabaseFactory.getDatabase();
String mimeType = db.getMimeTypeForStoreResponse(id);
long contentLength = db.getContentLengthForStoreResponse(id);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = db.lookupResponse(id);
if (inputStream == null) {
errorResponse("id " + id + " is unknown to server", response);
} else if (mimeType == null) {
errorResponse("Unable to determine mime-type for id " + id, response);
} else {
String suffix = MIMEUtil.getSuffixFromMIMEType(mimeType).toLowerCase();
// if attachment parameter unset, default to false for mime-type of 'xml' and true for everything else.
boolean useAttachment = (StringUtils.isEmpty(attachment) && !"xml".equals(suffix)) || Boolean.parseBoolean(attachment);
if (useAttachment) {
String attachmentName = (new StringBuilder(id)).append('.').append(suffix).toString();
if (altName) {
attachmentName = (new StringBuilder(alternateFilename)).append('.').append(suffix).toString();
}
response.addHeader("Content-Disposition", "attachment; filename=\"" + attachmentName + "\"");
}
response.setContentType(mimeType);
if ("xml".equals(suffix)) {
// NOTE: We don't set "Content-Length" header, xml may be modified
// need these to work around aggressive IE 8 caching.
response.addHeader("Cache-Control", "no-cache, no-store");
response.addHeader("Pragma", "no-cache");
response.addHeader("Expires", "-1");
try {
outputStream = response.getOutputStream();
} catch (IOException e) {
throw new IOException("Error obtaining output stream for response", e);
}
copyResponseAsXML(inputStream, outputStream, useAttachment || indentXML, id);
} else {
if (contentLength > -1) {
// Can't use response.setContentLength(...) as it accepts an int (max of 2^31 - 1) ?!
// response.setContentLength(contentLength);
response.setHeader("Content-Length", Long.toString(contentLength));
} else {
LOGGER.warn("Content-Length unknown for response to id {}", id);
}
try {
outputStream = response.getOutputStream();
} catch (IOException e) {
throw new IOException("Error obtaining output stream for response", e);
}
copyResponseStream(inputStream, outputStream, id, contentLength);
}
}
} catch (Exception e) {
logException(e);
} finally {
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
}
}
}
protected void errorResponse(String error, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
PrintWriter writer = response.getWriter();
writer.write("<html><title>Error</title><body>" + error + "</body></html>");
writer.flush();
LOGGER.warn("Error processing response: " + error);
}
protected void copyResponseStream(
InputStream inputStream,
OutputStream outputStream,
String id,
long contentLength) throws IOException {
long contentWritten = 0;
try {
byte[] buffer = new byte[8192];
int bufferRead;
while ((bufferRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bufferRead);
contentWritten += bufferRead;
}
} catch (IOException e) {
String exceptionMessage = contentLength > -1
? String.format("Error writing response to output stream for id %s, %d of %d bytes written", id, contentWritten, contentLength)
: String.format("Error writing response to output stream for id %s, %d bytes written", id, contentWritten);
throw new IOException(exceptionMessage, e);
}
LOGGER.info("{} bytes written in response to id {}", contentWritten, id);
}
protected void copyResponseAsXML(
InputStream inputStream,
OutputStream outputStream,
boolean indent,
String id) throws IOException {
try {
XMLUtil.copyXML(inputStream, outputStream, indent);
} catch (IOException e) {
throw new IOException("Error writing XML response for id " + id, e);
}
}
private void logException(Exception exception) {
StringBuilder errorBuilder = new StringBuilder(exception.getMessage());
Throwable cause = getRootCause(exception);
if (cause != exception) {
errorBuilder.append(", exception message: ").append(cause.getMessage());
}
LOGGER.error(errorBuilder.toString());
}
public static Throwable getRootCause(Throwable t) {
return t.getCause() == null ? t : getRootCause(t.getCause());
}
public boolean isIDValid(String id){
if(id.length() <= uuid_length){
try {
UUID checkUUID = UUID.fromString(id);
if(checkUUID.toString().equals(id)){
return true;
}else{
return false;
}
} catch (Exception e) {
return false;
}
}else {
String uuidPartOne = id.substring(0, uuid_length);
String uuidPartTwo = id.substring(id.length() - uuid_length, id.length());
return isUUIDValid(uuidPartOne) && isUUIDValid(uuidPartTwo);
}
}
public boolean isUUIDValid(String uuid) {
// the following can be used to check whether the id is a valid UUID
try {
UUID checkUUID = UUID.fromString(uuid);
if (checkUUID.toString().equals(uuid)) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
}

View File

@ -0,0 +1,393 @@
/**
* 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;
// FvK: added Property Change Listener support
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.URLDecoder;
import java.util.Map;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.xmlbeans.XmlException;
import org.n52.wps.GeneratorDocument.Generator;
import org.n52.wps.ParserDocument.Parser;
import org.n52.wps.PropertyDocument.Property;
import org.n52.wps.commons.WPSConfig;
import org.n52.wps.io.GeneratorFactory;
import org.n52.wps.io.ParserFactory;
import org.n52.wps.server.database.DatabaseFactory;
import org.n52.wps.server.handler.RequestHandler;
import org.n52.wps.util.XMLBeansHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This WPS supports HTTP GET for describeProcess and getCapabilities and XML-POST for execute.
*
* @author foerster
*
*/
public class WebProcessingService extends HttpServlet {
// Universal version identifier for a Serializable class.
// Should be used here, because HttpServlet implements the java.io.Serializable
private static final long serialVersionUID = 8943233273641771839L;
public static String PROPERTY_NAME_WEBAPP_PATH = "webappPath";
public static String BASE_DIR = null;
public static String WEBAPP_PATH = null;
public static String SERVLET_PATH = "WebProcessingService";
public static String WPS_NAMESPACE = "http://www.opengis.net/wps/1.0.0";
public static String DEFAULT_LANGUAGE = "en-US";
protected static Logger LOGGER = LoggerFactory.getLogger(WebProcessingService.class);
public final static String PROP_forceGeoToolsXYAxisOrder = "forceGeoToolsXYAxisOrder";
/**
*
* Returns a preconfigured OutputStream It takes care of: - caching - content-Encoding
*
* @param hsRequest
* the HttpServletRequest
* @param hsResponse
* the HttpServlerResponse
* @return the preconfigured OutputStream
* @throws IOException
* a task of the tomcat
*/
private static OutputStream getConfiguredOutputStream(HttpServletRequest hsRequest, HttpServletResponse hsResponse) throws IOException {
/*
* Forbids clients to cache the response May solve problems with proxies and bad implementations
*/
hsResponse.setHeader("Expires", "0");
if (hsRequest.getProtocol().equals("HTTP/1.1")) {
hsResponse.setHeader("Cache-Control", "no-cache");
} else if (hsRequest.getProtocol().equals("HTTP/1.0")) {
hsResponse.setHeader("Pragma", "no-cache");
}
// Enable/disable gzip compression
if (hsRequest.getHeader("Accept-Encoding") != null
&& hsRequest.getHeader("Accept-Encoding").indexOf("gzip") >= 0) {
hsResponse.setHeader("Content-Encoding", "gzip");
LOGGER.info("gzip-Compression for output enabled");
return new GZIPOutputStream(hsResponse.getOutputStream());
} // else {
LOGGER.info("gzip-Compression for output disabled");
return hsResponse.getOutputStream();
// }
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
LOGGER.info("WebProcessingService initializing...");
try {
if (WPSConfig.getInstance(config) == null) {
LOGGER.error("Initialization failed! Please look at the properties file!");
return;
}
}
catch (Exception e) {
LOGGER.error("Initialization failed! Please look at the properties file!", e);
return;
}
LOGGER.info("Initialization of wps properties successful!");
Property[] serverProps = WPSConfig.getInstance().getPropertiesForServer();
for (Property property : serverProps) {
if(PROP_forceGeoToolsXYAxisOrder.equals(property.getName())){
if(Boolean.parseBoolean(property.getStringValue())){
// this is important to set the lon lat support for correct CRS transformation.
System.setProperty("org.geotools.referencing.forceXY", "true");
LOGGER.info("Set org.geotools.referencing.forceXY to true.");
}
break;
}
}
BASE_DIR = this.getServletContext().getRealPath("");
Parser[] parsers = WPSConfig.getInstance().getActiveRegisteredParser();
ParserFactory.initialize(parsers);
Generator[] generators = WPSConfig.getInstance().getActiveRegisteredGenerator();
GeneratorFactory.initialize(generators);
// call RepositoyManager to initialize
RepositoryManager.getInstance();
LOGGER.info("Algorithms initialized");
// String customWebappPath = WPSConfiguration.getInstance().getProperty(PROPERTY_NAME_WEBAPP_PATH);
String customWebappPath = WPSConfig.getInstance().getWPSConfig().getServer().getWebappPath();
if (customWebappPath != null) {
WEBAPP_PATH = customWebappPath;
}
else {
WEBAPP_PATH = "wps";
LOGGER.warn("No custom webapp path found, use default wps");
}
LOGGER.info("webappPath is set to: " + customWebappPath);
try {
CapabilitiesConfiguration.getInstance(BASE_DIR + File.separator + "config"
+ File.separator + "wpsCapabilitiesSkeleton.xml");
}
catch (IOException e) {
LOGGER.error("error while initializing capabilitiesConfiguration", e);
}
catch (XmlException e) {
LOGGER.error("error while initializing capabilitiesConfiguration", e);
}
// Get an instance of the database for initialization of the database
DatabaseFactory.getDatabase();
LOGGER.info("WPS up and running!");
// FvK: added Property Change Listener support
// creates listener and register it to the wpsConfig instance.
// it will listen to changes of the wpsCapabilities
WPSConfig.getInstance().addPropertyChangeListener(org.n52.wps.commons.WPSConfig.WPSCAPABILITIES_SKELETON_PROPERTY_EVENT_NAME,
new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent propertyChangeEvent) {
LOGGER.info(this.getClass().getName()
+ ": Received Property Change Event: "
+ propertyChangeEvent.getPropertyName());
try {
CapabilitiesConfiguration.reloadSkeleton();
}
catch (IOException e) {
LOGGER.error("error while initializing capabilitiesConfiguration",
e);
}
catch (XmlException e) {
LOGGER.error("error while initializing capabilitiesConfiguration",
e);
}
}
});
// FvK: added Property Change Listener support
// creates listener and register it to the wpsConfig instance.
// it will listen to changes of the wpsConfiguration
WPSConfig.getInstance().addPropertyChangeListener(org.n52.wps.commons.WPSConfig.WPSCONFIG_PROPERTY_EVENT_NAME,
new PropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent propertyChangeEvent) {
LOGGER.info(this.getClass().getName()
+ ": Received Property Change Event: "
+ propertyChangeEvent.getPropertyName());
try {
CapabilitiesConfiguration.reloadSkeleton();
}
catch (IOException e) {
LOGGER.error("error while initializing capabilitiesConfiguration",
e);
}
catch (XmlException e) {
LOGGER.error("error while initializing capabilitiesConfiguration",
e);
}
}
});
}
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
try {
@SuppressWarnings("resource")
OutputStream out = res.getOutputStream(); // closed by res.flushBuffer();
RequestHandler handler = new RequestHandler((Map<String, String[]>) req.getParameterMap(), out);
String mimeType = handler.getResponseMimeType();
res.setContentType(mimeType);
handler.handle();
res.setStatus(HttpServletResponse.SC_OK);
}
catch (ExceptionReport e) {
handleException(e, res);
}
catch (RuntimeException e) {
ExceptionReport er = new ExceptionReport("Error handing request: " + e.getMessage(),
ExceptionReport.NO_APPLICABLE_CODE,
e);
handleException(er, res);
}
finally {
if (res != null) {
res.flushBuffer();
}
// out.flush();
// out.close();
}
}
public final static int MAXIMUM_REQUEST_SIZE = 128 << 20;
public final static String SPECIAL_XML_POST_VARIABLE = "request";
private static final String XML_CONTENT_TYPE = "text/xml";
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
BufferedReader reader = null;
try {
String contentType = req.getContentType();
String characterEncoding = req.getCharacterEncoding();
if (characterEncoding == null || characterEncoding.length() == 0) {
characterEncoding = "UTF-8"; // default character encoding if unspecified
}
int contentLength = req.getContentLength();
if (contentLength > MAXIMUM_REQUEST_SIZE) {
LOGGER.warn("POST request rejected, request size of " + contentLength + " too large.");
ExceptionReport er = new ExceptionReport("Request body too large, limited to " + MAXIMUM_REQUEST_SIZE
+ " bytes", ExceptionReport.NO_APPLICABLE_CODE);
handleException(er, res);
}
LOGGER.debug("Received POST: Content-Type = " + contentType + ", Character-Encoding = " + characterEncoding
+ ", Content-Length = " + contentLength);
int requestSize = 0;
StringWriter writer = contentLength > 0 ? new StringWriter(contentLength) : new StringWriter();
reader = req.getReader();
char[] buffer = new char[8192];
int read;
while ( (read = reader.read(buffer)) != -1 && requestSize < MAXIMUM_REQUEST_SIZE) {
writer.write(buffer, 0, read);
requestSize += read;
}
LOGGER.debug("POST request contained " + requestSize + " characters");
// Protect against denial of service attacks.
if (requestSize >= MAXIMUM_REQUEST_SIZE && reader.read() > -1) {
LOGGER.warn("POST request rejected, request size of " + requestSize + " too large.");
ExceptionReport er = new ExceptionReport("Request body too large, limited to " + MAXIMUM_REQUEST_SIZE
+ " bytes", ExceptionReport.NO_APPLICABLE_CODE);
handleException(er, res);
}
String documentString = writer.toString();
// Perform URL decoding, if necessary
// if ("application/x-www-form-urlencoded".equals(contentType)) {
if ( (contentType).startsWith("application/x-www-form-urlencoded")) {
if (documentString.startsWith(SPECIAL_XML_POST_VARIABLE + "=")) {
// This is a hack to permit xml to be easily submitted via a form POST.
// By convention, we are allowing users to post xml if they name it
// with a POST parameter "request" although this is not
// valid per the specification.
documentString = documentString.substring(SPECIAL_XML_POST_VARIABLE.length() + 1);
LOGGER.debug("POST request form variable removed");
}
documentString = URLDecoder.decode(documentString, characterEncoding);
LOGGER.debug("Decoded of POST:\n" + documentString + "\n");
}
RequestHandler handler = new RequestHandler(new ByteArrayInputStream(documentString.getBytes("UTF-8")),
res.getOutputStream());
String mimeType = handler.getResponseMimeType();
res.setContentType(mimeType);
handler.handle();
res.setStatus(HttpServletResponse.SC_OK);
}
catch (ExceptionReport e) {
handleException(e, res);
}
catch (Exception e) {
ExceptionReport er = new ExceptionReport("Error handing request: " + e.getMessage(), ExceptionReport.NO_APPLICABLE_CODE, e);
handleException(er, res);
}
finally {
if (res != null) {
res.flushBuffer();
}
if (reader != null) {
reader.close();
}
}
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
if (SERVLET_PATH == null) {
req.getContextPath();
}
super.service(req, res);
}
private static void handleException(ExceptionReport exception, HttpServletResponse res) {
res.setContentType(XML_CONTENT_TYPE);
try {
LOGGER.debug(exception.toString());
// DO NOT MIX getWriter and getOuputStream!
exception.getExceptionDocument().save(res.getOutputStream(),
XMLBeansHelper.getXmlOptions());
res.setStatus(exception.getHTTPStatusCode());
}
catch (IOException e) {
LOGGER.warn("exception occured while writing ExceptionReport to stream");
try {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"error occured, while writing OWS Exception output");
}
catch (IOException ex) {
LOGGER.error("error while writing error code to client!");
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
}
@Override
public void destroy() {
super.destroy();
DatabaseFactory.getDatabase().shutdown();
}
}

View File

@ -0,0 +1,85 @@
/**
* 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.handler;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Map;
import org.n52.wps.io.data.IData;
import net.opengis.wps.x100.InputType;
/**
* For some algorithms it is needed to intercept
* the DataInputs before being processed. An algorithm
* should provide implementations of these through this
* interface and the corresponding annotation.
*
* @author matthes rieke
*
*/
public interface DataInputInterceptors {
/**
* @return a map where input identifiers are keys
*/
public Map<String, InterceptorInstance> getInterceptors();
public static interface InterceptorInstance {
/**
* applies the actual interception
* @param input the input as provided in the Execute request
*
* @return true if processed, this triggers a skip of parsing within the InputHandler
*/
public List<IData> applyInterception(InputType input);
}
/**
* Decorate your Algorithm implementation with this
* annotation. the value must be the fully qualified
* class name of the {@link DataInputInterceptors} implementation.
*
* @author matthes rieke
*
*/
@Retention(RetentionPolicy.RUNTIME)
public static @interface DataInputInterceptorImplementations {
String value();
}
}

View File

@ -0,0 +1,62 @@
/**
* 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.handler;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.n52.wps.ServerDocument.Server;
import org.n52.wps.commons.WPSConfig;
/**
* After the client Request is accepted, it should be executed. To prevent
* resource-exhaustion, this ThreadPoolExecutor stores the Requests in a queue,
* and handles only a couple of them at a time. To tune the performance one can
* alter the parameters of this pool.
*
* Proper pool size estimation: N = Number of processors WT = Average waiting
* time of a task ST = Average service time of a task #Threads = N * (1 + WT/ST)
*
* @author Timon ter Braak
*/
public class RequestExecutor extends ThreadPoolExecutor {
public static Server serverConfig = WPSConfig.getInstance().getWPSConfig().getServer();
/**
* Create a RequestExecutor.
*/
public RequestExecutor() {
super(serverConfig.getMinPoolSize().intValue(), serverConfig.getMaxPoolSize().intValue(), serverConfig.getKeepAliveSeconds().intValue(),
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(
serverConfig.getMaxQueuedTasks().intValue()));
}
}

View File

@ -0,0 +1,398 @@
/**
* 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.handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.WebProcessingService;
import org.n52.wps.server.request.CapabilitiesRequest;
import org.n52.wps.server.request.DescribeProcessRequest;
import org.n52.wps.server.request.ExecuteRequest;
import org.n52.wps.server.request.Request;
import org.n52.wps.server.request.RetrieveResultRequest;
import org.n52.wps.server.response.ExecuteResponse;
import org.n52.wps.server.response.Response;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
/**
* This class accepts client requests, determines its type and then schedules
* the {@link ExecuteRequest}'s for execution. The request is executed for a
* short time, within the client will be served with an immediate result. If the
* time runs out, the client will be served with a reference to the future
* result. The client can come back later to retrieve the result. Uses
* "computation_timeout_seconds" from wps.properties
*
* @author Timon ter Braak
*/
public class RequestHandler {
public static final String VERSION_ATTRIBUTE_NAME = "version";
/** Computation timeout in seconds */
protected static RequestExecutor pool = new RequestExecutor();
protected OutputStream os;
private static Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
protected String responseMimeType;
protected Request req;
// Empty constructor due to classes which extend the RequestHandler
protected RequestHandler() {
}
/**
* Handles requests of type HTTP_GET (currently capabilities and
* describeProcess). A Map is used to represent the client input.
*
* @param params
* The client input
* @param os
* The OutputStream to write the response to.
* @throws ExceptionReport
* If the requested operation is not supported
*/
public RequestHandler(Map<String, String[]> params, OutputStream os)
throws ExceptionReport {
this.os = os;
//sleepingTime is 0, by default.
/*if(WPSConfiguration.getInstance().exists(PROPERTY_NAME_COMPUTATION_TIMEOUT)) {
this.sleepingTime = Integer.parseInt(WPSConfiguration.getInstance().getProperty(PROPERTY_NAME_COMPUTATION_TIMEOUT));
}
String sleepTime = WPSConfig.getInstance().getWPSConfig().getServer().getComputationTimeoutMilliSeconds();
*/
Request req;
CaseInsensitiveMap ciMap = new CaseInsensitiveMap(params);
/*
* check if service parameter is present and equals "WPS"
* otherwise an ExceptionReport will be thrown
*/
String serviceType = Request.getMapValue("service", ciMap, true);
if(!serviceType.equalsIgnoreCase("WPS")){
throw new ExceptionReport("Parameter <service> is not correct, expected: WPS, got: " + serviceType,
ExceptionReport.INVALID_PARAMETER_VALUE, "service");
}
/*
* check language. if not supported, return ExceptionReport
* Fix for https://bugzilla.52north.org/show_bug.cgi?id=905
*/
String language = Request.getMapValue("language", ciMap, false);
if(language != null){
Request.checkLanguageSupported(language);
}
// get the request type
String requestType = Request.getMapValue("request", ciMap, true);
if (requestType.equalsIgnoreCase("GetCapabilities")) {
req = new CapabilitiesRequest(ciMap);
}
else if (requestType.equalsIgnoreCase("DescribeProcess")) {
req = new DescribeProcessRequest(ciMap);
}
else if (requestType.equalsIgnoreCase("Execute")) {
req = new ExecuteRequest(ciMap);
setResponseMimeType((ExecuteRequest)req);
}
else if (requestType.equalsIgnoreCase("RetrieveResult")) {
req = new RetrieveResultRequest(ciMap);
}
else {
throw new ExceptionReport(
"The requested Operation is not supported or not applicable to the specification: "
+ requestType,
ExceptionReport.OPERATION_NOT_SUPPORTED, requestType);
}
this.req = req;
}
/**
* Handles requests of type HTTP_POST (currently executeProcess). A Document
* is used to represent the client input. This Document must first be parsed
* from an InputStream.
*
* @param is
* The client input
* @param os
* The OutputStream to write the response to.
* @throws ExceptionReport
*/
public RequestHandler(InputStream is, OutputStream os)
throws ExceptionReport {
String nodeName, localName, nodeURI, version = null;
Document doc;
this.os = os;
boolean isCapabilitiesNode = false;
try {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
fac.setNamespaceAware(true);
// parse the InputStream to create a Document
doc = fac.newDocumentBuilder().parse(is);
// Get the first non-comment child.
Node child = doc.getFirstChild();
while(child.getNodeName().compareTo("#comment")==0) {
child = child.getNextSibling();
}
nodeName = child.getNodeName();
localName = child.getLocalName();
nodeURI = child.getNamespaceURI();
Node versionNode = child.getAttributes().getNamedItem("version");
/*
* check for service parameter. this has to be present for all requests
*/
Node serviceNode = child.getAttributes().getNamedItem("service");
if(serviceNode == null){
throw new ExceptionReport("Parameter <service> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE, "service");
}else{
if(!serviceNode.getNodeValue().equalsIgnoreCase("WPS")){
throw new ExceptionReport("Parameter <service> not specified.", ExceptionReport.INVALID_PARAMETER_VALUE, "service");
}
}
isCapabilitiesNode = nodeName.toLowerCase().contains("capabilities");
if(versionNode == null && !isCapabilitiesNode) {
throw new ExceptionReport("Parameter <version> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE, "version");
}
//TODO: I think this can be removed, as capabilities requests do not have a version parameter (BenjaminPross)
if(!isCapabilitiesNode){
// version = child.getFirstChild().getTextContent();//.getNextSibling().getFirstChild().getNextSibling().getFirstChild().getNodeValue();
version = child.getAttributes().getNamedItem("version").getNodeValue();
}
/*
* check language, if not supported, return ExceptionReport
* Fix for https://bugzilla.52north.org/show_bug.cgi?id=905
*/
Node languageNode = child.getAttributes().getNamedItem("language");
if(languageNode != null){
String language = languageNode.getNodeValue();
Request.checkLanguageSupported(language);
}
} catch (SAXException e) {
throw new ExceptionReport(
"There went something wrong with parsing the POST data: "
+ e.getMessage(),
ExceptionReport.NO_APPLICABLE_CODE, e);
} catch (IOException e) {
throw new ExceptionReport(
"There went something wrong with the network connection.",
ExceptionReport.NO_APPLICABLE_CODE, e);
} catch (ParserConfigurationException e) {
throw new ExceptionReport(
"There is a internal parser configuration error",
ExceptionReport.NO_APPLICABLE_CODE, e);
}
//Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
if(!isCapabilitiesNode && version == null) {
throw new ExceptionReport("Parameter <version> not specified." , ExceptionReport.MISSING_PARAMETER_VALUE, "version");
}
if(!isCapabilitiesNode && !version.equals(Request.SUPPORTED_VERSION)) {
throw new ExceptionReport("Version not supported." , ExceptionReport.INVALID_PARAMETER_VALUE, "version");
}
// get the request type
if (nodeURI.equals(WebProcessingService.WPS_NAMESPACE) && localName.equals("Execute")) {
req = new ExecuteRequest(doc);
setResponseMimeType((ExecuteRequest)req);
}else if (nodeURI.equals(WebProcessingService.WPS_NAMESPACE) && localName.equals("GetCapabilities")){
req = new CapabilitiesRequest(doc);
this.responseMimeType = "text/xml";
} else if (nodeURI.equals(WebProcessingService.WPS_NAMESPACE) && localName.equals("DescribeProcess")) {
req = new DescribeProcessRequest(doc);
this.responseMimeType = "text/xml";
} else if(!localName.equals("Execute")){
throw new ExceptionReport("The requested Operation not supported or not applicable to the specification: "
+ nodeName, ExceptionReport.OPERATION_NOT_SUPPORTED, localName);
}
else if(nodeURI.equals(WebProcessingService.WPS_NAMESPACE)) {
throw new ExceptionReport("specified namespace is not supported: "
+ nodeURI, ExceptionReport.INVALID_PARAMETER_VALUE);
}
}
/**
* Handle a request after its type is determined. The request is scheduled
* for execution. If the server has enough free resources, the client will
* be served immediately. If time runs out, the client will be asked to come
* back later with a reference to the result.
*
* @param req The request of the client.
* @throws ExceptionReport
*/
public void handle() throws ExceptionReport {
Response resp = null;
if(req ==null){
throw new ExceptionReport("Internal Error","");
}
if (req instanceof ExecuteRequest) {
// cast the request to an executerequest
ExecuteRequest execReq = (ExecuteRequest) req;
execReq.updateStatusAccepted();
ExceptionReport exceptionReport = null;
try {
if (execReq.isStoreResponse()) {
resp = new ExecuteResponse(execReq);
InputStream is = resp.getAsStream();
IOUtils.copy(is, os);
is.close();
pool.submit(execReq);
return;
}
try {
// retrieve status with timeout enabled
try {
resp = pool.submit(execReq).get();
}
catch (ExecutionException ee) {
LOGGER.warn("exception while handling ExecuteRequest.");
// the computation threw an error
// probably the client input is not valid
if (ee.getCause() instanceof ExceptionReport) {
exceptionReport = (ExceptionReport) ee
.getCause();
} else {
exceptionReport = new ExceptionReport(
"An error occurred in the computation: "
+ ee.getMessage(),
ExceptionReport.NO_APPLICABLE_CODE);
}
} catch (InterruptedException ie) {
LOGGER.warn("interrupted while handling ExecuteRequest.");
// interrupted while waiting in the queue
exceptionReport = new ExceptionReport(
"The computation in the process was interrupted.",
ExceptionReport.NO_APPLICABLE_CODE);
}
} finally {
if (exceptionReport != null) {
LOGGER.debug("ExceptionReport not null: " + exceptionReport.getMessage());
// NOT SURE, if this exceptionReport is also written to the DB, if required... test please!
throw exceptionReport;
}
// send the result to the outputstream of the client.
/* if(((ExecuteRequest) req).isQuickStatus()) {
resp = new ExecuteResponse(execReq);
}*/
else if(resp == null) {
LOGGER.warn("null response handling ExecuteRequest.");
throw new ExceptionReport("Problem with handling threads in RequestHandler", ExceptionReport.NO_APPLICABLE_CODE);
}
if(!execReq.isStoreResponse()) {
InputStream is = resp.getAsStream();
IOUtils.copy(is, os);
is.close();
LOGGER.info("Served ExecuteRequest.");
}
}
} catch (RejectedExecutionException ree) {
LOGGER.warn("exception handling ExecuteRequest.", ree);
// server too busy?
throw new ExceptionReport(
"The requested process was rejected. Maybe the server is flooded with requests.",
ExceptionReport.SERVER_BUSY);
} catch (Exception e) {
LOGGER.error("exception handling ExecuteRequest.", e);
if (e instanceof ExceptionReport) {
throw (ExceptionReport)e;
}
throw new ExceptionReport("Could not read from response stream.", ExceptionReport.NO_APPLICABLE_CODE);
}
} else {
// for GetCapabilities and DescribeProcess:
resp = req.call();
try {
InputStream is = resp.getAsStream();
IOUtils.copy(is, os);
is.close();
} catch (IOException e) {
throw new ExceptionReport("Could not read from response stream.", ExceptionReport.NO_APPLICABLE_CODE);
}
}
}
protected void setResponseMimeType(ExecuteRequest req) {
if(req.isRawData()){
responseMimeType = req.getExecuteResponseBuilder().getMimeType();
}else{
responseMimeType = "text/xml";
}
}
public String getResponseMimeType(){
if(responseMimeType == null){
return "text/xml";
}
return responseMimeType.toLowerCase();
}
}

View File

@ -0,0 +1,159 @@
/**
* 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.request;
import java.util.ArrayList;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.handler.RequestHandler;
import org.n52.wps.server.response.CapabilitiesResponse;
import org.n52.wps.server.response.Response;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Handles a CapabilitesRequest
*/
public class CapabilitiesRequest extends Request {
private static final String ACCEPT_VERSIONS_ELEMENT_NAME = "AcceptVersions";
private static final String PARAM_SERVICE = "service";
private static final String PARAM_VERSION = "version";
private static final Object REQUEST_DOC = "document";
/**
* Creates a CapabilitesRequest based on a Map (HTTP_GET)
*
* @param ciMap
* The client input
* @throws ExceptionReport
*/
public CapabilitiesRequest(CaseInsensitiveMap ciMap) throws ExceptionReport {
super(ciMap);
//Fix for https://bugzilla.52north.org/show_bug.cgi?id=907
String providedAcceptVersionsString = Request.getMapValue("acceptversions", ciMap, false);
if (providedAcceptVersionsString != null) {
String[] providedAcceptVersions = providedAcceptVersionsString.split(",");
if (providedAcceptVersions != null) {
map.put("version", providedAcceptVersions);
}
}
}
public CapabilitiesRequest(Document doc) throws ExceptionReport {
super(doc);
this.map = new CaseInsensitiveMap();
Node fc = this.doc.getFirstChild();
String name = fc.getNodeName();
this.map.put(REQUEST_DOC, name);
Node serviceItem = fc.getAttributes().getNamedItem("service");
if (serviceItem != null) {
String service = serviceItem.getNodeValue();
String[] serviceArray = {service};
this.map.put(PARAM_SERVICE, serviceArray);
}
NodeList nList = doc.getFirstChild().getChildNodes();
ArrayList<String> versionList = new ArrayList<String>();
for (int i = 0; i < nList.getLength(); i++) {
Node n = nList.item(i);
if (n.getLocalName() != null) {
if (n.getLocalName().equalsIgnoreCase(ACCEPT_VERSIONS_ELEMENT_NAME)) {
NodeList nList2 = n.getChildNodes();
for (int j = 0; j < nList2.getLength(); j++) {
Node n2 = nList2.item(j);
if (n2.getLocalName() != null
&& n2.getLocalName().equalsIgnoreCase(RequestHandler.VERSION_ATTRIBUTE_NAME)) {
versionList.add(n2.getTextContent());
}
}
break;
}
}
}
if ( !versionList.isEmpty()) {
this.map.put(PARAM_VERSION, versionList.toArray(new String[versionList.size()]));
}
}
/**
* Validates the client input
*
* @throws ExceptionReport
* @return True if the input is valid, False otherwise
*/
public boolean validate() throws ExceptionReport {
String services = getMapValue(PARAM_SERVICE, true);
if ( !services.equalsIgnoreCase("wps")) {
throw new ExceptionReport("Parameter <service> is not correct, expected: WPS , got: " + services,
ExceptionReport.INVALID_PARAMETER_VALUE, "service");
}
String[] versions = getMapArray(PARAM_VERSION, false);
if ( !requireVersion(SUPPORTED_VERSION, false)) {
throw new ExceptionReport("Requested versions are not supported, you requested: "
+ Request.accumulateString(versions), ExceptionReport.VERSION_NEGOTIATION_FAILED, "version");
}
return true;
}
/**
* Actually serves the Request.
*
* @throws ExceptionReport
* @return Response The result of the computation
*/
public Response call() throws ExceptionReport {
validate();
LOGGER.info("Handled GetCapabilitiesRequest successfully!");
return new CapabilitiesResponse(this);
}
/**
* Not used in this class. Returns null;
*/
public Object getAttachedResult() {
return null;
}
}

View File

@ -0,0 +1,185 @@
/**
* 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.request;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import net.opengis.wps.x100.ProcessDescriptionType;
import net.opengis.wps.x100.ProcessDescriptionsDocument;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.xmlbeans.XmlCursor;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.RepositoryManager;
import org.n52.wps.server.WebProcessingService;
import org.n52.wps.server.response.DescribeProcessResponse;
import org.n52.wps.server.response.Response;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Handles a DescribeProcessRequest
* @see Request
*/
public class DescribeProcessRequest extends Request {
private ProcessDescriptionsDocument document;
/**
* Creates a DescribeProcessRequest based on a Map (HTTP_GET)
* @param ciMap The client input
* @throws ExceptionReport
*/
public DescribeProcessRequest(CaseInsensitiveMap ciMap) throws ExceptionReport{
super(ciMap);
}
/**
* Creates a DescribeProcessRequest based on a Document (SOAP?)
* @param doc The client input
* @throws ExceptionReport
*/
public DescribeProcessRequest(Document doc) throws ExceptionReport{
super(doc);
//put the respective elements of the document in the map
NamedNodeMap nnm = doc.getFirstChild().getAttributes();
map = new CaseInsensitiveMap();
for (int i = 0; i < nnm.getLength(); i++) {
Node n = nnm.item(i);
if(n.getLocalName().equalsIgnoreCase("service")){
map.put(n.getLocalName(), new String[]{n.getNodeValue()});
}else if(n.getLocalName().equalsIgnoreCase("version")){
map.put(n.getLocalName(), new String[]{n.getNodeValue()});
}
}
//get identifier
String identifierList = "";
NodeList nList = doc.getFirstChild().getChildNodes();
boolean identifierParameterExists = false;
for (int i = 0; i < nList.getLength(); i++) {
Node n = nList.item(i);
if(n.getLocalName() != null && n.getLocalName().equalsIgnoreCase("identifier")){
identifierParameterExists = true;
String s = n.getTextContent();
if(s != null && !s.isEmpty()){
identifierList = identifierList.concat(s + ",");
}
}
}
if(identifierParameterExists){
map.put("identifier", new String[]{identifierList});
}
}
/**
* Validates the client input
* @throws ExceptionReport
* @return True if the input is valid, False otherwise
*/
public boolean validate() throws ExceptionReport{
getMapValue("version", true, new String[]{"1.0.0"}); // required
getMapValue("identifier", true); // required!
return true;
}
public Object getAttachedResult(){
return document;
}
/**
* Actually serves the Request.
* @throws ExceptionReport
* @return Response The result of the computation
*/
public Response call() throws ExceptionReport {
validate();
document = ProcessDescriptionsDocument.Factory.newInstance();
document.addNewProcessDescriptions();
XmlCursor c = document.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/wpsDescribeProcess_response.xsd");
String[] identifiers = getMapValue("identifier", true).split(",");
document.getProcessDescriptions().setLang(WebProcessingService.DEFAULT_LANGUAGE);
document.getProcessDescriptions().setService("WPS");
document.getProcessDescriptions().setVersion(Request.SUPPORTED_VERSION);
if(identifiers.length==1 && identifiers[0].equalsIgnoreCase("all")){
List<String> identifierList = RepositoryManager.getInstance().getAlgorithms();
identifiers = new String[identifierList.size()];
for(int i = 0;i<identifierList.size();i++){
identifiers[i] = identifierList.get(i);
}
}
// if(identifiers.length == 0){
// throw new ExceptionReport("No process identifier specified for describe process operation.",
// ExceptionReport.MISSING_PARAMETER_VALUE,
// "parameter: identifier");
// }else
if(identifiers.length == 1){
if(identifiers[0] == null || identifiers[0].isEmpty()){
throw new ExceptionReport("Process description request with empty identifier.",
ExceptionReport.INVALID_PARAMETER_VALUE,
"identifier");
}
}
for(String algorithmName : identifiers) {
if(!RepositoryManager.getInstance().containsAlgorithm(algorithmName)) {
throw new ExceptionReport("Algorithm does not exist: " + algorithmName,
ExceptionReport.INVALID_PARAMETER_VALUE,
"identifier");
}
ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(algorithmName);
document.getProcessDescriptions().addNewProcessDescription().set(description);
}
LOGGER.info("Handled Request successfully for: " + getMapValue("identifier", true));
return new DescribeProcessResponse(this);
}
}

View File

@ -0,0 +1,920 @@
/**
* 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.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("&amp;","&");
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);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,279 @@
/**
* 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.request;
import java.util.UUID;
import java.util.concurrent.Callable;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.response.Response;
import org.w3c.dom.Document;
/**
* The client requests some operation from the server.
* The request generates a unique reference based on the client, time and a count.
* Not secure! Upcoming references are easily guessed or altered.
* @see java.rmi.server.UID
*/
abstract public class Request implements Callable <Response> {
protected CaseInsensitiveMap map = null;
protected Document doc = null;
protected static Logger LOGGER = LoggerFactory.getLogger(Request.class);
protected UUID id = null;
public static final String SUPPORTED_VERSION = "1.0.0";
public static final String[] SUPPORTED_LANGUAGES = new String[]{"en-US"};
/**
* Create a Request based on a CaseInsensitiveMap as input (HTTP GET)
* @param map The Map which holds the client input.
*/
public Request(CaseInsensitiveMap map) throws ExceptionReport{
super();
this.map = map;
}
/**
* Create a Request based on a Document as input (HTTP POST)
* @param doc The Document which holds the client input.
*/
public Request(Document doc) throws ExceptionReport{
super();
this.doc = doc;
}
/**
* Returns the user input in Document form
* @return Document || null if Request(Map, outputstream) was used
*/
public Document getDocument(){
return doc;
}
/**
* Returns the user input in Map form
* @return Map || null if Request(Document, OutputStream) was used
*/
public CaseInsensitiveMap getMap(){
return map;
}
/**
* Retrieve a value from an input-map with a lookup-key
* @param key The lookup-key
* @param map The input-map to look in
* @param required If the key-value pair must be in the map.
* @return The value of the key-value pair
*/
public static String getMapValue(String key, CaseInsensitiveMap map, boolean required) throws ExceptionReport{
if(map.containsKey(key)){
return ((String[]) map.get(key))[0];
}else if(!required){
LOGGER.warn("Parameter <" + key + "> not found.");
return null;
}else{
//Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
throw new ExceptionReport("Parameter <" + key + "> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE, key);
}
}
/**
* Retrieve a value from an input-map with a lookup-key
* @param key The lookup-key
* @param map The input-map to look in
* @param required If the key-value pair must be in the map.
* @return The value of the key-value pair
*/
public static String getMapValue(String key, CaseInsensitiveMap map, boolean required, String[] supportedValues) throws ExceptionReport{
if(map.containsKey(key)){
String value = ((String[]) map.get(key))[0];
for (String string : supportedValues) {
if(string.equalsIgnoreCase(value)){
return value;
}
}
throw new ExceptionReport("Invalid value for parameter <" + key + ">.", ExceptionReport.INVALID_PARAMETER_VALUE, key);
}else if(!required){
LOGGER.warn("Parameter <" + key + "> not found.");
return null;
}else{
//Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
throw new ExceptionReport("Parameter <" + key + "> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE, key);
}
}
/**
* Retrieve an array of values from an input-map with a lookup-key
* @param key The lookup-key
* @param map The input-map to look in
* @param required If the key-value pair must be in the map.
* @return The array of values of the key-value pair
*/
public static String[] getMapArray(String key, CaseInsensitiveMap map, boolean required) throws ExceptionReport{
if(map.containsKey(key)){
return (String[]) map.get(key);
}else if(!required){
LOGGER.warn("Parameter <" + key + "> not found.");
return null;
}else{
//Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
throw new ExceptionReport("Parameter <" + key + "> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE, key);
}
}
/**
* Retrieve a value from the client-input-map with a lookup-key
* @param The lookup-key
* @return The value of the key-value pair
*/
protected String getMapValue(String key, boolean required) throws ExceptionReport{
return Request.getMapValue(key, this.map, required);
}
/**
* Retrieve a value from the client-input-map with a lookup-key
* @param The lookup-key
* @return The value of the key-value pair
*/
protected String getMapValue(String key, boolean required, String[] supportedValues) throws ExceptionReport{
return Request.getMapValue(key, this.map, required, supportedValues);
}
/**
* Retrieve an array of values from the client-input-map with a lookup-key
* @param The lookup-key
* @return The array of values of the key-value pair
*/
protected String[] getMapArray(String key, boolean required) throws ExceptionReport{
return Request.getMapArray(key, this.map, required);
}
/**
* Returns the version that the client requested.
* @return An array of versions that are compatible with the client
*/
protected String[] getRequestedVersions(boolean mandatory) throws ExceptionReport{
return getMapArray("version", mandatory);
}
/**
* The process (request) on the server could require a specific version on the client
* @param version The version that is required on the client
* @return True if the required version matches, False otherwise.
*/
public boolean requireVersion(String version, boolean mandatory) throws ExceptionReport{
String[] versions = getRequestedVersions(mandatory);
if(mandatory && versions == null) {
//Fix for Bug 904 https://bugzilla.52north.org/show_bug.cgi?id=904
throw new ExceptionReport("Parameter <version> not specified.", ExceptionReport.MISSING_PARAMETER_VALUE, "version");
}
else if(versions == null && ! mandatory) {
return true;
}
for(String v : versions) {
//remove possible blanks
if(v.trim().equals(version)) {
return true;
}
}
return false;
}
/**
* Accumulates the Strings in an array, separated by ", " (without quotes).
* @param strings The array to accumulate
* @return The accumulated String
*/
public static String accumulateString(String[] strings) {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < strings.length; i++) {
String s = strings[i];
if(!(i == strings.length-1)){
sb.append(s + ", ");
}else{
sb.append(s);
}
}
return sb.toString();
}
public UUID getUniqueId(){
if (id == null) {
this.id = UUID.randomUUID();
}
return id;
}
/**
* Checks, if the language is supported by the WPS.
* The language parameter is optional, however, if a wrong language is requested,
* an ExceptionReport has to be returned to the client.
*
* See https://bugzilla.52north.org/show_bug.cgi?id=905.
*
* @param language The language to be checked.
* @throws ExceptionReport If a wrong language is requested, this ExceptionReport will be returned to the client.
*/
public static void checkLanguageSupported(String language) throws ExceptionReport {
for (String supportedLanguage : SUPPORTED_LANGUAGES) {
if(supportedLanguage.equals(language)){
return;
}
}
throw new ExceptionReport(
"The requested language " + language + " is not supported",
ExceptionReport.INVALID_PARAMETER_VALUE, "language");
}
abstract public Object getAttachedResult();
/**
* After creation a Request is handled. This is done by calling this method.
* This handling could contain a lot of computations. These computations should
* be called from within this method.
* @return A Response to the client Request
* @see java.util.concurrent.Callable#call()
*/
abstract public Response call() throws ExceptionReport;
/**
* There should be some validation required on the (input of the) clients Request.
* @return True if the clients Request can be handled without problems, False otherwise
*/
abstract public boolean validate() throws ExceptionReport;
}

View File

@ -0,0 +1,94 @@
/**
* 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.request;
import java.io.InputStream;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.database.IDatabase;
import org.n52.wps.server.database.DatabaseFactory;
import org.n52.wps.server.response.Response;
import org.n52.wps.server.response.RetrieveResultResponse;
/**
* If the server is too busy or the computation is too long,
* the client can retrieve the result at a later time.
* This class represents a Request to obtain the result.
* The respons might be the result, be also could contain a
* message that the result is not available yet.
*/
public class RetrieveResultRequest extends Request {
private InputStream storedResponse = null;
/**
* Create a Request based on a CaseInsensitiveMap as input (HTTP GET)
* @param ciMap The Map which holds the client input.
*/
public RetrieveResultRequest(CaseInsensitiveMap ciMap) throws ExceptionReport{
super(ciMap);
}
/**
* Actually serves the Request.
* @throws ExceptionReport
*/
public Response call() throws ExceptionReport {
if(validate()){
return new RetrieveResultResponse(this);
}
return null;
}
/**
* Validates the client input
* @return True if the input is valid, False otherwise
*/
public boolean validate() throws ExceptionReport {
String req_id = getMapValue("request_id", true);
if(req_id.length() == 0){
throw new ExceptionReport("The value of parameter <request_id> is not valid.", ExceptionReport.INVALID_PARAMETER_VALUE);
}
try{
}catch(NumberFormatException e){
throw new ExceptionReport("The value of parameter <request_id> is not an integer identifier", ExceptionReport.INVALID_PARAMETER_VALUE);
}
IDatabase db = DatabaseFactory.getDatabase();
this.storedResponse = db.lookupResponse(req_id);
return (this.storedResponse != null);
}
public Object getAttachedResult() throws NullPointerException {
if(this.storedResponse == null)
throw new NullPointerException("No stored responses were found!");
return this.storedResponse;
}
}

View File

@ -0,0 +1,183 @@
/**
* 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.request.strategy;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import net.opengis.wps.x100.InputType;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DecompressingHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.wps.server.ExceptionReport;
/**
*
* @author Matthias Mueller
*
* Basic methods to retrieve input data using HTTP/GET, HTTP/POST or HTTP/POST with href'd body
*
*/
public class DefaultReferenceStrategy implements IReferenceStrategy{
// TODO: follow HTTP redirects with LaxRedirectStrategy
Logger logger = LoggerFactory.getLogger(DefaultReferenceStrategy.class);
//TODO: get proxy from config
//static final HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http");
static final HttpHost proxy = null;
@Override
public boolean isApplicable(InputType input) {
// TODO Auto-generated method stub
return true;
}
// TODO: follow references, e..g
@Override
public ReferenceInputStream fetchData(InputType input) throws ExceptionReport {
String href = input.getReference().getHref();
String mimeType = input.getReference().getMimeType();
try {
// Handling POST with referenced document
if(input.getReference().isSetBodyReference()) {
String bodyHref = input.getReference().getBodyReference().getHref();
// but Body reference into a String
StringWriter writer = new StringWriter();
IOUtils.copy(httpGet(bodyHref, null), writer);
String body = writer.toString();
// trigger POST request
return httpPost(href, body, mimeType);
}
// Handle POST with inline message
else if (input.getReference().isSetBody()) {
String body = input.getReference().getBody().toString();
return httpPost(href, body, mimeType);
}
// Handle get request
else {
return httpGet(href, mimeType);
}
}
catch(RuntimeException e) {
throw new ExceptionReport("Error occured while parsing XML",
ExceptionReport.NO_APPLICABLE_CODE, e);
}
catch(MalformedURLException e) {
String inputID = input.getIdentifier().getStringValue();
throw new ExceptionReport("The inputURL of the execute is wrong: inputID: " + inputID + " | dataURL: " + href,
ExceptionReport.INVALID_PARAMETER_VALUE );
}
catch(IOException e) {
String inputID = input.getIdentifier().getStringValue();
throw new ExceptionReport("Error occured while receiving the complexReferenceURL: inputID: " + inputID + " | dataURL: " + href,
ExceptionReport.INVALID_PARAMETER_VALUE );
}
}
/**
* Make a GET request using mimeType and href
*
* TODO: add support for autoretry, proxy
*/
private ReferenceInputStream httpGet(final String dataURLString, final String mimeType) throws IOException {
HttpClient backend = new DefaultHttpClient();
DecompressingHttpClient httpclient = new DecompressingHttpClient(backend);
HttpGet httpget = new HttpGet(dataURLString);
if (mimeType != null){
httpget.addHeader(new BasicHeader("Content-type", mimeType));
}
return processResponse(httpclient.execute(httpget));
}
/**
* Make a POST request using mimeType and href
*
* TODO: add support for autoretry, proxy
*/
private ReferenceInputStream httpPost(final String dataURLString, final String body, final String mimeType) throws IOException {
HttpClient backend = new DefaultHttpClient();
DecompressingHttpClient httpclient = new DecompressingHttpClient(backend);
HttpPost httppost = new HttpPost(dataURLString);
if (mimeType != null){
httppost.addHeader(new BasicHeader("Content-type", mimeType));
}
// set body entity
HttpEntity postEntity = new StringEntity(body);
httppost.setEntity(postEntity);
return processResponse(httpclient.execute(httppost));
}
private ReferenceInputStream processResponse(HttpResponse response) throws IOException {
HttpEntity entity = response.getEntity();
Header header;
header = entity.getContentType();
String mimeType = header == null ? null : header.getValue();
header = entity.getContentEncoding();
String encoding = header == null ? null : header.getValue();
return new ReferenceInputStream(entity.getContent(), mimeType, encoding);
}
}

View File

@ -0,0 +1,39 @@
/**
* 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.request.strategy;
import org.n52.wps.server.ExceptionReport;
import net.opengis.wps.x100.InputType;
public interface IReferenceStrategy {
public boolean isApplicable(InputType input);
public ReferenceInputStream fetchData(InputType input) throws ExceptionReport;
}

View File

@ -0,0 +1,212 @@
/**
* 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.request.strategy;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DecompressingHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.n52.wps.server.request.InputHandler;
/**
* An extension of an Input Stream with HTTP Connection abilities.
* Uses an {@link InputStream} internally. HTTP connection is established
* in a lazy fashion, i.e. on first read attempt.
*
* This class shall prevent timeout issues with I/O streaming in the WPS framework.
*
* @deprecated alternative implementation now used, featuring {@link ReferenceInputStream} and
* corresponding adjustments in {@link InputHandler}
*
* @author Matthias Mueller, TU Dresden
*
*/
@Deprecated
public class LazyHttpInputStream extends InputStream {
private InputStream is;
private boolean initDone = false;
// connection parameters
final boolean useHttpGet;
final String dataURLString;
final String body;
final String mimeType;
/**
* Constructor for HTTP/POST
*
* @param dataURLString
* @param body
* @param mimeType
*/
public LazyHttpInputStream (final String dataURLString, final String body, final String mimeType){
this.dataURLString = dataURLString;
this.body = body;
this.mimeType = mimeType;
useHttpGet = false;
}
/**
* Constructor for HTTP/GET
*
* @param dataURLString
* @param body
* @param mimeType
*/
public LazyHttpInputStream (final String dataURLString, final String mimeType){
this.dataURLString = dataURLString;
this.body = null;
this.mimeType = mimeType;
useHttpGet = true;
}
/**
* Private init method that makes HTTP connections.
*
* @throws IOException
*/
private final void init() throws IOException{
if (useHttpGet){
is = httpGet(dataURLString, mimeType);
} else {
is = httpPost(dataURLString, body, mimeType);
}
initDone = true;
}
@Override
public int read() throws IOException {
if (!initDone){
init();
}
return is.read();
}
@Override
public int available() throws IOException {
if (!initDone){
init();
}
return is.available();
}
@Override
public void close() throws IOException {
if (!initDone){
init();
}
is.close();
}
@Override
public synchronized void mark(int readlimit) {
if (!initDone){
try {
init();
} catch (IOException e) {
// silent catch
}
}
is.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
if (!initDone){
init();
}
is.reset();
}
@Override
public boolean markSupported() {
if (!initDone){
// silent catch
}
return is.markSupported();
}
/**
* Make a GET request using mimeType and href
*
* TODO: add support for autoretry, proxy
*/
private static InputStream httpGet(final String dataURLString, final String mimeType) throws IOException {
HttpClient backend = new DefaultHttpClient();
DecompressingHttpClient httpclient = new DecompressingHttpClient(backend);
HttpGet httpget = new HttpGet(dataURLString);
if (mimeType != null){
httpget.addHeader(new BasicHeader("Content-type", mimeType));
}
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
return entity.getContent();
}
/**
* Make a POST request using mimeType and href
*
* TODO: add support for autoretry, proxy
*/
private static InputStream httpPost(final String dataURLString, final String body, final String mimeType) throws IOException {
HttpClient backend = new DefaultHttpClient();
DecompressingHttpClient httpclient = new DecompressingHttpClient(backend);
HttpPost httppost = new HttpPost(dataURLString);
if (mimeType != null){
httppost.addHeader(new BasicHeader("Content-type", mimeType));
}
// set body entity
HttpEntity postEntity = new StringEntity(body);
httppost.setEntity(postEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resultEntity = response.getEntity();
return resultEntity.getContent();
}
}

View File

@ -0,0 +1,56 @@
/**
* 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.request.strategy;
import java.io.FilterInputStream;
import java.io.InputStream;
/**
*
* @author tkunicki
*/
public class ReferenceInputStream extends FilterInputStream {
private final String mimeType;
private final String encoding;
public ReferenceInputStream(InputStream inputStream, String mimeType, String encoding) {
super(inputStream);
this.mimeType = mimeType;
this.encoding = encoding;
}
public String getMimeType() {
return mimeType;
}
public String getEncoding() {
return encoding;
}
}

View File

@ -0,0 +1,71 @@
/**
* 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.request.strategy;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.n52.wps.server.ExceptionReport;
import net.opengis.wps.x100.InputType;
public class ReferenceStrategyRegister {
protected List<IReferenceStrategy> registeredStrategies;
private static ReferenceStrategyRegister instance;
public synchronized static ReferenceStrategyRegister getInstance(){
if(instance==null){
instance = new ReferenceStrategyRegister();
}
return instance;
}
private ReferenceStrategyRegister(){
registeredStrategies = new ArrayList<IReferenceStrategy>();
registeredStrategies.add(new WCS111XMLEmbeddedBase64OutputReferenceStrategy());
}
protected void registerStrategy(IReferenceStrategy strategy){
registeredStrategies.add(strategy);
}
public ReferenceInputStream resolveReference(InputType input) throws ExceptionReport{
IReferenceStrategy foundStrategy = new DefaultReferenceStrategy();
for(IReferenceStrategy strategy : registeredStrategies){
if(strategy.isApplicable(input)){
foundStrategy = strategy;
break;
}
}
return foundStrategy.fetchData(input);
}
}

View File

@ -0,0 +1,184 @@
/**
* 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.request.strategy;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.GZIPInputStream;
import net.opengis.wps.x100.InputType;
import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.xmlbeans.XmlObject;
import org.n52.wps.server.ExceptionReport;
public class WCS111XMLEmbeddedBase64OutputReferenceStrategy implements IReferenceStrategy{
private String fetchedMimeType;
private String fetchedEncoding;
@Override
public boolean isApplicable(InputType input) {
if(input.getReference().isSetBody()) {
XmlObject xo = input.getReference().getBody();
return xo.toString().contains("http://www.opengis.net/wcs/1.1.1");
}else{
String dataURLString = input.getReference().getHref();
return (dataURLString.contains("=GetCoverage") && dataURLString.contains("=1.1.1"));
}
}
@Override
public ReferenceInputStream fetchData(InputType input) throws ExceptionReport {
String dataURLString = input.getReference().getHref();
String schema = input.getReference().getSchema();
String encoding = input.getReference().getEncoding();
String mimeType = input.getReference().getMimeType();
try {
URL dataURL = new URL(dataURLString);
// Do not give a direct inputstream.
// The XML handlers cannot handle slow connections
URLConnection conn = dataURL.openConnection();
conn.setRequestProperty("Accept-Encoding", "gzip");
conn.setRequestProperty("Content-type", "multipart/mixed");
//Handling POST with referenced document
if(input.getReference().isSetBodyReference()) {
String bodyReference = input.getReference().getBodyReference().getHref();
URL bodyReferenceURL = new URL (bodyReference);
URLConnection bodyReferenceConn = bodyReferenceURL.openConnection();
bodyReferenceConn.setRequestProperty("Accept-Encoding", "gzip");
InputStream referenceInputStream = retrievingZippedContent(bodyReferenceConn);
IOUtils.copy(referenceInputStream, conn.getOutputStream());
}
//Handling POST with inline message
else if (input.getReference().isSetBody()) {
conn.setDoOutput(true);
input.getReference().getBody().save(conn.getOutputStream());
}
InputStream inputStream = retrievingZippedContent(conn);
BufferedReader bRead = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
//boundary between different content types
String boundary = "";
boolean boundaryFound = false;
boolean encodedImagepart = false;
String encodedImage = "";
//e.g. base64
String contentTransferEncoding = "";
String imageContentType = "";
int boundaryCount = 0;
while((line = bRead.readLine()) != null){
if(line.contains("boundary")){
boundary = line.substring(line.indexOf("\"") + 1, line.lastIndexOf("\""));
boundaryFound = true;
continue;
}
if(boundaryFound){
if(line.contains(boundary)){
boundaryCount++;
continue;
}
}
if(encodedImagepart){
encodedImage = encodedImage.concat(line);
}
//is the image always the third part?!
else if(boundaryCount == 2){
if(line.contains("Content-Type")){
imageContentType = line.substring(line.indexOf(":") +1).trim();
}else if(line.contains("Content-Transfer-Encoding")){
contentTransferEncoding = line.substring(line.indexOf(":") +1).trim();
}else if(line.contains("Content-ID")){
/* just move further one line (which is hopefully empty)
* and start parsing the encoded image
*/
line = bRead.readLine();
encodedImagepart = true;
}
}
}
return new ReferenceInputStream(
new Base64InputStream(new ByteArrayInputStream(encodedImage.getBytes())),
imageContentType,
null); // encoding is null since encoding was removed
}
catch(RuntimeException e) {
throw new ExceptionReport("Error occured while parsing XML",
ExceptionReport.NO_APPLICABLE_CODE, e);
}
catch(MalformedURLException e) {
String inputID = input.getIdentifier().getStringValue();
throw new ExceptionReport("The inputURL of the execute is wrong: inputID: " + inputID + " | dataURL: " + dataURLString,
ExceptionReport.INVALID_PARAMETER_VALUE );
}
catch(IOException e) {
String inputID = input.getIdentifier().getStringValue();
throw new ExceptionReport("Error occured while receiving the complexReferenceURL: inputID: " + inputID + " | dataURL: " + dataURLString,
ExceptionReport.INVALID_PARAMETER_VALUE );
}
}
private InputStream retrievingZippedContent(URLConnection conn) throws IOException{
String contentType = conn.getContentEncoding();
if(contentType != null && contentType.equals("gzip")) {
return new GZIPInputStream(conn.getInputStream());
}
else{
return conn.getInputStream();
}
}
}

View File

@ -0,0 +1,68 @@
/**
* 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.IOException;
import java.io.InputStream;
import org.apache.xmlbeans.XmlException;
import org.n52.wps.server.CapabilitiesConfiguration;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.request.CapabilitiesRequest;
import org.n52.wps.util.XMLBeansHelper;
/**
* A Response to the Request "GetCapabilities"
*
*/
public class CapabilitiesResponse extends Response {
/**
* Serves the Request with a Response
* @param request The GetCapabilities request
*/
public CapabilitiesResponse(CapabilitiesRequest request){
super(request);
}
/**
* Save this Response to an OutputStream
* @param os The OutputStream to save this Response to
* @throws ExceptionReport
*/
public InputStream getAsStream() throws ExceptionReport{
try {
return CapabilitiesConfiguration.getInstance().newInputStream(XMLBeansHelper.getXmlOptions());
} catch (IOException e) {
throw new ExceptionReport("Exception occured while generating response", ExceptionReport.NO_APPLICABLE_CODE, e);
} catch (XmlException e) {
throw new ExceptionReport("Exception occured while generating response", ExceptionReport.NO_APPLICABLE_CODE, e);
}
}
}

View File

@ -0,0 +1,55 @@
/**
* 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 net.opengis.wps.x100.ProcessDescriptionsDocument;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.request.DescribeProcessRequest;
import org.n52.wps.util.XMLBeansHelper;
public class DescribeProcessResponse extends Response{
public DescribeProcessResponse(DescribeProcessRequest request){
super(request);
}
@Override
public InputStream getAsStream() throws ExceptionReport{
try {
return ((ProcessDescriptionsDocument)request.getAttachedResult()).newInputStream(XMLBeansHelper.getXmlOptions());
}
catch(Exception e) {
throw new ExceptionReport("Exception occured while writing response document", ExceptionReport.NO_APPLICABLE_CODE, e);
}
}
}

View File

@ -0,0 +1,56 @@
/**
* 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 org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.request.ExecuteRequest;
public class ExecuteResponse extends Response {
private ExecuteResponseBuilder builder;
public ExecuteResponse(ExecuteRequest request) throws ExceptionReport{
super(request);
this.builder = ((ExecuteRequest)this.request).getExecuteResponseBuilder();
}
@Override
public InputStream getAsStream() throws ExceptionReport{
return this.builder.getAsStream();
}
public ExecuteResponseBuilder getExecuteResponseBuilder(){
return builder;
}
public String getMimeType(){
return builder.getMimeType();
}
}

View File

@ -0,0 +1,381 @@
/**
* 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<request.getExecute().getResponseForm().getResponseDocument().getOutputArray().length; i++) {
OutputDefinitionType definition = request.getExecute().getResponseForm().getResponseDocument().getOutputArray(i);
DocumentOutputDefinitionType documentDef = request.getExecute().getResponseForm().getResponseDocument().getOutputArray(i);
String responseID = definition.getIdentifier().getStringValue();
OutputDescriptionType desc = XMLBeansHelper.findOutputByID(responseID, outputDescs);
if(desc==null){
throw new ExceptionReport("Could not find the output id " + responseID, ExceptionReport.INVALID_PARAMETER_VALUE);
}
if(desc.isSetComplexOutput()) {
String mimeType = getMimeType(definition);
String schema = ExecuteResponseBuilder.getSchema(desc, definition);
String encoding = ExecuteResponseBuilder.getEncoding(desc, definition);
generateComplexDataOutput(responseID, documentDef.getAsReference(), false, schema, mimeType, encoding, desc.getTitle());
}
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(responseID, doc, false, reference, schema, mimeType, encoding, desc.getTitle());
}
else if (desc.isSetBoundingBoxOutput()) {
generateBBOXOutput(responseID, doc, false, desc.getTitle());
}
else{
throw new ExceptionReport("Requested type not supported: BBOX", ExceptionReport.INVALID_PARAMETER_VALUE);
}
}
}
else {
LOGGER.info("OutputDefinitions are not stated explicitly in request");
// THIS IS A WORKAROUND AND ACTUALLY NOT COMPLIANT TO THE SPEC.
ProcessDescriptionType description = RepositoryManager.getInstance().getProcessDescription(request.getExecute().getIdentifier().getStringValue());
if(description==null){
throw new RuntimeException("Error while accessing the process description for "+ request.getExecute().getIdentifier().getStringValue());
}
OutputDescriptionType [] d = description.getProcessOutputs().getOutputArray();
for (int i = 0; i < d.length; i++)
{
if(d[i].isSetComplexOutput()) {
String schema = d[i].getComplexOutput().getDefault().getFormat().getSchema();
String encoding = d[i].getComplexOutput().getDefault().getFormat().getEncoding();
String mimeType = d[i].getComplexOutput().getDefault().getFormat().getMimeType();
generateComplexDataOutput(d[i].getIdentifier().getStringValue(), false, false, schema, mimeType, encoding, d[i].getTitle());
}
else if(d[i].isSetLiteralOutput()) {
generateLiteralDataOutput(d[i].getIdentifier().getStringValue(), doc, false, d[i].getLiteralOutput().getDataType().getReference(), null, null, null, d[i].getTitle());
}
}
}
} else if(request.isStoreResponse()) {
responseElem.setStatusLocation(DatabaseFactory.getDatabase().generateRetrieveResultURL((request.getUniqueId()).toString()));
}
}
/**
* Returns the schema according to the given output description and type.
*/
private static String getSchema(OutputDescriptionType desc, OutputDefinitionType def) {
String schema = null;
if(def != null) {
schema = def.getSchema();
}
return schema;
}
private static String getEncoding(OutputDescriptionType desc, OutputDefinitionType def) {
String encoding = null;
if(def != null) {
encoding = def.getEncoding();
}
return encoding;
}
public String getMimeType() {
return getMimeType(null);
}
public String getMimeType(OutputDefinitionType def) {
String mimeType = "";
OutputDescriptionType[] outputDescs = description.getProcessOutputs()
.getOutputArray();
boolean isResponseForm = request.getExecute().isSetResponseForm();
String inputID = "";
if(def != null){
inputID = def.getIdentifier().getStringValue();
}else if(isResponseForm){
if (request.getExecute().getResponseForm().isSetRawDataOutput()) {
inputID = request.getExecute().getResponseForm().getRawDataOutput()
.getIdentifier().getStringValue();
} else if (request.getExecute().getResponseForm()
.isSetResponseDocument()) {
inputID = request.getExecute().getResponseForm()
.getResponseDocument().getOutputArray(0).getIdentifier()
.getStringValue();
}
}
OutputDescriptionType outputDes = null;
for (OutputDescriptionType tmpOutputDes : outputDescs) {
if (inputID.equalsIgnoreCase(tmpOutputDes.getIdentifier()
.getStringValue())) {
outputDes = tmpOutputDes;
break;
}
}
if (isResponseForm) {
// Get the outputdescriptions from the algorithm
if (request.isRawData()) {
mimeType = request.getExecute().getResponseForm()
.getRawDataOutput().getMimeType();
} else {
// mimeType = "text/xml";
// MSS 03/02/2009 defaulting to text/xml doesn't work when the
// data is a complex raster
if (outputDes.isSetLiteralOutput()) {
mimeType = "text/plain";
} else if(outputDes.isSetBoundingBoxOutput()){
mimeType = "text/xml";
} else {
if (def != null) {
mimeType = def.getMimeType();
} else {
if (outputDes.isSetComplexOutput()) {
mimeType = outputDes.getComplexOutput()
.getDefault().getFormat().getMimeType();
LOGGER.warn("Using default mime type: "
+ mimeType
+ " for input: "
+ inputID);
}
}
}
}
}
if (mimeType == null) {
if (outputDes.isSetLiteralOutput()) {
mimeType = "text/plain";
} else if(outputDes.isSetBoundingBoxOutput()){
mimeType = "text/xml";
} else if (outputDes.isSetComplexOutput()) {
mimeType = outputDes.getComplexOutput().getDefault()
.getFormat().getMimeType();
LOGGER.warn("Using default mime type: " + mimeType
+ " for input: "
+ inputID);
}
}
return mimeType;
}
private void generateComplexDataOutput(String responseID, boolean asReference, boolean rawData, String schema, String mimeType, String encoding, LanguageStringType title) throws ExceptionReport{
IData obj = request.getAttachedResult().get(responseID);
if(rawData) {
rawDataHandler = new RawData(obj, responseID, schema, encoding, mimeType, this.identifier, description);
}
else {
OutputDataItem handler = new OutputDataItem(obj, responseID, schema, encoding, mimeType, title, this.identifier, description);
if(asReference) {
handler.updateResponseAsReference(doc, (request.getUniqueId()).toString(),mimeType);
}
else {
handler.updateResponseForInlineComplexData(doc);
}
}
}
private void generateLiteralDataOutput(String responseID, ExecuteResponseDocument res, boolean rawData, String dataTypeReference, String schema, String mimeType, String encoding, LanguageStringType title) throws ExceptionReport {
IData obj = request.getAttachedResult().get(responseID);
if(rawData) {
rawDataHandler = new RawData(obj, responseID, schema, encoding, mimeType, this.identifier, description);
}else{
OutputDataItem handler = new OutputDataItem(obj, responseID, schema, encoding, mimeType, title, this.identifier, description);
handler.updateResponseForLiteralData(res, dataTypeReference);
}
}
private void generateBBOXOutput(String responseID, ExecuteResponseDocument res, boolean rawData, LanguageStringType title) throws ExceptionReport {
IBBOXData obj = (IBBOXData) request.getAttachedResult().get(responseID);
if(rawData) {
rawDataHandler = new RawData(obj, responseID, null, null, null, this.identifier, description);
}else{
OutputDataItem handler = new OutputDataItem(obj, responseID, null, null, null, title, this.identifier, description);
handler.updateResponseForBBOXData(res, obj);
}
}
public InputStream getAsStream() throws ExceptionReport{
if(request.isRawData() && rawDataHandler != null) {
return rawDataHandler.getAsStream();
}
if(request.isStoreResponse()) {
String id = request.getUniqueId().toString();
String statusLocation = DatabaseFactory.getDatabase().generateRetrieveResultURL(id);
doc.getExecuteResponse().setStatusLocation(statusLocation);
}
try {
return doc.newInputStream(XMLBeansHelper.getXmlOptions());
}
catch(Exception e) {
throw new RuntimeException(e);
}
}
public void setStatus(StatusType status) {
//workaround, should be generated either at the creation of the document or when the process has been finished.
status.setCreationTime(creationTime);
doc.getExecuteResponse().setStatus(status);
}
}

View File

@ -0,0 +1,257 @@
/**
* 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.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.opengis.ows.x11.BoundingBoxType;
import net.opengis.ows.x11.CodeType;
import net.opengis.ows.x11.LanguageStringType;
import net.opengis.wps.x100.ComplexDataType;
import net.opengis.wps.x100.ExecuteResponseDocument;
import net.opengis.wps.x100.LiteralDataType;
import net.opengis.wps.x100.OutputDataType;
import net.opengis.wps.x100.OutputReferenceType;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.n52.wps.io.BasicXMLTypeFactory;
import org.n52.wps.io.IOHandler;
import org.n52.wps.io.data.IBBOXData;
import org.n52.wps.io.data.IData;
import org.n52.wps.io.data.binding.literal.AbstractLiteralDataBinding;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.database.DatabaseFactory;
import org.n52.wps.server.database.IDatabase;
import com.google.common.primitives.Doubles;
/*
* @author foerster
*
*/
public class OutputDataItem extends ResponseData {
private static final Logger LOGGER = LoggerFactory.getLogger(OutputDataItem.class);
private static final String COMPLEX_DATA_TYPE = "ComplexDataResponse";
private LanguageStringType title;
/**
*
* @param obj
* @param id
* @param schema
* @param encoding
* @param mimeType
* @param title
* @param algorithmIdentifier
* @throws ExceptionReport
*/
public OutputDataItem(IData obj, String id, String schema, String encoding,
String mimeType, LanguageStringType title, String algorithmIdentifier, ProcessDescriptionType description) throws ExceptionReport {
super(obj, id, schema, encoding, mimeType, algorithmIdentifier, description);
this.title = title;
}
/**
*
* @param res
* @throws ExceptionReport
*/
public void updateResponseForInlineComplexData(ExecuteResponseDocument res) throws ExceptionReport {
OutputDataType output = prepareOutput(res);
prepareGenerator();
ComplexDataType complexData = null;
try {
// CHECKING IF STORE IS TRUE AND THEN PROCESSING.... SOMEHOW!
// CREATING A COMPLEXVALUE
// in case encoding is NULL -or- empty -or- UTF-8
// send plain text (XML or not) in response node
//
// in case encoding is base64
// send base64encoded (binary) data in node
//
// in case encoding is
//
InputStream stream = null;
if (encoding == null || encoding.equals("") || encoding.equalsIgnoreCase(IOHandler.DEFAULT_ENCODING)){
stream = generator.generateStream(super.obj, mimeType, schema);
}
// in case encoding is base64 create a new text node
// and parse the generator's result into it
else if (encoding.equalsIgnoreCase(IOHandler.ENCODING_BASE64)){
stream = generator.generateBase64Stream(super.obj, mimeType, schema);
}
else {
throw new ExceptionReport("Unable to generate encoding " + encoding, ExceptionReport.NO_APPLICABLE_CODE);
}
complexData = output.addNewData().addNewComplexData();
if(mimeType.contains("xml") || mimeType.contains("XML")){
complexData.set(XmlObject.Factory.parse(stream));
stream.close();
}else{
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.newDocument();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(stream, baos);
stream.close();
String text = baos.toString();
baos.close();
Node dataNode = document.createTextNode(text);
complexData.set(XmlObject.Factory.parse(dataNode));
}
} catch(RuntimeException e) {
LOGGER.error(e.getMessage(), e);
throw new ExceptionReport("Could not create Inline Complex Data from the process result", ExceptionReport.NO_APPLICABLE_CODE, e);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
throw new ExceptionReport("Could not create Inline Complex Data from the process result", ExceptionReport.NO_APPLICABLE_CODE, e);
} catch (XmlException e) {
LOGGER.error(e.getMessage(), e);
throw new ExceptionReport("Could not create Inline Complex Data from the process result. Check encoding (base64 for inline binary data or UTF-8 for XML based data)", ExceptionReport.NO_APPLICABLE_CODE, e);
} catch (ParserConfigurationException e) {
LOGGER.error(e.getMessage(), e);
throw new ExceptionReport("Could not create Inline Base64 Complex Data from the process result", ExceptionReport.NO_APPLICABLE_CODE, e);
}
if (complexData != null) {
if (schema != null) {
// setting the schema attribute for the output.
complexData.setSchema(schema);
}
if (encoding != null) {
complexData.setEncoding(encoding);
}
if (mimeType != null) {
complexData.setMimeType(mimeType);
}
}
}
public void updateResponseForLiteralData(ExecuteResponseDocument res, String dataTypeReference){
OutputDataType output = prepareOutput(res);
String processValue = BasicXMLTypeFactory.getStringRepresentation(dataTypeReference, obj);
LiteralDataType literalData = output.addNewData().addNewLiteralData();
if (dataTypeReference != null) {
literalData.setDataType(dataTypeReference);
}
literalData.setStringValue(processValue);
if(obj instanceof AbstractLiteralDataBinding){
String uom = ((AbstractLiteralDataBinding)obj).getUnitOfMeasurement();
if(uom != null && !uom.equals("")){
literalData.setUom(uom);
}
}
}
public void updateResponseAsReference(ExecuteResponseDocument res, String reqID, String mimeType) throws ExceptionReport {
prepareGenerator();
OutputDataType output = prepareOutput(res);
InputStream stream;
OutputReferenceType outReference = output.addNewReference();
if (schema != null) {
outReference.setSchema(schema);
}
if (encoding != null) {
outReference.setEncoding(encoding);
}
if (mimeType != null) {
outReference.setMimeType(mimeType);
}
IDatabase db = DatabaseFactory.getDatabase();
String storeID = reqID + "" + id;
try {
if (encoding == null || encoding.equals("") || encoding.equalsIgnoreCase(IOHandler.DEFAULT_ENCODING)){
stream = generator.generateStream(super.obj, mimeType, schema);
}
// in case encoding is base64
else if (encoding.equalsIgnoreCase(IOHandler.ENCODING_BASE64)){
stream = generator.generateBase64Stream(super.obj, mimeType, schema);
}
else {
throw new ExceptionReport("Unable to generate encoding " + encoding, ExceptionReport.NO_APPLICABLE_CODE);
}
}
catch (IOException e){
LOGGER.error(e.getMessage(), e);
throw new ExceptionReport("Error while generating Complex Data out of the process result", ExceptionReport.NO_APPLICABLE_CODE, e);
}
String storeReference = db.storeComplexValue(storeID, stream, COMPLEX_DATA_TYPE, mimeType);
storeReference = storeReference.replace("#", "%23");
outReference.setHref(storeReference);
// MSS: 05-02-2009 changed default output type to text/xml to be certain that the calling application doesn't
// serve the wrong type as it is a reference in this case.
this.mimeType = "text/xml";
}
private OutputDataType prepareOutput(ExecuteResponseDocument res){
OutputDataType output = res.getExecuteResponse().getProcessOutputs().addNewOutput();
CodeType identifierCode = output.addNewIdentifier();
identifierCode.setStringValue(id);
output.setTitle(title);
return output;
}
public void updateResponseForBBOXData(ExecuteResponseDocument res, IBBOXData bbox) {
OutputDataType output = prepareOutput(res);
BoundingBoxType bboxData = output.addNewData().addNewBoundingBoxData();
if (bbox.getCRS() != null) {
bboxData.setCrs(bbox.getCRS());
}
bboxData.setLowerCorner(Doubles.asList(bbox.getLowerCorner()));
bboxData.setUpperCorner(Doubles.asList(bbox.getUpperCorner()));
bboxData.setDimensions(BigInteger.valueOf(bbox.getDimension()));
}
}

View File

@ -0,0 +1,128 @@
/**
* 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.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.n52.wps.io.IOHandler;
import org.n52.wps.io.data.IBBOXData;
import org.n52.wps.io.data.IComplexData;
import org.n52.wps.io.data.IData;
import org.n52.wps.io.data.ILiteralData;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.util.XMLBeansHelper;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.primitives.Doubles;
/*
* @author foerster
*
*/
public class RawData extends ResponseData {
public static final Joiner SPACE_JOINER = Joiner.on(" ");
/**
* @param obj
* @param id
* @param schema
* @param encoding
* @param mimeType
*/
public RawData(IData obj, String id, String schema, String encoding,
String mimeType, String algorithmIdentifier,
ProcessDescriptionType description)
throws ExceptionReport {
super(obj, id, schema, encoding, mimeType, algorithmIdentifier, description);
if (obj instanceof IComplexData) {
prepareGenerator();
}
}
public InputStream getAsStream() throws ExceptionReport {
try {
if(obj instanceof ILiteralData){
return new ByteArrayInputStream(String.valueOf(obj.getPayload()).getBytes(Charsets.UTF_8));
}
if(obj instanceof IBBOXData){
IBBOXData bbox = (IBBOXData) obj;
StringBuilder builder = new StringBuilder();
builder.append("<wps:BoundingBoxData");
appendAttr(builder, "xmlns:ows", XMLBeansHelper.NS_OWS_1_1);
appendAttr(builder, "xmlns:wps", XMLBeansHelper.NS_WPS_1_0_0);
if (bbox.getCRS() != null) {
appendAttr(builder, "crs", escape(bbox.getCRS()));
}
appendAttr(builder, "dimensions", bbox.getDimension());
builder.append(">");
builder.append("\n\t");
builder.append("<ows:LowerCorner>");
SPACE_JOINER.appendTo(builder, Doubles.asList(bbox.getLowerCorner()));
builder.append("</ows:LowerCorner>");
builder.append("\n\t");
builder.append("<ows:UpperCorner>");
SPACE_JOINER.appendTo(builder, Doubles.asList(bbox.getUpperCorner()));
builder.append("</ows:UpperCorner>");
builder.append("\n");
builder.append("</wps:BoundingBoxData>");
return new ByteArrayInputStream(builder.toString().getBytes(Charsets.UTF_8));
}
//complexdata
if(encoding == null || "".equals(encoding) || encoding.equalsIgnoreCase(IOHandler.DEFAULT_ENCODING)){
return generator.generateStream(obj, mimeType, schema);
}
else if(encoding.equalsIgnoreCase(IOHandler.ENCODING_BASE64)){
return generator.generateBase64Stream(obj, mimeType, schema);
}
} catch (IOException e) {
throw new ExceptionReport("Error while generating Complex Data out of the process result", ExceptionReport.NO_APPLICABLE_CODE, e);
}
throw new ExceptionReport("Could not determine encoding. Use default (=not set) or base64", ExceptionReport.NO_APPLICABLE_CODE);
}
private StringBuilder appendAttr(StringBuilder builder, String key, Object value) {
return builder.append(' ').append(key).append('=')
.append('"').append(value).append('"');
}
private static String escape(String s) {
return s.replaceAll("&", "&amp;")
.replaceAll("\"", "&quot;")
.replaceAll("'", "&apos;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
}
}

View File

@ -0,0 +1,61 @@
/**
* 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.UUID;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.request.Request;
abstract public class Response {
protected Request request;
public Response(Request request){
this.request = request;
}
public UUID getUniqueId(){
return this.request.getUniqueId();
}
public String getType() {
return this.getClass().getName();
}
public abstract InputStream getAsStream() throws ExceptionReport;
public Request getRequest(){
return request;
}
}

View File

@ -0,0 +1,359 @@
/**
* 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.util.ArrayList;
import java.util.List;
import net.opengis.wps.x100.ComplexDataDescriptionType;
import net.opengis.wps.x100.OutputDescriptionType;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.n52.wps.io.GeneratorFactory;
import org.n52.wps.io.IGenerator;
import org.n52.wps.io.data.IData;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.RepositoryManager;
/*
* @author foerster
* This and the inheriting classes in charge of populating the ExecuteResponseDocument.
*/
public abstract class ResponseData {
private static Logger LOGGER = LoggerFactory.getLogger(ResponseData.class);
protected IData obj = null;
protected String id;
protected String schema;
protected String encoding;
protected String mimeType;
protected IGenerator generator = null;
protected String algorithmIdentifier = null;
protected ProcessDescriptionType description = null;
public ResponseData(IData obj, String id, String schema, String encoding,
String mimeType, String algorithmIdentifier, ProcessDescriptionType description) throws ExceptionReport {
this.obj = obj;
this.id = id;
this.algorithmIdentifier = algorithmIdentifier;
this.description = description;
this.encoding = encoding;
OutputDescriptionType outputType =null;
OutputDescriptionType[] describeProcessOutput = description.getProcessOutputs().getOutputArray();
for(OutputDescriptionType tempOutputType : describeProcessOutput){
if(tempOutputType.getIdentifier().getStringValue().equalsIgnoreCase(id)){
outputType = tempOutputType;
}
}
//select generator
//0. complex output set? --> no: skip
//1. mimeType set?
//yes--> set it
//1.1 schema/encoding set?
//yes-->set it
//not-->set default values for parser with matching mime type
//no--> schema or/and encoding are set?
//yes-->use it, look if only one mime type can be found
//not-->use default values
String finalSchema = null;
String finalMimeType = null;
String finalEncoding = null;
if (outputType.isSetComplexOutput()){
if (mimeType != null){
//mime type in request
ComplexDataDescriptionType format = null;
String defaultMimeType = outputType.getComplexOutput().getDefault().getFormat().getMimeType();
boolean canUseDefault = false;
if(defaultMimeType.equalsIgnoreCase(mimeType)){
ComplexDataDescriptionType potenitalFormat = outputType.getComplexOutput().getDefault().getFormat();
if(schema != null && encoding == null){
if(schema.equalsIgnoreCase(potenitalFormat.getSchema())){
canUseDefault = true;
format = potenitalFormat;
}
}
if(schema == null && encoding != null){
if(encoding.equalsIgnoreCase(potenitalFormat.getEncoding())){
canUseDefault = true;
format = potenitalFormat;
}
}
if(schema != null && encoding != null){
if(schema.equalsIgnoreCase(potenitalFormat.getSchema()) && encoding.equalsIgnoreCase(potenitalFormat.getEncoding())){
canUseDefault = true;
format = potenitalFormat;
}
}
if(schema == null && encoding == null){
canUseDefault = true;
format = potenitalFormat;
}
}
if(!canUseDefault){
ComplexDataDescriptionType[] formats =outputType.getComplexOutput().getSupported().getFormatArray();
for(ComplexDataDescriptionType potenitalFormat : formats){
if(potenitalFormat.getMimeType().equalsIgnoreCase(mimeType)){
if(schema != null && encoding == null){
if(schema.equalsIgnoreCase(potenitalFormat.getSchema())){
format = potenitalFormat;
}
}
if(schema == null && encoding != null){
if(encoding.equalsIgnoreCase(potenitalFormat.getEncoding()) || potenitalFormat.getEncoding() == null){
format = potenitalFormat;
}
}
if(schema != null && encoding != null){
if(schema.equalsIgnoreCase(potenitalFormat.getSchema()) && ((encoding.equalsIgnoreCase(potenitalFormat.getEncoding()) || potenitalFormat.getEncoding() == null) )){
format = potenitalFormat;
}
}
if(schema == null && encoding == null){
format = potenitalFormat;
}
}
}
}
if(format == null){
throw new ExceptionReport("Could not determine output format", ExceptionReport.INVALID_PARAMETER_VALUE);
}
finalMimeType = format.getMimeType();
if(format.isSetEncoding()){
//no encoding provided--> select default one for mimeType
finalEncoding = format.getEncoding();
}
if(format.isSetSchema()){
//no encoding provided--> select default one for mimeType
finalSchema = format.getSchema();
}
}else{
//mimeType not in request
if(mimeType==null && encoding==null && schema == null){
//nothing set, use default values
finalSchema = outputType.getComplexOutput().getDefault().getFormat().getSchema();
finalMimeType = outputType.getComplexOutput().getDefault().getFormat().getMimeType();
finalEncoding = outputType.getComplexOutput().getDefault().getFormat().getEncoding();
}else{
//do a smart search an look if a mimeType can be found for either schema and/or encoding
if(mimeType==null){
if(encoding!=null && schema==null){
//encoding set only
ComplexDataDescriptionType encodingFormat = null;
String defaultEncoding = outputType.getComplexOutput().getDefault().getFormat().getEncoding();
int found = 0;
String foundEncoding = null;
if(defaultEncoding.equalsIgnoreCase(encoding)){
foundEncoding = outputType.getComplexOutput().getDefault().getFormat().getEncoding();
encodingFormat = outputType.getComplexOutput().getDefault().getFormat();
found = found +1;
}else{
ComplexDataDescriptionType[] formats = outputType.getComplexOutput().getSupported().getFormatArray();
for(ComplexDataDescriptionType tempFormat : formats){
if(tempFormat.getEncoding().equalsIgnoreCase(encoding)){
foundEncoding = tempFormat.getEncoding();
encodingFormat = tempFormat;
found = found +1;
}
}
}
if(found == 1){
finalEncoding = foundEncoding;
finalMimeType = encodingFormat.getMimeType();
if(encodingFormat.isSetSchema()){
finalSchema = encodingFormat.getSchema();
}
}else{
throw new ExceptionReport("Request incomplete. Could not determine a suitable input format based on the given input [mime Type missing and given encoding not unique]", ExceptionReport.MISSING_PARAMETER_VALUE);
}
}
if(schema != null && encoding==null){
//schema set only
ComplexDataDescriptionType schemaFormat = null;
String defaultSchema = outputType.getComplexOutput().getDefault().getFormat().getSchema();
int found = 0;
String foundSchema = null;
if(defaultSchema.equalsIgnoreCase(schema)){
foundSchema = outputType.getComplexOutput().getDefault().getFormat().getSchema();
schemaFormat = outputType.getComplexOutput().getDefault().getFormat();
found = found +1;
}else{
ComplexDataDescriptionType[] formats = outputType.getComplexOutput().getSupported().getFormatArray();
for(ComplexDataDescriptionType tempFormat : formats){
if(tempFormat.getEncoding().equalsIgnoreCase(schema)){
foundSchema = tempFormat.getSchema();
schemaFormat =tempFormat;
found = found +1;
}
}
}
if(found == 1){
finalSchema = foundSchema;
finalMimeType = schemaFormat.getMimeType();
if(schemaFormat.isSetEncoding()){
finalEncoding = schemaFormat.getEncoding();
}
}else{
throw new ExceptionReport("Request incomplete. Could not determine a suitable input format based on the given input [mime Type missing and given schema not unique]", ExceptionReport.MISSING_PARAMETER_VALUE);
}
}
if(encoding!=null && schema!=null){
//schema and encoding set
//encoding
String defaultEncoding = outputType.getComplexOutput().getDefault().getFormat().getEncoding();
List<ComplexDataDescriptionType> foundEncodingList = new ArrayList<ComplexDataDescriptionType>();
if(defaultEncoding.equalsIgnoreCase(encoding)){
foundEncodingList.add(outputType.getComplexOutput().getDefault().getFormat());
}else{
ComplexDataDescriptionType[] formats = outputType.getComplexOutput().getSupported().getFormatArray();
for(ComplexDataDescriptionType tempFormat : formats){
if(tempFormat.getEncoding().equalsIgnoreCase(encoding)){
foundEncodingList.add(tempFormat);
}
}
//schema
List<ComplexDataDescriptionType> foundSchemaList = new ArrayList<ComplexDataDescriptionType>();
String defaultSchema = outputType.getComplexOutput().getDefault().getFormat().getSchema();
if(defaultSchema.equalsIgnoreCase(schema)){
foundSchemaList.add(outputType.getComplexOutput().getDefault().getFormat());
}else{
formats = outputType.getComplexOutput().getSupported().getFormatArray();
for(ComplexDataDescriptionType tempFormat : formats){
if(tempFormat.getEncoding().equalsIgnoreCase(schema)){
foundSchemaList.add(tempFormat);
}
}
}
//results
ComplexDataDescriptionType foundCommonFormat = null;
for(ComplexDataDescriptionType encodingFormat : foundEncodingList){
for(ComplexDataDescriptionType schemaFormat : foundSchemaList){
if(encodingFormat.equals(schemaFormat)){
foundCommonFormat = encodingFormat;
}
}
}
if(foundCommonFormat!=null){
mimeType = foundCommonFormat.getMimeType();
if(foundCommonFormat.isSetEncoding()){
finalEncoding = foundCommonFormat.getEncoding();
}
if(foundCommonFormat.isSetSchema()){
finalSchema = foundCommonFormat.getSchema();
}
}else{
throw new ExceptionReport("Request incomplete. Could not determine a suitable input format based on the given input [mime Type missing and given encoding and schema are not unique]", ExceptionReport.MISSING_PARAMETER_VALUE);
}
}
}
}
}
}
}
this.schema = finalSchema;
if(this.encoding==null){
this.encoding = finalEncoding;
}
this.mimeType = finalMimeType;
}
protected void prepareGenerator() throws ExceptionReport {
Class<?> algorithmOutput = RepositoryManager.getInstance().getOutputDataTypeForAlgorithm(this.algorithmIdentifier, id);
LOGGER.debug("Looking for matching Generator: schema: {}, mimeType {}, encoding: {}", schema, mimeType, encoding);
GeneratorFactory factory = GeneratorFactory.getInstance();
this.generator = factory.getGenerator(this.schema, this.mimeType, this.encoding, algorithmOutput);
if(this.generator != null){
LOGGER.info("Using generator " + generator.getClass().getName() + " for Schema: " + schema);
}
if(this.generator == null) {
throw new ExceptionReport("Could not find an appropriate generator based on given mimetype/schema/encoding for output", ExceptionReport.NO_APPLICABLE_CODE);
}
}
}

View File

@ -0,0 +1,48 @@
/**
* 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 org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.request.RetrieveResultRequest;
public class RetrieveResultResponse extends Response {
public RetrieveResultResponse(RetrieveResultRequest request) {
super(request);
}
public InputStream getAsStream() throws ExceptionReport {
return (InputStream)request.getAttachedResult();
}
}

View File

@ -0,0 +1,130 @@
/**
* 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.util;
import java.util.concurrent.ConcurrentMap;
import net.opengis.wps.x100.InputDescriptionType;
import net.opengis.wps.x100.OutputDescriptionType;
import net.opengis.wps.x100.ProcessDescriptionType.DataInputs;
import org.apache.xmlbeans.XmlOptions;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
/*
*
* Some conveniant methods, to access some XMLBean objects.
* @author foerster
*
*/
public class XMLBeansHelper {
public static OutputDescriptionType findOutputByID(String outputID, OutputDescriptionType[] outputDescs) {
for(OutputDescriptionType desc : outputDescs) {
if(desc.getIdentifier().getStringValue().equals(outputID)) {
return desc;
}
}
return null;
}
public static InputDescriptionType findInputByID(String outputID, DataInputs inputs) {
for(InputDescriptionType desc : inputs.getInputArray()) {
if(desc.getIdentifier().getStringValue().equals(outputID)) {
return desc;
}
}
return null;
}
/**
* @return the default XmlOptions used in responses
*/
public static XmlOptions getXmlOptions() {
return new XmlOptions()
.setSaveNamespacesFirst()
.setSaveSuggestedPrefixes(PREFIXES)
.setSaveAggressiveNamespaces()
.setSavePrettyPrint();
}
/**
* Registers a prefix for a namespace to be used in responses.
*
* @param namespace the XML namespace
* @param prefix the prefix
*/
public static void registerPrefix(String namespace, String prefix) {
PREFIXES.put(Preconditions.checkNotNull(Strings.emptyToNull(namespace)),
Preconditions.checkNotNull(Strings.emptyToNull(prefix)));
}
/**
* The namespace for WPS 1.0.0: {@value}.
*/
public static final String NS_WPS_1_0_0 = "http://www.opengis.net/wps/1.0.0";
/**
* The prefix for WPS 1.0.0: {@value}.
*/
public static final String NS_WPS_PREFIX = "wps";
/**
* The namespace for WPS 1.0.0: {@value}.
*/
public static final String NS_OWS_1_1 = "http://www.opengis.net/ows/1.1";
/**
* The prefix for WPS 1.0.0: {@value}.
*/
public static final String NS_OWS_PREFIX = "ows";
/**
* The namespace for XSI: {@value}.
*/
public static final String NS_XSI
= "http://www.w3.org/2001/XMLSchema-instance";
/**
* The prefix for XSI: {@value}.
*/
public static final String NS_XSI_PREFIX = "xsi";
private static final ConcurrentMap<String, String> PREFIXES;
static {
PREFIXES = Maps.newConcurrentMap();
PREFIXES.put(NS_XSI, NS_XSI_PREFIX);
PREFIXES.put(NS_WPS_1_0_0, NS_WPS_PREFIX);
PREFIXES.put(NS_OWS_1_1, NS_OWS_PREFIX);
}
}

View File

@ -0,0 +1,148 @@
/**
* 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.request;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import net.opengis.wps.x100.ExecuteDocument;
import net.opengis.wps.x100.InputType;
import org.apache.xmlbeans.XmlException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.n52.wps.io.data.binding.bbox.BoundingBoxData;
import org.n52.wps.server.ExceptionReport;
import com.google.common.primitives.Doubles;
/**
*
* @author isuftin
*/
public class DummyTestClassAlgorithmInputHandlerTest {
private static String sampleFileName = null;
private static File sampleFile = null;
private static ExecuteDocument execDoc = null;
private static InputType[] inputArray = null;
private static File projectRoot = null;
@BeforeClass
public static void setupClass() {
sampleFileName = "src/test/resources/DummyTestClass.xml";
sampleFile = new File(sampleFileName);
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() throws XmlException, IOException {
WPSConfigTestUtil.generateMockConfig(getClass(), "/org/n52/wps/io/test/inputhandler/generator/wps_config.xml");
execDoc = ExecuteDocument.Factory.parse(sampleFile);
inputArray = execDoc.getExecute().getDataInputs().getInputArray();
File f = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getFile());
projectRoot = new File(f.getParentFile().getParentFile().getParent());
}
@After
public void tearDown() {
}
@Test(expected = ExceptionReport.class)
public void testInputHandlerInitializationWithIncorrectAlgorithmName() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, "this.algorithm.name.does.not.exist").build();
}
@Test(expected = ExceptionReport.class)
public void testInputHandlerInitializationWithNullAlgorithmName() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, null).build();
}
@Test(expected = NullPointerException.class)
public void testInputHandlerInitializationWithNullInputsArray() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(null, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
}
@Test
public void testInputHandlerInitializationWithEmptyInputsArray() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(new InputType[]{}, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
assertThat(instance, not(nullValue()));
assertThat(instance.getParsedInputData().isEmpty(), is(true));
}
@Test
public void testInputHandlerInitialization() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
assertThat(instance, not(nullValue()));
}
@Test
public void testGetParsedInputDataWithCorrectInput() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
assertThat(instance.getParsedInputData().isEmpty(), is(false));
assertThat(instance.getParsedInputData().size(), equalTo(1));
assertThat(instance.getParsedInputData().size(), equalTo(1));
assertThat(instance.getParsedInputData().get("BBOXInputData"), is(notNullValue()));
assertThat(instance.getParsedInputData().get("BBOXInputData").size(), equalTo(1));
assertThat(instance.getParsedInputData().get("BBOXInputData").get(0), is(notNullValue()));
assertThat((BoundingBoxData)instance.getParsedInputData().get("BBOXInputData").get(0).getPayload(), is(notNullValue()));
BoundingBoxData test = (BoundingBoxData)instance.getParsedInputData().get("BBOXInputData").get(0).getPayload();
assertThat(Doubles.asList(test.getLowerCorner()), contains(46.75, 13.05));
assertThat(Doubles.asList(test.getUpperCorner()), contains(46.85, 13.25));
assertThat(test.getCRS(), is(nullValue()));
assertThat(test.getDimension(), is(2));
}
}

View File

@ -0,0 +1,121 @@
/**
* 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.request;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import net.opengis.wps.x100.ExecuteResponseDocument;
import net.opengis.wps.x100.StatusType;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlValidationError;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.n52.wps.commons.WPSConfig;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.database.DatabaseFactory;
/**
*
* @author bpross-52n
*/
public class ExecuteRequestTest {
private DocumentBuilderFactory fac;
@BeforeClass
public static void setUpClass()
throws XmlException, IOException {
WPSConfig.forceInitialization("src/test/resources/org/n52/wps/io/test/inputhandler/generator/wps_config.xml");
}
@Before
public void setUp(){
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
fac = DocumentBuilderFactory.newInstance();
fac.setNamespaceAware(true);
}
@Test
public void testUpdateStatusError() throws ExceptionReport, XmlException, IOException, SAXException, ParserConfigurationException {
FileInputStream fis = new FileInputStream(new File("src/test/resources/LRDTCCorruptInputResponseDocStatusTrue.xml"));
// parse the InputStream to create a Document
Document doc = fac.newDocumentBuilder().parse(fis);
ExecuteRequest request = new ExecuteRequest(doc);
String exceptionText = "TestError";
request.updateStatusError(exceptionText);
File response = DatabaseFactory.getDatabase().lookupResponseAsFile(request.getUniqueId().toString());
ExecuteResponseDocument responseDoc = ExecuteResponseDocument.Factory.parse(response);
StatusType statusType = responseDoc.getExecuteResponse().getStatus();
assertTrue(validateExecuteResponse(responseDoc));
assertTrue(statusType.isSetProcessFailed());
assertTrue(statusType.getProcessFailed().getExceptionReport().getExceptionArray(0).getExceptionTextArray(0).equals(exceptionText));
}
private boolean validateExecuteResponse(ExecuteResponseDocument responseDoc) {
XmlOptions xmlOptions = new XmlOptions();
List<XmlValidationError> xmlValidationErrorList = new ArrayList<XmlValidationError>();
xmlOptions.setErrorListener(xmlValidationErrorList);
boolean valid = responseDoc.validate(xmlOptions);
if (!valid) {
System.err.println("Error validating process description for " + getClass().getCanonicalName());
for (XmlValidationError xmlValidationError : xmlValidationErrorList) {
System.err.println("\tMessage: " + xmlValidationError.getMessage());
System.err.println("\tLocation of invalid XML: " +
xmlValidationError.getCursorLocation().xmlText());
}
}
return valid;
}
}

View File

@ -0,0 +1,160 @@
/**
* 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.request;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import net.opengis.wps.x100.ComplexDataDescriptionType;
import net.opengis.wps.x100.ExecuteDocument;
import net.opengis.wps.x100.InputDescriptionType;
import net.opengis.wps.x100.InputType;
import org.apache.xmlbeans.XmlException;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.handler.DataInputInterceptors.InterceptorInstance;
/**
*
* @author isuftin
*/
public class InputHandlerTest {
private static File simpleBufferAlgorithmFile = null;
private static File dummyTestClassAlgorithmFile = null;
private static ExecuteDocument simpleBufferAlgorithmExecDoc = null;
private static ExecuteDocument dummyTestClassAlgorithmExecDoc = null;
private static InputType[] simpleBufferAlgorithmInputArray = null;
private static InputType[] dummyTestClassAlgorithmInputArray = null;
@BeforeClass
public static void setupClass() throws XmlException, IOException {
WPSConfigTestUtil.generateMockConfig(InputHandlerTest.class, "/org/n52/wps/io/test/inputhandler/generator/wps_config.xml");
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() throws XmlException, IOException {
simpleBufferAlgorithmFile = new File("src/test/resources/SimpleBufferAlgorithm.xml");
simpleBufferAlgorithmExecDoc = ExecuteDocument.Factory.parse(simpleBufferAlgorithmFile);
simpleBufferAlgorithmInputArray = simpleBufferAlgorithmExecDoc.getExecute().getDataInputs().getInputArray();
dummyTestClassAlgorithmFile = new File("src/test/resources/DummyTestClass.xml");
dummyTestClassAlgorithmExecDoc = ExecuteDocument.Factory.parse(dummyTestClassAlgorithmFile);
dummyTestClassAlgorithmInputArray = dummyTestClassAlgorithmExecDoc.getExecute().getDataInputs().getInputArray();
}
@After
public void tearDown() {
}
@Test
public void testInputHandlerInitialization() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(simpleBufferAlgorithmInputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
assertThat(instance, not(nullValue()));
}
@Test
public void testInputHandlerResolveInputInterceptors() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerResolveInputInterceptors...");
InputHandler instance = new InputHandler.Builder(simpleBufferAlgorithmInputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
Map<String, InterceptorInstance> resolveInputInterceptors = instance.resolveInputInterceptors("org.n52.wps.server.algorithm.SimpleBufferAlgorithm");
assertThat(resolveInputInterceptors.size(), equalTo(0));
instance = new InputHandler.Builder(dummyTestClassAlgorithmInputArray, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
resolveInputInterceptors = instance.resolveInputInterceptors("org.n52.wps.server.algorithm.SimpleBufferAlgorithm");
assertThat(resolveInputInterceptors.size(), equalTo(0));
}
@Test
public void testInputHandlerResolveInputDescriptionTypes() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerResolveInputDescriptionTypes...");
InputHandler instance = new InputHandler.Builder(simpleBufferAlgorithmInputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
InputDescriptionType idt = instance.getInputReferenceDescriptionType("data");
assertThat(idt, is(notNullValue()));
assertThat(idt.getMaxOccurs().intValue(), equalTo(1));
assertThat(idt.getMinOccurs().intValue(), equalTo(1));
instance = new InputHandler.Builder(dummyTestClassAlgorithmInputArray, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
idt = instance.getInputReferenceDescriptionType("BBOXInputData");
assertThat(idt, is(notNullValue()));
assertThat(idt.getMaxOccurs().intValue(), equalTo(1));
assertThat(idt.getMinOccurs().intValue(), equalTo(0));
}
@Test
public void testInputHandlerGetNonDefaultFormat() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerGetNonDefaultFormat...");
InputHandler instance = new InputHandler.Builder(simpleBufferAlgorithmInputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
InputDescriptionType idt = instance.getInputReferenceDescriptionType("data");
String dataMimeType = "text/xml; subtype=gml/3.1.0";
String dataSchema = "http://schemas.opengis.net/gml/3.1.0/base/feature.xsd";
String dataEncoding = null;
ComplexDataDescriptionType cddt = instance.getNonDefaultFormat(idt, dataMimeType, dataSchema, dataEncoding);
assertThat(cddt, is(notNullValue()));
assertThat(cddt.getEncoding(), is(nullValue()));
assertThat(cddt.getMimeType(), is(equalTo("text/xml; subtype=gml/3.1.0")));
assertThat(cddt.getSchema(), is(equalTo("http://schemas.opengis.net/gml/3.1.0/base/feature.xsd")));
instance = new InputHandler.Builder(dummyTestClassAlgorithmInputArray, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
idt = instance.getInputReferenceDescriptionType("BBOXInputData");
cddt = instance.getNonDefaultFormat(idt, dataMimeType, dataSchema, dataEncoding);
assertThat(cddt, is(nullValue()));
}
@Test//TODO check test, why is method getComplexValueNodeString used for bbox data?
public void testInputHandlerGetComplexValueNodeString() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerGetComplexValueNodeString...");
InputHandler instance = new InputHandler.Builder(simpleBufferAlgorithmInputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
String result = instance.getComplexValueNodeString(simpleBufferAlgorithmInputArray[0].getData().getComplexData().getDomNode());
assertThat(result, not(isEmptyOrNullString()));
assertThat(result, containsString("147.25674400000003 -42.778393 147.22018400000002 -42.824776 147.179596 -42.82143 147.11132800000001 -42.795731 147.057098 -42.741581 147.00347900000003 -42.704803 146.91909800000002 -42.622734 146.91053799999997 -42.610928 146.88998400000003 -42.585396 146.83844 -42.572792 146.78569 -42.539352 146.724335 -42.485966 146.695023 -42.469582 146.64987200000002 -42.450371 146.604965 -42.432274 146.578781 -42.408531 146.539307 -42.364208 146.525055 -42.30883 146.558044 -42.275948 146.57624800000002 -42.23777 146.58146699999998 -42.203426 146.490005 -42.180222 146.3797 -42.146332 146.33406100000002 -42.138741 146.270966 -42.165703 146.197296 -42.224072 146.167908 -42.244835 146.16493200000002 -42.245171 146.111023 -42.265202 146.03747600000003 -42.239738 145.981628 -42.187851 145.85391199999998 -42.133492 145.819611 -42.129154 145.72052000000002 -42.104084 145.61857600000002 -42.056023 145.541718 -42.027241 145.48628200000002 -41.983326 145.452744 -41.926544 145.494034 -41.896477 145.59173600000003 -41.860214 145.64211999999998 -41.838398 145.669449 -41.830734 145.680923 -41.795753 145.68296800000002 -41.743221 145.67515600000002 -41.710377 145.680115 -41.688908 145.70106500000003 -41.648228 145.71479799999997 -41.609509 145.62919599999998 -41.462051 145.64889499999998 -41.470337 145.633423 -41.420902 145.631866 -41.36528 145.640854 -41.301533 145.700424 -41.242611 145.77242999999999 -41.193897 145.80233800000002 -41.161488 145.856018 -41.08007"));
instance = new InputHandler.Builder(dummyTestClassAlgorithmInputArray, "org.n52.wps.server.algorithm.test.DummyTestClass").build();
result = instance.getComplexValueNodeString(dummyTestClassAlgorithmInputArray[0].getData().getBoundingBoxData().getDomNode());
assertThat(result, not(isEmptyOrNullString()));
assertThat(result, containsString("46.75 13.05"));
}
}

View File

@ -0,0 +1,160 @@
/**
* 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.request;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import net.opengis.wps.x100.ExecuteDocument;
import net.opengis.wps.x100.InputType;
import org.apache.xmlbeans.XmlException;
import org.geotools.feature.DefaultFeatureCollection;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.n52.wps.io.data.IData;
import org.n52.wps.server.ExceptionReport;
/**
*
* @author isuftin
*/
public class SimpleBufferAlgorithmInputHandlerTest {
private static String sampleFileName = null;
private static File sampleFile = null;
private static ExecuteDocument execDoc = null;
private static InputType[] inputArray = null;
private static File projectRoot = null;
@BeforeClass
public static void setupClass() throws XmlException, IOException {
sampleFileName = "src/test/resources/SimpleBufferAlgorithm.xml";
sampleFile = new File(sampleFileName);
WPSConfigTestUtil.generateMockConfig(SimpleBufferAlgorithmInputHandlerTest.class, "/org/n52/wps/io/test/inputhandler/generator/wps_config.xml");
execDoc = ExecuteDocument.Factory.parse(sampleFile);
inputArray = execDoc.getExecute().getDataInputs().getInputArray();
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() throws XmlException, IOException {
File f = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getFile());
projectRoot = new File(f.getParentFile().getParentFile().getParent());
}
@After
public void tearDown() {
}
@Test(expected = ExceptionReport.class)
public void testInputHandlerInitializationWithIncorrectAlgorithmName() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, "this.algorithm.name.does.not.exist").build();
}
@Test(expected = ExceptionReport.class)
public void testInputHandlerInitializationWithNullAlgorithmName() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, null).build();
}
@Test(expected = NullPointerException.class)
public void testInputHandlerInitializationWithNullInputsArray() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(null, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
}
@Test
public void testInputHandlerInitializationWithEmptyInputsArray() throws ExceptionReport {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(new InputType[]{}, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
assertThat(instance, not(nullValue()));
assertThat(instance.getParsedInputData().isEmpty(), is(true));
}
@Test
public void testInputHandlerInitialization() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
assertThat(instance, not(nullValue()));
}
@Test
public void testGetParsedInputDataWithCorrectInput() throws ExceptionReport, XmlException, IOException {
System.out.println("Testing testInputHandlerInitialization...");
InputHandler instance = new InputHandler.Builder(inputArray, "org.n52.wps.server.algorithm.SimpleBufferAlgorithm").build();
assertThat(instance.getParsedInputData().isEmpty(), is(false));
assertThat(instance.getParsedInputData().size(), equalTo(2));
assertThat(instance.getParsedInputData().keySet().size(), equalTo(2));
assertThat(instance.getParsedInputData().keySet(), containsInAnyOrder("width", "data"));
assertThat(instance.getParsedInputData().get("data").size(), equalTo(1));
assertThat(instance.getParsedInputData().get("width").size(), equalTo(1));
IData width = instance.getParsedInputData().get("width").get(0);
IData data = instance.getParsedInputData().get("data").get(0);
assertThat(data, is(notNullValue()));
assertThat(data.getSupportedClass().getName(), is(equalToIgnoringCase("org.geotools.feature.FeatureCollection")));
assertThat(data.getPayload(), is(notNullValue()));
assertThat(((DefaultFeatureCollection) data.getPayload()).getID(), is(equalToIgnoringCase("featureCollection")));
assertThat(((DefaultFeatureCollection) data.getPayload()).getSchema().getTypeName(), is(equalToIgnoringCase("tasmania_roads")));
assertThat(((DefaultFeatureCollection) data.getPayload()).getSchema().getAttributeCount(), equalTo(7));
assertThat(((DefaultFeatureCollection) data.getPayload()).fids().size(), equalTo(14));
assertThat(((DefaultFeatureCollection) data.getPayload()).fids().toArray()[0].toString(), is(equalToIgnoringCase("tasmania_roads.1")));
assertThat(((DefaultFeatureCollection) data.getPayload()).fids().toArray()[13].toString(), is(equalToIgnoringCase("tasmania_roads.9")));
assertThat(((DefaultFeatureCollection) data.getPayload()).getBounds().toString(), is(equalToIgnoringCase("ReferencedEnvelope[145.19754 : 148.27298000000002, -43.423512 : -40.852802]")));
assertThat(((DefaultFeatureCollection) data.getPayload()).getBounds().getArea(), equalTo(7.906064362400054d));
assertThat(((DefaultFeatureCollection) data.getPayload()).getBounds().getDimension(), equalTo(2));
assertThat(width, is(notNullValue()));
assertThat(((Double)width.getPayload()), equalTo(20.0d));
}
}

View File

@ -0,0 +1,61 @@
/**
* 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.request;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.xmlbeans.XmlException;
import org.n52.wps.commons.WPSConfig;
/**
*
* @author tkunicki
*/
public class WPSConfigTestUtil {
public static void generateMockConfig(String path) throws XmlException, IOException {
generateMockConfig(WPSConfigTestUtil.class, path);
}
public static void generateMockConfig(Class clazz, String path) throws XmlException, IOException {
InputStream configInputStream = null;
try {
configInputStream = new BufferedInputStream(clazz.getResourceAsStream(path));
WPSConfig.forceInitialization(configInputStream);
} finally {
if (configInputStream != null) {
try { configInputStream.close(); } catch (IOException ignore) {}
}
}
}
}

View File

@ -0,0 +1,379 @@
/**
* 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 static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import net.opengis.wps.x100.DocumentOutputDefinitionType;
import net.opengis.wps.x100.OutputDefinitionType;
import org.apache.xmlbeans.XmlException;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.n52.wps.server.request.ExecuteRequest;
import org.n52.wps.server.request.InputHandlerTest;
import org.n52.wps.server.request.WPSConfigTestUtil;
/**
* This class tests the getMimeType method of the ExecuteResponseBuilder class.
* TODO: Enhance with multiple in-/output tests
*
* @author Benjamin Pross(bpross-52n)
*
*/
public class ExecuteResponseBuilderTest {
private ExecuteRequest executeRequest;
private DocumentBuilderFactory fac;
@BeforeClass
public static void setupClass() throws XmlException, IOException {
WPSConfigTestUtil.generateMockConfig(InputHandlerTest.class, "/org/n52/wps/io/test/inputhandler/generator/wps_config.xml");
}
@Before
public void setUp() throws Exception {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
fac = DocumentBuilderFactory.newInstance();
fac.setNamespaceAware(true);
}
@Test
public void testGetMimeTypeLiteralOutputResponseDoc() {
try {
String sampleFileName = "src/test/resources/DTCExecuteLiteralOutputResponseDoc.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
/*
* only one output here
*/
OutputDefinitionType definition = executeRequest.getExecute().getResponseForm().getResponseDocument().getOutputArray(0);
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(definition);
/*
* this should be text/plain as LiteralData was requested
*/
assertTrue(mimeType.equals("text/plain"));
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeLiteralOutputRawData() {
try {
String sampleFileName = "src/test/resources/DTCExecuteLiteralOutputRawData.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
/*
* only one output here
*/
OutputDefinitionType definition = executeRequest.getExecute().getResponseForm().getRawDataOutput();
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(definition);
/*
* this should be text/plain as LiteralData was requested
*/
assertTrue(mimeType.equals("text/plain"));
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeComplexOutputRawData() {
try {
String sampleFileName = "src/test/resources/DTCExecuteComplexOutputRawDataMimeTiff.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is;
is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc;
doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
/*
* only one output here
*/
OutputDefinitionType definition = executeRequest.getExecute().getResponseForm().getRawDataOutput();
String originalMimeType = definition.getMimeType();
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(definition);
/*
* this should be the same mime type as requested
*/
assertTrue(mimeType.equals(originalMimeType));
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeComplexOutputResponseDoc() {
try {
String sampleFileName = "src/test/resources/DTCExecuteComplexOutputResponseDocMimeTiff.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is;
is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc;
doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
/*
* only one output here
*/
OutputDefinitionType definition = executeRequest.getExecute().getResponseForm().getResponseDocument().getOutputArray(0);
String originalMimeType = definition.getMimeType();
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(definition);
/*
* this should be the same mime type as requested
*/
assertTrue(mimeType.equals(originalMimeType));
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeMultipleComplexOutputsResponseDocPerm1() {
try {
String sampleFileName = "src/test/resources/MCIODTCExecuteComplexOutputResponseDocPerm1.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is;
is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc;
doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
DocumentOutputDefinitionType[] outputs = executeRequest.getExecute().getResponseForm().getResponseDocument().getOutputArray();
for (DocumentOutputDefinitionType documentOutputDefinitionType : outputs) {
String identifier = documentOutputDefinitionType.getIdentifier().getStringValue();
String originalMimeType = documentOutputDefinitionType.getMimeType();
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(documentOutputDefinitionType);
if(identifier.contains("Complex")){
assertTrue(mimeType.equals(originalMimeType));
}else{
assertTrue(mimeType.equals("text/plain") || mimeType.equals("text/xml"));
}
}
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeMultipleComplexOutputsResponseDocPerm2() {
try {
String sampleFileName = "src/test/resources/MCIODTCExecuteComplexOutputResponseDocPerm2.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is;
is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc;
doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
DocumentOutputDefinitionType[] outputs = executeRequest.getExecute().getResponseForm().getResponseDocument().getOutputArray();
for (DocumentOutputDefinitionType documentOutputDefinitionType : outputs) {
String identifier = documentOutputDefinitionType.getIdentifier().getStringValue();
String originalMimeType = documentOutputDefinitionType.getMimeType();
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(documentOutputDefinitionType);
if(identifier.contains("Complex")){
assertTrue(mimeType.equals(originalMimeType));
}else{
assertTrue(mimeType.equals("text/plain") || mimeType.equals("text/xml"));
}
}
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeBBOXOutputResponseDoc() {
try {
String sampleFileName = "src/test/resources/DTCExecuteBBOXOutputResponseDoc.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is;
is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc;
doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
/*
* only one output here
*/
OutputDefinitionType definition = executeRequest.getExecute().getResponseForm().getResponseDocument().getOutputArray(0);
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(definition);
/*
* this should be text/xml as BBOXData was requested
*/
assertTrue(mimeType.equals("text/xml"));
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testGetMimeTypeBBOXOutputRawData() {
try {
String sampleFileName = "src/test/resources/DTCExecuteBBOXOutputRawData.xml";
File sampleFile = new File(sampleFileName);
FileInputStream is;
is = new FileInputStream(sampleFile);
// parse the InputStream to create a Document
Document doc;
doc = fac.newDocumentBuilder().parse(is);
is.close();
executeRequest = new ExecuteRequest(doc);
/*
* only one output here
*/
OutputDefinitionType definition = executeRequest.getExecute().getResponseForm().getRawDataOutput();
String mimeType = executeRequest.getExecuteResponseBuilder()
.getMimeType(definition);
/*
* this should be text/xml as BBOXData was requested
*/
assertTrue(mimeType.equals("text/xml"));
} catch (Exception e) {
fail(e.getMessage());
}
}
}

View File

@ -0,0 +1,256 @@
/**
* 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 static org.junit.Assert.assertTrue;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import net.opengis.ows.x11.LanguageStringType;
import net.opengis.wps.x100.ExecuteResponseDocument;
import net.opengis.wps.x100.ExecuteResponseDocument.ExecuteResponse;
import net.opengis.wps.x100.LiteralOutputType;
import net.opengis.wps.x100.OutputDescriptionType;
import net.opengis.wps.x100.ProcessBriefType;
import net.opengis.wps.x100.ProcessDescriptionType;
import net.opengis.wps.x100.ProcessDescriptionType.ProcessOutputs;
import net.opengis.wps.x100.ProcessDescriptionsDocument;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlValidationError;
import org.junit.Before;
import org.junit.Test;
import org.n52.wps.io.BasicXMLTypeFactory;
import org.n52.wps.io.data.ILiteralData;
import org.n52.wps.io.data.binding.literal.LiteralAnyURIBinding;
import org.n52.wps.io.data.binding.literal.LiteralBase64BinaryBinding;
import org.n52.wps.io.data.binding.literal.LiteralBooleanBinding;
import org.n52.wps.io.data.binding.literal.LiteralByteBinding;
import org.n52.wps.io.data.binding.literal.LiteralDateTimeBinding;
import org.n52.wps.io.data.binding.literal.LiteralDoubleBinding;
import org.n52.wps.io.data.binding.literal.LiteralFloatBinding;
import org.n52.wps.io.data.binding.literal.LiteralIntBinding;
import org.n52.wps.io.data.binding.literal.LiteralLongBinding;
import org.n52.wps.io.data.binding.literal.LiteralShortBinding;
import org.n52.wps.io.data.binding.literal.LiteralStringBinding;
import org.n52.wps.server.CapabilitiesConfiguration;
import org.n52.wps.server.WebProcessingService;
import org.n52.wps.server.request.Request;
/**
* @author BenjaminPross(bpross-52n)
*
* This class is for testing the updateResponseForLiteralData() method of the class OutputDataItem.java.
*
*/
public class OutputDataItemTest {
private ProcessDescriptionType descriptionsType;
private String processID = "org.n52.wps.server.response.OutputDataItemTest";
private ExecuteResponseDocument mockupResponseDocument;
private LanguageStringType outputTitle = LanguageStringType.Factory
.newInstance();
private LanguageStringType processTitle = LanguageStringType.Factory
.newInstance();
private Random random = new Random();
private List<ILiteralData> literalDataList;
@Before
public void setUp() {
literalDataList = new ArrayList<ILiteralData>();
String url = "";
try {
url = "http://52north.org";
literalDataList.add(new LiteralAnyURIBinding(new URL(url).toURI()));
} catch (Exception e1) {
System.out.println(url + " caused " + e1);
}
String uuid = UUID.randomUUID().toString();
literalDataList.add(new LiteralBase64BinaryBinding(uuid.getBytes()));
literalDataList.add(new LiteralBooleanBinding(true));
literalDataList.add(new LiteralByteBinding((byte) 127));
literalDataList.add(new LiteralDateTimeBinding(Calendar.getInstance()
.getTime()));
literalDataList.add(new LiteralDoubleBinding(random.nextDouble()));
literalDataList.add(new LiteralFloatBinding(random.nextFloat()));
literalDataList.add(new LiteralIntBinding(random.nextInt()));
literalDataList.add(new LiteralLongBinding(random.nextLong()));
literalDataList.add(new LiteralShortBinding((short) random.nextInt(Short.MAX_VALUE + 1)));
literalDataList.add(new LiteralStringBinding(uuid));
outputTitle.setStringValue("output title");
processTitle.setStringValue("process title");
ProcessDescriptionsDocument descriptionsDocument = ProcessDescriptionsDocument.Factory
.newInstance();
descriptionsType = descriptionsDocument.addNewProcessDescriptions()
.addNewProcessDescription();
descriptionsType.addNewIdentifier().setStringValue(processID);
mockupResponseDocument = createExecuteResponseDocument();
}
private ExecuteResponseDocument createExecuteResponseDocument() {
ExecuteResponseDocument doc = ExecuteResponseDocument.Factory
.newInstance();
ExecuteResponse responseElem = 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");
responseElem.setServiceInstance(CapabilitiesConfiguration.ENDPOINT_URL
+ "?REQUEST=GetCapabilities&SERVICE=WPS");
responseElem.setLang(WebProcessingService.DEFAULT_LANGUAGE);
responseElem.setService("WPS");
responseElem.setVersion(Request.SUPPORTED_VERSION);
ProcessBriefType process = responseElem.addNewProcess();
process.addNewIdentifier().setStringValue(processID);
process.setProcessVersion("1.0.0");
process.setTitle(processTitle);
responseElem.addNewStatus().setProcessSucceeded("Process successful");
responseElem.getStatus().setCreationTime(Calendar.getInstance());
responseElem.addNewProcessOutputs();
return doc;
}
@Test
public void testUpdateResponseForLiteralData() {
for (ILiteralData literalData : literalDataList) {
try {
testLiteralOutput(literalData);
} catch (Exception e) {
System.out.println("Test failed for " + literalData.getClass()
+ " " + e);
}
mockupResponseDocument.getExecuteResponse().getProcessOutputs()
.removeOutput(0);
}
}
private void testLiteralOutput(ILiteralData literalDataBinding)
throws Exception {
String startText = "Testing " + literalDataBinding.getClass()
+ " and value ";
String endText = "ResponseDocument valid for "
+ literalDataBinding.getClass() + " and value ";
if (literalDataBinding.getPayload() instanceof byte[]) {
byte[] bytes = (byte[]) literalDataBinding.getPayload();
String bytesAsIntegerValues = "[";
for (int i = 0; i < bytes.length; i++) {
if(i < bytes.length -1){
bytesAsIntegerValues = bytesAsIntegerValues
.concat((int) bytes[i] + ", ");
}else{
bytesAsIntegerValues = bytesAsIntegerValues
.concat((int) bytes[i] + "]");
}
}
startText = startText.concat("" + bytesAsIntegerValues);
endText = endText.concat("" + bytesAsIntegerValues);
} else {
startText = startText.concat("" + literalDataBinding.getPayload());
endText = endText.concat("" + literalDataBinding.getPayload());
}
System.out.println(startText);
ProcessOutputs processOutputs = descriptionsType.addNewProcessOutputs();
OutputDescriptionType outputDescType = processOutputs.addNewOutput();
outputDescType.addNewIdentifier().setStringValue("output");
LiteralOutputType outputType = outputDescType.addNewLiteralOutput();
String dataTypeAsString = BasicXMLTypeFactory
.getXMLDataTypeforBinding(literalDataBinding.getClass());
outputType.addNewDataType().setStringValue(dataTypeAsString);
OutputDataItem ouDI = new OutputDataItem(literalDataBinding, "output",
null, null, null, outputTitle, processID, descriptionsType);
ouDI.updateResponseForLiteralData(mockupResponseDocument,
dataTypeAsString);
assertTrue(validateResponseDocument(mockupResponseDocument));
System.out.println(endText);
System.out.println();
}
private boolean validateResponseDocument(ExecuteResponseDocument doc) {
XmlOptions xmlOptions = new XmlOptions();
List<XmlValidationError> xmlValidationErrorList = new ArrayList<XmlValidationError>();
xmlOptions.setErrorListener(xmlValidationErrorList);
boolean valid = doc.validate(xmlOptions);
if (!valid) {
System.err
.println("Error validating ExecuteResponseDocument for data type"
+ doc.getExecuteResponse().getProcessOutputs()
.getOutputArray(0).getData()
.getLiteralData().getDataType());
for (XmlValidationError xmlValidationError : xmlValidationErrorList) {
System.err.println("\tMessage: "
+ xmlValidationError.getMessage());
System.err.println("\tLocation of invalid XML: "
+ xmlValidationError.getCursorLocation().xmlText());
}
}
return valid;
}
}

View File

@ -0,0 +1,129 @@
/**
* 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 static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import net.opengis.wps.x100.ProcessDescriptionType;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.n52.wps.commons.WPSConfig;
import org.n52.wps.io.data.IData;
import org.n52.wps.io.data.binding.bbox.BoundingBoxData;
import org.n52.wps.server.IAlgorithm;
import org.n52.wps.server.algorithm.test.DummyTestClass;
/**
* This class is for testing RawData output.
*
* @author Benjamin Pross (bpross-52n)
*
*/
public class RawDataTest {
IAlgorithm algorithm;
ProcessDescriptionType processDescription;
String identifier;
@BeforeClass
public static void setUpClass() {
try {
WPSConfig.forceInitialization("../52n-wps-webapp/src/main/webapp/config/wps_config.xml");
} catch (XmlException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
@Before
public void setUp(){
algorithm = new DummyTestClass();
processDescription = algorithm.getDescription();
identifier = algorithm.getWellKnownName();
}
@Test
public void testBBoxRawDataOutputCRS(){
IData envelope = new BoundingBoxData(
new double[] { 46, 102 },
new double[] { 47, 103 }, "EPSG:4326");
InputStream is;
try {
RawData bboxRawData = new RawData(envelope, "BBOXOutputData", null, null, null, identifier, processDescription);
is = bboxRawData.getAsStream();
XmlObject bboxXMLObject = XmlObject.Factory.parse(is);
assertTrue(bboxXMLObject != null);
assertTrue(bboxXMLObject.getDomNode().getFirstChild().getNodeName().equals("wps:BoundingBoxData"));
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void testBBoxRawDataOutput(){
IData envelope = new BoundingBoxData(
new double[] { 46, 102 },
new double[] { 47, 103 }, null);
InputStream is;
try {
RawData bboxRawData = new RawData(envelope, "BBOXOutputData", null, null, null, identifier, processDescription);
is = bboxRawData.getAsStream();
XmlObject bboxXMLObject = XmlObject.Factory.parse(is);
assertTrue(bboxXMLObject != null);
assertTrue(bboxXMLObject.getDomNode().getFirstChild().getNodeName().equals("wps:BoundingBoxData"));
} catch (Exception e) {
fail(e.getMessage());
}
}
}

View File

@ -0,0 +1,84 @@
/**
* 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.test;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import net.opengis.wps.x100.ExecuteDocument;
import net.opengis.wps.x100.InputType;
import org.apache.xmlbeans.XmlException;
import org.junit.Assert;
import org.junit.Test;
import org.n52.wps.server.ExceptionReport;
import org.n52.wps.server.request.strategy.DefaultReferenceStrategy;
import org.n52.wps.server.request.strategy.IReferenceStrategy;
public class HttpInputTest {
static final String sampleFileName = "src/test/resources/InputTestExecuteSample.xml";
@Test
public void testHttpInput() throws XmlException, IOException{
// Arrange
File sample = new File(sampleFileName);
ExecuteDocument execDoc = ExecuteDocument.Factory.parse(sample);
InputType[] inputArray = execDoc.getExecute().getDataInputs().getInputArray();
// Act & Assert
for (InputType currentInput : inputArray){
System.out.println("Testing input " + currentInput.getIdentifier().getStringValue());
IReferenceStrategy strategy = new DefaultReferenceStrategy();
try {
InputStream is = strategy.fetchData(currentInput);
Assert.assertNotNull(is);
printStream(is);
} catch (ExceptionReport e) {
e.printStackTrace();
}
}
}
private static void printStream (InputStream is) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line = null;
while((line = in.readLine()) != null) {
System.out.println(line);
}
}
}

View File

@ -0,0 +1,72 @@
/**
* 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.test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.n52.wps.server.RetrieveResultServlet;
public class UUIDTest {
RetrieveResultServlet resultServlet;
@Before
public void setup(){
resultServlet = new RetrieveResultServlet();
}
@Test
public void testUUIDValidationValidStatusID(){
String id1 = "615c4b53-13a6-4228-9bd2-5bc4a0b09e95";
assertTrue(resultServlet.isIDValid(id1));
}
@Test
public void testUUIDValidationValidResultID(){
String id2 = "615c4b53-13a6-4228-9bd2-5bc4a0b09e95result.49b52cb6-5fe6-4812-8faf-ac7bf338ee4d";
assertTrue(resultServlet.isIDValid(id2));
}
@Test
public void testUUIDValidationInvalidStatusID(){
String id3 = "1143eb2c-b93e-4340-8769-1437b621bd5e%3Cscript%3Ealert%28%27oh%20noes%27%29%3B%3C/script%3E";
assertFalse((resultServlet.isIDValid(id3)));
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0"
xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>BBOXInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:BoundingBoxData crs="EPSG:4326">
<ows:LowerCorner>46.75 13.05</ows:LowerCorner>
<ows:UpperCorner>46.85 13.25</ows:UpperCorner>
</wps:BoundingBoxData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput>
<ows:Identifier>BBOXOutputData</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>BBOXInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:BoundingBoxData crs="EPSG:4326">
<ows:LowerCorner>46.75 13.05</ows:LowerCorner>
<ows:UpperCorner>46.85 13.25</ows:UpperCorner>
</wps:BoundingBoxData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="false">
<wps:Output asReference="false" mimeType="image/tiff">
<ows:Identifier>BBOXOutputData</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0"
xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>ComplexInputData</ows:Identifier>
<wps:Reference mimeType="image/tiff"
xlink:href="http://52north.org/files/geoprocessing/Testdata/elev_srtm_30m21.tif" />
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="image/tiff">
<ows:Identifier>ComplexOutputData</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>ComplexInputData</ows:Identifier>
<wps:Reference mimeType="image/tiff" xlink:href="http://52north.org/files/geoprocessing/Testdata/elev_srtm_30m21.tif"/>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="false">
<wps:Output asReference="false" mimeType="image/tiff">
<ows:Identifier>ComplexOutputData</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0"
xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>LiteralInputData</ows:Identifier>
<wps:Data>
<wps:LiteralData>007</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput>
<ows:Identifier>LiteralOutputData</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>LiteralInputData</ows:Identifier>
<wps:Data>
<wps:LiteralData>007</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="false">
<wps:Output asReference="false">
<ows:Identifier>LiteralOutputData</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.DummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>BBOXInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:BoundingBoxData>
<ows:LowerCorner>46.75 13.05</ows:LowerCorner>
<ows:UpperCorner>46.85 13.25</ows:UpperCorner>
</wps:BoundingBoxData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="false">
<wps:Output asReference="false">
<ows:Identifier>BBOXOutputData</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>HTTP_INPUT_TEST</ows:Identifier>
<wps:DataInputs>
<!-- simple get 1 -->
<wps:Input>
<ows:Identifier>INPUT1</ows:Identifier>
<wps:Reference xlink:href="http://52north.org/communities/geoprocessing/index.html"/>
</wps:Input>
<!-- simple get 2 -->
<wps:Input>
<ows:Identifier>INPUT2</ows:Identifier>
<wps:Reference xlink:href="http://geoprocessing.demo.52north.org:8080/wps2/WebProcessingService">
<wps:Body>
<wps:GetCapabilities service="WPS" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsGetCapabilities_request.xsd">
<wps:AcceptVersions>
<ows:Version>1.0.0</ows:Version>
</wps:AcceptVersions>
</wps:GetCapabilities>
</wps:Body>
</wps:Reference>
</wps:Input>
<!-- TODO: set up inputs for POST and "POST w/ body reference" -->
</wps:DataInputs>
<wps:ResponseForm>
<wps:RawDataOutput mimeType="application/x-netcdf">
<ows:Identifier>RESULT</ows:Identifier>
</wps:RawDataOutput>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,19 @@
<wps:Execute xmlns:wps="http://www.opengis.net/wps/1.0.0" version="1.0.0" service="WPS" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ows:Identifier xmlns:ows="http://www.opengis.net/ows/1.1">org.n52.wps.server.algorithm.test.LongRunningDummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier xmlns:ows="http://www.opengis.net/ows/1.1">ComplexInputData</ows:Identifier>
<ows:Title xmlns:ows="http://www.opengis.net/ows/1.1">ComplexInputData</ows:Title>
<wps:Reference mimeType="image/tiff" xlink:href="" xmlns:xlink="http://www.w3.org/1999/xlink" method="GET"/>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument storeExecuteResponse="true">
<wps:Output asReference="true" mimeType="application/PDF">
<ows:Identifier xmlns:ows="http://www.opengis.net/ows/1.1">ComplexOutputData</ows:Identifier>
<ows:Title xmlns:ows="http://www.opengis.net/ows/1.1"/>
<ows:Abstract xmlns:ows="http://www.opengis.net/ows/1.1"/>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.MultipleComplexInAndOutputsDummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>ComplexInputData1</ows:Identifier>
<wps:Reference mimeType="image/tiff" xlink:href="http://52north.org/files/geoprocessing/Testdata/elev_srtm_30m21.tif"/>
</wps:Input>
<wps:Input>
<ows:Identifier>ComplexInputData2</ows:Identifier>
<wps:Reference mimeType="image/png" xlink:href="http://geoprocessing.demo.52north.org:8080/openlayers-example/52n48x48-transp.png"/>
</wps:Input>
<wps:Input>
<ows:Identifier>BBOXInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:BoundingBoxData crs="EPSG:4326">
<ows:LowerCorner>46.75 13.05</ows:LowerCorner>
<ows:UpperCorner>46.85 13.25</ows:UpperCorner>
</wps:BoundingBoxData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>LiteralInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:LiteralData>007</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="false">
<wps:Output asReference="false">
<ows:Identifier>BBOXOutputData</ows:Identifier>
</wps:Output>
<wps:Output asReference="false" mimeType="image/tiff" encoding="base64">
<ows:Identifier>ComplexOutputData1</ows:Identifier>
</wps:Output>
<wps:Output asReference="false" mimeType="image/png" encoding="base64">
<ows:Identifier>ComplexOutputData2</ows:Identifier>
</wps:Output>
<wps:Output asReference="false">
<ows:Identifier>LiteralOutputData</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.test.MultipleComplexInAndOutputsDummyTestClass</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>ComplexInputData2</ows:Identifier>
<wps:Reference mimeType="image/png" xlink:href="http://geoprocessing.demo.52north.org:8080/openlayers-example/52n48x48-transp.png"/>
</wps:Input>
<wps:Input>
<ows:Identifier>ComplexInputData1</ows:Identifier>
<wps:Reference mimeType="image/tiff" xlink:href="http://52north.org/files/geoprocessing/Testdata/elev_srtm_30m21.tif"/>
</wps:Input>
<wps:Input>
<ows:Identifier>BBOXInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:BoundingBoxData crs="EPSG:4326">
<ows:LowerCorner>46.75 13.05</ows:LowerCorner>
<ows:UpperCorner>46.85 13.25</ows:UpperCorner>
</wps:BoundingBoxData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>LiteralInputData</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:LiteralData>007</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument status="false" storeExecuteResponse="false">
<wps:Output asReference="false" mimeType="image/png" encoding="base64">
<ows:Identifier>ComplexOutputData2</ows:Identifier>
</wps:Output>
<wps:Output asReference="false" mimeType="image/tiff" encoding="base64">
<ows:Identifier>ComplexOutputData1</ows:Identifier>
</wps:Output>
<wps:Output asReference="false">
<ows:Identifier>BBOXOutputData</ows:Identifier>
</wps:Output>
<wps:Output asReference="false">
<ows:Identifier>LiteralOutputData</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

View File

@ -0,0 +1 @@
org.n52.wps.server.CapabilitiesGetProcessDescriptionExceptionTest$InstantiationExceptionAlgorithm

View File

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wps:Execute service="WPS" version="1.0.0" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsExecute_request.xsd">
<ows:Identifier>org.n52.wps.server.algorithm.SimpleBufferAlgorithm</ows:Identifier>
<wps:DataInputs>
<wps:Input>
<ows:Identifier>data</ows:Identifier>
<wps:Data>
<wps:ComplexData schema="http://schemas.opengis.net/gml/3.1.0/base/feature.xsd" mimeType="text/xml; subtype=gml/3.1.0">
<wfs:FeatureCollection numberOfFeatures="0" timeStamp="2012-03-08T18:26:46.296+01:00" xsi:schemaLocation="http://www.openplans.org/topp http://geoprocessing.demo.52north.org:8080/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=topp%3Atasmania_roads http://www.opengis.net/wfs http://geoprocessing.demo.52north.org:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd" xmlns:ogc="http://www.opengis.net/ogc" xmlns:tiger="http://www.census.gov" xmlns:cite="http://www.opengeospatial.net/cite" xmlns:nurc="http://www.nurc.nato.int" xmlns:sde="http://geoserver.sf.net" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:it.geosolutions="http://www.geo-solutions.it" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:diss="diss" xmlns:sf="http://www.openplans.org/spearfish" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">
<gml:featureMembers>
<topp:tasmania_roads gml:id="tasmania_roads.1">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>146.46858200000003 -41.241478 146.574768 -41.251186 146.64041099999997 -41.255154 146.76612899999998 -41.332348 146.79418900000002 -41.34417 146.82217400000002 -41.362988 146.86343399999998 -41.380234 146.899521 -41.379452 146.929504 -41.378227 147.008041 -41.356079 147.098343 -41.362919</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>street</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.2">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.098343 -41.362919 147.17305 -41.452778 147.213867 -41.503773 147.234894 -41.546661 147.251129 -41.573826 147.26466399999998 -41.602474 147.28448500000002 -41.617554 147.30058300000002 -41.637878</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>highway</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.3">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.30058300000002 -41.637878 147.225815 -41.626938 147.18331899999998 -41.619236 147.08236699999998 -41.577755 147.03132599999998 -41.565205 146.96148699999998 -41.564186 146.92454500000002 -41.568565 146.876328 -41.569614 146.783722 -41.56073 146.684937 -41.536232 146.614258 -41.478153 146.61999500000002 -41.423958 146.582581 -41.365482 146.52478000000002 -41.29541 146.47749299999998 -41.277622 146.46858200000003 -41.241478</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>lane</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.4">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.522247 -41.859921 147.55186500000002 -41.927834 147.59732100000002 -42.017418 147.578644 -42.113216 147.541656 -42.217743 147.46867400000002 -42.22662</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>highway</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.5">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>146.103699 -41.171677 146.30361900000003 -41.237202 146.36222800000002 -41.236279 146.39418 -41.245384 146.44372600000003 -41.244308 146.46858200000003 -41.241478</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>gravel</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.6">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>145.856018 -41.08007 145.944839 -41.119896 146.03799400000003 -41.150059 146.103699 -41.171677</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>road</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.7">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.46867400000002 -42.22662 147.474945 -42.292259 147.467697 -42.301292 147.45182799999998 -42.341656 147.42454500000002 -42.378723 147.366013 -42.412552 147.345779 -42.432449 147.28932200000003 -42.476475 147.26451100000003 -42.503899 147.25991800000003 -42.547539 147.24940500000002 -42.614006 147.278351 -42.693249 147.284271 -42.757759 147.25674400000003 -42.778393</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>highway</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.8">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>148.249252 -41.860851 148.23443600000002 -41.901783 148.19212299999998 -41.93721 148.15576199999998 -41.953667 148.12773099999998 -41.994537 148.053131 -42.100563</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>road</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.9">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>145.19754 -40.878323 145.24667399999998 -40.86021 145.29328900000002 -40.852802 145.46522499999998 -40.897865 145.538498 -40.936264 145.554062 -40.939201 145.60211199999998 -40.962936 145.646362 -40.98243 145.68383799999998 -40.989883 145.71058699999998 -40.996201 145.74429300000003 -41.007545 145.80195600000002 -41.041782 145.856018 -41.08007</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>logging</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.10">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.360001 -42.91993 147.348816 -42.93726 147.28504900000001 -42.979027 147.220886 -42.995876 147.16442899999998 -43.027004 147.068237 -43.06319 146.96463 -43.116447 146.94955399999998 -43.17004 146.95369 -43.209591 146.96412700000002 -43.224545 146.97572300000002 -43.250484 146.98075899999998 -43.2701 146.98260499999998 -43.287716 146.970871 -43.31691 146.940521 -43.33812 146.94305400000002 -43.362263 146.95219400000002 -43.39278 146.95542899999998 -43.423512</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>road</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.11">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.30058300000002 -41.637878 147.372009 -41.695503 147.40258799999998 -41.725574 147.44406099999998 -41.749676 147.490433 -41.782482 147.506866 -41.795624 147.522919 -41.835609 147.522247 -41.859921</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>highway</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.12">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>148.053131 -42.100563 148.028229 -42.188286 148.00225799999998 -42.2295 147.96995500000003 -42.254417 147.96029700000003 -42.284897 147.942719 -42.398819 147.92640699999998 -42.486034 147.875092 -42.538582 147.832001 -42.587299 147.744217 -42.631607 147.69329800000003 -42.656067 147.61819500000001 -42.691135 147.57531699999998 -42.743092 147.57829299999997 -42.769539 147.54785199999998 -42.814312 147.50669900000003 -42.842907 147.488312 -42.877041 147.44969200000003 -42.901054 147.416809 -42.902828</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>road</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.13">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.098343 -41.362919 147.065445 -41.311977 147.02407799999997 -41.257534 146.981445 -41.211391 146.94822699999997 -41.181595 146.92677300000003 -41.172501 146.905029 -41.147144 146.940765 -41.085857 146.96266200000002 -41.075096 147.02108800000002 -41.080925 147.09922799999998 -41.123959 147.187607 -41.150597 147.28202800000003 -41.104244 147.29571499999997 -41.075798 147.30659500000002 -41.062832 147.32574499999998 -41.053524 147.36299100000002 -41.080441 147.41902199999998 -41.081764 147.46588100000002 -41.06089 147.51930199999998 -41.092793 147.528595 -41.137089 147.552521 -41.193565 147.594223 -41.233875 147.73440599999998 -41.239891 147.82937600000002 -41.196636 147.882614 -41.163197 147.91127 -41.163109 147.985168 -41.226128 148.022156 -41.292599 148.07511899999997 -41.313915 148.200104 -41.323097 148.23619100000002 -41.339245 148.27298000000002 -41.383488 148.25 -41.45713 148.254395 -41.53941 148.26243599999998 -41.585217 148.249252 -41.860851</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>road</topp:TYPE>
</topp:tasmania_roads>
<topp:tasmania_roads gml:id="tasmania_roads.14">
<topp:the_geom>
<gml:MultiLineString>
<gml:lineStringMember>
<gml:LineString>
<gml:posList>147.25674400000003 -42.778393 147.22018400000002 -42.824776 147.179596 -42.82143 147.11132800000001 -42.795731 147.057098 -42.741581 147.00347900000003 -42.704803 146.91909800000002 -42.622734 146.91053799999997 -42.610928 146.88998400000003 -42.585396 146.83844 -42.572792 146.78569 -42.539352 146.724335 -42.485966 146.695023 -42.469582 146.64987200000002 -42.450371 146.604965 -42.432274 146.578781 -42.408531 146.539307 -42.364208 146.525055 -42.30883 146.558044 -42.275948 146.57624800000002 -42.23777 146.58146699999998 -42.203426 146.490005 -42.180222 146.3797 -42.146332 146.33406100000002 -42.138741 146.270966 -42.165703 146.197296 -42.224072 146.167908 -42.244835 146.16493200000002 -42.245171 146.111023 -42.265202 146.03747600000003 -42.239738 145.981628 -42.187851 145.85391199999998 -42.133492 145.819611 -42.129154 145.72052000000002 -42.104084 145.61857600000002 -42.056023 145.541718 -42.027241 145.48628200000002 -41.983326 145.452744 -41.926544 145.494034 -41.896477 145.59173600000003 -41.860214 145.64211999999998 -41.838398 145.669449 -41.830734 145.680923 -41.795753 145.68296800000002 -41.743221 145.67515600000002 -41.710377 145.680115 -41.688908 145.70106500000003 -41.648228 145.71479799999997 -41.609509 145.62919599999998 -41.462051 145.64889499999998 -41.470337 145.633423 -41.420902 145.631866 -41.36528 145.640854 -41.301533 145.700424 -41.242611 145.77242999999999 -41.193897 145.80233800000002 -41.161488 145.856018 -41.08007</gml:posList>
</gml:LineString>
</gml:lineStringMember>
</gml:MultiLineString>
</topp:the_geom>
<topp:TYPE>road</topp:TYPE>
</topp:tasmania_roads>
</gml:featureMembers>
</wfs:FeatureCollection>
</wps:ComplexData>
</wps:Data>
</wps:Input>
<wps:Input>
<ows:Identifier>width</ows:Identifier>
<ows:Title>Distance which people will walk to get to a playground.</ows:Title>
<wps:Data>
<wps:LiteralData>20</wps:LiteralData>
</wps:Data>
</wps:Input>
</wps:DataInputs>
<wps:ResponseForm>
<wps:ResponseDocument>
<wps:Output>
<ows:Identifier>result</ows:Identifier>
</wps:Output>
</wps:ResponseDocument>
</wps:ResponseForm>
</wps:Execute>

File diff suppressed because it is too large Load Diff