/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.teiid.olingo.common;
import java.util.Collections;
import java.util.Iterator;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.geo.Geospatial;
import org.apache.olingo.commons.api.edm.geo.GeospatialCollection;
import org.apache.olingo.commons.api.edm.geo.LineString;
import org.apache.olingo.commons.api.edm.geo.MultiLineString;
import org.apache.olingo.commons.api.edm.geo.MultiPoint;
import org.apache.olingo.commons.api.edm.geo.MultiPolygon;
import org.apache.olingo.commons.api.edm.geo.Point;
import org.apache.olingo.commons.api.edm.geo.Polygon;
import org.apache.olingo.commons.core.edm.primitivetype.EdmDouble;
/**
* Taken from org.apache.olingo.client.core.serialization to avoid the dependency on olingo client
*/
class AtomGeoValueSerializer {
private void points(final XMLStreamWriter writer, final Iterator<Point> itor, final boolean wrap)
throws XMLStreamException {
while (itor.hasNext()) {
final Point point = itor.next();
if (wrap) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINT, Constants.NS_GML);
}
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POS, Constants.NS_GML);
try {
writer.writeCharacters(EdmDouble.getInstance().valueToString(point.getX(), null, null,
Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null)
+ " "
+ EdmDouble.getInstance().valueToString(point.getY(), null, null,
Constants.DEFAULT_PRECISION, Constants.DEFAULT_SCALE, null));
} catch (EdmPrimitiveTypeException e) {
throw new XMLStreamException("While serializing point coordinates as double", e);
}
writer.writeEndElement();
if (wrap) {
writer.writeEndElement();
}
}
}
private void lineStrings(final XMLStreamWriter writer, final Iterator<LineString> itor, final boolean wrap)
throws XMLStreamException {
while (itor.hasNext()) {
final LineString lineString = itor.next();
if (wrap) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRING, Constants.NS_GML);
}
points(writer, lineString.iterator(), false);
if (wrap) {
writer.writeEndElement();
}
}
}
private void polygons(final XMLStreamWriter writer, final Iterator<Polygon> itor, final boolean wrap)
throws XMLStreamException {
while (itor.hasNext()) {
final Polygon polygon = itor.next();
if (wrap) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON, Constants.NS_GML);
}
if (!polygon.getExterior().isEmpty()) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_EXTERIOR, Constants.NS_GML);
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_LINEARRING, Constants.NS_GML);
points(writer, polygon.getExterior().iterator(), false);
writer.writeEndElement();
writer.writeEndElement();
}
if (!polygon.getInterior().isEmpty()) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_INTERIOR, Constants.NS_GML);
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_LINEARRING, Constants.NS_GML);
points(writer, polygon.getInterior().iterator(), false);
writer.writeEndElement();
writer.writeEndElement();
}
if (wrap) {
writer.writeEndElement();
}
}
}
private void writeSrsName(final XMLStreamWriter writer, final Geospatial value) throws XMLStreamException {
if (value.getSrid() != null && value.getSrid().isNotDefault()) {
writer.writeAttribute(Constants.PREFIX_GML, Constants.NS_GML, Constants.ATTR_SRSNAME,
Constants.SRS_URLPREFIX + value.getSrid().toString());
}
}
public void serialize(final XMLStreamWriter writer, final Geospatial value) throws XMLStreamException {
switch (value.getEdmPrimitiveTypeKind()) {
case GeographyPoint:
case GeometryPoint:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINT, Constants.NS_GML);
writeSrsName(writer, value);
points(writer, Collections.singleton((Point) value).iterator(), false);
writer.writeEndElement();
break;
case GeometryMultiPoint:
case GeographyMultiPoint:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTIPOINT, Constants.NS_GML);
writeSrsName(writer, value);
if (!((MultiPoint) value).isEmpty()) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINTMEMBERS, Constants.NS_GML);
points(writer, ((MultiPoint) value).iterator(), true);
writer.writeEndElement();
}
writer.writeEndElement();
break;
case GeometryLineString:
case GeographyLineString:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRING, Constants.NS_GML);
writeSrsName(writer, value);
lineStrings(writer, Collections.singleton((LineString) value).iterator(), false);
writer.writeEndElement();
break;
case GeometryMultiLineString:
case GeographyMultiLineString:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTILINESTRING, Constants.NS_GML);
writeSrsName(writer, value);
if (!((MultiLineString) value).isEmpty()) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRINGMEMBERS, Constants.NS_GML);
lineStrings(writer, ((MultiLineString) value).iterator(), true);
writer.writeEndElement();
}
writer.writeEndElement();
break;
case GeographyPolygon:
case GeometryPolygon:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON, Constants.NS_GML);
writeSrsName(writer, value);
polygons(writer, Collections.singleton(((Polygon) value)).iterator(), false);
writer.writeEndElement();
break;
case GeographyMultiPolygon:
case GeometryMultiPolygon:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTIPOLYGON, Constants.NS_GML);
writeSrsName(writer, value);
if (!((MultiPolygon) value).isEmpty()) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_SURFACEMEMBERS, Constants.NS_GML);
polygons(writer, ((MultiPolygon) value).iterator(), true);
writer.writeEndElement();
}
writer.writeEndElement();
break;
case GeographyCollection:
case GeometryCollection:
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_GEOCOLLECTION, Constants.NS_GML);
writeSrsName(writer, value);
if (!((GeospatialCollection) value).isEmpty()) {
writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_GEOMEMBERS, Constants.NS_GML);
for (Geospatial geospatial : ((GeospatialCollection) value)) {
serialize(writer, geospatial);
}
writer.writeEndElement();
}
writer.writeEndElement();
break;
default:
}
}
}