52n-wps-algorithm-gcube/src/main/java/org/n52/wps/server/AbstractSelfDescribingAlgor...

421 lines
14 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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());
}
}
}
}
}