Repository: olingo-odata4
Updated Branches:
  refs/heads/master ebdf0d3e3 -> e839533bb


OLINGO-1292 adding srid serialization and deserialization to server json

Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b09dde0b
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b09dde0b
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b09dde0b

Branch: refs/heads/master
Commit: b09dde0b3991f458dec1e90e74e6fce0639cb849
Parents: 8cbe468
Author: shawkins <[email protected]>
Authored: Mon Sep 24 10:23:31 2018 -0400
Committer: shawkins <[email protected]>
Committed: Mon Sep 24 10:23:31 2018 -0400

----------------------------------------------------------------------
 .../json/ODataJsonDeserializer.java             | 39 +++++++++++---------
 .../serializer/json/ODataJsonSerializer.java    | 25 +++++++++----
 .../json/ODataJsonDeserializerEntityTest.java   |  4 +-
 .../json/ODataJsonSerializerTest.java           | 11 ++----
 .../json/ODataJsonSerializerv01Test.java        |  9 ++---
 5 files changed, 49 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b09dde0b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
index 0e8fbf9..d18e347 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
@@ -70,6 +70,7 @@ 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.api.edm.geo.SRID;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
@@ -769,9 +770,13 @@ public class ODataJsonDeserializer implements 
ODataDeserializer {
         final JsonNode topNode = jsonNode.remove(
             geoDataType.equals(GeospatialCollection.class) ? 
Constants.JSON_GEOMETRIES : Constants.JSON_COORDINATES);
 
-        // The "crs" member mentioned in some versions of the OData 
specification is not part of GeoJSON.
-        // It used to be used to specify the coordinate reference system.
-        // TODO: Is it OK to follow RFC 7946 strictly and not allow this 
element from its obsolete predecessor?
+        SRID srid = null;
+        if (jsonNode.has(Constants.JSON_CRS)) {
+          srid = SRID.valueOf(
+          jsonNode.remove(Constants.JSON_CRS).get(Constants.PROPERTIES).
+            get(Constants.JSON_NAME).asText().split(":")[1]);
+        }
+        
         assertJsonNodeIsEmpty(jsonNode);
 
         if (topNode != null && topNode.isArray()) {
@@ -779,29 +784,29 @@ public class ODataJsonDeserializer implements 
ODataDeserializer {
               Geospatial.Dimension.GEOMETRY :
               Geospatial.Dimension.GEOGRAPHY;
           if (geoDataType.equals(Point.class)) {
-            return readGeoPointValue(name, dimension, topNode);
+            return readGeoPointValue(name, dimension, topNode, srid);
           } else if (geoDataType.equals(MultiPoint.class)) {
-            return new MultiPoint(dimension, null, readGeoPointValues(name, 
dimension, 0, false, topNode));
+            return new MultiPoint(dimension, srid, readGeoPointValues(name, 
dimension, 0, false, topNode));
           } else if (geoDataType.equals(LineString.class)) {
             // Although a line string with less than two points is not really 
one, the OData specification says:
             // "The coordinates member of a LineString can have zero or more 
positions".
             // Therefore the required minimal size of the points array 
currently is zero.
-            return new LineString(dimension, null, readGeoPointValues(name, 
dimension, 0, false, topNode));
+            return new LineString(dimension, srid, readGeoPointValues(name, 
dimension, 0, false, topNode));
           } else if (geoDataType.equals(MultiLineString.class)) {
             List<LineString> lines = new ArrayList<LineString>();
             for (final JsonNode element : topNode) {
               // Line strings can be empty (see above).
-              lines.add(new LineString(dimension, null, 
readGeoPointValues(name, dimension, 0, false, element)));
+              lines.add(new LineString(dimension, srid, 
readGeoPointValues(name, dimension, 0, false, element)));
             }
-            return new MultiLineString(dimension, null, lines);
+            return new MultiLineString(dimension, srid, lines);
           } else if (geoDataType.equals(Polygon.class)) {
-            return readGeoPolygon(name, dimension, topNode);
+            return readGeoPolygon(name, dimension, topNode, srid);
           } else if (geoDataType.equals(MultiPolygon.class)) {
             List<Polygon> polygons = new ArrayList<Polygon>();
             for (final JsonNode element : topNode) {
-              polygons.add(readGeoPolygon(name, dimension, element));
+              polygons.add(readGeoPolygon(name, dimension, element, null));
             }
-            return new MultiPolygon(dimension, null, polygons);
+            return new MultiPolygon(dimension, srid, polygons);
           } else if (geoDataType.equals(GeospatialCollection.class)) {
             List<Geospatial> elements = new ArrayList<Geospatial>();
             for (final JsonNode element : topNode) {
@@ -812,7 +817,7 @@ public class ODataJsonDeserializer implements 
ODataDeserializer {
                     
DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, name);
               }
             }
-            return new GeospatialCollection(dimension, null, elements);
+            return new GeospatialCollection(dimension, srid, elements);
           }
         }
       }
@@ -821,11 +826,11 @@ public class ODataJsonDeserializer implements 
ODataDeserializer {
         DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, name);
   }
 
-  private Point readGeoPointValue(final String name, final 
Geospatial.Dimension dimension, JsonNode node)
+  private Point readGeoPointValue(final String name, final 
Geospatial.Dimension dimension, JsonNode node, SRID srid)
       throws DeserializerException, EdmPrimitiveTypeException {
     if (node.isArray() && (node.size() ==2 || node.size() == 3)
         && node.get(0).isNumber() && node.get(1).isNumber() && (node.get(2) == 
null || node.get(2).isNumber())) {
-      Point point = new Point(dimension, null);
+      Point point = new Point(dimension, srid);
       point.setX(getDoubleValue(node.get(0).asText()));
       point.setY(getDoubleValue(node.get(1).asText()));
       if (node.get(2) != null) {
@@ -855,7 +860,7 @@ public class ODataJsonDeserializer implements 
ODataDeserializer {
     if (node.isArray()) {
       List<Point> points = new ArrayList<Point>();
       for (final JsonNode element : node) {
-        points.add(readGeoPointValue(name, dimension, element));
+        points.add(readGeoPointValue(name, dimension, element, null));
       }
       if (points.size() >= minimalSize
           && (!closed || points.get(points.size() - 1).equals(points.get(0)))) 
{
@@ -866,13 +871,13 @@ public class ODataJsonDeserializer implements 
ODataDeserializer {
         DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, name);
   }
 
-  private Polygon readGeoPolygon(final String name, final Geospatial.Dimension 
dimension, JsonNode node)
+  private Polygon readGeoPolygon(final String name, final Geospatial.Dimension 
dimension, JsonNode node, SRID srid)
       throws DeserializerException, EdmPrimitiveTypeException {
     // GeoJSON would allow for more than one interior polygon (hole).
     // But there is no place in the data object to store this information so 
for now we throw an error.
     // There could be a more strict verification that the lines describe 
boundaries and have the correct winding order.
     if (node.isArray() && (node.size() == 1 || node.size() == 2)) {
-      return new Polygon(dimension, null,
+      return new Polygon(dimension, srid,
           node.size() > 1 ? readGeoPointValues(name, dimension, 4, true, 
node.get(1)) : null,
           readGeoPointValues(name, dimension, 4, true, node.get(0)));
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b09dde0b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index 4322210..c331ed6 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -63,6 +63,7 @@ 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.api.edm.geo.SRID;
 import org.apache.olingo.commons.api.format.ContentType;
 import 
org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.ODataServerError;
@@ -920,7 +921,7 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
       writePrimitiveValue(property.getName(), type, property.asPrimitive(),
           isNullable, maxLength, precision, scale, isUnicode, json);
     } else if (property.isGeospatial()) {
-      writeGeoValue(property.getName(), type, property.asGeospatial(), 
isNullable, json);
+      writeGeoValue(property.getName(), type, property.asGeospatial(), 
isNullable, json, null);
     } else if (property.isEnum()) {
       writePrimitiveValue(property.getName(), type, property.asEnum(),
           isNullable, maxLength, precision, scale, isUnicode, json);
@@ -976,7 +977,7 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
 
   /** Writes a geospatial value following the GeoJSON specification defined in 
RFC 7946. */
   protected void writeGeoValue(final String name, final EdmPrimitiveType type, 
final Geospatial geoValue,
-      final Boolean isNullable, JsonGenerator json)
+      final Boolean isNullable, JsonGenerator json, SRID parentSrid)
       throws EdmPrimitiveTypeException, IOException, SerializerException {
     if (geoValue == null) {
       if (isNullable == null || isNullable) {
@@ -988,10 +989,6 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
       if (!type.getDefaultType().isAssignableFrom(geoValue.getClass())) {
         throw new EdmPrimitiveTypeException("The value type " + 
geoValue.getClass() + " is not supported.");
       }
-      if (geoValue.getSrid() != null && geoValue.getSrid().isNotDefault()) {
-        throw new SerializerException("Non-standard SRID not supported!",
-            SerializerException.MessageKeys.WRONG_PROPERTY_VALUE, name, 
geoValue.toString());
-      }
       json.writeStartObject();
       json.writeStringField(Constants.ATTR_TYPE, 
geoValueTypeToJsonName.get(geoValue.getGeoType()));
       json.writeFieldName(geoValue.getGeoType() == 
Geospatial.Type.GEOSPATIALCOLLECTION ?
@@ -1028,14 +1025,28 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
       case GEOSPATIALCOLLECTION:
         for (final Geospatial element : (GeospatialCollection) geoValue) {
           writeGeoValue(name, 
EdmPrimitiveTypeFactory.getInstance(element.getEdmPrimitiveTypeKind()),
-              element, isNullable, json);
+              element, isNullable, json, geoValue.getSrid());
         }
         break;
       }
       json.writeEndArray();
+      
+      if (geoValue.getSrid() != null && geoValue.getSrid().isNotDefault() 
+                 && (parentSrid == null || 
!parentSrid.equals(geoValue.getSrid()))) {
+         srid(json, geoValue.getSrid());
+      }
       json.writeEndObject();
     }
   }
+  
+  private void srid(final JsonGenerator jgen, final SRID srid) throws 
IOException {
+    jgen.writeObjectFieldStart(Constants.JSON_CRS);
+       jgen.writeStringField(Constants.ATTR_TYPE, Constants.JSON_NAME);
+       jgen.writeObjectFieldStart(Constants.PROPERTIES);
+       jgen.writeStringField(Constants.JSON_NAME, "EPSG:" + srid.toString());
+       jgen.writeEndObject();
+       jgen.writeEndObject();
+  }
 
   private void writeGeoPoint(JsonGenerator json, final Point point) throws 
IOException {
     json.writeNumber(point.getX());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b09dde0b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
index 1eb96a9..417bfe3 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
@@ -896,12 +896,14 @@ public class ODataJsonDeserializerEntityTest extends 
AbstractODataDeserializerTe
   public void geoPoint() throws Exception {
     final EdmEntityType entityType = 
mockEntityType(EdmPrimitiveTypeKind.GeometryPoint);
     final String preamble = "{\"" + entityType.getPropertyNames().get(0) + 
"\":{";
-    final Entity entity = deserialize(preamble + 
"\"type\":\"Point\",\"coordinates\":[1.25,2.75]}}",
+    final Entity entity = deserialize(preamble + 
"\"type\":\"Point\",\"coordinates\":[1.25,2.75]," +
+               
"\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:42\"}}}}",
         entityType);
     assertEquals(1, entity.getProperties().size());
     assertTrue(entity.getProperties().get(0).getValue() instanceof Point);
     final Point point = (Point) entity.getProperties().get(0).getValue();
     assertEquals(Geospatial.Dimension.GEOMETRY, point.getDimension());
+    assertEquals("42", point.getSrid().toString());
     assertEquals(1.25, point.getX(), 0);
     assertEquals(2.75, point.getY(), 0);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b09dde0b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index 13a7ed5..ec9482b 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.server.core.serializer.json;
 
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -2306,12 +2304,9 @@ public class ODataJsonSerializerTest {
     final Entity entity = new Entity()
         .addProperty(new Property(null, entityType.getPropertyNames().get(0), 
ValueType.GEOSPATIAL,
             new Point(Dimension.GEOMETRY, SRID.valueOf("42"))));
-    try {
-      serializerNoMetadata.entity(metadata, entityType, entity, null);
-      fail("Expected exception not thrown.");
-    } catch (final SerializerException e) {
-      assertNotNull(e);
-    }
+    
Assert.assertEquals("{\"PropertyGeometryPoint\":{\"type\":\"Point\",\"coordinates\":[0.0,0.0],"
+               + 
"\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:42\"}}}}",
+            IOUtils.toString(serializerNoMetadata.entity(metadata, entityType, 
entity, null).getContent()));
   }
 
   private Point createPoint(final double x, final double y) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b09dde0b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java
index 1b8d60f..17532c0 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java
@@ -2312,12 +2312,9 @@ public class ODataJsonSerializerv01Test {
     final Entity entity = new Entity()
         .addProperty(new Property(null, entityType.getPropertyNames().get(0), 
ValueType.GEOSPATIAL,
             new Point(Dimension.GEOMETRY, SRID.valueOf("42"))));
-    try {
-      serializerNoMetadata.entity(metadata, entityType, entity, null);
-      fail("Expected exception not thrown.");
-    } catch (final SerializerException e) {
-      assertNotNull(e);
-    }
+    
Assert.assertEquals("{\"PropertyGeometryPoint\":{\"type\":\"Point\",\"coordinates\":[0.0,0.0],"
+               + 
"\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:42\"}}}}",
+            IOUtils.toString(serializerNoMetadata.entity(metadata, entityType, 
entity, null).getContent()));
   }
 
   private Point createPoint(final double x, final double y) {

Reply via email to