branch for release 4.6.1
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/branches/data-analysis/52n-wps-algorithm-d4s/3.6@151432 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
commit
b95572fe28
|
@ -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>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>52n-wps-algorithm-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>
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,38 @@
|
|||
Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
Software GmbH
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
This project includes:
|
||||
52North WPS Algorithm API under Apache License, Version 2.0
|
||||
52North WPS Commons under Apache License, Version 2.0
|
||||
52North WPS Input/Output API under Apache License, Version 2.0
|
||||
Commons Codec under The Apache Software License, Version 2.0
|
||||
Commons IO under The Apache Software License, Version 2.0
|
||||
Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0
|
||||
Hamcrest Core under New BSD License
|
||||
Joda time under Apache 2
|
||||
JUnit under Common Public License Version 1.0
|
||||
OGC OWS schema (spec. v1.1.0) under The Apache Software License, Version 2.0
|
||||
OGC WPS schema (spec. v1.0.0) under The Apache Software License, Version 2.0
|
||||
SLF4J API Module under MIT License
|
||||
SLF4J Simple Binding under MIT License
|
||||
stax-utils under BSD
|
||||
Stax2 API under The BSD License
|
||||
W3C xlink schema (spec. v1.1.0) under The Apache Software License, Version 2.0
|
||||
Woodstox under The Apache Software License, Version 2.0
|
||||
WPS-Config under The Apache Software License, Version 2.0
|
||||
Xalan Java under The Apache Software License, Version 2.0
|
||||
Xalan Java Serializer under The Apache Software License, Version 2.0
|
||||
XmlBeans under The Apache Software License, Version 2.0
|
||||
|
|
@ -0,0 +1 @@
|
|||
${gcube.license}
|
|
@ -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.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<ReleaseNotes>
|
||||
<Changeset component="${groupId}.${artifactId}.3-6-1" date="2017-07-05">
|
||||
<Change>First Release</Change>
|
||||
</Changeset>
|
||||
</ReleaseNotes>
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
<?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-algorithm-gcube</artifactId>
|
||||
<name>52North WPS Algorithm API modified for gcube</name>
|
||||
<version>3.6.1-SNAPSHOT</version>
|
||||
<description>API for implementation of algorithms to be exposed as web processes</description>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>.</directory>
|
||||
<includes>
|
||||
<include>LICENSE</include>
|
||||
<include>NOTICE</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<header>../misc/licenses/license_header_for_api_modules.txt</header>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jasig.maven</groupId>
|
||||
<artifactId>maven-notice-plugin</artifactId>
|
||||
<configuration>
|
||||
<noticeTemplate>../misc/licenses/NOTICE_for_api_modules.template</noticeTemplate>
|
||||
<licenseMapping>
|
||||
<param>../misc/licenses/license-mappings.xml</param>
|
||||
</licenseMapping>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>check-licenses</id>
|
||||
<phase />
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.12.1.GA</version>
|
||||
</dependency>
|
||||
<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-io</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>52n-xml-wps-v100</artifactId>
|
||||
<groupId>org.n52.sensorweb</groupId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.n52.wps</groupId>
|
||||
<artifactId>52n-wps-config</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# 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:01 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.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
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface Algorithm {
|
||||
String identifier() default "";
|
||||
String title() default "";
|
||||
String abstrakt() default ""; // 'abstract' is java reserved keyword
|
||||
String version();
|
||||
boolean storeSupported() default true;
|
||||
boolean statusSupported() default true;
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javassist.ClassClassPath;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.ExecuteMethodBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.ComplexDataInputFieldAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.ComplexDataInputMethodAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.ComplexDataOutputFieldAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.ComplexDataOutputMethodAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.ExecuteAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.InputAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.LiteralDataInputFieldAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.LiteralDataInputMethodAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.LiteralDataOutputFieldAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.LiteralDataOutputMethodAnnotationParser;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationParser.OutputAnnotationParser;
|
||||
import org.n52.wps.algorithm.descriptor.AlgorithmDescriptor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class AnnotatedAlgorithmIntrospector {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(AnnotatedAlgorithmIntrospector.class);
|
||||
|
||||
private final static List<InputAnnotationParser<?,Field,?>> INPUT_FIELD_PARSERS;
|
||||
private final static List<InputAnnotationParser<?,Method,?>> INPUT_METHOD_PARSERS;
|
||||
private final static List<OutputAnnotationParser<?,Field,?>> OUTPUT_FIELD_PARSERS;
|
||||
private final static List<OutputAnnotationParser<?,Method,?>> OUTPUT_METHOD_PARSERS;
|
||||
private final static ExecuteAnnotationParser PROCESS_PARSER;
|
||||
|
||||
static {
|
||||
List<InputAnnotationParser<?,Field,?>> inputFieldParsers =
|
||||
new ArrayList<InputAnnotationParser<?,Field,?>>();
|
||||
inputFieldParsers.add(new LiteralDataInputFieldAnnotationParser());
|
||||
inputFieldParsers.add(new ComplexDataInputFieldAnnotationParser());
|
||||
INPUT_FIELD_PARSERS = Collections.unmodifiableList(inputFieldParsers);
|
||||
|
||||
List<InputAnnotationParser<?,Method,?>> inputMethodParsers =
|
||||
new ArrayList<InputAnnotationParser<?,Method,?>>();
|
||||
inputMethodParsers.add(new LiteralDataInputMethodAnnotationParser());
|
||||
inputMethodParsers.add(new ComplexDataInputMethodAnnotationParser());
|
||||
INPUT_METHOD_PARSERS = Collections.unmodifiableList(inputMethodParsers);
|
||||
|
||||
List<OutputAnnotationParser<?,Field,?>> outputFieldParsers =
|
||||
new ArrayList<OutputAnnotationParser<?,Field,?>>();
|
||||
outputFieldParsers.add(new LiteralDataOutputFieldAnnotationParser());
|
||||
outputFieldParsers.add(new ComplexDataOutputFieldAnnotationParser());
|
||||
OUTPUT_FIELD_PARSERS = Collections.unmodifiableList(outputFieldParsers);
|
||||
|
||||
List<OutputAnnotationParser<?,Method,?>> outputMethodParsers =
|
||||
new ArrayList<OutputAnnotationParser<?,Method,?>>();
|
||||
outputMethodParsers.add(new LiteralDataOutputMethodAnnotationParser());
|
||||
outputMethodParsers.add(new ComplexDataOutputMethodAnnotationParser());
|
||||
OUTPUT_METHOD_PARSERS = Collections.unmodifiableList(outputMethodParsers);
|
||||
|
||||
PROCESS_PARSER = new ExecuteAnnotationParser();
|
||||
}
|
||||
|
||||
private final static Map<Class<?>, AnnotatedAlgorithmIntrospector> INTROSPECTOR_MAP =
|
||||
new HashMap<Class<?>, AnnotatedAlgorithmIntrospector>();
|
||||
public static synchronized AnnotatedAlgorithmIntrospector getInstrospector(Class<?> algorithmClass) {
|
||||
AnnotatedAlgorithmIntrospector introspector = INTROSPECTOR_MAP.get(algorithmClass);
|
||||
if (introspector == null) {
|
||||
introspector = new AnnotatedAlgorithmIntrospector(algorithmClass);
|
||||
INTROSPECTOR_MAP.put(algorithmClass, introspector);
|
||||
}
|
||||
return introspector;
|
||||
}
|
||||
|
||||
private Class<?> algorithmClass;
|
||||
|
||||
private AlgorithmDescriptor algorithmDescriptor;
|
||||
|
||||
private ExecuteMethodBinding executeMethodBinding;
|
||||
private Map<String, AnnotationBinding.InputBinding<?, ?>> inputBindingMap;
|
||||
private Map<String, AnnotationBinding.OutputBinding<?, ?>> outputBindingMap;
|
||||
|
||||
|
||||
public AnnotatedAlgorithmIntrospector(Class<?> algorithmClass) {
|
||||
|
||||
this.algorithmClass = algorithmClass;
|
||||
|
||||
inputBindingMap = new LinkedHashMap<String, InputBinding<?, ?>>();
|
||||
outputBindingMap = new LinkedHashMap<String, OutputBinding<?, ?>>();
|
||||
|
||||
parseClass();
|
||||
|
||||
inputBindingMap = Collections.unmodifiableMap(inputBindingMap);
|
||||
outputBindingMap = Collections.unmodifiableMap(outputBindingMap);
|
||||
}
|
||||
|
||||
//Modified by Gianpaolo Coro
|
||||
private void parseClass() {
|
||||
|
||||
if (!algorithmClass.isAnnotationPresent(Algorithm.class)) {
|
||||
throw new RuntimeException("Class isn't annotated with an Algorithm annotation");
|
||||
}
|
||||
|
||||
boolean validContructor = false;
|
||||
try {
|
||||
Constructor defaultConstructor = algorithmClass.getConstructor(new Class[0]);
|
||||
validContructor = (defaultConstructor.getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC;
|
||||
} catch (NoSuchMethodException ex) {
|
||||
// inherit error message on fall through...
|
||||
} catch (SecurityException ex) {
|
||||
throw new RuntimeException("Current security policy limits use of reflection, error introspecting " + algorithmClass.getName());
|
||||
}
|
||||
if (!validContructor) {
|
||||
throw new RuntimeException("Classes with Algorithm annotation require public no-arg constructor, error introspecting " + algorithmClass.getName());
|
||||
}
|
||||
|
||||
|
||||
AlgorithmDescriptor.Builder<?> algorithmBuilder = null;
|
||||
|
||||
Algorithm algorithm = algorithmClass.getAnnotation(Algorithm.class);
|
||||
|
||||
//MODIFICATIONS BY G CORO TO ACCOUNT FOR METHODS ORDER
|
||||
List<Method> sortedMethods = new ArrayList<Method>();
|
||||
List<Integer> methodsIdxs = new ArrayList<Integer>();
|
||||
try{
|
||||
for (Method m:algorithmClass.getDeclaredMethods()){
|
||||
//System.out.println("Javaassist Analysing method "+m.getName());
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
ClassClassPath ccpath = new ClassClassPath(m.getDeclaringClass());
|
||||
pool.insertClassPath(ccpath);
|
||||
//System.out.println("Javaassist searching for canonical name "+m.getDeclaringClass().getCanonicalName());
|
||||
CtClass cc = pool.get(m.getDeclaringClass().getCanonicalName());
|
||||
//System.out.println("Javaassist cc "+cc.getName());
|
||||
CtMethod javassistMethod = cc.getDeclaredMethod(m.getName());
|
||||
//System.out.println("Javaassist method "+javassistMethod.getName());
|
||||
|
||||
int linenumber = javassistMethod.getMethodInfo().getLineNumber(0);
|
||||
//System.out.println("Javaassist line number "+linenumber);
|
||||
int i=0;
|
||||
for (Integer methodsIdx :methodsIdxs){
|
||||
if (methodsIdx>linenumber){
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
sortedMethods.add(i,m);
|
||||
methodsIdxs.add(i,linenumber);
|
||||
}
|
||||
}catch(Exception e){
|
||||
LOGGER.warn("error getting method order",e);
|
||||
}
|
||||
|
||||
Method[] sMethods = sortedMethods.toArray(new Method[sortedMethods.size()]);
|
||||
|
||||
algorithmBuilder = AlgorithmDescriptor.builder(
|
||||
algorithm.identifier().length() > 0 ?
|
||||
algorithm.identifier() :
|
||||
algorithmClass.getCanonicalName());
|
||||
|
||||
|
||||
|
||||
|
||||
algorithmBuilder.
|
||||
title(algorithm.title()).
|
||||
abstrakt(algorithm.abstrakt()).
|
||||
version(algorithm.version()).
|
||||
storeSupported(algorithm.storeSupported()).
|
||||
statusSupported(algorithm.statusSupported());
|
||||
|
||||
parseElements(sMethods,
|
||||
INPUT_METHOD_PARSERS,
|
||||
OUTPUT_METHOD_PARSERS);
|
||||
parseElements(algorithmClass.getDeclaredFields(),
|
||||
INPUT_FIELD_PARSERS,
|
||||
OUTPUT_FIELD_PARSERS);
|
||||
|
||||
|
||||
for (Method method : sMethods) {
|
||||
if (method.isAnnotationPresent(PROCESS_PARSER.getSupportedAnnotation())) {
|
||||
ExecuteMethodBinding executeMethodBinding = PROCESS_PARSER.parse(method);
|
||||
if (executeMethodBinding != null) {
|
||||
if (this.executeMethodBinding != null) {
|
||||
// we need to error out here because ordering of getDeclaredMethods() or
|
||||
// getMethods() is not guarenteed to be consistent, if it were consistent
|
||||
// maybe we could ignore this state, but having an algorithm behave
|
||||
// differently betweeen runtimes would be bad...
|
||||
throw new RuntimeException("Multiple execute method bindings encountered for class " + getClass().getCanonicalName());
|
||||
}
|
||||
this.executeMethodBinding = executeMethodBinding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.executeMethodBinding == null) {
|
||||
throw new RuntimeException("No execute method binding for class " + this.algorithmClass.getCanonicalName());
|
||||
}
|
||||
|
||||
for (InputBinding<?,?> inputBinding : inputBindingMap.values()) {
|
||||
algorithmBuilder.addInputDescriptor(inputBinding.getDescriptor());
|
||||
}
|
||||
for (OutputBinding<?,?> outputBinding : outputBindingMap.values()) {
|
||||
algorithmBuilder.addOutputDescriptor(outputBinding.getDescriptor());
|
||||
}
|
||||
algorithmDescriptor = algorithmBuilder.build();
|
||||
}
|
||||
|
||||
public AlgorithmDescriptor getAlgorithmDescriptor() {
|
||||
return algorithmDescriptor;
|
||||
}
|
||||
|
||||
public ExecuteMethodBinding getExecuteMethodBinding() {
|
||||
return executeMethodBinding;
|
||||
}
|
||||
|
||||
public Map<String, AnnotationBinding.InputBinding<?, ?>> getInputBindingMap() {
|
||||
return inputBindingMap;
|
||||
}
|
||||
|
||||
public Map<String, AnnotationBinding.OutputBinding<?, ?>> getOutputBindingMap() {
|
||||
return outputBindingMap;
|
||||
}
|
||||
|
||||
public <M extends AccessibleObject & Member> void parseElements(
|
||||
M members[],
|
||||
List<InputAnnotationParser<?,M,?>> inputParser,
|
||||
List<OutputAnnotationParser<?,M,?>> outputParser) {
|
||||
for (M member : members) {
|
||||
for (OutputAnnotationParser<?,M,?> parser : outputParser) {
|
||||
if (member.isAnnotationPresent(parser.getSupportedAnnotation())) {
|
||||
OutputBinding<?,?> binding = parser.parse(member);
|
||||
if (binding != null) {
|
||||
outputBindingMap.put(binding.getDescriptor().getIdentifier(), binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (InputAnnotationParser<?,M,?> parser : inputParser) {
|
||||
if (member.isAnnotationPresent(parser.getSupportedAnnotation())) {
|
||||
InputBinding<?,?> binding = parser.parse(member);
|
||||
if (binding != null) {
|
||||
inputBindingMap.put(binding.getDescriptor().getIdentifier(), binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,476 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.n52.wps.algorithm.descriptor.BoundDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.InputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.OutputDescriptor;
|
||||
import org.n52.wps.algorithm.util.ClassUtil;
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class AnnotationBinding<M extends AccessibleObject & Member> {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(AnnotationBinding.class);
|
||||
|
||||
private M member;
|
||||
|
||||
public AnnotationBinding(M member) {
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public M getMember() {
|
||||
return member;
|
||||
}
|
||||
|
||||
protected boolean checkModifier() {
|
||||
return (getMember().getModifiers() & Modifier.PUBLIC) != 0;
|
||||
}
|
||||
|
||||
public abstract boolean validate();
|
||||
|
||||
public static class ExecuteMethodBinding extends AnnotationBinding<Method> {
|
||||
|
||||
public ExecuteMethodBinding(Method method) {
|
||||
super(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
if (!checkModifier()) {
|
||||
LOGGER.error("Method {} with Execute annotation can't be used, not public.", getMember());
|
||||
return false;
|
||||
}
|
||||
// eh, do we really need to care about this?
|
||||
if (!getMember().getReturnType().equals(void.class)) {
|
||||
LOGGER.error("Method {} with Execute annotation can't be used, return type not void", getMember());
|
||||
return false;
|
||||
}
|
||||
if (getMember().getParameterTypes().length != 0) {
|
||||
LOGGER.error("Method {} with Execute annotation can't be used, method parameter count is > 0.", getMember());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void execute(Object annotatedInstance) {
|
||||
try {
|
||||
getMember().invoke(annotatedInstance);
|
||||
}catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Internal error executing process", ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Internal error executing process", ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
Throwable cause = ex.getCause() == null ? ex : ex.getCause();
|
||||
throw new RuntimeException(cause.getMessage(), cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class DataBinding<M extends AccessibleObject & Member, D extends BoundDescriptor> extends AnnotationBinding<M> {
|
||||
|
||||
private D descriptor;
|
||||
|
||||
public DataBinding(M member) {
|
||||
super(member);
|
||||
}
|
||||
|
||||
public void setDescriptor(D descriptor) {
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public D getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
public abstract Type getMemberType();
|
||||
|
||||
public Type getType() {
|
||||
return getMemberType();
|
||||
}
|
||||
|
||||
public Type getPayloadType() {
|
||||
Type type = getType();
|
||||
if (isTypeEnum()) {
|
||||
return String.class;
|
||||
}
|
||||
if (type instanceof Class<?>) {
|
||||
Class<?> inputClass = (Class<?>) type;
|
||||
if (inputClass.isPrimitive()) {
|
||||
return ClassUtil.wrap(inputClass);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean isTypeEnum() {
|
||||
Type inputType = getType();
|
||||
return (inputType instanceof Class<?>) && ((Class<?>) inputType).isEnum();
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class InputBinding<M extends AccessibleObject & Member, D extends InputDescriptor> extends DataBinding<M,D> {
|
||||
|
||||
public InputBinding(M member) {
|
||||
super(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
Type memberType = getMemberType();
|
||||
Type inputType = memberType;
|
||||
if (memberType instanceof Class<?>) {
|
||||
Class<?> memberClass = (Class<?>) memberType;
|
||||
if (List.class.isAssignableFrom(memberClass)) {
|
||||
// We treat List as List<? extends Object>
|
||||
inputType = NOT_PARAMETERIZED_TYPE;
|
||||
}
|
||||
} else if (memberType instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedMemberType = (ParameterizedType) memberType;
|
||||
Class<?> rawClass = (Class<?>) parameterizedMemberType.getRawType();
|
||||
if (List.class.isAssignableFrom(rawClass)) {
|
||||
inputType = parameterizedMemberType.getActualTypeArguments()[0];
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("Unable to infer concrete type information for " + getMember());
|
||||
}
|
||||
return inputType;
|
||||
}
|
||||
|
||||
public boolean isMemberTypeList() {
|
||||
Type memberType = getMemberType();
|
||||
if (memberType instanceof Class<?>) {
|
||||
return List.class.isAssignableFrom((Class<?>) memberType);
|
||||
} else if (memberType instanceof ParameterizedType) {
|
||||
Class<?> rawClass = (Class<?>) ((ParameterizedType) memberType).getRawType();
|
||||
return List.class.isAssignableFrom(rawClass);
|
||||
} else {
|
||||
LOGGER.error("Unable to infer concrete type information for " + getMember());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean checkType() {
|
||||
Type inputPayloadType = getPayloadType();
|
||||
Class<? extends IData> bindingClass = getDescriptor().getBinding();
|
||||
try {
|
||||
Class<?> bindingPayloadClass = bindingClass.getMethod("getPayload", (Class<?>[]) null).getReturnType();
|
||||
if (inputPayloadType instanceof Class<?>) {
|
||||
return ((Class<?>) inputPayloadType).isAssignableFrom(bindingPayloadClass);
|
||||
} else if (inputPayloadType instanceof ParameterizedType) {
|
||||
// i.e. List<FeatureCollection<SimpleFeatureType,SimpleFeature>>
|
||||
return ((Class<?>) ((ParameterizedType) inputPayloadType).getRawType()).isAssignableFrom(bindingPayloadClass);
|
||||
} else if (inputPayloadType instanceof WildcardType) {
|
||||
// i.e. List<? extends String> or List<? super String>
|
||||
WildcardType inputTypeWildcardType = (WildcardType) inputPayloadType;
|
||||
Type[] lowerBounds = inputTypeWildcardType.getLowerBounds();
|
||||
Type[] upperBounds = inputTypeWildcardType.getUpperBounds();
|
||||
Class<?> lowerBoundClass = null;
|
||||
Class<?> upperBoundClass = null;
|
||||
if (lowerBounds != null && lowerBounds.length > 0) {
|
||||
if (lowerBounds[0] instanceof Class<?>) {
|
||||
lowerBoundClass = (Class<?>) lowerBounds[0];
|
||||
} else if (lowerBounds[0] instanceof ParameterizedType) {
|
||||
lowerBoundClass = (Class<?>) ((ParameterizedType) lowerBounds[0]).getRawType();
|
||||
}
|
||||
}
|
||||
if (upperBounds != null && upperBounds.length > 0) {
|
||||
if (upperBounds[0] instanceof Class<?>) {
|
||||
upperBoundClass = (Class<?>) upperBounds[0];
|
||||
} else if (upperBounds[0] instanceof ParameterizedType) {
|
||||
upperBoundClass = (Class<?>) ((ParameterizedType) upperBounds[0]).getRawType();
|
||||
}
|
||||
}
|
||||
return (upperBoundClass == null || upperBoundClass.isAssignableFrom(bindingPayloadClass)) && (lowerBounds == null || bindingPayloadClass.isAssignableFrom(lowerBoundClass));
|
||||
} else {
|
||||
LOGGER.error("Unable to infer assignability from type for " + getMember());
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object unbindInput(List<IData> boundValueList) {
|
||||
Object value = null;
|
||||
if (boundValueList != null && boundValueList.size() > 0) {
|
||||
if (isMemberTypeList()) {
|
||||
List valueList = new ArrayList(boundValueList.size());
|
||||
for (IData bound : boundValueList) {
|
||||
value = bound.getPayload();
|
||||
if (isTypeEnum()) {
|
||||
value = Enum.valueOf((Class<? extends Enum>)getType(), (String)value);
|
||||
}
|
||||
valueList.add(value);
|
||||
}
|
||||
value = valueList;
|
||||
} else if (boundValueList.size() == 1) {
|
||||
value = boundValueList.get(0).getPayload();
|
||||
if (isTypeEnum()) {
|
||||
value = Enum.valueOf((Class<? extends Enum>)getType(), (String)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public abstract void set(Object annotatedObject, List<IData> boundInputList);
|
||||
}
|
||||
|
||||
public static abstract class OutputBinding<M extends AccessibleObject & Member, D extends OutputDescriptor> extends DataBinding<M,D> {
|
||||
|
||||
private Constructor<? extends IData> bindingConstructor;
|
||||
|
||||
public OutputBinding(M member) {
|
||||
super(member);
|
||||
}
|
||||
|
||||
protected boolean checkType( ) {
|
||||
return getConstructor() != null;
|
||||
}
|
||||
|
||||
public IData bindOutputValue(Object outputValue) {
|
||||
try {
|
||||
if (isTypeEnum()) {
|
||||
outputValue = ((Enum<?>)outputValue).name();
|
||||
}
|
||||
return getConstructor().newInstance(outputValue);
|
||||
} catch (InstantiationException ex) {
|
||||
throw new RuntimeException("Internal error processing outputs", ex);
|
||||
} catch (SecurityException ex) {
|
||||
throw new RuntimeException("Internal error processing outputs", ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Internal error processing outputs", ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
Throwable cause = ex.getCause() == null ? ex : ex.getCause();
|
||||
throw new RuntimeException(cause.getMessage(), cause);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract IData get(Object annotatedInstance);
|
||||
|
||||
private synchronized Constructor<? extends IData> getConstructor() {
|
||||
if (bindingConstructor == null ){
|
||||
try {
|
||||
Class<? extends IData> bindingClass = getDescriptor().getBinding();
|
||||
Class<?> outputPayloadClass = bindingClass.getMethod("getPayload", (Class<?>[]) null).getReturnType();
|
||||
Type bindingPayloadType = getPayloadType();
|
||||
if (bindingPayloadType instanceof Class<?>) {
|
||||
Class<?> bindingPayloadClass = (Class<?>) bindingPayloadType;
|
||||
if (bindingPayloadClass.isAssignableFrom(outputPayloadClass)) {
|
||||
bindingConstructor = bindingClass.getConstructor(bindingPayloadClass);
|
||||
}
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
// error handling on fall-through
|
||||
}
|
||||
}
|
||||
return bindingConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InputFieldBinding<D extends InputDescriptor> extends InputBinding<Field, D> {
|
||||
|
||||
public InputFieldBinding(Field field) {
|
||||
super(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getMemberType() {
|
||||
return getMember().getGenericType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
if (!checkModifier()) {
|
||||
LOGGER.error("Field {} with input annotation can't be used, not public.", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!(getDescriptor().getMaxOccurs().intValue() < 2 || isMemberTypeList())) {
|
||||
LOGGER.error("Field {} with input annotation can't be used, maxOccurs > 1 and field is not of type List", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!checkType()) {
|
||||
LOGGER.error("Field {} with input annotation can't be used, unable to safely assign field using binding payload type", getMember());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object annotatedObject, List<IData> boundInputList) {
|
||||
try {
|
||||
getMember().set(annotatedObject, unbindInput(boundInputList));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class InputMethodBinding<D extends InputDescriptor> extends InputBinding<Method, D> {
|
||||
|
||||
public InputMethodBinding(Method method) {
|
||||
super(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getMemberType() {
|
||||
Type[] genericParameterTypes = getMember().getGenericParameterTypes();
|
||||
return (genericParameterTypes.length == 0) ? Void.class : genericParameterTypes[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
if (!checkModifier()) {
|
||||
LOGGER.error("Field {} with input annotation can't be used, not public.", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!(getDescriptor().getMaxOccurs().intValue() < 2 || isMemberTypeList())) {
|
||||
LOGGER.error("Field {} with input annotation can't be used, maxOccurs > 1 and field is not of type List", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!checkType()) {
|
||||
LOGGER.error("Field {} with input annotation can't be used, unable to safely assign field using binding payload type", getMember());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object annotatedObject, List<IData> boundInputList) {
|
||||
try {
|
||||
getMember().invoke(annotatedObject, unbindInput(boundInputList));
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
Throwable cause = ex.getCause() == null ? ex : ex.getCause();
|
||||
throw new RuntimeException(cause.getMessage(), cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class OutputFieldBinding<D extends OutputDescriptor> extends OutputBinding<Field, D> {
|
||||
|
||||
public OutputFieldBinding(Field field) {
|
||||
super(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getMemberType() {
|
||||
return getMember().getGenericType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
if (!checkModifier()) {
|
||||
LOGGER.error("Field {} with output annotation can't be used, not public.", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!checkType()) {
|
||||
LOGGER.error("Field {} with output annotation can't be used, unable to safely construct binding using field type", getMember());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IData get(Object annotatedInstance) {
|
||||
Object value;
|
||||
try {
|
||||
value = getMember().get(annotatedInstance);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
}
|
||||
return value == null ? null : bindOutputValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class OutputMethodBinding<D extends OutputDescriptor> extends OutputBinding<Method, D> {
|
||||
|
||||
public OutputMethodBinding(Method method) {
|
||||
super(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getMemberType() {
|
||||
return getMember().getGenericReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
Method method = getMember();
|
||||
if (method.getParameterTypes().length != 0) {
|
||||
LOGGER.error("Method {} with output annotation can't be used, parameter count != 0", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!checkModifier()) {
|
||||
LOGGER.error("Method {} with output annotation can't be used, not public", getMember());
|
||||
return false;
|
||||
}
|
||||
if (!checkType()) {
|
||||
LOGGER.error("Method {} with output annotation can't be used, unable to safely construct binding using method return type", getMember());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IData get(Object annotatedInstance) {
|
||||
Object value;
|
||||
try {
|
||||
value = getMember().invoke(annotatedInstance);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Internal error processing inputs", ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
Throwable cause = ex.getCause() == null ? ex : ex.getCause();
|
||||
throw new RuntimeException(cause.getMessage(), cause);
|
||||
}
|
||||
return value == null ? null : bindOutputValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
// for example, a type reprecenting the <? extends Object> for types of List<? extends Object> or List
|
||||
public final Type NOT_PARAMETERIZED_TYPE = new WildcardType() {
|
||||
@Override public Type[] getUpperBounds() { return new Type[]{Object.class}; }
|
||||
@Override public Type[] getLowerBounds() { return new Type[0]; }
|
||||
};
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputFieldBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputMethodBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputFieldBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputMethodBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.ExecuteMethodBinding;
|
||||
import org.n52.wps.algorithm.descriptor.BoundDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.ComplexDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.ComplexDataOutputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.InputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataOutputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.OutputDescriptor;
|
||||
import org.n52.wps.algorithm.util.ClassUtil;
|
||||
import org.n52.wps.io.BasicXMLTypeFactory;
|
||||
import org.n52.wps.io.data.ILiteralData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class AnnotationParser<A extends Annotation, M extends AccessibleObject & Member, B extends AnnotationBinding<M>> {
|
||||
|
||||
public final static Logger LOGGER = LoggerFactory.getLogger(AnnotationParser.class);
|
||||
|
||||
public B parse(M member) {
|
||||
A annotation = member.getAnnotation(getSupportedAnnotation());
|
||||
return annotation == null ? null : parse(annotation, member);
|
||||
}
|
||||
|
||||
public abstract B parse(A annotation, M member);
|
||||
|
||||
public abstract Class<? extends A> getSupportedAnnotation();
|
||||
|
||||
public static class ExecuteAnnotationParser extends AnnotationParser<Execute, Method, ExecuteMethodBinding> {
|
||||
|
||||
@Override
|
||||
public ExecuteMethodBinding parse(Execute annotation, Method member) {
|
||||
ExecuteMethodBinding annotationBinding = new ExecuteMethodBinding(member);
|
||||
return annotationBinding.validate() ? annotationBinding : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Execute> getSupportedAnnotation() {
|
||||
return Execute.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract static class DataAnnotationParser<A extends Annotation, M extends AccessibleObject & Member, B extends AnnotationBinding.DataBinding<M, ? extends BoundDescriptor>>
|
||||
extends AnnotationParser<A,M,B> {
|
||||
protected abstract B createBinding(M member);
|
||||
}
|
||||
|
||||
public abstract static class InputAnnotationParser<A extends Annotation, M extends AccessibleObject & Member, B extends AnnotationBinding.InputBinding<M, ? extends InputDescriptor>>
|
||||
extends DataAnnotationParser<A,M,B> {}
|
||||
|
||||
public abstract static class OutputAnnotationParser<A extends Annotation, M extends AccessibleObject & Member, B extends AnnotationBinding.OutputBinding<M, ? extends OutputDescriptor>>
|
||||
extends DataAnnotationParser<A,M,B> {}
|
||||
|
||||
public abstract static class LiteralDataInputAnnotationParser<M extends AccessibleObject & Member, B extends AnnotationBinding.InputBinding<M, LiteralDataInputDescriptor>>
|
||||
extends InputAnnotationParser<LiteralDataInput, M, B> {
|
||||
|
||||
@Override
|
||||
public B parse(LiteralDataInput annotation, M member) {
|
||||
|
||||
B annotatedBinding = createBinding(member);
|
||||
// auto generate binding if it's not explicitly declared
|
||||
Type payloadType = annotatedBinding.getPayloadType();
|
||||
Class<? extends ILiteralData> binding = annotation.binding();
|
||||
if (binding == null || ILiteralData.class.equals(binding)) {
|
||||
if (payloadType instanceof Class<?>) {
|
||||
binding = BasicXMLTypeFactory.getBindingForPayloadType((Class<?>) payloadType);
|
||||
if (binding == null) {
|
||||
LOGGER.error("Unable to locate binding class for {}; binding not found.", payloadType);
|
||||
}
|
||||
} else {
|
||||
if (annotatedBinding.isMemberTypeList()) {
|
||||
LOGGER.error("Unable to determine binding class for {}; List must be parameterized with a type matching a known binding payload to use auto-binding.", payloadType);
|
||||
} else {
|
||||
LOGGER.error("Unable to determine binding class for {}; type must fully resolved to use auto-binding", payloadType);
|
||||
}
|
||||
}
|
||||
}
|
||||
String[] allowedValues = annotation.allowedValues();
|
||||
String defaultValue = annotation.defaultValue();
|
||||
int maxOccurs = annotation.maxOccurs();
|
||||
// If InputType is enum
|
||||
// 1) generate allowedValues if not explicitly declared
|
||||
// 2) validate allowedValues if explicitly declared
|
||||
// 3) validate defaultValue if declared
|
||||
// 4) check for special ENUM_COUNT maxOccurs flag
|
||||
Type inputType = annotatedBinding.getType();
|
||||
if (annotatedBinding.isTypeEnum()) {
|
||||
Class<? extends Enum> inputEnumClass = (Class<? extends Enum>) inputType;
|
||||
// validate contents of allowed values maps to enum
|
||||
if (allowedValues.length > 0) {
|
||||
List<String> invalidValues = new ArrayList<String>();
|
||||
for (String value : allowedValues) {
|
||||
try {
|
||||
Enum.valueOf(inputEnumClass, value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
invalidValues.add(value);
|
||||
LOGGER.warn("Invalid allowed value \"{}\" specified for for enumerated input type {}", value, inputType);
|
||||
}
|
||||
}
|
||||
if (invalidValues.size() > 0) {
|
||||
List<String> updatedValues = new ArrayList<String>(Arrays.asList(allowedValues));
|
||||
updatedValues.removeAll(invalidValues);
|
||||
allowedValues = updatedValues.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
// if list is empty, populated with values from enum
|
||||
if (allowedValues.length == 0) {
|
||||
allowedValues = ClassUtil.convertEnumToStringArray(inputEnumClass);
|
||||
}
|
||||
if (defaultValue.length() > 0) {
|
||||
try {
|
||||
Enum.valueOf(inputEnumClass, defaultValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOGGER.warn("Invalid default value \"{}\" specified for for enumerated input type {}, ignoring.", defaultValue, inputType);
|
||||
defaultValue = "";
|
||||
}
|
||||
}
|
||||
if (maxOccurs == LiteralDataInput.ENUM_COUNT) {
|
||||
maxOccurs = inputEnumClass.getEnumConstants().length;
|
||||
}
|
||||
} else {
|
||||
if (maxOccurs == LiteralDataInput.ENUM_COUNT) {
|
||||
maxOccurs = 1;
|
||||
LOGGER.warn("Invalid maxOccurs \"ENUM_COUNT\" specified for for input type {}, setting maxOccurs to {}", inputType, maxOccurs);
|
||||
}
|
||||
}
|
||||
if (binding != null) {
|
||||
LiteralDataInputDescriptor descriptor =
|
||||
LiteralDataInputDescriptor.builder(annotation.identifier(), binding).
|
||||
title(annotation.title()).
|
||||
abstrakt(annotation.abstrakt()).
|
||||
minOccurs(annotation.minOccurs()).
|
||||
maxOccurs(maxOccurs).
|
||||
defaultValue(defaultValue).
|
||||
allowedValues(allowedValues).
|
||||
build();
|
||||
annotatedBinding.setDescriptor(descriptor);
|
||||
} else {
|
||||
LOGGER.error("Unable to generate binding for input identifier \"{}\"", annotation.identifier());
|
||||
}
|
||||
return annotatedBinding.validate() ? annotatedBinding : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends LiteralDataInput> getSupportedAnnotation() {
|
||||
return LiteralDataInput.class;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class LiteralDataOutputAnnotationParser<M extends AccessibleObject & Member, B extends AnnotationBinding.OutputBinding<M, LiteralDataOutputDescriptor>>
|
||||
extends OutputAnnotationParser<LiteralDataOutput, M, B> {
|
||||
|
||||
@Override
|
||||
public B parse(LiteralDataOutput annotation, M member) {
|
||||
B annotatedBinding = createBinding(member);
|
||||
// auto generate binding if it's not explicitly declared
|
||||
Type payloadType = annotatedBinding.getPayloadType();
|
||||
Class<? extends ILiteralData> binding = annotation.binding();
|
||||
if (binding == null || ILiteralData.class.equals(binding)) {
|
||||
if (payloadType instanceof Class<?>) {
|
||||
binding = BasicXMLTypeFactory.getBindingForPayloadType((Class<?>) payloadType);
|
||||
if (binding == null) {
|
||||
LOGGER.error("Unable to locate binding class for {}; binding not found.", payloadType);
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("Unable to determine binding class for {}; type must fully resolved to use auto-binding", payloadType);
|
||||
}
|
||||
}
|
||||
if (binding != null) {
|
||||
LiteralDataOutputDescriptor descriptor =
|
||||
LiteralDataOutputDescriptor.builder(annotation.identifier(), binding).
|
||||
title(annotation.title()).
|
||||
abstrakt(annotation.abstrakt()).
|
||||
build();
|
||||
annotatedBinding.setDescriptor(descriptor);
|
||||
} else {
|
||||
LOGGER.error("Unable to generate binding for output identifier \"{}\"", annotation.identifier());
|
||||
}
|
||||
return annotatedBinding.validate() ? annotatedBinding : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends LiteralDataOutput> getSupportedAnnotation() {
|
||||
return LiteralDataOutput.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ComplexDataInputAnnotationParser<M extends AccessibleObject & Member, B extends AnnotationBinding.InputBinding<M, ComplexDataInputDescriptor>>
|
||||
extends InputAnnotationParser<ComplexDataInput, M, B> {
|
||||
|
||||
@Override
|
||||
public B parse(ComplexDataInput annotation, M member) {
|
||||
B annotatedBinding = createBinding(member);
|
||||
ComplexDataInputDescriptor descriptor =
|
||||
ComplexDataInputDescriptor.builder(annotation.identifier(), annotation.binding()).
|
||||
title(annotation.title()).
|
||||
abstrakt(annotation.abstrakt()).
|
||||
minOccurs(annotation.minOccurs()).
|
||||
maxOccurs(annotation.maxOccurs()).
|
||||
maximumMegaBytes(annotation.maximumMegaBytes()).
|
||||
build();
|
||||
annotatedBinding.setDescriptor(descriptor);
|
||||
return annotatedBinding.validate() ? annotatedBinding : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ComplexDataInput> getSupportedAnnotation() {
|
||||
return ComplexDataInput.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected B createBinding(M member) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class ComplexDataOutputAnnotationParser<M extends AccessibleObject & Member, B extends AnnotationBinding.OutputBinding<M, ComplexDataOutputDescriptor>>
|
||||
extends OutputAnnotationParser<ComplexDataOutput, M, B> {
|
||||
|
||||
@Override
|
||||
public B parse (ComplexDataOutput annotation, M member) {
|
||||
B annotatedBinding = createBinding(member);
|
||||
ComplexDataOutputDescriptor descriptor =
|
||||
ComplexDataOutputDescriptor.builder(annotation.identifier(), annotation.binding()).
|
||||
title(annotation.title()).
|
||||
abstrakt(annotation.abstrakt()).
|
||||
build();
|
||||
annotatedBinding.setDescriptor(descriptor);
|
||||
return annotatedBinding.validate() ? annotatedBinding : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ComplexDataOutput> getSupportedAnnotation() {
|
||||
return ComplexDataOutput.class;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LiteralDataInputFieldAnnotationParser extends LiteralDataInputAnnotationParser<Field, AnnotationBinding.InputBinding<Field, LiteralDataInputDescriptor>> {
|
||||
@Override
|
||||
protected InputBinding<Field, LiteralDataInputDescriptor> createBinding(Field member) {
|
||||
return new InputFieldBinding<LiteralDataInputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
public static class LiteralDataOutputFieldAnnotationParser extends LiteralDataOutputAnnotationParser<Field, AnnotationBinding.OutputBinding<Field, LiteralDataOutputDescriptor>> {
|
||||
@Override
|
||||
protected OutputBinding<Field, LiteralDataOutputDescriptor> createBinding(Field member) {
|
||||
return new OutputFieldBinding<LiteralDataOutputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
public static class ComplexDataInputFieldAnnotationParser extends ComplexDataInputAnnotationParser<Field, AnnotationBinding.InputBinding<Field, ComplexDataInputDescriptor>> {
|
||||
@Override
|
||||
protected InputBinding<Field, ComplexDataInputDescriptor> createBinding(Field member) {
|
||||
return new InputFieldBinding<ComplexDataInputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
public static class ComplexDataOutputFieldAnnotationParser extends ComplexDataOutputAnnotationParser<Field, AnnotationBinding.OutputBinding<Field, ComplexDataOutputDescriptor>> {
|
||||
@Override
|
||||
protected OutputBinding<Field, ComplexDataOutputDescriptor> createBinding(Field member) {
|
||||
return new OutputFieldBinding<ComplexDataOutputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
|
||||
public static class LiteralDataInputMethodAnnotationParser extends LiteralDataInputAnnotationParser<Method, AnnotationBinding.InputBinding<Method, LiteralDataInputDescriptor>> {
|
||||
@Override
|
||||
protected InputBinding<Method, LiteralDataInputDescriptor> createBinding(Method member) {
|
||||
return new InputMethodBinding<LiteralDataInputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
public static class LiteralDataOutputMethodAnnotationParser extends LiteralDataOutputAnnotationParser<Method, AnnotationBinding.OutputBinding<Method, LiteralDataOutputDescriptor>> {
|
||||
@Override
|
||||
protected OutputBinding<Method, LiteralDataOutputDescriptor> createBinding(Method member) {
|
||||
return new OutputMethodBinding<LiteralDataOutputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
public static class ComplexDataInputMethodAnnotationParser extends ComplexDataInputAnnotationParser<Method, AnnotationBinding.InputBinding<Method, ComplexDataInputDescriptor>> {
|
||||
@Override
|
||||
protected InputBinding<Method, ComplexDataInputDescriptor> createBinding(Method member) {
|
||||
return new InputMethodBinding<ComplexDataInputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
public static class ComplexDataOutputMethodAnnotationParser extends ComplexDataOutputAnnotationParser<Method, AnnotationBinding.OutputBinding<Method, ComplexDataOutputDescriptor>> {
|
||||
@Override
|
||||
protected OutputBinding<Method, ComplexDataOutputDescriptor> createBinding(Method member) {
|
||||
return new OutputMethodBinding<ComplexDataOutputDescriptor>(member);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.n52.wps.io.data.IComplexData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
public @interface ComplexDataInput {
|
||||
String identifier(); // identifier
|
||||
String title() default "";
|
||||
String abstrakt() default ""; // 'abstract' is java reserved keyword
|
||||
int minOccurs() default 1;
|
||||
int maxOccurs() default 1;
|
||||
int maximumMegaBytes() default 0;
|
||||
Class <? extends IComplexData> binding();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.n52.wps.io.data.IComplexData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
public @interface ComplexDataOutput {
|
||||
String identifier(); // identifier
|
||||
String title() default "";
|
||||
String abstrakt() default ""; // 'abstract' is java reserved keyword
|
||||
Class <? extends IComplexData> binding();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface Execute {
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.n52.wps.io.data.ILiteralData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
public @interface LiteralDataInput {
|
||||
String identifier(); // identifier
|
||||
String title() default "";
|
||||
String abstrakt() default ""; // 'abstract' is java reserved keyword
|
||||
int minOccurs() default 1;
|
||||
int maxOccurs() default 1;
|
||||
String defaultValue() default "";
|
||||
String[] allowedValues() default {};
|
||||
Class <? extends ILiteralData> binding() default ILiteralData.class;
|
||||
|
||||
//// special maxOccurs flags
|
||||
// set maxOccurs to enum constant count
|
||||
public final static int ENUM_COUNT = -1;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.n52.wps.io.data.ILiteralData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
public @interface LiteralDataOutput {
|
||||
String identifier(); // identifier
|
||||
String title() default "";
|
||||
String abstrakt() default ""; // 'abstract' is java reserved keyword
|
||||
Class <? extends ILiteralData> binding() default ILiteralData.class;
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class AlgorithmDescriptor extends Descriptor {
|
||||
|
||||
private final String version;
|
||||
private final boolean storeSupported;
|
||||
private final boolean statusSupported;
|
||||
private final Map<String, InputDescriptor> inputDescriptorMap;
|
||||
private final Map<String, OutputDescriptor> outputDescriptorMap;
|
||||
|
||||
AlgorithmDescriptor(Builder<? extends Builder<?>> builder) {
|
||||
super(builder);
|
||||
this.version = builder.version;
|
||||
this.storeSupported = builder.storeSupported;
|
||||
this.statusSupported = builder.statusSupported;
|
||||
|
||||
Preconditions.checkState(
|
||||
builder.outputDescriptors.size() > 0,
|
||||
"Need at minimum 1 output for algorithm.");
|
||||
|
||||
// LinkedHaskMap to preserve order
|
||||
Map<String, InputDescriptor> iMap = new LinkedHashMap<String, InputDescriptor>();
|
||||
for (InputDescriptor iDescriptor : builder.inputDescriptors) {
|
||||
iMap.put(iDescriptor.getIdentifier(), iDescriptor);
|
||||
}
|
||||
inputDescriptorMap = Collections.unmodifiableMap(iMap);
|
||||
|
||||
Map<String, OutputDescriptor> oMap = new LinkedHashMap<String, OutputDescriptor>();
|
||||
for (OutputDescriptor oDescriptor : builder.outputDescriptors) {
|
||||
oMap.put(oDescriptor.getIdentifier(), oDescriptor);
|
||||
}
|
||||
outputDescriptorMap = Collections.unmodifiableMap(oMap);
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean getStoreSupported() {
|
||||
return storeSupported;
|
||||
}
|
||||
|
||||
public boolean getStatusSupported() {
|
||||
return statusSupported;
|
||||
}
|
||||
|
||||
public List<String> getInputIdentifiers() {
|
||||
return Collections.unmodifiableList(new ArrayList<String>(inputDescriptorMap.keySet()));
|
||||
}
|
||||
|
||||
public InputDescriptor getInputDescriptor(String identifier) {
|
||||
return inputDescriptorMap.get(identifier);
|
||||
}
|
||||
|
||||
public Collection<InputDescriptor> getInputDescriptors() {
|
||||
return inputDescriptorMap.values();
|
||||
}
|
||||
|
||||
public List<String> getOutputIdentifiers() {
|
||||
return Collections.unmodifiableList(new ArrayList<String>(outputDescriptorMap.keySet()));
|
||||
}
|
||||
|
||||
public OutputDescriptor getOutputDescriptor(String identifier) {
|
||||
return outputDescriptorMap.get(identifier);
|
||||
}
|
||||
|
||||
public Collection<OutputDescriptor> getOutputDescriptors() {
|
||||
return outputDescriptorMap.values();
|
||||
}
|
||||
|
||||
public static Builder<?> builder(String identifier) {
|
||||
return new BuilderTyped(identifier);
|
||||
}
|
||||
|
||||
public static Builder<?> builder(Class<?> clazz) {
|
||||
Preconditions.checkNotNull(clazz, "clazz may not be null");
|
||||
return new BuilderTyped(clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
private static class BuilderTyped extends Builder<BuilderTyped> {
|
||||
public BuilderTyped(String identifier) {
|
||||
super(identifier);
|
||||
}
|
||||
@Override
|
||||
protected BuilderTyped self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B>> extends Descriptor.Builder<B>{
|
||||
|
||||
private String version = "1.0.0";
|
||||
private boolean storeSupported = true;
|
||||
private boolean statusSupported = true;
|
||||
private List<InputDescriptor> inputDescriptors;
|
||||
private List<OutputDescriptor> outputDescriptors;
|
||||
|
||||
protected Builder(String identifier) {
|
||||
super(identifier);
|
||||
title(identifier);
|
||||
inputDescriptors = new ArrayList<InputDescriptor>();
|
||||
outputDescriptors = new ArrayList<OutputDescriptor>();
|
||||
}
|
||||
|
||||
public B version(String version) {
|
||||
this.version = version;
|
||||
return self();
|
||||
}
|
||||
|
||||
public B storeSupported(boolean storeSupported) {
|
||||
this.storeSupported = storeSupported;
|
||||
return self();
|
||||
}
|
||||
|
||||
public B statusSupported(boolean statusSupported) {
|
||||
this.statusSupported = statusSupported;
|
||||
return self();
|
||||
}
|
||||
|
||||
public B addInputDescriptor(InputDescriptor.Builder inputDescriptorBuilder) {
|
||||
return addInputDescriptor(inputDescriptorBuilder.build());
|
||||
}
|
||||
|
||||
public B addInputDescriptor(InputDescriptor inputDescriptor) {
|
||||
this.inputDescriptors.add(inputDescriptor);
|
||||
return self();
|
||||
}
|
||||
|
||||
public B addInputDescriptors(List<? extends InputDescriptor> inputDescriptors) {
|
||||
this.inputDescriptors.addAll(inputDescriptors);
|
||||
return self();
|
||||
}
|
||||
|
||||
public B addOutputDescriptor(OutputDescriptor.Builder outputDescriptorBuilder) {
|
||||
return addOutputDescriptor(outputDescriptorBuilder.build());
|
||||
}
|
||||
|
||||
public B addOutputDescriptor(OutputDescriptor outputDescriptor) {
|
||||
this.outputDescriptors.add(outputDescriptor);
|
||||
return self();
|
||||
}
|
||||
|
||||
public B addOutputDescriptors(List<? extends OutputDescriptor> outputDescriptors) {
|
||||
this.outputDescriptors.addAll(outputDescriptors);
|
||||
return self();
|
||||
}
|
||||
|
||||
public AlgorithmDescriptor build() {
|
||||
return new AlgorithmDescriptor(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class BoundDescriptor<T extends Class<?>> extends Descriptor {
|
||||
|
||||
private final T binding;
|
||||
|
||||
BoundDescriptor(Builder<? extends Builder<?,T>, T> builder) {
|
||||
super(builder);
|
||||
this.binding = builder.binding;
|
||||
}
|
||||
|
||||
public T getBinding() {
|
||||
return binding;
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<?>> extends Descriptor.Builder<B> {
|
||||
|
||||
private final T binding;
|
||||
|
||||
protected Builder(String identifier, T binding) {
|
||||
super(identifier);
|
||||
Preconditions.checkArgument(binding != null, "binding may not be null");
|
||||
this.binding = binding;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.math.BigInteger;
|
||||
import org.n52.wps.io.data.IComplexData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class ComplexDataInputDescriptor<T extends Class<? extends IComplexData>> extends InputDescriptor<T> {
|
||||
|
||||
private final BigInteger maximumMegaBytes;
|
||||
|
||||
private ComplexDataInputDescriptor(Builder builder) {
|
||||
super(builder);
|
||||
this.maximumMegaBytes = builder.maximumMegaBytes;
|
||||
}
|
||||
|
||||
public boolean hasMaximumMegaBytes() {
|
||||
return maximumMegaBytes != null && maximumMegaBytes.longValue() > 0;
|
||||
}
|
||||
|
||||
public BigInteger getMaximumMegaBytes() {
|
||||
return maximumMegaBytes;
|
||||
}
|
||||
|
||||
public static <T extends Class<? extends IComplexData>> Builder<?,T> builder(String identifier, T binding) {
|
||||
return new BuilderTyped(identifier, binding);
|
||||
}
|
||||
|
||||
private static class BuilderTyped<T extends Class<? extends IComplexData>> extends Builder<BuilderTyped<T>, T> {
|
||||
public BuilderTyped(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
@Override
|
||||
protected BuilderTyped self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<? extends IComplexData>> extends InputDescriptor.Builder<B,T> {
|
||||
|
||||
private BigInteger maximumMegaBytes;
|
||||
|
||||
private Builder(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
|
||||
public B maximumMegaBytes(int maximumMegaBytes) {
|
||||
return maximumMegaBytes(BigInteger.valueOf(maximumMegaBytes));
|
||||
}
|
||||
|
||||
public B maximumMegaBytes(BigInteger maximumMegaBytes) {
|
||||
Preconditions.checkArgument(maximumMegaBytes.longValue() >= 0, "maximumMegabytes must be >= 0");
|
||||
this.maximumMegaBytes = maximumMegaBytes;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComplexDataInputDescriptor<T> build() {
|
||||
return new ComplexDataInputDescriptor<T>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import org.n52.wps.io.data.IComplexData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class ComplexDataOutputDescriptor<T extends Class<? extends IComplexData>> extends OutputDescriptor<T> {
|
||||
|
||||
|
||||
private ComplexDataOutputDescriptor(Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public static <T extends Class<? extends IComplexData>> Builder<?,T> builder(String identifier, T binding) {
|
||||
return new BuilderTyped(identifier, binding);
|
||||
}
|
||||
|
||||
private static class BuilderTyped<T extends Class<? extends IComplexData>> extends Builder<BuilderTyped<T>, T> {
|
||||
public BuilderTyped(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
@Override
|
||||
protected BuilderTyped self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<? extends IComplexData>> extends OutputDescriptor.Builder<B,T> {
|
||||
|
||||
private Builder(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
|
||||
public ComplexDataOutputDescriptor<T> build() {
|
||||
return new ComplexDataOutputDescriptor<T>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class Descriptor {
|
||||
|
||||
private final String identifier;
|
||||
private final String title;
|
||||
private final String abstrakt; // want 'abstract' but it's a java keyword
|
||||
|
||||
Descriptor(Builder<? extends Builder<?>> builder) {
|
||||
this.identifier = builder.identifier;
|
||||
this.title = builder.title;
|
||||
this.abstrakt = builder.abstrakt;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public boolean hasTitle() {
|
||||
return title != null && title.length() > 0;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public boolean hasAbstract() {
|
||||
return abstrakt != null && abstrakt.length() > 0;
|
||||
}
|
||||
|
||||
public String getAbstract() {
|
||||
return abstrakt;
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B>> {
|
||||
|
||||
private final String identifier;
|
||||
private String title;
|
||||
private String abstrakt; // want 'abstract' but it's a java keyword
|
||||
|
||||
public Builder(String identifier) {
|
||||
Preconditions.checkArgument(
|
||||
!(identifier == null || identifier.isEmpty()),
|
||||
"identifier may not be null or an empty String");
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public B title(String title) {
|
||||
this.title = title;
|
||||
return self();
|
||||
}
|
||||
|
||||
// want 'abstract' but it's a java keyword
|
||||
public B abstrakt(String abstrakt) {
|
||||
this.abstrakt = abstrakt;
|
||||
return self();
|
||||
}
|
||||
|
||||
protected abstract B self();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.math.BigInteger;
|
||||
import org.n52.wps.io.data.IData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class InputDescriptor<T extends Class<? extends IData>> extends BoundDescriptor<T> {
|
||||
|
||||
private final BigInteger minOccurs;
|
||||
private final BigInteger maxOccurs;
|
||||
|
||||
protected InputDescriptor(Builder<? extends Builder<?,T>, T> builder) {
|
||||
super(builder);
|
||||
this.minOccurs = builder.minOccurs;
|
||||
this.maxOccurs = builder.maxOccurs;
|
||||
Preconditions.checkState(maxOccurs.longValue() >= minOccurs.longValue(), "maxOccurs must be >= minOccurs");
|
||||
}
|
||||
|
||||
public BigInteger getMinOccurs() {
|
||||
return minOccurs;
|
||||
}
|
||||
|
||||
public BigInteger getMaxOccurs() {
|
||||
return maxOccurs;
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<? extends IData>> extends BoundDescriptor.Builder<B,T>{
|
||||
|
||||
private BigInteger minOccurs = BigInteger.ONE;
|
||||
private BigInteger maxOccurs = BigInteger.ONE;
|
||||
|
||||
protected Builder(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
|
||||
public B minOccurs(int minOccurs) {
|
||||
return minOccurs(BigInteger.valueOf(minOccurs));
|
||||
}
|
||||
|
||||
public B minOccurs(BigInteger minOccurs) {
|
||||
Preconditions.checkArgument(minOccurs.longValue() >= 0, "minOccurs must be >= 0");
|
||||
this.minOccurs = minOccurs;
|
||||
return self();
|
||||
}
|
||||
|
||||
public B maxOccurs(int maxOccurs) {
|
||||
return maxOccurs(BigInteger.valueOf(maxOccurs));
|
||||
}
|
||||
|
||||
public B maxOccurs(BigInteger maxOccurs) {
|
||||
Preconditions.checkArgument(maxOccurs.longValue() > 0, "maxOccurs must be > 0");
|
||||
this.maxOccurs = maxOccurs;
|
||||
return self();
|
||||
}
|
||||
|
||||
public <E extends Enum<E>> B maxOccurs(Class<E> enumType) {
|
||||
return maxOccurs(enumType.getEnumConstants().length);
|
||||
}
|
||||
|
||||
public abstract InputDescriptor<T> build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
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.io.BasicXMLTypeFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class LiteralDataInputDescriptor<T extends Class<? extends ILiteralData>> extends InputDescriptor<T> {
|
||||
|
||||
private final String dataType;
|
||||
private final String defaultValue;
|
||||
private final List<String> allowedValues;
|
||||
|
||||
protected LiteralDataInputDescriptor(Builder builder) {
|
||||
super(builder);
|
||||
this.dataType = builder.dataType;
|
||||
this.defaultValue = builder.defaultValue;
|
||||
this.allowedValues = builder.allowedValues != null ?
|
||||
Collections.unmodifiableList(builder.allowedValues) :
|
||||
Collections.EMPTY_LIST;
|
||||
// if allowedValues and defaultValue are set, make sure defaultValue is in set of allowedValues
|
||||
Preconditions.checkState(
|
||||
!hasAllowedValues() || !hasDefaultValue() || allowedValues.contains(defaultValue),
|
||||
"defaultValue of %s not in set of allowedValues", defaultValue);
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public boolean hasDefaultValue() {
|
||||
return defaultValue != null && defaultValue.length() > 0;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public boolean hasAllowedValues() {
|
||||
return allowedValues != null && allowedValues.size() > 0;
|
||||
}
|
||||
|
||||
public List<String> getAllowedValues() {
|
||||
return allowedValues;
|
||||
}
|
||||
|
||||
public static <T extends Class<? extends ILiteralData>> Builder<?,T> builder(String identifier, T binding) {
|
||||
return new BuilderTyped(identifier, binding);
|
||||
}
|
||||
|
||||
// utility functions, quite verbose...
|
||||
public static Builder<?,Class<LiteralAnyURIBinding>> anyURIBuilder(String identifier) {
|
||||
return builder(identifier, LiteralAnyURIBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralBase64BinaryBinding>> base64BinaryBuilder(String identifier) {
|
||||
return builder(identifier, LiteralBase64BinaryBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralBooleanBinding>> booleanBuilder(String identifier) {
|
||||
return builder(identifier, LiteralBooleanBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralByteBinding>> byteBuilder(String identifier) {
|
||||
return builder(identifier, LiteralByteBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralDateTimeBinding>> dateTimeBuilder(String identifier) {
|
||||
return builder(identifier, LiteralDateTimeBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralDoubleBinding>> doubleBuilder(String identifier) {
|
||||
return builder(identifier, LiteralDoubleBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralFloatBinding>> floatBuilder(String identifier) {
|
||||
return builder(identifier, LiteralFloatBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralIntBinding>> intBuilder(String identifier) {
|
||||
return builder(identifier, LiteralIntBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralLongBinding>> longBuilder(String identifier) {
|
||||
return builder(identifier, LiteralLongBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralShortBinding>> shortBuilder(String identifier) {
|
||||
return builder(identifier, LiteralShortBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralStringBinding>> stringBuilder(String identifier) {
|
||||
return builder(identifier, LiteralStringBinding.class);
|
||||
}
|
||||
|
||||
private static class BuilderTyped<T extends Class<? extends ILiteralData>> extends Builder<BuilderTyped<T>, T> {
|
||||
public BuilderTyped(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
@Override
|
||||
protected BuilderTyped self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<? extends ILiteralData>> extends InputDescriptor.Builder<B,T> {
|
||||
|
||||
private final String dataType;
|
||||
private String defaultValue;
|
||||
private List<String> allowedValues;
|
||||
|
||||
protected Builder(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
this.dataType = Preconditions.checkNotNull(
|
||||
BasicXMLTypeFactory.getXMLDataTypeforBinding(binding),
|
||||
"Unable to resolve XML DataType for binding class %s",
|
||||
binding);
|
||||
}
|
||||
|
||||
public B defaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
return self();
|
||||
}
|
||||
|
||||
public B allowedValues(Class<? extends Enum> allowedValues) {
|
||||
Enum[] constants = allowedValues.getEnumConstants();
|
||||
List<String> names = new ArrayList<String>(constants.length);
|
||||
for (Enum constant : constants) { names.add(constant.name()); }
|
||||
return allowedValues(names);
|
||||
}
|
||||
|
||||
public B allowedValues(String[] allowedValues) {
|
||||
return allowedValues(Arrays.asList(allowedValues));
|
||||
}
|
||||
|
||||
public B allowedValues(List<String> allowedValues) {
|
||||
this.allowedValues = allowedValues;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiteralDataInputDescriptor<T> build() {
|
||||
return new LiteralDataInputDescriptor<T>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class LiteralDataOutputDescriptor<T extends Class<? extends ILiteralData>> extends OutputDescriptor<T> {
|
||||
|
||||
private final String dataType;
|
||||
|
||||
protected LiteralDataOutputDescriptor(Builder builder) {
|
||||
super(builder);
|
||||
this.dataType = builder.dataType;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public static <T extends Class<? extends ILiteralData>> Builder<?,T> builder(String identifier, T binding) {
|
||||
return new BuilderTyped(identifier, binding);
|
||||
}
|
||||
|
||||
// utility functions, quite verbose...
|
||||
public static Builder<?,Class<LiteralAnyURIBinding>> anyURIBuilder(String identifier) {
|
||||
return builder(identifier, LiteralAnyURIBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralBase64BinaryBinding>> base64BinaryBuilder(String identifier) {
|
||||
return builder(identifier, LiteralBase64BinaryBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralBooleanBinding>> booleanBuilder(String identifier) {
|
||||
return builder(identifier, LiteralBooleanBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralByteBinding>> byteBuilder(String identifier) {
|
||||
return builder(identifier, LiteralByteBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralDateTimeBinding>> dateTimeBuilder(String identifier) {
|
||||
return builder(identifier, LiteralDateTimeBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralDoubleBinding>> doubleBuilder(String identifier) {
|
||||
return builder(identifier, LiteralDoubleBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralFloatBinding>> floatBuilder(String identifier) {
|
||||
return builder(identifier, LiteralFloatBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralIntBinding>> intBuilder(String identifier) {
|
||||
return builder(identifier, LiteralIntBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralLongBinding>> longBuilder(String identifier) {
|
||||
return builder(identifier, LiteralLongBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralShortBinding>> shortBuilder(String identifier) {
|
||||
return builder(identifier, LiteralShortBinding.class);
|
||||
}
|
||||
|
||||
public static Builder<?,Class<LiteralStringBinding>> stringBuilder(String identifier) {
|
||||
return builder(identifier, LiteralStringBinding.class);
|
||||
}
|
||||
|
||||
private static class BuilderTyped<T extends Class<? extends ILiteralData>> extends Builder<BuilderTyped<T>, T> {
|
||||
public BuilderTyped(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
@Override
|
||||
protected BuilderTyped self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<? extends ILiteralData>> extends OutputDescriptor.Builder<B,T> {
|
||||
|
||||
private final String dataType;
|
||||
|
||||
protected Builder(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
this.dataType = Preconditions.checkNotNull(
|
||||
BasicXMLTypeFactory.getXMLDataTypeforBinding(binding),
|
||||
"Unable to resolve XML DataType for binding class %s",
|
||||
binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiteralDataOutputDescriptor<T> build() {
|
||||
return new LiteralDataOutputDescriptor<T>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import org.n52.wps.io.data.IData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class OutputDescriptor<T extends Class<? extends IData>> extends BoundDescriptor<T> {
|
||||
|
||||
OutputDescriptor(Builder<? extends Builder<?,T>, T> builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public static abstract class Builder<B extends Builder<B,T>, T extends Class<? extends IData>> extends BoundDescriptor.Builder<B,T>{
|
||||
|
||||
protected Builder(String identifier, T binding) {
|
||||
super(identifier, binding);
|
||||
}
|
||||
|
||||
public abstract OutputDescriptor<T> build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.util;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class ClassUtil {
|
||||
|
||||
private final static Map<Class<?>, Class<?>> TO_WRAPPER;
|
||||
private final static Map<Class<?>, Class<?>> FROM_WRAPPER;
|
||||
|
||||
static {
|
||||
BiMap<Class<?>, Class<?>> map = HashBiMap.create();
|
||||
map.put(Float.TYPE, Float.class);
|
||||
map.put(Double.TYPE, Double.class);
|
||||
map.put(Byte.TYPE, Byte.class);
|
||||
map.put(Short.TYPE, Short.class);
|
||||
map.put(Integer.TYPE, Integer.class);
|
||||
map.put(Long.TYPE, Long.class);
|
||||
map.put(Character.TYPE, Character.class);
|
||||
map.put(Boolean.TYPE, Boolean.class);
|
||||
TO_WRAPPER = Collections.unmodifiableMap(map);
|
||||
FROM_WRAPPER = Collections.unmodifiableMap(map.inverse());
|
||||
}
|
||||
|
||||
|
||||
public static <T extends Enum<T>> List<T> convertStringToEnumList(Class<T> enumType, List<String> stringList) {
|
||||
List<T> enumList = new ArrayList<T>();
|
||||
for (String string : stringList) {
|
||||
enumList.add(Enum.valueOf(enumType, string));
|
||||
}
|
||||
return enumList;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> List<String> convertEnumToStringList(Class<T> enumType) {
|
||||
ArrayList stringList = null;
|
||||
T[] constants = enumType.getEnumConstants();
|
||||
if (constants != null && constants.length > 0) {
|
||||
stringList = new ArrayList(constants.length);
|
||||
for (T constant : constants) {
|
||||
stringList.add(constant.name());
|
||||
}
|
||||
}
|
||||
return stringList;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> String[] convertEnumToStringArray(Class<T> enumType) {
|
||||
List<String> stringList = convertEnumToStringList(enumType);
|
||||
return stringList == null ? null :
|
||||
stringList.toArray(new String[stringList.size()]);
|
||||
}
|
||||
|
||||
public static boolean isWrapper(Class<?> clazz) {
|
||||
return FROM_WRAPPER.containsKey(clazz);
|
||||
}
|
||||
|
||||
public static Class<?> unwrap(Class<?> clazz) {
|
||||
Class<?> unwrapped = FROM_WRAPPER.get(clazz);
|
||||
if (unwrapped == null)
|
||||
return clazz;
|
||||
return unwrapped;
|
||||
|
||||
}
|
||||
|
||||
public static Class<?> wrap(Class<?> clazz) {
|
||||
Class<?> wrapped = TO_WRAPPER.get(clazz);
|
||||
if (wrapped == null)
|
||||
return clazz;
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
import net.opengis.wps.x100.ProcessDescriptionsDocument;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
|
||||
/**
|
||||
* This class has to be extended in order to be served through the WPS.
|
||||
* The class file should also include a description file of the algorithm. This file has to be
|
||||
* valid against the describeProcess.xsd. The file has to be placed in the folder of the class file and has
|
||||
* to be named the same as the Algorithm.
|
||||
*
|
||||
* <p>If you want to apply a different initialization method, just override the initializeDescription() method.
|
||||
*
|
||||
* NOTE: This class is an adapter and it is recommended to extend this.
|
||||
* @author foerster
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractAlgorithm implements IAlgorithm
|
||||
{
|
||||
private ProcessDescriptionType description; // private, force access through getter method for lazy loading.
|
||||
private final String wkName;
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(AbstractAlgorithm.class);
|
||||
|
||||
/**
|
||||
* default constructor, calls the initializeDescription() Method
|
||||
*/
|
||||
public AbstractAlgorithm() {
|
||||
this.wkName = this.getClass().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* default constructor, calls the initializeDescription() Method
|
||||
*/
|
||||
public AbstractAlgorithm(String wellKnownName) {
|
||||
this.wkName = wellKnownName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten, in case you want to have a way of initializing.
|
||||
*
|
||||
* In detail it looks for a xml descfile, which is located in the same directory as the implementing class and has the same
|
||||
* name as the class, but with the extension XML.
|
||||
* @return
|
||||
*/
|
||||
protected ProcessDescriptionType initializeDescription() {
|
||||
String className = this.getClass().getName().replace(".", "/");
|
||||
InputStream xmlDesc = this.getClass().getResourceAsStream("/" + className + ".xml");
|
||||
try {
|
||||
XmlOptions option = new XmlOptions();
|
||||
option.setLoadTrimTextBuffer();
|
||||
ProcessDescriptionsDocument doc = ProcessDescriptionsDocument.Factory.parse(xmlDesc, option);
|
||||
if(doc.getProcessDescriptions().getProcessDescriptionArray().length == 0) {
|
||||
LOGGER.warn("ProcessDescription does not contain correct any description");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Checking that the process name (full class name or well-known name) matches the identifier.
|
||||
if(!doc.getProcessDescriptions().getProcessDescriptionArray(0).getIdentifier().getStringValue().equals(this.getClass().getName()) &&
|
||||
!doc.getProcessDescriptions().getProcessDescriptionArray(0).getIdentifier().getStringValue().equals(this.getWellKnownName())) {
|
||||
doc.getProcessDescriptions().getProcessDescriptionArray(0).getIdentifier().setStringValue(this.getClass().getName());
|
||||
LOGGER.warn("Identifier was not correct, was changed now temporary for server use to " + this.getClass().getName() + ". Please change it later in the description!");
|
||||
}
|
||||
|
||||
return doc.getProcessDescriptions().getProcessDescriptionArray(0);
|
||||
}
|
||||
catch(IOException e) {
|
||||
LOGGER.warn("Could not initialize algorithm, parsing error: " + this.getClass().getName(), e);
|
||||
}
|
||||
catch(XmlException e) {
|
||||
LOGGER.warn("Could not initialize algorithm, parsing error: " + this.getClass().getName(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ProcessDescriptionType getDescription() {
|
||||
if (description == null) {
|
||||
description = initializeDescription();
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDescriptionIsValid() {
|
||||
return getDescription().validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWellKnownName() {
|
||||
return this.wkName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.n52.wps.algorithm.annotation.AnnotatedAlgorithmIntrospector;
|
||||
import static org.n52.wps.algorithm.annotation.AnnotatedAlgorithmIntrospector.getInstrospector;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding;
|
||||
import org.n52.wps.algorithm.descriptor.AlgorithmDescriptor;
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public abstract class AbstractAnnotatedAlgorithm extends AbstractDescriptorAlgorithm {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(AbstractAnnotatedAlgorithm.class);
|
||||
|
||||
@Override
|
||||
protected AlgorithmDescriptor createAlgorithmDescriptor() {
|
||||
return getInstrospector(getAlgorithmClass()).getAlgorithmDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, IData> run(Map<String, List<IData>> inputMap) {
|
||||
Object annotatedInstance = getAlgorithmInstance();
|
||||
|
||||
AnnotatedAlgorithmIntrospector introspector = getInstrospector(annotatedInstance.getClass());
|
||||
|
||||
for (Map.Entry<String, AnnotationBinding.InputBinding<?, ?>> iEntry : introspector.getInputBindingMap().entrySet()) {
|
||||
iEntry.getValue().set(annotatedInstance, inputMap.get(iEntry.getKey()));
|
||||
}
|
||||
|
||||
getInstrospector(annotatedInstance.getClass()).getExecuteMethodBinding().execute(annotatedInstance);
|
||||
|
||||
Map<String, IData> oMap = new HashMap<String, IData>();
|
||||
for (Map.Entry<String, AnnotationBinding.OutputBinding<?, ?>> oEntry : introspector.getOutputBindingMap().entrySet()) {
|
||||
oMap.put(oEntry.getKey(), oEntry.getValue().get(annotatedInstance));
|
||||
}
|
||||
return oMap;
|
||||
}
|
||||
|
||||
public Object getAlgorithmInstance() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Class<?> getAlgorithmClass() {
|
||||
return getClass();
|
||||
}
|
||||
|
||||
public static class Proxy extends AbstractAnnotatedAlgorithm {
|
||||
|
||||
final private Class<?> proxiedClass;
|
||||
final private Object proxiedInstance;
|
||||
|
||||
public Proxy(Class<?> proxiedClass) {
|
||||
this.proxiedClass = proxiedClass;
|
||||
try {
|
||||
this.proxiedInstance = proxiedClass.newInstance();
|
||||
} catch (InstantiationException ex) {
|
||||
throw new RuntimeException("unable to instantiate proxied algorithm instance");
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException("unable to instantiate proxied algorithm instance");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getAlgorithmClass() {
|
||||
return proxiedClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAlgorithmInstance() {
|
||||
return proxiedInstance;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.opengis.ows.x11.AllowedValuesDocument.AllowedValues;
|
||||
import net.opengis.wps.x100.ComplexDataCombinationType;
|
||||
import net.opengis.wps.x100.ComplexDataCombinationsType;
|
||||
import net.opengis.wps.x100.ComplexDataDescriptionType;
|
||||
import net.opengis.wps.x100.InputDescriptionType;
|
||||
import net.opengis.wps.x100.LiteralInputType;
|
||||
import net.opengis.wps.x100.OutputDescriptionType;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType.DataInputs;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType.ProcessOutputs;
|
||||
import net.opengis.wps.x100.ProcessDescriptionsDocument;
|
||||
import net.opengis.wps.x100.ProcessDescriptionsDocument.ProcessDescriptions;
|
||||
import net.opengis.wps.x100.SupportedComplexDataInputType;
|
||||
import net.opengis.wps.x100.SupportedComplexDataType;
|
||||
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.apache.xmlbeans.XmlValidationError;
|
||||
import org.n52.wps.FormatDocument.Format;
|
||||
import org.n52.wps.algorithm.descriptor.AlgorithmDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.ComplexDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.ComplexDataOutputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.InputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataOutputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.OutputDescriptor;
|
||||
import org.n52.wps.io.GeneratorFactory;
|
||||
import org.n52.wps.io.IGenerator;
|
||||
import org.n52.wps.io.IOHandler;
|
||||
import org.n52.wps.io.IParser;
|
||||
import org.n52.wps.io.ParserFactory;
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.n52.wps.server.observerpattern.IObserver;
|
||||
import org.n52.wps.server.observerpattern.ISubject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
public abstract class AbstractDescriptorAlgorithm implements IAlgorithm, ISubject {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(AbstractDescriptorAlgorithm.class);
|
||||
|
||||
private AlgorithmDescriptor descriptor;
|
||||
private ProcessDescriptionType description;
|
||||
|
||||
public AbstractDescriptorAlgorithm() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ProcessDescriptionType getDescription() {
|
||||
if (description == null) {
|
||||
description = createProcessDescription();
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWellKnownName() {
|
||||
return getAlgorithmDescriptor().getIdentifier();
|
||||
}
|
||||
|
||||
private ProcessDescriptionType createProcessDescription() {
|
||||
|
||||
AlgorithmDescriptor algorithmDescriptor = getAlgorithmDescriptor();
|
||||
|
||||
ProcessDescriptionsDocument document = ProcessDescriptionsDocument.Factory.newInstance();
|
||||
ProcessDescriptions processDescriptions = document.addNewProcessDescriptions();
|
||||
ProcessDescriptionType processDescription = processDescriptions.addNewProcessDescription();
|
||||
|
||||
if (algorithmDescriptor == null) {
|
||||
throw new IllegalStateException("Instance must have an algorithm descriptor");
|
||||
} else {
|
||||
|
||||
// 1. Identifier
|
||||
processDescription.setStatusSupported(algorithmDescriptor.getStatusSupported());
|
||||
processDescription.setStoreSupported(algorithmDescriptor.getStoreSupported());
|
||||
processDescription.setProcessVersion(algorithmDescriptor.getVersion());
|
||||
processDescription.addNewIdentifier().setStringValue(algorithmDescriptor.getIdentifier());
|
||||
processDescription.addNewTitle().setStringValue( algorithmDescriptor.hasTitle() ?
|
||||
algorithmDescriptor.getTitle() :
|
||||
algorithmDescriptor.getIdentifier());
|
||||
if (algorithmDescriptor.hasAbstract()) {
|
||||
processDescription.addNewAbstract().setStringValue(algorithmDescriptor.getAbstract());
|
||||
}
|
||||
|
||||
// 2. Inputs
|
||||
Collection<InputDescriptor> inputDescriptors = algorithmDescriptor.getInputDescriptors();
|
||||
DataInputs dataInputs = null;
|
||||
if (inputDescriptors.size() > 0) {
|
||||
dataInputs = processDescription.addNewDataInputs();
|
||||
}
|
||||
for (InputDescriptor inputDescriptor : inputDescriptors) {
|
||||
|
||||
InputDescriptionType dataInput = dataInputs.addNewInput();
|
||||
dataInput.setMinOccurs(inputDescriptor.getMinOccurs());
|
||||
dataInput.setMaxOccurs(inputDescriptor.getMaxOccurs());
|
||||
|
||||
dataInput.addNewIdentifier().setStringValue(inputDescriptor.getIdentifier());
|
||||
dataInput.addNewTitle().setStringValue( inputDescriptor.hasTitle() ?
|
||||
inputDescriptor.getTitle() :
|
||||
inputDescriptor.getIdentifier());
|
||||
if (inputDescriptor.hasAbstract()) {
|
||||
dataInput.addNewAbstract().setStringValue(inputDescriptor.getAbstract());
|
||||
}
|
||||
|
||||
if (inputDescriptor instanceof LiteralDataInputDescriptor) {
|
||||
LiteralDataInputDescriptor<?> literalDescriptor = (LiteralDataInputDescriptor)inputDescriptor;
|
||||
|
||||
LiteralInputType literalData = dataInput.addNewLiteralData();
|
||||
literalData.addNewDataType().setReference(literalDescriptor.getDataType());
|
||||
|
||||
if (literalDescriptor.hasDefaultValue()) {
|
||||
literalData.setDefaultValue(literalDescriptor.getDefaultValue());
|
||||
}
|
||||
if (literalDescriptor.hasAllowedValues()) {
|
||||
AllowedValues allowed = literalData.addNewAllowedValues();
|
||||
for (String allowedValue : literalDescriptor.getAllowedValues()) {
|
||||
allowed.addNewValue().setStringValue(allowedValue);
|
||||
}
|
||||
} else {
|
||||
literalData.addNewAnyValue();
|
||||
}
|
||||
|
||||
} else if (inputDescriptor instanceof ComplexDataInputDescriptor) {
|
||||
SupportedComplexDataInputType complexDataType = dataInput.addNewComplexData();
|
||||
ComplexDataInputDescriptor complexInputDescriptor =
|
||||
(ComplexDataInputDescriptor)inputDescriptor;
|
||||
if (complexInputDescriptor.hasMaximumMegaBytes()) {
|
||||
complexDataType.setMaximumMegabytes(complexInputDescriptor.getMaximumMegaBytes());
|
||||
}
|
||||
describeComplexDataInputType(complexDataType, inputDescriptor.getBinding());
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Outputs
|
||||
ProcessOutputs dataOutputs = processDescription.addNewProcessOutputs();
|
||||
Collection<OutputDescriptor> outputDescriptors = algorithmDescriptor.getOutputDescriptors();
|
||||
if (outputDescriptors.size() < 1) {
|
||||
LOGGER.error("No outputs found for algorithm {}", algorithmDescriptor.getIdentifier());
|
||||
}
|
||||
for (OutputDescriptor outputDescriptor : outputDescriptors) {
|
||||
|
||||
OutputDescriptionType dataOutput = dataOutputs.addNewOutput();
|
||||
dataOutput.addNewIdentifier().setStringValue(outputDescriptor.getIdentifier());
|
||||
dataOutput.addNewTitle().setStringValue( outputDescriptor.hasTitle() ?
|
||||
outputDescriptor.getTitle() :
|
||||
outputDescriptor.getIdentifier());
|
||||
if (outputDescriptor.hasAbstract()) {
|
||||
dataOutput.addNewAbstract().setStringValue(outputDescriptor.getAbstract());
|
||||
}
|
||||
|
||||
if (outputDescriptor instanceof LiteralDataOutputDescriptor) {
|
||||
LiteralDataOutputDescriptor<?> literalDescriptor = (LiteralDataOutputDescriptor)outputDescriptor;
|
||||
dataOutput.addNewLiteralOutput().addNewDataType().
|
||||
setReference(literalDescriptor.getDataType());
|
||||
} else if (outputDescriptor instanceof ComplexDataOutputDescriptor) {
|
||||
describeComplexDataOutputType(dataOutput.addNewComplexOutput(), outputDescriptor.getBinding());
|
||||
}
|
||||
}
|
||||
}
|
||||
return document.getProcessDescriptions().getProcessDescriptionArray(0);
|
||||
}
|
||||
|
||||
private void describeComplexDataInputType(SupportedComplexDataType complexData, Class dataTypeClass) {
|
||||
List<IParser> parsers = ParserFactory.getInstance().getAllParsers();
|
||||
List<IParser> foundParsers = new ArrayList<IParser>();
|
||||
for (IParser parser : parsers) {
|
||||
// /*2.0*/ Class[] supportedClasses = parser.getSupportedInternalOutputDataType();
|
||||
/*3.0*/ Class[] supportedClasses = parser.getSupportedDataBindings();
|
||||
for (Class clazz : supportedClasses) {
|
||||
if (dataTypeClass.isAssignableFrom(clazz)) {
|
||||
foundParsers.add(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
describeComplexDataType(complexData, foundParsers);
|
||||
}
|
||||
|
||||
private void describeComplexDataOutputType(SupportedComplexDataType complexData, Class dataTypeClass) {
|
||||
|
||||
List<IGenerator> generators = GeneratorFactory.getInstance().getAllGenerators();
|
||||
List<IGenerator> foundGenerators = new ArrayList<IGenerator>();
|
||||
for (IGenerator generator : generators) {
|
||||
// /*2.0*/ Class[] supportedClasses = generator.getSupportedInternalInputDataType(); // appears to have been removed in 52n WPS 3.0
|
||||
/*3.0*/ Class[] supportedClasses = generator.getSupportedDataBindings();
|
||||
for (Class clazz : supportedClasses) {
|
||||
if (clazz.isAssignableFrom(dataTypeClass)) {
|
||||
foundGenerators.add(generator);
|
||||
}
|
||||
}
|
||||
}
|
||||
describeComplexDataType(complexData, foundGenerators);
|
||||
}
|
||||
|
||||
private void describeComplexDataType(
|
||||
SupportedComplexDataType complexData,
|
||||
List<? extends IOHandler> handlers)
|
||||
{
|
||||
ComplexDataCombinationType defaultFormatType = complexData.addNewDefault();
|
||||
ComplexDataCombinationsType supportedFormatType = complexData.addNewSupported();
|
||||
|
||||
boolean needDefault = true;
|
||||
for (IOHandler handler : handlers) {
|
||||
|
||||
Format[] fullFormats = handler.getSupportedFullFormats();
|
||||
if (fullFormats != null && fullFormats.length > 0) {
|
||||
if (needDefault) {
|
||||
needDefault = false;
|
||||
describeComplexDataFormat(
|
||||
defaultFormatType.addNewFormat(),
|
||||
fullFormats[0]);
|
||||
}
|
||||
for (int formatIndex = 0, formatCount = fullFormats.length; formatIndex < formatCount; ++formatIndex) {
|
||||
describeComplexDataFormat(
|
||||
supportedFormatType.addNewFormat(),
|
||||
fullFormats[formatIndex]);
|
||||
}
|
||||
} else {
|
||||
|
||||
String[] formats = handler.getSupportedFormats();
|
||||
|
||||
if (formats == null || formats.length == 0) {
|
||||
LOGGER.warn("Skipping IOHandler {} in ProcessDescription generation for {}, no formats specified",
|
||||
handler.getClass().getSimpleName(),
|
||||
getWellKnownName());
|
||||
} else {
|
||||
// if formats, encodings or schemas arrays are 'null' or empty, create
|
||||
// new array with single 'null' element. We do this so we can utilize
|
||||
// a single set of nested loops to process all permutations. 'null'
|
||||
// values will not be output...
|
||||
String[] encodings = handler.getSupportedEncodings();
|
||||
if (encodings == null || encodings.length == 0) {
|
||||
encodings = new String[] { null };
|
||||
}
|
||||
String[] schemas = handler.getSupportedSchemas();
|
||||
if (schemas == null || schemas.length == 0) {
|
||||
schemas = new String[] { null };
|
||||
}
|
||||
|
||||
for (String format : formats) {
|
||||
for (String encoding : encodings) {
|
||||
for (String schema : schemas) {
|
||||
if (needDefault) {
|
||||
needDefault = false;
|
||||
describeComplexDataFormat(
|
||||
defaultFormatType.addNewFormat(),
|
||||
format, encoding, schema);
|
||||
}
|
||||
describeComplexDataFormat(
|
||||
supportedFormatType.addNewFormat(),
|
||||
format, encoding, schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void describeComplexDataFormat(
|
||||
ComplexDataDescriptionType description,
|
||||
Format format)
|
||||
{
|
||||
describeComplexDataFormat(description,
|
||||
format.getMimetype(),
|
||||
format.getEncoding(),
|
||||
format.getSchema());
|
||||
}
|
||||
|
||||
private void describeComplexDataFormat(ComplexDataDescriptionType description,
|
||||
String format,
|
||||
String encoding,
|
||||
String schema) {
|
||||
if ( !Strings.isNullOrEmpty(format)) {
|
||||
description.setMimeType(format);
|
||||
}
|
||||
if ( !Strings.isNullOrEmpty(encoding)) {
|
||||
description.setEncoding(encoding);
|
||||
}
|
||||
if ( !Strings.isNullOrEmpty(schema)) {
|
||||
description.setSchema(schema);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDescriptionIsValid() {
|
||||
XmlOptions xmlOptions = new XmlOptions();
|
||||
List<XmlValidationError> xmlValidationErrorList = new ArrayList<XmlValidationError>();
|
||||
xmlOptions.setErrorListener(xmlValidationErrorList);
|
||||
boolean valid = getDescription().validate(xmlOptions);
|
||||
if (!valid) {
|
||||
LOGGER.error("Error validating process description for " + getClass().getCanonicalName());
|
||||
for (XmlValidationError xmlValidationError : xmlValidationErrorList) {
|
||||
LOGGER.error("\tMessage: {}", xmlValidationError.getMessage());
|
||||
LOGGER.error("\tLocation of invalid XML: {}",
|
||||
xmlValidationError.getCursorLocation().xmlText());
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
protected final synchronized AlgorithmDescriptor getAlgorithmDescriptor() {
|
||||
if (descriptor == null) {
|
||||
descriptor = createAlgorithmDescriptor();
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
protected abstract AlgorithmDescriptor createAlgorithmDescriptor();
|
||||
|
||||
@Override
|
||||
public Class<? extends IData> getInputDataType(String identifier) {
|
||||
AlgorithmDescriptor algorithmDescriptor = getAlgorithmDescriptor();
|
||||
if (algorithmDescriptor != null) {
|
||||
return getAlgorithmDescriptor().getInputDescriptor(identifier).getBinding();
|
||||
} else {
|
||||
throw new IllegalStateException("Instance must have an algorithm descriptor");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IData> getOutputDataType(String identifier) {
|
||||
AlgorithmDescriptor algorithmDescriptor = getAlgorithmDescriptor();
|
||||
if (algorithmDescriptor != null) {
|
||||
return getAlgorithmDescriptor().getOutputDescriptor(identifier).getBinding();
|
||||
} else {
|
||||
throw new IllegalStateException("Instance must have an algorithm descriptor");
|
||||
}
|
||||
}
|
||||
|
||||
private List observers = new ArrayList();
|
||||
private Object state = null;
|
||||
|
||||
@Override
|
||||
public Object getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Object state) {
|
||||
this.state = state;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addObserver(IObserver o) {
|
||||
observers.add(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObserver(IObserver o) {
|
||||
observers.remove(o);
|
||||
}
|
||||
|
||||
public void notifyObservers() {
|
||||
Iterator i = observers.iterator();
|
||||
while (i.hasNext()) {
|
||||
IObserver o = (IObserver) i.next();
|
||||
o.update(this);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> errorList = new ArrayList();
|
||||
protected List<String> addError(String error) {
|
||||
errorList.add(error);
|
||||
return errorList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getErrors() {
|
||||
return errorList;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
import net.opengis.wps.x100.ProcessDescriptionsDocument;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.n52.wps.server.observerpattern.IObserver;
|
||||
import org.n52.wps.server.observerpattern.ISubject;
|
||||
|
||||
public abstract class AbstractObservableAlgorithm implements IAlgorithm, ISubject{
|
||||
|
||||
protected ProcessDescriptionType description;
|
||||
protected final String wkName;
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(AbstractAlgorithm.class);
|
||||
|
||||
/**
|
||||
* default constructor, calls the initializeDescription() Method
|
||||
*/
|
||||
public AbstractObservableAlgorithm() {
|
||||
this.description = initializeDescription();
|
||||
this.wkName = "";
|
||||
}
|
||||
|
||||
public AbstractObservableAlgorithm(ProcessDescriptionType description) {
|
||||
this.description = description;
|
||||
this.wkName = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* default constructor, calls the initializeDescription() Method
|
||||
*/
|
||||
public AbstractObservableAlgorithm(String wellKnownName) {
|
||||
this.wkName = wellKnownName; // Has to be initialized before the description.
|
||||
this.description = initializeDescription();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overwritten, in case you want to have a way of initializing.
|
||||
*
|
||||
* In detail it looks for a xml descfile, which is located in the same directory as the implementing class and has the same
|
||||
* name as the class, but with the extension XML.
|
||||
* @return
|
||||
*/
|
||||
protected ProcessDescriptionType initializeDescription() {
|
||||
String className = this.getClass().getName().replace(".", "/");
|
||||
InputStream xmlDesc = this.getClass().getResourceAsStream("/" + className + ".xml");
|
||||
try {
|
||||
XmlOptions option = new XmlOptions();
|
||||
option.setLoadTrimTextBuffer();
|
||||
ProcessDescriptionsDocument doc = ProcessDescriptionsDocument.Factory.parse(xmlDesc, option);
|
||||
if(doc.getProcessDescriptions().getProcessDescriptionArray().length == 0) {
|
||||
LOGGER.warn("ProcessDescription does not contain correct any description");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Checking that the process name (full class name or well-known name) matches the identifier.
|
||||
if(!doc.getProcessDescriptions().getProcessDescriptionArray(0).getIdentifier().getStringValue().equals(this.getClass().getName()) &&
|
||||
!doc.getProcessDescriptions().getProcessDescriptionArray(0).getIdentifier().getStringValue().equals(this.getWellKnownName())) {
|
||||
doc.getProcessDescriptions().getProcessDescriptionArray(0).getIdentifier().setStringValue(this.getClass().getName());
|
||||
LOGGER.warn("Identifier was not correct, was changed now temporary for server use to " + this.getClass().getName() + ". Please change it later in the description!");
|
||||
}
|
||||
|
||||
return doc.getProcessDescriptions().getProcessDescriptionArray(0);
|
||||
}
|
||||
catch(IOException e) {
|
||||
LOGGER.warn("Could not initialize algorithm, parsing error: " + this.getClass().getName(), e);
|
||||
}
|
||||
catch(XmlException e) {
|
||||
LOGGER.warn("Could not initialize algorithm, parsing error: " + this.getClass().getName(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ProcessDescriptionType getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean processDescriptionIsValid() {
|
||||
return description.validate();
|
||||
}
|
||||
|
||||
public String getWellKnownName() {
|
||||
return this.wkName;
|
||||
}
|
||||
|
||||
private List observers = new ArrayList();
|
||||
|
||||
private Object state = null;
|
||||
|
||||
public Object getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void update(Object state) {
|
||||
this.state = state;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void addObserver(IObserver o) {
|
||||
observers.add(o);
|
||||
}
|
||||
|
||||
public void removeObserver(IObserver o) {
|
||||
observers.remove(o);
|
||||
}
|
||||
|
||||
public void notifyObservers() {
|
||||
Iterator i = observers.iterator();
|
||||
while (i.hasNext()) {
|
||||
IObserver o = (IObserver) i.next();
|
||||
o.update(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,420 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.opengis.ows.x11.DomainMetadataType;
|
||||
import net.opengis.wps.x100.CRSsType;
|
||||
import net.opengis.wps.x100.ComplexDataCombinationType;
|
||||
import net.opengis.wps.x100.ComplexDataCombinationsType;
|
||||
import net.opengis.wps.x100.ComplexDataDescriptionType;
|
||||
import net.opengis.wps.x100.InputDescriptionType;
|
||||
import net.opengis.wps.x100.LiteralInputType;
|
||||
import net.opengis.wps.x100.LiteralOutputType;
|
||||
import net.opengis.wps.x100.OutputDescriptionType;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType.DataInputs;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType.ProcessOutputs;
|
||||
import net.opengis.wps.x100.ProcessDescriptionsDocument;
|
||||
import net.opengis.wps.x100.ProcessDescriptionsDocument.ProcessDescriptions;
|
||||
import net.opengis.wps.x100.SupportedCRSsType;
|
||||
import net.opengis.wps.x100.SupportedCRSsType.Default;
|
||||
import net.opengis.wps.x100.SupportedComplexDataInputType;
|
||||
import net.opengis.wps.x100.SupportedComplexDataType;
|
||||
|
||||
import org.n52.wps.FormatDocument.Format;
|
||||
import org.n52.wps.io.GeneratorFactory;
|
||||
import org.n52.wps.io.IGenerator;
|
||||
import org.n52.wps.io.IParser;
|
||||
import org.n52.wps.io.ParserFactory;
|
||||
import org.n52.wps.io.data.IBBOXData;
|
||||
import org.n52.wps.io.data.IComplexData;
|
||||
import org.n52.wps.io.data.ILiteralData;
|
||||
import org.n52.wps.server.observerpattern.IObserver;
|
||||
import org.n52.wps.server.observerpattern.ISubject;
|
||||
|
||||
|
||||
public abstract class AbstractSelfDescribingAlgorithm extends AbstractAlgorithm implements ISubject{
|
||||
|
||||
@Override
|
||||
protected ProcessDescriptionType initializeDescription() {
|
||||
ProcessDescriptionsDocument document = ProcessDescriptionsDocument.Factory.newInstance();
|
||||
ProcessDescriptions processDescriptions = document.addNewProcessDescriptions();
|
||||
ProcessDescriptionType processDescription = processDescriptions.addNewProcessDescription();
|
||||
processDescription.setStatusSupported(true);
|
||||
processDescription.setStoreSupported(true);
|
||||
processDescription.setProcessVersion("1.0.0");
|
||||
|
||||
//1. Identifier
|
||||
processDescription.addNewIdentifier().setStringValue(this.getClass().getName());
|
||||
processDescription.addNewTitle().setStringValue(this.getClass().getCanonicalName());
|
||||
|
||||
//2. Inputs
|
||||
List<String> identifiers = this.getInputIdentifiers();
|
||||
DataInputs dataInputs = null;
|
||||
if(identifiers.size()>0){
|
||||
dataInputs = processDescription.addNewDataInputs();
|
||||
}
|
||||
|
||||
for(String identifier : identifiers){
|
||||
InputDescriptionType dataInput = dataInputs.addNewInput();
|
||||
dataInput.setMinOccurs(getMinOccurs(identifier));
|
||||
dataInput.setMaxOccurs(getMaxOccurs(identifier));
|
||||
dataInput.addNewIdentifier().setStringValue(identifier);
|
||||
dataInput.addNewTitle().setStringValue(identifier);
|
||||
|
||||
Class<?> inputDataTypeClass = this.getInputDataType(identifier);
|
||||
Class<?>[] interfaces = inputDataTypeClass.getInterfaces();
|
||||
|
||||
//we have to add this because of the new AbstractLiteralDataBinding class
|
||||
if(interfaces.length == 0){
|
||||
interfaces = inputDataTypeClass.getSuperclass().getInterfaces();
|
||||
}
|
||||
|
||||
for(Class<?> implementedInterface : interfaces){
|
||||
if(implementedInterface.equals(ILiteralData.class)){
|
||||
LiteralInputType literalData = dataInput.addNewLiteralData();
|
||||
String inputClassType = "";
|
||||
|
||||
Constructor<?>[] constructors = inputDataTypeClass.getConstructors();
|
||||
for(Constructor<?> constructor : constructors){
|
||||
Class<?>[] parameters = constructor.getParameterTypes();
|
||||
if(parameters.length==1){
|
||||
inputClassType = parameters[0].getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
if(inputClassType.length()>0){
|
||||
DomainMetadataType datatype = literalData.addNewDataType();
|
||||
datatype.setReference("xs:"+inputClassType.toLowerCase());
|
||||
literalData.addNewAnyValue();
|
||||
}
|
||||
}else if(implementedInterface.equals(IBBOXData.class)){
|
||||
SupportedCRSsType bboxData = dataInput.addNewBoundingBoxData();
|
||||
String[] supportedCRSAray = getSupportedCRSForBBOXInput(identifier);
|
||||
for(int i = 0; i<supportedCRSAray.length; i++){
|
||||
if(i==0){
|
||||
Default defaultCRS = bboxData.addNewDefault();
|
||||
defaultCRS.setCRS(supportedCRSAray[0]);
|
||||
if(supportedCRSAray.length==1){
|
||||
CRSsType supportedCRS = bboxData.addNewSupported();
|
||||
supportedCRS.addCRS(supportedCRSAray[0]);
|
||||
}
|
||||
}else{
|
||||
if(i==1){
|
||||
CRSsType supportedCRS = bboxData.addNewSupported();
|
||||
supportedCRS.addCRS(supportedCRSAray[1]);
|
||||
}else{
|
||||
bboxData.getSupported().addCRS(supportedCRSAray[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}else if(implementedInterface.equals(IComplexData.class)){
|
||||
SupportedComplexDataInputType complexData = dataInput.addNewComplexData();
|
||||
List<IParser> parsers = ParserFactory.getInstance().getAllParsers();
|
||||
List<IParser> foundParsers = new ArrayList<IParser>();
|
||||
for(IParser parser : parsers) {
|
||||
Class<?>[] supportedClasses = parser.getSupportedDataBindings();
|
||||
for(Class<?> clazz : supportedClasses){
|
||||
if(clazz.equals(inputDataTypeClass)){
|
||||
foundParsers.add(parser);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
addInputFormats(complexData, foundParsers);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//3. Outputs
|
||||
ProcessOutputs dataOutputs = processDescription.addNewProcessOutputs();
|
||||
List<String> outputIdentifiers = this.getOutputIdentifiers();
|
||||
for(String identifier : outputIdentifiers){
|
||||
OutputDescriptionType dataOutput = dataOutputs.addNewOutput();
|
||||
|
||||
|
||||
dataOutput.addNewIdentifier().setStringValue(identifier);
|
||||
dataOutput.addNewTitle().setStringValue(identifier);
|
||||
dataOutput.addNewAbstract().setStringValue(identifier);
|
||||
|
||||
Class<?> outputDataTypeClass = this.getOutputDataType(identifier);
|
||||
Class<?>[] interfaces = outputDataTypeClass.getInterfaces();
|
||||
|
||||
//we have to add this because of the new AbstractLiteralDataBinding class
|
||||
if(interfaces.length == 0){
|
||||
interfaces = outputDataTypeClass.getSuperclass().getInterfaces();
|
||||
}
|
||||
for(Class<?> implementedInterface : interfaces){
|
||||
|
||||
|
||||
if(implementedInterface.equals(ILiteralData.class)){
|
||||
LiteralOutputType literalData = dataOutput.addNewLiteralOutput();
|
||||
String outputClassType = "";
|
||||
|
||||
Constructor<?>[] constructors = outputDataTypeClass.getConstructors();
|
||||
for(Constructor<?> constructor : constructors){
|
||||
Class<?>[] parameters = constructor.getParameterTypes();
|
||||
if(parameters.length==1){
|
||||
outputClassType = parameters[0].getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
if(outputClassType.length()>0){
|
||||
literalData.addNewDataType().setReference("xs:"+outputClassType.toLowerCase());
|
||||
}
|
||||
|
||||
}else if(implementedInterface.equals(IBBOXData.class)){
|
||||
SupportedCRSsType bboxData = dataOutput.addNewBoundingBoxOutput();
|
||||
String[] supportedCRSAray = getSupportedCRSForBBOXOutput(identifier);
|
||||
for(int i = 0; i<supportedCRSAray.length; i++){
|
||||
if(i==0){
|
||||
Default defaultCRS = bboxData.addNewDefault();
|
||||
defaultCRS.setCRS(supportedCRSAray[0]);
|
||||
if(supportedCRSAray.length==1){
|
||||
CRSsType supportedCRS = bboxData.addNewSupported();
|
||||
supportedCRS.addCRS(supportedCRSAray[0]);
|
||||
}
|
||||
}else{
|
||||
if(i==1){
|
||||
CRSsType supportedCRS = bboxData.addNewSupported();
|
||||
supportedCRS.addCRS(supportedCRSAray[1]);
|
||||
}else{
|
||||
bboxData.getSupported().addCRS(supportedCRSAray[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}else if(implementedInterface.equals(IComplexData.class)){
|
||||
|
||||
SupportedComplexDataType complexData = dataOutput.addNewComplexOutput();
|
||||
|
||||
List<IGenerator> generators = GeneratorFactory.getInstance().getAllGenerators();
|
||||
List<IGenerator> foundGenerators = new ArrayList<IGenerator>();
|
||||
for(IGenerator generator : generators) {
|
||||
Class<?>[] supportedClasses = generator.getSupportedDataBindings();
|
||||
for(Class<?> clazz : supportedClasses){
|
||||
if(clazz.equals(outputDataTypeClass)){
|
||||
foundGenerators.add(generator);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
addOutputFormats(complexData, foundGenerators);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return document.getProcessDescriptions().getProcessDescriptionArray(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this class for BBOX input data to set supported mime types. The first one in the resulting array will be the default one.
|
||||
* @param identifier ID of the input BBOXType
|
||||
* @return
|
||||
*/
|
||||
public String[] getSupportedCRSForBBOXInput(String identifier){
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this class for BBOX output data to set supported mime types. The first one in the resulting array will be the default one.
|
||||
* @param identifier ID of the input BBOXType
|
||||
* @return
|
||||
*/
|
||||
public String[] getSupportedCRSForBBOXOutput(String identifier){
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public BigInteger getMinOccurs(String identifier){
|
||||
return new BigInteger("1");
|
||||
}
|
||||
public BigInteger getMaxOccurs(String identifier){
|
||||
return new BigInteger("1");
|
||||
}
|
||||
|
||||
public abstract List<String> getInputIdentifiers();
|
||||
public abstract List<String> getOutputIdentifiers();
|
||||
|
||||
|
||||
|
||||
private List<IObserver> observers = new ArrayList<IObserver>();
|
||||
|
||||
private Object state = null;
|
||||
|
||||
public Object getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void update(Object state) {
|
||||
this.state = state;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public void addObserver(IObserver o) {
|
||||
observers.add(o);
|
||||
}
|
||||
|
||||
public void removeObserver(IObserver o) {
|
||||
observers.remove(o);
|
||||
}
|
||||
|
||||
public void notifyObservers() {
|
||||
Iterator<IObserver> i = observers.iterator();
|
||||
while (i.hasNext()) {
|
||||
IObserver o = (IObserver) i.next();
|
||||
o.update(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getErrors() {
|
||||
List<String> errors = new ArrayList<String>();
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
private void addInputFormats(SupportedComplexDataInputType complexData,
|
||||
List<IParser> foundParsers) {
|
||||
ComplexDataCombinationsType supportedInputFormat = complexData
|
||||
.addNewSupported();
|
||||
|
||||
for (int i = 0; i < foundParsers.size(); i++) {
|
||||
IParser parser = foundParsers.get(i);
|
||||
|
||||
Format[] supportedFullFormats = parser.getSupportedFullFormats();
|
||||
|
||||
if (complexData.getDefault() == null) {
|
||||
ComplexDataCombinationType defaultInputFormat = complexData
|
||||
.addNewDefault();
|
||||
/*
|
||||
* default format will be the first config format
|
||||
*/
|
||||
Format format = supportedFullFormats[0];
|
||||
ComplexDataDescriptionType defaultFormat = defaultInputFormat
|
||||
.addNewFormat();
|
||||
defaultFormat.setMimeType(format.getMimetype());
|
||||
|
||||
String encoding = format.getEncoding();
|
||||
|
||||
if (encoding != null && !encoding.equals("")) {
|
||||
defaultFormat.setEncoding(encoding);
|
||||
}
|
||||
|
||||
String schema = format.getSchema();
|
||||
|
||||
if (schema != null && !schema.equals("")) {
|
||||
defaultFormat.setSchema(schema);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < supportedFullFormats.length; j++) {
|
||||
/*
|
||||
* create supportedFormat for each mimetype, encoding, schema
|
||||
* composition mimetypes can have several encodings and schemas
|
||||
*/
|
||||
Format format1 = supportedFullFormats[j];
|
||||
|
||||
/*
|
||||
* add one format for this mimetype
|
||||
*/
|
||||
ComplexDataDescriptionType supportedFormat = supportedInputFormat
|
||||
.addNewFormat();
|
||||
supportedFormat.setMimeType(format1.getMimetype());
|
||||
if (format1.getEncoding() != null) {
|
||||
supportedFormat.setEncoding(format1.getEncoding());
|
||||
}
|
||||
if (format1.getSchema() != null) {
|
||||
supportedFormat.setSchema(format1.getSchema());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addOutputFormats(SupportedComplexDataType complexData,
|
||||
List<IGenerator> foundGenerators) {
|
||||
ComplexDataCombinationsType supportedOutputFormat = complexData
|
||||
.addNewSupported();
|
||||
|
||||
for (int i = 0; i < foundGenerators.size(); i++) {
|
||||
IGenerator generator = foundGenerators.get(i);
|
||||
|
||||
Format[] supportedFullFormats = generator.getSupportedFullFormats();
|
||||
|
||||
if (complexData.getDefault() == null) {
|
||||
ComplexDataCombinationType defaultInputFormat = complexData
|
||||
.addNewDefault();
|
||||
/*
|
||||
* default format will be the first config format
|
||||
*/
|
||||
Format format = supportedFullFormats[0];
|
||||
ComplexDataDescriptionType defaultFormat = defaultInputFormat
|
||||
.addNewFormat();
|
||||
defaultFormat.setMimeType(format.getMimetype());
|
||||
|
||||
String encoding = format.getEncoding();
|
||||
|
||||
if (encoding != null && !encoding.equals("")) {
|
||||
defaultFormat.setEncoding(encoding);
|
||||
}
|
||||
|
||||
String schema = format.getSchema();
|
||||
|
||||
if (schema != null && !schema.equals("")) {
|
||||
defaultFormat.setSchema(schema);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < supportedFullFormats.length; j++) {
|
||||
/*
|
||||
* create supportedFormat for each mimetype, encoding, schema
|
||||
* composition mimetypes can have several encodings and schemas
|
||||
*/
|
||||
Format format1 = supportedFullFormats[j];
|
||||
|
||||
/*
|
||||
* add one format for this mimetype
|
||||
*/
|
||||
ComplexDataDescriptionType supportedFormat = supportedOutputFormat
|
||||
.addNewFormat();
|
||||
supportedFormat.setMimeType(format1.getMimetype());
|
||||
if (format1.getEncoding() != null) {
|
||||
supportedFormat.setEncoding(format1.getEncoding());
|
||||
}
|
||||
if (format1.getSchema() != null) {
|
||||
supportedFormat.setSchema(format1.getSchema());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.n52.wps.io.data.IData;
|
||||
|
||||
import net.opengis.wps.x100.ExecuteDocument;
|
||||
|
||||
public abstract class AbstractTransactionalAlgorithm implements IAlgorithm{
|
||||
|
||||
|
||||
protected String algorithmID;
|
||||
|
||||
|
||||
public AbstractTransactionalAlgorithm(String algorithmID){
|
||||
this.algorithmID = algorithmID;
|
||||
|
||||
}
|
||||
|
||||
public String getAlgorithmID() {
|
||||
return algorithmID;
|
||||
}
|
||||
|
||||
public abstract Map<String, IData> run(ExecuteDocument document);
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
|
||||
public class AlgorithmParameterException extends RuntimeException {
|
||||
private static final long serialVersionUID = -514774594848925943L;
|
||||
|
||||
public AlgorithmParameterException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AlgorithmParameterException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.n52.wps.server.ExceptionReport;
|
||||
|
||||
/**
|
||||
* @author Bastian Schaeffer, University of Muenster, Theodor Foerster, ITC
|
||||
*
|
||||
*/
|
||||
public interface IAlgorithm {
|
||||
|
||||
Map<String, IData> run(Map<String, List<IData>> inputData) throws ExceptionReport;
|
||||
|
||||
List<String> getErrors();
|
||||
|
||||
ProcessDescriptionType getDescription();
|
||||
|
||||
/** Returns some well-known name for the process.
|
||||
*
|
||||
* @return Returns some well-known name for the process or algorithm
|
||||
* if that exists, else returns an empty String, never null.
|
||||
* @note The fully-qualified class name is gotten via getName();
|
||||
*/
|
||||
String getWellKnownName();
|
||||
|
||||
/**
|
||||
* Checks if the processDescription complies to the process itself and fits any schema or other dependencies.
|
||||
*/
|
||||
boolean processDescriptionIsValid();
|
||||
|
||||
Class< ? > getInputDataType(String id);
|
||||
|
||||
Class< ? > getOutputDataType(String id);
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
|
||||
/**
|
||||
* @author Bastian Schaeffer, University of Muenster, Theodor Foerster, ITC
|
||||
*
|
||||
*/
|
||||
public interface IAlgorithmRepository {
|
||||
Collection<String> getAlgorithmNames();
|
||||
|
||||
IAlgorithm getAlgorithm(String processID);
|
||||
|
||||
ProcessDescriptionType getProcessDescription(String processID);
|
||||
|
||||
boolean containsAlgorithm(String processID);
|
||||
|
||||
/**
|
||||
* use to free resources
|
||||
*/
|
||||
public void shutdown();
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
/**
|
||||
* @author Bastian Schaeffer, University of Muenster
|
||||
*
|
||||
*/
|
||||
public interface ITransactionalAlgorithmRepository extends IAlgorithmRepository{
|
||||
boolean addAlgorithm(Object className);
|
||||
boolean removeAlgorithm(Object className);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface IWorkspaceRepository {
|
||||
File getWorkspace();
|
||||
boolean createWorkspace();
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.n52.wps.PropertyDocument.Property;
|
||||
import org.n52.wps.algorithm.annotation.Algorithm;
|
||||
import org.n52.wps.commons.WPSConfig;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A static repository to retrieve the available algorithms.
|
||||
* @author foerster
|
||||
*
|
||||
*/
|
||||
public class LocalAlgorithmRepository implements ITransactionalAlgorithmRepository{
|
||||
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(LocalAlgorithmRepository.class);
|
||||
private Map<String, String> algorithmMap;
|
||||
private Map<String, ProcessDescriptionType> processDescriptionMap;
|
||||
|
||||
public LocalAlgorithmRepository() {
|
||||
algorithmMap = new HashMap<String, String>();
|
||||
processDescriptionMap = new HashMap<String, ProcessDescriptionType>();
|
||||
|
||||
// check if the repository is active
|
||||
if(WPSConfig.getInstance().isRepositoryActive(this.getClass().getCanonicalName())){
|
||||
Property[] propertyArray = WPSConfig.getInstance().getPropertiesForRepositoryClass(this.getClass().getCanonicalName());
|
||||
for(Property property : propertyArray){
|
||||
// check the name and active state
|
||||
if(property.getName().equalsIgnoreCase("Algorithm") && property.getActive()){
|
||||
addAlgorithm(property.getStringValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("Local Algorithm Repository is inactive.");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addAlgorithms(String[] algorithms) {
|
||||
for(String algorithmClassName : algorithms) {
|
||||
addAlgorithm(algorithmClassName);
|
||||
}
|
||||
LOGGER.info("Algorithms registered!");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public IAlgorithm getAlgorithm(String className) {
|
||||
try {
|
||||
return loadAlgorithm(algorithmMap.get(className));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("error getting algorithm",e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getAlgorithmNames() {
|
||||
return new ArrayList<String>(algorithmMap.keySet());
|
||||
}
|
||||
|
||||
public boolean containsAlgorithm(String className) {
|
||||
return algorithmMap.containsKey(className);
|
||||
}
|
||||
|
||||
private IAlgorithm loadAlgorithm(String algorithmClassName) throws Exception {
|
||||
Class<?> algorithmClass = LocalAlgorithmRepository.class.getClassLoader().loadClass(algorithmClassName);
|
||||
IAlgorithm algorithm = null;
|
||||
if (IAlgorithm.class.isAssignableFrom(algorithmClass)) {
|
||||
algorithm = IAlgorithm.class.cast(algorithmClass.newInstance());
|
||||
} else if (algorithmClass.isAnnotationPresent(Algorithm.class)) {
|
||||
// we have an annotated algorithm that doesn't implement IAlgorithm
|
||||
// wrap it in a proxy class
|
||||
algorithm = new AbstractAnnotatedAlgorithm.Proxy(algorithmClass);
|
||||
}
|
||||
else {
|
||||
throw new Exception("Could not load algorithm " + algorithmClassName + " does not implement IAlgorithm or have a Algorithm annotation.");
|
||||
}
|
||||
|
||||
if(!algorithm.processDescriptionIsValid()) {
|
||||
LOGGER.warn("Algorithm description is not valid: " + algorithmClassName);
|
||||
throw new Exception("Could not load algorithm " +algorithmClassName +". ProcessDescription Not Valid.");
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public boolean addAlgorithm(Object processID) {
|
||||
if(!(processID instanceof String)){
|
||||
return false;
|
||||
}
|
||||
String algorithmClassName = (String) processID;
|
||||
|
||||
algorithmMap.put(algorithmClassName, algorithmClassName);
|
||||
LOGGER.info("Algorithm class registered: " + algorithmClassName);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public boolean removeAlgorithm(Object processID) {
|
||||
if(!(processID instanceof String)){
|
||||
return false;
|
||||
}
|
||||
String className = (String) processID;
|
||||
if(algorithmMap.containsKey(className)){
|
||||
algorithmMap.remove(className);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDescriptionType getProcessDescription(String processID) {
|
||||
if(!processDescriptionMap.containsKey(processID)){
|
||||
processDescriptionMap.put(processID, getAlgorithm(processID).getDescription());
|
||||
}
|
||||
return processDescriptionMap.get(processID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
|
||||
public class ServiceLoaderAlgorithmRepository implements IAlgorithmRepository {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServiceLoaderAlgorithmRepository.class);
|
||||
private Map<String, Class<? extends IAlgorithm>> currentAlgorithms;
|
||||
|
||||
public ServiceLoaderAlgorithmRepository() {
|
||||
this.currentAlgorithms = loadAlgorithms();
|
||||
}
|
||||
|
||||
private Map<String, Class<? extends IAlgorithm>> loadAlgorithms() {
|
||||
Map<String, Class<? extends IAlgorithm>> result = new HashMap<String, Class<? extends IAlgorithm>>();
|
||||
ServiceLoader<IAlgorithm> loader = ServiceLoader.load(IAlgorithm.class);
|
||||
|
||||
for (IAlgorithm ia : loader) {
|
||||
logger.debug("Adding algorithm with identifier {} and class {}",
|
||||
ia.getWellKnownName(), ia.getClass().getCanonicalName());
|
||||
result.put(ia.getWellKnownName(), ia.getClass());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getAlgorithmNames() {
|
||||
return this.currentAlgorithms.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAlgorithm getAlgorithm(String processID) {
|
||||
Class<? extends IAlgorithm> clazz = this.currentAlgorithms.get(processID);
|
||||
if (clazz != null) {
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDescriptionType getProcessDescription(String processID) {
|
||||
IAlgorithm algo = getAlgorithm(processID);
|
||||
if (algo != null) {
|
||||
return algo.getDescription();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAlgorithm(String processID) {
|
||||
return this.currentAlgorithms.containsKey(processID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.n52.wps.PropertyDocument.Property;
|
||||
import org.n52.wps.commons.WPSConfig;
|
||||
|
||||
/**
|
||||
* A static repository to retrieve the available algorithms.
|
||||
*
|
||||
* @author foerster, Bastian Schaeffer, University of Muenster
|
||||
*
|
||||
*/
|
||||
public class UploadedAlgorithmRepository implements
|
||||
ITransactionalAlgorithmRepository {
|
||||
|
||||
private static Logger LOGGER = LoggerFactory
|
||||
.getLogger(LocalAlgorithmRepository.class);
|
||||
private Map<String, String> algorithmMap;
|
||||
private Map<String, ProcessDescriptionType> processDescriptionMap;
|
||||
|
||||
public UploadedAlgorithmRepository() {
|
||||
algorithmMap = new HashMap<String, String>();
|
||||
processDescriptionMap = new HashMap<String, ProcessDescriptionType>();
|
||||
|
||||
if (WPSConfig.getInstance().isRepositoryActive(
|
||||
this.getClass().getCanonicalName())) {
|
||||
Property[] propertyArray = WPSConfig.getInstance()
|
||||
.getPropertiesForRepositoryClass(
|
||||
this.getClass().getCanonicalName());
|
||||
for (Property property : propertyArray) {
|
||||
if (property.getName().equalsIgnoreCase("Algorithm")
|
||||
&& property.getActive()) {
|
||||
addAlgorithm(property.getStringValue());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("Local Algorithm Repository is inactive.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean addAlgorithms(String[] algorithms) {
|
||||
for (String algorithmClassName : algorithms) {
|
||||
addAlgorithm(algorithmClassName);
|
||||
}
|
||||
LOGGER.info("Algorithms registered!");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public IAlgorithm getAlgorithm(String className) {
|
||||
try {
|
||||
return loadAlgorithm(algorithmMap.get(className));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("error getting algorithm",e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<IAlgorithm> getAlgorithms() {
|
||||
Collection<IAlgorithm> resultList = new ArrayList<IAlgorithm>();
|
||||
try {
|
||||
for (String algorithmClasses : algorithmMap.values()) {
|
||||
resultList
|
||||
.add(loadAlgorithm(algorithmMap.get(algorithmClasses)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("error getting algorithm",e);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public Collection<String> getAlgorithmNames() {
|
||||
return new ArrayList<String>(algorithmMap.keySet());
|
||||
}
|
||||
|
||||
public boolean containsAlgorithm(String className) {
|
||||
return algorithmMap.containsKey(className);
|
||||
}
|
||||
|
||||
private IAlgorithm loadAlgorithm(String algorithmClassName)
|
||||
throws Exception {
|
||||
IAlgorithm algorithm = (IAlgorithm) LocalAlgorithmRepository.class
|
||||
.getClassLoader().loadClass(algorithmClassName).newInstance();
|
||||
if (!algorithm.processDescriptionIsValid()) {
|
||||
LOGGER.warn("Algorithm description is not valid: "
|
||||
+ algorithmClassName);
|
||||
throw new Exception("Could not load algorithm "
|
||||
+ algorithmClassName + ". ProcessDescription Not Valid.");
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public boolean addAlgorithm(Object processID) {
|
||||
if (!(processID instanceof String)) {
|
||||
return false;
|
||||
}
|
||||
String algorithmClassName = (String) processID;
|
||||
|
||||
algorithmMap.put(algorithmClassName, algorithmClassName);
|
||||
LOGGER.info("Algorithm class registered: " + algorithmClassName);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public boolean removeAlgorithm(Object processID) {
|
||||
if (!(processID instanceof String)) {
|
||||
return false;
|
||||
}
|
||||
String className = (String) processID;
|
||||
if (algorithmMap.containsKey(className)) {
|
||||
algorithmMap.remove(className);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessDescriptionType getProcessDescription(String processID) {
|
||||
if (!processDescriptionMap.containsKey(processID)) {
|
||||
processDescriptionMap.put(processID, getAlgorithm(processID)
|
||||
.getDescription());
|
||||
}
|
||||
return processDescriptionMap.get(processID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.test.mock;
|
||||
|
||||
import org.n52.wps.io.data.IComplexData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class MockBinding implements IComplexData {
|
||||
|
||||
private final MockComplexObject payload;
|
||||
|
||||
public MockBinding(MockComplexObject payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MockComplexObject getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getSupportedClass() {
|
||||
return MockComplexObject.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.test.mock;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class MockComplexObject {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.test.mock;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public enum MockEnum {
|
||||
VALUE1,
|
||||
VALUE2,
|
||||
VALUE3
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.test.mock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.n52.wps.FormatDocument.Format;
|
||||
import org.n52.wps.io.IGenerator;
|
||||
import org.n52.wps.io.data.IData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class MockGenerator implements IGenerator {
|
||||
|
||||
public final static List<String> schemaSet;
|
||||
public final static List<String> formatSet;
|
||||
public final static List<String> encodingSet;
|
||||
|
||||
static {
|
||||
schemaSet = Collections.unmodifiableList(new ArrayList(MockUtil.getParserSupportedSchemas(MockParser.class)));
|
||||
formatSet = Collections.unmodifiableList(new ArrayList(MockUtil.getParserSupportedFormats(MockParser.class)));
|
||||
encodingSet = Collections.unmodifiableList(new ArrayList(MockUtil.getParserSupportedEncodings(MockParser.class)));
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public OutputStream generate(IData coll) {
|
||||
// throw new UnsupportedOperationException("Not supported yet.");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Class[] getSupportedInternalInputDataType() {
|
||||
// return new Class[] { MockBinding.class };
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isSupportedSchema(String schema) {
|
||||
return schemaSet.contains(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedFormat(String format) {
|
||||
return formatSet.contains(format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedEncoding(String encoding) {
|
||||
return encodingSet.contains(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedSchemas() {
|
||||
return schemaSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedFormats() {
|
||||
return formatSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedEncodings() {
|
||||
return encodingSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream generateStream(IData data, String mimeType, String schema) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream generateBase64Stream(IData data, String mimeType, String schema) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedDataBinding(Class<?> clazz) {
|
||||
return Arrays.binarySearch(getSupportedDataBindings(), clazz) > -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format[] getSupportedFullFormats() {
|
||||
Format f = Format.Factory.newInstance();
|
||||
f.setSchema(schemaSet.get(0));
|
||||
f.setEncoding(encodingSet.get(0));
|
||||
f.setMimetype(formatSet.get(0));
|
||||
return new Format[] {f};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getSupportedDataBindings() {
|
||||
return new Class[] { MockBinding.class };
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.test.mock;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.n52.wps.FormatDocument.Format;
|
||||
import org.n52.wps.io.IParser;
|
||||
import org.n52.wps.io.data.IData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class MockParser implements IParser {
|
||||
|
||||
public final static List<String> schemaSet;
|
||||
public final static List<String> formatSet;
|
||||
public final static List<String> encodingSet;
|
||||
|
||||
static {
|
||||
schemaSet = Collections.unmodifiableList(new ArrayList(MockUtil.getParserSupportedSchemas(MockParser.class)));
|
||||
formatSet = Collections.unmodifiableList(new ArrayList(MockUtil.getParserSupportedFormats(MockParser.class)));
|
||||
encodingSet = Collections.unmodifiableList(new ArrayList(MockUtil.getParserSupportedEncodings(MockParser.class)));
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public IData parse(InputStream input, String mimeType) {
|
||||
// throw new UnsupportedOperationException("Not supported yet.");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Class[] getSupportedInternalOutputDataType() {
|
||||
// return new Class[] { MockBinding.class };
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isSupportedSchema(String schema) {
|
||||
return schemaSet.contains(schema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedFormat(String format) {
|
||||
return formatSet.contains(format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedEncoding(String encoding) {
|
||||
return encodingSet.contains(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedSchemas() {
|
||||
return schemaSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedFormats() {
|
||||
return formatSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSupportedEncodings() {
|
||||
return encodingSet.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IData parse(InputStream input, String mimeType, String schema) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IData parseBase64(InputStream input, String mimeType, String schema) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedDataBinding(Class<?> clazz) {
|
||||
return Arrays.binarySearch(getSupportedDataBindings(), clazz) > -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Format[] getSupportedFullFormats() {
|
||||
Format f = Format.Factory.newInstance();
|
||||
f.setSchema(schemaSet.get(0));
|
||||
f.setEncoding(encodingSet.get(0));
|
||||
f.setMimetype(formatSet.get(0));
|
||||
return new Format[] {f};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getSupportedDataBindings() {
|
||||
return new Class[] { MockBinding.class };
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.test.mock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.n52.wps.PropertyDocument;
|
||||
import org.n52.wps.PropertyDocument.Property;
|
||||
import org.n52.wps.commons.WPSConfig;
|
||||
import org.n52.wps.io.GeneratorFactory;
|
||||
import org.n52.wps.io.IGenerator;
|
||||
import org.n52.wps.io.IParser;
|
||||
import org.n52.wps.io.ParserFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class MockUtil {
|
||||
|
||||
public final static String SUPPORTED_SCHEMA = "supportedSchema";
|
||||
public final static String SUPPORTED_FORMAT = "supportedFormat";
|
||||
public final static String SUPPORTED_ENCODING = "supportedEncoding";
|
||||
|
||||
|
||||
private static WPSConfig MOCK_CONFIG;
|
||||
public synchronized static WPSConfig getMockConfig() throws XmlException, IOException {
|
||||
if (MOCK_CONFIG == null) {
|
||||
InputStream configInputStream = null;
|
||||
try {
|
||||
configInputStream = MockUtil.class.getResourceAsStream(
|
||||
"/org/n52/test/mock/wps_config.xml");
|
||||
WPSConfig.forceInitialization(configInputStream);
|
||||
MOCK_CONFIG = WPSConfig.getInstance();
|
||||
ParserFactory.initialize(MOCK_CONFIG.getActiveRegisteredParser());
|
||||
GeneratorFactory.initialize(MOCK_CONFIG.getActiveRegisteredGenerator());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(configInputStream);
|
||||
}
|
||||
}
|
||||
return MOCK_CONFIG;
|
||||
}
|
||||
|
||||
public static Collection<String> getParserSupportedSchemas(Class<? extends IParser> clazz) {
|
||||
return getParserPropertyValues(clazz, SUPPORTED_SCHEMA);
|
||||
}
|
||||
|
||||
public static Collection<String> getParserSupportedFormats(Class<? extends IParser> clazz) {
|
||||
return getParserPropertyValues(clazz, SUPPORTED_FORMAT);
|
||||
}
|
||||
|
||||
public static Collection<String> getParserSupportedEncodings(Class<? extends IParser> clazz) {
|
||||
return getParserPropertyValues(clazz, SUPPORTED_ENCODING);
|
||||
}
|
||||
|
||||
public static Collection<String> getGeneratorSupportedSchemas(Class<? extends IGenerator> clazz) {
|
||||
return getGeneratorPropertyValues(clazz, SUPPORTED_SCHEMA);
|
||||
}
|
||||
|
||||
public static Collection<String> getGeneratorSupportedFormats(Class<? extends IGenerator> clazz) {
|
||||
return getGeneratorPropertyValues(clazz, SUPPORTED_FORMAT);
|
||||
}
|
||||
|
||||
public static Collection<String> getGeneratorSupportedEncodings(Class<? extends IGenerator> clazz) {
|
||||
return getGeneratorPropertyValues(clazz, SUPPORTED_ENCODING);
|
||||
}
|
||||
|
||||
public static Collection<String> getParserPropertyValues(Class<? extends IParser> clazz, String propertyName) {
|
||||
String clazzName = clazz.getName();
|
||||
ArrayList<String> propertyList = new ArrayList<String>();
|
||||
try {
|
||||
WPSConfig mockConfig = MockUtil.getMockConfig();
|
||||
PropertyDocument.Property properties[] =
|
||||
mockConfig.getPropertiesForParserClass(clazzName);
|
||||
for (Property property : properties) {
|
||||
if (propertyName.equals(property.getName())) {
|
||||
propertyList.add(property.getStringValue());
|
||||
}
|
||||
}
|
||||
propertyList.trimToSize();
|
||||
} catch (Exception e) {
|
||||
System.err.println("ERROR parsing property " + propertyName + " for Parser class " + clazzName);
|
||||
}
|
||||
return propertyList;
|
||||
}
|
||||
|
||||
public static Collection<String> getGeneratorPropertyValues(Class<? extends IGenerator> clazz, String propertyName) {
|
||||
String clazzName = clazz.getName();
|
||||
ArrayList<String> propertyList = new ArrayList<String>();
|
||||
try {
|
||||
WPSConfig mockConfig = MockUtil.getMockConfig();
|
||||
PropertyDocument.Property properties[] =
|
||||
mockConfig.getPropertiesForGeneratorClass(clazzName);
|
||||
for (Property property : properties) {
|
||||
if (propertyName.equals(property.getName())) {
|
||||
propertyList.add(property.getStringValue());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("ERROR parsing property " + propertyName + " for Generator class " + clazzName);
|
||||
}
|
||||
propertyList.trimToSize();
|
||||
return propertyList;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
public class AnnotatedAlgorithmIntrospectorTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
public AnnotatedAlgorithmIntrospector instance;
|
||||
|
||||
@Test
|
||||
public void testClassWithNoExecuteAnnotation() {
|
||||
thrown.expect(RuntimeException.class);
|
||||
thrown.expectMessage(CoreMatchers.containsString("No execute method binding"));
|
||||
instance = new AnnotatedAlgorithmIntrospector(ClassWithNoExecuteAnnotation.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,592 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.test.mock.MockEnum;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputFieldBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.InputMethodBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputFieldBinding;
|
||||
import org.n52.wps.algorithm.annotation.AnnotationBinding.OutputMethodBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class AnnotatedMemberDescriptorTest extends TestCase {
|
||||
|
||||
// START - TEST DATA AS CLASS FIELDS AND METHODS
|
||||
|
||||
// represent almost all cases: literal or complex data, input or output. with expections noted below
|
||||
public String stringField;
|
||||
public List<String> stringListField;
|
||||
public List<? extends String> stringExtendListField;
|
||||
public List<? super String> stringSuperListField;
|
||||
public List unboundListField; // effectively List<? extends Object>
|
||||
|
||||
// no polymorphism in test methods, will break use of methodMap
|
||||
public void setString(String stringParameter) {
|
||||
this.stringField = stringParameter;
|
||||
}
|
||||
public String getString() {
|
||||
return stringField;
|
||||
}
|
||||
public void setStringList(List<String> stringListParameter) {
|
||||
this.stringListField = stringListParameter;
|
||||
}
|
||||
public List<String> getStringList() {
|
||||
return this.stringListField;
|
||||
}
|
||||
public void setStringExtendList(List<? extends String> stringExtendListParameter) {
|
||||
this.stringExtendListField = stringExtendListParameter;
|
||||
}
|
||||
public List<? extends String> getStringExtendList() {
|
||||
return this.stringExtendListField;
|
||||
}
|
||||
public void setStringSuperList(List<? super String> stringSuperListParameter) {
|
||||
this.stringSuperListField = stringSuperListParameter;
|
||||
}
|
||||
public List<? super String> getStringSuperList() {
|
||||
return this.stringSuperListField;
|
||||
}
|
||||
public void setUnboundList(List unboundListParameter) {
|
||||
this.unboundListField = unboundListParameter;
|
||||
}
|
||||
public List getUnboundList() {
|
||||
return this.unboundListField;
|
||||
}
|
||||
|
||||
// special case: enumerations for *inputs* have data type of String *unless* List for outputs
|
||||
public MockEnum enumField;
|
||||
public List<MockEnum> enumListField;
|
||||
/* NOT CURRENTLY SUPPORTED, need to be able to infer concrete type by reflection
|
||||
public List<? extends MockEnum> enumExtendsListField;
|
||||
public List<? super MockEnum> enumSuperListField;
|
||||
*/
|
||||
|
||||
// no polymorphism in test methods, will break use of methodMap
|
||||
public MockEnum getEnum() {
|
||||
return enumField;
|
||||
}
|
||||
public void setEnum(MockEnum enumParameter) {
|
||||
this.enumField = enumParameter;
|
||||
}
|
||||
public List<MockEnum> getEnumList() {
|
||||
return enumListField;
|
||||
}
|
||||
public void setEnumList(List<MockEnum> enumListParameter) {
|
||||
this.enumListField = enumListParameter;
|
||||
}
|
||||
/* NOT CURRENTLY SUPPORTED, need to be able to infer concrete type by reflection
|
||||
public List<? extends MockEnum> getEnumExtendList() {
|
||||
return enumExtendsListField;
|
||||
}
|
||||
public void setEnumExtendList(List<? extends MockEnum> enumExtendsListParameter) {
|
||||
this.enumExtendsListField = enumExtendsListParameter;
|
||||
}
|
||||
public List<? super MockEnum> getEnumSuperList() {
|
||||
return enumSuperListField;
|
||||
}
|
||||
public void setEnumSuperList(List<? super MockEnum> enumSuperListParameter) {
|
||||
this.enumSuperListField = enumSuperListParameter;
|
||||
}
|
||||
*/
|
||||
|
||||
// END - TEST DATA AS CLASS FIELDS AND METHODS
|
||||
|
||||
Map<String, Method> methodMap;
|
||||
|
||||
public AnnotatedMemberDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
methodMap = new HashMap<String, Method>();
|
||||
for (Method method : AnnotationMemberDescriptorSample.class.getDeclaredMethods()) {
|
||||
methodMap.put(method.getName(), method);
|
||||
}
|
||||
methodMap = Collections.unmodifiableMap(methodMap);
|
||||
}
|
||||
|
||||
private Method getSampleMethod(String name) throws NoSuchMethodException {
|
||||
Method method = methodMap.get(name);
|
||||
if (method == null) {
|
||||
throw new NoSuchMethodException(name);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
private Field getSampleField(String name) throws NoSuchFieldException {
|
||||
return AnnotationMemberDescriptorSample.class.getDeclaredField(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testStringFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringSetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("setString");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringGetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("getString");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
private void validateInputMember(InputBinding memberDescriptor) {
|
||||
// data type matches member for inputs type *unless* member type is List
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// payload type matches data type, special handling reserved for enumerations
|
||||
assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateOutputMember(OutputBinding memberDescriptor) {
|
||||
// data type matches member type for outputs
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// data type matches payload type, special handling reserved for enumerations
|
||||
assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
public void testStringListFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringListField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateInputListMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringListFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringListField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateOutputListMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringListSetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("setStringList");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateInputListMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringListGetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("getStringList");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateOutputListMember(memberDescriptor);
|
||||
}
|
||||
|
||||
private void validateInputListMember(InputBinding memberDescriptor) {
|
||||
// we extract the parameterized type of the list for inputs. since member
|
||||
// type is List<String> we expect String
|
||||
assertEquals(String.class, memberDescriptor.getType());
|
||||
// payload type matches data type, special handling reserved for enumerations
|
||||
assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(true, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateOutputListMember(OutputBinding memberDescriptor) {
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
public void testStringExtendListFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringExtendListField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateExtendListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringExtendListFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringExtendListField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateExtendListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringExtendListSetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("setStringExtendList");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateExtendListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringExtendListGetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("getStringExtendList");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateExtendListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
private void validateExtendListInputMember(InputBinding memberDescriptor) {
|
||||
// we extract the parameterized type of the list for inputs. since member
|
||||
// type is List<? extends String> we expect a WildcardType of <? extends String>
|
||||
// we need this information later to make sure we can safely assign an
|
||||
// instance to the list with type safety (fail early behavior)
|
||||
Type type = memberDescriptor.getType();
|
||||
assertTrue(type instanceof WildcardType);
|
||||
WildcardType typeWildcard = (WildcardType)type;
|
||||
assertEquals(0, typeWildcard.getLowerBounds().length);
|
||||
assertEquals(1, typeWildcard.getUpperBounds().length);
|
||||
assertEquals(String.class, typeWildcard.getUpperBounds()[0]);
|
||||
// we extract the parameterized type of the list for inputs
|
||||
assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(true, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateExtendListOutputMember(OutputBinding memberDescriptor) {
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
public void testStringSuperListFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringSuperListField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateSuperListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringSuperListFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("stringSuperListField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateSuperListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringSuperListSetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("setStringSuperList");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateSuperListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testStringSuperListGetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("getStringSuperList");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateSuperListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
private void validateSuperListInputMember(InputBinding memberDescriptor) {
|
||||
// we extract the parameterized type of the list for inputs. since member
|
||||
// type is List<? super String> we expect a WildcardType of <? super String>
|
||||
// we need this information later to make sure we can safely assign an
|
||||
// instance to the list with type safety (fail early behavior)
|
||||
Type type = memberDescriptor.getType();
|
||||
assertTrue(type instanceof WildcardType);
|
||||
WildcardType typeWildcard = (WildcardType)type;
|
||||
assertEquals(1, typeWildcard.getLowerBounds().length);
|
||||
assertEquals(String.class, typeWildcard.getLowerBounds()[0]);
|
||||
assertEquals(1, typeWildcard.getUpperBounds().length);
|
||||
assertEquals(Object.class, typeWildcard.getUpperBounds()[0]);
|
||||
// we extract the parameterized type of the list for inputs
|
||||
assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(true, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateSuperListOutputMember(OutputBinding memberDescriptor) {
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
public void testUnboundListFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("unboundListField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateUnboundListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testUnboundListFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("unboundListField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateUnboundListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testUnboundListSetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("setUnboundList");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateUnboundListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testUnboundListGetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("getUnboundList");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateUnboundListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
private void validateUnboundListInputMember(InputBinding memberDescriptor) {
|
||||
// // we extract the parameterized type of the list for inputs. since member
|
||||
// // type is List<? super String> we expect a WildcardType of <? super String>
|
||||
// // we need this information later to make sure we can safely assign an
|
||||
// // instance to the list with type safety (fail early behavior)
|
||||
// Type type = memberDescriptor.getType();
|
||||
// assertTrue(type instanceof WildcardType);
|
||||
// WildcardType typeWildcard = (WildcardType)type;
|
||||
// assertEquals(0, typeWildcard.getLowerBounds().length);
|
||||
// assertEquals(1, typeWildcard.getUpperBounds().length);
|
||||
// assertEquals(Object.class, typeWildcard.getUpperBounds()[0]);
|
||||
// // we extract the parameterized type of the list for inputs
|
||||
// assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
// assertEquals(true, memberDescriptor.isMemberTypeList());
|
||||
// assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
// we extract the parameterized type of the list for inputs. since member
|
||||
// type is List<? extends Object> we expect a WildcardType of <? extends Object>
|
||||
// we need this information later to make sure we can safely assign an
|
||||
// instance to the list with type safety (fail early behavior)
|
||||
Type type = memberDescriptor.getType();
|
||||
assertTrue(type instanceof WildcardType);
|
||||
WildcardType typeWildcard = (WildcardType)type;
|
||||
assertEquals(0, typeWildcard.getLowerBounds().length);
|
||||
assertEquals(1, typeWildcard.getUpperBounds().length);
|
||||
assertEquals(Object.class, typeWildcard.getUpperBounds()[0]);
|
||||
// we extract the parameterized type of the list for inputs
|
||||
assertEquals(memberDescriptor.getType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(true, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateUnboundListOutputMember(OutputBinding memberDescriptor) {
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
public void testEnumFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("enumField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testEnumFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("enumField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testEnumSetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("setEnum");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testEnumGetter() throws NoSuchMethodException {
|
||||
Method method = getSampleMethod("getEnum");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
private void validateEnumInputMember(InputBinding memberDescriptor) {
|
||||
assertEquals(MockEnum.class, memberDescriptor.getType());
|
||||
// for all instances of Class<? extends Enum> the payload type is Class<String>
|
||||
// as these will be bound with LiteralStringBinding
|
||||
assertEquals(String.class, memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(true, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateEnumOutputMember(OutputBinding memberDescriptor) {
|
||||
assertEquals(MockEnum.class, memberDescriptor.getType());
|
||||
// for all instances of Class<? extends Enum> the payload type is Class<String>
|
||||
// as these will be bound with LiteralStringBinding
|
||||
assertEquals(String.class, memberDescriptor.getPayloadType());
|
||||
assertEquals(true, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
public void testEnumListFieldAsInput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("enumListField");
|
||||
InputFieldBinding memberDescriptor = new InputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testEnumListFieldAsOutput() throws NoSuchFieldException {
|
||||
Field field = getSampleField("enumListField");
|
||||
OutputFieldBinding memberDescriptor = new OutputFieldBinding(field);
|
||||
|
||||
assertEquals(field, memberDescriptor.getMember());
|
||||
assertEquals(field.getGenericType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testEnumListSetter() throws NoSuchFieldException, NoSuchMethodException {
|
||||
Method method = getSampleMethod("setEnumList");
|
||||
InputMethodBinding memberDescriptor = new InputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericParameterTypes()[0], memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumListInputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
public void testEnumListGetter() throws NoSuchFieldException, NoSuchMethodException {
|
||||
Method method = getSampleMethod("getEnumList");
|
||||
OutputMethodBinding memberDescriptor = new OutputMethodBinding(method);
|
||||
|
||||
assertEquals(method, memberDescriptor.getMember());
|
||||
assertEquals(method.getGenericReturnType(), memberDescriptor.getMemberType());
|
||||
|
||||
validateEnumListOutputMember(memberDescriptor);
|
||||
}
|
||||
|
||||
|
||||
private void validateEnumListInputMember(InputBinding memberDescriptor) {
|
||||
assertEquals(MockEnum.class, memberDescriptor.getType());
|
||||
assertEquals(String.class, memberDescriptor.getPayloadType());
|
||||
assertEquals(true, memberDescriptor.isMemberTypeList());
|
||||
assertEquals(true, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
private void validateEnumListOutputMember(OutputBinding memberDescriptor) {
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getType());
|
||||
// no special handling for outputs of member type List, member type matches data type
|
||||
assertEquals(memberDescriptor.getMemberType(), memberDescriptor.getPayloadType());
|
||||
assertEquals(false, memberDescriptor.isTypeEnum());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
import java.util.List;
|
||||
import org.n52.test.mock.MockEnum;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class AnnotationMemberDescriptorSample {
|
||||
|
||||
// TEST IMPLEMENTATION NOTE: no polymorphism in sample methods, the reflection utilities
|
||||
// used for generic method lookup used in the unit tests (polymorphism is ok in
|
||||
// actual implementations as the annotations are what drive method lookups)
|
||||
|
||||
// Represents almost all cases for fields: literal or complex data, input or output. with expections noted below.
|
||||
// We are using String instances, but any literal or complex payload type could be swapped out.
|
||||
public String stringField;
|
||||
public List<String> stringListField;
|
||||
public List<? extends String> stringExtendListField;
|
||||
public List<? super String> stringSuperListField;
|
||||
public List unboundListField; // effectively List<? extends Object>
|
||||
|
||||
public void setString(String stringParameter) {
|
||||
this.stringField = stringParameter;
|
||||
}
|
||||
public String getString() {
|
||||
return stringField;
|
||||
}
|
||||
public void setStringList(List<String> stringListParameter) {
|
||||
this.stringListField = stringListParameter;
|
||||
}
|
||||
public List<String> getStringList() {
|
||||
return this.stringListField;
|
||||
}
|
||||
public void setStringExtendList(List<? extends String> stringExtendListParameter) {
|
||||
this.stringExtendListField = stringExtendListParameter;
|
||||
}
|
||||
public List<? extends String> getStringExtendList() {
|
||||
return this.stringExtendListField;
|
||||
}
|
||||
public void setStringSuperList(List<? super String> stringSuperListParameter) {
|
||||
this.stringSuperListField = stringSuperListParameter;
|
||||
}
|
||||
public List<? super String> getStringSuperList() {
|
||||
return this.stringSuperListField;
|
||||
}
|
||||
public void setUnboundList(List unboundListParameter) {
|
||||
this.unboundListField = unboundListParameter;
|
||||
}
|
||||
public List getUnboundList() {
|
||||
return this.unboundListField;
|
||||
}
|
||||
|
||||
// Special case: enumerations for *inputs* have payload type of String so that
|
||||
// Enumerations can be bound with LiteralStringBinding instances. Exception
|
||||
// is List of enums for outputs.
|
||||
public MockEnum enumField;
|
||||
public List<MockEnum> enumListField;
|
||||
/* NOT CURRENTLY SUPPORTED, need to be able to infer concrete type by reflection
|
||||
public List<? extends MockEnum> enumExtendsListField;
|
||||
public List<? super MockEnum> enumSuperListField;
|
||||
*/
|
||||
public MockEnum getEnum() {
|
||||
return enumField;
|
||||
}
|
||||
public void setEnum(MockEnum enumParameter) {
|
||||
this.enumField = enumParameter;
|
||||
}
|
||||
public List<MockEnum> getEnumList() {
|
||||
return enumListField;
|
||||
}
|
||||
public void setEnumList(List<MockEnum> enumListParameter) {
|
||||
this.enumListField = enumListParameter;
|
||||
}
|
||||
/* NOT CURRENTLY SUPPORTED, need to be able to infer concrete type by reflection
|
||||
public List<? extends MockEnum> getEnumExtendList() {
|
||||
return enumExtendsListField;
|
||||
}
|
||||
public void setEnumExtendList(List<? extends MockEnum> enumExtendsListParameter) {
|
||||
this.enumExtendsListField = enumExtendsListParameter;
|
||||
}
|
||||
public List<? super MockEnum> getEnumSuperList() {
|
||||
return enumSuperListField;
|
||||
}
|
||||
public void setEnumSuperList(List<? super MockEnum> enumSuperListParameter) {
|
||||
this.enumSuperListField = enumSuperListParameter;
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.annotation;
|
||||
|
||||
@Algorithm(version = "1.0.0")
|
||||
public class ClassWithNoExecuteAnnotation {
|
||||
|
||||
private String output;
|
||||
|
||||
// We forgot to mark this method as @Execute
|
||||
public void execute() {
|
||||
|
||||
}
|
||||
|
||||
@LiteralDataOutput(identifier = "output")
|
||||
public String getOutput() {
|
||||
return output;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.test.mock.MockBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class AlgorithmDescriptorTest extends TestCase {
|
||||
|
||||
private LiteralDataOutputDescriptor.Builder MOCK_OUPUT1_BUILDER;
|
||||
|
||||
private List<InputDescriptor.Builder<?,?>> MOCK_INPUT_BUILDERS;
|
||||
private List<OutputDescriptor.Builder<?,?>> MOCK_OUTPUT_BUILDERS;
|
||||
|
||||
public AlgorithmDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
MOCK_INPUT_BUILDERS = new ArrayList<InputDescriptor.Builder<?,?>>();
|
||||
MOCK_INPUT_BUILDERS.add(LiteralDataInputDescriptor.booleanBuilder("mock_input1"));
|
||||
MOCK_INPUT_BUILDERS.add(LiteralDataInputDescriptor.booleanBuilder("mock_input2"));
|
||||
MOCK_INPUT_BUILDERS.add(ComplexDataInputDescriptor.builder("mock_input3", MockBinding.class));
|
||||
MOCK_INPUT_BUILDERS.add(ComplexDataInputDescriptor.builder("mock_input4", MockBinding.class));
|
||||
MOCK_INPUT_BUILDERS = Collections.unmodifiableList(MOCK_INPUT_BUILDERS);
|
||||
|
||||
MOCK_OUPUT1_BUILDER = LiteralDataOutputDescriptor.booleanBuilder("mock_output1");
|
||||
|
||||
MOCK_OUTPUT_BUILDERS = new ArrayList<OutputDescriptor.Builder<?,?>>();
|
||||
// MOCK_OUTPUT_BUILDERS.add(LiteralDataOutputDescriptor.booleanBuilder("mock_output1"));
|
||||
MOCK_OUTPUT_BUILDERS.add(LiteralDataOutputDescriptor.booleanBuilder("mock_output2"));
|
||||
MOCK_OUTPUT_BUILDERS.add(ComplexDataOutputDescriptor.builder("mock_output3", MockBinding.class));
|
||||
MOCK_OUTPUT_BUILDERS.add(ComplexDataOutputDescriptor.builder("mock_output4", MockBinding.class));
|
||||
MOCK_OUTPUT_BUILDERS = Collections.unmodifiableList(MOCK_OUTPUT_BUILDERS);
|
||||
|
||||
}
|
||||
|
||||
public void testStaticBuilder_String() {
|
||||
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// Test fail-early, exception should be thrown if identifier is 'null';
|
||||
boolean thrown = false;
|
||||
try {
|
||||
AlgorithmDescriptor.builder((String)null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// test that static builder with String parameter
|
||||
descriptor = AlgorithmDescriptor.builder("mock_identifier").
|
||||
addOutputDescriptor(MOCK_OUPUT1_BUILDER). // require one output
|
||||
build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertTrue(descriptor.hasTitle());
|
||||
assertEquals("mock_identifier", descriptor.getTitle());
|
||||
|
||||
}
|
||||
|
||||
public void testStaticBuilder_Class() {
|
||||
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// Test fail-early, exception should be thrown if idnetifier is 'null';
|
||||
boolean thrown = false;
|
||||
try {
|
||||
AlgorithmDescriptor.builder((Class)null);
|
||||
fail("Expected NullPointerException");
|
||||
} catch (NullPointerException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// test that static builder with a valid class parameter
|
||||
descriptor = AlgorithmDescriptor.builder(getClass()).
|
||||
addOutputDescriptor(MOCK_OUPUT1_BUILDER). // require one output
|
||||
build();
|
||||
assertEquals(getClass().getCanonicalName(), descriptor.getIdentifier());
|
||||
assertTrue(descriptor.hasTitle());
|
||||
assertEquals(getClass().getCanonicalName(), descriptor.getTitle());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testVersion() {
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// test default is "1.0.0"
|
||||
descriptor = createMinimumCompliantBuilder().build();
|
||||
assertEquals("1.0.0", descriptor.getVersion());
|
||||
|
||||
// test we can change
|
||||
descriptor = createMinimumCompliantBuilder().version("X.Y.Z").build();
|
||||
assertEquals("X.Y.Z", descriptor.getVersion());
|
||||
}
|
||||
|
||||
public void testStoreSupported() {
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// test default is true
|
||||
descriptor = createMinimumCompliantBuilder().build();
|
||||
assertTrue(descriptor.getStoreSupported());
|
||||
|
||||
// test we can set to true (explicitly)
|
||||
descriptor = createMinimumCompliantBuilder().storeSupported(true).build();
|
||||
assertTrue(descriptor.getStoreSupported());
|
||||
|
||||
// test we can set to false
|
||||
descriptor = createMinimumCompliantBuilder().storeSupported(false).build();
|
||||
assertFalse(descriptor.getStoreSupported());
|
||||
}
|
||||
|
||||
public void testStatusSupported() {
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// test default is true
|
||||
descriptor = createMinimumCompliantBuilder().build();
|
||||
assertTrue(descriptor.getStatusSupported());
|
||||
|
||||
// test we can set to true (explicitly)
|
||||
descriptor = createMinimumCompliantBuilder().statusSupported(true).build();
|
||||
assertTrue(descriptor.getStatusSupported());
|
||||
|
||||
// test we can set to false
|
||||
descriptor = createMinimumCompliantBuilder().statusSupported(false).build();
|
||||
assertFalse(descriptor.getStatusSupported());
|
||||
}
|
||||
|
||||
public void testInputDescriptorHandling() {
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// test default is true
|
||||
descriptor = createMinimumCompliantBuilder().build();
|
||||
assertNotNull(descriptor.getInputDescriptors());
|
||||
assertEquals(0, descriptor.getInputDescriptors().size());
|
||||
assertNotNull(descriptor.getInputIdentifiers());
|
||||
assertEquals(0, descriptor.getInputIdentifiers().size());
|
||||
|
||||
|
||||
// test addInputDescriptor(InputDescriptor.Builder<?,?>) interface.
|
||||
AlgorithmDescriptor.Builder<?> builder = createMinimumCompliantBuilder();
|
||||
for (InputDescriptor.Builder inputBuilder : MOCK_INPUT_BUILDERS) {
|
||||
builder.addInputDescriptor(inputBuilder);
|
||||
}
|
||||
validateInputDescriptors(builder.build());
|
||||
|
||||
// test addInputDescriptor(InputDescriptor<?>) interface.
|
||||
builder = createMinimumCompliantBuilder();
|
||||
for (InputDescriptor.Builder inputBuilder : MOCK_INPUT_BUILDERS) {
|
||||
builder.addInputDescriptor(inputBuilder.build());
|
||||
}
|
||||
validateInputDescriptors(builder.build());
|
||||
|
||||
// test addInputDescriptor(InputDescriptor<?>) interface.
|
||||
builder = createMinimumCompliantBuilder();
|
||||
List<InputDescriptor> inputDescriptorList = new ArrayList<InputDescriptor>(MOCK_INPUT_BUILDERS.size());
|
||||
for (InputDescriptor.Builder inputBuilder : MOCK_INPUT_BUILDERS) {
|
||||
inputDescriptorList.add(inputBuilder.build());
|
||||
}
|
||||
builder.addInputDescriptors(inputDescriptorList);
|
||||
validateInputDescriptors(builder.build());
|
||||
}
|
||||
|
||||
public void testOutputDescriptorHanding() {
|
||||
AlgorithmDescriptor descriptor = null;
|
||||
|
||||
// Test fail-early, exception should be thrown if idnetifier is 'null';
|
||||
boolean thrown = false;
|
||||
try {
|
||||
AlgorithmDescriptor.builder("mock_identifier").build();
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalStateException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// test assumption that createMinimumCompliantBuilder() returns us 1 output
|
||||
descriptor = createMinimumCompliantBuilder().build();
|
||||
assertNotNull(descriptor.getOutputDescriptors());
|
||||
assertEquals(1, descriptor.getOutputDescriptors().size());
|
||||
assertNotNull(descriptor.getOutputIdentifiers());
|
||||
assertEquals(1, descriptor.getOutputIdentifiers().size());
|
||||
|
||||
// test addOutputDescriptor(OutputDescriptor.Builder<?,?>) interface.
|
||||
AlgorithmDescriptor.Builder<?> builder = createMinimumCompliantBuilder();
|
||||
for (OutputDescriptor.Builder outputBuilder : MOCK_OUTPUT_BUILDERS) {
|
||||
builder.addOutputDescriptor(outputBuilder);
|
||||
}
|
||||
validateOutputDescriptors(builder.build());
|
||||
|
||||
// test addOutputDescriptor(OutputDescriptor<?>) interface.
|
||||
builder = createMinimumCompliantBuilder();
|
||||
for (OutputDescriptor.Builder outputBuilder : MOCK_OUTPUT_BUILDERS) {
|
||||
builder.addOutputDescriptor(outputBuilder.build());
|
||||
}
|
||||
validateOutputDescriptors(builder.build());
|
||||
|
||||
// test addOutputDescriptor(OutputDescriptor<?>) interface.
|
||||
builder = createMinimumCompliantBuilder();
|
||||
List<OutputDescriptor> outputDescriptorList = new ArrayList<OutputDescriptor>(MOCK_OUTPUT_BUILDERS.size());
|
||||
for (OutputDescriptor.Builder outputBuilder : MOCK_OUTPUT_BUILDERS) {
|
||||
outputDescriptorList.add(outputBuilder.build());
|
||||
}
|
||||
builder.addOutputDescriptors(outputDescriptorList);
|
||||
validateOutputDescriptors(builder.build());
|
||||
}
|
||||
|
||||
private AlgorithmDescriptor.Builder<?> createMinimumCompliantBuilder() {
|
||||
return AlgorithmDescriptor.builder("mock_identifier").
|
||||
addOutputDescriptor(MOCK_OUPUT1_BUILDER);
|
||||
}
|
||||
|
||||
private void validateInputDescriptors(AlgorithmDescriptor algorithmDescriptor) {
|
||||
assertNotNull(algorithmDescriptor.getInputDescriptors());
|
||||
|
||||
// Test Collection<InputDescriptor> getInputDescriptors()
|
||||
Collection<InputDescriptor> collection = algorithmDescriptor.getInputDescriptors();
|
||||
// correct size?
|
||||
assertEquals(4, collection.size());
|
||||
// input order preserved?
|
||||
Iterator<InputDescriptor> iterator = collection.iterator();
|
||||
InputDescriptor inputDescriptor = iterator.next();
|
||||
assertNotNull(inputDescriptor);
|
||||
assertEquals("mock_input1", inputDescriptor.getIdentifier());
|
||||
inputDescriptor = iterator.next();
|
||||
assertNotNull(inputDescriptor);
|
||||
assertEquals("mock_input2", inputDescriptor.getIdentifier());
|
||||
inputDescriptor = iterator.next();
|
||||
assertNotNull(inputDescriptor);
|
||||
assertEquals("mock_input3", inputDescriptor.getIdentifier());
|
||||
inputDescriptor = iterator.next();
|
||||
assertNotNull(inputDescriptor);
|
||||
assertEquals("mock_input4", inputDescriptor.getIdentifier());
|
||||
assertFalse(iterator.hasNext());
|
||||
|
||||
// Test InputDescriptor getInputDescriptor(String)
|
||||
// Can we access by indentifier?
|
||||
assertNotNull(algorithmDescriptor.getInputDescriptor("mock_input1"));
|
||||
assertNotNull(algorithmDescriptor.getInputDescriptor("mock_input2"));
|
||||
assertNotNull(algorithmDescriptor.getInputDescriptor("mock_input3"));
|
||||
assertNotNull(algorithmDescriptor.getInputDescriptor("mock_input4"));
|
||||
// Are we getting the correct decriptors returned by identifier?
|
||||
assertEquals(algorithmDescriptor.getInputDescriptor("mock_input1").getIdentifier(), "mock_input1");
|
||||
assertEquals(algorithmDescriptor.getInputDescriptor("mock_input2").getIdentifier(), "mock_input2");
|
||||
assertEquals(algorithmDescriptor.getInputDescriptor("mock_input3").getIdentifier(), "mock_input3");
|
||||
assertEquals(algorithmDescriptor.getInputDescriptor("mock_input4").getIdentifier(), "mock_input4");
|
||||
|
||||
// Test List<String> getInputIdentifiers();
|
||||
List<String> inputIdentifierList = algorithmDescriptor.getInputIdentifiers();
|
||||
// Size ok?
|
||||
assertEquals(4, inputIdentifierList.size());
|
||||
// Order preserved?
|
||||
assertEquals("mock_input1", inputIdentifierList.get(0));
|
||||
assertEquals("mock_input2", inputIdentifierList.get(1));
|
||||
assertEquals("mock_input3", inputIdentifierList.get(2));
|
||||
assertEquals("mock_input4", inputIdentifierList.get(3));
|
||||
}
|
||||
|
||||
private void validateOutputDescriptors(AlgorithmDescriptor algorithmDescriptor) {
|
||||
assertNotNull(algorithmDescriptor.getOutputDescriptors());
|
||||
|
||||
// Test Collection<OutputDescriptor> getOutputDescriptors()
|
||||
Collection<OutputDescriptor> collection = algorithmDescriptor.getOutputDescriptors();
|
||||
// correct size?
|
||||
assertEquals(4, collection.size());
|
||||
// output order preserved?
|
||||
Iterator<OutputDescriptor> iterator = collection.iterator();
|
||||
OutputDescriptor outputDescriptor = iterator.next();
|
||||
assertNotNull(outputDescriptor);
|
||||
assertEquals("mock_output1", outputDescriptor.getIdentifier());
|
||||
outputDescriptor = iterator.next();
|
||||
assertNotNull(outputDescriptor);
|
||||
assertEquals("mock_output2", outputDescriptor.getIdentifier());
|
||||
outputDescriptor = iterator.next();
|
||||
assertNotNull(outputDescriptor);
|
||||
assertEquals("mock_output3", outputDescriptor.getIdentifier());
|
||||
outputDescriptor = iterator.next();
|
||||
assertNotNull(outputDescriptor);
|
||||
assertEquals("mock_output4", outputDescriptor.getIdentifier());
|
||||
assertFalse(iterator.hasNext());
|
||||
|
||||
// Test OutputDescriptor getOutputDescriptor(String)
|
||||
// Can we access by indentifier?
|
||||
assertNotNull(algorithmDescriptor.getOutputDescriptor("mock_output1"));
|
||||
assertNotNull(algorithmDescriptor.getOutputDescriptor("mock_output2"));
|
||||
assertNotNull(algorithmDescriptor.getOutputDescriptor("mock_output3"));
|
||||
assertNotNull(algorithmDescriptor.getOutputDescriptor("mock_output4"));
|
||||
// Are we getting the correct decriptors returned by identifier?
|
||||
assertEquals(algorithmDescriptor.getOutputDescriptor("mock_output1").getIdentifier(), "mock_output1");
|
||||
assertEquals(algorithmDescriptor.getOutputDescriptor("mock_output2").getIdentifier(), "mock_output2");
|
||||
assertEquals(algorithmDescriptor.getOutputDescriptor("mock_output3").getIdentifier(), "mock_output3");
|
||||
assertEquals(algorithmDescriptor.getOutputDescriptor("mock_output4").getIdentifier(), "mock_output4");
|
||||
|
||||
// Test List<String> getOutputIdentifiers();
|
||||
List<String> outputIdentifierList = algorithmDescriptor.getOutputIdentifiers();
|
||||
// Size ok?
|
||||
assertEquals(4, outputIdentifierList.size());
|
||||
// Order preserved?
|
||||
assertEquals("mock_output1", outputIdentifierList.get(0));
|
||||
assertEquals("mock_output2", outputIdentifierList.get(1));
|
||||
assertEquals("mock_output3", outputIdentifierList.get(2));
|
||||
assertEquals("mock_output4", outputIdentifierList.get(3));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class BoundDataDescriptorTest extends TestCase {
|
||||
|
||||
public BoundDataDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testBinding() {
|
||||
|
||||
BoundDescriptor descriptor = null;
|
||||
|
||||
// Test fail-early, exception should be thrown if binding is 'null';
|
||||
boolean thrown = false;
|
||||
try {
|
||||
descriptor = (new BoundDescriptorImpl.Builder(null)).build();
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// make sure the class type we build with is the same as the one returned
|
||||
// by the constucted object
|
||||
descriptor = (new BoundDescriptorImpl.Builder(Double.class)).build();
|
||||
assertEquals(Double.class, descriptor.getBinding());
|
||||
|
||||
descriptor = (new BoundDescriptorImpl.Builder(MockNumber.class)).build();
|
||||
assertEquals(MockNumber.class, descriptor.getBinding());
|
||||
}
|
||||
|
||||
public static class BoundDescriptorImpl extends BoundDescriptor<Class<? extends Number>> {
|
||||
private BoundDescriptorImpl(Builder builder) { super(builder); }
|
||||
public static class Builder extends BoundDescriptor.Builder<Builder, Class<? extends Number>> {
|
||||
Builder(Class<? extends Number> binding) {
|
||||
super("mock_identifier", binding);
|
||||
}
|
||||
@Override protected Builder self() { return this; }
|
||||
public BoundDescriptorImpl build() { return new BoundDescriptorImpl(this); }
|
||||
}
|
||||
}
|
||||
|
||||
public static class MockNumber extends Number {
|
||||
@Override public int intValue() { return Integer.MAX_VALUE; }
|
||||
@Override public long longValue() { return Long.MAX_VALUE; }
|
||||
@Override public float floatValue() { return Float.MAX_VALUE; }
|
||||
@Override public double doubleValue() { return Double.MAX_VALUE; };
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.test.mock.MockBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class ComplexDataInputDescriptorTest extends TestCase {
|
||||
|
||||
public ComplexDataInputDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testMaximumMegabytes() {
|
||||
ComplexDataInputDescriptor descriptor = null;
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).build();
|
||||
assertNull(descriptor.getMaximumMegaBytes());
|
||||
assertFalse(descriptor.hasMaximumMegaBytes());
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(0).build();
|
||||
assertNotNull(descriptor.getMaximumMegaBytes());
|
||||
assertEquals(BigInteger.valueOf(0), descriptor.getMaximumMegaBytes());
|
||||
assertFalse(descriptor.hasMaximumMegaBytes());
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(BigInteger.valueOf(0)).build();
|
||||
assertNotNull(descriptor.getMaximumMegaBytes());
|
||||
assertEquals(BigInteger.valueOf(0), descriptor.getMaximumMegaBytes());
|
||||
assertFalse(descriptor.hasMaximumMegaBytes());
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(1).build();
|
||||
assertNotNull(descriptor.getMaximumMegaBytes());
|
||||
assertEquals(BigInteger.valueOf(1), descriptor.getMaximumMegaBytes());
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(BigInteger.valueOf(1)).build();
|
||||
assertNotNull(descriptor.getMaximumMegaBytes());
|
||||
assertEquals(BigInteger.valueOf(1), descriptor.getMaximumMegaBytes());
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(Integer.MAX_VALUE).build();
|
||||
assertNotNull(descriptor.getMaximumMegaBytes());
|
||||
assertEquals(BigInteger.valueOf(Integer.MAX_VALUE), descriptor.getMaximumMegaBytes());
|
||||
|
||||
descriptor = ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(BigInteger.valueOf(Integer.MAX_VALUE)).build();
|
||||
assertNotNull(descriptor.getMaximumMegaBytes());
|
||||
assertEquals(BigInteger.valueOf(Integer.MAX_VALUE), descriptor.getMaximumMegaBytes());
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(-1);
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(BigInteger.valueOf(-1));
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(Integer.MIN_VALUE);
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).
|
||||
maximumMegaBytes(BigInteger.valueOf(Integer.MIN_VALUE));
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
}
|
||||
|
||||
public void testStaticBuilder() {
|
||||
ComplexDataInputDescriptor descriptor =
|
||||
ComplexDataInputDescriptor.builder("mock_identifier", MockBinding.class).build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(MockBinding.class, descriptor.getBinding());
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder(null, MockBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder("", MockBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataInputDescriptor.builder("mock_identifier", null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.test.mock.MockBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class ComplexDataOutputDescriptorTest extends TestCase {
|
||||
|
||||
public ComplexDataOutputDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testBuilder() {
|
||||
ComplexDataOutputDescriptor descriptor =
|
||||
ComplexDataOutputDescriptor.builder("mock_identifier", MockBinding.class).build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(MockBinding.class, descriptor.getBinding());
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
ComplexDataOutputDescriptor.builder(null, MockBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataOutputDescriptor.builder("", MockBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
ComplexDataOutputDescriptor.builder("mock_identifier", null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class DescriptorTest extends TestCase {
|
||||
|
||||
public DescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testIdentifier() {
|
||||
|
||||
DescriptorImpl descriptor = null;
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
new DescriptorImpl.Builder(null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
new DescriptorImpl.Builder("");
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// set case: set to 'an_identifier'
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
|
||||
}
|
||||
|
||||
public void testTitle() {
|
||||
|
||||
DescriptorImpl descriptor = null;
|
||||
|
||||
// default case: title is not initialized and therefore is null;
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).build();
|
||||
assertNull(descriptor.getTitle());
|
||||
assertFalse(descriptor.hasTitle());
|
||||
|
||||
// unset annotation case: 'title' default/unset value for annotations
|
||||
// is empty string as 'null' is not a valid annotation value;
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).title("").build();
|
||||
assertEquals("", descriptor.getTitle());
|
||||
assertFalse(descriptor.hasTitle());
|
||||
|
||||
// set case: set to 'an_title'
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).title("mock_title").build();
|
||||
assertEquals("mock_title", descriptor.getTitle());
|
||||
assertTrue(descriptor.hasTitle());
|
||||
}
|
||||
|
||||
public void testAbstract() {
|
||||
|
||||
DescriptorImpl descriptor = null;
|
||||
|
||||
// default case: abstrakt is not initialized and therefore is null;
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).build();
|
||||
assertNull(descriptor.getAbstract());
|
||||
assertFalse(descriptor.hasAbstract());
|
||||
|
||||
// unset annotation case: 'abstrakt' default/unset value for annotations
|
||||
// is empty string as 'null' is not a valid annotation value;
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).abstrakt("").build();
|
||||
assertEquals("", descriptor.getAbstract());
|
||||
assertFalse(descriptor.hasAbstract());
|
||||
|
||||
// set case: set to 'an_abstrakt'
|
||||
descriptor = (new DescriptorImpl.Builder("mock_identifier")).abstrakt("an_abstract").build();
|
||||
assertEquals("an_abstract", descriptor.getAbstract());
|
||||
assertTrue(descriptor.hasAbstract());
|
||||
|
||||
}
|
||||
|
||||
// Dummy implementation, Descriptor and Builder classes are abstract
|
||||
// so we need to provide an concrete implementation to test.
|
||||
public static class DescriptorImpl extends Descriptor {
|
||||
private DescriptorImpl(Builder builder) { super(builder); }
|
||||
public static class Builder extends Descriptor.Builder<Builder> {
|
||||
Builder(String identifier) { super(identifier); }
|
||||
@Override protected Builder self() { return this; }
|
||||
public DescriptorImpl build() { return new DescriptorImpl(this); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.test.mock.MockEnum;
|
||||
import org.n52.wps.io.data.IData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class InputDataDescriptorTest extends TestCase {
|
||||
|
||||
public InputDataDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testMinOccurs() {
|
||||
InputDescriptor inputDescriptor = null;
|
||||
|
||||
// test default minOccurs is 1
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).build();
|
||||
assertEquals(BigInteger.valueOf(1), inputDescriptor.getMinOccurs());
|
||||
|
||||
// test default minOccurs is 1, that we set it again doesn't matter
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).minOccurs(1).build();
|
||||
assertEquals(BigInteger.valueOf(1), inputDescriptor.getMinOccurs());
|
||||
// the other API
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).minOccurs(BigInteger.valueOf(1)).build();
|
||||
assertEquals(BigInteger.valueOf(1), inputDescriptor.getMinOccurs());
|
||||
|
||||
// test that 0 is OK
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).minOccurs(0).build();
|
||||
assertEquals(BigInteger.valueOf(0), inputDescriptor.getMinOccurs());
|
||||
// the other API
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).minOccurs(BigInteger.valueOf(0)).build();
|
||||
assertEquals(BigInteger.valueOf(0), inputDescriptor.getMinOccurs());
|
||||
|
||||
// test fail early on < 0
|
||||
boolean thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).minOccurs(-1);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
// The other API
|
||||
thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).minOccurs(BigInteger.valueOf(-1));
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// test that minOccurs can't be > maxOccurs
|
||||
thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).minOccurs(2).build();
|
||||
fail("Expected IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
// The other API
|
||||
thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).minOccurs(BigInteger.valueOf(2)).build();
|
||||
fail("Expected IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
}
|
||||
|
||||
public void testMaxOccurs() {
|
||||
|
||||
InputDescriptor inputDescriptor = null;
|
||||
|
||||
// test default maxOccurs is 1
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).build();
|
||||
assertEquals(BigInteger.valueOf(1), inputDescriptor.getMaxOccurs());
|
||||
|
||||
// test default maxOccurs is 1, that we set it again doesn't matter
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).maxOccurs(1).build();
|
||||
assertEquals(BigInteger.valueOf(1), inputDescriptor.getMaxOccurs());
|
||||
// the other API
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).maxOccurs(BigInteger.valueOf(1)).build();
|
||||
assertEquals(BigInteger.valueOf(1), inputDescriptor.getMaxOccurs());
|
||||
|
||||
// test that we can set maxOccurs value > 1
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).maxOccurs(2).build();
|
||||
assertEquals(BigInteger.valueOf(2), inputDescriptor.getMaxOccurs());
|
||||
// the other API
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).maxOccurs(BigInteger.valueOf(2)).build();
|
||||
assertEquals(BigInteger.valueOf(2), inputDescriptor.getMaxOccurs());
|
||||
|
||||
// test that we set maxOccurs to number of enum constants
|
||||
inputDescriptor = (new InputDescriptorImpl.Builder()).maxOccurs(MockEnum.class).build();
|
||||
assertEquals(BigInteger.valueOf(MockEnum.values().length), inputDescriptor.getMaxOccurs());
|
||||
|
||||
// test fail-early for maxOccurs < 1;
|
||||
boolean thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).maxOccurs(0);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
// the other API
|
||||
thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).maxOccurs(BigInteger.valueOf(0));
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
// test maxOccurs can be < minOccurs even if both are non-default
|
||||
thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).
|
||||
minOccurs(3).
|
||||
maxOccurs(2).
|
||||
build();
|
||||
fail("Expected IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
// the other API
|
||||
thrown = false;
|
||||
try {
|
||||
(new InputDescriptorImpl.Builder()).
|
||||
minOccurs(BigInteger.valueOf(3)).
|
||||
maxOccurs(BigInteger.valueOf(2)).
|
||||
build();
|
||||
fail("Expected IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
}
|
||||
|
||||
public static class InputDescriptorImpl extends InputDescriptor<Class<IData>> {
|
||||
private InputDescriptorImpl(Builder builder) { super(builder); }
|
||||
public static class Builder extends InputDescriptor.Builder<Builder, Class<IData>> {
|
||||
Builder() {
|
||||
super("mock_identifier", IData.class);
|
||||
}
|
||||
@Override protected Builder self() { return this; }
|
||||
@Override public InputDescriptorImpl build() { return new InputDescriptorImpl(this); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.wps.algorithm.util.ClassUtil;
|
||||
import org.n52.wps.io.BasicXMLTypeFactory;
|
||||
import org.n52.wps.io.data.binding.literal.LiteralAnyURIBinding;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class LiteralDataInputDescriptorTest extends TestCase {
|
||||
|
||||
public final static String MOCK_UNALLOWED = "MOCK_UNALLOWED";
|
||||
|
||||
public enum MOCK_ALLOWED_VALUES {
|
||||
MOCK_ALLOWED1,
|
||||
MOCK_ALLOWED2,
|
||||
MOCK_ALLOWED3,
|
||||
}
|
||||
|
||||
public LiteralDataInputDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testDefaultValue() {
|
||||
LiteralDataInputDescriptor descriptor = null;
|
||||
|
||||
// test default for defaultValue
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).build();
|
||||
assertNull(descriptor.getDefaultValue());
|
||||
assertFalse(descriptor.hasDefaultValue());
|
||||
|
||||
// test "" for defaultValue (unset annotation case)
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
defaultValue("").
|
||||
build();
|
||||
assertEquals("", descriptor.getDefaultValue());
|
||||
assertFalse(descriptor.hasDefaultValue());
|
||||
|
||||
// test with a valid defaultValue (unset annotation case)
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
defaultValue("mock_default").
|
||||
build();
|
||||
assertEquals("mock_default", descriptor.getDefaultValue());
|
||||
assertTrue(descriptor.hasDefaultValue());
|
||||
}
|
||||
|
||||
public void testAllowedValues() {
|
||||
LiteralDataInputDescriptor descriptor = null;
|
||||
|
||||
// test default for allowedValues
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).build();
|
||||
assertNotNull(descriptor.getAllowedValues());
|
||||
assertEquals(0, descriptor.getAllowedValues().size());
|
||||
assertFalse(descriptor.hasAllowedValues());
|
||||
|
||||
// test allowedValues(String[])
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
allowedValues(ClassUtil.convertEnumToStringArray(MOCK_ALLOWED_VALUES.class)).build();
|
||||
validateAllowValues(descriptor);
|
||||
|
||||
// test allowedValues(List<String>)
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
allowedValues(ClassUtil.convertEnumToStringList(MOCK_ALLOWED_VALUES.class)).build();
|
||||
validateAllowValues(descriptor);
|
||||
|
||||
// test allowedValues(Class<? extends Enum>)
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
allowedValues(MOCK_ALLOWED_VALUES.class).build();
|
||||
validateAllowValues(descriptor);
|
||||
|
||||
// test allowedValues()
|
||||
descriptor = LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
defaultValue(MOCK_ALLOWED_VALUES.MOCK_ALLOWED1.name()).
|
||||
allowedValues(MOCK_ALLOWED_VALUES.class).build();
|
||||
validateAllowValues(descriptor);
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).
|
||||
defaultValue(MOCK_UNALLOWED).
|
||||
allowedValues(MOCK_ALLOWED_VALUES.class).
|
||||
build();
|
||||
fail("Expected IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
}
|
||||
|
||||
public void testBuilder() {
|
||||
LiteralDataInputDescriptor descriptor =
|
||||
LiteralDataInputDescriptor.builder("mock_identifier", LiteralStringBinding.class).build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralStringBinding.class, descriptor.getBinding());
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
LiteralDataInputDescriptor.builder(null, LiteralStringBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
LiteralDataInputDescriptor.builder("", LiteralStringBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
LiteralDataInputDescriptor.builder("mock_identifier", null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
}
|
||||
|
||||
public void testAnyURIBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.anyURIBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralAnyURIBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.ANYURI_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testBase64BinaryBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.anyURIBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralAnyURIBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.ANYURI_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testBooleanBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.booleanBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralBooleanBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.BOOLEAN_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testByteBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.byteBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralByteBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.BYTE_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testDateTimeBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.dateTimeBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralDateTimeBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.DATETIME_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testDoubleBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.doubleBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralDoubleBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.DOUBLE_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testFloatBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.floatBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralFloatBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.FLOAT_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testIntBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.intBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralIntBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.INT_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testLongBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.longBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralLongBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.LONG_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testShortBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.shortBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralShortBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.SHORT_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testStringBuilder() {
|
||||
LiteralDataInputDescriptor descriptor = LiteralDataInputDescriptor.stringBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralStringBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.STRING_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
private void validateAllowValues(LiteralDataInputDescriptor descriptor) {
|
||||
assertTrue(descriptor.hasAllowedValues());
|
||||
|
||||
List<String> allowedValueList = descriptor.getAllowedValues();
|
||||
|
||||
assertNotNull(allowedValueList);
|
||||
assertEquals(MOCK_ALLOWED_VALUES.values().length, allowedValueList.size());
|
||||
for (int index = 0; index < allowedValueList.size(); ++index) {
|
||||
assertNotNull(allowedValueList.get(index));
|
||||
assertEquals(MOCK_ALLOWED_VALUES.values()[index].name(), allowedValueList.get(index));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.algorithm.descriptor;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.n52.wps.io.BasicXMLTypeFactory;
|
||||
import org.n52.wps.io.data.binding.literal.LiteralAnyURIBinding;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class LiteralDataOutputDescriptorTest extends TestCase {
|
||||
|
||||
public LiteralDataOutputDescriptorTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
public void testStaticBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor =
|
||||
LiteralDataOutputDescriptor.builder("mock_identifier", LiteralStringBinding.class).build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralStringBinding.class, descriptor.getBinding());
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
LiteralDataOutputDescriptor.builder(null, LiteralStringBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
LiteralDataOutputDescriptor.builder("", LiteralStringBinding.class);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
thrown = false;
|
||||
try {
|
||||
LiteralDataOutputDescriptor.builder("mock_identifier", null);
|
||||
fail("Expected IllegalArgumentException");
|
||||
} catch (IllegalArgumentException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
|
||||
}
|
||||
|
||||
public void testAnyURIBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.anyURIBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralAnyURIBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.ANYURI_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testBase64BinaryBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.anyURIBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralAnyURIBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.ANYURI_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testBooleanBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.booleanBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralBooleanBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.BOOLEAN_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testByteBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.byteBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralByteBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.BYTE_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testDateTimeBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.dateTimeBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralDateTimeBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.DATETIME_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testDoubleBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.doubleBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralDoubleBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.DOUBLE_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testFloatBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.floatBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralFloatBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.FLOAT_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testIntBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.intBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralIntBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.INT_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testLongBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.longBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralLongBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.LONG_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testShortBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.shortBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralShortBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.SHORT_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
public void testStringBuilder() {
|
||||
LiteralDataOutputDescriptor descriptor = LiteralDataOutputDescriptor.stringBuilder("mock_identifier").build();
|
||||
assertEquals("mock_identifier", descriptor.getIdentifier());
|
||||
assertEquals(LiteralStringBinding.class, descriptor.getBinding());
|
||||
assertEquals(BasicXMLTypeFactory.STRING_URI, descriptor.getDataType());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.HashMap;
|
||||
import org.n52.test.mock.MockUtil;
|
||||
import junit.framework.TestCase;
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class AbstractSelfDescribingAlgorithmTest extends TestCase {
|
||||
|
||||
public AbstractSelfDescribingAlgorithmTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MockUtil.getMockConfig();
|
||||
}
|
||||
|
||||
public void testComplexSelfDescribingAlgorithmUsingDescriptor() {
|
||||
IAlgorithm algorithm = new ComplexSelfDescribingAlgorithmUsingDescriptor();
|
||||
printAlgorithmProcessDescription(algorithm);
|
||||
}
|
||||
|
||||
public void testComplexAnnotatedAlgorithm() {
|
||||
IAlgorithm algorithm = new ComplexAnnotatedAlgorithm();
|
||||
printAlgorithmProcessDescription(algorithm);
|
||||
}
|
||||
|
||||
public void testStringReverseSelfDescribingAlgorithm() {
|
||||
IAlgorithm algorithm = new StringReverseSelfDescribingAlgorithm();
|
||||
printAlgorithmProcessDescription(algorithm);
|
||||
}
|
||||
|
||||
public void testStringReverseAnnotatedAlgorithm() {
|
||||
IAlgorithm algorithm = new StringReverseAnnotatedAlgorithm();
|
||||
printAlgorithmProcessDescription(algorithm);
|
||||
}
|
||||
|
||||
public void testStringJoinSelfDescribingAlgorithm() {
|
||||
IAlgorithm algorithm = new StringJoinSelfDescribingAlgorithm();
|
||||
printAlgorithmProcessDescription(algorithm);
|
||||
}
|
||||
|
||||
public void testStringJoinAnnotatedAlgorithm() {
|
||||
IAlgorithm algorithm = new StringJoinAnnotatedAlgorithm();
|
||||
printAlgorithmProcessDescription(algorithm);
|
||||
}
|
||||
|
||||
private void printAlgorithmProcessDescription(IAlgorithm algorithm) {
|
||||
System.out.println();
|
||||
System.out.println(" ### DescribeProcess for " + algorithm.getClass().getName() + " ###");
|
||||
System.out.println(getXMLAsStringFromDescription(algorithm.getDescription()));
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private String getXMLAsStringFromDescription(ProcessDescriptionType decription) {
|
||||
XmlOptions options = new XmlOptions();
|
||||
options.setSavePrettyPrint();
|
||||
options.setSaveOuter();
|
||||
HashMap ns = new HashMap();
|
||||
ns.put("http://www.opengis.net/wps/1.0.0", "wps");
|
||||
ns.put("http://www.opengis.net/ows/1.1", "ows");
|
||||
options.setSaveNamespacesFirst().
|
||||
setSaveSuggestedPrefixes(ns).
|
||||
setSaveAggressiveNamespaces();
|
||||
return decription.xmlText(options);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.n52.test.mock.MockBinding;
|
||||
import org.n52.test.mock.MockEnum;
|
||||
import org.n52.test.mock.MockComplexObject;
|
||||
import org.n52.wps.algorithm.annotation.Algorithm;
|
||||
import org.n52.wps.algorithm.annotation.ComplexDataInput;
|
||||
import org.n52.wps.algorithm.annotation.ComplexDataOutput;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataInput;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataOutput;
|
||||
import org.n52.wps.algorithm.annotation.Execute;
|
||||
import org.n52.wps.io.data.binding.literal.LiteralByteBinding;
|
||||
import org.n52.wps.io.data.binding.literal.LiteralShortBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Algorithm(
|
||||
// identifier="SampleIdentifier" fully qualified class name is used when this is missing
|
||||
version="0.0.1", // default is "1.0.0"
|
||||
title="Sample Algorithm Title", // identifier is used if title is not set
|
||||
abstrakt="Sample Algortihm Abstract", // default is null (not output)
|
||||
storeSupported=false, // default is true
|
||||
statusSupported=true) // default is true
|
||||
public class ComplexAnnotatedAlgorithm extends AbstractAnnotatedAlgorithm {
|
||||
|
||||
|
||||
// EXAMPLES FOR OUTPUTS
|
||||
|
||||
@LiteralDataInput(
|
||||
// binding=LiteralDoubleBinding.class, not needed, can infer type from field type
|
||||
identifier=Constants.LITERAL_DOUBLE,
|
||||
title="Sample Input Title",
|
||||
abstrakt="Sample Input Abstract",
|
||||
minOccurs=0,
|
||||
maxOccurs=2)
|
||||
public List<Double> inputLiteralDouble;
|
||||
// public List<? extends Double> inputLiteralDouble; OK, but needs explicit binding
|
||||
// public List<? super Double> inputLiteralDouble; OK, but needs explicit binding
|
||||
// public List<?> inputLiteralDouble; OK, but needs explicit binding
|
||||
// public List<? extends Number> inputLiteralDouble; OK, but needs explicit binding
|
||||
// public List<? super Number> inputLiteralDouble; FAIL, [dD]ouble not superclass of Number
|
||||
// public [dDouble] inputLiteralDouble; FAIL, maxOccurs is 2, need List!
|
||||
//
|
||||
// not an exhaustive list, point is we can autobind literal types. For types
|
||||
// where autobinding can't be inferred one can explicitly set binding but parser
|
||||
// will check types to validate assignability between binding payload and field or
|
||||
// method argument. Methods or fields must be public!
|
||||
|
||||
// primitive field
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_FLOAT)
|
||||
public float inputLiteralFloat;
|
||||
|
||||
|
||||
private Long inputLiteralLong;
|
||||
// Primitive wrapper as method argument
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_LONG)
|
||||
public void setInputLiteralLong(Long inputLiteralLong) {
|
||||
this.inputLiteralLong = inputLiteralLong;
|
||||
}
|
||||
|
||||
|
||||
private int inputLiteralInt;
|
||||
// Primitive as method argument
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_INT)
|
||||
public void setInputLiteralLong(int inputLiteralInt) {
|
||||
this.inputLiteralInt = inputLiteralInt;
|
||||
}
|
||||
|
||||
private Number inputLiteralShort;
|
||||
// Number as method argument type
|
||||
@LiteralDataInput(
|
||||
binding=LiteralShortBinding.class, // REQUIRED since literal type can't be inferred from method parameter type
|
||||
identifier=Constants.LITERAL_SHORT)
|
||||
public void setInputLiteralLong(Number inputLiteralShort) {
|
||||
this.inputLiteralShort = inputLiteralShort;
|
||||
}
|
||||
|
||||
|
||||
// Object as field type
|
||||
@LiteralDataInput(
|
||||
binding=LiteralByteBinding.class, // REQUIRED since literal type can't be inferred from field type
|
||||
identifier=Constants.LITERAL_BYTE)
|
||||
public Object inputLiteralByte;
|
||||
|
||||
|
||||
private boolean inputeLiteralBoolean;
|
||||
// don't care what method name is, only check it's annotation...
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_BOOLEAN)
|
||||
public void setWithSomeRandomName(boolean inputeLiteralBoolean) {
|
||||
this.inputeLiteralBoolean = inputeLiteralBoolean;
|
||||
}
|
||||
|
||||
private String inputLiteralString;
|
||||
@LiteralDataInput(
|
||||
identifier=Constants.LITERAL_STRING,
|
||||
defaultValue="Some Default Value", // annotation parser will validate this is allowedValues if set
|
||||
allowedValues= { "Some Default Value", "Not the default Value" } )
|
||||
public void setInputLiteralString(String inputLiteralString) {
|
||||
this.inputLiteralString = inputLiteralString;
|
||||
}
|
||||
|
||||
private MockEnum inputLiteralEnum;
|
||||
@LiteralDataInput(
|
||||
// binding=LiteralStringBinding.class Not needed! Enums are auto-bound to strings!
|
||||
identifier=Constants.LITERAL_ENUM,
|
||||
// defaultValue=MockEnum.VALUE1, Argh, Can't do this!
|
||||
// defaultValue=MockEnum.VALUE1.name(), Argh, Can't do this either!, only literals or constants! So we settle for String constants
|
||||
defaultValue="VALUE1", // must be string but annotation parser will validate this is valid constant for MockEnum
|
||||
// allowedValues= { ... } Already set to Enum constants for MockEnum!
|
||||
maxOccurs=LiteralDataInput.ENUM_COUNT // special case, set maxOccurs to number of MockEnum constants
|
||||
)
|
||||
public void setInputEnumType(MockEnum inputLiteralEnum) {
|
||||
this.inputLiteralEnum = inputLiteralEnum;
|
||||
}
|
||||
|
||||
// then the rest of the inputs...
|
||||
private Date inputLiteralDateTime;
|
||||
private byte[] inputLiteralBase64Binary;
|
||||
private URI inputLiteralAnyURI;
|
||||
private MockComplexObject inputComplex;
|
||||
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_DATETIME)
|
||||
public void setInputLiteralDateTime(Date inputLiteralDateTime) {
|
||||
this.inputLiteralDateTime = inputLiteralDateTime;
|
||||
}
|
||||
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_BASE64BINARY)
|
||||
public void setInputLiteralDateTime(byte[] inputLiteralBase64Binary) {
|
||||
this.inputLiteralBase64Binary = inputLiteralBase64Binary;
|
||||
}
|
||||
|
||||
@LiteralDataInput(identifier=Constants.LITERAL_ANYURI)
|
||||
public void setInputLiteralDateTime(URI inputLiteralAnyURI) {
|
||||
this.inputLiteralAnyURI = inputLiteralAnyURI;
|
||||
}
|
||||
|
||||
@ComplexDataInput(
|
||||
identifier=Constants.COMPLEX,
|
||||
binding=MockBinding.class, // Binding required for complex types!
|
||||
maximumMegaBytes=16)
|
||||
public void setInputComplex(MockComplexObject inputComplex) {
|
||||
this.inputComplex = inputComplex;
|
||||
}
|
||||
|
||||
|
||||
// EXAMPLES FOR OUTPUTS
|
||||
@LiteralDataOutput(
|
||||
identifier=Constants.LITERAL_DOUBLE,
|
||||
title="Sample Output Title", // identifier is used if title is not set
|
||||
abstrakt="Sample Output Abstract") // defaults to null (not output)
|
||||
public Double outputLiteralDouble;
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_FLOAT)
|
||||
public float outputLiteralFloat;
|
||||
|
||||
|
||||
private Long outputLiteralLong;
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_LONG)
|
||||
public Long getOutputLiteralLong() { return outputLiteralLong; }
|
||||
|
||||
private int outputLiteralInt;
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_INT)
|
||||
public int getOutputLiteralInt() { return outputLiteralInt; }
|
||||
|
||||
|
||||
@LiteralDataOutput(
|
||||
binding=LiteralShortBinding.class, // REQUIRED, can't infer binding for type Number
|
||||
identifier=Constants.LITERAL_SHORT)
|
||||
public Number outputLiteralShort;
|
||||
|
||||
// and the rest...
|
||||
|
||||
private byte outputLiteralByte;
|
||||
private boolean outputLiteralBoolean;
|
||||
private String outputLiteralString;
|
||||
private Date outputLiteralDateTime;
|
||||
private byte[] outputLiteralBase64Binary;
|
||||
private URI outputLiteralAnyURI;
|
||||
private MockComplexObject outputComplex;
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_BYTE)
|
||||
public byte getOutputLiteralByte() { return outputLiteralByte; }
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_BOOLEAN)
|
||||
public boolean getOutputLiteralBoolean() { return outputLiteralBoolean; }
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_STRING)
|
||||
public String getOutputLiteralString() { return outputLiteralString; }
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_DATETIME)
|
||||
public Date getOutputLiteralDateTime() { return outputLiteralDateTime; }
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_BASE64BINARY)
|
||||
public byte[] getOutputLiteralBase64Binary() { return outputLiteralBase64Binary; }
|
||||
|
||||
@LiteralDataOutput(identifier=Constants.LITERAL_ANYURI)
|
||||
public URI getOutputLiteralAnyURI() { return outputLiteralAnyURI; }
|
||||
|
||||
@ComplexDataOutput(
|
||||
binding=MockBinding.class, // Binding required for complex types!
|
||||
identifier=Constants.COMPLEX)
|
||||
public MockComplexObject getComplex() { return outputComplex; }
|
||||
|
||||
|
||||
@Execute
|
||||
public void doStuff() {
|
||||
|
||||
// values already unbound by setting fields or calling methods
|
||||
|
||||
// just access your variables directly...
|
||||
|
||||
// output fields or methods will be called and bound after this method call returns
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import org.n52.test.mock.MockBinding;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.n52.test.mock.MockEnum;
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.n52.wps.algorithm.descriptor.AlgorithmDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.ComplexDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.ComplexDataOutputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataOutputDescriptor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class ComplexSelfDescribingAlgorithmUsingDescriptor extends AbstractDescriptorAlgorithm {
|
||||
|
||||
// NOTE: AbstractSelfDescribingAlgorithm.initializeDescription(), is called
|
||||
// in the constructor of AbstractAlgorithm. This creates a situation where
|
||||
// initializeDescription() and getAlgorithmDescriptor() can be called before
|
||||
// the implementing classes have their constructors called...
|
||||
|
||||
// The descriptors do sanity checking and will throw Exceptions with illegal
|
||||
// arguments or state (i.e. null identifier or maxOccurs < minOccurs). If
|
||||
// you decide to instantiate the DESCRIPTOR using a static constructor be
|
||||
// sure to wrap it in a try/catch with logging otherwise class load will fail,
|
||||
// this is a difficult state to debug
|
||||
|
||||
|
||||
private static AlgorithmDescriptor DESCRIPTOR;
|
||||
protected synchronized static AlgorithmDescriptor getAlgorithmDescriptorStatic() {
|
||||
if (DESCRIPTOR == null) {
|
||||
DESCRIPTOR =
|
||||
// Adding a lot of fields in order to provide example of AlgorithmDescriptor
|
||||
// chaining with the different literal and complex types.
|
||||
// most process descriptions would be much simpler...
|
||||
// Show use of chaining enabled by use of Builder pattern...
|
||||
AlgorithmDescriptor.builder(ComplexSelfDescribingAlgorithmUsingDescriptor.class).
|
||||
version("0.0.1"). // default is "1.0.0"
|
||||
title("Sample Algorithm Title"). // identifier is used if title is not set
|
||||
abstrakt("Sample Algortihm Abstract"). // default is null (not output)
|
||||
statusSupported(false). // default is true
|
||||
storeSupported(false). // default is true
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.doubleBuilder(Constants.LITERAL_DOUBLE).
|
||||
title("Sample Input Title"). // identifier is used if title is not set
|
||||
abstrakt("Sample Input Abstract").// defaults to null (not output)
|
||||
minOccurs(0). // defaults to 1
|
||||
maxOccurs(2)). // defaults to 1
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.floatBuilder(Constants.LITERAL_FLOAT)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.longBuilder(Constants.LITERAL_LONG)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.intBuilder(Constants.LITERAL_INT)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.shortBuilder(Constants.LITERAL_SHORT)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.byteBuilder(Constants.LITERAL_BYTE)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.booleanBuilder(Constants.LITERAL_BOOLEAN)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.stringBuilder(Constants.LITERAL_STRING).
|
||||
defaultValue("Some Default Value"). // can set a default value.
|
||||
allowedValues(new String[] {"Some Default Value", "Not the default Value"})). // can set allowed values.
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.stringBuilder(Constants.LITERAL_ENUM).
|
||||
defaultValue(MockEnum.VALUE1.name()).// you can pass in an enum to set allowed values
|
||||
allowedValues(MockEnum.class). // you can pass in an enum to set allowed values
|
||||
maxOccurs(MockEnum.class)). // you can pass in an enum to set maxOccurs
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.dateTimeBuilder(Constants.LITERAL_DATETIME)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.base64BinaryBuilder(Constants.LITERAL_BASE64BINARY)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.anyURIBuilder(Constants.LITERAL_ANYURI)).
|
||||
addInputDescriptor(
|
||||
ComplexDataInputDescriptor.builder(Constants.COMPLEX, MockBinding.class).
|
||||
maximumMegaBytes(16)). // can set maximumMegaBytes for ComplexInput types
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.doubleBuilder(Constants.LITERAL_DOUBLE).
|
||||
title("Sample Output Title"). // identifier is used if title is not set
|
||||
abstrakt("Sample Output Abstract")). // defaults to null (not output)
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.floatBuilder(Constants.LITERAL_FLOAT)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.longBuilder(Constants.LITERAL_LONG)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.intBuilder(Constants.LITERAL_INT)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.shortBuilder(Constants.LITERAL_SHORT)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.byteBuilder(Constants.LITERAL_BYTE)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.booleanBuilder(Constants.LITERAL_BOOLEAN)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.stringBuilder(Constants.LITERAL_STRING)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.dateTimeBuilder(Constants.LITERAL_DATETIME)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.base64BinaryBuilder(Constants.LITERAL_BASE64BINARY)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.anyURIBuilder(Constants.LITERAL_ANYURI)).
|
||||
addOutputDescriptor(
|
||||
ComplexDataOutputDescriptor.builder(Constants.COMPLEX, MockBinding.class)).
|
||||
build();
|
||||
}
|
||||
return DESCRIPTOR;
|
||||
}
|
||||
|
||||
// Ideally this would be an abstract method in AbstractSelfDescribingAlgorithm,
|
||||
// this would break backwards compatibility with the Old API as it would
|
||||
// force migration to the new AlgorithmDescriptor based API.
|
||||
@Override
|
||||
public AlgorithmDescriptor createAlgorithmDescriptor() {
|
||||
// read note in static constructor...
|
||||
return getAlgorithmDescriptorStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, IData> run(Map<String, List<IData>> inputData) {
|
||||
// unbind and do stuff...
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
public final static String LITERAL_DOUBLE = "LITERAL_DOUBLE";
|
||||
public final static String LITERAL_FLOAT = "LITERAL_FLOAT";
|
||||
public final static String LITERAL_LONG = "LITERAL_LONG";
|
||||
public final static String LITERAL_INT = "LITERAL_INT";
|
||||
public final static String LITERAL_SHORT = "LITERAL_SHORT";
|
||||
public final static String LITERAL_BYTE = "LITERAL_BYTE";
|
||||
public final static String LITERAL_BOOLEAN = "LITERAL_BOOLEAN";
|
||||
public final static String LITERAL_STRING = "LITERAL_STRING";
|
||||
public final static String LITERAL_DATETIME = "LITERAL_DATETIME";
|
||||
public final static String LITERAL_BASE64BINARY = "LITERAL_BASE64BINARY";
|
||||
public final static String LITERAL_ANYURI = "LITERAL_ANYURI";
|
||||
public final static String LITERAL_ENUM = "LITERAL_ENUM";
|
||||
public final static String COMPLEX = "COMPLEX";
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import net.opengis.wps.x100.ProcessDescriptionType;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.n52.wps.algorithm.annotation.Algorithm;
|
||||
import org.n52.wps.algorithm.annotation.Execute;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataInput;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataOutput;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
public class ServiceLoaderAlgorithmTest {
|
||||
|
||||
private ServiceLoaderAlgorithmRepository repo;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
this.repo = new ServiceLoaderAlgorithmRepository();
|
||||
Assert.assertNotNull(this.repo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindAlgorithms() {
|
||||
String identified = "dummy-test-identifier";
|
||||
Assert.assertThat(repo.containsAlgorithm(identified), is(true));
|
||||
Assert.assertThat(repo.getAlgorithm(identified),
|
||||
is(notNullValue()));
|
||||
Assert.assertThat(repo.getAlgorithm(DummyAnnotatedAlgorithm.class
|
||||
.getCanonicalName()), is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotFindAlgorithm() {
|
||||
String identified = "not-in-there";
|
||||
Assert.assertThat(repo.containsAlgorithm(identified), is(not(true)));
|
||||
Assert.assertThat(repo.getAlgorithm(identified), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindTwoRegisteredAlgorithms() {
|
||||
Assert.assertThat(this.repo.getAlgorithmNames().size(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldResolveProcessDescription() {
|
||||
ProcessDescriptionType description = repo.getProcessDescription(DummyAnnotatedAlgorithm.class.getCanonicalName());
|
||||
Assert.assertThat(description, is(notNullValue()));
|
||||
Assert.assertThat(description, is(instanceOf(ProcessDescriptionType.class)));
|
||||
}
|
||||
|
||||
@Algorithm(version = "0.1")
|
||||
public static class DummyAnnotatedAlgorithm extends
|
||||
AbstractAnnotatedAlgorithm {
|
||||
|
||||
private String output;
|
||||
|
||||
@LiteralDataInput(identifier = "input")
|
||||
public String input;
|
||||
|
||||
@LiteralDataOutput(identifier = "output")
|
||||
public String getOutput() {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
@Execute
|
||||
public void myRunMethodFollowingNoSyntaxNoArgumentsAllowed() {
|
||||
this.output = "works like a charm.";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Algorithm(version = "0.1", identifier = "dummy-test-identifier")
|
||||
public static class DummyIdentifiedAnnotatedAlgorithm extends
|
||||
DummyAnnotatedAlgorithm {
|
||||
|
||||
private String output;
|
||||
|
||||
@LiteralDataInput(identifier = "input")
|
||||
public String input;
|
||||
|
||||
@LiteralDataOutput(identifier = "output")
|
||||
public String getOutput() {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
@Execute
|
||||
public void myRunMethodFollowingNoSyntaxNoArgumentsAllowed() {
|
||||
this.output = "works like a charm.";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import java.util.List;
|
||||
import org.n52.wps.algorithm.annotation.Algorithm;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataInput;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataOutput;
|
||||
import org.n52.wps.algorithm.annotation.Execute;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Algorithm(
|
||||
version="0.0.1",
|
||||
title="String Join Algorithm (Annotated)",
|
||||
abstrakt="This is an example algorithm implementation described using annotations that joins strings using the specified delimiter.",
|
||||
statusSupported=false,
|
||||
storeSupported=false)
|
||||
public class StringJoinAnnotatedAlgorithm extends AbstractAnnotatedAlgorithm {
|
||||
|
||||
public enum Delimiter {
|
||||
SPACE(' '),
|
||||
TAB('\t'),
|
||||
PIPE('|'),
|
||||
COMMA(','),
|
||||
SEMI_COLON(';'),
|
||||
COLON(':');
|
||||
public final char value;
|
||||
Delimiter(char value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> inputStrings;
|
||||
private Delimiter inputDelimiter;
|
||||
private String outputString;
|
||||
|
||||
@LiteralDataInput(
|
||||
identifier="INPUT_STRINGS",
|
||||
title="Input Strings",
|
||||
abstrakt="The strings you want joined.",
|
||||
minOccurs=2,
|
||||
maxOccurs=32)
|
||||
public void setInputString(List<String> inputStrings) {
|
||||
this.inputStrings = inputStrings;
|
||||
}
|
||||
|
||||
@LiteralDataInput(
|
||||
identifier="INPUT_DELIMITER",
|
||||
title="Delimiter",
|
||||
abstrakt="The value to use when joining strings")
|
||||
public void setInputDelimiter(Delimiter inputDelimiter) {
|
||||
this.inputDelimiter = inputDelimiter;
|
||||
}
|
||||
|
||||
|
||||
@LiteralDataOutput(
|
||||
identifier="OUTPUT_STRING",
|
||||
title="Output String",
|
||||
abstrakt="The strings joined with the delimiter")
|
||||
public String getOutputString() {
|
||||
return outputString;
|
||||
}
|
||||
|
||||
@LiteralDataInput(identifier="yourMom")
|
||||
public String yourMom;
|
||||
|
||||
@Execute
|
||||
public void reverse() {
|
||||
// don't need to do any parameter bounds checking that is specified
|
||||
// as part of the DescribeProcess, it's already done before this
|
||||
// method is called...
|
||||
outputString = Joiner.on(inputDelimiter.value).join(inputStrings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.n52.wps.algorithm.descriptor.AlgorithmDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataOutputDescriptor;
|
||||
import org.n52.wps.io.data.binding.literal.LiteralStringBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class StringJoinSelfDescribingAlgorithm extends AbstractDescriptorAlgorithm {
|
||||
|
||||
public final static String INPUT_STRINGS = "INPUT_STRINGS";
|
||||
public final static String INPUT_DELIMITER = "INPUT_DELIMITER";
|
||||
public final static String OUTPUT_STRING = "OUTPUT_STRING";
|
||||
|
||||
public enum Delimiter {
|
||||
SPACE(' '),
|
||||
TAB('\t'),
|
||||
PIPE('|'),
|
||||
COMMA(','),
|
||||
SEMI_COLON(';'),
|
||||
COLON(':');
|
||||
public final char value;
|
||||
Delimiter(char value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static AlgorithmDescriptor DESCRIPTOR;
|
||||
protected synchronized static AlgorithmDescriptor getAlgorithmDescriptorStatic() {
|
||||
if (DESCRIPTOR == null) {
|
||||
DESCRIPTOR =
|
||||
// passing in a class to the AlgorithmDescriptor.builder will set
|
||||
// set the identity to the the fully qualified class name. If this
|
||||
// is not desired use the String constructor.
|
||||
AlgorithmDescriptor.builder(StringJoinSelfDescribingAlgorithm.class).
|
||||
version("0.0.1"). // default is "1.0.0"
|
||||
title("String Join Algorithm (Self Describing)"). // identifier is used if title is not set
|
||||
abstrakt("This is an example algorithm implementation described using a chained builder that joins strings using the specified delimiter."). // default is null (not output)
|
||||
statusSupported(false). // default is true
|
||||
storeSupported(false). // default is true
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.stringBuilder(INPUT_STRINGS).
|
||||
title("Input Strings"). // identifier is used if title is not set
|
||||
abstrakt("The strings you want joined.").// defaults to null (not output)
|
||||
minOccurs(2). // defaults to 1
|
||||
maxOccurs(32)).
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.stringBuilder(INPUT_DELIMITER).
|
||||
title("Delimiter"). // identifier is used if title is not set
|
||||
abstrakt("The value to use when joining strings"). // defaults to null (not output)
|
||||
allowedValues(Delimiter.class)).
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.stringBuilder(OUTPUT_STRING).
|
||||
title("Output String"). // identifier is used if title is not set
|
||||
abstrakt("The strings joined with the delimiter")). // defaults to null (not output).
|
||||
build();
|
||||
}
|
||||
return DESCRIPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlgorithmDescriptor createAlgorithmDescriptor() {
|
||||
return getAlgorithmDescriptorStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, IData> run(Map<String, List<IData>> inputMap) {
|
||||
// unwrap input strings and error check
|
||||
List<IData> inputBoundStringList = inputMap.get(INPUT_STRINGS);
|
||||
if (inputBoundStringList == null || inputBoundStringList.size() < 2) {
|
||||
addError("Invalid parameter count for" + INPUT_STRINGS);
|
||||
return null;
|
||||
}
|
||||
List<String> inputStringList = new ArrayList<String>();
|
||||
for (IData boundString : inputBoundStringList) {
|
||||
if (boundString == null || !(boundString instanceof LiteralStringBinding)) {
|
||||
addError("unexpected binding ecountered unbinding " + INPUT_STRINGS + " parameter list");
|
||||
return null;
|
||||
}
|
||||
String inputString = ((LiteralStringBinding)boundString).getPayload();
|
||||
if (inputString == null || inputString.length() == 0) {
|
||||
addError("invalid value encounterd in " + INPUT_STRINGS + " parameter list");
|
||||
}
|
||||
inputStringList.add(inputString);
|
||||
}
|
||||
|
||||
// unwrap input delimiter and error check
|
||||
List<IData> inputBoundDelimiterList = inputMap.get(INPUT_DELIMITER);
|
||||
if (inputBoundDelimiterList == null || inputBoundDelimiterList.size() != 1) {
|
||||
addError("Invalid parameter count for" + INPUT_DELIMITER);
|
||||
return null;
|
||||
}
|
||||
|
||||
IData inputBoundDelimiterData = inputBoundDelimiterList.get(0);
|
||||
if (inputBoundDelimiterData == null || !(inputBoundDelimiterData instanceof LiteralStringBinding)) {
|
||||
addError("Something wierd happened with the request parser!");
|
||||
return null;
|
||||
}
|
||||
String inputDelimiterString = ((LiteralStringBinding)inputBoundDelimiterData).getPayload();
|
||||
Delimiter inputDelimiter = null;
|
||||
try {
|
||||
inputDelimiter = Delimiter.valueOf(inputDelimiterString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
addError("invalid value encounterd for " + INPUT_DELIMITER + " parameter");
|
||||
return null;
|
||||
}
|
||||
|
||||
// do work
|
||||
String outputString = Joiner.on(inputDelimiter.value).join(inputStringList);
|
||||
|
||||
// wrap output
|
||||
Map<String, IData> outputMap = new HashMap<String, IData>();
|
||||
outputMap.put(OUTPUT_STRING, new LiteralStringBinding(outputString));
|
||||
|
||||
return outputMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import org.n52.wps.algorithm.annotation.Algorithm;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataInput;
|
||||
import org.n52.wps.algorithm.annotation.LiteralDataOutput;
|
||||
import org.n52.wps.algorithm.annotation.Execute;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
@Algorithm(
|
||||
version="0.0.1",
|
||||
title="String Reverse Algorithm (Annotated)",
|
||||
abstrakt="This is an example algorithm implementation described using annotations that reverses a string.",
|
||||
statusSupported=false,
|
||||
storeSupported=false)
|
||||
public class StringReverseAnnotatedAlgorithm extends AbstractAnnotatedAlgorithm {
|
||||
|
||||
private String inputString;
|
||||
private String outputString;
|
||||
|
||||
@LiteralDataInput(
|
||||
identifier="INPUT_STRING",
|
||||
title="Input String",
|
||||
abstrakt="The input string you want reversed.")
|
||||
public void setInputString(String inputString) {
|
||||
this.inputString = inputString;
|
||||
}
|
||||
|
||||
|
||||
@LiteralDataOutput(
|
||||
identifier="OUTPUT_STRING",
|
||||
title="Output String",
|
||||
abstrakt="The reverse of the input string.")
|
||||
public String getOutputString() {
|
||||
return outputString;
|
||||
}
|
||||
|
||||
@Execute
|
||||
public void reverse() {
|
||||
outputString = (new StringBuffer(inputString)).reverse().toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source
|
||||
* Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.n52.wps.server;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.n52.wps.io.data.IData;
|
||||
import org.n52.wps.algorithm.descriptor.AlgorithmDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataInputDescriptor;
|
||||
import org.n52.wps.algorithm.descriptor.LiteralDataOutputDescriptor;
|
||||
import org.n52.wps.io.data.binding.literal.LiteralStringBinding;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tkunicki
|
||||
*/
|
||||
public class StringReverseSelfDescribingAlgorithm extends AbstractDescriptorAlgorithm {
|
||||
|
||||
public final static String INPUT_STRING = "INPUT_STRING";
|
||||
public final static String OUTPUT_STRING = "OUTPUT_STRING";
|
||||
|
||||
private static AlgorithmDescriptor DESCRIPTOR;
|
||||
protected synchronized static AlgorithmDescriptor getAlgorithmDescriptorStatic() {
|
||||
if (DESCRIPTOR == null) {
|
||||
DESCRIPTOR =
|
||||
// passing in a class to the AlgorithmDescriptor.builder will set
|
||||
// set the identity to the the fully qualified class name. If this
|
||||
// is not desired use the String constructor.
|
||||
AlgorithmDescriptor.builder(StringReverseSelfDescribingAlgorithm.class).
|
||||
version("0.0.1"). // default is "1.0.0"
|
||||
title("String Reverse Algorithm (Self Describing)"). // identifier is used if title is not set
|
||||
abstrakt("This is an example algorithm implementation described using a chained builder that reverses a string."). // default is null (not output)
|
||||
statusSupported(false). // default is true
|
||||
storeSupported(false). // default is true
|
||||
addInputDescriptor(
|
||||
LiteralDataInputDescriptor.stringBuilder(INPUT_STRING).
|
||||
title("Input String"). // identifier is used if title is not set
|
||||
abstrakt("The input string you want reversed.").// defaults to null (not output)
|
||||
minOccurs(1). // defaults to 1
|
||||
maxOccurs(1)). // defaults to 1
|
||||
addOutputDescriptor(
|
||||
LiteralDataOutputDescriptor.stringBuilder(OUTPUT_STRING).
|
||||
title("Output String"). // identifier is used if title is not set
|
||||
abstrakt("The reverse of the input string.")). // defaults to null (not output).
|
||||
build();
|
||||
}
|
||||
return DESCRIPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlgorithmDescriptor createAlgorithmDescriptor() {
|
||||
return getAlgorithmDescriptorStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, IData> run(Map<String, List<IData>> inputMap) {
|
||||
// unwrap input(s)
|
||||
List<IData> inputDataList = inputMap.get(INPUT_STRING);
|
||||
if (inputDataList == null || inputDataList.isEmpty()) {
|
||||
addError("Missing input string!");
|
||||
return null;
|
||||
}
|
||||
IData inputData = inputDataList.get(0);
|
||||
if (inputData == null || !(inputData instanceof LiteralStringBinding)) {
|
||||
addError("Something wierd happened with the request parser!");
|
||||
return null;
|
||||
}
|
||||
String inputString = ((LiteralStringBinding)inputData).getPayload();
|
||||
|
||||
// do work
|
||||
String outputString = (new StringBuffer(inputString)).reverse().toString();
|
||||
|
||||
// wrap output
|
||||
Map<String, IData> outputMap = new HashMap<String, IData>();
|
||||
outputMap.put(OUTPUT_STRING, new LiteralStringBinding(outputString));
|
||||
|
||||
return outputMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
org.n52.wps.server.ServiceLoaderAlgorithmTest$DummyAnnotatedAlgorithm
|
||||
org.n52.wps.server.ServiceLoaderAlgorithmTest$DummyIdentifiedAnnotatedAlgorithm
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<WPSConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://n52.org/wps schema_v1.xsd" xmlns="http://n52.org/wps">
|
||||
<Datahandlers>
|
||||
|
||||
<ParserList>
|
||||
<Parser name="MockParser" className="org.n52.test.mock.MockParser" active="true">
|
||||
<Property name="supportedSchema" active="true">http://a.mock.schema/apple</Property>
|
||||
<Property name="supportedSchema" active="true">http://a.mock.schema/orange</Property>
|
||||
<Property name="supportedFormat" active="true">test/mock</Property>
|
||||
<Property name="supportedEncoding" active="true">UTF-8</Property>
|
||||
</Parser>
|
||||
</ParserList>
|
||||
|
||||
<GeneratorList>
|
||||
<Generator name="MockGenerator" className="org.n52.test.mock.MockGenerator" active="true">
|
||||
<Property name="supportedSchema" active="true">http://a.mock.schema/apple</Property>
|
||||
<Property name="supportedSchema" active="true">http://a.mock.schema/orange</Property>
|
||||
<Property name="supportedFormat" active="true">test/mock</Property>
|
||||
<Property name="supportedEncoding" active="true">UTF-8</Property>
|
||||
</Generator>
|
||||
</GeneratorList>
|
||||
</Datahandlers>
|
||||
|
||||
<AlgorithmRepositoryList>
|
||||
|
||||
<Repository name="LocalAlgorithmRepository" className="org.n52.wps.server.LocalAlgorithmRepository" active="true">
|
||||
<Property name="Algorithm" active="true">org.n52.wps.server.SelfDescribingAlgorithmUsingDeprecatedAPI</Property>
|
||||
<Property name="Algorithm" active="true">org.n52.wps.server.SelfDescribingAlgorithmUsingDescriptor</Property>
|
||||
</Repository>
|
||||
<Repository name="ServiceLoaderAlgorithmRepository" className="org.n52.wps.server.ServiceLoaderAlgorithmRepository" active="true">
|
||||
</Repository>
|
||||
|
||||
</AlgorithmRepositoryList>
|
||||
|
||||
<!-- @hostname@, @hostport@ and @webappPath@ are filtered and replaced by values derived from
|
||||
HttpServelRequest instance of getRequestURL() in response using a Filter -->
|
||||
<Server hostname="@hostname@" hostport="@hostport@" webappPath="@webappPath@" includeDataInputsInResponse="true" computationTimeoutMilliSeconds="5" cacheCapabilites="false">
|
||||
<Database/>
|
||||
</Server>
|
||||
|
||||
</WPSConfiguration>
|
Loading…
Reference in New Issue