diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCompositeShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCompositeShape.java index 734eff6d18b..0d841c81e8c 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCompositeShape.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseCompositeShape.java @@ -82,11 +82,8 @@ public abstract class GeoBaseCompositeShape extends BasePlan */ public GeoBaseCompositeShape(final PlanetModel planetModel, final InputStream inputStream, final Class clazz) throws IOException { this(planetModel); - final SerializableObject[] array = SerializableObject.readHeterogeneousArray(planetModel, inputStream); + final T[] array = SerializableObject.readHeterogeneousArray(planetModel, inputStream, clazz); for (final SerializableObject member : array) { - if (!(clazz.isAssignableFrom(member.getClass()))) { - throw new IOException("Can't deserialize composite because member has wrong type: "+member.getClass().getName()); - } addShape(clazz.cast(member)); } } diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java index 7e4ef28c8d1..683e11a65b6 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java @@ -78,7 +78,11 @@ class GeoConcavePolygon extends GeoBasePolygon { public GeoConcavePolygon(final PlanetModel planetModel, final List pointList, final List holes) { super(planetModel); this.points = pointList; - this.holes = holes; + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } this.isInternalEdges = new BitSet(); done(false); } @@ -114,7 +118,11 @@ class GeoConcavePolygon extends GeoBasePolygon { final boolean returnEdgeInternal) { super(planetModel); this.points = pointList; - this.holes = holes; + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } this.isInternalEdges = internalEdgeFlags; done(returnEdgeInternal); } @@ -146,7 +154,11 @@ class GeoConcavePolygon extends GeoBasePolygon { final List holes) { super(planetModel); points = new ArrayList<>(); - this.holes = holes; + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } isInternalEdges = new BitSet(); points.add(new GeoPoint(planetModel, startLatitude, startLongitude)); } @@ -313,7 +325,12 @@ class GeoConcavePolygon extends GeoBasePolygon { public GeoConcavePolygon(final PlanetModel planetModel, final InputStream inputStream) throws IOException { super(planetModel); this.points = java.util.Arrays.asList(SerializableObject.readPointArray(planetModel, inputStream)); - this.holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream)); + final List holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream)); + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } this.isInternalEdges = SerializableObject.readBitSet(inputStream); done(this.isInternalEdges.get(points.size()-1)); } @@ -515,7 +532,7 @@ class GeoConcavePolygon extends GeoBasePolygon { public boolean equals(Object o) { if (!(o instanceof GeoConcavePolygon)) return false; - GeoConcavePolygon other = (GeoConcavePolygon) o; + final GeoConcavePolygon other = (GeoConcavePolygon) o; if (!super.equals(other)) return false; if (!other.isInternalEdges.equals(isInternalEdges)) diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java index 9711d81b957..a29dd0fc09e 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java @@ -76,7 +76,11 @@ class GeoConvexPolygon extends GeoBasePolygon { public GeoConvexPolygon(final PlanetModel planetModel, final List pointList, final List holes) { super(planetModel); this.points = pointList; - this.holes = holes; + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } this.isInternalEdges = new BitSet(); done(false); } @@ -112,7 +116,11 @@ class GeoConvexPolygon extends GeoBasePolygon { final boolean returnEdgeInternal) { super(planetModel); this.points = pointList; - this.holes = holes; + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } this.isInternalEdges = internalEdgeFlags; done(returnEdgeInternal); } @@ -144,7 +152,11 @@ class GeoConvexPolygon extends GeoBasePolygon { final List holes) { super(planetModel); points = new ArrayList<>(); - this.holes = holes; + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } isInternalEdges = new BitSet(); points.add(new GeoPoint(planetModel, startLatitude, startLongitude)); } @@ -309,7 +321,12 @@ class GeoConvexPolygon extends GeoBasePolygon { public GeoConvexPolygon(final PlanetModel planetModel, final InputStream inputStream) throws IOException { super(planetModel); this.points = java.util.Arrays.asList(SerializableObject.readPointArray(planetModel, inputStream)); - this.holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream)); + final List holes = java.util.Arrays.asList(SerializableObject.readPolygonArray(planetModel, inputStream)); + if (holes != null && holes.size() == 0) { + this.holes = null; + } else { + this.holes = holes; + } this.isInternalEdges = SerializableObject.readBitSet(inputStream); done(this.isInternalEdges.get(points.size()-1)); } @@ -501,7 +518,7 @@ class GeoConvexPolygon extends GeoBasePolygon { public boolean equals(Object o) { if (!(o instanceof GeoConvexPolygon)) return false; - GeoConvexPolygon other = (GeoConvexPolygon) o; + final GeoConvexPolygon other = (GeoConvexPolygon) o; if (!super.equals(other)) return false; if (!other.isInternalEdges.equals(isInternalEdges)) diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SerializableObject.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SerializableObject.java index da23cf2775a..7ca64e3d445 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SerializableObject.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/SerializableObject.java @@ -22,6 +22,7 @@ import java.io.OutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.lang.reflect.Constructor; +import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.BitSet; @@ -42,7 +43,7 @@ public interface SerializableObject { * @param outputStream is the output stream. * @param object is the object to write. */ - static void writeObject(final OutputStream outputStream, final SerializableObject object) throws IOException { + public static void writeObject(final OutputStream outputStream, final SerializableObject object) throws IOException { writeString(outputStream, object.getClass().getName()); object.write(outputStream); } @@ -52,7 +53,7 @@ public interface SerializableObject { * @param inputStream is the input stream. * @return the deserialized object. */ - static SerializableObject readObject(final PlanetModel planetModel, final InputStream inputStream) throws IOException { + public static SerializableObject readObject(final PlanetModel planetModel, final InputStream inputStream) throws IOException { // Read the class name final String className = readString(inputStream); try { @@ -96,7 +97,7 @@ public interface SerializableObject { * @param inputStream is the input stream. * @return the deserialized object. */ - static SerializableObject readObject(final InputStream inputStream) throws IOException { + public static SerializableObject readObject(final InputStream inputStream) throws IOException { // Read the class name final String className = readString(inputStream); try { @@ -173,7 +174,7 @@ public interface SerializableObject { * @return the array of points that was read. */ static GeoPoint[] readPointArray(final PlanetModel planetModel, final InputStream inputStream) throws IOException { - return (GeoPoint[])readHomogeneousArray(planetModel, inputStream, GeoPoint.class); + return readHomogeneousArray(planetModel, inputStream, GeoPoint.class); } /** Write a polgon array. @@ -198,7 +199,7 @@ public interface SerializableObject { * @return the array of polygons that was read. */ static GeoPolygon[] readPolygonArray(final PlanetModel planetModel, final InputStream inputStream) throws IOException { - return (GeoPolygon[])readHeterogeneousArray(planetModel, inputStream); + return readHeterogeneousArray(planetModel, inputStream, GeoPolygon.class); } /** Write an array. @@ -206,9 +207,13 @@ public interface SerializableObject { * @param values is the array. */ static void writeHomogeneousArray(final OutputStream outputStream, final SerializableObject[] values) throws IOException { - writeInt(outputStream, values.length); - for (final SerializableObject value : values) { - value.write(outputStream); + if (values == null) { + writeInt(outputStream, 0); + } else { + writeInt(outputStream, values.length); + for (final SerializableObject value : values) { + value.write(outputStream); + } } } @@ -217,9 +222,13 @@ public interface SerializableObject { * @param values is the array. */ static void writeHomogeneousArray(final OutputStream outputStream, final List values) throws IOException { - writeInt(outputStream, values.size()); - for (final SerializableObject value : values) { - value.write(outputStream); + if (values == null) { + writeInt(outputStream, 0); + } else { + writeInt(outputStream, values.size()); + for (final SerializableObject value : values) { + value.write(outputStream); + } } } @@ -229,11 +238,12 @@ public interface SerializableObject { * @param clazz is the class of the objects to read. * @return the array. */ - static SerializableObject[] readHomogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class clazz) throws IOException { + @SuppressWarnings("unchecked") + static T[] readHomogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class clazz) throws IOException { final int count = readInt(inputStream); - final SerializableObject[] rval = new SerializableObject[count]; + final T[] rval = (T[])Array.newInstance(clazz, count); for (int i = 0; i < count; i++) { - rval[i] = readObject(planetModel, inputStream, clazz); + rval[i] = clazz.cast(readObject(planetModel, inputStream, clazz)); } return rval; } @@ -243,9 +253,13 @@ public interface SerializableObject { * @param values is the array. */ static void writeHeterogeneousArray(final OutputStream outputStream, final SerializableObject[] values) throws IOException { - writeInt(outputStream, values.length); - for (final SerializableObject value : values) { - writeObject(outputStream, value); + if (values == null) { + writeInt(outputStream, 0); + } else { + writeInt(outputStream, values.length); + for (final SerializableObject value : values) { + writeObject(outputStream, value); + } } } @@ -254,9 +268,13 @@ public interface SerializableObject { * @param values is the array. */ static void writeHeterogeneousArray(final OutputStream outputStream, final List values) throws IOException { - writeInt(outputStream, values.size()); - for (final SerializableObject value : values) { - writeObject(outputStream, value); + if (values == null) { + writeInt(outputStream, 0); + } else { + writeInt(outputStream, values.size()); + for (final SerializableObject value : values) { + writeObject(outputStream, value); + } } } @@ -265,11 +283,12 @@ public interface SerializableObject { * @param inputStream is the input stream. * @return the array. */ - static SerializableObject[] readHeterogeneousArray(final PlanetModel planetModel, final InputStream inputStream) throws IOException { + @SuppressWarnings("unchecked") + static T[] readHeterogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class clazz) throws IOException { final int count = readInt(inputStream); - final SerializableObject[] rval = new SerializableObject[count]; + final T[] rval = (T[])Array.newInstance(clazz, count); for (int i = 0; i < count; i++) { - rval[i] = readObject(planetModel, inputStream); + rval[i] = clazz.cast(readObject(planetModel, inputStream)); } return rval; } diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomBinaryCodecTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomBinaryCodecTest.java new file mode 100644 index 00000000000..5828d52c58c --- /dev/null +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomBinaryCodecTest.java @@ -0,0 +1,51 @@ +/* + * 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.apache.lucene.spatial3d.geom; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.carrotsearch.randomizedtesting.annotations.Repeat; +import org.junit.Test; + +/** + * Test to check Serialization + */ +public class RandomBinaryCodecTest extends RandomGeoShapeGenerator{ + + @Test + @Repeat(iterations = 100) + public void testRandomShapeCodec() throws IOException{ + PlanetModel planetModel = randomPlanetModel(); + int type = randomShapeType(); + while (type == COMPLEX_POLYGON){ + //We need to implement equals method + type = randomShapeType(); + } + + GeoShape shape = randomGeoShape(type, planetModel); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + SerializableObject.writeObject(outputStream, shape); + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + SerializableObject shapeCopy = SerializableObject.readObject(planetModel, inputStream); + assertEquals(shape, shapeCopy); + } + + +}