diff --git a/engine/src/main/java/org/n52/javaps/algorithm/AbstractSelfDescribingAlgorithm.java b/engine/src/main/java/org/n52/javaps/algorithm/AbstractSelfDescribingAlgorithm.java new file mode 100644 index 00000000..39acb6fe --- /dev/null +++ b/engine/src/main/java/org/n52/javaps/algorithm/AbstractSelfDescribingAlgorithm.java @@ -0,0 +1,528 @@ +/* + * Copyright 2016-2019 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.javaps.algorithm; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.n52.javaps.commons.observerpattern.IObserver; +import org.n52.javaps.commons.observerpattern.ISubject; +import org.n52.javaps.description.TypedBoundingBoxInputDescription; +import org.n52.javaps.description.TypedComplexInputDescription; +import org.n52.javaps.description.TypedComplexOutputDescription; +import org.n52.javaps.description.TypedLiteralInputDescription; +import org.n52.javaps.description.TypedProcessDescription; +import org.n52.javaps.description.impl.TypedComplexOutputDescriptionImpl; +import org.n52.javaps.description.impl.TypedProcessDescriptionFactory; +import org.n52.javaps.io.complex.ComplexData; +import org.n52.javaps.io.literal.LiteralType; +import org.n52.shetland.ogc.ows.OwsAllowedValues; +import org.n52.shetland.ogc.ows.OwsAnyValue; +import org.n52.shetland.ogc.ows.OwsCRS; +import org.n52.shetland.ogc.ows.OwsCode; +import org.n52.shetland.ogc.ows.OwsKeyword; +import org.n52.shetland.ogc.ows.OwsLanguageString; +import org.n52.shetland.ogc.ows.OwsMetadata; +import org.n52.shetland.ogc.ows.OwsValue; +import org.n52.shetland.ogc.wps.Format; +import org.n52.shetland.ogc.wps.description.ProcessInputDescription; +import org.n52.shetland.ogc.wps.description.ProcessOutputDescription; + +public abstract class AbstractSelfDescribingAlgorithm extends AbstractAlgorithm implements ISubject { + + private String title; + + private String _abstract; + + private String version; + + private boolean storeSupported; + + private boolean statusSupported; + + private Collection inputs = new ArrayList<>(); + + private Collection outputs = new ArrayList<>(); + + private TypedProcessDescriptionFactory descriptionFactory = new TypedProcessDescriptionFactory(); + + private List observers = new ArrayList(); + + private Object state; + + // @Inject + // private OutputHandlerRepository generatorRepository; + // + // @Inject + // private InputHandlerRepository parserRepository; + + private OwsMetadata metadata; + + private String getTitle() { + return title; + } + + protected void setTitle(String title) { + this.title = title; + } + + private String getAbstract() { + return _abstract; + } + + protected void setAbstract(String _abstract) { + this._abstract = _abstract; + } + + private String getVersion() { + return version; + } + + protected void setVersion(String version) { + this.version = version; + } + + @Override + protected TypedProcessDescription createDescription() { + + TypedProcessDescription description = new TypedProcessDescriptionFactory().process().withIdentifier(this + .getClass().getName()).withTitle(getTitle()).withAbstract(getAbstract()) + // .withMetadata(getMetadata()) + // TODO process could have no inputs + .withInput(getInputs()).withOutput(getOutputs()).withVersion(getVersion()).statusSupported( + getStatusSupported()).storeSupported(getStoreSupported()).build(); + + return description; + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + List keywordList, + Set metadata, + Format defaultFormat, + Set supportedFormats, + BigInteger maximumMegaBytes, + BigInteger minOccurs, + BigInteger maxOccurs, + Class> dataBinding) { + + List keywords = new ArrayList<>(); + + for (String keyword : keywordList) { + OwsKeyword owsKeyword = new OwsKeyword(keyword); + keywords.add(owsKeyword); + } + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withMinimalOccurence(minOccurs) + .withKeywords(keywords). + // FIXME + withMetadata(metadata.iterator().next()).withMaximalOccurence(maxOccurs).withMaximumMegabytes( + maximumMegaBytes).withDefaultFormat(defaultFormat).withSupportedFormat(supportedFormats) + .withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Set metadata, + Format defaultFormat, + Set supportedFormats, + BigInteger maximumMegaBytes, + BigInteger minOccurs, + BigInteger maxOccurs, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withMinimalOccurence(minOccurs) + // FIXME + .withMetadata(metadata.iterator().next()).withMaximalOccurence(maxOccurs).withMaximumMegabytes( + maximumMegaBytes).withDefaultFormat(defaultFormat).withSupportedFormat(supportedFormats) + .withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Set metadata, + Format defaultFormat, + Set supportedFormats, + BigInteger maxOccurs, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title). + // FIXME + withMetadata(metadata.iterator().next()).withMaximalOccurence(maxOccurs).withDefaultFormat( + defaultFormat).withSupportedFormat(supportedFormats).withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Format defaultFormat, + Set supportedFormats, + BigInteger maximumMegaBytes, + BigInteger minOccurs, + BigInteger maxOccurs, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withMinimalOccurence(minOccurs) + .withMaximalOccurence(maxOccurs).withMaximumMegabytes(maximumMegaBytes) + .withDefaultFormat(defaultFormat).withSupportedFormat(supportedFormats).withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Format defaultFormat, + Set supportedFormats, + BigInteger maximumMegaBytes, + BigInteger maxOccurs, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withMaximalOccurence(maxOccurs) + .withMaximumMegabytes(maximumMegaBytes).withDefaultFormat(defaultFormat).withSupportedFormat( + supportedFormats).withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Format defaultFormat, + Set supportedFormats, + BigInteger maxOccurs, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withMaximalOccurence(maxOccurs) + .withDefaultFormat(defaultFormat).withSupportedFormat(supportedFormats).withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Format defaultFormat, + Set supportedFormats, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withDefaultFormat(defaultFormat) + .withSupportedFormat(supportedFormats).withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + String title, + String _abstract, + Set supportedFormats, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withAbstract(_abstract).withTitle(title).withSupportedFormat(supportedFormats) + .withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + Format defaultFormat, + Set supportedFormats, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withDefaultFormat(defaultFormat).withSupportedFormat(supportedFormats).withType( + dataBinding).build(); + + inputs.add(inputDescription); + } + + protected void addComplexInputDescription(String id, + Set supportedFormats, + Class> dataBinding) { + + TypedComplexInputDescription inputDescription = new TypedProcessDescriptionFactory().complexInput() + .withIdentifier(id).withDefaultFormat(supportedFormats.iterator().next()).withSupportedFormat( + supportedFormats).withType(dataBinding).build(); + + inputs.add(inputDescription); + } + + // protected void addComplexInputDescription(String id, + // Class> dataBinding) { + // + // Set supportedFormats = + // this.parserRepository.getSupportedFormats(dataBinding); + // Format defaultFormat = + // this.parserRepository.getDefaultFormat(dataBinding).orElse(null); + // + // TypedComplexInputDescription inputDescription = new + // TypedProcessDescriptionFactory().complexInput() + // .withIdentifier(id).withAbstract(_abstract).withTitle(title).withDefaultFormat(defaultFormat) + // .withSupportedFormat(supportedFormats).withType(dataBinding).build(); + // + // inputs.add(inputDescription); + // } + + protected void addLiteralInputDescription(String id, + List allowedValues, + LiteralType dataBinding) { + + TypedLiteralInputDescription inputDescription = descriptionFactory.literalInput().withIdentifier(id).withType( + dataBinding).withDefaultLiteralDataDomain(descriptionFactory.literalDataDomain().withValueDescription( + allowedValues.isEmpty() ? OwsAnyValue.instance() + : new OwsAllowedValues(allowedValues.stream().map(OwsValue::new))).withDataType( + dataBinding.getDataType())).build(); + + inputs.add(inputDescription); + } + + protected void addLiteralInputDescription(String id, + List allowedValues, + BigInteger minOccurs, + BigInteger maxOccurs, + LiteralType dataBinding) { + + TypedLiteralInputDescription inputDescription = descriptionFactory.literalInput().withIdentifier(id) + .withMinimalOccurence(minOccurs).withMaximalOccurence(maxOccurs).withType(dataBinding) + .withDefaultLiteralDataDomain(descriptionFactory.literalDataDomain().withValueDescription(allowedValues + .isEmpty() ? OwsAnyValue.instance() + : new OwsAllowedValues(allowedValues.stream().map(OwsValue::new))).withDataType( + dataBinding.getDataType())).build(); + + inputs.add(inputDescription); + } + + protected void addBoundingBoxInputDescription(String id, + BigInteger minOccurs, + BigInteger maxOccurs, + OwsCRS defaultCRS, + List supportedCRSs) { + + TypedBoundingBoxInputDescription inputDescription = descriptionFactory.boundingBoxInput().withIdentifier(id) + .withMinimalOccurence(minOccurs).withMaximalOccurence(maxOccurs).withDefaultCRS(defaultCRS) + .withSupportedCRS(supportedCRSs).build(); + + inputs.add(inputDescription); + } + + protected void addBoundingBoxInputDescription(String id, + BigInteger minOccurs, + BigInteger maxOccurs, + OwsCRS defaultCRS) { + + TypedBoundingBoxInputDescription inputDescription = descriptionFactory.boundingBoxInput().withIdentifier(id) + .withMinimalOccurence(minOccurs).withMaximalOccurence(maxOccurs).withDefaultCRS(defaultCRS).build(); + + inputs.add(inputDescription); + } + + protected void addComplexOutputDescription(String id, + String title, + String _abstract, + List keywords, + Set metadata, + Format defaultFormat, + Set supportedFormats, + BigInteger maximumMegabytes, + Class> dataBinding) { + + TypedComplexOutputDescription outputDescription = new TypedComplexOutputDescriptionImpl(new OwsCode(id), + new OwsLanguageString(title), new OwsLanguageString(_abstract), null, metadata, defaultFormat, + supportedFormats, maximumMegabytes, dataBinding); + + outputs.add(outputDescription); + } + + protected void addComplexOutputDescription(String id, + String title, + String _abstract, + Format defaultFormat, + Set supportedFormats, + Class> dataBinding) { + + TypedComplexOutputDescription outputDescription = descriptionFactory.complexOutput().withIdentifier(id) + .withAbstract(_abstract).withTitle(title).withDefaultFormat(defaultFormat).withSupportedFormat( + supportedFormats).withType(dataBinding).build(); + + outputs.add(outputDescription); + } + + protected void addComplexOutputDescription(String id, + String title, + String _abstract, + Set supportedFormats, + Class> dataBinding) { + + TypedComplexOutputDescription outputDescription = descriptionFactory.complexOutput().withIdentifier(id) + .withAbstract(_abstract).withTitle(title).withDefaultFormat(supportedFormats.iterator().next()) + .withSupportedFormat(supportedFormats).withType(dataBinding).build(); + + outputs.add(outputDescription); + } + + // protected void addComplexOutputDescription(String id, + // String title, + // String _abstract, + // Class> dataBinding) { + // + // Set supportedFormats = + // this.generatorRepository.getSupportedFormats(dataBinding); + // Format defaultFormat = + // this.generatorRepository.getDefaultFormat(dataBinding).orElse(null); + // + // TypedComplexOutputDescription outputDescription = + // descriptionFactory.complexOutput().withIdentifier(id) + // .withAbstract(_abstract).withTitle(title).withDefaultFormat(defaultFormat).withSupportedFormat( + // supportedFormats).withType(dataBinding).build(); + // + // outputs.add(outputDescription); + // } + + private Collection getOutputs() { + return outputs; + } + + private Collection getInputs() { + return inputs; + } + + private OwsMetadata getMetadata() { + return this.metadata; + } + + protected void setMetadata(OwsMetadata metadata) { + this.metadata = metadata; + } + + private boolean getStoreSupported() { + return storeSupported; + } + + private boolean getStatusSupported() { + return statusSupported; + } + + protected void setStoreSupported(boolean storeSupported) { + this.storeSupported = storeSupported; + } + + protected void setStatusSupported(boolean statusSupported) { + this.statusSupported = statusSupported; + } + + /** + * 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 an array containing Strings representing the supported CRSs for + * inputs + */ + 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 an array containing Strings representing the supported CRSs for + * outputs + */ + 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 getInputIdentifiers(); + + public abstract List getOutputIdentifiers(); + + 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); + } + } + + @Override + public List getErrors() { + List errors = new ArrayList(); + return errors; + } + + // public void setParserRepository(InputHandlerRepository parserRepository) + // { + // this.parserRepository = parserRepository; + // + // } + // + // public void setGeneratorRepository(OutputHandlerRepository + // generatorRepository) { + // this.generatorRepository = generatorRepository; + // } + +} diff --git a/engine/src/main/java/org/n52/javaps/algorithm/LocalAlgorithmRepository.java b/engine/src/main/java/org/n52/javaps/algorithm/LocalAlgorithmRepository.java index 472467cc..dc799985 100644 --- a/engine/src/main/java/org/n52/javaps/algorithm/LocalAlgorithmRepository.java +++ b/engine/src/main/java/org/n52/javaps/algorithm/LocalAlgorithmRepository.java @@ -124,6 +124,10 @@ public void addAlgorithm(IAlgorithm instance) { LOG.warn(duplicateAlgorithmId, description.getId()); } this.algorithms.put(description.getId(), () -> instance); +// if (instance instanceof AbstractSelfDescribingAlgorithm) { +// ((AbstractSelfDescribingAlgorithm) instance).setParserRepository(parserRepository); +// ((AbstractSelfDescribingAlgorithm) instance).setGeneratorRepository(generatorRepository); +// } LOG.info("Algorithm {} with id {} registered", instance, description.getId()); } diff --git a/engine/src/main/java/org/n52/javaps/algorithm/annotation/BoundingBoxInputAnnotationParser.java b/engine/src/main/java/org/n52/javaps/algorithm/annotation/BoundingBoxInputAnnotationParser.java index 314d1e0a..70afb7a6 100644 --- a/engine/src/main/java/org/n52/javaps/algorithm/annotation/BoundingBoxInputAnnotationParser.java +++ b/engine/src/main/java/org/n52/javaps/algorithm/annotation/BoundingBoxInputAnnotationParser.java @@ -73,8 +73,6 @@ protected TypedBoundingBoxInputDescription createDescription(BoundingBoxInput an 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( diff --git a/engine/src/main/java/org/n52/javaps/algorithm/annotation/LiteralOutputAnnotationParser.java b/engine/src/main/java/org/n52/javaps/algorithm/annotation/LiteralOutputAnnotationParser.java index 2a84621b..aefc8d38 100644 --- a/engine/src/main/java/org/n52/javaps/algorithm/annotation/LiteralOutputAnnotationParser.java +++ b/engine/src/main/java/org/n52/javaps/algorithm/annotation/LiteralOutputAnnotationParser.java @@ -55,7 +55,6 @@ public LiteralType getLiteralType(LiteralOutput annotation, } @Override - @SuppressWarnings("unchecked") public TypedLiteralOutputDescription createDescription(LiteralOutput annotation, B binding) { LiteralType bindingType = getLiteralType(annotation, binding); diff --git a/engine/src/main/java/org/n52/javaps/description/impl/TypedBoundingBoxInputDescriptionImpl.java b/engine/src/main/java/org/n52/javaps/description/impl/TypedBoundingBoxInputDescriptionImpl.java index c4c0e23d..2610ec9e 100644 --- a/engine/src/main/java/org/n52/javaps/description/impl/TypedBoundingBoxInputDescriptionImpl.java +++ b/engine/src/main/java/org/n52/javaps/description/impl/TypedBoundingBoxInputDescriptionImpl.java @@ -18,6 +18,7 @@ import java.util.Set; +import org.n52.javaps.description.TypedBoundingBoxInputDescription; import org.n52.shetland.ogc.ows.OwsCRS; import org.n52.shetland.ogc.ows.OwsCode; import org.n52.shetland.ogc.ows.OwsKeyword; @@ -25,8 +26,6 @@ import org.n52.shetland.ogc.ows.OwsMetadata; import org.n52.shetland.ogc.wps.InputOccurence; import org.n52.shetland.ogc.wps.description.impl.BoundingBoxInputDescriptionImpl; -import org.n52.shetland.ogc.wps.description.impl.BoundingBoxInputDescriptionImpl.AbstractBuilder; -import org.n52.javaps.description.TypedBoundingBoxInputDescription; public class TypedBoundingBoxInputDescriptionImpl extends BoundingBoxInputDescriptionImpl implements TypedBoundingBoxInputDescription { diff --git a/engine/src/main/java/org/n52/javaps/engine/impl/StaticURLOutputReferencer.java b/engine/src/main/java/org/n52/javaps/engine/impl/StaticURLOutputReferencer.java index d12c879a..9defc711 100644 --- a/engine/src/main/java/org/n52/javaps/engine/impl/StaticURLOutputReferencer.java +++ b/engine/src/main/java/org/n52/javaps/engine/impl/StaticURLOutputReferencer.java @@ -62,6 +62,7 @@ public URI reference(OutputReference identifier) { @Override public OutputReference dereference(URI uri) throws IllegalArgumentException { + LOG.info("Dereferencing URI: " + uri); UriComponents build; this.lock.readLock().lock(); try { diff --git a/pom.xml b/pom.xml index ee0bc051..fc85d209 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ 5.1.3.RELEASE 1.7.25 2.3 - 5.2.0 + 5.2.0-SNAPSHOT