From 646d24ebdc16634bb04e3efd4fe92b15c832fd5d Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Wed, 6 Jan 2016 09:00:50 -0500 Subject: [PATCH 01/21] Add a test that the typename isn't highlighted --- .../search/highlight/HighlighterSearchIT.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java b/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java index 41fe4975e4b..ec4d0fabcfd 100644 --- a/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java +++ b/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.highlight; import com.carrotsearch.randomizedtesting.generators.RandomPicks; + import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; @@ -2533,6 +2534,24 @@ public class HighlighterSearchIT extends ESIntegTestCase { } } + public void testDoesNotHighlightTypeName() throws Exception { + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("typename").startObject("properties") + .startObject("foo").field("type", "string") + .field("index_options", "offsets") + .field("term_vector", "with_positions_offsets") + .endObject().endObject().endObject().endObject(); + assertAcked(prepareCreate("test").addMapping("typename", mapping)); + ensureGreen(); + + indexRandom(true, client().prepareIndex("test", "typename").setSource("foo", "test typename")); + + for (String highlighter: new String[] {"plain", "fvh", "postings"}) { + SearchResponse response = client().prepareSearch("test").setTypes("typename").setQuery(matchQuery("foo", "test")) + .highlighter(new HighlightBuilder().field("foo").highlighterType(highlighter).requireFieldMatch(false)).get(); + assertHighlight(response, 0, "foo", 0, 1, equalTo("test typename")); + } + } + @AwaitsFix(bugUrl="Broken now that BoostingQuery does not extend BooleanQuery anymore") public void testFastVectorHighlighterPhraseBoost() throws Exception { assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); From 664d67d41d972fd732251fc891f2b1d75e39cb5d Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Wed, 6 Jan 2016 11:32:03 -0500 Subject: [PATCH 02/21] Add test for alias filter leaking into highlighter --- .../search/highlight/HighlighterSearchIT.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java b/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java index ec4d0fabcfd..25444fa6fe7 100644 --- a/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java +++ b/core/src/test/java/org/elasticsearch/search/highlight/HighlighterSearchIT.java @@ -2552,6 +2552,26 @@ public class HighlighterSearchIT extends ESIntegTestCase { } } + public void testDoesNotHighlightAliasFilters() throws Exception { + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("typename").startObject("properties") + .startObject("foo").field("type", "string") + .field("index_options", "offsets") + .field("term_vector", "with_positions_offsets") + .endObject().endObject().endObject().endObject(); + assertAcked(prepareCreate("test").addMapping("typename", mapping)); + assertAcked(client().admin().indices().prepareAliases().addAlias("test", "filtered_alias", matchQuery("foo", "japanese"))); + ensureGreen(); + + indexRandom(true, client().prepareIndex("test", "typename").setSource("foo", "test japanese")); + + for (String highlighter: new String[] {"plain", "fvh", "postings"}) { + SearchResponse response = client().prepareSearch("filtered_alias").setTypes("typename").setQuery(matchQuery("foo", "test")) + .highlighter(new HighlightBuilder().field("foo").highlighterType(highlighter).requireFieldMatch(false)).get(); + assertHighlight(response, 0, "foo", 0, 1, equalTo("test japanese")); + } + } + + @AwaitsFix(bugUrl="Broken now that BoostingQuery does not extend BooleanQuery anymore") public void testFastVectorHighlighterPhraseBoost() throws Exception { assertAcked(prepareCreate("test").addMapping("type1", type1TermVectorMapping())); From 2e994a2000e0983c41ec7cf038573fde40548e72 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 11 Jan 2016 12:01:35 +0000 Subject: [PATCH 03/21] Updated links on scripting reference --- docs/reference/modules/scripting.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/modules/scripting.asciidoc b/docs/reference/modules/scripting.asciidoc index aea7846202e..dfded61e9a8 100644 --- a/docs/reference/modules/scripting.asciidoc +++ b/docs/reference/modules/scripting.asciidoc @@ -78,8 +78,8 @@ supported scripting languages: |expression |yes |built-in |mustache |yes |built-in |mvel |no |https://github.com/elastic/elasticsearch-lang-mvel[elasticsearch-lang-mvel] -|javascript |no |https://github.com/elastic/elasticsearch-lang-javascript[elasticsearch-lang-javascript] -|python |no |https://github.com/elastic/elasticsearch-lang-python[elasticsearch-lang-python] +|javascript |no |https://github.com/elastic/elasticsearch/tree/master/plugins/lang-javascript[elasticsearch-lang-javascript] +|python |no |https://github.com/elastic/elasticsearch/tree/master/plugins/lang-python[elasticsearch-lang-python] |======================================================================= To increase security, Elasticsearch does not allow you to specify scripts for From bd1d935c26f0c47bf8084eb6af021944105d54d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Thu, 10 Dec 2015 20:33:01 +0100 Subject: [PATCH 04/21] Fix small error in distance normalization in test --- .../elasticsearch/index/query/GeoDistanceQueryBuilderTests.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java index da807f1b0d5..7511915c49c 100644 --- a/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/GeoDistanceQueryBuilderTests.java @@ -204,6 +204,7 @@ public class GeoDistanceQueryBuilderTests extends AbstractQueryTestCase Date: Wed, 16 Dec 2015 12:21:17 +0100 Subject: [PATCH 05/21] Geo: Add validation of shapes to shape builders So far the validation of geo shapes was only taking place in the parse methods in ShapeBuilder. With the recent refactoring we no longer can rely on shapes being parsed from json, so the same kind of validation should take place when just using the java api. A lot of validation concerns the number of points a shape needs to have in order to be valid. Since this is not possible with current builders where points can be added one by one, the builder constructors are changed to require the mandatory parameters and validate those already at construction time. To help with constructing longer lists of points, a new utility PointsListBuilder is instroduces which can produce list of coordinates accepted by most of the other shape builder constructors. Also adding tests for invalid shape exceptions to the already existing shape builder tests. --- .../common/geo/builders/CircleBuilder.java | 10 +- .../common/geo/builders/EnvelopeBuilder.java | 25 +-- .../geo/builders/LineStringBuilder.java | 31 ++- .../geo/builders/MultiLineStringBuilder.java | 6 +- .../geo/builders/MultiPointBuilder.java | 17 +- .../geo/builders/MultiPolygonBuilder.java | 5 +- .../common/geo/builders/PointBuilder.java | 8 + .../common/geo/builders/PointCollection.java | 19 +- .../common/geo/builders/PointListBuilder.java | 98 ++++++++ .../common/geo/builders/PolygonBuilder.java | 89 ++++---- .../common/geo/builders/ShapeBuilder.java | 16 +- .../common/geo/builders/ShapeBuilders.java | 26 +-- .../common/geo/GeoJSONShapeParserTests.java | 1 + .../common/geo/ShapeBuilderTests.java | 212 +++++++++++------- .../AbstractShapeBuilderTestCase.java | 2 +- .../geo/builders/CircleBuilderTests.java | 28 ++- .../geo/builders/EnvelopeBuilderTests.java | 31 ++- .../geo/builders/LineStringBuilderTests.java | 25 +++ .../builders/MultiLineStringBuilderTests.java | 37 +-- .../geo/builders/MultiPointBuilderTests.java | 45 +++- .../geo/builders/PolygonBuilderTests.java | 3 +- .../query/GeoShapeQueryBuilderTests.java | 4 +- .../query/QueryDSLDocumentationTests.java | 7 +- .../elasticsearch/search/geo/GeoFilterIT.java | 114 +++++----- .../search/geo/GeoShapeQueryTests.java | 36 +-- .../test/geo/RandomShapeGenerator.java | 9 +- 26 files changed, 599 insertions(+), 305 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java index eb77ef7a46a..16641aede20 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java @@ -37,10 +37,18 @@ public class CircleBuilder extends ShapeBuilder { public static final CircleBuilder PROTOTYPE = new CircleBuilder(); - private DistanceUnit unit; + private DistanceUnit unit = DistanceUnit.DEFAULT; private double radius; private Coordinate center; + /** + * Creates a circle centered at [0.0, 0.0]. + * Center can be changed by calling {@link #center(Coordinate)} later. + */ + public CircleBuilder() { + this.center = ZERO_ZERO; + } + /** * Set the center of the circle * diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java index 71b68207e74..708241c6666 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java @@ -32,33 +32,22 @@ public class EnvelopeBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE; - public static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(); + public static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(new Coordinate(-1.0, 1.0), new Coordinate(1.0, -1.0)); private Coordinate topLeft; private Coordinate bottomRight; - public EnvelopeBuilder topLeft(Coordinate topLeft) { + public EnvelopeBuilder(Coordinate topLeft, Coordinate bottomRight) { + Objects.requireNonNull(topLeft, "topLeft of envelope cannot be null"); + Objects.requireNonNull(bottomRight, "bottomRight of envelope cannot be null"); this.topLeft = topLeft; - return this; - } - - public EnvelopeBuilder topLeft(double longitude, double latitude) { - return topLeft(coordinate(longitude, latitude)); + this.bottomRight = bottomRight; } public Coordinate topLeft() { return this.topLeft; } - public EnvelopeBuilder bottomRight(Coordinate bottomRight) { - this.bottomRight = bottomRight; - return this; - } - - public EnvelopeBuilder bottomRight(double longitude, double latitude) { - return bottomRight(coordinate(longitude, latitude)); - } - public Coordinate bottomRight() { return this.bottomRight; } @@ -110,8 +99,6 @@ public class EnvelopeBuilder extends ShapeBuilder { @Override public EnvelopeBuilder readFrom(StreamInput in) throws IOException { - return new EnvelopeBuilder() - .topLeft(readCoordinateFrom(in)) - .bottomRight(readCoordinateFrom(in)); + return new EnvelopeBuilder(readCoordinateFrom(in), readCoordinateFrom(in)); } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java index 0bf1ed8fa09..48752d013ae 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java @@ -33,11 +33,35 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + public class LineStringBuilder extends PointCollection { + /** + * Construct a new LineString. + * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) + * a LineString must contain two or more positions + * @param points the initial list of points + * @throw {@link IllegalArgumentException} if there are less then two points defined + */ + public LineStringBuilder(List points) { + super(points); + if (points.size() < 2) { + throw new IllegalArgumentException("invalid number of points in LineString (found [" + points.size()+ "] - must be >= 2)"); + } + } + public static final GeoShapeType TYPE = GeoShapeType.LINESTRING; - public static final LineStringBuilder PROTOTYPE = new LineStringBuilder(); + public static final LineStringBuilder PROTOTYPE = new LineStringBuilder(new PointListBuilder().point(0.0, 0.0).point(1.0, 1.0).list()); @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { @@ -172,11 +196,12 @@ public class LineStringBuilder extends PointCollection { @Override public LineStringBuilder readFrom(StreamInput in) throws IOException { - LineStringBuilder lineStringBuilder = new LineStringBuilder(); + PointListBuilder pl = new PointListBuilder(); int size = in.readVInt(); for (int i=0; i < size; i++) { - lineStringBuilder.point(readCoordinateFrom(in)); + pl.point(readCoordinateFrom(in)); } + LineStringBuilder lineStringBuilder = new LineStringBuilder(pl.list()); return lineStringBuilder; } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java index be09ae81836..4dc13454216 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java @@ -27,6 +27,10 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.XContentBuilder; + import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; @@ -46,7 +50,7 @@ public class MultiLineStringBuilder extends ShapeBuilder { } public MultiLineStringBuilder linestring(Coordinate[] coordinates) { - return this.linestring(new LineStringBuilder().points(coordinates)); + return this.linestring(new LineStringBuilder(new PointListBuilder().points(coordinates).list())); } public Coordinate[][] coordinates() { diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java index b0e86a819aa..ebc5d822d3b 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -36,7 +37,15 @@ public class MultiPointBuilder extends PointCollection { public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT; - public final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder(); + public final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder(Arrays.asList(new Coordinate[]{new Coordinate(0.0, 0.0)})); + + /** + * Create a new {@link MultiPointBuilder}. + * @param points needs at least two points to be valid, otherwise will throw an exception + */ + public MultiPointBuilder(List points) { + super(points); + } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { @@ -93,11 +102,13 @@ public class MultiPointBuilder extends PointCollection { @Override public MultiPointBuilder readFrom(StreamInput in) throws IOException { - MultiPointBuilder multiPointBuilder = new MultiPointBuilder(); int size = in.readVInt(); + List points = new ArrayList(size); for (int i=0; i < size; i++) { - multiPointBuilder.point(readCoordinateFrom(in)); + points.add(readCoordinateFrom(in)); } + MultiPointBuilder multiPointBuilder = new MultiPointBuilder(points); + return multiPointBuilder; } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java index cff06dbfe59..37eafb57e9c 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Shape; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.geo.XShapeCollection; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -28,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -58,8 +60,7 @@ public class MultiPolygonBuilder extends ShapeBuilder { * {@link MultiPolygonBuilder} to the polygon if polygon has different orientation. */ public MultiPolygonBuilder polygon(PolygonBuilder polygon) { - PolygonBuilder pb = new PolygonBuilder(this.orientation); - pb.points(polygon.shell().coordinates(false)); + PolygonBuilder pb = new PolygonBuilder(Arrays.asList(polygon.shell().coordinates(false)), this.orientation); for (LineStringBuilder hole : polygon.holes()) { pb.hole(hole); } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java index afb713cb09d..1cee6525e7a 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Point; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -35,6 +36,13 @@ public class PointBuilder extends ShapeBuilder { private Coordinate coordinate; + /** + * Create a point at [0.0,0.0] + */ + public PointBuilder() { + this.coordinate = ZERO_ZERO; + } + public PointBuilder coordinate(Coordinate coordinate) { this.coordinate = coordinate; return this; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java index b48aacd857b..58b85fff760 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java @@ -20,25 +20,30 @@ package org.elasticsearch.common.geo.builders; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; /** * The {@link PointCollection} is an abstract base implementation for all GeoShapes. It simply handles a set of points. */ public abstract class PointCollection> extends ShapeBuilder { - protected final ArrayList points; + protected final List points; - protected PointCollection() { - this(new ArrayList()); - } - - protected PointCollection(ArrayList points) { + /** + * Construct a new collection of points. + * @param points an initial list of points + * @throws IllegalArgumentException if points is null or empty + */ + protected PointCollection(List points) { + if (points == null || points.size() == 0) { + throw new IllegalArgumentException("cannot create point collection with empty set of points"); + } this.points = points; } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java new file mode 100644 index 00000000000..febb3dcb5ba --- /dev/null +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java @@ -0,0 +1,98 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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.elasticsearch.common.geo.builders; + +import com.vividsolutions.jts.geom.Coordinate; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * A builder for a list of points (of {@link Coordinate} type). + * Enables chaining of individual points either as long/lat pairs + * or as {@link Coordinate} elements, arrays or collections. + */ +public class PointListBuilder { + + private final List points = new ArrayList<>(); + + /** + * Add a new point to the collection + * @param longitude longitude of the coordinate + * @param latitude latitude of the coordinate + * @return this + */ + public PointListBuilder point(double longitude, double latitude) { + return this.point(new Coordinate(longitude, latitude)); + } + + /** + * Add a new point to the collection + * @param coordinate coordinate of the point + * @return this + */ + public PointListBuilder point(Coordinate coordinate) { + this.points.add(coordinate); + return this; + } + + /** + * Add a array of points to the collection + * + * @param coordinates array of {@link Coordinate}s to add + * @return this + */ + public PointListBuilder points(Coordinate...coordinates) { + return this.points(Arrays.asList(coordinates)); + } + + /** + * Add a collection of points to the collection + * + * @param coordinates array of {@link Coordinate}s to add + * @return this + */ + public PointListBuilder points(Collection coordinates) { + this.points.addAll(coordinates); + return this; + } + + /** + * Closes the current list of points by adding the starting point as the end point + * if they are not already the same + */ + public PointListBuilder close() { + Coordinate start = points.get(0); + Coordinate end = points.get(points.size()-1); + if(start.x != end.x || start.y != end.y) { + points.add(start); + } + return this; + } + + /** + * @return the current list of points + */ + public List list() { + return new ArrayList<>(this.points); + } +} diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java index 026fc9aa170..189b2c9ce86 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java @@ -52,7 +52,8 @@ import java.util.concurrent.atomic.AtomicBoolean; public class PolygonBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.POLYGON; - public static final PolygonBuilder PROTOTYPE = new PolygonBuilder(); + public static final PolygonBuilder PROTOTYPE = new PolygonBuilder(new PointListBuilder().point(0.0, 0.0).point(0.0, 1.0) + .point(1.0, 0.0).point(0.0, 0.0).list()); private static final Coordinate[][] EMPTY = new Coordinate[0][]; @@ -64,55 +65,40 @@ public class PolygonBuilder extends ShapeBuilder { // List of line strings defining the holes of the polygon private final ArrayList holes = new ArrayList<>(); - public PolygonBuilder() { - this(Orientation.RIGHT); + public PolygonBuilder(List points, Orientation orientation) { + this(points, orientation, false); } - public PolygonBuilder(Orientation orientation) { - this(new ArrayList(), orientation); - } - - public PolygonBuilder(ArrayList points, Orientation orientation) { + public PolygonBuilder(List points, Orientation orientation, boolean coerce) { this.orientation = orientation; - this.shell = new LineStringBuilder().points(points); + this.shell = validateLinearRing(new LineStringBuilder(points), coerce); + } + + public PolygonBuilder(List points) { + this(points, Orientation.RIGHT); } public Orientation orientation() { return this.orientation; } - public PolygonBuilder point(double longitude, double latitude) { - shell.point(longitude, latitude); - return this; - } - - /** - * Add a point to the shell of the polygon - * @param coordinate coordinate of the new point - * @return this - */ - public PolygonBuilder point(Coordinate coordinate) { - shell.point(coordinate); - return this; - } - - /** - * Add an array of points to the shell of the polygon - * @param coordinates coordinates of the new points to add - * @return this - */ - public PolygonBuilder points(Coordinate...coordinates) { - shell.points(coordinates); - return this; - } - /** * Add a new hole to the polygon * @param hole linear ring defining the hole * @return this */ public PolygonBuilder hole(LineStringBuilder hole) { - holes.add(hole); + return this.hole(hole, false); + } + + /** + * Add a new hole to the polygon + * @param hole linear ring defining the hole + * @param coerce if set to true, will close the hole by adding starting point as end point + * @return this + */ + public PolygonBuilder hole(LineStringBuilder hole, boolean coerce) { + holes.add(validateLinearRing(hole, coerce)); return this; } @@ -138,6 +124,30 @@ public class PolygonBuilder extends ShapeBuilder { return this; } + private static LineStringBuilder validateLinearRing(LineStringBuilder linestring, boolean coerce) { + /** + * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) + * A LinearRing is closed LineString with 4 or more positions. The first and last positions + * are equivalent (they represent equivalent points). Though a LinearRing is not explicitly + * represented as a GeoJSON geometry type, it is referred to in the Polygon geometry type definition. + */ + int numValidPts; + List points = linestring.points; + if (points.size() < (numValidPts = (coerce) ? 3 : 4)) { + throw new IllegalArgumentException( + "invalid number of points in LinearRing (found [" + points.size() + "] - must be >= " + numValidPts + ")"); + } + + if (!points.get(0).equals(points.get(points.size() - 1))) { + if (coerce) { + points.add(points.get(0)); + } else { + throw new IllegalArgumentException("invalid LinearRing found (coordinates are not closed)"); + } + } + return linestring; + } + /** * Validates only 1 vertex is tangential (shared) between the interior and exterior of a polygon */ @@ -235,7 +245,7 @@ public class PolygonBuilder extends ShapeBuilder { return factory.createPolygon(shell, holes); } - protected static LinearRing linearRing(GeometryFactory factory, ArrayList coordinates) { + protected static LinearRing linearRing(GeometryFactory factory, List coordinates) { return factory.createLinearRing(coordinates.toArray(new Coordinate[coordinates.size()])); } @@ -711,8 +721,8 @@ public class PolygonBuilder extends ShapeBuilder { @Override public void writeTo(StreamOutput out) throws IOException { - orientation.writeTo(out); shell.writeTo(out); + orientation.writeTo(out); out.writeVInt(holes.size()); for (LineStringBuilder hole : holes) { hole.writeTo(out); @@ -721,8 +731,9 @@ public class PolygonBuilder extends ShapeBuilder { @Override public PolygonBuilder readFrom(StreamInput in) throws IOException { - PolygonBuilder polyBuilder = new PolygonBuilder(Orientation.readFrom(in)); - polyBuilder.shell = LineStringBuilder.PROTOTYPE.readFrom(in); + LineStringBuilder shell = LineStringBuilder.PROTOTYPE.readFrom(in); + Orientation orientation = Orientation.readFrom(in); + PolygonBuilder polyBuilder = new PolygonBuilder(shell.points, orientation); int holes = in.readVInt(); for (int i = 0; i < holes; i++) { polyBuilder.hole(LineStringBuilder.PROTOTYPE.readFrom(in)); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java index d286237e547..e080ee4e201 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java @@ -64,6 +64,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri } public static final double DATELINE = 180; + + /** + * coordinate at [0.0, 0.0] + */ + public static final Coordinate ZERO_ZERO = new Coordinate(0.0, 0.0); // TODO how might we use JtsSpatialContextFactory to configure the context (esp. for non-geo)? public static final JtsSpatialContext SPATIAL_CONTEXT = JtsSpatialContext.GEO; public static final GeometryFactory FACTORY = SPATIAL_CONTEXT.getGeometryFactory(); @@ -569,7 +574,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri uL = new Coordinate(Math.min(uL.x, lR.x), Math.max(uL.y, lR.y)); lR = new Coordinate(Math.max(uLtmp.x, lR.x), Math.min(uLtmp.y, lR.y)); } - return ShapeBuilders.newEnvelope().topLeft(uL).bottomRight(lR); + return ShapeBuilders.newEnvelope(uL, lR); } protected static void validateMultiPointNode(CoordinateNode coordinates) { @@ -589,12 +594,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri protected static MultiPointBuilder parseMultiPoint(CoordinateNode coordinates) { validateMultiPointNode(coordinates); - - MultiPointBuilder points = new MultiPointBuilder(); + PointListBuilder points = new PointListBuilder(); for (CoordinateNode node : coordinates.children) { points.point(node.coordinate); } - return points; + return new MultiPointBuilder(points.list()); } protected static LineStringBuilder parseLineString(CoordinateNode coordinates) { @@ -607,11 +611,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri throw new ElasticsearchParseException("invalid number of points in LineString (found [{}] - must be >= 2)", coordinates.children.size()); } - LineStringBuilder line = ShapeBuilders.newLineString(); + PointListBuilder line = new PointListBuilder(); for (CoordinateNode node : coordinates.children) { line.point(node.coordinate); } - return line; + return ShapeBuilders.newLineString(line.list()); } protected static MultiLineStringBuilder parseMultiLine(CoordinateNode coordinates) { diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java index 61d7a9cd07e..1fb36fe21e1 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java @@ -21,6 +21,8 @@ package org.elasticsearch.common.geo.builders; import com.vividsolutions.jts.geom.Coordinate; +import java.util.List; + /** * A collection of static methods for creating ShapeBuilders. */ @@ -50,16 +52,16 @@ public class ShapeBuilders { * Create a new set of points * @return new {@link MultiPointBuilder} */ - public static MultiPointBuilder newMultiPoint() { - return new MultiPointBuilder(); + public static MultiPointBuilder newMultiPoint(List points) { + return new MultiPointBuilder(points); } /** * Create a new lineString * @return a new {@link LineStringBuilder} */ - public static LineStringBuilder newLineString() { - return new LineStringBuilder(); + public static LineStringBuilder newLineString(List list) { + return new LineStringBuilder(list); } /** @@ -74,16 +76,8 @@ public class ShapeBuilders { * Create a new Polygon * @return a new {@link PointBuilder} */ - public static PolygonBuilder newPolygon() { - return new PolygonBuilder(); - } - - /** - * Create a new Polygon - * @return a new {@link PointBuilder} - */ - public static PolygonBuilder newPolygon(ShapeBuilder.Orientation orientation) { - return new PolygonBuilder(orientation); + public static PolygonBuilder newPolygon(List shell) { + return new PolygonBuilder(shell); } /** @@ -124,7 +118,7 @@ public class ShapeBuilders { * * @return a new {@link EnvelopeBuilder} */ - public static EnvelopeBuilder newEnvelope() { - return new EnvelopeBuilder(); + public static EnvelopeBuilder newEnvelope(Coordinate topLeft, Coordinate bottomRight) { + return new EnvelopeBuilder(topLeft, bottomRight); } } diff --git a/core/src/test/java/org/elasticsearch/common/geo/GeoJSONShapeParserTests.java b/core/src/test/java/org/elasticsearch/common/geo/GeoJSONShapeParserTests.java index d65137b21b9..6e4d3867fde 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/GeoJSONShapeParserTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/GeoJSONShapeParserTests.java @@ -34,6 +34,7 @@ import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; + import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.xcontent.XContentFactory; diff --git a/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java index ac439ff12e0..0837361ab15 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java @@ -29,6 +29,7 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Polygon; import org.elasticsearch.common.geo.builders.LineStringBuilder; +import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; @@ -50,7 +51,7 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewRectangle() { - Rectangle rectangle = ShapeBuilders.newEnvelope().topLeft(-45, 30).bottomRight(45, -30).build(); + Rectangle rectangle = ShapeBuilders.newEnvelope(new Coordinate(-45, 30), new Coordinate(45, -30)).build(); assertEquals(-45D, rectangle.getMinX(), 0.0d); assertEquals(-30D, rectangle.getMinY(), 0.0d); assertEquals(45D, rectangle.getMaxX(), 0.0d); @@ -58,12 +59,12 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon() { - Polygon polygon = ShapeBuilders.newPolygon() + Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() .point(-45, 30) .point(45, 30) .point(45, -30) .point(-45, -30) - .point(-45, 30).toPolygon(); + .point(-45, 30).list()).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -73,12 +74,12 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon_coordinate() { - Polygon polygon = ShapeBuilders.newPolygon() + Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() .point(new Coordinate(-45, 30)) .point(new Coordinate(45, 30)) .point(new Coordinate(45, -30)) .point(new Coordinate(-45, -30)) - .point(new Coordinate(-45, 30)).toPolygon(); + .point(new Coordinate(-45, 30)).list()).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -88,8 +89,9 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon_coordinates() { - Polygon polygon = ShapeBuilders.newPolygon() - .points(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() + .points(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)) + .list()).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -100,7 +102,7 @@ public class ShapeBuilderTests extends ESTestCase { public void testLineStringBuilder() { // Building a simple LineString - ShapeBuilders.newLineString() + ShapeBuilders.newLineString(new PointListBuilder() .point(-130.0, 55.0) .point(-130.0, -40.0) .point(-15.0, -40.0) @@ -108,10 +110,10 @@ public class ShapeBuilderTests extends ESTestCase { .point(-45.0, 50.0) .point(-45.0, -15.0) .point(-110.0, -15.0) - .point(-110.0, 55.0).build(); + .point(-110.0, 55.0).list()).build(); // Building a linestring that needs to be wrapped - ShapeBuilders.newLineString() + ShapeBuilders.newLineString(new PointListBuilder() .point(100.0, 50.0) .point(110.0, -40.0) .point(240.0, -40.0) @@ -120,66 +122,73 @@ public class ShapeBuilderTests extends ESTestCase { .point(200.0, -30.0) .point(130.0, -30.0) .point(130.0, 60.0) + .list()) .build(); // Building a lineString on the dateline - ShapeBuilders.newLineString() + ShapeBuilders.newLineString(new PointListBuilder() .point(-180.0, 80.0) .point(-180.0, 40.0) .point(-180.0, -40.0) .point(-180.0, -80.0) + .list()) .build(); // Building a lineString on the dateline - ShapeBuilders.newLineString() + ShapeBuilders.newLineString(new PointListBuilder() .point(180.0, 80.0) .point(180.0, 40.0) .point(180.0, -40.0) .point(180.0, -80.0) + .list()) .build(); } public void testMultiLineString() { ShapeBuilders.newMultiLinestring() - .linestring(new LineStringBuilder() + .linestring(new LineStringBuilder(new PointListBuilder() .point(-100.0, 50.0) .point(50.0, 50.0) .point(50.0, 20.0) .point(-100.0, 20.0) + .list()) ) - .linestring(new LineStringBuilder() + .linestring(new LineStringBuilder(new PointListBuilder() .point(-100.0, 20.0) .point(50.0, 20.0) .point(50.0, 0.0) .point(-100.0, 0.0) + .list()) ) .build(); // LineString that needs to be wrappped ShapeBuilders.newMultiLinestring() - .linestring(new LineStringBuilder() + .linestring(new LineStringBuilder(new PointListBuilder() .point(150.0, 60.0) .point(200.0, 60.0) .point(200.0, 40.0) .point(150.0, 40.0) + .list()) ) - .linestring(new LineStringBuilder() + .linestring(new LineStringBuilder(new PointListBuilder() .point(150.0, 20.0) .point(200.0, 20.0) .point(200.0, 0.0) .point(150.0, 0.0) + .list()) ) .build(); } public void testPolygonSelfIntersection() { try { - ShapeBuilders.newPolygon() + ShapeBuilders.newPolygon(new PointListBuilder() .point(-40.0, 50.0) .point(40.0, 50.0) .point(-40.0, -50.0) - .point(40.0, -50.0) - .close().build(); + .point(40.0, -50.0).close().list()) + .build(); fail("Expected InvalidShapeException"); } catch (InvalidShapeException e) { assertThat(e.getMessage(), containsString("Self-intersection at or near point (0.0")); @@ -212,22 +221,26 @@ public class ShapeBuilderTests extends ESTestCase { } public void testPolygonWrapping() { - Shape shape = ShapeBuilders.newPolygon() + Shape shape = ShapeBuilders.newPolygon(new PointListBuilder() .point(-150.0, 65.0) .point(-250.0, 65.0) .point(-250.0, -65.0) .point(-150.0, -65.0) - .close().build(); + .close() + .list()) + .build(); assertMultiPolygon(shape); } public void testLineStringWrapping() { - Shape shape = ShapeBuilders.newLineString() + Shape shape = ShapeBuilders.newLineString(new PointListBuilder() .point(-150.0, 65.0) .point(-250.0, 65.0) .point(-250.0, -65.0) .point(-150.0, -65.0) + .close() + .list()) .build(); assertMultiLineString(shape); } @@ -238,7 +251,7 @@ public class ShapeBuilderTests extends ESTestCase { // expected results: 3 polygons, 1 with a hole // a giant c shape - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(174,0) .point(-176,0) .point(-176,3) @@ -247,10 +260,11 @@ public class ShapeBuilderTests extends ESTestCase { .point(-176,5) .point(-176,8) .point(174,8) - .point(174,0); + .point(174,0) + .list()); // 3/4 of an embedded 'c', crossing dateline once - builder.hole(new LineStringBuilder() + builder.hole(new LineStringBuilder(new PointListBuilder() .point(175, 1) .point(175, 7) .point(-178, 7) @@ -259,15 +273,17 @@ public class ShapeBuilderTests extends ESTestCase { .point(176, 2) .point(179, 2) .point(179,1) - .point(175, 1)); + .point(175, 1) + .list())); // embedded hole right of the dateline - builder.hole(new LineStringBuilder() + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-179, 1) .point(-179, 2) .point(-177, 2) .point(-177,1) - .point(-179,1)); + .point(-179,1) + .list())); Shape shape = builder.close().build(); assertMultiPolygon(shape); @@ -279,7 +295,7 @@ public class ShapeBuilderTests extends ESTestCase { // expected results: 3 polygons, 1 with a hole // a giant c shape - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-186,0) .point(-176,0) .point(-176,3) @@ -288,10 +304,11 @@ public class ShapeBuilderTests extends ESTestCase { .point(-176,5) .point(-176,8) .point(-186,8) - .point(-186,0); + .point(-186,0) + .list()); // 3/4 of an embedded 'c', crossing dateline once - builder.hole(new LineStringBuilder() + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-185,1) .point(-181,1) .point(-181,2) @@ -300,22 +317,24 @@ public class ShapeBuilderTests extends ESTestCase { .point(-178,6) .point(-178,7) .point(-185,7) - .point(-185,1)); + .point(-185,1) + .list())); // embedded hole right of the dateline - builder.hole(new LineStringBuilder() + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-179,1) .point(-177,1) .point(-177,2) .point(-179,2) - .point(-179,1)); + .point(-179,1) + .list())); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testComplexShapeWithHole() { - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-85.0018514,37.1311314) .point(-85.0016645,37.1315293) .point(-85.0016246,37.1317069) @@ -353,9 +372,10 @@ public class ShapeBuilderTests extends ESTestCase { .point(-85.0009461,37.1311684) .point(-85.0011373,37.1311515) .point(-85.0016455,37.1310491) - .point(-85.0018514,37.1311314); + .point(-85.0018514,37.1311314) + .list()); - builder.hole(new LineStringBuilder() + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-85.0000002,37.1317672) .point(-85.0001983,37.1317538) .point(-85.0003378,37.1317582) @@ -381,39 +401,44 @@ public class ShapeBuilderTests extends ESTestCase { .point(-84.9993527,37.1317788) .point(-84.9994931,37.1318061) .point(-84.9996815,37.1317979) - .point(-85.0000002,37.1317672)); + .point(-85.0000002,37.1317672) + .list()) + ); Shape shape = builder.close().build(); assertPolygon(shape); } public void testShapeWithHoleAtEdgeEndPoints() { - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-4, 2) .point(4, 2) .point(6, 0) .point(4, -2) .point(-4, -2) .point(-6, 0) - .point(-4, 2); + .point(-4, 2) + .list()); - builder.hole(new LineStringBuilder() + builder.hole(new LineStringBuilder(new PointListBuilder() .point(4, 1) .point(4, -1) .point(-4, -1) .point(-4, 1) - .point(4, 1)); + .point(4, 1) + .list())); Shape shape = builder.close().build(); assertPolygon(shape); } public void testShapeWithPointOnDateline() { - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(180, 0) .point(176, 4) .point(176, -4) - .point(180, 0); + .point(180, 0) + .list()); Shape shape = builder.close().build(); assertPolygon(shape); @@ -421,21 +446,23 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithEdgeAlongDateline() { // test case 1: test the positive side of the dateline - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(180, 0) .point(176, 4) .point(180, -4) - .point(180, 0); + .point(180, 0) + .list()); Shape shape = builder.close().build(); assertPolygon(shape); // test case 2: test the negative side of the dateline - builder = ShapeBuilders.newPolygon() + builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-176, 4) .point(-180, 0) .point(-180, -4) - .point(-176, 4); + .point(-176, 4) + .list()); shape = builder.close().build(); assertPolygon(shape); @@ -443,73 +470,85 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithBoundaryHoles() { // test case 1: test the positive side of the dateline - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-177, 10) .point(176, 15) .point(172, 0) .point(176, -15) .point(-177, -10) - .point(-177, 10); - builder.hole(new LineStringBuilder() + .point(-177, 10) + .list()); + builder.hole(new LineStringBuilder(new PointListBuilder() .point(176, 10) .point(180, 5) .point(180, -5) .point(176, -10) - .point(176, 10)); + .point(176, 10) + .list())); Shape shape = builder.close().build(); assertMultiPolygon(shape); // test case 2: test the negative side of the dateline - builder = ShapeBuilders.newPolygon() + builder = ShapeBuilders.newPolygon( + new PointListBuilder() .point(-176, 15) .point(179, 10) .point(179, -10) .point(-176, -15) - .point(-172, 0); - builder.hole(new LineStringBuilder() + .point(-172, 0) + .close() + .list()); + builder.hole(new LineStringBuilder( + new PointListBuilder() .point(-176, 10) .point(-176, -10) .point(-180, -5) .point(-180, 5) - .point(-176, 10)); + .point(-176, 10) + .close() + .list())); shape = builder.close().build(); assertMultiPolygon(shape); } public void testShapeWithTangentialHole() { // test a shape with one tangential (shared) vertex (should pass) - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(179, 10) .point(168, 15) .point(164, 0) .point(166, -15) .point(179, -10) - .point(179, 10); - builder.hole(new LineStringBuilder() + .point(179, 10) + .list()); + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-177, 10) .point(-178, -10) .point(-180, -5) .point(-180, 5) - .point(-177, 10)); + .point(-177, 10) + .list())); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testShapeWithInvalidTangentialHole() { // test a shape with one invalid tangential (shared) vertex (should throw exception) - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(179, 10) .point(168, 15) .point(164, 0) .point(166, -15) .point(179, -10) - .point(179, 10); - builder.hole(new LineStringBuilder() + .point(179, 10) + .list()); + builder.hole(new LineStringBuilder(new PointListBuilder() .point(164, 0) .point(175, 10) .point(175, 5) .point(179, -10) - .point(164, 0)); + .point(164, 0) + .list())); try { builder.close().build(); fail("Expected InvalidShapeException"); @@ -520,43 +559,48 @@ public class ShapeBuilderTests extends ESTestCase { public void testBoundaryShapeWithTangentialHole() { // test a shape with one tangential (shared) vertex for each hole (should pass) - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-177, 10) .point(176, 15) .point(172, 0) .point(176, -15) .point(-177, -10) - .point(-177, 10); - builder.hole(new LineStringBuilder() + .point(-177, 10) + .list()); + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-177, 10) .point(-178, -10) .point(-180, -5) .point(-180, 5) - .point(-177, 10)); - builder.hole(new LineStringBuilder() + .point(-177, 10) + .list())); + builder.hole(new LineStringBuilder(new PointListBuilder() .point(172, 0) .point(176, 10) .point(176, -5) - .point(172, 0)); + .point(172, 0) + .list())); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testBoundaryShapeWithInvalidTangentialHole() { // test shape with two tangential (shared) vertices (should throw exception) - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-177, 10) .point(176, 15) .point(172, 0) .point(176, -15) .point(-177, -10) - .point(-177, 10); - builder.hole(new LineStringBuilder() + .point(-177, 10) + .list()); + builder.hole(new LineStringBuilder(new PointListBuilder() .point(-177, 10) .point(172, 0) .point(180, -5) .point(176, -10) - .point(-177, 10)); + .point(-177, 10) + .list())); try { builder.close().build(); fail("Expected InvalidShapeException"); @@ -569,11 +613,12 @@ public class ShapeBuilderTests extends ESTestCase { * Test an enveloping polygon around the max mercator bounds */ public void testBoundaryShape() { - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(-180, 90) .point(180, 90) .point(180, -90) - .point(-180, -90); + .point(-180, 90) + .list()); Shape shape = builder.close().build(); @@ -582,21 +627,23 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithAlternateOrientation() { // cw: should produce a multi polygon spanning hemispheres - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(180, 0) .point(176, 4) .point(-176, 4) - .point(180, 0); + .point(180, 0) + .list()); Shape shape = builder.close().build(); assertPolygon(shape); // cw: geo core will convert to ccw across the dateline - builder = ShapeBuilders.newPolygon() + builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(180, 0) .point(-176, 4) .point(176, 4) - .point(180, 0); + .point(180, 0) + .list()); shape = builder.close().build(); @@ -604,12 +651,13 @@ public class ShapeBuilderTests extends ESTestCase { } public void testInvalidShapeWithConsecutiveDuplicatePoints() { - PolygonBuilder builder = ShapeBuilders.newPolygon() + PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() .point(180, 0) .point(176, 4) .point(176, 4) .point(-176, 4) - .point(180, 0); + .point(180, 0) + .list()); try { builder.close().build(); fail("Expected InvalidShapeException"); diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java b/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java index 279e31aadd4..03294b8e49c 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/AbstractShapeBuilderTestCase.java @@ -40,7 +40,7 @@ import static org.hamcrest.Matchers.not; public abstract class AbstractShapeBuilderTestCase extends ESTestCase { - private static final int NUMBER_OF_TESTBUILDERS = 20; + private static final int NUMBER_OF_TESTBUILDERS = 100; private static NamedWriteableRegistry namedWriteableRegistry; /** diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/CircleBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/builders/CircleBuilderTests.java index bd90fefc922..3c9ca34c6ea 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/CircleBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/CircleBuilderTests.java @@ -42,9 +42,18 @@ public class CircleBuilderTests extends AbstractShapeBuilderTestCase 0.0 || original.center().y > 0.0) { + mutation.center(new Coordinate(original.center().x/2, original.center().y/2)); + } else { + // original center was 0.0, 0.0 + mutation.center(randomDouble() + 0.1, randomDouble() + 0.1); + } } else if (randomBoolean()) { - radius = radius/2; + if (radius > 0) { + radius = radius/2; + } else { + radius = randomDouble() + 0.1; + } } else { DistanceUnit newRandom = unit; while (newRandom == unit) { @@ -56,10 +65,15 @@ public class CircleBuilderTests extends AbstractShapeBuilderTestCase { + public void testInvalidConstructorArgs() { + try { + new EnvelopeBuilder(null, new Coordinate(1.0, -1.0)); + fail("Exception expected"); + } catch (NullPointerException e) { + assertThat("topLeft of envelope cannot be null", equalTo(e.getMessage())); + } + + try { + new EnvelopeBuilder(new Coordinate(1.0, -1.0), null); + fail("Exception expected"); + } catch (NullPointerException e) { + assertThat("bottomRight of envelope cannot be null", equalTo(e.getMessage())); + } + } + @Override protected EnvelopeBuilder createTestShapeBuilder() { return createRandomShape(); @@ -42,26 +60,25 @@ public class EnvelopeBuilderTests extends AbstractShapeBuilderTestCase { + public void testInvalidConstructorArgs() { + try { + new LineStringBuilder(null); + fail("Exception expected"); + } catch (IllegalArgumentException e) { + assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); + } + + try { + new LineStringBuilder(new PointListBuilder().list()); + fail("Exception expected"); + } catch (IllegalArgumentException e) { + assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); + } + + try { + new LineStringBuilder(new PointListBuilder().point(0.0, 0.0).list()); + fail("Exception expected"); + } catch (IllegalArgumentException e) { + assertThat("invalid number of points in LineString (found [1] - must be >= 2)", equalTo(e.getMessage())); + } + } + @Override protected LineStringBuilder createTestShapeBuilder() { return createRandomShape(); diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilderTests.java index c2224ae6d68..3c618fd3696 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilderTests.java @@ -40,30 +40,37 @@ public class MultiLineStringBuilderTests extends AbstractShapeBuilderTestCase 0) { + int lineToChange = randomInt(coordinates.length - 1); + for (int i = 0; i < coordinates.length; i++) { + Coordinate[] line = coordinates[i]; + if (i == lineToChange) { + Coordinate coordinate = randomFrom(line); + if (randomBoolean()) { + if (coordinate.x != 0.0) { + coordinate.x = coordinate.x / 2; + } else { + coordinate.x = randomDoubleBetween(-180.0, 180.0, true); + } } else { - coordinate.x = randomDoubleBetween(-180.0, 180.0, true); - } - } else { - if (coordinate.y != 0.0) { - coordinate.y = coordinate.y / 2; - } else { - coordinate.y = randomDoubleBetween(-90.0, 90.0, true); + if (coordinate.y != 0.0) { + coordinate.y = coordinate.y / 2; + } else { + coordinate.y = randomDoubleBetween(-90.0, 90.0, true); + } } } } + } else { + mutation.linestring((LineStringBuilder) RandomShapeGenerator.createShape(getRandom(), ShapeType.LINESTRING)); } return mutation; } static MultiLineStringBuilder createRandomShape() { + if (true) { + return new MultiLineStringBuilder(); + } return (MultiLineStringBuilder) RandomShapeGenerator.createShape(getRandom(), ShapeType.MULTILINESTRING); } } diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/MultiPointBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/builders/MultiPointBuilderTests.java index fb365df0122..6135f326b6e 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/MultiPointBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/MultiPointBuilderTests.java @@ -25,8 +25,29 @@ import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType; import java.io.IOException; +import static org.hamcrest.Matchers.equalTo; + public class MultiPointBuilderTests extends AbstractShapeBuilderTestCase { + public void testInvalidBuilderException() { + try { + new MultiPointBuilder(null); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException e) { + assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); + } + + try { + new MultiPointBuilder(new PointListBuilder().list()); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException e) { + assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); + } + + // one point is minimum + new MultiPointBuilder(new PointListBuilder().point(0.0, 0.0).list()); + } + @Override protected MultiPointBuilder createTestShapeBuilder() { return createRandomShape(); @@ -40,19 +61,23 @@ public class MultiPointBuilderTests extends AbstractShapeBuilderTestCase 0) { + Coordinate coordinate = randomFrom(coordinates); + if (randomBoolean()) { + if (coordinate.x != 0.0) { + coordinate.x = coordinate.x / 2; + } else { + coordinate.x = randomDoubleBetween(-180.0, 180.0, true); + } } else { - coordinate.x = randomDoubleBetween(-180.0, 180.0, true); + if (coordinate.y != 0.0) { + coordinate.y = coordinate.y / 2; + } else { + coordinate.y = randomDoubleBetween(-90.0, 90.0, true); + } } } else { - if (coordinate.y != 0.0) { - coordinate.y = coordinate.y / 2; - } else { - coordinate.y = randomDoubleBetween(-90.0, 90.0, true); - } + coordinates = new Coordinate[]{new Coordinate(1.0, 1.0)}; } return mutation.points(coordinates); } diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/PolygonBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/builders/PolygonBuilderTests.java index ea83359c1f0..c7b4673a466 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/PolygonBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/PolygonBuilderTests.java @@ -77,8 +77,7 @@ public class PolygonBuilderTests extends AbstractShapeBuilderTestCase Date: Mon, 11 Jan 2016 20:56:19 +0000 Subject: [PATCH 06/21] updated scripting links to doc links and removed mvel --- docs/reference/modules/scripting.asciidoc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/reference/modules/scripting.asciidoc b/docs/reference/modules/scripting.asciidoc index dfded61e9a8..53786fa41ea 100644 --- a/docs/reference/modules/scripting.asciidoc +++ b/docs/reference/modules/scripting.asciidoc @@ -77,9 +77,8 @@ supported scripting languages: |groovy |no |built-in |expression |yes |built-in |mustache |yes |built-in -|mvel |no |https://github.com/elastic/elasticsearch-lang-mvel[elasticsearch-lang-mvel] -|javascript |no |https://github.com/elastic/elasticsearch/tree/master/plugins/lang-javascript[elasticsearch-lang-javascript] -|python |no |https://github.com/elastic/elasticsearch/tree/master/plugins/lang-python[elasticsearch-lang-python] +|javascript |no |https://www.elastic.co/guide/en/elasticsearch/plugins/current/lang-javascript.html[elasticsearch-lang-javascript] +|python |no |https://www.elastic.co/guide/en/elasticsearch/plugins/current/lang-python.html[elasticsearch-lang-python] |======================================================================= To increase security, Elasticsearch does not allow you to specify scripts for From 01ce49e94ee7dcd9a8696b53a84e2a0184284a93 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Mon, 11 Jan 2016 13:35:59 -0500 Subject: [PATCH 07/21] Ban Serializable 1. Uses forbidden patterns to prevent things from referencing java.io.Serializable or from mentioning serialVersionUID. 2. Uses -Xlint:-serial so we don't have to hear from javac that we aren't declaring serialVersionUID on any classes that we make that happen to extend Serializable. 3. Remove Serializable and serialVersionUID declarations. I didn't use forbidden apis because it doesn't look like it has a way to ban explicitly implementing Serializable. If you try to ban Serializable with forbidden apis you end up banning all Exceptions and all Strings. Closes #15847 --- .../elasticsearch/gradle/BuildPlugin.groovy | 3 +- .../precommit/ForbiddenPatternsTask.groovy | 3 ++ core/build.gradle | 4 +- .../org/elasticsearch/SpecialPermission.java | 17 +++---- .../common/inject/ConfigurationException.java | 2 - .../common/inject/CreationException.java | 2 - .../common/inject/ProvisionException.java | 2 - .../common/inject/internal/Errors.java | 3 +- .../common/inject/internal/Join.java | 2 - .../common/inject/internal/MoreTypes.java | 29 ++---------- .../inject/matcher/AbstractMatcher.java | 10 +--- .../common/inject/matcher/Matchers.java | 46 ++++--------------- .../common/inject/name/NamedImpl.java | 5 +- .../common/inject/spi/Message.java | 19 +------- .../common/inject/util/Types.java | 14 +++--- .../org/elasticsearch/common/joda/Joda.java | 4 -- .../common/logging/jdk/ESLogRecord.java | 2 - .../common/util/concurrent/BaseFuture.java | 3 -- .../elasticsearch/script/ClassPermission.java | 14 ++---- .../java/org/joda/time/base/BaseDateTime.java | 10 +--- plugins/discovery-azure/build.gradle | 2 +- .../script/javascript/support/NativeList.java | 1 - .../script/javascript/support/NativeMap.java | 8 ++-- .../support/ScriptableLinkedHashMap.java | 6 +-- plugins/repository-azure/build.gradle | 2 - test/framework/build.gradle | 2 +- 26 files changed, 54 insertions(+), 161 deletions(-) diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy index b8fd793ef23..3cf1ccce824 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy @@ -309,9 +309,10 @@ class BuildPlugin implements Plugin { /* * -path because gradle will send in paths that don't always exist. * -missing because we have tons of missing @returns and @param. + * -serial because we don't use java serialization. */ // don't even think about passing args with -J-xxx, oracle will ask you to submit a bug report :) - options.compilerArgs << '-Werror' << '-Xlint:all,-path' << '-Xdoclint:all' << '-Xdoclint:-missing' + options.compilerArgs << '-Werror' << '-Xlint:all,-path,-serial' << '-Xdoclint:all' << '-Xdoclint:-missing' // compile with compact 3 profile by default // NOTE: this is just a compile time check: does not replace testing with a compact3 JRE if (project.compactProfile != 'full') { diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/ForbiddenPatternsTask.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/ForbiddenPatternsTask.groovy index 7d8982e3f2d..190b0150bc4 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/ForbiddenPatternsTask.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/ForbiddenPatternsTask.groovy @@ -62,6 +62,9 @@ public class ForbiddenPatternsTask extends DefaultTask { patterns.put('nocommit', /nocommit/) patterns.put('tab', /\t/) patterns.put('wildcard imports', /^\s*import.*\.\*/) + // We don't use Java serialization so we fail if it looks like we're trying to. + patterns.put('declares serialVersionUID', /serialVersionUID/) + patterns.put('references Serializable', /java\.io\.Serializable/) inputs.property("excludes", filesFilter.excludes) inputs.property("rules", patterns) diff --git a/core/build.gradle b/core/build.gradle index 229951f895d..e1511a9cdd1 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -102,8 +102,8 @@ if (isEclipse) { } } -compileJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-serial,-try,-unchecked" -compileTestJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-serial,-try,-unchecked" +compileJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-try,-unchecked" +compileTestJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-try,-unchecked" forbiddenPatterns { exclude '**/*.json' diff --git a/core/src/main/java/org/elasticsearch/SpecialPermission.java b/core/src/main/java/org/elasticsearch/SpecialPermission.java index 171f08884c3..7d796346c64 100644 --- a/core/src/main/java/org/elasticsearch/SpecialPermission.java +++ b/core/src/main/java/org/elasticsearch/SpecialPermission.java @@ -22,15 +22,15 @@ package org.elasticsearch; import java.security.BasicPermission; /** - * Elasticsearch-specific permission to check before entering - * {@code AccessController.doPrivileged()} blocks. + * Elasticsearch-specific permission to check before entering + * {@code AccessController.doPrivileged()} blocks. *

- * We try to avoid these blocks in our code and keep security simple, - * but we need them for a few special places to contain hacks for third + * We try to avoid these blocks in our code and keep security simple, + * but we need them for a few special places to contain hacks for third * party code, or dangerous things used by scripting engines. *

* All normal code has this permission, but checking this before truncating the stack - * prevents unprivileged code (e.g. scripts), which do not have it, from gaining elevated + * prevents unprivileged code (e.g. scripts), which do not have it, from gaining elevated * privileges. *

* In other words, don't do this: @@ -57,9 +57,6 @@ import java.security.BasicPermission; * */ public final class SpecialPermission extends BasicPermission { - - private static final long serialVersionUID = -4129500096157408168L; - /** * Creates a new SpecialPermision object. */ @@ -68,11 +65,11 @@ public final class SpecialPermission extends BasicPermission { // but let's just keep it simple if we can. super("*"); } - + /** * Creates a new SpecialPermission object. * This constructor exists for use by the {@code Policy} object to instantiate new Permission objects. - * + * * @param name ignored * @param actions ignored */ diff --git a/core/src/main/java/org/elasticsearch/common/inject/ConfigurationException.java b/core/src/main/java/org/elasticsearch/common/inject/ConfigurationException.java index 870fece6fdf..a4a61a342fe 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/ConfigurationException.java +++ b/core/src/main/java/org/elasticsearch/common/inject/ConfigurationException.java @@ -81,6 +81,4 @@ public final class ConfigurationException extends RuntimeException { public String getMessage() { return Errors.format("Guice configuration errors", messages); } - - private static final long serialVersionUID = 0; } \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/common/inject/CreationException.java b/core/src/main/java/org/elasticsearch/common/inject/CreationException.java index 4c8e94bd8f8..dc5cbbb5898 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/CreationException.java +++ b/core/src/main/java/org/elasticsearch/common/inject/CreationException.java @@ -52,6 +52,4 @@ public class CreationException extends RuntimeException { public String getMessage() { return Errors.format("Guice creation errors", messages); } - - private static final long serialVersionUID = 0; } diff --git a/core/src/main/java/org/elasticsearch/common/inject/ProvisionException.java b/core/src/main/java/org/elasticsearch/common/inject/ProvisionException.java index c8887af7b33..4e8314c3847 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/ProvisionException.java +++ b/core/src/main/java/org/elasticsearch/common/inject/ProvisionException.java @@ -68,6 +68,4 @@ public final class ProvisionException extends RuntimeException { public String getMessage() { return Errors.format("Guice provision errors", messages); } - - private static final long serialVersionUID = 0; } diff --git a/core/src/main/java/org/elasticsearch/common/inject/internal/Errors.java b/core/src/main/java/org/elasticsearch/common/inject/internal/Errors.java index d9e193b1f62..795ff5380aa 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/internal/Errors.java +++ b/core/src/main/java/org/elasticsearch/common/inject/internal/Errors.java @@ -32,7 +32,6 @@ import org.elasticsearch.common.inject.spi.Message; import org.elasticsearch.common.inject.spi.TypeListenerBinding; import java.io.PrintWriter; -import java.io.Serializable; import java.io.StringWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; @@ -66,7 +65,7 @@ import static java.util.Collections.unmodifiableList; * * @author jessewilson@google.com (Jesse Wilson) */ -public final class Errors implements Serializable { +public final class Errors { /** * The root errors object. Used to access the list of error messages. diff --git a/core/src/main/java/org/elasticsearch/common/inject/internal/Join.java b/core/src/main/java/org/elasticsearch/common/inject/internal/Join.java index 1c8c835615b..c876ea4cb9d 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/internal/Join.java +++ b/core/src/main/java/org/elasticsearch/common/inject/internal/Join.java @@ -313,7 +313,5 @@ public final class Join { private JoinException(IOException cause) { super(cause); } - - private static final long serialVersionUID = 1L; } } diff --git a/core/src/main/java/org/elasticsearch/common/inject/internal/MoreTypes.java b/core/src/main/java/org/elasticsearch/common/inject/internal/MoreTypes.java index 63d8e404d82..ed46a5c3c54 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/internal/MoreTypes.java +++ b/core/src/main/java/org/elasticsearch/common/inject/internal/MoreTypes.java @@ -21,7 +21,6 @@ import org.elasticsearch.common.inject.ConfigurationException; import org.elasticsearch.common.inject.TypeLiteral; import org.elasticsearch.common.inject.spi.Message; -import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; @@ -108,8 +107,7 @@ public class MoreTypes { /** * Returns a type that is functionally equal but not necessarily equal - * according to {@link Object#equals(Object) Object.equals()}. The returned - * type is {@link Serializable}. + * according to {@link Object#equals(Object) Object.equals()}. */ public static Type canonicalize(Type type) { if (type instanceof ParameterizedTypeImpl @@ -140,17 +138,6 @@ public class MoreTypes { } } - /** - * Returns a type that's functionally equal but not necessarily equal - * according to {@link Object#equals(Object) Object.equals}. The returned - * member is {@link Serializable}. - */ - public static Member serializableCopy(Member member) { - return member instanceof MemberImpl - ? member - : new MemberImpl(member); - } - public static Class getRawType(Type type) { if (type instanceof Class) { // type is a normal class. @@ -450,7 +437,7 @@ public class MoreTypes { } public static class ParameterizedTypeImpl - implements ParameterizedType, Serializable, CompositeType { + implements ParameterizedType, CompositeType { private final Type ownerType; private final Type rawType; private final Type[] typeArguments; @@ -527,12 +514,10 @@ public class MoreTypes { public String toString() { return MoreTypes.toString(this); } - - private static final long serialVersionUID = 0; } public static class GenericArrayTypeImpl - implements GenericArrayType, Serializable, CompositeType { + implements GenericArrayType, CompositeType { private final Type componentType; public GenericArrayTypeImpl(Type componentType) { @@ -564,8 +549,6 @@ public class MoreTypes { public String toString() { return MoreTypes.toString(this); } - - private static final long serialVersionUID = 0; } /** @@ -573,7 +556,7 @@ public class MoreTypes { * lower bounds. We only support what the Java 6 language needs - at most one * bound. If a lower bound is set, the upper bound must be Object.class. */ - public static class WildcardTypeImpl implements WildcardType, Serializable, CompositeType { + public static class WildcardTypeImpl implements WildcardType, CompositeType { private final Type upperBound; private final Type lowerBound; @@ -632,8 +615,6 @@ public class MoreTypes { public String toString() { return MoreTypes.toString(this); } - - private static final long serialVersionUID = 0; } private static void checkNotPrimitive(Type type, String use) { @@ -647,7 +628,7 @@ public class MoreTypes { * our exception types. We workaround this with this serializable implementation. It includes all * of the API methods, plus everything we use for line numbers and messaging. */ - public static class MemberImpl implements Member, Serializable { + public static class MemberImpl implements Member { private final Class declaringClass; private final String name; private final int modifiers; diff --git a/core/src/main/java/org/elasticsearch/common/inject/matcher/AbstractMatcher.java b/core/src/main/java/org/elasticsearch/common/inject/matcher/AbstractMatcher.java index a180ecacb84..9ad7bc407d0 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/matcher/AbstractMatcher.java +++ b/core/src/main/java/org/elasticsearch/common/inject/matcher/AbstractMatcher.java @@ -16,8 +16,6 @@ package org.elasticsearch.common.inject.matcher; -import java.io.Serializable; - /** * Implements {@code and()} and {@code or()}. * @@ -35,7 +33,7 @@ public abstract class AbstractMatcher implements Matcher { return new OrMatcher<>(this, other); } - private static class AndMatcher extends AbstractMatcher implements Serializable { + private static class AndMatcher extends AbstractMatcher { private final Matcher a, b; public AndMatcher(Matcher a, Matcher b) { @@ -64,11 +62,9 @@ public abstract class AbstractMatcher implements Matcher { public String toString() { return "and(" + a + ", " + b + ")"; } - - private static final long serialVersionUID = 0; } - private static class OrMatcher extends AbstractMatcher implements Serializable { + private static class OrMatcher extends AbstractMatcher { private final Matcher a, b; public OrMatcher(Matcher a, Matcher b) { @@ -97,7 +93,5 @@ public abstract class AbstractMatcher implements Matcher { public String toString() { return "or(" + a + ", " + b + ")"; } - - private static final long serialVersionUID = 0; } } diff --git a/core/src/main/java/org/elasticsearch/common/inject/matcher/Matchers.java b/core/src/main/java/org/elasticsearch/common/inject/matcher/Matchers.java index 96df76c0b93..e2ced98034e 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/matcher/Matchers.java +++ b/core/src/main/java/org/elasticsearch/common/inject/matcher/Matchers.java @@ -16,7 +16,6 @@ package org.elasticsearch.common.inject.matcher; -import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -42,7 +41,7 @@ public class Matchers { private static final Matcher ANY = new Any(); - private static class Any extends AbstractMatcher implements Serializable { + private static class Any extends AbstractMatcher { @Override public boolean matches(Object o) { return true; @@ -56,8 +55,6 @@ public class Matchers { public Object readResolve() { return any(); } - - private static final long serialVersionUID = 0; } /** @@ -67,7 +64,7 @@ public class Matchers { return new Not<>(p); } - private static class Not extends AbstractMatcher implements Serializable { + private static class Not extends AbstractMatcher { final Matcher delegate; private Not(Matcher delegate) { @@ -94,8 +91,6 @@ public class Matchers { public String toString() { return "not(" + delegate + ")"; } - - private static final long serialVersionUID = 0; } private static void checkForRuntimeRetention( @@ -115,8 +110,7 @@ public class Matchers { return new AnnotatedWithType(annotationType); } - private static class AnnotatedWithType extends AbstractMatcher - implements Serializable { + private static class AnnotatedWithType extends AbstractMatcher { private final Class annotationType; public AnnotatedWithType(Class annotationType) { @@ -144,8 +138,6 @@ public class Matchers { public String toString() { return "annotatedWith(" + annotationType.getSimpleName() + ".class)"; } - - private static final long serialVersionUID = 0; } /** @@ -157,8 +149,7 @@ public class Matchers { return new AnnotatedWith(annotation); } - private static class AnnotatedWith extends AbstractMatcher - implements Serializable { + private static class AnnotatedWith extends AbstractMatcher { private final Annotation annotation; public AnnotatedWith(Annotation annotation) { @@ -187,8 +178,6 @@ public class Matchers { public String toString() { return "annotatedWith(" + annotation + ")"; } - - private static final long serialVersionUID = 0; } /** @@ -199,8 +188,7 @@ public class Matchers { return new SubclassesOf(superclass); } - private static class SubclassesOf extends AbstractMatcher - implements Serializable { + private static class SubclassesOf extends AbstractMatcher { private final Class superclass; public SubclassesOf(Class superclass) { @@ -227,8 +215,6 @@ public class Matchers { public String toString() { return "subclassesOf(" + superclass.getSimpleName() + ".class)"; } - - private static final long serialVersionUID = 0; } /** @@ -238,8 +224,7 @@ public class Matchers { return new Only(value); } - private static class Only extends AbstractMatcher - implements Serializable { + private static class Only extends AbstractMatcher { private final Object value; public Only(Object value) { @@ -266,8 +251,6 @@ public class Matchers { public String toString() { return "only(" + value + ")"; } - - private static final long serialVersionUID = 0; } /** @@ -277,8 +260,7 @@ public class Matchers { return new IdenticalTo(value); } - private static class IdenticalTo extends AbstractMatcher - implements Serializable { + private static class IdenticalTo extends AbstractMatcher { private final Object value; public IdenticalTo(Object value) { @@ -305,8 +287,6 @@ public class Matchers { public String toString() { return "identicalTo(" + value + ")"; } - - private static final long serialVersionUID = 0; } /** @@ -317,7 +297,7 @@ public class Matchers { return new InPackage(targetPackage); } - private static class InPackage extends AbstractMatcher implements Serializable { + private static class InPackage extends AbstractMatcher { private final transient Package targetPackage; private final String packageName; @@ -350,8 +330,6 @@ public class Matchers { public Object readResolve() { return inPackage(Package.getPackage(packageName)); } - - private static final long serialVersionUID = 0; } /** @@ -364,7 +342,7 @@ public class Matchers { return new InSubpackage(targetPackageName); } - private static class InSubpackage extends AbstractMatcher implements Serializable { + private static class InSubpackage extends AbstractMatcher { private final String targetPackageName; public InSubpackage(String targetPackageName) { @@ -393,8 +371,6 @@ public class Matchers { public String toString() { return "inSubpackage(" + targetPackageName + ")"; } - - private static final long serialVersionUID = 0; } /** @@ -405,7 +381,7 @@ public class Matchers { return new Returns(returnType); } - private static class Returns extends AbstractMatcher implements Serializable { + private static class Returns extends AbstractMatcher { private final Matcher> returnType; public Returns(Matcher> returnType) { @@ -432,7 +408,5 @@ public class Matchers { public String toString() { return "returns(" + returnType + ")"; } - - private static final long serialVersionUID = 0; } } diff --git a/core/src/main/java/org/elasticsearch/common/inject/name/NamedImpl.java b/core/src/main/java/org/elasticsearch/common/inject/name/NamedImpl.java index 7c43e7c5a73..e4cc088e30a 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/name/NamedImpl.java +++ b/core/src/main/java/org/elasticsearch/common/inject/name/NamedImpl.java @@ -16,11 +16,10 @@ package org.elasticsearch.common.inject.name; -import java.io.Serializable; import java.lang.annotation.Annotation; import java.util.Objects; -class NamedImpl implements Named, Serializable { +class NamedImpl implements Named { private final String value; @@ -58,6 +57,4 @@ class NamedImpl implements Named, Serializable { public Class annotationType() { return Named.class; } - - private static final long serialVersionUID = 0; } diff --git a/core/src/main/java/org/elasticsearch/common/inject/spi/Message.java b/core/src/main/java/org/elasticsearch/common/inject/spi/Message.java index 5a39b9edf13..619feca805e 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/spi/Message.java +++ b/core/src/main/java/org/elasticsearch/common/inject/spi/Message.java @@ -20,9 +20,6 @@ import org.elasticsearch.common.inject.Binder; import org.elasticsearch.common.inject.internal.Errors; import org.elasticsearch.common.inject.internal.SourceProvider; -import java.io.ObjectStreamException; -import java.io.Serializable; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -40,7 +37,7 @@ import java.util.Objects; * * @author crazybob@google.com (Bob Lee) */ -public final class Message implements Serializable, Element { +public final class Message implements Element { private final String message; private final Throwable cause; private final List sources; @@ -131,18 +128,4 @@ public final class Message implements Serializable, Element { public void applyTo(Binder binder) { binder.withSource(getSource()).addError(this); } - - /** - * When serialized, we eagerly convert sources to strings. This hurts our formatting, but it - * guarantees that the receiving end will be able to read the message. - */ - private Object writeReplace() throws ObjectStreamException { - Object[] sourcesAsStrings = sources.toArray(); - for (int i = 0; i < sourcesAsStrings.length; i++) { - sourcesAsStrings[i] = Errors.convert(sourcesAsStrings[i]).toString(); - } - return new Message(Arrays.asList(sourcesAsStrings), message, cause); - } - - private static final long serialVersionUID = 0; } \ No newline at end of file diff --git a/core/src/main/java/org/elasticsearch/common/inject/util/Types.java b/core/src/main/java/org/elasticsearch/common/inject/util/Types.java index 43bb97c1499..a3f42a0d374 100644 --- a/core/src/main/java/org/elasticsearch/common/inject/util/Types.java +++ b/core/src/main/java/org/elasticsearch/common/inject/util/Types.java @@ -45,7 +45,7 @@ public final class Types { * Returns a new parameterized type, applying {@code typeArguments} to * {@code rawType}. The returned type does not have an owner type. * - * @return a {@link java.io.Serializable serializable} parameterized type. + * @return a parameterized type. */ public static ParameterizedType newParameterizedType(Type rawType, Type... typeArguments) { return newParameterizedTypeWithOwner(null, rawType, typeArguments); @@ -55,7 +55,7 @@ public final class Types { * Returns a new parameterized type, applying {@code typeArguments} to * {@code rawType} and enclosed by {@code ownerType}. * - * @return a {@link java.io.Serializable serializable} parameterized type. + * @return a parameterized type. */ public static ParameterizedType newParameterizedTypeWithOwner( Type ownerType, Type rawType, Type... typeArguments) { @@ -66,7 +66,7 @@ public final class Types { * Returns an array type whose elements are all instances of * {@code componentType}. * - * @return a {@link java.io.Serializable serializable} generic array type. + * @return a generic array type. */ public static GenericArrayType arrayOf(Type componentType) { return new GenericArrayTypeImpl(componentType); @@ -95,7 +95,7 @@ public final class Types { * Returns a type modelling a {@link List} whose elements are of type * {@code elementType}. * - * @return a {@link java.io.Serializable serializable} parameterized type. + * @return a parameterized type. */ public static ParameterizedType listOf(Type elementType) { return newParameterizedType(List.class, elementType); @@ -105,7 +105,7 @@ public final class Types { * Returns a type modelling a {@link Set} whose elements are of type * {@code elementType}. * - * @return a {@link java.io.Serializable serializable} parameterized type. + * @return a parameterized type. */ public static ParameterizedType setOf(Type elementType) { return newParameterizedType(Set.class, elementType); @@ -115,7 +115,7 @@ public final class Types { * Returns a type modelling a {@link Map} whose keys are of type * {@code keyType} and whose values are of type {@code valueType}. * - * @return a {@link java.io.Serializable serializable} parameterized type. + * @return a parameterized type. */ public static ParameterizedType mapOf(Type keyType, Type valueType) { return newParameterizedType(Map.class, keyType, valueType); @@ -127,7 +127,7 @@ public final class Types { * Returns a type modelling a {@link Provider} that provides elements of type * {@code elementType}. * - * @return a {@link java.io.Serializable serializable} parameterized type. + * @return a parameterized type. */ public static ParameterizedType providerOf(Type providedType) { return newParameterizedType(Provider.class, providedType); diff --git a/core/src/main/java/org/elasticsearch/common/joda/Joda.java b/core/src/main/java/org/elasticsearch/common/joda/Joda.java index 34ca5f77da5..b65a248c21f 100644 --- a/core/src/main/java/org/elasticsearch/common/joda/Joda.java +++ b/core/src/main/java/org/elasticsearch/common/joda/Joda.java @@ -296,8 +296,6 @@ public class Joda { public static final DurationFieldType Quarters = new DurationFieldType("quarters") { - private static final long serialVersionUID = -8167713675442491871L; - @Override public DurationField getField(Chronology chronology) { return new ScaledDurationField(chronology.months(), Quarters, 3); @@ -305,8 +303,6 @@ public class Joda { }; public static final DateTimeFieldType QuarterOfYear = new DateTimeFieldType("quarterOfYear") { - private static final long serialVersionUID = -5677872459807379123L; - @Override public DurationFieldType getDurationType() { return Quarters; diff --git a/core/src/main/java/org/elasticsearch/common/logging/jdk/ESLogRecord.java b/core/src/main/java/org/elasticsearch/common/logging/jdk/ESLogRecord.java index d4c64218c1d..c462262e9e9 100644 --- a/core/src/main/java/org/elasticsearch/common/logging/jdk/ESLogRecord.java +++ b/core/src/main/java/org/elasticsearch/common/logging/jdk/ESLogRecord.java @@ -30,8 +30,6 @@ import java.util.logging.LogRecord; * information of the code calling the logger */ public class ESLogRecord extends LogRecord { - - private static final long serialVersionUID = 1107741560233585726L; private static final String FQCN = AbstractESLogger.class.getName(); private String sourceClassName; private String sourceMethodName; diff --git a/core/src/main/java/org/elasticsearch/common/util/concurrent/BaseFuture.java b/core/src/main/java/org/elasticsearch/common/util/concurrent/BaseFuture.java index 5fcb1a8f152..84e1f204ac8 100644 --- a/core/src/main/java/org/elasticsearch/common/util/concurrent/BaseFuture.java +++ b/core/src/main/java/org/elasticsearch/common/util/concurrent/BaseFuture.java @@ -180,9 +180,6 @@ public abstract class BaseFuture implements Future { * pass around a -1 everywhere. */ static final class Sync extends AbstractQueuedSynchronizer { - - private static final long serialVersionUID = 0L; - /* Valid states. */ static final int RUNNING = 0; static final int COMPLETING = 1; diff --git a/core/src/main/java/org/elasticsearch/script/ClassPermission.java b/core/src/main/java/org/elasticsearch/script/ClassPermission.java index eb580bac3ea..0effe85578a 100644 --- a/core/src/main/java/org/elasticsearch/script/ClassPermission.java +++ b/core/src/main/java/org/elasticsearch/script/ClassPermission.java @@ -72,8 +72,6 @@ import java.util.Set; * */ public final class ClassPermission extends BasicPermission { - private static final long serialVersionUID = 3530711429252193884L; - public static final String STANDARD = "<>"; /** Typical set of classes for scripting: basic data types, math, dates, and simple collections */ // this is the list from the old grovy sandbox impl (+ some things like String, Iterator, etc that were missing) @@ -109,17 +107,17 @@ public final class ClassPermission extends BasicPermission { /** * Creates a new ClassPermission object. - * + * * @param name class to grant permission to */ public ClassPermission(String name) { super(name); } - + /** * Creates a new ClassPermission object. * This constructor exists for use by the {@code Policy} object to instantiate new Permission objects. - * + * * @param name class to grant permission to * @param actions ignored */ @@ -144,8 +142,6 @@ public final class ClassPermission extends BasicPermission { // BasicPermissionCollection only handles wildcards, we expand <> here PermissionCollection impl = super.newPermissionCollection(); return new PermissionCollection() { - private static final long serialVersionUID = 6792220143549780002L; - @Override public void add(Permission permission) { if (permission instanceof ClassPermission && STANDARD.equals(permission.getName())) { @@ -156,12 +152,12 @@ public final class ClassPermission extends BasicPermission { impl.add(permission); } } - + @Override public boolean implies(Permission permission) { return impl.implies(permission); } - + @Override public Enumeration elements() { return impl.elements(); diff --git a/core/src/main/java/org/joda/time/base/BaseDateTime.java b/core/src/main/java/org/joda/time/base/BaseDateTime.java index 4cf6ff6b50e..29c34246249 100644 --- a/core/src/main/java/org/joda/time/base/BaseDateTime.java +++ b/core/src/main/java/org/joda/time/base/BaseDateTime.java @@ -24,8 +24,6 @@ import org.joda.time.chrono.ISOChronology; import org.joda.time.convert.ConverterManager; import org.joda.time.convert.InstantConverter; -import java.io.Serializable; - /** * BaseDateTime is an abstract implementation of ReadableDateTime that stores * data in long and Chronology fields. @@ -43,13 +41,7 @@ import java.io.Serializable; */ public abstract class BaseDateTime extends AbstractDateTime - implements ReadableDateTime, Serializable { - - /** - * Serialization lock - */ - private static final long serialVersionUID = -6728882245981L; - + implements ReadableDateTime { /** * The millis from 1970-01-01T00:00:00Z */ diff --git a/plugins/discovery-azure/build.gradle b/plugins/discovery-azure/build.gradle index f6b56c9823a..2451672f1d1 100644 --- a/plugins/discovery-azure/build.gradle +++ b/plugins/discovery-azure/build.gradle @@ -56,7 +56,7 @@ dependencyLicenses { mapping from: /jaxb-.*/, to: 'jaxb' } -compileJava.options.compilerArgs << '-Xlint:-path,-serial,-unchecked' +compileJava.options.compilerArgs << '-Xlint:-path,-unchecked' thirdPartyAudit.excludes = [ // classes are missing diff --git a/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeList.java b/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeList.java index 1bf555db81e..dc533e5881e 100644 --- a/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeList.java +++ b/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeList.java @@ -31,7 +31,6 @@ import java.util.List; * */ public class NativeList extends NativeJavaObject implements Scriptable, Wrapper { - private static final long serialVersionUID = 3664761893203964569L; private static final String LENGTH_PROPERTY = "length"; private final List list; diff --git a/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeMap.java b/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeMap.java index ef9be14b0dd..8d7373cb8a0 100644 --- a/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeMap.java +++ b/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/NativeMap.java @@ -19,20 +19,18 @@ package org.elasticsearch.script.javascript.support; -import java.util.Iterator; -import java.util.Map; - import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Wrapper; +import java.util.Iterator; +import java.util.Map; + /** * Wrapper for exposing maps in Rhino scripts. * * */ public class NativeMap implements Scriptable, Wrapper { - private static final long serialVersionUID = 3664761893203964569L; - private Map map; private Scriptable parentScope; private Scriptable prototype; diff --git a/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/ScriptableLinkedHashMap.java b/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/ScriptableLinkedHashMap.java index f4df25f0861..001711f818b 100644 --- a/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/ScriptableLinkedHashMap.java +++ b/plugins/lang-javascript/src/main/java/org/elasticsearch/script/javascript/support/ScriptableLinkedHashMap.java @@ -19,12 +19,12 @@ package org.elasticsearch.script.javascript.support; +import org.mozilla.javascript.Scriptable; + import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; -import org.mozilla.javascript.Scriptable; - /** * Implementation of a Scriptable Map. This is the best choice for maps that want to represent * JavaScript associative arrays - allowing access via key and integer index. It maintains and @@ -33,8 +33,6 @@ import org.mozilla.javascript.Scriptable; * */ public class ScriptableLinkedHashMap extends LinkedHashMap implements ScriptableMap { - private static final long serialVersionUID = 3774167893214964123L; - private Scriptable parentScope; private Scriptable prototype; diff --git a/plugins/repository-azure/build.gradle b/plugins/repository-azure/build.gradle index 85a927c02f9..122bd6dfa80 100644 --- a/plugins/repository-azure/build.gradle +++ b/plugins/repository-azure/build.gradle @@ -35,5 +35,3 @@ dependencyLicenses { mapping from: /stax-.*/, to: 'stax' } -compileJava.options.compilerArgs << '-Xlint:-serial' - diff --git a/test/framework/build.gradle b/test/framework/build.gradle index 46728d06283..355459f99f5 100644 --- a/test/framework/build.gradle +++ b/test/framework/build.gradle @@ -33,7 +33,7 @@ dependencies { compile 'org.elasticsearch:securemock:1.2' } -compileJava.options.compilerArgs << '-Xlint:-cast,-rawtypes,-serial,-try,-unchecked' +compileJava.options.compilerArgs << '-Xlint:-cast,-rawtypes,-try,-unchecked' compileTestJava.options.compilerArgs << '-Xlint:-rawtypes' // the main files are actually test files, so use the appopriate forbidden api sigs From 42134cca4d8e61b79b7362f975d092890eecba3a Mon Sep 17 00:00:00 2001 From: Ali Beyad Date: Mon, 11 Jan 2016 17:04:20 -0500 Subject: [PATCH 08/21] Fixes an issue where, if the content type of the request body could not be determined, the UpdateRequest would still try to parse the content instead of throwing the standard ElasticsearchParseException. This manifests when passing illegal JSON in the request body that does not begin with a '{'. By trying to parse the content from an unknown request body content type, the UpdateRequest was throwing a null pointer exception. This has been fixed to throw an ElasticsearchParseException, to be consistent with the behavior of all other requests in the face of undecipherable request content types. Closes #15822 --- .../elasticsearch/action/update/UpdateRequest.java | 5 +++-- .../common/xcontent/XContentFactory.java | 3 +++ .../action/update/UpdateRequestTests.java | 12 ++++++++++++ .../common/xcontent/XContentFactoryTests.java | 8 ++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/update/UpdateRequest.java b/core/src/main/java/org/elasticsearch/action/update/UpdateRequest.java index 9e061d29500..6bc69ed4d9c 100644 --- a/core/src/main/java/org/elasticsearch/action/update/UpdateRequest.java +++ b/core/src/main/java/org/elasticsearch/action/update/UpdateRequest.java @@ -639,8 +639,7 @@ public class UpdateRequest extends InstanceShardOperationRequest ScriptParameterParser scriptParameterParser = new ScriptParameterParser(); Map scriptParams = null; Script script = null; - XContentType xContentType = XContentFactory.xContentType(source); - try (XContentParser parser = XContentFactory.xContent(xContentType).createParser(source)) { + try (XContentParser parser = XContentFactory.xContent(source).createParser(source)) { XContentParser.Token token = parser.nextToken(); if (token == null) { return this; @@ -657,10 +656,12 @@ public class UpdateRequest extends InstanceShardOperationRequest } else if ("scripted_upsert".equals(currentFieldName)) { scriptedUpsert = parser.booleanValue(); } else if ("upsert".equals(currentFieldName)) { + XContentType xContentType = XContentFactory.xContentType(source); XContentBuilder builder = XContentFactory.contentBuilder(xContentType); builder.copyCurrentStructure(parser); safeUpsertRequest().source(builder); } else if ("doc".equals(currentFieldName)) { + XContentType xContentType = XContentFactory.xContentType(source); XContentBuilder docBuilder = XContentFactory.contentBuilder(xContentType); docBuilder.copyCurrentStructure(parser); safeDoc().source(docBuilder); diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentFactory.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentFactory.java index 627486548cd..47dd1249d4a 100644 --- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentFactory.java +++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentFactory.java @@ -133,6 +133,9 @@ public class XContentFactory { * Returns the {@link org.elasticsearch.common.xcontent.XContent} for the provided content type. */ public static XContent xContent(XContentType type) { + if (type == null) { + throw new IllegalArgumentException("Cannot get xcontent for unknown type"); + } return type.xContent(); } diff --git a/core/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java b/core/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java index 51053f63a01..55260957105 100644 --- a/core/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java +++ b/core/src/test/java/org/elasticsearch/action/update/UpdateRequestTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.update; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.Version; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.common.io.stream.Streamable; @@ -166,4 +167,15 @@ public class UpdateRequestTests extends ESTestCase { indexAction = (IndexRequest) action; assertThat(indexAction.ttl(), is(providedTTLValue)); } + + // Related to issue #15822 + public void testInvalidBodyThrowsParseException() throws Exception { + UpdateRequest request = new UpdateRequest("test", "type", "1"); + try { + request.source(new byte[] { (byte) '"' }); + fail("Should have thrown a ElasticsearchParseException"); + } catch (ElasticsearchParseException e) { + assertThat(e.getMessage(), equalTo("Failed to derive xcontent")); + } + } } diff --git a/core/src/test/java/org/elasticsearch/common/xcontent/XContentFactoryTests.java b/core/src/test/java/org/elasticsearch/common/xcontent/XContentFactoryTests.java index 9b1cfb64573..583234461b3 100644 --- a/core/src/test/java/org/elasticsearch/common/xcontent/XContentFactoryTests.java +++ b/core/src/test/java/org/elasticsearch/common/xcontent/XContentFactoryTests.java @@ -97,6 +97,14 @@ public class XContentFactoryTests extends ESTestCase { assertNull(XContentFactory.xContentType(is)); } + public void testInvalidStream() throws Exception { + byte[] bytes = new byte[] { (byte) '"' }; + assertNull(XContentFactory.xContentType(bytes)); + + bytes = new byte[] { (byte) 'x' }; + assertNull(XContentFactory.xContentType(bytes)); + } + public void testJsonFromBytesOptionallyPrecededByUtf8Bom() throws Exception { byte[] bytes = new byte[] {(byte) '{', (byte) '}'}; assertThat(XContentFactory.xContentType(bytes), equalTo(XContentType.JSON)); From 5ded9ac9eb1360dda6ac75cff9ea268e75fff9b4 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Mon, 11 Jan 2016 21:36:16 -0500 Subject: [PATCH 09/21] Stop using deprecated constructors for queries DisjunctionMaxQuery and BooleanQuery --- .../lucene/queries/BlendedTermQuery.java | 9 ++-- .../classic/MapperQueryParser.java | 42 +++++++++---------- .../common/lucene/search/XMoreLikeThis.java | 10 ++--- .../index/query/MoreLikeThisQueryBuilder.java | 6 +-- .../index/search/MultiMatchQuery.java | 6 +-- .../lucene/queries/BlendedTermQueryTests.java | 15 +++---- 6 files changed, 43 insertions(+), 45 deletions(-) diff --git a/core/src/main/java/org/apache/lucene/queries/BlendedTermQuery.java b/core/src/main/java/org/apache/lucene/queries/BlendedTermQuery.java index 645929d3992..798fac01a7a 100644 --- a/core/src/main/java/org/apache/lucene/queries/BlendedTermQuery.java +++ b/core/src/main/java/org/apache/lucene/queries/BlendedTermQuery.java @@ -36,6 +36,7 @@ import org.apache.lucene.util.InPlaceMergeSorter; import org.apache.lucene.util.ToStringUtils; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -326,7 +327,7 @@ public abstract class BlendedTermQuery extends Query { } if ((maxTermFrequency >= 1f && docFreqs[i] > maxTermFrequency) || (docFreqs[i] > (int) Math.ceil(maxTermFrequency - * (float) maxDoc))) { + * maxDoc))) { highBuilder.add(query, BooleanClause.Occur.SHOULD); } else { lowBuilder.add(query, BooleanClause.Occur.SHOULD); @@ -362,15 +363,15 @@ public abstract class BlendedTermQuery extends Query { return new BlendedTermQuery(terms, boosts) { @Override protected Query topLevelQuery(Term[] terms, TermContext[] ctx, int[] docFreqs, int maxDoc) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreakerMultiplier); + List queries = new ArrayList<>(ctx.length); for (int i = 0; i < terms.length; i++) { Query query = new TermQuery(terms[i], ctx[i]); if (boosts != null && boosts[i] != 1f) { query = new BoostQuery(query, boosts[i]); } - disMaxQuery.add(query); + queries.add(query); } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, tieBreakerMultiplier); } }; } diff --git a/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java b/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java index 89eedce09d8..f153cd53c55 100644 --- a/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java +++ b/core/src/main/java/org/apache/lucene/queryparser/classic/MapperQueryParser.java @@ -142,19 +142,19 @@ public class MapperQueryParser extends QueryParser { return getFieldQuerySingle(fields.iterator().next(), queryText, quoted); } if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = getFieldQuerySingle(mField, queryText, quoted); if (q != null) { added = true; - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { @@ -242,20 +242,20 @@ public class MapperQueryParser extends QueryParser { Collection fields = extractMultiFields(field); if (fields != null) { if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = super.getFieldQuery(mField, queryText, slop); if (q != null) { added = true; q = applySlop(q, slop); - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { @@ -295,19 +295,19 @@ public class MapperQueryParser extends QueryParser { } if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = getRangeQuerySingle(mField, part1, part2, startInclusive, endInclusive); if (q != null) { added = true; - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { @@ -359,19 +359,19 @@ public class MapperQueryParser extends QueryParser { return getFuzzyQuerySingle(fields.iterator().next(), termStr, minSimilarity); } if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = getFuzzyQuerySingle(mField, termStr, minSimilarity); if (q != null) { added = true; - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { @@ -422,19 +422,19 @@ public class MapperQueryParser extends QueryParser { return getPrefixQuerySingle(fields.iterator().next(), termStr); } if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = getPrefixQuerySingle(mField, termStr); if (q != null) { added = true; - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { @@ -552,19 +552,19 @@ public class MapperQueryParser extends QueryParser { return getWildcardQuerySingle(fields.iterator().next(), termStr); } if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = getWildcardQuerySingle(mField, termStr); if (q != null) { added = true; - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { @@ -681,19 +681,19 @@ public class MapperQueryParser extends QueryParser { return getRegexpQuerySingle(fields.iterator().next(), termStr); } if (settings.useDisMax()) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker()); + List queries = new ArrayList<>(); boolean added = false; for (String mField : fields) { Query q = getRegexpQuerySingle(mField, termStr); if (q != null) { added = true; - disMaxQuery.add(applyBoost(mField, q)); + queries.add(applyBoost(mField, q)); } } if (!added) { return null; } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, settings.tieBreaker()); } else { List clauses = new ArrayList<>(); for (String mField : fields) { diff --git a/core/src/main/java/org/elasticsearch/common/lucene/search/XMoreLikeThis.java b/core/src/main/java/org/elasticsearch/common/lucene/search/XMoreLikeThis.java index 16378523b5c..e973689615e 100644 --- a/core/src/main/java/org/elasticsearch/common/lucene/search/XMoreLikeThis.java +++ b/core/src/main/java/org/elasticsearch/common/lucene/search/XMoreLikeThis.java @@ -656,7 +656,7 @@ public final class XMoreLikeThis { } } // term selection is per field, then appended to a single boolean query - BooleanQuery bq = new BooleanQuery(); + BooleanQuery.Builder bq = new BooleanQuery.Builder(); for (String fieldName : fieldNames) { Map termFreqMap = new HashMap<>(); for (Fields fields : likeFields) { @@ -667,22 +667,22 @@ public final class XMoreLikeThis { } addToQuery(createQueue(termFreqMap, fieldName), bq); } - return bq; + return bq.build(); } /** * Create the More like query from a PriorityQueue */ private Query createQuery(PriorityQueue q) { - BooleanQuery query = new BooleanQuery(); + BooleanQuery.Builder query = new BooleanQuery.Builder(); addToQuery(q, query); - return query; + return query.build(); } /** * Add to an existing boolean query the More Like This query from this PriorityQueue */ - private void addToQuery(PriorityQueue q, BooleanQuery query) { + private void addToQuery(PriorityQueue q, BooleanQuery.Builder query) { ScoreTerm scoreTerm; float bestScore = -1; diff --git a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java index df9dcb497d0..ffb21a32dd0 100644 --- a/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/MoreLikeThisQueryBuilder.java @@ -875,14 +875,14 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder moreLikeFields, @@ -949,7 +949,7 @@ public class MoreLikeThisQueryBuilder extends AbstractQueryBuilder uids = new ArrayList<>(); for (Item item : likeItems) { diff --git a/core/src/main/java/org/elasticsearch/index/search/MultiMatchQuery.java b/core/src/main/java/org/elasticsearch/index/search/MultiMatchQuery.java index cf30c3dbe47..7e7118ba329 100644 --- a/core/src/main/java/org/elasticsearch/index/search/MultiMatchQuery.java +++ b/core/src/main/java/org/elasticsearch/index/search/MultiMatchQuery.java @@ -128,11 +128,11 @@ public class MultiMatchQuery extends MatchQuery { return groupQuery.get(0); } if (groupDismax) { - DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker); + List queries = new ArrayList<>(); for (Query query : groupQuery) { - disMaxQuery.add(query); + queries.add(query); } - return disMaxQuery; + return new DisjunctionMaxQuery(queries, tieBreaker); } else { final BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder(); for (Query query : groupQuery) { diff --git a/core/src/test/java/org/apache/lucene/queries/BlendedTermQueryTests.java b/core/src/test/java/org/apache/lucene/queries/BlendedTermQueryTests.java index 725b1bd4400..39b4df44059 100644 --- a/core/src/test/java/org/apache/lucene/queries/BlendedTermQueryTests.java +++ b/core/src/test/java/org/apache/lucene/queries/BlendedTermQueryTests.java @@ -159,16 +159,13 @@ public class BlendedTermQueryTests extends ESTestCase { { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.setDisableCoord(true); - DisjunctionMaxQuery uname = new DisjunctionMaxQuery(0.0f); - uname.add(new TermQuery(new Term("username", "foo"))); - uname.add(new TermQuery(new Term("song", "foo"))); + DisjunctionMaxQuery uname = new DisjunctionMaxQuery( + Arrays.asList(new TermQuery(new Term("username", "foo")), new TermQuery(new Term("song", "foo"))), 0.0f); - DisjunctionMaxQuery s = new DisjunctionMaxQuery(0.0f); - s.add(new TermQuery(new Term("username", "fighers"))); - s.add(new TermQuery(new Term("song", "fighers"))); - DisjunctionMaxQuery gen = new DisjunctionMaxQuery(0f); - gen.add(new TermQuery(new Term("username", "generator"))); - gen.add(new TermQuery(new Term("song", "generator"))); + DisjunctionMaxQuery s = new DisjunctionMaxQuery( + Arrays.asList(new TermQuery(new Term("username", "fighers")), new TermQuery(new Term("song", "fighers"))), 0.0f); + DisjunctionMaxQuery gen = new DisjunctionMaxQuery( + Arrays.asList(new TermQuery(new Term("username", "generator")), new TermQuery(new Term("song", "generator"))), 0f); query.add(uname, BooleanClause.Occur.SHOULD); query.add(s, BooleanClause.Occur.SHOULD); query.add(gen, BooleanClause.Occur.SHOULD); From ae0bf1b32f1c741101ba7bc57bc1dba71574569b Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Mon, 11 Jan 2016 21:47:32 -0500 Subject: [PATCH 10/21] Deprecate span_near's collect_payloads --- .../index/query/SpanNearQueryBuilder.java | 28 +----- .../index/query/SpanNearQueryParser.java | 6 +- .../query/QueryDSLDocumentationTests.java | 3 +- .../SpanContainingQueryBuilderTests.java | 69 +++++++------ .../query/SpanNearQueryBuilderTests.java | 97 +++++++++++++------ .../index/query/SpanNotQueryBuilderTests.java | 73 +++++++------- .../query/SpanWithinQueryBuilderTests.java | 69 +++++++------ docs/reference/migration/migrate_3_0.asciidoc | 4 + .../query-dsl/span-near-query.asciidoc | 3 +- 9 files changed, 180 insertions(+), 172 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java index 9066262810c..80eb94f4276 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryBuilder.java @@ -43,17 +43,12 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder clauses = new ArrayList<>(); private final int slop; private boolean inOrder = DEFAULT_IN_ORDER; - private boolean collectPayloads = DEFAULT_COLLECT_PAYLOADS; - static final SpanNearQueryBuilder PROTOTYPE = new SpanNearQueryBuilder(SpanTermQueryBuilder.PROTOTYPE, 0); /** @@ -107,21 +102,6 @@ public class SpanNearQueryBuilder extends AbstractQueryBuilder { public static final ParseField COLLECT_PAYLOADS_FIELD = new ParseField("collect_payloads"); public static final ParseField CLAUSES_FIELD = new ParseField("clauses"); public static final ParseField IN_ORDER_FIELD = new ParseField("in_order"); - + @Override public String[] names() { return new String[]{SpanNearQueryBuilder.NAME, Strings.toCamelCase(SpanNearQueryBuilder.NAME)}; @@ -50,7 +50,6 @@ public class SpanNearQueryParser implements QueryParser { float boost = AbstractQueryBuilder.DEFAULT_BOOST; Integer slop = null; boolean inOrder = SpanNearQueryBuilder.DEFAULT_IN_ORDER; - boolean collectPayloads = SpanNearQueryBuilder.DEFAULT_COLLECT_PAYLOADS; String queryName = null; List clauses = new ArrayList<>(); @@ -76,7 +75,7 @@ public class SpanNearQueryParser implements QueryParser { if (parseContext.parseFieldMatcher().match(currentFieldName, IN_ORDER_FIELD)) { inOrder = parser.booleanValue(); } else if (parseContext.parseFieldMatcher().match(currentFieldName, COLLECT_PAYLOADS_FIELD)) { - collectPayloads = parser.booleanValue(); + // Deprecated in 3.0.0 } else if (parseContext.parseFieldMatcher().match(currentFieldName, SLOP_FIELD)) { slop = parser.intValue(); } else if (parseContext.parseFieldMatcher().match(currentFieldName, AbstractQueryBuilder.BOOST_FIELD)) { @@ -104,7 +103,6 @@ public class SpanNearQueryParser implements QueryParser { queryBuilder.clause(clauses.get(i)); } queryBuilder.inOrder(inOrder); - queryBuilder.collectPayloads(collectPayloads); queryBuilder.boost(boost); queryBuilder.queryName(queryName); return queryBuilder; diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java index 028987448f0..65c2ee046fe 100644 --- a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java @@ -331,8 +331,7 @@ public class QueryDSLDocumentationTests extends ESTestCase { spanNearQuery(spanTermQuery("field","value1"), 12) .clause(spanTermQuery("field","value2")) .clause(spanTermQuery("field","value3")) - .inOrder(false) - .collectPayloads(false); + .inOrder(false); } public void testSpanNot() { diff --git a/core/src/test/java/org/elasticsearch/index/query/SpanContainingQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/SpanContainingQueryBuilderTests.java index 79089b57fb4..f6d18447c94 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SpanContainingQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SpanContainingQueryBuilderTests.java @@ -56,41 +56,40 @@ public class SpanContainingQueryBuilderTests extends AbstractQueryTestCase Date: Tue, 12 Jan 2016 10:36:46 +0000 Subject: [PATCH 11/21] updated to use dynamic plugins tag --- docs/reference/modules/scripting.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/modules/scripting.asciidoc b/docs/reference/modules/scripting.asciidoc index 53786fa41ea..96b36944fb8 100644 --- a/docs/reference/modules/scripting.asciidoc +++ b/docs/reference/modules/scripting.asciidoc @@ -77,8 +77,8 @@ supported scripting languages: |groovy |no |built-in |expression |yes |built-in |mustache |yes |built-in -|javascript |no |https://www.elastic.co/guide/en/elasticsearch/plugins/current/lang-javascript.html[elasticsearch-lang-javascript] -|python |no |https://www.elastic.co/guide/en/elasticsearch/plugins/current/lang-python.html[elasticsearch-lang-python] +|javascript |no |{plugins}/lang-javascript.html[elasticsearch-lang-javascript] +|python |no |{plugins}/lang-python.html[elasticsearch-lang-python] |======================================================================= To increase security, Elasticsearch does not allow you to specify scripts for From 77e9eed6f18f22895e91161993358bbd84918d59 Mon Sep 17 00:00:00 2001 From: Felipe Forbeck Date: Wed, 16 Dec 2015 23:55:53 -0200 Subject: [PATCH 12/21] Docs explanation for unassigned shard reason codes. Fixes #14001 Closes #15912 --- docs/reference/cat/shards.asciidoc | 33 +++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/reference/cat/shards.asciidoc b/docs/reference/cat/shards.asciidoc index a4359af258e..294b622bc8f 100644 --- a/docs/reference/cat/shards.asciidoc +++ b/docs/reference/cat/shards.asciidoc @@ -15,6 +15,7 @@ wiki1 1 p STARTED 3013 29.6mb 192.168.56.30 Frankie Raye wiki1 2 p STARTED 3973 38.1mb 192.168.56.20 Commander Kraken -------------------------------------------------- +[float] [[index-pattern]] === Index pattern @@ -31,6 +32,7 @@ wiki2 2 p STARTED 275 7.8mb 192.168.56.20 Commander Kraken -------------------------------------------------- +[float] [[relocation]] === Relocation @@ -46,6 +48,7 @@ wiki1 0 r RELOCATING 3014 31.1mb 192.168.56.20 Commander Kraken -> 192.168.56.30 wiki1 1 r RELOCATING 3013 29.6mb 192.168.56.10 Stiletto -> 192.168.56.30 Frankie Raye -------------------------------------------------- +[float] [[states]] === Shard states @@ -66,8 +69,8 @@ wiki1 2 p STARTED 3973 38.1mb 192.168.56.20 Commander Kraken -------------------------------------------------- If a shard cannot be assigned, for example you've overallocated the -number of replicas for the number of nodes in the cluster, they will -remain `UNASSIGNED`. +number of replicas for the number of nodes in the cluster, the shard +will remain `UNASSIGNED` with the <> `ALLOCATION_FAILED`. [source,sh] -------------------------------------------------- @@ -78,13 +81,33 @@ remain `UNASSIGNED`. wiki1 0 p STARTED 3014 31.1mb 192.168.56.10 Stiletto wiki1 0 r STARTED 3014 31.1mb 192.168.56.30 Frankie Raye wiki1 0 r STARTED 3014 31.1mb 192.168.56.20 Commander Kraken -wiki1 0 r UNASSIGNED +wiki1 0 r UNASSIGNED ALLOCATION_FAILED wiki1 1 r STARTED 3013 29.6mb 192.168.56.10 Stiletto wiki1 1 p STARTED 3013 29.6mb 192.168.56.30 Frankie Raye wiki1 1 r STARTED 3013 29.6mb 192.168.56.20 Commander Kraken -wiki1 1 r UNASSIGNED +wiki1 1 r UNASSIGNED ALLOCATION_FAILED wiki1 2 r STARTED 3973 38.1mb 192.168.56.10 Stiletto wiki1 2 r STARTED 3973 38.1mb 192.168.56.30 Frankie Raye wiki1 2 p STARTED 3973 38.1mb 192.168.56.20 Commander Kraken -wiki1 2 r UNASSIGNED +wiki1 2 r UNASSIGNED ALLOCATION_FAILED -------------------------------------------------- + +[float] +[[reason-unassigned]] +=== Reasons for unassigned shard + +These are the possible reasons for a shard be in a unassigned state: + +[horizontal] +`INDEX_CREATED`:: Unassigned as a result of an API creation of an index. +`CLUSTER_RECOVERED`:: Unassigned as a result of a full cluster recovery. +`INDEX_REOPENED`:: Unassigned as a result of opening a closed index. +`DANGLING_INDEX_IMPORTED`:: Unassigned as a result of importing a dangling index. +`NEW_INDEX_RESTORED`:: Unassigned as a result of restoring into a new index. +`EXISTING_INDEX_RESTORED`:: Unassigned as a result of restoring into a closed index. +`REPLICA_ADDED`:: Unassigned as a result of explicit addition of a replica. +`ALLOCATION_FAILED`:: Unassigned as a result of a failed allocation of the shard. +`NODE_LEFT`:: Unassigned as a result of the node hosting it leaving the cluster. +`REROUTE_CANCELLED`:: Unassigned as a result of explicit cancel reroute command. +`REINITIALIZED`:: When a shard moves from started back to initializing, for example, with shadow replicas. +`REALLOCATED_REPLICA`:: A better replica location is identified and causes the existing replica allocation to be cancelled. From ff2593e74a6ac6d723a9aed4a9694b21273cb8c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Tue, 12 Jan 2016 11:43:04 +0100 Subject: [PATCH 13/21] Rename PointCollectionBuilder to CoordinatesBuilder Also renaming internal methods to reflect that they are dealing with jts coordinates. Also renamed the list() to build() method for creating the coordinates lists and adding constructors to PolygonBuilder that take CoordinatesBuilders and implicitely call build() on them. --- .../common/geo/builders/CircleBuilder.java | 3 +- ...lection.java => CoordinateCollection.java} | 57 +- ...stBuilder.java => CoordinatesBuilder.java} | 56 +- .../common/geo/builders/EnvelopeBuilder.java | 3 +- .../builders/GeometryCollectionBuilder.java | 3 +- .../geo/builders/LineStringBuilder.java | 55 +- .../geo/builders/MultiLineStringBuilder.java | 9 +- .../geo/builders/MultiPointBuilder.java | 24 +- .../geo/builders/MultiPolygonBuilder.java | 5 +- .../common/geo/builders/PointBuilder.java | 2 +- .../common/geo/builders/PolygonBuilder.java | 67 +- .../common/geo/builders/ShapeBuilder.java | 20 +- .../common/geo/builders/ShapeBuilders.java | 20 +- .../common/geo/ShapeBuilderTests.java | 737 +++++++++--------- .../geo/builders/LineStringBuilderTests.java | 10 +- .../geo/builders/MultiPointBuilderTests.java | 6 +- .../geo/builders/PolygonBuilderTests.java | 34 +- .../query/QueryDSLDocumentationTests.java | 16 +- .../elasticsearch/search/geo/GeoFilterIT.java | 119 ++- .../search/geo/GeoShapeQueryTests.java | 26 +- .../test/geo/RandomShapeGenerator.java | 12 +- 21 files changed, 665 insertions(+), 619 deletions(-) rename core/src/main/java/org/elasticsearch/common/geo/builders/{PointCollection.java => CoordinateCollection.java} (59%) rename core/src/main/java/org/elasticsearch/common/geo/builders/{PointListBuilder.java => CoordinatesBuilder.java} (60%) diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java index 16641aede20..c15e0d9130e 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CircleBuilder.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Circle; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.unit.DistanceUnit; @@ -35,7 +36,7 @@ public class CircleBuilder extends ShapeBuilder { public static final String FIELD_RADIUS = "radius"; public static final GeoShapeType TYPE = GeoShapeType.CIRCLE; - public static final CircleBuilder PROTOTYPE = new CircleBuilder(); + static final CircleBuilder PROTOTYPE = new CircleBuilder(); private DistanceUnit unit = DistanceUnit.DEFAULT; private double radius; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinateCollection.java similarity index 59% rename from core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java rename to core/src/main/java/org/elasticsearch/common/geo/builders/CoordinateCollection.java index 58b85fff760..72ac7be8114 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointCollection.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinateCollection.java @@ -29,22 +29,23 @@ import java.util.Collection; import java.util.List; /** - * The {@link PointCollection} is an abstract base implementation for all GeoShapes. It simply handles a set of points. + * The {@link CoordinateCollection} is an abstract base implementation for {@link LineStringBuilder} and {@link MultiPointBuilder}. + * It holds a common list of {@link Coordinate}, provides setters for adding elements to the list and can render this to XContent. */ -public abstract class PointCollection> extends ShapeBuilder { +public abstract class CoordinateCollection> extends ShapeBuilder { - protected final List points; + protected final List coordinates; /** - * Construct a new collection of points. - * @param points an initial list of points - * @throws IllegalArgumentException if points is null or empty + * Construct a new collection of coordinates. + * @param coordinates an initial list of coordinates + * @throws IllegalArgumentException if coordinates is null or empty */ - protected PointCollection(List points) { - if (points == null || points.size() == 0) { + protected CoordinateCollection(List coordinates) { + if (coordinates == null || coordinates.size() == 0) { throw new IllegalArgumentException("cannot create point collection with empty set of points"); } - this.points = points; + this.coordinates = coordinates; } @SuppressWarnings("unchecked") @@ -53,54 +54,54 @@ public abstract class PointCollection> extends Shap } /** - * Add a new point to the collection + * Add a new coordinate to the collection * @param longitude longitude of the coordinate * @param latitude latitude of the coordinate * @return this */ - public E point(double longitude, double latitude) { - return this.point(coordinate(longitude, latitude)); + public E coordinate(double longitude, double latitude) { + return this.coordinate(new Coordinate(longitude, latitude)); } /** - * Add a new point to the collection + * Add a new coordinate to the collection * @param coordinate coordinate of the point * @return this */ - public E point(Coordinate coordinate) { - this.points.add(coordinate); + public E coordinate(Coordinate coordinate) { + this.coordinates.add(coordinate); return thisRef(); } /** - * Add a array of points to the collection + * Add a array of coordinates to the collection * * @param coordinates array of {@link Coordinate}s to add * @return this */ - public E points(Coordinate...coordinates) { - return this.points(Arrays.asList(coordinates)); + public E coordinates(Coordinate...coordinates) { + return this.coordinates(Arrays.asList(coordinates)); } /** - * Add a collection of points to the collection + * Add a collection of coordinates to the collection * * @param coordinates array of {@link Coordinate}s to add * @return this */ - public E points(Collection coordinates) { - this.points.addAll(coordinates); + public E coordinates(Collection coordinates) { + this.coordinates.addAll(coordinates); return thisRef(); } /** - * Copy all points to a new Array + * Copy all coordinate to a new Array * * @param closed if set to true the first point of the array is repeated as last element * @return Array of coordinates */ protected Coordinate[] coordinates(boolean closed) { - Coordinate[] result = points.toArray(new Coordinate[points.size() + (closed?1:0)]); + Coordinate[] result = coordinates.toArray(new Coordinate[coordinates.size() + (closed?1:0)]); if(closed) { result[result.length-1] = result[0]; } @@ -116,14 +117,14 @@ public abstract class PointCollection> extends Shap */ protected XContentBuilder coordinatesToXcontent(XContentBuilder builder, boolean closed) throws IOException { builder.startArray(); - for(Coordinate point : points) { - toXContent(builder, point); + for(Coordinate coord : coordinates) { + toXContent(builder, coord); } if(closed) { - Coordinate start = points.get(0); - Coordinate end = points.get(points.size()-1); + Coordinate start = coordinates.get(0); + Coordinate end = coordinates.get(coordinates.size()-1); if(start.x != end.x || start.y != end.y) { - toXContent(builder, points.get(0)); + toXContent(builder, coordinates.get(0)); } } builder.endArray(); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinatesBuilder.java similarity index 60% rename from core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java rename to core/src/main/java/org/elasticsearch/common/geo/builders/CoordinatesBuilder.java index febb3dcb5ba..43393d5e086 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointListBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/CoordinatesBuilder.java @@ -27,60 +27,60 @@ import java.util.Collection; import java.util.List; /** - * A builder for a list of points (of {@link Coordinate} type). - * Enables chaining of individual points either as long/lat pairs + * A builder for a list of coordinates. + * Enables chaining of individual coordinates either as long/lat pairs * or as {@link Coordinate} elements, arrays or collections. */ -public class PointListBuilder { +public class CoordinatesBuilder { private final List points = new ArrayList<>(); /** - * Add a new point to the collection - * @param longitude longitude of the coordinate - * @param latitude latitude of the coordinate + * Add a new coordinate to the collection + * @param coordinate the coordinate to add * @return this */ - public PointListBuilder point(double longitude, double latitude) { - return this.point(new Coordinate(longitude, latitude)); - } - - /** - * Add a new point to the collection - * @param coordinate coordinate of the point - * @return this - */ - public PointListBuilder point(Coordinate coordinate) { + public CoordinatesBuilder coordinate(Coordinate coordinate) { this.points.add(coordinate); return this; } /** - * Add a array of points to the collection - * - * @param coordinates array of {@link Coordinate}s to add + * Add a new coordinate to the collection + * @param longitude longitude of the coordinate + * @param latitude latitude of the coordinate * @return this */ - public PointListBuilder points(Coordinate...coordinates) { - return this.points(Arrays.asList(coordinates)); + public CoordinatesBuilder coordinate(double longitude, double latitude) { + return this.coordinate(new Coordinate(longitude, latitude)); } /** - * Add a collection of points to the collection + * Add an array of coordinates to the current coordinates * * @param coordinates array of {@link Coordinate}s to add * @return this */ - public PointListBuilder points(Collection coordinates) { + public CoordinatesBuilder coordinates(Coordinate...coordinates) { + return this.coordinates(Arrays.asList(coordinates)); + } + + /** + * Add a collection of coordinates to the current coordinates + * + * @param coordinates collection of {@link Coordinate}s to add + * @return this + */ + public CoordinatesBuilder coordinates(Collection coordinates) { this.points.addAll(coordinates); return this; } /** - * Closes the current list of points by adding the starting point as the end point - * if they are not already the same + * Makes a closed ring out of the current coordinates by adding the starting point as the end point. + * Will have no effect of starting and end point are already the same coordinate. */ - public PointListBuilder close() { + public CoordinatesBuilder close() { Coordinate start = points.get(0); Coordinate end = points.get(points.size()-1); if(start.x != end.x || start.y != end.y) { @@ -90,9 +90,9 @@ public class PointListBuilder { } /** - * @return the current list of points + * @return a list containing the current coordinates */ - public List list() { + public List build() { return new ArrayList<>(this.points); } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java index 708241c6666..9ad51292977 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/EnvelopeBuilder.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Rectangle; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -32,7 +33,7 @@ public class EnvelopeBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.ENVELOPE; - public static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(new Coordinate(-1.0, 1.0), new Coordinate(1.0, -1.0)); + static final EnvelopeBuilder PROTOTYPE = new EnvelopeBuilder(new Coordinate(-1.0, 1.0), new Coordinate(1.0, -1.0)); private Coordinate topLeft; private Coordinate bottomRight; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java index 5fc6b58e176..6e0094f7165 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/GeometryCollectionBuilder.java @@ -20,6 +20,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Shape; + import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.geo.XShapeCollection; import org.elasticsearch.common.io.stream.StreamInput; @@ -35,7 +36,7 @@ public class GeometryCollectionBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.GEOMETRYCOLLECTION; - public static final GeometryCollectionBuilder PROTOTYPE = new GeometryCollectionBuilder(); + static final GeometryCollectionBuilder PROTOTYPE = new GeometryCollectionBuilder(); protected final ArrayList shapes = new ArrayList<>(); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java index 48752d013ae..1f16037cd0d 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java @@ -24,14 +24,6 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -43,25 +35,29 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -public class LineStringBuilder extends PointCollection { +public class LineStringBuilder extends CoordinateCollection { /** * Construct a new LineString. * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) - * a LineString must contain two or more positions - * @param points the initial list of points - * @throw {@link IllegalArgumentException} if there are less then two points defined + * a LineString must contain two or more coordinates + * @param coordinates the initial list of coordinates + * @throw {@link IllegalArgumentException} if there are less then two coordinates defined */ - public LineStringBuilder(List points) { - super(points); - if (points.size() < 2) { - throw new IllegalArgumentException("invalid number of points in LineString (found [" + points.size()+ "] - must be >= 2)"); + public LineStringBuilder(List coordinates) { + super(coordinates); + if (coordinates.size() < 2) { + throw new IllegalArgumentException("invalid number of points in LineString (found [" + coordinates.size()+ "] - must be >= 2)"); } } + public LineStringBuilder(CoordinatesBuilder coordinates) { + this(coordinates.build()); + } + public static final GeoShapeType TYPE = GeoShapeType.LINESTRING; - public static final LineStringBuilder PROTOTYPE = new LineStringBuilder(new PointListBuilder().point(0.0, 0.0).point(1.0, 1.0).list()); + static final LineStringBuilder PROTOTYPE = new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).coordinate(1.0, 1.0)); @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { @@ -74,13 +70,14 @@ public class LineStringBuilder extends PointCollection { } /** - * Closes the current lineString by adding the starting point as the end point + * Closes the current lineString by adding the starting point as the end point. + * This will have no effect if starting and end point are already the same. */ public LineStringBuilder close() { - Coordinate start = points.get(0); - Coordinate end = points.get(points.size()-1); + Coordinate start = coordinates.get(0); + Coordinate end = coordinates.get(coordinates.size() - 1); if(start.x != end.x || start.y != end.y) { - points.add(start); + coordinates.add(start); } return this; } @@ -92,7 +89,7 @@ public class LineStringBuilder extends PointCollection { @Override public Shape build() { - Coordinate[] coordinates = points.toArray(new Coordinate[points.size()]); + Coordinate[] coordinates = this.coordinates.toArray(new Coordinate[this.coordinates.size()]); Geometry geometry; if(wrapdateline) { ArrayList strings = decompose(FACTORY, coordinates, new ArrayList()); @@ -171,7 +168,7 @@ public class LineStringBuilder extends PointCollection { @Override public int hashCode() { - return Objects.hash(points); + return Objects.hash(coordinates); } @Override @@ -183,25 +180,25 @@ public class LineStringBuilder extends PointCollection { return false; } LineStringBuilder other = (LineStringBuilder) obj; - return Objects.equals(points, other.points); + return Objects.equals(coordinates, other.coordinates); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(points.size()); - for (Coordinate point : points) { + out.writeVInt(coordinates.size()); + for (Coordinate point : coordinates) { writeCoordinateTo(point, out); } } @Override public LineStringBuilder readFrom(StreamInput in) throws IOException { - PointListBuilder pl = new PointListBuilder(); + CoordinatesBuilder coordinates = new CoordinatesBuilder(); int size = in.readVInt(); for (int i=0; i < size; i++) { - pl.point(readCoordinateFrom(in)); + coordinates.coordinate(readCoordinateFrom(in)); } - LineStringBuilder lineStringBuilder = new LineStringBuilder(pl.list()); + LineStringBuilder lineStringBuilder = new LineStringBuilder(coordinates); return lineStringBuilder; } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java index 4dc13454216..0de79ac8fe8 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiLineStringBuilder.java @@ -23,9 +23,6 @@ import com.spatial4j.core.shape.Shape; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LineString; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -40,7 +37,7 @@ public class MultiLineStringBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.MULTILINESTRING; - public static final MultiLineStringBuilder PROTOTYPE = new MultiLineStringBuilder(); + static final MultiLineStringBuilder PROTOTYPE = new MultiLineStringBuilder(); private final ArrayList lines = new ArrayList<>(); @@ -49,10 +46,6 @@ public class MultiLineStringBuilder extends ShapeBuilder { return this; } - public MultiLineStringBuilder linestring(Coordinate[] coordinates) { - return this.linestring(new LineStringBuilder(new PointListBuilder().points(coordinates).list())); - } - public Coordinate[][] coordinates() { Coordinate[][] result = new Coordinate[lines.size()][]; for (int i = 0; i < result.length; i++) { diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java index ebc5d822d3b..1ed976f43ee 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPointBuilder.java @@ -22,6 +22,7 @@ package org.elasticsearch.common.geo.builders; import com.spatial4j.core.shape.Point; import com.spatial4j.core.shape.Shape; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.common.geo.XShapeCollection; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -29,22 +30,21 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; -public class MultiPointBuilder extends PointCollection { +public class MultiPointBuilder extends CoordinateCollection { public static final GeoShapeType TYPE = GeoShapeType.MULTIPOINT; - public final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder(Arrays.asList(new Coordinate[]{new Coordinate(0.0, 0.0)})); + final static MultiPointBuilder PROTOTYPE = new MultiPointBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).build()); /** * Create a new {@link MultiPointBuilder}. - * @param points needs at least two points to be valid, otherwise will throw an exception + * @param coordinates needs at least two coordinates to be valid, otherwise will throw an exception */ - public MultiPointBuilder(List points) { - super(points); + public MultiPointBuilder(List coordinates) { + super(coordinates); } @Override @@ -61,8 +61,8 @@ public class MultiPointBuilder extends PointCollection { public Shape build() { //Could wrap JtsGeometry but probably slower due to conversions to/from JTS in relate() //MultiPoint geometry = FACTORY.createMultiPoint(points.toArray(new Coordinate[points.size()])); - List shapes = new ArrayList<>(points.size()); - for (Coordinate coord : points) { + List shapes = new ArrayList<>(coordinates.size()); + for (Coordinate coord : coordinates) { shapes.add(SPATIAL_CONTEXT.makePoint(coord.x, coord.y)); } XShapeCollection multiPoints = new XShapeCollection<>(shapes, SPATIAL_CONTEXT); @@ -77,7 +77,7 @@ public class MultiPointBuilder extends PointCollection { @Override public int hashCode() { - return Objects.hash(points); + return Objects.hash(coordinates); } @Override @@ -89,13 +89,13 @@ public class MultiPointBuilder extends PointCollection { return false; } MultiPointBuilder other = (MultiPointBuilder) obj; - return Objects.equals(points, other.points); + return Objects.equals(coordinates, other.coordinates); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeVInt(points.size()); - for (Coordinate point : points) { + out.writeVInt(coordinates.size()); + for (Coordinate point : coordinates) { writeCoordinateTo(point, out); } } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java index 37eafb57e9c..8d77d395155 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/MultiPolygonBuilder.java @@ -29,7 +29,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -37,7 +36,7 @@ import java.util.Objects; public class MultiPolygonBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.MULTIPOLYGON; - public static final MultiPolygonBuilder PROTOTYPE = new MultiPolygonBuilder(); + static final MultiPolygonBuilder PROTOTYPE = new MultiPolygonBuilder(); private final ArrayList polygons = new ArrayList<>(); @@ -60,7 +59,7 @@ public class MultiPolygonBuilder extends ShapeBuilder { * {@link MultiPolygonBuilder} to the polygon if polygon has different orientation. */ public MultiPolygonBuilder polygon(PolygonBuilder polygon) { - PolygonBuilder pb = new PolygonBuilder(Arrays.asList(polygon.shell().coordinates(false)), this.orientation); + PolygonBuilder pb = new PolygonBuilder(new CoordinatesBuilder().coordinates(polygon.shell().coordinates(false)), this.orientation); for (LineStringBuilder hole : polygon.holes()) { pb.hole(hole); } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java index 1cee6525e7a..40e57566d48 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PointBuilder.java @@ -32,7 +32,7 @@ import java.util.Objects; public class PointBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.POINT; - public static final PointBuilder PROTOTYPE = new PointBuilder(); + static final PointBuilder PROTOTYPE = new PointBuilder(); private Coordinate coordinate; diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java index 189b2c9ce86..36589a4a4a7 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/PolygonBuilder.java @@ -27,6 +27,7 @@ import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; + import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -52,8 +53,8 @@ import java.util.concurrent.atomic.AtomicBoolean; public class PolygonBuilder extends ShapeBuilder { public static final GeoShapeType TYPE = GeoShapeType.POLYGON; - public static final PolygonBuilder PROTOTYPE = new PolygonBuilder(new PointListBuilder().point(0.0, 0.0).point(0.0, 1.0) - .point(1.0, 0.0).point(0.0, 0.0).list()); + static final PolygonBuilder PROTOTYPE = new PolygonBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0).coordinate(0.0, 1.0) + .coordinate(1.0, 0.0).coordinate(0.0, 0.0)); private static final Coordinate[][] EMPTY = new Coordinate[0][]; @@ -65,17 +66,25 @@ public class PolygonBuilder extends ShapeBuilder { // List of line strings defining the holes of the polygon private final ArrayList holes = new ArrayList<>(); - public PolygonBuilder(List points, Orientation orientation) { - this(points, orientation, false); - } - - public PolygonBuilder(List points, Orientation orientation, boolean coerce) { + public PolygonBuilder(LineStringBuilder lineString, Orientation orientation, boolean coerce) { this.orientation = orientation; - this.shell = validateLinearRing(new LineStringBuilder(points), coerce); + if (coerce) { + lineString.close(); + } + validateLinearRing(lineString); + this.shell = lineString; } - public PolygonBuilder(List points) { - this(points, Orientation.RIGHT); + public PolygonBuilder(LineStringBuilder lineString, Orientation orientation) { + this(lineString, orientation, false); + } + + public PolygonBuilder(CoordinatesBuilder coordinates, Orientation orientation) { + this(new LineStringBuilder(coordinates), orientation, false); + } + + public PolygonBuilder(CoordinatesBuilder coordinates) { + this(coordinates, Orientation.RIGHT); } public Orientation orientation() { @@ -94,11 +103,15 @@ public class PolygonBuilder extends ShapeBuilder { /** * Add a new hole to the polygon * @param hole linear ring defining the hole - * @param coerce if set to true, will close the hole by adding starting point as end point + * @param coerce if set to true, it will try to close the hole by adding starting point as end point * @return this */ public PolygonBuilder hole(LineStringBuilder hole, boolean coerce) { - holes.add(validateLinearRing(hole, coerce)); + if (coerce) { + hole.close(); + } + validateLinearRing(hole); + holes.add(hole); return this; } @@ -124,36 +137,30 @@ public class PolygonBuilder extends ShapeBuilder { return this; } - private static LineStringBuilder validateLinearRing(LineStringBuilder linestring, boolean coerce) { + private static void validateLinearRing(LineStringBuilder lineString) { /** * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) * A LinearRing is closed LineString with 4 or more positions. The first and last positions * are equivalent (they represent equivalent points). Though a LinearRing is not explicitly * represented as a GeoJSON geometry type, it is referred to in the Polygon geometry type definition. */ - int numValidPts; - List points = linestring.points; - if (points.size() < (numValidPts = (coerce) ? 3 : 4)) { + List points = lineString.coordinates; + if (points.size() < 4) { throw new IllegalArgumentException( - "invalid number of points in LinearRing (found [" + points.size() + "] - must be >= " + numValidPts + ")"); + "invalid number of points in LinearRing (found [" + points.size() + "] - must be >= 4)"); } if (!points.get(0).equals(points.get(points.size() - 1))) { - if (coerce) { - points.add(points.get(0)); - } else { throw new IllegalArgumentException("invalid LinearRing found (coordinates are not closed)"); - } } - return linestring; } /** * Validates only 1 vertex is tangential (shared) between the interior and exterior of a polygon */ protected void validateHole(LineStringBuilder shell, LineStringBuilder hole) { - HashSet exterior = Sets.newHashSet(shell.points); - HashSet interior = Sets.newHashSet(hole.points); + HashSet exterior = Sets.newHashSet(shell.coordinates); + HashSet interior = Sets.newHashSet(hole.coordinates); exterior.retainAll(interior); if (exterior.size() >= 2) { throw new InvalidShapeException("Invalid polygon, interior cannot share more than one point with the exterior"); @@ -171,9 +178,9 @@ public class PolygonBuilder extends ShapeBuilder { * @return coordinates of the polygon */ public Coordinate[][][] coordinates() { - int numEdges = shell.points.size()-1; // Last point is repeated + int numEdges = shell.coordinates.size()-1; // Last point is repeated for (int i = 0; i < holes.size(); i++) { - numEdges += holes.get(i).points.size()-1; + numEdges += holes.get(i).coordinates.size()-1; validateHole(shell, this.holes.get(i)); } @@ -236,11 +243,11 @@ public class PolygonBuilder extends ShapeBuilder { } protected Polygon toPolygon(GeometryFactory factory) { - final LinearRing shell = linearRing(factory, this.shell.points); + final LinearRing shell = linearRing(factory, this.shell.coordinates); final LinearRing[] holes = new LinearRing[this.holes.size()]; Iterator iterator = this.holes.iterator(); for (int i = 0; iterator.hasNext(); i++) { - holes[i] = linearRing(factory, iterator.next().points); + holes[i] = linearRing(factory, iterator.next().coordinates); } return factory.createPolygon(shell, holes); } @@ -731,9 +738,9 @@ public class PolygonBuilder extends ShapeBuilder { @Override public PolygonBuilder readFrom(StreamInput in) throws IOException { - LineStringBuilder shell = LineStringBuilder.PROTOTYPE.readFrom(in); + LineStringBuilder shell = LineStringBuilder.PROTOTYPE.readFrom(in); Orientation orientation = Orientation.readFrom(in); - PolygonBuilder polyBuilder = new PolygonBuilder(shell.points, orientation); + PolygonBuilder polyBuilder = new PolygonBuilder(shell, orientation); int holes = in.readVInt(); for (int i = 0; i < holes; i++) { polyBuilder.hole(LineStringBuilder.PROTOTYPE.readFrom(in)); diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java index e080ee4e201..8c3ea3f3261 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilder.java @@ -26,6 +26,7 @@ import com.spatial4j.core.shape.jts.JtsGeometry; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; + import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.support.ToXContentToBytes; import org.elasticsearch.common.io.stream.NamedWriteable; @@ -86,11 +87,6 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri protected final boolean autoIndexJtsGeometry = true;//may want to turn off once SpatialStrategy impls do it. protected ShapeBuilder() { - - } - - protected static Coordinate coordinate(double longitude, double latitude) { - return new Coordinate(longitude, latitude); } protected JtsGeometry jtsGeometry(Geometry geom) { @@ -594,11 +590,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri protected static MultiPointBuilder parseMultiPoint(CoordinateNode coordinates) { validateMultiPointNode(coordinates); - PointListBuilder points = new PointListBuilder(); + CoordinatesBuilder points = new CoordinatesBuilder(); for (CoordinateNode node : coordinates.children) { - points.point(node.coordinate); + points.coordinate(node.coordinate); } - return new MultiPointBuilder(points.list()); + return new MultiPointBuilder(points.build()); } protected static LineStringBuilder parseLineString(CoordinateNode coordinates) { @@ -611,11 +607,11 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri throw new ElasticsearchParseException("invalid number of points in LineString (found [{}] - must be >= 2)", coordinates.children.size()); } - PointListBuilder line = new PointListBuilder(); + CoordinatesBuilder line = new CoordinatesBuilder(); for (CoordinateNode node : coordinates.children) { - line.point(node.coordinate); + line.coordinate(node.coordinate); } - return ShapeBuilders.newLineString(line.list()); + return ShapeBuilders.newLineString(line); } protected static MultiLineStringBuilder parseMultiLine(CoordinateNode coordinates) { @@ -663,7 +659,7 @@ public abstract class ShapeBuilder extends ToXContentToBytes implements NamedWri } LineStringBuilder shell = parseLinearRing(coordinates.children.get(0), coerce); - PolygonBuilder polygon = new PolygonBuilder(shell.points, orientation); + PolygonBuilder polygon = new PolygonBuilder(shell, orientation); for (int i = 1; i < coordinates.children.size(); i++) { polygon.hole(parseLinearRing(coordinates.children.get(i), coerce)); } diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java index 1fb36fe21e1..1c828814431 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/ShapeBuilders.java @@ -64,6 +64,14 @@ public class ShapeBuilders { return new LineStringBuilder(list); } + /** + * Create a new lineString + * @return a new {@link LineStringBuilder} + */ + public static LineStringBuilder newLineString(CoordinatesBuilder coordinates) { + return new LineStringBuilder(coordinates); + } + /** * Create a new Collection of lineStrings * @return a new {@link MultiLineStringBuilder} @@ -73,10 +81,18 @@ public class ShapeBuilders { } /** - * Create a new Polygon - * @return a new {@link PointBuilder} + * Create a new PolygonBuilder + * @return a new {@link PolygonBuilder} */ public static PolygonBuilder newPolygon(List shell) { + return new PolygonBuilder(new CoordinatesBuilder().coordinates(shell)); + } + + /** + * Create a new PolygonBuilder + * @return a new {@link PolygonBuilder} + */ + public static PolygonBuilder newPolygon(CoordinatesBuilder shell) { return new PolygonBuilder(shell); } diff --git a/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java index 0837361ab15..d0e03ceddad 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/ShapeBuilderTests.java @@ -28,8 +28,9 @@ import com.spatial4j.core.shape.impl.PointImpl; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Polygon; + +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; @@ -59,12 +60,12 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon() { - Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-45, 30) - .point(45, 30) - .point(45, -30) - .point(-45, -30) - .point(-45, 30).list()).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-45, 30) + .coordinate(45, 30) + .coordinate(45, -30) + .coordinate(-45, -30) + .coordinate(-45, 30)).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -74,12 +75,12 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon_coordinate() { - Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .point(new Coordinate(-45, 30)) - .point(new Coordinate(45, 30)) - .point(new Coordinate(45, -30)) - .point(new Coordinate(-45, -30)) - .point(new Coordinate(-45, 30)).list()).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(new Coordinate(-45, 30)) + .coordinate(new Coordinate(45, 30)) + .coordinate(new Coordinate(45, -30)) + .coordinate(new Coordinate(-45, -30)) + .coordinate(new Coordinate(-45, 30))).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -89,9 +90,9 @@ public class ShapeBuilderTests extends ESTestCase { } public void testNewPolygon_coordinates() { - Polygon polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .points(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)) - .list()).toPolygon(); + Polygon polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinates(new Coordinate(-45, 30), new Coordinate(45, 30), new Coordinate(45, -30), new Coordinate(-45, -30), new Coordinate(-45, 30)) + ).toPolygon(); LineString exterior = polygon.getExteriorRing(); assertEquals(exterior.getCoordinateN(0), new Coordinate(-45, 30)); @@ -102,92 +103,92 @@ public class ShapeBuilderTests extends ESTestCase { public void testLineStringBuilder() { // Building a simple LineString - ShapeBuilders.newLineString(new PointListBuilder() - .point(-130.0, 55.0) - .point(-130.0, -40.0) - .point(-15.0, -40.0) - .point(-20.0, 50.0) - .point(-45.0, 50.0) - .point(-45.0, -15.0) - .point(-110.0, -15.0) - .point(-110.0, 55.0).list()).build(); + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(-130.0, 55.0) + .coordinate(-130.0, -40.0) + .coordinate(-15.0, -40.0) + .coordinate(-20.0, 50.0) + .coordinate(-45.0, 50.0) + .coordinate(-45.0, -15.0) + .coordinate(-110.0, -15.0) + .coordinate(-110.0, 55.0)).build(); // Building a linestring that needs to be wrapped - ShapeBuilders.newLineString(new PointListBuilder() - .point(100.0, 50.0) - .point(110.0, -40.0) - .point(240.0, -40.0) - .point(230.0, 60.0) - .point(200.0, 60.0) - .point(200.0, -30.0) - .point(130.0, -30.0) - .point(130.0, 60.0) - .list()) + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(100.0, 50.0) + .coordinate(110.0, -40.0) + .coordinate(240.0, -40.0) + .coordinate(230.0, 60.0) + .coordinate(200.0, 60.0) + .coordinate(200.0, -30.0) + .coordinate(130.0, -30.0) + .coordinate(130.0, 60.0) + ) .build(); // Building a lineString on the dateline - ShapeBuilders.newLineString(new PointListBuilder() - .point(-180.0, 80.0) - .point(-180.0, 40.0) - .point(-180.0, -40.0) - .point(-180.0, -80.0) - .list()) + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(-180.0, 80.0) + .coordinate(-180.0, 40.0) + .coordinate(-180.0, -40.0) + .coordinate(-180.0, -80.0) + ) .build(); // Building a lineString on the dateline - ShapeBuilders.newLineString(new PointListBuilder() - .point(180.0, 80.0) - .point(180.0, 40.0) - .point(180.0, -40.0) - .point(180.0, -80.0) - .list()) + ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(180.0, 80.0) + .coordinate(180.0, 40.0) + .coordinate(180.0, -40.0) + .coordinate(180.0, -80.0) + ) .build(); } public void testMultiLineString() { ShapeBuilders.newMultiLinestring() - .linestring(new LineStringBuilder(new PointListBuilder() - .point(-100.0, 50.0) - .point(50.0, 50.0) - .point(50.0, 20.0) - .point(-100.0, 20.0) - .list()) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-100.0, 50.0) + .coordinate(50.0, 50.0) + .coordinate(50.0, 20.0) + .coordinate(-100.0, 20.0) + ) ) - .linestring(new LineStringBuilder(new PointListBuilder() - .point(-100.0, 20.0) - .point(50.0, 20.0) - .point(50.0, 0.0) - .point(-100.0, 0.0) - .list()) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-100.0, 20.0) + .coordinate(50.0, 20.0) + .coordinate(50.0, 0.0) + .coordinate(-100.0, 0.0) + ) ) .build(); // LineString that needs to be wrappped ShapeBuilders.newMultiLinestring() - .linestring(new LineStringBuilder(new PointListBuilder() - .point(150.0, 60.0) - .point(200.0, 60.0) - .point(200.0, 40.0) - .point(150.0, 40.0) - .list()) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(150.0, 60.0) + .coordinate(200.0, 60.0) + .coordinate(200.0, 40.0) + .coordinate(150.0, 40.0) + ) + ) + .linestring(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(150.0, 20.0) + .coordinate(200.0, 20.0) + .coordinate(200.0, 0.0) + .coordinate(150.0, 0.0) ) - .linestring(new LineStringBuilder(new PointListBuilder() - .point(150.0, 20.0) - .point(200.0, 20.0) - .point(200.0, 0.0) - .point(150.0, 0.0) - .list()) ) .build(); } public void testPolygonSelfIntersection() { try { - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-40.0, 50.0) - .point(40.0, 50.0) - .point(-40.0, -50.0) - .point(40.0, -50.0).close().list()) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-40.0, 50.0) + .coordinate(40.0, 50.0) + .coordinate(-40.0, -50.0) + .coordinate(40.0, -50.0).close()) .build(); fail("Expected InvalidShapeException"); } catch (InvalidShapeException e) { @@ -221,26 +222,26 @@ public class ShapeBuilderTests extends ESTestCase { } public void testPolygonWrapping() { - Shape shape = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-150.0, 65.0) - .point(-250.0, 65.0) - .point(-250.0, -65.0) - .point(-150.0, -65.0) + Shape shape = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-150.0, 65.0) + .coordinate(-250.0, 65.0) + .coordinate(-250.0, -65.0) + .coordinate(-150.0, -65.0) .close() - .list()) + ) .build(); assertMultiPolygon(shape); } public void testLineStringWrapping() { - Shape shape = ShapeBuilders.newLineString(new PointListBuilder() - .point(-150.0, 65.0) - .point(-250.0, 65.0) - .point(-250.0, -65.0) - .point(-150.0, -65.0) + Shape shape = ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(-150.0, 65.0) + .coordinate(-250.0, 65.0) + .coordinate(-250.0, -65.0) + .coordinate(-150.0, -65.0) .close() - .list()) + ) .build(); assertMultiLineString(shape); } @@ -251,39 +252,39 @@ public class ShapeBuilderTests extends ESTestCase { // expected results: 3 polygons, 1 with a hole // a giant c shape - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(174,0) - .point(-176,0) - .point(-176,3) - .point(177,3) - .point(177,5) - .point(-176,5) - .point(-176,8) - .point(174,8) - .point(174,0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(174,0) + .coordinate(-176,0) + .coordinate(-176,3) + .coordinate(177,3) + .coordinate(177,5) + .coordinate(-176,5) + .coordinate(-176,8) + .coordinate(174,8) + .coordinate(174,0) + ); // 3/4 of an embedded 'c', crossing dateline once - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(175, 1) - .point(175, 7) - .point(-178, 7) - .point(-178, 6) - .point(176, 6) - .point(176, 2) - .point(179, 2) - .point(179,1) - .point(175, 1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(175, 1) + .coordinate(175, 7) + .coordinate(-178, 7) + .coordinate(-178, 6) + .coordinate(176, 6) + .coordinate(176, 2) + .coordinate(179, 2) + .coordinate(179,1) + .coordinate(175, 1) + )); // embedded hole right of the dateline - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-179, 1) - .point(-179, 2) - .point(-177, 2) - .point(-177,1) - .point(-179,1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-179, 1) + .coordinate(-179, 2) + .coordinate(-177, 2) + .coordinate(-177,1) + .coordinate(-179,1) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); @@ -295,114 +296,114 @@ public class ShapeBuilderTests extends ESTestCase { // expected results: 3 polygons, 1 with a hole // a giant c shape - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-186,0) - .point(-176,0) - .point(-176,3) - .point(-183,3) - .point(-183,5) - .point(-176,5) - .point(-176,8) - .point(-186,8) - .point(-186,0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-186,0) + .coordinate(-176,0) + .coordinate(-176,3) + .coordinate(-183,3) + .coordinate(-183,5) + .coordinate(-176,5) + .coordinate(-176,8) + .coordinate(-186,8) + .coordinate(-186,0) + ); // 3/4 of an embedded 'c', crossing dateline once - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-185,1) - .point(-181,1) - .point(-181,2) - .point(-184,2) - .point(-184,6) - .point(-178,6) - .point(-178,7) - .point(-185,7) - .point(-185,1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-185,1) + .coordinate(-181,1) + .coordinate(-181,2) + .coordinate(-184,2) + .coordinate(-184,6) + .coordinate(-178,6) + .coordinate(-178,7) + .coordinate(-185,7) + .coordinate(-185,1) + )); // embedded hole right of the dateline - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-179,1) - .point(-177,1) - .point(-177,2) - .point(-179,2) - .point(-179,1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-179,1) + .coordinate(-177,1) + .coordinate(-177,2) + .coordinate(-179,2) + .coordinate(-179,1) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testComplexShapeWithHole() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-85.0018514,37.1311314) - .point(-85.0016645,37.1315293) - .point(-85.0016246,37.1317069) - .point(-85.0016526,37.1318183) - .point(-85.0017119,37.1319196) - .point(-85.0019371,37.1321182) - .point(-85.0019972,37.1322115) - .point(-85.0019942,37.1323234) - .point(-85.0019543,37.1324336) - .point(-85.001906,37.1324985) - .point(-85.001834,37.1325497) - .point(-85.0016965,37.1325907) - .point(-85.0016011,37.1325873) - .point(-85.0014816,37.1325353) - .point(-85.0011755,37.1323509) - .point(-85.000955,37.1322802) - .point(-85.0006241,37.1322529) - .point(-85.0000002,37.1322307) - .point(-84.9994,37.1323001) - .point(-84.999109,37.1322864) - .point(-84.998934,37.1322415) - .point(-84.9988639,37.1321888) - .point(-84.9987841,37.1320944) - .point(-84.9987208,37.131954) - .point(-84.998736,37.1316611) - .point(-84.9988091,37.131334) - .point(-84.9989283,37.1311337) - .point(-84.9991943,37.1309198) - .point(-84.9993573,37.1308459) - .point(-84.9995888,37.1307924) - .point(-84.9998746,37.130806) - .point(-85.0000002,37.1308358) - .point(-85.0004984,37.1310658) - .point(-85.0008008,37.1311625) - .point(-85.0009461,37.1311684) - .point(-85.0011373,37.1311515) - .point(-85.0016455,37.1310491) - .point(-85.0018514,37.1311314) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-85.0018514,37.1311314) + .coordinate(-85.0016645,37.1315293) + .coordinate(-85.0016246,37.1317069) + .coordinate(-85.0016526,37.1318183) + .coordinate(-85.0017119,37.1319196) + .coordinate(-85.0019371,37.1321182) + .coordinate(-85.0019972,37.1322115) + .coordinate(-85.0019942,37.1323234) + .coordinate(-85.0019543,37.1324336) + .coordinate(-85.001906,37.1324985) + .coordinate(-85.001834,37.1325497) + .coordinate(-85.0016965,37.1325907) + .coordinate(-85.0016011,37.1325873) + .coordinate(-85.0014816,37.1325353) + .coordinate(-85.0011755,37.1323509) + .coordinate(-85.000955,37.1322802) + .coordinate(-85.0006241,37.1322529) + .coordinate(-85.0000002,37.1322307) + .coordinate(-84.9994,37.1323001) + .coordinate(-84.999109,37.1322864) + .coordinate(-84.998934,37.1322415) + .coordinate(-84.9988639,37.1321888) + .coordinate(-84.9987841,37.1320944) + .coordinate(-84.9987208,37.131954) + .coordinate(-84.998736,37.1316611) + .coordinate(-84.9988091,37.131334) + .coordinate(-84.9989283,37.1311337) + .coordinate(-84.9991943,37.1309198) + .coordinate(-84.9993573,37.1308459) + .coordinate(-84.9995888,37.1307924) + .coordinate(-84.9998746,37.130806) + .coordinate(-85.0000002,37.1308358) + .coordinate(-85.0004984,37.1310658) + .coordinate(-85.0008008,37.1311625) + .coordinate(-85.0009461,37.1311684) + .coordinate(-85.0011373,37.1311515) + .coordinate(-85.0016455,37.1310491) + .coordinate(-85.0018514,37.1311314) + ); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-85.0000002,37.1317672) - .point(-85.0001983,37.1317538) - .point(-85.0003378,37.1317582) - .point(-85.0004697,37.131792) - .point(-85.0008048,37.1319439) - .point(-85.0009342,37.1319838) - .point(-85.0010184,37.1319463) - .point(-85.0010618,37.13184) - .point(-85.0010057,37.1315102) - .point(-85.000977,37.1314403) - .point(-85.0009182,37.1313793) - .point(-85.0005366,37.1312209) - .point(-85.000224,37.1311466) - .point(-85.000087,37.1311356) - .point(-85.0000002,37.1311433) - .point(-84.9995021,37.1312336) - .point(-84.9993308,37.1312859) - .point(-84.9992567,37.1313252) - .point(-84.9991868,37.1314277) - .point(-84.9991593,37.1315381) - .point(-84.9991841,37.1316527) - .point(-84.9992329,37.1317117) - .point(-84.9993527,37.1317788) - .point(-84.9994931,37.1318061) - .point(-84.9996815,37.1317979) - .point(-85.0000002,37.1317672) - .list()) + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-85.0000002,37.1317672) + .coordinate(-85.0001983,37.1317538) + .coordinate(-85.0003378,37.1317582) + .coordinate(-85.0004697,37.131792) + .coordinate(-85.0008048,37.1319439) + .coordinate(-85.0009342,37.1319838) + .coordinate(-85.0010184,37.1319463) + .coordinate(-85.0010618,37.13184) + .coordinate(-85.0010057,37.1315102) + .coordinate(-85.000977,37.1314403) + .coordinate(-85.0009182,37.1313793) + .coordinate(-85.0005366,37.1312209) + .coordinate(-85.000224,37.1311466) + .coordinate(-85.000087,37.1311356) + .coordinate(-85.0000002,37.1311433) + .coordinate(-84.9995021,37.1312336) + .coordinate(-84.9993308,37.1312859) + .coordinate(-84.9992567,37.1313252) + .coordinate(-84.9991868,37.1314277) + .coordinate(-84.9991593,37.1315381) + .coordinate(-84.9991841,37.1316527) + .coordinate(-84.9992329,37.1317117) + .coordinate(-84.9993527,37.1317788) + .coordinate(-84.9994931,37.1318061) + .coordinate(-84.9996815,37.1317979) + .coordinate(-85.0000002,37.1317672) + ) ); Shape shape = builder.close().build(); @@ -410,35 +411,35 @@ public class ShapeBuilderTests extends ESTestCase { } public void testShapeWithHoleAtEdgeEndPoints() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-4, 2) - .point(4, 2) - .point(6, 0) - .point(4, -2) - .point(-4, -2) - .point(-6, 0) - .point(-4, 2) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-4, 2) + .coordinate(4, 2) + .coordinate(6, 0) + .coordinate(4, -2) + .coordinate(-4, -2) + .coordinate(-6, 0) + .coordinate(-4, 2) + ); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(4, 1) - .point(4, -1) - .point(-4, -1) - .point(-4, 1) - .point(4, 1) - .list())); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(4, 1) + .coordinate(4, -1) + .coordinate(-4, -1) + .coordinate(-4, 1) + .coordinate(4, 1) + )); Shape shape = builder.close().build(); assertPolygon(shape); } public void testShapeWithPointOnDateline() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(176, -4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(176, -4) + .coordinate(180, 0) + ); Shape shape = builder.close().build(); assertPolygon(shape); @@ -446,23 +447,23 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithEdgeAlongDateline() { // test case 1: test the positive side of the dateline - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(180, -4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(180, -4) + .coordinate(180, 0) + ); Shape shape = builder.close().build(); assertPolygon(shape); // test case 2: test the negative side of the dateline - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-176, 4) - .point(-180, 0) - .point(-180, -4) - .point(-176, 4) - .list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-176, 4) + .coordinate(-180, 0) + .coordinate(-180, -4) + .coordinate(-176, 4) + ); shape = builder.close().build(); assertPolygon(shape); @@ -470,85 +471,85 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithBoundaryHoles() { // test case 1: test the positive side of the dateline - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-177, 10) - .point(176, 15) - .point(172, 0) - .point(176, -15) - .point(-177, -10) - .point(-177, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(176, 10) - .point(180, 5) - .point(180, -5) - .point(176, -10) - .point(176, 10) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(176, 15) + .coordinate(172, 0) + .coordinate(176, -15) + .coordinate(-177, -10) + .coordinate(-177, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(176, 10) + .coordinate(180, 5) + .coordinate(180, -5) + .coordinate(176, -10) + .coordinate(176, 10) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); // test case 2: test the negative side of the dateline builder = ShapeBuilders.newPolygon( - new PointListBuilder() - .point(-176, 15) - .point(179, 10) - .point(179, -10) - .point(-176, -15) - .point(-172, 0) + new CoordinatesBuilder() + .coordinate(-176, 15) + .coordinate(179, 10) + .coordinate(179, -10) + .coordinate(-176, -15) + .coordinate(-172, 0) .close() - .list()); + ); builder.hole(new LineStringBuilder( - new PointListBuilder() - .point(-176, 10) - .point(-176, -10) - .point(-180, -5) - .point(-180, 5) - .point(-176, 10) + new CoordinatesBuilder() + .coordinate(-176, 10) + .coordinate(-176, -10) + .coordinate(-180, -5) + .coordinate(-180, 5) + .coordinate(-176, 10) .close() - .list())); + )); shape = builder.close().build(); assertMultiPolygon(shape); } public void testShapeWithTangentialHole() { // test a shape with one tangential (shared) vertex (should pass) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(179, 10) - .point(168, 15) - .point(164, 0) - .point(166, -15) - .point(179, -10) - .point(179, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-177, 10) - .point(-178, -10) - .point(-180, -5) - .point(-180, 5) - .point(-177, 10) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(179, 10) + .coordinate(168, 15) + .coordinate(164, 0) + .coordinate(166, -15) + .coordinate(179, -10) + .coordinate(179, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(-178, -10) + .coordinate(-180, -5) + .coordinate(-180, 5) + .coordinate(-177, 10) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testShapeWithInvalidTangentialHole() { // test a shape with one invalid tangential (shared) vertex (should throw exception) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(179, 10) - .point(168, 15) - .point(164, 0) - .point(166, -15) - .point(179, -10) - .point(179, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(164, 0) - .point(175, 10) - .point(175, 5) - .point(179, -10) - .point(164, 0) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(179, 10) + .coordinate(168, 15) + .coordinate(164, 0) + .coordinate(166, -15) + .coordinate(179, -10) + .coordinate(179, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(164, 0) + .coordinate(175, 10) + .coordinate(175, 5) + .coordinate(179, -10) + .coordinate(164, 0) + )); try { builder.close().build(); fail("Expected InvalidShapeException"); @@ -559,48 +560,48 @@ public class ShapeBuilderTests extends ESTestCase { public void testBoundaryShapeWithTangentialHole() { // test a shape with one tangential (shared) vertex for each hole (should pass) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-177, 10) - .point(176, 15) - .point(172, 0) - .point(176, -15) - .point(-177, -10) - .point(-177, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-177, 10) - .point(-178, -10) - .point(-180, -5) - .point(-180, 5) - .point(-177, 10) - .list())); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(172, 0) - .point(176, 10) - .point(176, -5) - .point(172, 0) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(176, 15) + .coordinate(172, 0) + .coordinate(176, -15) + .coordinate(-177, -10) + .coordinate(-177, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(-178, -10) + .coordinate(-180, -5) + .coordinate(-180, 5) + .coordinate(-177, 10) + )); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(172, 0) + .coordinate(176, 10) + .coordinate(176, -5) + .coordinate(172, 0) + )); Shape shape = builder.close().build(); assertMultiPolygon(shape); } public void testBoundaryShapeWithInvalidTangentialHole() { // test shape with two tangential (shared) vertices (should throw exception) - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-177, 10) - .point(176, 15) - .point(172, 0) - .point(176, -15) - .point(-177, -10) - .point(-177, 10) - .list()); - builder.hole(new LineStringBuilder(new PointListBuilder() - .point(-177, 10) - .point(172, 0) - .point(180, -5) - .point(176, -10) - .point(-177, 10) - .list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(176, 15) + .coordinate(172, 0) + .coordinate(176, -15) + .coordinate(-177, -10) + .coordinate(-177, 10) + ); + builder.hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-177, 10) + .coordinate(172, 0) + .coordinate(180, -5) + .coordinate(176, -10) + .coordinate(-177, 10) + )); try { builder.close().build(); fail("Expected InvalidShapeException"); @@ -613,12 +614,12 @@ public class ShapeBuilderTests extends ESTestCase { * Test an enveloping polygon around the max mercator bounds */ public void testBoundaryShape() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-180, 90) - .point(180, 90) - .point(180, -90) - .point(-180, 90) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-180, 90) + .coordinate(180, 90) + .coordinate(180, -90) + .coordinate(-180, 90) + ); Shape shape = builder.close().build(); @@ -627,23 +628,23 @@ public class ShapeBuilderTests extends ESTestCase { public void testShapeWithAlternateOrientation() { // cw: should produce a multi polygon spanning hemispheres - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(-176, 4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(-176, 4) + .coordinate(180, 0) + ); Shape shape = builder.close().build(); assertPolygon(shape); // cw: geo core will convert to ccw across the dateline - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(-176, 4) - .point(176, 4) - .point(180, 0) - .list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(-176, 4) + .coordinate(176, 4) + .coordinate(180, 0) + ); shape = builder.close().build(); @@ -651,13 +652,13 @@ public class ShapeBuilderTests extends ESTestCase { } public void testInvalidShapeWithConsecutiveDuplicatePoints() { - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(180, 0) - .point(176, 4) - .point(176, 4) - .point(-176, 4) - .point(180, 0) - .list()); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(180, 0) + .coordinate(176, 4) + .coordinate(176, 4) + .coordinate(-176, 4) + .coordinate(180, 0) + ); try { builder.close().build(); fail("Expected InvalidShapeException"); diff --git a/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java b/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java index 8562ad6adf5..f6fcf8449d3 100644 --- a/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/common/geo/builders/LineStringBuilderTests.java @@ -20,10 +20,12 @@ package org.elasticsearch.common.geo.builders; import com.vividsolutions.jts.geom.Coordinate; + import org.elasticsearch.test.geo.RandomShapeGenerator; import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType; import java.io.IOException; +import java.util.List; import static org.hamcrest.Matchers.equalTo; @@ -31,21 +33,21 @@ public class LineStringBuilderTests extends AbstractShapeBuilderTestCase) null); fail("Exception expected"); } catch (IllegalArgumentException e) { assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); } try { - new LineStringBuilder(new PointListBuilder().list()); + new LineStringBuilder(new CoordinatesBuilder()); fail("Exception expected"); } catch (IllegalArgumentException e) { assertThat("cannot create point collection with empty set of points", equalTo(e.getMessage())); } try { - new LineStringBuilder(new PointListBuilder().point(0.0, 0.0).list()); + new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0)); fail("Exception expected"); } catch (IllegalArgumentException e) { assertThat("invalid number of points in LineString (found [1] - must be >= 2)", equalTo(e.getMessage())); @@ -79,7 +81,7 @@ public class LineStringBuilderTests extends AbstractShapeBuilderTestCase { @Override @@ -77,7 +80,7 @@ public class PolygonBuilderTests extends AbstractShapeBuilderTestCase= 4)", e.getMessage()); + } + + PolygonBuilder pb = new PolygonBuilder(new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0) + .coordinate(1.0, 0.0).coordinate(1.0, 1.0).build()), Orientation.RIGHT, true); + assertThat("Shell should have been closed via coerce", pb.shell().coordinates(false).length, equalTo(4)); + } + + public void testCoerceHole() { + PolygonBuilder pb = new PolygonBuilder(new CoordinatesBuilder().coordinate(0.0, 0.0) + .coordinate(2.0, 0.0).coordinate(2.0, 2.0).coordinate(0.0, 0.0)); + try{ + pb.hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0,0.0).coordinate(1.0,0.0).coordinate(1.0,1.0).build())); + fail("should raise validation exception"); + } catch (IllegalArgumentException e) { + assertEquals("invalid number of points in LinearRing (found [3] - must be >= 4)", e.getMessage()); + } + + pb.hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(0.0,0.0).coordinate(1.0,0.0).coordinate(1.0,1.0).build()), true); + assertThat("hole should have been closed via coerce", pb.holes().get(0).coordinates(false).length, equalTo(4)); + } + } diff --git a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java index d93bcc2fe41..61f7865fa13 100644 --- a/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java @@ -23,7 +23,7 @@ import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.ShapeRelation; -import org.elasticsearch.common.geo.builders.PointListBuilder; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item; @@ -176,13 +176,13 @@ public class QueryDSLDocumentationTests extends ESTestCase { GeoShapeQueryBuilder qb = geoShapeQuery( "pin.location", ShapeBuilders.newMultiPoint( - new PointListBuilder() - .point(0, 0) - .point(0, 10) - .point(10, 10) - .point(10, 0) - .point(0, 0) - .list())); + new CoordinatesBuilder() + .coordinate(0, 0) + .coordinate(0, 10) + .coordinate(10, 10) + .coordinate(10, 0) + .coordinate(0, 0) + .build())); qb.relation(ShapeRelation.WITHIN); qb = geoShapeQuery( diff --git a/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java b/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java index 00aee4f039e..e96c53fe943 100644 --- a/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java +++ b/core/src/test/java/org/elasticsearch/search/geo/GeoFilterIT.java @@ -23,6 +23,7 @@ import com.spatial4j.core.context.SpatialContext; import com.spatial4j.core.distance.DistanceUtils; import com.spatial4j.core.exception.InvalidShapeException; import com.spatial4j.core.shape.Shape; + import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy; import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree; import org.apache.lucene.spatial.query.SpatialArgs; @@ -40,9 +41,9 @@ import org.elasticsearch.common.Priority; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.geo.GeoPoint; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; import org.elasticsearch.common.geo.builders.MultiPolygonBuilder; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.io.Streams; @@ -120,29 +121,28 @@ public class GeoFilterIT extends ESIntegTestCase { public void testShapeBuilders() { try { // self intersection polygon - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10) - .point(10, 10) - .point(-10, 10) - .point(10, -10) - .close() - .list()) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10) + .coordinate(10, 10) + .coordinate(-10, 10) + .coordinate(10, -10) + .close()) .build(); fail("Self intersection not detected"); } catch (InvalidShapeException e) { } // polygon with hole - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list())) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close())) .build(); try { // polygon with overlapping hole - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder() - .point(-5, -5).point(-5, 11).point(5, 11).point(5, -5).close().list())) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 11).coordinate(5, 11).coordinate(5, -5).close())) .build(); fail("Self intersection not detected"); @@ -151,10 +151,10 @@ public class GeoFilterIT extends ESIntegTestCase { try { // polygon with intersection holes - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list())) - .hole(new LineStringBuilder(new PointListBuilder().point(-5, -6).point(5, -6).point(5, -4).point(-5, -4).close().list())) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close())) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(-5, -6).coordinate(5, -6).coordinate(5, -4).coordinate(-5, -4).close())) .build(); fail("Intersection of holes not detected"); } catch (InvalidShapeException e) { @@ -162,16 +162,15 @@ public class GeoFilterIT extends ESIntegTestCase { try { // Common line in polygon - ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10) - .point(-10, 10) - .point(-5, 10) - .point(-5, -5) - .point(-5, 20) - .point(10, 20) - .point(10, -10) - .close() - .list()) + ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10) + .coordinate(-10, 10) + .coordinate(-5, 10) + .coordinate(-5, -5) + .coordinate(-5, 20) + .coordinate(10, 20) + .coordinate(10, -10) + .close()) .build(); fail("Self intersection not detected"); } catch (InvalidShapeException e) { @@ -181,21 +180,21 @@ public class GeoFilterIT extends ESIntegTestCase { ShapeBuilders .newMultiPolygon() .polygon(new PolygonBuilder( - new PointListBuilder().point(-10, -10) - .point(-10, 10) - .point(10, 10) - .point(10, -10).close().list()) + new CoordinatesBuilder().coordinate(-10, -10) + .coordinate(-10, 10) + .coordinate(10, 10) + .coordinate(10, -10).close()) .hole(new LineStringBuilder( - new PointListBuilder().point(-5, -5) - .point(-5, 5) - .point(5, 5) - .point(5, -5).close().list()))) + new CoordinatesBuilder().coordinate(-5, -5) + .coordinate(-5, 5) + .coordinate(5, 5) + .coordinate(5, -5).close()))) .polygon(new PolygonBuilder( - new PointListBuilder() - .point(-4, -4) - .point(-4, 4) - .point(4, 4) - .point(4, -4).close().list())) + new CoordinatesBuilder() + .coordinate(-4, -4) + .coordinate(-4, 4) + .coordinate(4, 4) + .coordinate(4, -4).close())) .build(); } @@ -225,11 +224,11 @@ public class GeoFilterIT extends ESIntegTestCase { // the second polygon of size 4x4 equidistant from all sites MultiPolygonBuilder polygon = ShapeBuilders.newMultiPolygon() .polygon(new PolygonBuilder( - new PointListBuilder().point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder() - .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list()))) + new CoordinatesBuilder().coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close()))) .polygon(new PolygonBuilder( - new PointListBuilder().point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close().list())); + new CoordinatesBuilder().coordinate(-4, -4).coordinate(-4, 4).coordinate(4, 4).coordinate(4, -4).close())); BytesReference data = jsonBuilder().startObject().field("area", polygon).endObject().bytes(); client().prepareIndex("shapes", "polygon", "1").setSource(data).execute().actionGet(); @@ -288,10 +287,10 @@ public class GeoFilterIT extends ESIntegTestCase { } // Create a polygon that fills the empty area of the polygon defined above - PolygonBuilder inverse = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-5, -5).point(-5, 5).point(5, 5).point(5, -5).close().list()) + PolygonBuilder inverse = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 5).coordinate(5, 5).coordinate(5, -5).close()) .hole(new LineStringBuilder( - new PointListBuilder().point(-4, -4).point(-4, 4).point(4, 4).point(4, -4).close().list())); + new CoordinatesBuilder().coordinate(-4, -4).coordinate(-4, 4).coordinate(4, 4).coordinate(4, -4).close())); data = jsonBuilder().startObject().field("area", inverse).endObject().bytes(); client().prepareIndex("shapes", "polygon", "2").setSource(data).execute().actionGet(); @@ -306,15 +305,15 @@ public class GeoFilterIT extends ESIntegTestCase { assertFirstHit(result, hasId("2")); // Create Polygon with hole and common edge - PolygonBuilder builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-10, -10).point(-10, 10).point(10, 10).point(10, -10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder() - .point(-5, -5).point(-5, 5).point(10, 5).point(10, -5).close().list())); + PolygonBuilder builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-10, -10).coordinate(-10, 10).coordinate(10, 10).coordinate(10, -10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder() + .coordinate(-5, -5).coordinate(-5, 5).coordinate(10, 5).coordinate(10, -5).close())); if (withinSupport) { // Polygon WithIn Polygon - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(-30, -30).point(-30, 30).point(30, 30).point(30, -30).close().list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(-30, -30).coordinate(-30, 30).coordinate(30, 30).coordinate(30, -30).close()); result = client().prepareSearch() .setQuery(matchAllQuery()) @@ -324,17 +323,17 @@ public class GeoFilterIT extends ESIntegTestCase { } // Create a polygon crossing longitude 180. - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()); data = jsonBuilder().startObject().field("area", builder).endObject().bytes(); client().prepareIndex("shapes", "polygon", "1").setSource(data).execute().actionGet(); client().admin().indices().prepareRefresh().execute().actionGet(); // Create a polygon crossing longitude 180 with hole. - builder = ShapeBuilders.newPolygon(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close().list())); + builder = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(175, -5).coordinate(185, -5).coordinate(185, 5).coordinate(175, 5).close())); data = jsonBuilder().startObject().field("area", builder).endObject().bytes(); client().prepareIndex("shapes", "polygon", "1").setSource(data).execute().actionGet(); diff --git a/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java b/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java index 5813e028583..c6f05ee23a2 100644 --- a/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java +++ b/core/src/test/java/org/elasticsearch/search/geo/GeoShapeQueryTests.java @@ -25,10 +25,10 @@ import com.vividsolutions.jts.geom.Coordinate; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.geo.ShapeRelation; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.EnvelopeBuilder; import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -198,13 +198,13 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase { } public void testReusableBuilder() throws IOException { - ShapeBuilder polygon = ShapeBuilders.newPolygon(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()) - .hole(new LineStringBuilder(new PointListBuilder().point(175, -5).point(185, -5).point(185, 5).point(175, 5).close().list())); + ShapeBuilder polygon = ShapeBuilders.newPolygon(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()) + .hole(new LineStringBuilder(new CoordinatesBuilder().coordinate(175, -5).coordinate(185, -5).coordinate(185, 5).coordinate(175, 5).close())); assertUnmodified(polygon); - ShapeBuilder linestring = ShapeBuilders.newLineString(new PointListBuilder() - .point(170, -10).point(190, -10).point(190, 10).point(170, 10).close().list()); + ShapeBuilder linestring = ShapeBuilders.newLineString(new CoordinatesBuilder() + .coordinate(170, -10).coordinate(190, -10).coordinate(190, 10).coordinate(170, 10).close()); assertUnmodified(linestring); } @@ -377,8 +377,8 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase { "location", ShapeBuilders.newGeometryCollection() .polygon( - ShapeBuilders.newPolygon(new PointListBuilder().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0) - .point(99.0, -1.0).list()))).relation(ShapeRelation.INTERSECTS); + ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(99.0, -1.0).coordinate(99.0, 3.0).coordinate(103.0, 3.0).coordinate(103.0, -1.0) + .coordinate(99.0, -1.0)))).relation(ShapeRelation.INTERSECTS); SearchResponse result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery()) .setPostFilter(filter).get(); assertSearchResponse(result); @@ -386,17 +386,17 @@ public class GeoShapeQueryTests extends ESSingleNodeTestCase { filter = QueryBuilders.geoShapeQuery( "location", ShapeBuilders.newGeometryCollection().polygon( - ShapeBuilders.newPolygon(new PointListBuilder().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0) - .point(199.0, -11.0).list()))).relation(ShapeRelation.INTERSECTS); + ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(199.0, -11.0).coordinate(199.0, 13.0).coordinate(193.0, 13.0).coordinate(193.0, -11.0) + .coordinate(199.0, -11.0)))).relation(ShapeRelation.INTERSECTS); result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery()) .setPostFilter(filter).get(); assertSearchResponse(result); assertHitCount(result, 0); filter = QueryBuilders.geoShapeQuery("location", ShapeBuilders.newGeometryCollection() - .polygon(ShapeBuilders.newPolygon(new PointListBuilder().point(99.0, -1.0).point(99.0, 3.0).point(103.0, 3.0).point(103.0, -1.0).point(99.0, -1.0).list())) + .polygon(ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(99.0, -1.0).coordinate(99.0, 3.0).coordinate(103.0, 3.0).coordinate(103.0, -1.0).coordinate(99.0, -1.0))) .polygon( - ShapeBuilders.newPolygon(new PointListBuilder().point(199.0, -11.0).point(199.0, 13.0).point(193.0, 13.0).point(193.0, -11.0) - .point(199.0, -11.0).list()))).relation(ShapeRelation.INTERSECTS); + ShapeBuilders.newPolygon(new CoordinatesBuilder().coordinate(199.0, -11.0).coordinate(199.0, 13.0).coordinate(193.0, 13.0).coordinate(193.0, -11.0) + .coordinate(199.0, -11.0)))).relation(ShapeRelation.INTERSECTS); result = client().prepareSearch("test").setTypes("type").setQuery(QueryBuilders.matchAllQuery()) .setPostFilter(filter).get(); assertSearchResponse(result); diff --git a/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java b/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java index 01f7c8f66ee..4cc7f8f8487 100644 --- a/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java +++ b/core/src/test/java/org/elasticsearch/test/geo/RandomShapeGenerator.java @@ -31,13 +31,13 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.geo.builders.CoordinateCollection; +import org.elasticsearch.common.geo.builders.CoordinatesBuilder; import org.elasticsearch.common.geo.builders.GeometryCollectionBuilder; import org.elasticsearch.common.geo.builders.LineStringBuilder; import org.elasticsearch.common.geo.builders.MultiLineStringBuilder; import org.elasticsearch.common.geo.builders.MultiPointBuilder; import org.elasticsearch.common.geo.builders.PointBuilder; -import org.elasticsearch.common.geo.builders.PointCollection; -import org.elasticsearch.common.geo.builders.PointListBuilder; import org.elasticsearch.common.geo.builders.PolygonBuilder; import org.elasticsearch.common.geo.builders.ShapeBuilder; import org.elasticsearch.search.geo.GeoShapeQueryTests; @@ -189,12 +189,12 @@ public class RandomShapeGenerator extends RandomGeoGenerator { // if this number gets out of hand, the number of self intersections for a linestring can become // (n^2-n)/2 and computing the relation intersection matrix will become NP-Hard int numPoints = RandomInts.randomIntBetween(r, 3, 10); - PointListBuilder pl = new PointListBuilder(); + CoordinatesBuilder coordinatesBuilder = new CoordinatesBuilder(); for (int i=0; i Date: Sat, 19 Dec 2015 02:38:40 -0200 Subject: [PATCH 14/21] Documented how to define custom mappings for all indexes and all types Closes #15557 --- .../mapping/dynamic/templates.asciidoc | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/reference/mapping/dynamic/templates.asciidoc b/docs/reference/mapping/dynamic/templates.asciidoc index b60c5f0510e..b903f1af066 100644 --- a/docs/reference/mapping/dynamic/templates.asciidoc +++ b/docs/reference/mapping/dynamic/templates.asciidoc @@ -250,3 +250,36 @@ PUT my_index/my_type/1 <1> The `english` field is mapped as a `string` field with the `english` analyzer. <2> The `count` field is mapped as a `long` field with `doc_values` disabled + +[[override-default-template]] +=== Override default template + +You can override the default mappings for all indices and all types +by specifying a `_default_` type mapping in an index template +which matches all indices. + +For example, to disable the `_all` field by default for all types in all +new indices, you could create the following index template: + +[source,js] +-------------------------------------------------- +PUT _template/disable_all_field +{ + "disable_all_field": { + "order": 0, + "template": "*", <1> + "mappings": { + "_default_": { <2> + "_all": { <3> + "enabled": false + } + } + } + } +} +-------------------------------------------------- +// AUTOSENSE +<1> Applies the mappings to an `index` which matches the pattern `*`, in other + words, all new indices. +<2> Defines the `_default_` type mapping types within the index. +<3> Disables the `_all` field by default. From c19981c67b8f8acd54c3ef2f5b2e88ea1975a9fb Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Tue, 12 Jan 2016 08:56:38 -0500 Subject: [PATCH 15/21] Add convenience method for capturing and clearing requests This commit adds convenience methods to o.e.t.t.CapturingTransport that enables capturing requests and clearing the captured requests with a single method. This is to simplify a common pattern in tests of capturing requests, and then clearing the captured requests. --- .../TransportBroadcastByNodeActionTests.java | 7 ++--- .../TransportReplicationActionTests.java | 28 +++++++++---------- .../action/shard/ShardStateActionTests.java | 6 ++-- .../test/transport/CapturingTransport.java | 27 ++++++++++++++++++ 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/core/src/test/java/org/elasticsearch/action/support/broadcast/node/TransportBroadcastByNodeActionTests.java b/core/src/test/java/org/elasticsearch/action/support/broadcast/node/TransportBroadcastByNodeActionTests.java index e4a1a9deed9..90d91dfb197 100644 --- a/core/src/test/java/org/elasticsearch/action/support/broadcast/node/TransportBroadcastByNodeActionTests.java +++ b/core/src/test/java/org/elasticsearch/action/support/broadcast/node/TransportBroadcastByNodeActionTests.java @@ -268,7 +268,7 @@ public class TransportBroadcastByNodeActionTests extends ESTestCase { PlainActionFuture listener = new PlainActionFuture<>(); action.new AsyncAction(request, listener).start(); - Map> capturedRequests = transport.capturedRequestsByTargetNode(); + Map> capturedRequests = transport.getCapturedRequestsByTargetNodeAndClear(); ShardsIterator shardIt = clusterService.state().routingTable().allShards(new String[]{TEST_INDEX}); Set set = new HashSet<>(); @@ -303,7 +303,7 @@ public class TransportBroadcastByNodeActionTests extends ESTestCase { action.new AsyncAction(request, listener).start(); - Map> capturedRequests = transport.capturedRequestsByTargetNode(); + Map> capturedRequests = transport.getCapturedRequestsByTargetNodeAndClear(); // the master should not be in the list of nodes that requests were sent to ShardsIterator shardIt = clusterService.state().routingTable().allShards(new String[]{TEST_INDEX}); @@ -389,8 +389,7 @@ public class TransportBroadcastByNodeActionTests extends ESTestCase { } action.new AsyncAction(request, listener).start(); - Map> capturedRequests = transport.capturedRequestsByTargetNode(); - transport.clear(); + Map> capturedRequests = transport.getCapturedRequestsByTargetNodeAndClear(); ShardsIterator shardIt = clusterService.state().getRoutingTable().allShards(new String[]{TEST_INDEX}); Map> map = new HashMap<>(); diff --git a/core/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationActionTests.java b/core/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationActionTests.java index 6ccf48c7930..0a390ea3706 100644 --- a/core/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationActionTests.java +++ b/core/src/test/java/org/elasticsearch/action/support/replication/TransportReplicationActionTests.java @@ -68,6 +68,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -193,7 +194,8 @@ public class TransportReplicationActionTests extends ESTestCase { final IndexShardRoutingTable shardRoutingTable = clusterService.state().routingTable().index(index).shard(shardId.id()); final String primaryNodeId = shardRoutingTable.primaryShard().currentNodeId(); - final List capturedRequests = transport.capturedRequestsByTargetNode().get(primaryNodeId); + final List capturedRequests = + transport.getCapturedRequestsByTargetNodeAndClear().get(primaryNodeId); assertThat(capturedRequests, notNullValue()); assertThat(capturedRequests.size(), equalTo(1)); assertThat(capturedRequests.get(0).action, equalTo("testAction[p]")); @@ -235,7 +237,7 @@ public class TransportReplicationActionTests extends ESTestCase { reroutePhase.run(); assertThat(request.shardId(), equalTo(shardId)); logger.info("--> primary is assigned to [{}], checking request forwarded", primaryNodeId); - final List capturedRequests = transport.capturedRequestsByTargetNode().get(primaryNodeId); + final List capturedRequests = transport.getCapturedRequestsByTargetNodeAndClear().get(primaryNodeId); assertThat(capturedRequests, notNullValue()); assertThat(capturedRequests.size(), equalTo(1)); if (clusterService.state().nodes().localNodeId().equals(primaryNodeId)) { @@ -256,7 +258,7 @@ public class TransportReplicationActionTests extends ESTestCase { primaryPhase.run(); assertThat("request was not processed on primary", request.processedOnPrimary.get(), equalTo(true)); final String replicaNodeId = clusterService.state().getRoutingTable().shardRoutingTable(index, shardId.id()).replicaShards().get(0).currentNodeId(); - final List requests = transport.capturedRequestsByTargetNode().get(replicaNodeId); + final List requests = transport.getCapturedRequestsByTargetNodeAndClear().get(replicaNodeId); assertThat(requests, notNullValue()); assertThat(requests.size(), equalTo(1)); assertThat("replica request was not sent", requests.get(0).action, equalTo("testAction[r]")); @@ -286,8 +288,9 @@ public class TransportReplicationActionTests extends ESTestCase { TransportReplicationAction.PrimaryPhase primaryPhase = actionWithAddedReplicaAfterPrimaryOp.new PrimaryPhase(request, createTransportChannel(listener)); primaryPhase.run(); assertThat("request was not processed on primary", request.processedOnPrimary.get(), equalTo(true)); + Map> capturedRequestsByTargetNode = transport.getCapturedRequestsByTargetNodeAndClear(); for (ShardRouting replica : stateWithAddedReplicas.getRoutingTable().shardRoutingTable(index, shardId.id()).replicaShards()) { - List requests = transport.capturedRequestsByTargetNode().get(replica.currentNodeId()); + List requests = capturedRequestsByTargetNode.get(replica.currentNodeId()); assertThat(requests, notNullValue()); assertThat(requests.size(), equalTo(1)); assertThat("replica request was not sent", requests.get(0).action, equalTo("testAction[r]")); @@ -319,8 +322,9 @@ public class TransportReplicationActionTests extends ESTestCase { primaryPhase.run(); assertThat("request was not processed on primary", request.processedOnPrimary.get(), equalTo(true)); ShardRouting relocatingReplicaShard = stateWithRelocatingReplica.getRoutingTable().shardRoutingTable(index, shardId.id()).replicaShards().get(0); + Map> capturedRequestsByTargetNode = transport.getCapturedRequestsByTargetNodeAndClear(); for (String node : new String[] {relocatingReplicaShard.currentNodeId(), relocatingReplicaShard.relocatingNodeId()}) { - List requests = transport.capturedRequestsByTargetNode().get(node); + List requests = capturedRequestsByTargetNode.get(node); assertThat(requests, notNullValue()); assertThat(requests.size(), equalTo(1)); assertThat("replica request was not sent to replica", requests.get(0).action, equalTo("testAction[r]")); @@ -489,8 +493,7 @@ public class TransportReplicationActionTests extends ESTestCase { assertThat(replicationPhase.totalShards(), equalTo(totalShards)); assertThat(replicationPhase.pending(), equalTo(assignedReplicas)); replicationPhase.run(); - final CapturingTransport.CapturedRequest[] capturedRequests = transport.capturedRequests(); - transport.clear(); + final CapturingTransport.CapturedRequest[] capturedRequests = transport.getCapturedRequestsAndClear(); HashMap nodesSentTo = new HashMap<>(); boolean executeOnReplica = @@ -544,8 +547,7 @@ public class TransportReplicationActionTests extends ESTestCase { logger.debug("--> simulating failure on {} with [{}]", capturedRequest.node, t.getClass().getSimpleName()); transport.handleResponse(capturedRequest.requestId, t); if (criticalFailure) { - CapturingTransport.CapturedRequest[] shardFailedRequests = transport.capturedRequests(); - transport.clear(); + CapturingTransport.CapturedRequest[] shardFailedRequests = transport.getCapturedRequestsAndClear(); assertEquals(1, shardFailedRequests.length); CapturingTransport.CapturedRequest shardFailedRequest = shardFailedRequests[0]; // get the shard the request was sent to @@ -636,19 +638,17 @@ public class TransportReplicationActionTests extends ESTestCase { assertThat(transport.capturedRequests().length, equalTo(1)); // try once with successful response transport.handleResponse(transport.capturedRequests()[0].requestId, TransportResponse.Empty.INSTANCE); - assertIndexShardCounter(1); transport.clear(); + assertIndexShardCounter(1); request = new Request(shardId).timeout("100ms"); primaryPhase = action.new PrimaryPhase(request, createTransportChannel(listener)); primaryPhase.run(); assertIndexShardCounter(2); - CapturingTransport.CapturedRequest[] replicationRequests = transport.capturedRequests(); - transport.clear(); + CapturingTransport.CapturedRequest[] replicationRequests = transport.getCapturedRequestsAndClear(); assertThat(replicationRequests.length, equalTo(1)); // try with failure response transport.handleResponse(replicationRequests[0].requestId, new CorruptIndexException("simulated", (String) null)); - CapturingTransport.CapturedRequest[] shardFailedRequests = transport.capturedRequests(); - transport.clear(); + CapturingTransport.CapturedRequest[] shardFailedRequests = transport.getCapturedRequestsAndClear(); assertEquals(1, shardFailedRequests.length); transport.handleResponse(shardFailedRequests[0].requestId, TransportResponse.Empty.INSTANCE); assertIndexShardCounter(1); diff --git a/core/src/test/java/org/elasticsearch/cluster/action/shard/ShardStateActionTests.java b/core/src/test/java/org/elasticsearch/cluster/action/shard/ShardStateActionTests.java index 4ad4a0a3d4c..f69c9149a9c 100644 --- a/core/src/test/java/org/elasticsearch/cluster/action/shard/ShardStateActionTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/action/shard/ShardStateActionTests.java @@ -135,8 +135,7 @@ public class ShardStateActionTests extends ESTestCase { } }); - final CapturingTransport.CapturedRequest[] capturedRequests = transport.capturedRequests(); - transport.clear(); + final CapturingTransport.CapturedRequest[] capturedRequests = transport.getCapturedRequestsAndClear(); assertThat(capturedRequests.length, equalTo(1)); assert !failure.get(); transport.handleResponse(capturedRequests[0].requestId, new TransportException("simulated")); @@ -171,8 +170,7 @@ public class ShardStateActionTests extends ESTestCase { progress.set(true); assertTrue(timedOut.get()); - final CapturingTransport.CapturedRequest[] capturedRequests = transport.capturedRequests(); - transport.clear(); + final CapturingTransport.CapturedRequest[] capturedRequests = transport.getCapturedRequestsAndClear(); assertThat(capturedRequests.length, equalTo(1)); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/transport/CapturingTransport.java b/test/framework/src/main/java/org/elasticsearch/test/transport/CapturingTransport.java index 229dc944b90..eefdb996e65 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/transport/CapturingTransport.java +++ b/test/framework/src/main/java/org/elasticsearch/test/transport/CapturingTransport.java @@ -66,6 +66,19 @@ public class CapturingTransport implements Transport { return capturedRequests.toArray(new CapturedRequest[0]); } + /** + * Returns all requests captured so far. This method does clear the + * captured requests list. If you do not want the captured requests + * list cleared, use {@link #capturedRequests()}. + * + * @return the captured requests + */ + public CapturedRequest[] getCapturedRequestsAndClear() { + CapturedRequest[] capturedRequests = capturedRequests(); + clear(); + return capturedRequests; + } + /** * returns all requests captured so far, grouped by target node. * Doesn't clear the captured request list. See {@link #clear()} @@ -83,6 +96,20 @@ public class CapturingTransport implements Transport { return map; } + /** + * Returns all requests captured so far, grouped by target node. + * This method does clear the captured request list. If you do not + * want the captured requests list cleared, use + * {@link #capturedRequestsByTargetNode()}. + * + * @return the captured requests grouped by target node + */ + public Map> getCapturedRequestsByTargetNodeAndClear() { + Map> map = capturedRequestsByTargetNode(); + clear(); + return map; + } + /** clears captured requests */ public void clear() { capturedRequests.clear(); From db3447fb031f94164e4eb47b505d7187141fefc2 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Tue, 12 Jan 2016 09:55:52 -0500 Subject: [PATCH 16/21] Properly deprecate the field --- .../org/elasticsearch/index/query/SpanNearQueryParser.java | 2 +- .../elasticsearch/index/query/SpanNearQueryBuilderTests.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java index 757bbb91b24..fc899ac5d1e 100644 --- a/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java +++ b/core/src/main/java/org/elasticsearch/index/query/SpanNearQueryParser.java @@ -34,7 +34,7 @@ import java.util.List; public class SpanNearQueryParser implements QueryParser { public static final ParseField SLOP_FIELD = new ParseField("slop"); - public static final ParseField COLLECT_PAYLOADS_FIELD = new ParseField("collect_payloads"); + public static final ParseField COLLECT_PAYLOADS_FIELD = new ParseField("collect_payloads").withAllDeprecated("no longer supported"); public static final ParseField CLAUSES_FIELD = new ParseField("clauses"); public static final ParseField IN_ORDER_FIELD = new ParseField("in_order"); diff --git a/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java index c1fc9bb1b12..dc8d096f688 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SpanNearQueryBuilderTests.java @@ -23,6 +23,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.spans.SpanNearQuery; import org.apache.lucene.search.spans.SpanQuery; import org.elasticsearch.Version; +import org.elasticsearch.common.ParseFieldMatcher; import java.io.IOException; import java.util.Iterator; @@ -146,6 +147,6 @@ public class SpanNearQueryBuilderTests extends AbstractQueryTestCase Date: Wed, 6 Jan 2016 12:12:20 -0500 Subject: [PATCH 17/21] Don't override originalQuery with request filters These filters leak into highlighting and probably other places and cause things like the type name to be highlighted when using requireFieldMatch=false. We could have special hacks to keep them out of highlighting but it feals better to keep them out of any variable named "originalQuery". Closes #15689 --- .../query/TransportValidateQueryAction.java | 5 +- .../search/internal/DefaultSearchContext.java | 59 ++++++++++++++----- .../search/highlight/HighlighterSearchIT.java | 1 - .../validate/SimpleValidateQueryIT.java | 2 +- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java index 326dbc01289..b7195f7df5c 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java @@ -182,11 +182,10 @@ public class TransportValidateQueryAction extends TransportBroadcastAction Date: Tue, 12 Jan 2016 20:07:20 +0100 Subject: [PATCH 18/21] Fixing javadoc problem --- .../elasticsearch/common/geo/builders/LineStringBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java index 1f16037cd0d..4542da436bd 100644 --- a/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java +++ b/core/src/main/java/org/elasticsearch/common/geo/builders/LineStringBuilder.java @@ -42,7 +42,7 @@ public class LineStringBuilder extends CoordinateCollection { * Per GeoJSON spec (http://geojson.org/geojson-spec.html#linestring) * a LineString must contain two or more coordinates * @param coordinates the initial list of coordinates - * @throw {@link IllegalArgumentException} if there are less then two coordinates defined + * @throws IllegalArgumentException if there are less then two coordinates defined */ public LineStringBuilder(List coordinates) { super(coordinates); From cde5bb88b10fa068c2ad77b1d892a23bc0865732 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 12 Jan 2016 11:15:11 -0800 Subject: [PATCH 19/21] Add printing timestamp to wait condition for elasticsearch nodes --- .../org/elasticsearch/gradle/test/ClusterConfiguration.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy index fa23299cee4..e308c1afda8 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy @@ -23,6 +23,8 @@ import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.tasks.Input +import java.time.LocalDateTime + /** Configuration for an elasticsearch cluster, used for integration tests. */ class ClusterConfiguration { @@ -55,6 +57,7 @@ class ClusterConfiguration { @Input Closure waitCondition = { NodeInfo node, AntBuilder ant -> File tmpFile = new File(node.cwd, 'wait.success') + ant.echo(message: "[${LocalDateTime.now()}] Waiting for elasticsearch node", level: "info") ant.get(src: "http://${node.httpUri()}", dest: tmpFile.toString(), ignoreerrors: true, // do not fail on error, so logging buffers can be flushed by the wait task From ce32b959fdcdaf5f3a78df9bf2d8039082735940 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Tue, 12 Jan 2016 14:40:47 -0500 Subject: [PATCH 20/21] fix possible concurrency bug in IMC when indexing threads are faster in writing bytes than the status checker is in checking all shards --- .../org/elasticsearch/indices/IndexingMemoryController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java b/core/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java index 35bf4d3b62c..e4f5416ef53 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java +++ b/core/src/main/java/org/elasticsearch/indices/IndexingMemoryController.java @@ -256,6 +256,8 @@ public class IndexingMemoryController extends AbstractComponent implements Index } finally { runLock.unlock(); } + // Could be while we were checking, more bytes arrived: + totalBytes = bytesWrittenSinceCheck.addAndGet(bytes); } else { break; } From a2796b555f5c174f78303a2ce0c5a6439259f84b Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Tue, 12 Jan 2016 12:10:58 +0100 Subject: [PATCH 21/21] mappings: Search filter should wrap the types filters in a separate boolean as should clauses So that a document must either match with one of the types and the non nested clause. Closes #15757 --- .../index/mapper/MapperService.java | 9 ++++--- .../index/mapper/MapperServiceTests.java | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java index 2ca42413568..25796c605f7 100755 --- a/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MapperService.java @@ -519,16 +519,17 @@ public class MapperService extends AbstractIndexComponent implements Closeable { return termsFilter; } } else { - // Current bool filter requires that at least one should clause matches, even with a must clause. - BooleanQuery.Builder bool = new BooleanQuery.Builder(); + BooleanQuery.Builder typesBool = new BooleanQuery.Builder(); for (String type : types) { DocumentMapper docMapper = documentMapper(type); if (docMapper == null) { - bool.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.SHOULD); + typesBool.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.SHOULD); } else { - bool.add(docMapper.typeFilter(), BooleanClause.Occur.SHOULD); + typesBool.add(docMapper.typeFilter(), BooleanClause.Occur.SHOULD); } } + BooleanQuery.Builder bool = new BooleanQuery.Builder(); + bool.add(typesBool.build(), Occur.MUST); if (filterPercolateType) { bool.add(percolatorType, BooleanClause.Occur.MUST_NOT); } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java b/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java index 035da8163ee..94445d3aadb 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/MapperServiceTests.java @@ -19,9 +19,17 @@ package org.elasticsearch.index.mapper; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.ConstantScoreQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermQuery; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.index.IndexService; +import org.elasticsearch.index.mapper.internal.TypeFieldMapper; import org.elasticsearch.test.ESSingleNodeTestCase; import org.junit.Rule; import org.junit.rules.ExpectedException; @@ -32,6 +40,7 @@ import java.util.HashSet; import java.util.concurrent.ExecutionException; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasToString; public class MapperServiceTests extends ESSingleNodeTestCase { @@ -122,4 +131,22 @@ public class MapperServiceTests extends ESSingleNodeTestCase { } assertFalse(indexService.mapperService().hasMapping(MapperService.DEFAULT_MAPPING)); } + + public void testSearchFilter() { + IndexService indexService = createIndex("index1", client().admin().indices().prepareCreate("index1") + .addMapping("type1", "field1", "type=nested") + .addMapping("type2", new Object[0]) + ); + + Query searchFilter = indexService.mapperService().searchFilter("type1", "type3"); + Query expectedQuery = new BooleanQuery.Builder() + .add(new BooleanQuery.Builder() + .add(new ConstantScoreQuery(new TermQuery(new Term(TypeFieldMapper.NAME, "type1"))), BooleanClause.Occur.SHOULD) + .add(new TermQuery(new Term(TypeFieldMapper.NAME, "type3")), BooleanClause.Occur.SHOULD) + .build(), BooleanClause.Occur.MUST + ) + .add(Queries.newNonNestedFilter(), BooleanClause.Occur.MUST) + .build(); + assertThat(searchFilter, equalTo(new ConstantScoreQuery(expectedQuery))); + } }