Skip to content

Commit

Permalink
Merge pull request #28 from 52North/develop
Browse files Browse the repository at this point in the history
Merge develop
  • Loading branch information
bpross-52n authored Mar 7, 2019
2 parents fbd6c65 + 24b3d46 commit 753350b
Show file tree
Hide file tree
Showing 22 changed files with 375 additions and 129 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ sudo: false
install: true
script: mvn -fae -U -B clean install
jdk:
- oraclejdk8
- openjdk8
- openjdk9
- openjdk10
cache:
directories:
- $HOME/.m2
Expand Down
12 changes: 10 additions & 2 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ This project includes:
Animal Sniffer Annotations under MIT license
Apache Commons Codec under Apache License, Version 2.0
Apache Commons Configuration under Apache License, Version 2.0
Apache Commons Lang under The Apache Software License, Version 2.0
Apache Commons Lang under Apache License, Version 2.0
Apache Commons Logging under The Apache Software License, Version 2.0
Apache HttpClient under Apache License, Version 2.0
Apache HttpCore under Apache License, Version 2.0
Apache Log4j API under The Apache Software License, Version 2.0
Apache Log4j Core under The Apache Software License, Version 2.0
Apache Log4j SLF4J Binding under The Apache Software License, Version 2.0
Apache Log4j Web under The Apache Software License, Version 2.0
Checker Qual under The MIT License
ClassLoader Leak Prevention library under Apache 2
Commons Lang under The Apache Software License, Version 2.0
Cross-Origin Resource Sharing (CORS) Filter under The Apache Software License, Version 2.0
Expand All @@ -49,15 +49,22 @@ This project includes:
EXIficient-Core under MIT License
EXIficient-Grammars under MIT License
FindBugs-jsr305 under The Apache Software License, Version 2.0
geolatte-geom under LGPL 3.0
Guava InternalFutureFailureAccess and InternalFutures under The Apache Software License, Version 2.0
Guava ListenableFuture only under The Apache Software License, Version 2.0
Guava: Google Core Libraries for Java under The Apache Software License, Version 2.0
J2ObjC Annotations under The Apache Software License, Version 2.0
Jackson-annotations under The Apache Software License, Version 2.0
Jackson-core under The Apache Software License, Version 2.0
jackson-databind under The Apache Software License, Version 2.0
Java Architecture for XML Binding under CDDL 1.1 or GPL2 w/ CPE
Java Property Utility under The Apache Software License, Version 2.0
JavaBeans(TM) Activation Framework under COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
javax.inject under The Apache Software License, Version 2.0
JCL 1.2 implemented over SLF4J under MIT License
Joda-Time under Apache 2
Old JAXB Core under CDDL+GPL License
Old JAXB Runtime under CDDL+GPL License
org.locationtech.jts:jts-core under Eclipse Publish License, Version 1.0 or Eclipse Distribution License - v 1.0
PJL Compressing Filter under Apache Software License V2.0
SLF4J API Module under MIT License
Expand All @@ -73,5 +80,6 @@ This project includes:
StAX API under The Apache Software License, Version 2.0
Xerces2-j under The Apache Software License, Version 2.0
XML Commons External Components XML APIs under The Apache Software License, Version 2.0 or The SAX License or The W3C License
XML Pull Parsing API under Public Domain
XmlBeans under The Apache Software License, Version 2.0

5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,14 @@ Try out the latest javaPS alpha-release on on our [Geoprocessing Demo Server](ht
## Support

You can get support in the community mailing list and forums:
http://52north.org/resources/mailing-lists-and-forums/
https://52north.org/discuss/#mailing-lists

## Contribute

Are you are interesting in contributing to javaPS and you want to pull your changes to the 52°North repository to make it available to all?
In that case we need your official permission and for this purpose we have a so called contributors license agreement (CLA) in place. With this agreement you grant us the rights to use and publish your code under an open source license.
A link to the contributors license agreement and further explanations are available here:
http://52north.org/about/licensing/cla-guideline

https://52north.org/software/licensing/guidelines/
## Credits

* Christian Autermann, @autermann
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,81 @@ How to add custom Processes/Algorithms to JavaPS

As described in the [Architectural Details Page](../architecture/architecture.markdown), processes are implementations of the interface ***IAlgorithm***, which prescribes an *execute()* method and a ***TypedProcessDescription***, the Java representation of a process description. The abstract component ***AbstractAlgorithm*** implements the interface and thus provides the rudimentary skeleton for any ***Algorithm*** implementation. However, algorithm developers do not have to extend ***AbstractAlgorithm*** themselves. Instead, **JavaPS** offers a more elegant and simple way of implementing custom ***Algorithms***. Through suitable *Java annotations*, any Java class may become an ***Algorithm*** that is found at application start-up by **JavaPS**. This functionality is provided by component ***AnnotatedAlgorithm***, which extends ***AbstractAlgorithm*** and thus provides a full implementation of the requirements (*process description* and *execute()* method). The necessary information is automatically parsed and derived from the *annotations*.

The following example demonstrates the definition of an *annotated algorithm*. The exemplar *"TestAlgorithm"* is marked as an implementation of ***IAlgorithm*** by annotating certain methods with key annotation, such as **@Algorithm**, **@LiteralInput**, **@LiteralOutput** and **@Execute**.
The following example demonstrates the definition of an *annotated algorithm*. The exemplar *"EchoProcess"* is marked as an implementation of ***IAlgorithm*** by annotating certain methods with key annotation, such as **@Algorithm**, **@LiteralInput**, **@LiteralOutput** and **@Execute**.

```
package org.n52.javaps.service;
package org.n52.wps.echoprocess;
//import statements omitted
@Algorithm(version = "1.0.0")
public class TestAlgorithm {
private String input1;
private String input2;
private String output1;
private String output2;
@LiteralInput(identifier = "input1")
public void setInput1(String value) {
this.input1 = value;
public class EchoProcess {
private static final Logger log = LoggerFactory.getLogger(EchoProcess.class);
private List<XmlObject> complexInput;
private List<String> literalInput;
private XmlObject complexOutput;
private String literalOutput;
private OwsBoundingBox boundingboxInput;
private OwsBoundingBox boundingboxOutput;
@Execute
public void echo() {
log.debug("Running echo process");
if (literalInput != null && literalInput.size() > 0){
literalOutput = literalInput.get(0);
} else{
log.debug("No literal input");
}
if (complexInput != null && complexInput.size() > 0){
complexOutput = complexInput.get(0);
} else{
log.debug("No complex input");
}
if (boundingboxInput != null){
boundingboxOutput = boundingboxInput;
} else{
log.debug("No bounding box input");
}
log.debug("Finished echo process, literal output is '{}', complex output is : {}", literalOutput, complexOutput);
}
@LiteralInput(identifier = "input2")
public void setInput2(String value) {
this.input2 = value;
@LiteralOutput(identifier = "literalOutput")
public String getLiteralOutput() {
return literalOutput;
}
@Execute
public void execute() {
this.output1 = input1;
this.output2 = input2;
@LiteralInput(identifier = "literalInput", maxOccurs = 1)
public void setLiteralInput(List<String> literalInput) {
this.literalInput = literalInput;
}
@BoundingBoxInput(defaultCRSString="EPSG:4326", identifier = "boundingboxInput")
public void setBoundingBox(OwsBoundingBox data){
this.boundingboxInput = data;
}
@BoundingBoxOutput(defaultCRSString="EPSG:4326", identifier = "boundingboxOutput")
public OwsBoundingBox getBoundingBox(){
return this.boundingboxOutput;
}
@LiteralOutput(identifier = "output1")
public String getOutput1() {
return this.output1;
@ComplexOutput(identifier="complexOutput", binding=GenericXMLDataBinding.class)
public XmlObject getComplexOutput() {
return complexOutput;
}
@LiteralOutput(identifier = "output2")
public String getOutput2() {
return this.output2;
@ComplexInput(identifier="complexInput", binding=GenericXMLDataBinding.class)
public void setComplexInput(List<XmlObject> complexInput) {
this.complexInput = complexInput;
}
}
Expand Down Expand Up @@ -96,6 +133,18 @@ Annotation `@ComplexInput` Properties
- long **maximumMegaBytes**: a limitation of the maximum size of the complex input's payload
- Class **binding**: reference to a *binding* class that implements/extends *ComplexData.class* and thus is able to parse the complex input from an *Execute* request correctly; basically this *binding* component acts as a wrapper for the input; more information about *binding* is provided in section [The Role of the Binding Implementations](#the-role-of-the-binding-implementations)

#### Setter Annotation **@BoundingBoxInput**

Annotation `@ComplexInput` Properties

- String **identifier**: specifies the unique *input identifier* of the input
- String **title**: the title of the input; can be chosen arbitrarily
- String **abstrakt**: a description of the input
- long **minOccurs**: the minimum number of occurrences within an *Execute* request; default value is "1"
- long **maxOccurs**: the maximum number of occurrences within an *Execute* request; default value is "1"
- String **defaultCRSString**: the default CRS as String; default value is "http://www.opengis.net/def/crs/EPSG/0/4326"
- String[] **supportedCRSStringArray**: String array of supported CRS; default value is {"http://www.opengis.net/def/crs/EPSG/0/4326"}

### Annotations for the Definition of *Process Outputs*

#### Setter Annotation **@LiteralOutput**
Expand All @@ -117,6 +166,16 @@ Annotation `@ComplexOutput` Properties
- String **abstrakt**: a description of the output
- Class **binding**: reference to a *binding* class that implements/extends *ComplexData.class* and thus is able to encode the output correctly; basically this *binding* component acts as a wrapper for the output; more information about *binding* is provided in section [The Role of the Binding Implementations](#the-role-of-the-binding-implementations)

#### Setter Annotation **@BoundingBoxOutput**

Annotation `@BoundingBoxOutput` Properties

- String **identifier**: specifies the unique *output identifier* of the output
- String **title**: the title of the output; can be chosen arbitrarily
- String **abstrakt**: a description of the output
- String **defaultCRSString**: the default CRS as String; default value is "http://www.opengis.net/def/crs/EPSG/0/4326"
- String[] **supportedCRSStringArray**: String array of supported CRS; default value is {"http://www.opengis.net/def/crs/EPSG/0/4326"}

### The Role of the Binding Implementations

During the previous explanation of the annotations for *in-* and *outputs*, a specific annotation called **binding** was introduced. Its purpose and relevance will be described in this section. In general, a **WPS** process defines several process *in-* and *outputs*. When a client constructs and sends an **Execute request**, the *inputs* are specified using a certain **format/encoding**. Also the client may request the process *output(s)* to be **encoded in a certain format**. While the available **formats** are predefined by the **JavaPS** implementation of that process, the ***Algorithm*** implementation uses a single internal representation of the *in-* and *outputs*. Hence, transformation between the different data representations is necessary.
Expand Down
4 changes: 4 additions & 0 deletions engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@

long maxOccurs() default 1;

String boundingBoxString() default "";

String defaultCRSString() default CRS_EPSG_4326;

String[] supportedCRSStringArray() default { CRS_EPSG_4326 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.lang.reflect.Member;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

import org.n52.javaps.description.TypedBoundingBoxInputDescription;
Expand All @@ -41,6 +43,7 @@ class BoundingBoxInputAnnotationParser<M extends AccessibleObject & Member, B ex
AbstractInputAnnotationParser<BoundingBoxInput, M, B> {

private static final Logger LOG = LoggerFactory.getLogger(BoundingBoxInputAnnotationParser.class);
private static final String COULD_NOT_CREATE_URI_FROM_STRING = "Could not create URI from String: ";

BoundingBoxInputAnnotationParser(Function<M, B> bindingFunction) {
super(bindingFunction);
Expand All @@ -55,16 +58,27 @@ protected TypedBoundingBoxInputDescription createDescription(BoundingBoxInput an
try {
defaultCRSURI = new URI(annotation.defaultCRSString());
} catch (URISyntaxException e) {
LOG.error("Could not create URI from String: " + annotation.defaultCRSString());
LOG.error(COULD_NOT_CREATE_URI_FROM_STRING + annotation.defaultCRSString());
defaultCRSURI = URI.create("http://www.opengis.net/def/crs/EPSG/0/4326");
}

List<OwsCRS> supportedCRSList = new ArrayList<>();

String [] supportedCRSArray = annotation.supportedCRSStringArray();

for (String crsString : supportedCRSArray) {
try {
supportedCRSList.add(new OwsCRS(new URI(crsString)));
} catch (URISyntaxException e) {
LOG.error(COULD_NOT_CREATE_URI_FROM_STRING + crsString);
}
}
// TODO add supported CRSs

return new TypedProcessDescriptionFactory().boundingBoxInput().withIdentifier(annotation.identifier())
.withAbstract(annotation.abstrakt()).withTitle(annotation.title()).withMinimalOccurence(annotation
.minOccurs()).withMaximalOccurence(annotation.maxOccurs()).withDefaultCRS(new OwsCRS(
defaultCRSURI)).build();
defaultCRSURI)).withSupportedCRS(supportedCRSList).build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ private Data<?> decodeReference(TypedProcessInputDescription<?> description,
private Data<?> decodeValueInput(TypedProcessInputDescription<?> description,
ValueProcessData input) throws InputDecodingException {
Format format = input.getFormat();

if (format.isEmpty()) {
if (description.isComplex()) {
format = description.asComplex().getDefaultFormat();
} else {
format = Format.TEXT_XML;
}
}

Class<? extends Data<?>> bindingType = description.getBindingType();

InputHandler handler = this.inputHandlerRepository.getInputHandler(format, bindingType).orElseThrow(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import javax.inject.Inject;

import org.n52.shetland.ogc.ows.OwsCode;
import org.n52.shetland.ogc.wps.Format;
import org.n52.shetland.ogc.wps.OutputDefinition;
import org.n52.shetland.ogc.wps.data.GroupProcessData;
import org.n52.shetland.ogc.wps.data.ProcessData;
Expand Down Expand Up @@ -79,7 +80,18 @@ private void createData(TypedProcessOutputDescriptionContainer description,
private ProcessData createValueData(TypedProcessOutputDescription<?> outputDescription,
OutputDefinition outputDefinition,
Data<?> data) throws OutputEncodingException {
OutputHandler outputHandler = this.outputHandlerRepository.getOutputHandler(outputDefinition.getFormat(), data)

Format format = outputDefinition.getFormat();

if (format.isEmpty()) {
if (outputDescription.isComplex()) {
format = outputDescription.asComplex().getDefaultFormat();
} else {
format = Format.TEXT_XML;
}
}

OutputHandler outputHandler = this.outputHandlerRepository.getOutputHandler(format, data)
.orElseThrow(noHandlerFound(outputDescription.getId()));
return new GeneratingProcessData(outputDescription, outputDefinition, outputHandler, data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ public ValueProcessData resolve() throws IOException {

private byte[] getFromLocalDisc() throws IOException {
URL fileURL = getURI().toURL();
InputStream is = new FileInputStream(fileURL.getFile());
return ByteStreams.toByteArray(is);
try (InputStream is = new FileInputStream(fileURL.getFile())) {
return ByteStreams.toByteArray(is);
}
}

}
23 changes: 22 additions & 1 deletion engine/src/main/java/org/n52/javaps/io/bbox/BoundingBoxData.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@
*/
package org.n52.javaps.io.bbox;

import org.n52.shetland.ogc.ows.OwsBoundingBox;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.n52.javaps.io.Data;
import org.n52.javaps.io.DecodingException;
import org.n52.shetland.ogc.ows.OwsBoundingBox;
import org.n52.shetland.ogc.wps.Format;

public final class BoundingBoxData implements Data<OwsBoundingBox> {
private static final long serialVersionUID = -3219612972795621553L;
Expand All @@ -37,4 +44,18 @@ public OwsBoundingBox getPayload() {
public Class<?> getSupportedClass() {
return OwsBoundingBox.class;
}

private synchronized void writeObject(java.io.ObjectOutputStream oos) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BoundingBoxInputOutputHandler generator = new BoundingBoxInputOutputHandler();
InputStream in = generator.generate(null, this, new Format());
IOUtils.copy(in, out);
}

private void readObject(java.io.ObjectInputStream oos) throws IOException, ClassNotFoundException,
DecodingException {
BoundingBoxInputOutputHandler parser = new BoundingBoxInputOutputHandler();
BoundingBoxData data = (BoundingBoxData) parser.parse(null, oos, new Format());
this.boundingBox = data.boundingBox;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,8 @@ public InputStream generate(TypedProcessOutputDescription<?> description,
InputStream stream = new ByteArrayInputStream(bytes);

if (format.isBase64()) {
stream = new Base64InputStream(stream, true);
return new Base64InputStream(stream, true);
}

return stream;
} catch (XMLStreamException ex) {
throw new IOException(ex);
Expand Down
Loading

0 comments on commit 753350b

Please sign in to comment.