/** * Copyright (C) 2012-2017 52°North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * If the program is linked with libraries which are licensed under one of * the following licenses, the combination of the program with the linked * library is not considered a "derivative work" of the program: * * - Apache License, version 2.0 * - Apache Software License, version 1.0 * - GNU Lesser General Public License, version 3 * - Mozilla Public License, versions 1.0, 1.1 and 2.0 * - Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed * under the aforementioned licenses, is permitted by the copyright holders * if the distribution is compliant with both the GNU General Public * License version 2 and the aforementioned licenses. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ package org.n52.sos.encode; import static org.n52.sos.util.http.HTTPStatus.BAD_REQUEST; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import net.opengis.gml.StringOrRefType; import net.opengis.swe.x101.AbstractDataComponentType; import net.opengis.swe.x101.AbstractEncodingType; import net.opengis.swe.x101.AnyScalarPropertyType; import net.opengis.swe.x101.BlockEncodingPropertyType; import net.opengis.swe.x101.CategoryDocument.Category; import net.opengis.swe.x101.CountDocument.Count; import net.opengis.swe.x101.DataArrayDocument; import net.opengis.swe.x101.DataArrayType; import net.opengis.swe.x101.DataComponentPropertyType; import net.opengis.swe.x101.DataRecordDocument; import net.opengis.swe.x101.DataRecordType; import net.opengis.swe.x101.EnvelopeType; import net.opengis.swe.x101.ObservablePropertyDocument.ObservableProperty; import net.opengis.swe.x101.QualityPropertyType; import net.opengis.swe.x101.QuantityDocument.Quantity; import net.opengis.swe.x101.QuantityRangeDocument.QuantityRange; import net.opengis.swe.x101.SimpleDataRecordType; import net.opengis.swe.x101.TextBlockDocument.TextBlock; import net.opengis.swe.x101.TextDocument.Text; import net.opengis.swe.x101.TimeDocument.Time; import net.opengis.swe.x101.TimeGeometricPrimitivePropertyType; import net.opengis.swe.x101.TimeRangeDocument.TimeRange; import net.opengis.swe.x101.UomPropertyType; import net.opengis.swe.x101.VectorPropertyType; import net.opengis.swe.x101.VectorType; import net.opengis.swe.x101.VectorType.Coordinate; import org.apache.xmlbeans.GDateBuilder; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlDateTime; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlString; import org.apache.xmlbeans.impl.values.XmlValueDisconnectedException; import org.joda.time.DateTime; import org.n52.sos.exception.ows.NoApplicableCodeException; import org.n52.sos.exception.ows.concrete.NotYetSupportedException; import org.n52.sos.exception.ows.concrete.UnsupportedEncoderInputException; import org.n52.sos.ogc.gml.GmlConstants; import org.n52.sos.ogc.gml.time.TimePeriod; import org.n52.sos.ogc.ows.OwsExceptionReport; import org.n52.sos.ogc.sos.SosConstants.HelperValues; import org.n52.sos.ogc.swe.SweAbstractDataComponent; import org.n52.sos.ogc.swe.SweConstants; import org.n52.sos.ogc.swe.SweCoordinate; import org.n52.sos.ogc.swe.SweDataArray; import org.n52.sos.ogc.swe.SweDataRecord; import org.n52.sos.ogc.swe.SweEnvelope; import org.n52.sos.ogc.swe.SweField; import org.n52.sos.ogc.swe.SweSimpleDataRecord; import org.n52.sos.ogc.swe.SweVector; import org.n52.sos.ogc.swe.encoding.SweAbstractEncoding; import org.n52.sos.ogc.swe.encoding.SweTextEncoding; import org.n52.sos.ogc.swe.simpleType.SweAbstractSimpleType; import org.n52.sos.ogc.swe.simpleType.SweBoolean; import org.n52.sos.ogc.swe.simpleType.SweCategory; import org.n52.sos.ogc.swe.simpleType.SweCount; import org.n52.sos.ogc.swe.simpleType.SweObservableProperty; import org.n52.sos.ogc.swe.simpleType.SweQuality; import org.n52.sos.ogc.swe.simpleType.SweQuantity; import org.n52.sos.ogc.swe.simpleType.SweQuantityRange; import org.n52.sos.ogc.swe.simpleType.SweText; import org.n52.sos.ogc.swe.simpleType.SweTime; import org.n52.sos.ogc.swe.simpleType.SweTimeRange; import org.n52.sos.util.CodingHelper; import org.n52.sos.util.XmlHelper; import org.n52.sos.util.XmlOptionsHelper; import org.n52.sos.w3c.SchemaLocation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * Encoder class for SWE Common 1.0.1 * * @since 4.0.0 */ public class SweCommonEncoderv101 extends AbstractXmlEncoder<Object> { private static final Logger LOGGER = LoggerFactory.getLogger(SweCommonEncoderv101.class); private static final Set<EncoderKey> ENCODER_KEYS = CodingHelper.encoderKeysForElements(SweConstants.NS_SWE_101, SweBoolean.class, SweCategory.class, SweCount.class, SweObservableProperty.class, SweQuantity.class, SweQuantityRange.class, SweText.class, SweTime.class, SweTimeRange.class, SweEnvelope.class, SweCoordinate.class, SweDataArray.class, SweDataRecord.class, SweSimpleDataRecord.class, TimePeriod.class); public SweCommonEncoderv101() { LOGGER.debug("Encoder for the following keys initialized successfully: {}!", Joiner.on(", ") .join(ENCODER_KEYS)); } @Override public Set<EncoderKey> getEncoderKeyType() { return Collections.unmodifiableSet(ENCODER_KEYS); } @Override public void addNamespacePrefixToMap(final Map<String, String> nameSpacePrefixMap) { nameSpacePrefixMap.put(SweConstants.NS_SWE_101, SweConstants.NS_SWE_PREFIX); } @Override public Set<SchemaLocation> getSchemaLocations() { return Sets.newHashSet(SweConstants.SWE_101_SCHEMA_LOCATION); } @Override public XmlObject encode(final Object element, final Map<HelperValues, String> additionalValues) throws OwsExceptionReport { XmlObject encodedObject = null; if (element instanceof SweAbstractSimpleType) { encodedObject = createSimpleType((SweAbstractSimpleType<?>)element, additionalValues); // } // if (element instanceof SweBoolean) { // encodedObject = createBoolean((SweBoolean) element); // } else if (element instanceof SweCategory) { // encodedObject = createCategory((SweCategory) element); // } else if (element instanceof SweCount) { // encodedObject = createCount((SweCount) element); // } else if (element instanceof SweObservableProperty) { // encodedObject = createObservableProperty((SweObservableProperty) element); // } else if (element instanceof SweQuantity) { // encodedObject = createQuantity((SweQuantity) element); // } else if (element instanceof SweQuantityRange) { // encodedObject = createQuantityRange((SweQuantityRange) element); // } else if (element instanceof SweText) { // encodedObject = createText((SweText) element); // } else if (element instanceof SweTime) { // encodedObject = createTime((SweTime) element); // } else if (element instanceof SweTimeRange) { // encodedObject = createTimeRange((SweTimeRange) element); } else if (element instanceof SweCoordinate) { encodedObject = createCoordinate((SweCoordinate<?>) element); } else if (element instanceof SweDataArray) { encodedObject = createDataArray((SweDataArray) element); } else if (element instanceof SweDataRecord) { DataRecordType drt = createDataRecord((SweDataRecord) element); if (additionalValues.containsKey(HelperValues.DOCUMENT)) { DataRecordDocument drd = DataRecordDocument.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); drd.setDataRecord(drt); encodedObject = drd; } else { encodedObject = drt; } } else if (element instanceof SweEnvelope) { encodedObject = createEnvelope((SweEnvelope) element); } else if (element instanceof SweSimpleDataRecord) { encodedObject = createSimpleDataRecord((SweSimpleDataRecord) element); } else if (element instanceof TimePeriod) { encodedObject = createTimeGeometricPrimitivePropertyType((TimePeriod) element); } else { throw new UnsupportedEncoderInputException(this, element); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Encoded object {} is valid: {}", encodedObject.schemaType().toString(), XmlHelper.validateDocument(encodedObject)); } return encodedObject; } private AbstractDataComponentType createSimpleType(final SweAbstractSimpleType<?> sosSimpleType) throws OwsExceptionReport { return createSimpleType(sosSimpleType, null); } private AbstractDataComponentType createSimpleType(final SweAbstractSimpleType<?> sosSimpleType, Map<HelperValues, String> additionalValues) throws OwsExceptionReport { AbstractDataComponentType abstractDataComponentType = null; if (sosSimpleType instanceof SweBoolean) { abstractDataComponentType = createBoolean((SweBoolean) sosSimpleType); } else if (sosSimpleType instanceof SweCategory) { abstractDataComponentType = createCategory((SweCategory) sosSimpleType); } else if (sosSimpleType instanceof SweCount) { abstractDataComponentType = createCount((SweCount) sosSimpleType); } else if (sosSimpleType instanceof SweObservableProperty) { abstractDataComponentType = createObservableProperty((SweObservableProperty) sosSimpleType); } else if (sosSimpleType instanceof SweQuantity) { abstractDataComponentType = createQuantity((SweQuantity) sosSimpleType); } else if (sosSimpleType instanceof SweQuantityRange) { abstractDataComponentType = createQuantityRange((SweQuantityRange) sosSimpleType); } else if (sosSimpleType instanceof SweText) { abstractDataComponentType = createText((SweText) sosSimpleType); } else if (sosSimpleType instanceof SweTimeRange) { abstractDataComponentType = createTimeRange((SweTimeRange) sosSimpleType); } else if (sosSimpleType instanceof SweTime) { abstractDataComponentType = createTime((SweTime) sosSimpleType); } else { throw new NotYetSupportedException(SweAbstractSimpleType.class.getSimpleName(), sosSimpleType); } addAbstractDataComponentValues(abstractDataComponentType, sosSimpleType); return abstractDataComponentType; } private SimpleDataRecordType createSimpleDataRecord(final SweSimpleDataRecord simpleDataRecord) throws OwsExceptionReport { final SimpleDataRecordType xbSimpleDataRecord = SimpleDataRecordType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (simpleDataRecord.isSetDefinition()) { xbSimpleDataRecord.setDefinition(simpleDataRecord.getDefinition()); } if (simpleDataRecord.isSetDescription()) { final StringOrRefType xbSoR = StringOrRefType.Factory.newInstance(); xbSoR.setStringValue(simpleDataRecord.getDefinition()); xbSimpleDataRecord.setDescription(xbSoR); } if (simpleDataRecord.isSetFields()) { final AnyScalarPropertyType[] xbFields = new AnyScalarPropertyType[simpleDataRecord.getFields().size()]; int xbFieldIndex = 0; for (final SweField sweField : simpleDataRecord.getFields()) { final AnyScalarPropertyType xbField = createFieldForSimpleDataRecord(sweField); xbFields[xbFieldIndex] = xbField; xbFieldIndex++; } xbSimpleDataRecord.setFieldArray(xbFields); } return xbSimpleDataRecord; } private AnyScalarPropertyType createFieldForSimpleDataRecord(final SweField sweField) throws OwsExceptionReport { final SweAbstractDataComponent sosElement = sweField.getElement(); final AnyScalarPropertyType xbField = AnyScalarPropertyType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (sweField.isSetName()) { xbField.setName(sweField.getName().getValue()); } final AbstractDataComponentType xbDCD; if (sosElement instanceof SweBoolean) { xbDCD = xbField.addNewBoolean(); xbDCD.set(createSimpleType((SweBoolean) sosElement)); } else if (sosElement instanceof SweCategory) { xbDCD = xbField.addNewCategory(); xbDCD.set(createSimpleType((SweCategory) sosElement)); } else if (sosElement instanceof SweCount) { xbDCD = xbField.addNewCount(); xbDCD.set(createSimpleType((SweCount) sosElement)); } else if (sosElement instanceof SweQuantity) { xbDCD = xbField.addNewQuantity(); xbDCD.set(createSimpleType((SweQuantity) sosElement)); } else if (sosElement instanceof SweText) { xbDCD = xbField.addNewText(); xbDCD.set(createSimpleType((SweText) sosElement)); } else if (sosElement instanceof SweTime) { xbDCD = xbField.addNewTime(); xbDCD.set(createSimpleType((SweTime) sosElement)); } else { throw new NoApplicableCodeException().withMessage( "The element type '%s' of the received %s is not supported by this encoder '%s'.", sosElement != null ? sosElement.getClass().getName() : null, sweField.getClass().getName(), getClass().getName()).setStatus(BAD_REQUEST); } return xbField; } private DataComponentPropertyType createField(final SweField sweField) throws OwsExceptionReport { final SweAbstractDataComponent sosElement = sweField.getElement(); final DataComponentPropertyType xbField = DataComponentPropertyType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (sweField.isSetName()) { xbField.setName(sweField.getName().getValue()); } if (sosElement instanceof SweBoolean) { xbField.addNewBoolean().set(createSimpleType((SweBoolean) sosElement)); } else if (sosElement instanceof SweCategory) { xbField.addNewCategory().set(createSimpleType((SweCategory) sosElement)); } else if (sosElement instanceof SweCount) { xbField.addNewCount().set(createSimpleType((SweCount) sosElement)); } else if (sosElement instanceof SweQuantity) { xbField.addNewQuantity().set(createSimpleType((SweQuantity) sosElement)); } else if (sosElement instanceof SweText) { xbField.addNewText().set(createSimpleType((SweText) sosElement)); } else if (sosElement instanceof SweTimeRange) { xbField.addNewTimeRange().set(createSimpleType((SweTimeRange) sosElement)); } else if (sosElement instanceof SweTime) { xbField.addNewTime().set(createSimpleType((SweTime) sosElement)); } else if (sosElement instanceof SweEnvelope) { final EnvelopeType xbEnvelope = (EnvelopeType) xbField.addNewAbstractDataRecord() .substitute(SweConstants.QN_ENVELOPE_SWE_101, EnvelopeType.type); xbEnvelope.set(createEnvelope((SweEnvelope) sosElement)); } else if (sosElement instanceof SweDataRecord) { final DataRecordType drt = (DataRecordType) xbField.addNewAbstractDataRecord() .substitute(SweConstants.QN_DATA_RECORD_SWE_101, DataRecordType.type); drt.set(createDataRecord((SweDataRecord) sosElement)); } else if (sosElement instanceof SweDataArray) { final DataArrayType dat = (DataArrayType) xbField.addNewAbstractDataRecord() .substitute(SweConstants.QN_DATA_RECORD_SWE_101, DataArrayType.type); dat.set(createDataArray((SweDataArray) sosElement).getDataArray1()); } else { throw new NoApplicableCodeException().withMessage( "The element type '%s' of the received '%s' is not supported by this encoder '%s'.", sosElement != null ? sosElement.getClass().getName() : null, sweField.getClass().getName(), getClass().getName()).setStatus(BAD_REQUEST); } return xbField; } private net.opengis.swe.x101.BooleanDocument.Boolean createBoolean(final SweBoolean bool) throws OwsExceptionReport { final net.opengis.swe.x101.BooleanDocument.Boolean xbBoolean = net.opengis.swe.x101.BooleanDocument.Boolean.Factory.newInstance(XmlOptionsHelper.getInstance() .getXmlOptions()); if (bool.isSetValue()) { xbBoolean.setValue(bool.getValue().booleanValue()); } if (bool.isSetQuality()) { xbBoolean.setQuality(createQuality(bool.getQuality())[0]); } return xbBoolean; } private QualityPropertyType[] createQuality(final Collection<SweQuality> quality) throws OwsExceptionReport { if (!quality.isEmpty()) { final ArrayList<QualityPropertyType> xbQualities = Lists.newArrayListWithCapacity(quality.size()); for (final SweQuality sweQuality : quality) { final QualityPropertyType xbQuality = QualityPropertyType.Factory.newInstance(); if (sweQuality instanceof SweText) { xbQuality.addNewText().set(createText((SweText) sweQuality)); } else if (sweQuality instanceof SweCategory) { xbQuality.addNewCategory().set(createCategory((SweCategory) sweQuality)); } else if (sweQuality instanceof SweQuantity) { xbQuality.addNewQuantity().set(createQuantity((SweQuantity) sweQuality)); } else if (sweQuality instanceof SweQuantityRange) { xbQuality.addNewQuantityRange().set(createQuantityRange((SweQuantityRange) sweQuality)); } xbQualities.add(xbQuality); } return xbQualities.toArray(new QualityPropertyType[xbQualities.size()]); } final QualityPropertyType[] result = {QualityPropertyType.Factory.newInstance()}; return result; } private Category createCategory(final SweCategory category) throws OwsExceptionReport { final Category xbCategory = Category.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (category.isSetValue()) { xbCategory.setValue(category.getValue()); } if (category.isSetCodeSpace()) { xbCategory.addNewCodeSpace().setHref(category.getCodeSpace()); } if (category.isSetQuality()) { xbCategory.setQuality(createQuality(category.getQuality())[0]); } return xbCategory; } private Count createCount(final SweCount count) throws OwsExceptionReport { final Count xbCount = Count.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (count.isSetValue()) { xbCount.setValue(new BigInteger(Integer.toString(count.getValue().intValue()))); } if (count.isSetQuality()) { xbCount.setQualityArray(createQuality(count.getQuality())); } return xbCount; } private ObservableProperty createObservableProperty(final SweObservableProperty observableProperty) throws OwsExceptionReport { final ObservableProperty xbObservableProperty = ObservableProperty.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); return xbObservableProperty; } /** * Adds values to SWE quantity * * @param quantity * SOS internal representation * @throws OwsExceptionReport */ protected Quantity createQuantity(final SweQuantity quantity) throws OwsExceptionReport { final Quantity xbQuantity = Quantity.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (quantity.isSetAxisID()) { xbQuantity.setAxisID(quantity.getAxisID()); } if (quantity.isSetValue()) { xbQuantity.setValue(Double.valueOf(quantity.getValue())); } if (quantity.isSetUom()) { xbQuantity.addNewUom().set(createUom(quantity.getUom())); } if (quantity.isSetQuality()) { xbQuantity.setQualityArray(createQuality(quantity.getQuality())); } return xbQuantity; } protected QuantityRange createQuantityRange(final SweQuantityRange quantityRange) throws OwsExceptionReport { final QuantityRange xbQuantityRange = QuantityRange.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (quantityRange.isSetAxisID()) { xbQuantityRange.setAxisID(quantityRange.getDescription()); } if (quantityRange.isSetValue()) { xbQuantityRange.setValue(quantityRange.getValue().getRangeAsList()); } if (quantityRange.isSetUom()) { xbQuantityRange.addNewUom().set(createUom(quantityRange.getUom())); } if (quantityRange.isSetQuality()) { xbQuantityRange.setQualityArray(createQuality(quantityRange.getQuality())); } return xbQuantityRange; } /** * Adds values to SWE text * * @param text * SOS internal representation * @throws OwsExceptionReport */ private Text createText(final SweText text) throws OwsExceptionReport { final Text xbText = Text.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (text.isSetValue()) { xbText.setValue(text.getValue()); } return xbText; } private Time createTime(final SweTime time) throws OwsExceptionReport { final Time xbTime = Time.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (time.isSetValue()) { final XmlDateTime xbDateTime = createDateTime(time.getValue()); xbTime.setValue(xbDateTime); } if (time.isSetUom()) { if (time.getUom().startsWith("urn:") || time.getUom().startsWith("http://")) { xbTime.addNewUom().setHref(time.getUom()); } else { xbTime.addNewUom().setCode(time.getUom()); } } if (time.isSetQuality()) { xbTime.setQuality(createQuality(time.getQuality())[0]); } return xbTime; } private XmlDateTime createDateTime(final DateTime sosDateTime) { final XmlDateTime xbDateTime = XmlDateTime.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); //encode the DateTime in UTC final GDateBuilder gdb = new GDateBuilder(sosDateTime.toDate()); gdb.normalize(); xbDateTime.setGDateValue(gdb.toGDate()); return xbDateTime; } private EnvelopeType createEnvelope(final SweEnvelope sosSweEnvelope) throws OwsExceptionReport { final EnvelopeType envelopeType = EnvelopeType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); addAbstractDataComponentValues(envelopeType, sosSweEnvelope); if (sosSweEnvelope.isReferenceFrameSet()) { envelopeType.setReferenceFrame(sosSweEnvelope.getReferenceFrame()); } if (sosSweEnvelope.isLowerCornerSet()) { envelopeType.setLowerCorner(createVectorProperty(sosSweEnvelope.getLowerCorner())); } if (sosSweEnvelope.isUpperCornerSet()) { envelopeType.setUpperCorner(createVectorProperty(sosSweEnvelope.getUpperCorner())); } if (sosSweEnvelope.isTimeSet()) { envelopeType.addNewTime().setTimeRange(createTimeRange(sosSweEnvelope.getTime())); } return envelopeType; } private VectorPropertyType createVectorProperty(final SweVector sosSweVector) throws OwsExceptionReport { final VectorPropertyType vectorPropertyType = VectorPropertyType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); vectorPropertyType.setVector(createVector(sosSweVector.getCoordinates())); return vectorPropertyType; } private VectorType createVector(final List<SweCoordinate<?>> coordinates) throws OwsExceptionReport { final VectorType vectorType = VectorType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); vectorType.setCoordinateArray(createCoordinates(coordinates)); return vectorType; } private TimeRange createTimeRange(final SweTimeRange timeRange) throws OwsExceptionReport { final TimeRange xbTimeRange = TimeRange.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); addAbstractDataComponentValues(xbTimeRange, timeRange); if (timeRange.isSetValue()) { xbTimeRange.setValue(timeRange.getValue().getRangeAsStringList()); } if (timeRange.isSetUom()) { xbTimeRange.addNewUom().setCode(timeRange.getUom()); } if (timeRange.isSetQuality()) { xbTimeRange.setQuality(createQuality(timeRange.getQuality())[0]); } return xbTimeRange; } private void addAbstractDataComponentValues(final AbstractDataComponentType xbComponent, final SweAbstractDataComponent component) throws OwsExceptionReport { if (component.isSetDefinition()) { xbComponent.setDefinition(component.getDefinition()); } if (component.isSetDescription()) { xbComponent.addNewDescription().setStringValue(component.getDescription()); } if (component.isSetName()) { xbComponent.addNewName().set(CodingHelper.encodeObjectToXml(GmlConstants.NS_GML, component.getName())); } } /** * Adds values to SWE coordinates * * @param coordinate * SOS internal representation * @throws OwsExceptionReport */ private Coordinate createCoordinate(final SweCoordinate<?> coordinate) throws OwsExceptionReport { final Coordinate xbCoordinate = Coordinate.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); xbCoordinate.setName(coordinate.getName()); xbCoordinate.setQuantity(createQuantity((SweQuantity) coordinate.getValue())); return xbCoordinate; } /** * Adds values to SWE coordinates * * @param coordinates * SOS internal representation * @throws OwsExceptionReport */ private Coordinate[] createCoordinates(final List<SweCoordinate<?>> coordinates) throws OwsExceptionReport { if (coordinates != null) { final ArrayList<Coordinate> xbCoordinates = new ArrayList<Coordinate>(coordinates.size()); for (final SweCoordinate<?> coordinate : coordinates) { xbCoordinates.add(createCoordinate(coordinate)); } return xbCoordinates.toArray(new Coordinate[xbCoordinates.size()]); } return null; } // TODO check types for SWE101 private DataRecordType createDataRecord(final SweDataRecord sosDataRecord) throws OwsExceptionReport { final List<SweField> sosFields = sosDataRecord.getFields(); final DataRecordType xbDataRecord = DataRecordType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (sosDataRecord.isSetDefinition()) { xbDataRecord.setDefinition(sosDataRecord.getDefinition()); } if (sosDataRecord.isSetFields()) { final DataComponentPropertyType[] xbFields = new DataComponentPropertyType[sosFields.size()]; int xbFieldIndex = 0; for (final SweField sosSweField : sosFields) { final DataComponentPropertyType xbField = createField(sosSweField); xbFields[xbFieldIndex] = xbField; xbFieldIndex++; } xbDataRecord.setFieldArray(xbFields); } return xbDataRecord; } private DataArrayDocument createDataArray(final SweDataArray sosDataArray) throws OwsExceptionReport { if (sosDataArray != null) { if (sosDataArray.isSetElementTyp()) { final DataArrayDocument xbDataArrayDoc = DataArrayDocument.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); final DataArrayType xbDataArray = xbDataArrayDoc.addNewDataArray1(); // set element count if (sosDataArray.isSetElementCount()) { xbDataArray.addNewElementCount().addNewCount().set(createCount(sosDataArray.getElementCount())); } if (sosDataArray.isSetElementTyp()) { final DataComponentPropertyType xbElementType = xbDataArray.addNewElementType(); xbElementType.setName("Components"); if (sosDataArray.getElementType() instanceof SweBoolean) { xbElementType.addNewBoolean().set(createSimpleType((SweBoolean)sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof Category) { xbElementType.addNewCategory().set(createSimpleType((SweCategory) sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof SweCount) { xbElementType.addNewCount().set(createSimpleType((SweCount) sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof SweQuantity) { xbElementType.addNewQuantity().set(createSimpleType((SweQuantity) sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof SweText) { xbElementType.addNewText().set(createSimpleType((SweText) sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof SweTimeRange) { xbElementType.addNewTimeRange().set(createSimpleType((SweTimeRange) sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof SweTime) { xbElementType.addNewTime().set(createSimpleType((SweTime) sosDataArray.getElementType())); } else if (sosDataArray.getElementType() instanceof SweEnvelope) { xbElementType.addNewAbstractDataRecord().set(createEnvelope((SweEnvelope) sosDataArray.getElementType())); xbElementType.getAbstractDataRecord().substitute(SweConstants.QN_ENVELOPE_SWE_101, EnvelopeType.type); } else if (sosDataArray.getElementType() instanceof SweDataRecord) { xbElementType.addNewAbstractDataRecord().set(createDataRecord((SweDataRecord) sosDataArray.getElementType())); xbElementType.getAbstractDataRecord().substitute(SweConstants.QN_DATA_RECORD_SWE_101, DataRecordType.type); } else if (sosDataArray.getElementType() instanceof SweDataArray) { xbElementType.addNewAbstractDataArray1().set(createDataArray((SweDataArray) sosDataArray.getElementType()).getDataArray1()); xbElementType.getAbstractDataArray1().substitute(SweConstants.QN_DATA_RECORD_SWE_101, DataArrayType.type); } else { throw new NoApplicableCodeException().withMessage( "The element type '%s' of the received '%s' is not supported by this encoder '%s'.", sosDataArray.getElementType() != null ? sosDataArray.getElementType().getClass().getName() : null, xbElementType.getClass().getName(), getClass().getName()).setStatus(BAD_REQUEST); } } if (sosDataArray.isSetEncoding()) { final BlockEncodingPropertyType xbEncoding = xbDataArray.addNewEncoding(); xbEncoding.set(createBlockEncoding(sosDataArray.getEncoding())); // xbDataArray.getEncoding().substitute( // new QName(SWEConstants.NS_SWE_101, // SWEConstants.EN_TEXT_ENCODING, // SWEConstants.NS_SWE_PREFIX), TextBlock.type); } // if (absObs.getObservationTemplateIDs() == null // || (absObs.getObservationTemplateIDs() != null && // absObs.getObservationTemplateIDs().isEmpty())) { // xbValues.newCursor().setTextValue(createResultString(phenComponents, // absObs)); // } if (sosDataArray.isSetValues()) { xbDataArray.addNewValues().set(createValues(sosDataArray.getValues(), sosDataArray.getEncoding())); } return xbDataArrayDoc; } else if (sosDataArray.isSetXml()) { try { XmlObject xmlObject = XmlObject.Factory.parse(sosDataArray.getXml().trim()); if (xmlObject instanceof DataArrayDocument) { return (DataArrayDocument)xmlObject; } else { DataArrayDocument xbDataArrayDoc = DataArrayDocument.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); xbDataArrayDoc.setDataArray1(DataArrayType.Factory.parse(sosDataArray.getXml().trim())); return xbDataArrayDoc; } } catch (XmlException e) { throw new NoApplicableCodeException().causedBy(e).withMessage("Error while encoding SweDataArray!"); } } } return null; } private XmlString createValues(final List<List<String>> values, final SweAbstractEncoding encoding) { // TODO How to deal with the decimal separator - is it an issue here? final StringBuilder valueStringBuilder = new StringBuilder(256); final SweTextEncoding textEncoding = (SweTextEncoding) encoding; // would also work, hmm // Configurator.getInstance().getDecimalSeparator(); final String tokenSeparator = textEncoding.getTokenSeparator(); final String blockSeparator = textEncoding.getBlockSeparator(); for (final List<String> block : values) { final StringBuilder blockStringBuilder = new StringBuilder(); for (final String token : block) { blockStringBuilder.append(token); blockStringBuilder.append(tokenSeparator); } String blockString = blockStringBuilder.toString(); // remove last token sep blockString = blockString.substring(0, blockString.lastIndexOf(tokenSeparator)); valueStringBuilder.append(blockString); valueStringBuilder.append(blockSeparator); } String valueString = valueStringBuilder.toString(); // remove last block sep valueString = valueString.substring(0, valueString.lastIndexOf(blockSeparator)); // create XB result object final XmlString xbValueString = XmlString.Factory.newInstance(); xbValueString.setStringValue(valueString); return xbValueString; } private BlockEncodingPropertyType createBlockEncoding(final SweAbstractEncoding sosSweAbstractEncoding) throws OwsExceptionReport { try { if (sosSweAbstractEncoding instanceof SweTextEncoding) { return createTextEncoding((SweTextEncoding) sosSweAbstractEncoding); } if (sosSweAbstractEncoding.getXml() != null && !sosSweAbstractEncoding.getXml().isEmpty()) { final XmlObject xmlObject = XmlObject.Factory.parse(sosSweAbstractEncoding.getXml()); if (xmlObject instanceof AbstractEncodingType) { return (BlockEncodingPropertyType) xmlObject; } throw new NoApplicableCodeException().withMessage("AbstractEncoding can not be encoded!"); } } catch (final XmlException e) { throw new NoApplicableCodeException().causedBy(e).withMessage("Error while encoding AbstractEncoding!"); } catch (final XmlValueDisconnectedException xvde) { throw new NoApplicableCodeException().causedBy(xvde).withMessage("Error while encoding AbstractEncoding!"); } catch (final Exception ge) { throw new NoApplicableCodeException().causedBy(ge).withMessage("Error while encoding AbstractEncoding!"); } return null; } private BlockEncodingPropertyType createTextEncoding(final SweTextEncoding sosTextEncoding) { final BlockEncodingPropertyType xbTextEncodingType = BlockEncodingPropertyType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); final TextBlock xbTextEncoding = xbTextEncodingType.addNewTextBlock(); if (sosTextEncoding.getBlockSeparator() != null) { xbTextEncoding.setBlockSeparator(sosTextEncoding.getBlockSeparator()); } // TODO check not used in SWE101 // if (sosTextEncoding.isSetCollapseWhiteSpaces()) { // xbTextEncoding.setCollapseWhiteSpaces(sosTextEncoding.isCollapseWhiteSpaces()); // } if (sosTextEncoding.getDecimalSeparator() != null) { xbTextEncoding.setDecimalSeparator(sosTextEncoding.getDecimalSeparator()); } if (sosTextEncoding.getTokenSeparator() != null) { xbTextEncoding.setTokenSeparator(sosTextEncoding.getTokenSeparator()); } // wont cast !!! net.opengis.swe.x101.impl.BlockEncodingPropertyTypeImpl // cannot be cast to net.opengis.swe.x101.AbstractEncodingType return xbTextEncodingType; } private XmlObject createTimeGeometricPrimitivePropertyType(final TimePeriod timePeriod) throws OwsExceptionReport { final TimeGeometricPrimitivePropertyType xbTimeGeometricPrimitiveProperty = TimeGeometricPrimitivePropertyType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (timePeriod.isSetStart() && timePeriod.isSetEnd()) { xbTimeGeometricPrimitiveProperty.addNewTimeGeometricPrimitive().set( CodingHelper.encodeObjectToXml(GmlConstants.NS_GML, timePeriod)); } // TODO check GML 311 rename nodename of geometric primitive to // gml:timePeriod final XmlCursor timeCursor = xbTimeGeometricPrimitiveProperty.newCursor(); final boolean hasTimePrimitive = timeCursor.toChild(new QName(GmlConstants.NS_GML, GmlConstants.EN_ABSTRACT_TIME_GEOM_PRIM)); if (hasTimePrimitive) { timeCursor.setName(new QName(GmlConstants.NS_GML, GmlConstants.EN_TIME_PERIOD)); } timeCursor.dispose(); return xbTimeGeometricPrimitiveProperty; } private UomPropertyType createUom(final String uom) { final UomPropertyType xbUom = UomPropertyType.Factory.newInstance(XmlOptionsHelper.getInstance().getXmlOptions()); if (uom.startsWith("urn:") || uom.startsWith("http://")) { xbUom.setHref(uom); } else { xbUom.setCode(uom); } return xbUom; } }