Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.n52.svalbard.encode.OmEncoderv20 Maven / Gradle / Ivy
/*
* Copyright 2015-2020 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.svalbard.encode;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import javax.inject.Inject;
import javax.xml.stream.XMLStreamException;
import org.apache.xmlbeans.XmlBoolean;
import org.apache.xmlbeans.XmlInteger;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlString;
import org.n52.janmayen.http.MediaType;
import org.n52.shetland.ogc.SupportedType;
import org.n52.shetland.ogc.gml.AbstractFeature;
import org.n52.shetland.ogc.om.AbstractObservationValue;
import org.n52.shetland.ogc.om.MultiObservationValues;
import org.n52.shetland.ogc.om.NamedValue;
import org.n52.shetland.ogc.om.ObservationValue;
import org.n52.shetland.ogc.om.OmConstants;
import org.n52.shetland.ogc.om.OmObservation;
import org.n52.shetland.ogc.om.OmObservationConstellation;
import org.n52.shetland.ogc.om.SingleObservationValue;
import org.n52.shetland.ogc.om.series.wml.WaterMLConstants;
import org.n52.shetland.ogc.om.values.BooleanValue;
import org.n52.shetland.ogc.om.values.CategoryValue;
import org.n52.shetland.ogc.om.values.ComplexValue;
import org.n52.shetland.ogc.om.values.CountValue;
import org.n52.shetland.ogc.om.values.CvDiscretePointCoverage;
import org.n52.shetland.ogc.om.values.GeometryValue;
import org.n52.shetland.ogc.om.values.HrefAttributeValue;
import org.n52.shetland.ogc.om.values.MultiPointCoverage;
import org.n52.shetland.ogc.om.values.NilTemplateValue;
import org.n52.shetland.ogc.om.values.ProfileValue;
import org.n52.shetland.ogc.om.values.QuantityRangeValue;
import org.n52.shetland.ogc.om.values.QuantityValue;
import org.n52.shetland.ogc.om.values.RectifiedGridCoverage;
import org.n52.shetland.ogc.om.values.ReferenceValue;
import org.n52.shetland.ogc.om.values.SweDataArrayValue;
import org.n52.shetland.ogc.om.values.TLVTValue;
import org.n52.shetland.ogc.om.values.TVPValue;
import org.n52.shetland.ogc.om.values.TextValue;
import org.n52.shetland.ogc.om.values.TimeRangeValue;
import org.n52.shetland.ogc.om.values.UnknownValue;
import org.n52.shetland.ogc.om.values.XmlValue;
import org.n52.shetland.ogc.om.values.visitor.ValueVisitor;
import org.n52.shetland.ogc.sensorML.SensorMLConstants;
import org.n52.shetland.ogc.sos.Sos2Constants;
import org.n52.shetland.ogc.sos.SosConstants;
import org.n52.shetland.ogc.swe.SweConstants;
import org.n52.shetland.ogc.swe.SweDataArray;
import org.n52.shetland.util.OMHelper;
import org.n52.shetland.w3c.Nillable;
import org.n52.shetland.w3c.SchemaLocation;
import org.n52.svalbard.ConformanceClasses;
import org.n52.svalbard.encode.exception.EncodingException;
import org.n52.svalbard.encode.exception.UnsupportedEncoderInputException;
import org.n52.svalbard.util.CodingHelper;
import org.n52.svalbard.util.SweHelper;
import org.n52.svalbard.write.OmV20XmlStreamWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import net.opengis.gml.x32.FeaturePropertyType;
import net.opengis.gml.x32.TimeInstantPropertyType;
import net.opengis.om.x20.OMObservationType;
import net.opengis.om.x20.OMProcessPropertyType;
import net.opengis.om.x20.TimeObjectPropertyType;
/**
* @since 1.0.0
*
*/
public class OmEncoderv20 extends AbstractOmEncoderv20 {
private static final String NIL_REASON_TEMPLATE = "template";
private static final String OBSERVATION_GML_ID_TEMPLATE = NIL_REASON_TEMPLATE;
private static final Logger LOGGER = LoggerFactory.getLogger(OmEncoderv20.class);
private static final Set ENCODER_KEYS = CodingHelper.encoderKeysForElements(OmConstants.NS_OM_2,
MultiObservationValues.class,
NamedValue.class,
SingleObservationValue.class,
OmObservation.class,
OmObservationConstellation.class);
// TODO: change to correct conformance class
private static final Set CONFORMANCE_CLASSES = new HashSet<>(Arrays
.asList(ConformanceClasses.OM_V2_MEASUREMENT,
ConformanceClasses.OM_V2_CATEGORY_OBSERVATION,
ConformanceClasses.OM_V2_COUNT_OBSERVATION,
ConformanceClasses.OM_V2_TRUTH_OBSERVATION,
ConformanceClasses.OM_V2_GEOMETRY_OBSERVATION,
ConformanceClasses.OM_V2_TEXT_OBSERVATION,
ConformanceClasses.OM_V2_COMPLEX_OBSERVATION));
private static final Set SUPPORTED_TYPES = new HashSet<>(Arrays
.asList(OmConstants.OBS_TYPE_SWE_ARRAY_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_COMPLEX_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_GEOMETRY_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_CATEGORY_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_COUNT_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_MEASUREMENT_TYPE,
OmConstants.OBS_TYPE_TEXT_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_TRUTH_OBSERVATION_TYPE,
OmConstants.OBS_TYPE_REFERENCE_OBSERVATION_TYPE));
private static final Map>> SUPPORTED_RESPONSE_FORMATS = Collections.singletonMap(
SosConstants.SOS,
Collections.singletonMap(Sos2Constants.SERVICEVERSION, Collections.singleton(OmConstants.NS_OM_2)));
private SweHelper sweHelper;
public OmEncoderv20() {
LOGGER.debug("Encoder for the following keys initialized successfully: {}!",
Joiner.on(", ").join(ENCODER_KEYS));
}
@Inject
public void setSweHelper(SweHelper sweHelper) {
this.sweHelper = sweHelper;
}
@Override
public Set getKeys() {
return Collections.unmodifiableSet(ENCODER_KEYS);
}
@Override
public Set getSupportedTypes() {
return Collections.unmodifiableSet(SUPPORTED_TYPES);
}
@Override
public Map> getSupportedResponseFormatObservationTypes() {
return Collections.singletonMap(OmConstants.NS_OM_2, getSupportedTypes());
}
@Override
public Set getConformanceClasses(String service, String version) {
if (SosConstants.SOS.equals(service) && Sos2Constants.SERVICEVERSION.equals(version)) {
return Collections.unmodifiableSet(CONFORMANCE_CLASSES);
}
return Collections.emptySet();
}
@Override
public boolean isObservationAndMeasurmentV20Type() {
return true;
}
@Override
public Set getSupportedResponseFormats(String service, String version) {
if (SUPPORTED_RESPONSE_FORMATS.get(service) != null &&
SUPPORTED_RESPONSE_FORMATS.get(service).get(version) != null) {
return SUPPORTED_RESPONSE_FORMATS.get(service).get(version);
}
return Collections.emptySet();
}
@Override
public boolean shouldObservationsWithSameXBeMerged() {
return false;
}
@Override
public boolean supportsResultStreamingForMergedValues() {
return false;
}
@Override
public String getDefaultFeatureEncodingNamespace() {
return null;
}
@Override
public MediaType getContentType() {
return OmConstants.CONTENT_TYPE_OM_2;
}
@Override
public Set getSchemaLocations() {
return Sets.newHashSet(OmConstants.OM_20_SCHEMA_LOCATION);
}
@Override
public XmlObject encode(Object element, EncodingContext additionalValues) throws EncodingException {
if (element instanceof ObservationValue) {
return encodeResult((ObservationValue>) element);
} else if (element instanceof OmObservationConstellation) {
return encodeObservationTemplate((OmObservationConstellation) element);
}
return super.encode(element, additionalValues);
}
@Override
public void encode(Object objectToEncode, OutputStream outputStream, EncodingContext ctx)
throws EncodingException {
if (objectToEncode instanceof OmObservation) {
try {
new OmV20XmlStreamWriter(
ctx.with(EncoderFlags.ENCODER_REPOSITORY, getEncoderRepository())
.with(XmlEncoderFlags.XML_OPTIONS, (Supplier) this::getXmlOptions),
outputStream, (OmObservation) objectToEncode).write();
} catch (XMLStreamException xmlse) {
throw new EncodingException("Error while writing element to stream!", xmlse);
}
} else {
super.encode(objectToEncode, ctx);
}
}
@Override
protected OMObservationType createOmObservationType() {
return OMObservationType.Factory.newInstance(getXmlOptions());
}
@Override
protected XmlObject createResult(OmObservation sosObservation) throws EncodingException {
ObservationValue> value = sosObservation.getValue();
// TODO if OM_SWEArrayObservation and ResultEncoding and ResultStructure exists,
if (value instanceof AbstractObservationValue) {
AbstractObservationValue> abstractObservationValue = (AbstractObservationValue>) value;
abstractObservationValue.setValuesForResultEncoding(sosObservation);
return encodeResult(abstractObservationValue);
}
return null;
}
@Override
protected XmlObject encodeResult(ObservationValue> observationValue) throws EncodingException {
if (observationValue instanceof SingleObservationValue) {
return createSingleObservationToResult((SingleObservationValue>) observationValue);
} else if (observationValue instanceof MultiObservationValues) {
return createMultiObservationValueToResult((MultiObservationValues>) observationValue);
}
return null;
}
@Override
protected void addObservationType(OMObservationType xbObservation, String observationType) {
if (!Strings.isNullOrEmpty(observationType)) {
xbObservation.addNewType().setHref(observationType);
}
}
// @Override
// public String getDefaultFeatureEncodingNamespace() {
// return SfConstants.NS_SAMS;
// }
@Override
protected String getDefaultProcedureEncodingNamspace() {
return SensorMLConstants.NS_SML;
}
@Override
protected boolean convertEncodedProcedure() {
return false;
}
@Override
protected void addAddtitionalInformation(OMObservationType omot, OmObservation observation)
throws EncodingException {
// do nothing
}
private OMObservationType encodeObservationTemplate(OmObservationConstellation observationTemplate)
throws EncodingException {
validateInput(observationTemplate);
OMObservationType xbObservationTemplate = createOmObservationType();
addGmlId(xbObservationTemplate);
addObservationType(xbObservationTemplate, observationTemplate.getObservationType());
addNilPhenomenonTime(xbObservationTemplate);
addNilResultTime(xbObservationTemplate);
addProcedure(xbObservationTemplate, observationTemplate.getNillableProcedure());
addObservedProperty(xbObservationTemplate, observationTemplate.getObservablePropertyIdentifier());
addFeature(xbObservationTemplate, observationTemplate.getNillableFeatureOfInterest());
addResult(xbObservationTemplate);
return xbObservationTemplate;
}
private void addResult(OMObservationType xbObservationTemplate) {
xbObservationTemplate.addNewResult();
}
private void addGmlId(OMObservationType xbObservationTemplate) {
xbObservationTemplate.setId(OBSERVATION_GML_ID_TEMPLATE);
}
private void addObservedProperty(OMObservationType xbObservationTemplate, String observablePropertyIdentifier) {
xbObservationTemplate.addNewObservedProperty().setHref(observablePropertyIdentifier);
}
private void addFeature(OMObservationType xbObservationTemplate,
Nillable featureOfInterest) throws EncodingException {
FeaturePropertyType xbFeatureOfInterest = xbObservationTemplate.addNewFeatureOfInterest();
if (featureOfInterest.isNil() || featureOfInterest.isAbsent()) {
xbFeatureOfInterest.setNilReason(NIL_REASON_TEMPLATE);
} else {
XmlObject xbEncodedFeature = encodeObjectToXmlPropertyType(
featureOfInterest.get().getDefaultElementEncoding(),
featureOfInterest.get(),
EncodingContext.empty());
xbFeatureOfInterest.set(xbEncodedFeature);
}
}
private void addProcedure(OMObservationType xbObservationTemplate, Nillable procedure) {
OMProcessPropertyType xbProcedure = xbObservationTemplate.addNewProcedure();
if (procedure.isNil() || procedure.isAbsent() || !procedure.get().isSetIdentifier()) {
xbProcedure.setNil();
xbProcedure.setNilReason(NIL_REASON_TEMPLATE);
} else {
xbProcedure.setHref(procedure.get().getIdentifier());
}
}
private void validateInput(OmObservationConstellation observationTemplate) throws UnsupportedEncoderInputException {
if (!observationTemplate.isSetObservationType() ||
observationTemplate.getObservationType().isEmpty()) {
throw new UnsupportedEncoderInputException(this, "missing type in OM_Observation");
}
}
private void addNilResultTime(OMObservationType xbObservationTemplate) {
TimeInstantPropertyType xbResultTime = xbObservationTemplate.addNewResultTime();
xbResultTime.setNilReason(NIL_REASON_TEMPLATE);
}
private void addNilPhenomenonTime(OMObservationType xbObservationTemplate) {
TimeObjectPropertyType xbPhenomenonTime = xbObservationTemplate.addNewPhenomenonTime();
xbPhenomenonTime.setNilReason(NIL_REASON_TEMPLATE);
}
private XmlObject createSingleObservationToResult(final SingleObservationValue> observationValue)
throws EncodingException {
final String observationType;
if (observationValue.isSetObservationType()) {
observationType = observationValue.getObservationType();
} else {
observationType = OMHelper.getObservationTypeFor(observationValue.getValue());
}
if (observationType.equals(OmConstants.OBS_TYPE_SWE_ARRAY_OBSERVATION)) {
SweDataArray dataArray = sweHelper.createSosSweDataArray(observationValue);
return encodeSWE(dataArray, EncodingContext.of(XmlBeansEncodingFlags.DOCUMENT));
}
return observationValue.getValue()
.accept(new ResultValueVisitor(observationType, observationValue.getObservationID()));
}
private XmlObject createMultiObservationValueToResult(MultiObservationValues> observationValue)
throws EncodingException {
SweDataArray dataArray = sweHelper.createSosSweDataArray(observationValue);
return encodeObjectToXml(SweConstants.NS_SWE_20, dataArray,
EncodingContext.of(XmlBeansEncodingFlags.DOCUMENT));
}
protected XmlString createXmlString() {
return XmlString.Factory.newInstance(getXmlOptions());
}
protected XmlInteger createXmlInteger() {
return XmlInteger.Factory.newInstance(getXmlOptions());
}
protected XmlBoolean createXmlBoolean() {
return XmlBoolean.Factory.newInstance(getXmlOptions());
}
protected XmlObject encodeSWE(Object o) throws EncodingException {
return encodeObjectToXml(SweConstants.NS_SWE_20, o);
}
protected XmlObject encodeSWE(Object o, EncodingContext additionalValues) throws EncodingException {
return encodeObjectToXml(SweConstants.NS_SWE_20, o, additionalValues);
}
private class ResultValueVisitor
implements ValueVisitor {
private final String observationType;
private final String observationId;
ResultValueVisitor(String observationType, String observationId) {
this.observationType = observationType;
this.observationId = observationId;
}
@Override
public XmlObject visit(BooleanValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_TRUTH_OBSERVATION)) {
XmlBoolean xbBoolean = createXmlBoolean();
if (value.isSetValue()) {
xbBoolean.setBooleanValue(value.getValue());
} else {
xbBoolean.setNil();
}
return xbBoolean;
} else {
return null;
}
}
@Override
public XmlObject visit(CategoryValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_CATEGORY_OBSERVATION)) {
if (value.isSetValue() && !value.getValue().isEmpty()) {
return encodeGML(value, EncodingContext.of(XmlBeansEncodingFlags.GMLID,
SosConstants.OBS_ID_PREFIX + observationId));
}
}
return null;
}
@Override
public XmlObject visit(ComplexValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_COMPLEX_OBSERVATION)) {
if (value.isSetValue()) {
return encodeSWE(value.getValue(), EncodingContext.of(XmlBeansEncodingFlags.FOR_OBSERVATION));
}
}
return null;
}
@Override
public XmlObject visit(CountValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_COUNT_OBSERVATION)) {
XmlInteger xbInteger = createXmlInteger();
if (value.isSetValue() && value.getValue() != Integer.MIN_VALUE) {
xbInteger.setBigIntegerValue(new BigInteger(value.getValue().toString()));
} else {
xbInteger.setNil();
}
return xbInteger;
} else {
return null;
}
}
@Override
public XmlObject visit(GeometryValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_GEOMETRY_OBSERVATION)) {
if (value.isSetValue()) {
return encodeGML(value.getValue(),
EncodingContext.empty()
.with(XmlBeansEncodingFlags.GMLID, SosConstants.OBS_ID_PREFIX + observationId)
.with(XmlBeansEncodingFlags.PROPERTY_TYPE));
} else {
return null;
}
} else {
return null;
}
}
@Override
public XmlObject visit(HrefAttributeValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(NilTemplateValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(QuantityValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_MEASUREMENT) ||
observationType.equals(WaterMLConstants.OBSERVATION_TYPE_MEASURMENT_TVP) ||
observationType.equals(WaterMLConstants.OBSERVATION_TYPE_MEASURMENT_TDR)) {
if (value.isSetValue()) {
return encodeGML(value);
}
}
return null;
}
@Override
public XmlObject visit(QuantityRangeValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(ReferenceValue value) throws EncodingException {
if (value.isSetValue()) {
return encodeGML(value.getValue());
}
return null;
}
@Override
public XmlObject visit(SweDataArrayValue value) throws EncodingException {
return encodeSWE(value.getValue(), EncodingContext.of(XmlBeansEncodingFlags.FOR_OBSERVATION));
}
@Override
public XmlObject visit(TVPValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(TextValue value) throws EncodingException {
if (observationType.equals(OmConstants.OBS_TYPE_TEXT_OBSERVATION)) {
XmlString xbString = createXmlString();
if (value.isSetValue()) {
xbString.setStringValue(value.getValue());
} else {
xbString.setNil();
}
return xbString;
} else {
return null;
}
}
@Override
public XmlObject visit(UnknownValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(TLVTValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(CvDiscretePointCoverage value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(MultiPointCoverage value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(RectifiedGridCoverage value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(ProfileValue value) throws EncodingException {
return encodeGWML(value, EncodingContext.of(XmlBeansEncodingFlags.FOR_OBSERVATION));
}
@Override
public XmlObject visit(TimeRangeValue value) throws EncodingException {
return null;
}
@Override
public XmlObject visit(XmlValue> value) throws EncodingException {
if (value.getValue() instanceof XmlObject) {
return (XmlObject) value.getValue();
}
return null;
}
}
}