Browse Source

AggregatorBuilder and PipelineAggregatorBuilder do not need generics. #18368

Similar reasoning as #18133 but for the aggs API. One important change is that
I moved the base PipelineAggregatorBuilder class to the o.e.s.aggregations
package instead of o.e.s.aggregations.pipeline so that the create method does
not need to be public.
Adrien Grand 9 years ago
parent
commit
a78c7d9911
41 changed files with 428 additions and 300 deletions
  1. 2 2
      core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java
  2. 3 3
      core/src/main/java/org/elasticsearch/search/SearchModule.java
  3. 182 0
      core/src/main/java/org/elasticsearch/search/aggregations/AbstractAggregationBuilder.java
  4. 18 128
      core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilder.java
  5. 1 1
      core/src/main/java/org/elasticsearch/search/aggregations/Aggregator.java
  6. 38 39
      core/src/main/java/org/elasticsearch/search/aggregations/AggregatorFactories.java
  7. 2 3
      core/src/main/java/org/elasticsearch/search/aggregations/AggregatorParsers.java
  8. 84 0
      core/src/main/java/org/elasticsearch/search/aggregations/PipelineAggregatorBuilder.java
  9. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java
  10. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java
  11. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/bucket/global/GlobalAggregationBuilder.java
  12. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregationBuilder.java
  13. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ReverseNestedAggregationBuilder.java
  14. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregationBuilder.java
  15. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregationBuilder.java
  16. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregationBuilder.java
  17. 15 45
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/AbstractPipelineAggregatorBuilder.java
  18. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/BucketHelpers.java
  19. 2 1
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/PipelineAggregator.java
  20. 4 3
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/BucketMetricsPipelineAggregatorBuilder.java
  21. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/avg/AvgBucketPipelineAggregatorBuilder.java
  22. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/max/MaxBucketPipelineAggregatorBuilder.java
  23. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/min/MinBucketPipelineAggregatorBuilder.java
  24. 2 3
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/percentile/PercentilesBucketPipelineAggregatorBuilder.java
  25. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/stats/StatsBucketPipelineAggregatorBuilder.java
  26. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/stats/extended/ExtendedStatsBucketPipelineAggregatorBuilder.java
  27. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/sum/SumBucketPipelineAggregatorBuilder.java
  28. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketscript/BucketScriptPipelineAggregatorBuilder.java
  29. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketselector/BucketSelectorPipelineAggregatorBuilder.java
  30. 4 3
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/cumulativesum/CumulativeSumPipelineAggregatorBuilder.java
  31. 4 3
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/derivative/DerivativePipelineAggregatorBuilder.java
  32. 4 3
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/movavg/MovAvgPipelineAggregatorBuilder.java
  33. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/serialdiff/SerialDiffPipelineAggregatorBuilder.java
  34. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java
  35. 2 2
      core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
  36. 3 3
      core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java
  37. 6 6
      core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java
  38. 1 1
      core/src/test/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/AbstractBucketMetricsTestCase.java
  39. 4 4
      core/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgTests.java
  40. 2 2
      modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateRequestBuilder.java
  41. 7 7
      modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateSourceBuilder.java

+ 2 - 2
core/src/main/java/org/elasticsearch/action/search/SearchRequestBuilder.java

@@ -29,7 +29,7 @@ import org.elasticsearch.script.Script;
 import org.elasticsearch.script.Template;
 import org.elasticsearch.search.Scroll;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.elasticsearch.search.highlight.HighlightBuilder;
 import org.elasticsearch.search.rescore.RescoreBuilder;
@@ -373,7 +373,7 @@ public class SearchRequestBuilder extends ActionRequestBuilder<SearchRequest, Se
     /**
      * Adds an aggregation to the search operation.
      */
-    public SearchRequestBuilder addAggregation(AggregationBuilder<?> aggregation) {
+    public SearchRequestBuilder addAggregation(AggregationBuilder aggregation) {
         sourceBuilder().aggregation(aggregation);
         return this;
     }

+ 3 - 3
core/src/main/java/org/elasticsearch/search/SearchModule.java

@@ -98,6 +98,7 @@ import org.elasticsearch.search.aggregations.AggregationPhase;
 import org.elasticsearch.search.aggregations.Aggregator;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorParsers;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder;
 import org.elasticsearch.search.aggregations.bucket.children.InternalChildren;
 import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
@@ -201,7 +202,6 @@ import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountAggreg
 import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCountParser;
 import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValue;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.InternalBucketMetricValue;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.avg.AvgBucketPipelineAggregator;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.avg.AvgBucketPipelineAggregatorBuilder;
@@ -422,7 +422,7 @@ public class SearchModule extends AbstractModule {
      * @param aggregationName names by which the aggregation may be parsed. The first name is special because it is the name that the reader
      *        is registered under.
      */
-    public <AB extends AggregationBuilder<AB>> void registerAggregation(Writeable.Reader<AB> reader, Aggregator.Parser aggregationParser,
+    public void registerAggregation(Writeable.Reader<? extends AggregationBuilder> reader, Aggregator.Parser aggregationParser,
                                                                         ParseField aggregationName) {
         aggregationParserRegistry.register(aggregationParser, aggregationName);
         namedWriteableRegistry.register(AggregationBuilder.class, aggregationName.getPreferredName(), reader);
@@ -436,7 +436,7 @@ public class SearchModule extends AbstractModule {
      * @param aggregationName names by which the aggregation may be parsed. The first name is special because it is the name that the reader
      *        is registered under.
      */
-    public <AB extends PipelineAggregatorBuilder<AB>> void registerPipelineAggregation(Writeable.Reader<AB> reader,
+    public void registerPipelineAggregation(Writeable.Reader<? extends PipelineAggregatorBuilder> reader,
             PipelineAggregator.Parser aggregationParser, ParseField aggregationName) {
         pipelineAggregationParserRegistry.register(aggregationParser, aggregationName);
         namedWriteableRegistry.register(PipelineAggregatorBuilder.class, aggregationName.getPreferredName(), reader);

+ 182 - 0
core/src/main/java/org/elasticsearch/search/aggregations/AbstractAggregationBuilder.java

@@ -0,0 +1,182 @@
+/*
+ * 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.search.aggregations;
+
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.search.aggregations.InternalAggregation.Type;
+import org.elasticsearch.search.aggregations.support.AggregationContext;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Base implementation of a {@link AggregationBuilder}.
+ */
+public abstract class AbstractAggregationBuilder<AB extends AbstractAggregationBuilder<AB>>
+    extends AggregationBuilder {
+
+    protected Map<String, Object> metaData;
+
+    /**
+     * Constructs a new aggregation builder.
+     *
+     * @param name  The aggregation name
+     * @param type  The aggregation type
+     */
+    public AbstractAggregationBuilder(String name, Type type) {
+        super(name, type);
+    }
+
+    /**
+     * Read from a stream.
+     */
+    protected AbstractAggregationBuilder(StreamInput in, Type type) throws IOException {
+        super(in.readString(), type);
+        factoriesBuilder = new AggregatorFactories.Builder(in);
+        metaData = in.readMap();
+    }
+
+    @Override
+    public final void writeTo(StreamOutput out) throws IOException {
+        out.writeString(name);
+        factoriesBuilder.writeTo(out);
+        out.writeMap(metaData);
+        doWriteTo(out);
+    }
+
+    protected abstract void doWriteTo(StreamOutput out) throws IOException;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public AB subAggregation(AggregationBuilder aggregation) {
+        if (aggregation == null) {
+            throw new IllegalArgumentException("[aggregation] must not be null: [" + name + "]");
+        }
+        factoriesBuilder.addAggregator(aggregation);
+        return (AB) this;
+    }
+
+    /**
+     * Add a sub aggregation to this aggregation.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public AB subAggregation(PipelineAggregatorBuilder aggregation) {
+        if (aggregation == null) {
+            throw new IllegalArgumentException("[aggregation] must not be null: [" + name + "]");
+        }
+        factoriesBuilder.addPipelineAggregator(aggregation);
+        return (AB) this;
+    }
+
+    /**
+     * Registers sub-factories with this factory. The sub-factory will be
+     * responsible for the creation of sub-aggregators under the aggregator
+     * created by this factory.
+     *
+     * @param subFactories
+     *            The sub-factories
+     * @return this factory (fluent interface)
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public AB subAggregations(AggregatorFactories.Builder subFactories) {
+        if (subFactories == null) {
+            throw new IllegalArgumentException("[subFactories] must not be null: [" + name + "]");
+        }
+        this.factoriesBuilder = subFactories;
+        return (AB) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public AB setMetaData(Map<String, Object> metaData) {
+        if (metaData == null) {
+            throw new IllegalArgumentException("[metaData] must not be null: [" + name + "]");
+        }
+        this.metaData = metaData;
+        return (AB) this;
+    }
+
+    public String getType() {
+        return type.name();
+    }
+
+    @Override
+    public final AggregatorFactory<?> build(AggregationContext context, AggregatorFactory<?> parent) throws IOException {
+        AggregatorFactory<?> factory = doBuild(context, parent, factoriesBuilder);
+        return factory;
+    }
+
+    protected abstract AggregatorFactory<?> doBuild(AggregationContext context, AggregatorFactory<?> parent,
+            AggregatorFactories.Builder subfactoriesBuilder) throws IOException;
+
+    @Override
+    public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+        builder.startObject(name);
+
+        if (this.metaData != null) {
+            builder.field("meta", this.metaData);
+        }
+        builder.field(type.name());
+        internalXContent(builder, params);
+
+        if (factoriesBuilder != null && (factoriesBuilder.count()) > 0) {
+            builder.field("aggregations");
+            factoriesBuilder.toXContent(builder, params);
+
+        }
+
+        return builder.endObject();
+    }
+
+    protected abstract XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException;
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(factoriesBuilder, metaData, name, type, doHashCode());
+    }
+
+    protected abstract int doHashCode();
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        @SuppressWarnings("unchecked")
+        AbstractAggregationBuilder<AB> other = (AbstractAggregationBuilder<AB>) obj;
+        if (!Objects.equals(name, other.name))
+            return false;
+        if (!Objects.equals(type, other.type))
+            return false;
+        if (!Objects.equals(metaData, other.metaData))
+            return false;
+        if (!Objects.equals(factoriesBuilder, other.factoriesBuilder))
+            return false;
+        return doEquals(obj);
+    }
+
+    protected abstract boolean doEquals(Object obj);
+
+}

+ 18 - 128
core/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilder.java

@@ -21,29 +21,23 @@ package org.elasticsearch.search.aggregations;
 
 import org.elasticsearch.action.support.ToXContentToBytes;
 import org.elasticsearch.common.io.stream.NamedWriteable;
-import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.ToXContent;
-import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.InternalAggregation.Type;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
 
 import java.io.IOException;
 import java.util.Map;
-import java.util.Objects;
 
 /**
  * A factory that knows how to create an {@link Aggregator} of a specific type.
  */
-public abstract class AggregationBuilder<AB extends AggregationBuilder<AB>>
+public abstract class AggregationBuilder
     extends ToXContentToBytes
     implements NamedWriteable, ToXContent {
 
-    protected String name;
-    protected Type type;
+    protected final String name;
+    protected final Type type;
     protected AggregatorFactories.Builder factoriesBuilder = AggregatorFactories.builder();
-    protected Map<String, Object> metaData;
 
     /**
      * Constructs a new aggregation builder.
@@ -51,7 +45,7 @@ public abstract class AggregationBuilder<AB extends AggregationBuilder<AB>>
      * @param name  The aggregation name
      * @param type  The aggregation type
      */
-    public AggregationBuilder(String name, Type type) {
+    protected AggregationBuilder(String name, Type type) {
         if (name == null) {
             throw new IllegalArgumentException("[name] must not be null: [" + name + "]");
         }
@@ -62,136 +56,32 @@ public abstract class AggregationBuilder<AB extends AggregationBuilder<AB>>
         this.type = type;
     }
 
-    /**
-     * Read from a stream.
-     */
-    protected AggregationBuilder(StreamInput in, Type type) throws IOException {
-        name = in.readString();
-        this.type = type;
-        factoriesBuilder = new AggregatorFactories.Builder(in);
-        metaData = in.readMap();
+    /** Return this aggregation's name. */
+    public String getName() {
+        return name;
     }
 
-    @Override
-    public final void writeTo(StreamOutput out) throws IOException {
-        out.writeString(name);
-        factoriesBuilder.writeTo(out);
-        out.writeMap(metaData);
-        doWriteTo(out);
-    }
+    /** Internal: build an {@link AggregatorFactory} based on the configuration of this builder. */
+    protected abstract AggregatorFactory<?> build(AggregationContext context, AggregatorFactory<?> parent) throws IOException;
 
-    protected abstract void doWriteTo(StreamOutput out) throws IOException;
+    /** Associate metadata with this {@link AggregationBuilder}. */
+    public abstract AggregationBuilder setMetaData(Map<String, Object> metaData);
 
-    /**
-     * Add a sub aggregation to this aggregation.
-     */
-    @SuppressWarnings("unchecked")
-    public AB subAggregation(AggregationBuilder<?> aggregation) {
-        if (aggregation == null) {
-            throw new IllegalArgumentException("[aggregation] must not be null: [" + name + "]");
-        }
-        factoriesBuilder.addAggregator(aggregation);
-        return (AB) this;
-    }
+    /** Add a sub aggregation to this builder. */
+    public abstract AggregationBuilder subAggregation(AggregationBuilder aggregation);
 
-    /**
-     * Add a sub aggregation to this aggregation.
-     */
-    @SuppressWarnings("unchecked")
-    public AB subAggregation(PipelineAggregatorBuilder<?> aggregation) {
-        if (aggregation == null) {
-            throw new IllegalArgumentException("[aggregation] must not be null: [" + name + "]");
-        }
-        factoriesBuilder.addPipelineAggregator(aggregation);
-        return (AB) this;
-    }
+    /** Add a sub aggregation to this builder. */
+    public abstract AggregationBuilder subAggregation(PipelineAggregatorBuilder aggregation);
 
     /**
-     * Registers sub-factories with this factory. The sub-factory will be
+     * Internal: Registers sub-factories with this factory. The sub-factory will be
      * responsible for the creation of sub-aggregators under the aggregator
-     * created by this factory.
+     * created by this factory. This is only for use by {@link AggregatorParsers}.
      *
      * @param subFactories
      *            The sub-factories
      * @return this factory (fluent interface)
      */
-    @SuppressWarnings("unchecked")
-    public AB subAggregations(AggregatorFactories.Builder subFactories) {
-        if (subFactories == null) {
-            throw new IllegalArgumentException("[subFactories] must not be null: [" + name + "]");
-        }
-        this.factoriesBuilder = subFactories;
-        return (AB) this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public AB setMetaData(Map<String, Object> metaData) {
-        if (metaData == null) {
-            throw new IllegalArgumentException("[metaData] must not be null: [" + name + "]");
-        }
-        this.metaData = metaData;
-        return (AB) this;
-    }
-
-    public String getType() {
-        return type.name();
-    }
-
-    public final AggregatorFactory<?> build(AggregationContext context, AggregatorFactory<?> parent) throws IOException {
-        AggregatorFactory<?> factory = doBuild(context, parent, factoriesBuilder);
-        return factory;
-    }
-
-    protected abstract AggregatorFactory<?> doBuild(AggregationContext context, AggregatorFactory<?> parent,
-            AggregatorFactories.Builder subfactoriesBuilder) throws IOException;
-
-    @Override
-    public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
-        builder.startObject(name);
-
-        if (this.metaData != null) {
-            builder.field("meta", this.metaData);
-        }
-        builder.field(type.name());
-        internalXContent(builder, params);
-
-        if (factoriesBuilder != null && (factoriesBuilder.count()) > 0) {
-            builder.field("aggregations");
-            factoriesBuilder.toXContent(builder, params);
-
-        }
-
-        return builder.endObject();
-    }
-
-    protected abstract XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException;
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(factoriesBuilder, metaData, name, type, doHashCode());
-    }
-
-    protected abstract int doHashCode();
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        @SuppressWarnings("unchecked")
-        AggregationBuilder<AB> other = (AggregationBuilder<AB>) obj;
-        if (!Objects.equals(name, other.name))
-            return false;
-        if (!Objects.equals(type, other.type))
-            return false;
-        if (!Objects.equals(metaData, other.metaData))
-            return false;
-        if (!Objects.equals(factoriesBuilder, other.factoriesBuilder))
-            return false;
-        return doEquals(obj);
-    }
-
-    protected abstract boolean doEquals(Object obj);
+    protected abstract AggregationBuilder subAggregations(AggregatorFactories.Builder subFactories);
 
 }

+ 1 - 1
core/src/main/java/org/elasticsearch/search/aggregations/Aggregator.java

@@ -55,7 +55,7 @@ public abstract class Aggregator extends BucketCollector implements Releasable {
          * @return                  The resolved aggregator factory or {@code null} in case the aggregation should be skipped
          * @throws java.io.IOException      When parsing fails
          */
-        AggregationBuilder<?> parse(String aggregationName, QueryParseContext context) throws IOException;
+        AggregationBuilder parse(String aggregationName, QueryParseContext context) throws IOException;
     }
 
     /**

+ 38 - 39
core/src/main/java/org/elasticsearch/search/aggregations/AggregatorFactories.java

@@ -24,7 +24,6 @@ import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.Writeable;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
 import org.elasticsearch.search.aggregations.support.AggregationPath;
 import org.elasticsearch.search.aggregations.support.AggregationPath.PathElement;
@@ -45,18 +44,18 @@ import java.util.Set;
 public class AggregatorFactories {
 
     public static final AggregatorFactories EMPTY = new AggregatorFactories(null, new AggregatorFactory<?>[0],
-            new ArrayList<PipelineAggregatorBuilder<?>>());
+            new ArrayList<PipelineAggregatorBuilder>());
 
     private AggregatorFactory<?> parent;
     private AggregatorFactory<?>[] factories;
-    private List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories;
+    private List<PipelineAggregatorBuilder> pipelineAggregatorFactories;
 
     public static Builder builder() {
         return new Builder();
     }
 
     private AggregatorFactories(AggregatorFactory<?> parent, AggregatorFactory<?>[] factories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregators) {
+            List<PipelineAggregatorBuilder> pipelineAggregators) {
         this.parent = parent;
         this.factories = factories;
         this.pipelineAggregatorFactories = pipelineAggregators;
@@ -64,7 +63,7 @@ public class AggregatorFactories {
 
     public List<PipelineAggregator> createPipelineAggregators() throws IOException {
         List<PipelineAggregator> pipelineAggregators = new ArrayList<>();
-        for (PipelineAggregatorBuilder<?> factory : this.pipelineAggregatorFactories) {
+        for (PipelineAggregatorBuilder factory : this.pipelineAggregatorFactories) {
             pipelineAggregators.add(factory.create());
         }
         return pipelineAggregators;
@@ -117,15 +116,15 @@ public class AggregatorFactories {
         for (AggregatorFactory<?> factory : factories) {
             factory.validate();
         }
-        for (PipelineAggregatorBuilder<?> factory : pipelineAggregatorFactories) {
+        for (PipelineAggregatorBuilder factory : pipelineAggregatorFactories) {
             factory.validate(parent, factories, pipelineAggregatorFactories);
         }
     }
 
     public static class Builder extends ToXContentToBytes implements Writeable {
         private final Set<String> names = new HashSet<>();
-        private final List<AggregationBuilder<?>> aggregationBuilders = new ArrayList<>();
-        private final List<PipelineAggregatorBuilder<?>> pipelineAggregatorBuilders = new ArrayList<>();
+        private final List<AggregationBuilder> aggregationBuilders = new ArrayList<>();
+        private final List<PipelineAggregatorBuilder> pipelineAggregatorBuilders = new ArrayList<>();
         private boolean skipResolveOrder;
 
         /**
@@ -151,11 +150,11 @@ public class AggregatorFactories {
         @Override
         public void writeTo(StreamOutput out) throws IOException {
             out.writeVInt(this.aggregationBuilders.size());
-            for (AggregationBuilder<?> factory : aggregationBuilders) {
+            for (AggregationBuilder factory : aggregationBuilders) {
                 out.writeNamedWriteable(factory);
             }
             out.writeVInt(this.pipelineAggregatorBuilders.size());
-            for (PipelineAggregatorBuilder<?> factory : pipelineAggregatorBuilders) {
+            for (PipelineAggregatorBuilder factory : pipelineAggregatorBuilders) {
                 out.writeNamedWriteable(factory);
             }
         }
@@ -164,7 +163,7 @@ public class AggregatorFactories {
             throw new UnsupportedOperationException("This needs to be removed");
         }
 
-        public Builder addAggregator(AggregationBuilder<?> factory) {
+        public Builder addAggregator(AggregationBuilder factory) {
             if (!names.add(factory.name)) {
                 throw new IllegalArgumentException("Two sibling aggregations cannot have the same name: [" + factory.name + "]");
             }
@@ -172,7 +171,7 @@ public class AggregatorFactories {
             return this;
         }
 
-        public Builder addPipelineAggregator(PipelineAggregatorBuilder<?> pipelineAggregatorFactory) {
+        public Builder addPipelineAggregator(PipelineAggregatorBuilder pipelineAggregatorFactory) {
             this.pipelineAggregatorBuilders.add(pipelineAggregatorFactory);
             return this;
         }
@@ -189,7 +188,7 @@ public class AggregatorFactories {
             if (aggregationBuilders.isEmpty() && pipelineAggregatorBuilders.isEmpty()) {
                 return EMPTY;
             }
-            List<PipelineAggregatorBuilder<?>> orderedpipelineAggregators = null;
+            List<PipelineAggregatorBuilder> orderedpipelineAggregators = null;
             if (skipResolveOrder) {
                 orderedpipelineAggregators = new ArrayList<>(pipelineAggregatorBuilders);
             } else {
@@ -202,31 +201,31 @@ public class AggregatorFactories {
             return new AggregatorFactories(parent, aggFactories, orderedpipelineAggregators);
         }
 
-        private List<PipelineAggregatorBuilder<?>> resolvePipelineAggregatorOrder(
-                List<PipelineAggregatorBuilder<?>> pipelineAggregatorBuilders, List<AggregationBuilder<?>> aggBuilders) {
-            Map<String, PipelineAggregatorBuilder<?>> pipelineAggregatorBuildersMap = new HashMap<>();
-            for (PipelineAggregatorBuilder<?> builder : pipelineAggregatorBuilders) {
+        private List<PipelineAggregatorBuilder> resolvePipelineAggregatorOrder(
+                List<PipelineAggregatorBuilder> pipelineAggregatorBuilders, List<AggregationBuilder> aggBuilders) {
+            Map<String, PipelineAggregatorBuilder> pipelineAggregatorBuildersMap = new HashMap<>();
+            for (PipelineAggregatorBuilder builder : pipelineAggregatorBuilders) {
                 pipelineAggregatorBuildersMap.put(builder.getName(), builder);
             }
-            Map<String, AggregationBuilder<?>> aggBuildersMap = new HashMap<>();
-            for (AggregationBuilder<?> aggBuilder : aggBuilders) {
+            Map<String, AggregationBuilder> aggBuildersMap = new HashMap<>();
+            for (AggregationBuilder aggBuilder : aggBuilders) {
                 aggBuildersMap.put(aggBuilder.name, aggBuilder);
             }
-            List<PipelineAggregatorBuilder<?>> orderedPipelineAggregatorrs = new LinkedList<>();
-            List<PipelineAggregatorBuilder<?>> unmarkedBuilders = new ArrayList<PipelineAggregatorBuilder<?>>(pipelineAggregatorBuilders);
-            Set<PipelineAggregatorBuilder<?>> temporarilyMarked = new HashSet<PipelineAggregatorBuilder<?>>();
+            List<PipelineAggregatorBuilder> orderedPipelineAggregatorrs = new LinkedList<>();
+            List<PipelineAggregatorBuilder> unmarkedBuilders = new ArrayList<PipelineAggregatorBuilder>(pipelineAggregatorBuilders);
+            Set<PipelineAggregatorBuilder> temporarilyMarked = new HashSet<PipelineAggregatorBuilder>();
             while (!unmarkedBuilders.isEmpty()) {
-                PipelineAggregatorBuilder<?> builder = unmarkedBuilders.get(0);
+                PipelineAggregatorBuilder builder = unmarkedBuilders.get(0);
                 resolvePipelineAggregatorOrder(aggBuildersMap, pipelineAggregatorBuildersMap, orderedPipelineAggregatorrs, unmarkedBuilders,
                         temporarilyMarked, builder);
             }
             return orderedPipelineAggregatorrs;
         }
 
-        private void resolvePipelineAggregatorOrder(Map<String, AggregationBuilder<?>> aggBuildersMap,
-                Map<String, PipelineAggregatorBuilder<?>> pipelineAggregatorBuildersMap,
-                List<PipelineAggregatorBuilder<?>> orderedPipelineAggregators, List<PipelineAggregatorBuilder<?>> unmarkedBuilders,
-                Set<PipelineAggregatorBuilder<?>> temporarilyMarked, PipelineAggregatorBuilder<?> builder) {
+        private void resolvePipelineAggregatorOrder(Map<String, AggregationBuilder> aggBuildersMap,
+                Map<String, PipelineAggregatorBuilder> pipelineAggregatorBuildersMap,
+                List<PipelineAggregatorBuilder> orderedPipelineAggregators, List<PipelineAggregatorBuilder> unmarkedBuilders,
+                Set<PipelineAggregatorBuilder> temporarilyMarked, PipelineAggregatorBuilder builder) {
             if (temporarilyMarked.contains(builder)) {
                 throw new IllegalArgumentException("Cyclical dependency found with pipeline aggregator [" + builder.getName() + "]");
             } else if (unmarkedBuilders.contains(builder)) {
@@ -238,7 +237,7 @@ public class AggregatorFactories {
                     if (bucketsPath.equals("_count") || bucketsPath.equals("_key")) {
                         continue;
                     } else if (aggBuildersMap.containsKey(firstAggName)) {
-                        AggregationBuilder<?> aggBuilder = aggBuildersMap.get(firstAggName);
+                        AggregationBuilder aggBuilder = aggBuildersMap.get(firstAggName);
                         for (int i = 1; i < bucketsPathElements.size(); i++) {
                             PathElement pathElement = bucketsPathElements.get(i);
                             String aggName = pathElement.name;
@@ -247,9 +246,9 @@ public class AggregatorFactories {
                             } else {
                                 // Check the non-pipeline sub-aggregator
                                 // factories
-                                AggregationBuilder<?>[] subBuilders = aggBuilder.factoriesBuilder.getAggregatorFactories();
+                                AggregationBuilder[] subBuilders = aggBuilder.factoriesBuilder.getAggregatorFactories();
                                 boolean foundSubBuilder = false;
-                                for (AggregationBuilder<?> subBuilder : subBuilders) {
+                                for (AggregationBuilder subBuilder : subBuilders) {
                                     if (aggName.equals(subBuilder.name)) {
                                         aggBuilder = subBuilder;
                                         foundSubBuilder = true;
@@ -258,9 +257,9 @@ public class AggregatorFactories {
                                 }
                                 // Check the pipeline sub-aggregator factories
                                 if (!foundSubBuilder && (i == bucketsPathElements.size() - 1)) {
-                                    List<PipelineAggregatorBuilder<?>> subPipelineBuilders = aggBuilder.factoriesBuilder.pipelineAggregatorBuilders;
-                                    for (PipelineAggregatorBuilder<?> subFactory : subPipelineBuilders) {
-                                        if (aggName.equals(subFactory.name())) {
+                                    List<PipelineAggregatorBuilder> subPipelineBuilders = aggBuilder.factoriesBuilder.pipelineAggregatorBuilders;
+                                    for (PipelineAggregatorBuilder subFactory : subPipelineBuilders) {
+                                        if (aggName.equals(subFactory.getName())) {
                                             foundSubBuilder = true;
                                             break;
                                         }
@@ -274,7 +273,7 @@ public class AggregatorFactories {
                         }
                         continue;
                     } else {
-                        PipelineAggregatorBuilder<?> matchingBuilder = pipelineAggregatorBuildersMap.get(firstAggName);
+                        PipelineAggregatorBuilder matchingBuilder = pipelineAggregatorBuildersMap.get(firstAggName);
                         if (matchingBuilder != null) {
                             resolvePipelineAggregatorOrder(aggBuildersMap, pipelineAggregatorBuildersMap, orderedPipelineAggregators,
                                     unmarkedBuilders, temporarilyMarked, matchingBuilder);
@@ -289,11 +288,11 @@ public class AggregatorFactories {
             }
         }
 
-        AggregationBuilder<?>[] getAggregatorFactories() {
-            return this.aggregationBuilders.toArray(new AggregationBuilder<?>[this.aggregationBuilders.size()]);
+        AggregationBuilder[] getAggregatorFactories() {
+            return this.aggregationBuilders.toArray(new AggregationBuilder[this.aggregationBuilders.size()]);
         }
 
-        List<PipelineAggregatorBuilder<?>> getPipelineAggregatorFactories() {
+        List<PipelineAggregatorBuilder> getPipelineAggregatorFactories() {
             return this.pipelineAggregatorBuilders;
         }
 
@@ -305,12 +304,12 @@ public class AggregatorFactories {
         public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
             builder.startObject();
             if (aggregationBuilders != null) {
-                for (AggregationBuilder<?> subAgg : aggregationBuilders) {
+                for (AggregationBuilder subAgg : aggregationBuilders) {
                     subAgg.toXContent(builder, params);
                 }
             }
             if (pipelineAggregatorBuilders != null) {
-                for (PipelineAggregatorBuilder<?> subAgg : pipelineAggregatorBuilders) {
+                for (PipelineAggregatorBuilder subAgg : pipelineAggregatorBuilders) {
                     subAgg.toXContent(builder, params);
                 }
             }

+ 2 - 3
core/src/main/java/org/elasticsearch/search/aggregations/AggregatorParsers.java

@@ -24,7 +24,6 @@ import org.elasticsearch.common.xcontent.ParseFieldRegistry;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.Map;
@@ -104,8 +103,8 @@ public class AggregatorParsers {
                         + token + "], expected a [" + XContentParser.Token.START_OBJECT + "].");
             }
 
-            AggregationBuilder<?> aggFactory = null;
-            PipelineAggregatorBuilder<?> pipelineAggregatorFactory = null;
+            AggregationBuilder aggFactory = null;
+            PipelineAggregatorBuilder pipelineAggregatorFactory = null;
             AggregatorFactories.Builder subFactories = null;
 
             Map<String, Object> metaData = null;

+ 84 - 0
core/src/main/java/org/elasticsearch/search/aggregations/PipelineAggregatorBuilder.java

@@ -0,0 +1,84 @@
+/*
+ * 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.search.aggregations;
+
+import org.elasticsearch.action.support.ToXContentToBytes;
+import org.elasticsearch.common.io.stream.NamedWriteable;
+import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A factory that knows how to create an {@link PipelineAggregator} of a
+ * specific type.
+ */
+public abstract class PipelineAggregatorBuilder extends ToXContentToBytes
+        implements NamedWriteable {
+
+    protected final String name;
+    protected final String[] bucketsPaths;
+
+    /**
+     * Constructs a new pipeline aggregator factory.
+     *
+     * @param name
+     *            The aggregation name
+     */
+    protected PipelineAggregatorBuilder(String name, String[] bucketsPaths) {
+        if (name == null) {
+            throw new IllegalArgumentException("[name] must not be null: [" + name + "]");
+        }
+        if (bucketsPaths == null) {
+            throw new IllegalArgumentException("[bucketsPaths] must not be null: [" + name + "]");
+        }
+        this.name = name;
+        this.bucketsPaths = bucketsPaths;
+    }
+
+    /** Return this aggregation's name. */
+    public String getName() {
+        return name;
+    }
+
+    /** Return the consumed buckets paths. */
+    public final String[] getBucketsPaths() {
+        return bucketsPaths;
+    }
+
+    /**
+     * Internal: Validates the state of this factory (makes sure the factory is properly
+     * configured)
+     */
+    protected abstract void validate(AggregatorFactory<?> parent, AggregatorFactory<?>[] factories,
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories);
+
+    /**
+     * Creates the pipeline aggregator
+     *
+     * @return The created aggregator
+     */
+    protected abstract PipelineAggregator create() throws IOException;
+
+    /** Associate metadata with this {@link PipelineAggregatorBuilder}. */
+    public abstract PipelineAggregatorBuilder setMetaData(Map<String, Object> metaData);
+
+}

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java

@@ -28,7 +28,7 @@ import org.elasticsearch.index.query.EmptyQueryBuilder;
 import org.elasticsearch.index.query.MatchAllQueryBuilder;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
@@ -36,7 +36,7 @@ import org.elasticsearch.search.aggregations.support.AggregationContext;
 import java.io.IOException;
 import java.util.Objects;
 
-public class FilterAggregationBuilder extends AggregationBuilder<FilterAggregationBuilder> {
+public class FilterAggregationBuilder extends AbstractAggregationBuilder<FilterAggregationBuilder> {
     public static final String NAME = InternalFilter.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/filters/FiltersAggregationBuilder.java

@@ -28,7 +28,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.bucket.filters.FiltersAggregator.KeyedFilter;
@@ -43,7 +43,7 @@ import java.util.Objects;
 
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
 
-public class FiltersAggregationBuilder extends AggregationBuilder<FiltersAggregationBuilder> {
+public class FiltersAggregationBuilder extends AbstractAggregationBuilder<FiltersAggregationBuilder> {
     public static final String NAME = InternalFilters.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/global/GlobalAggregationBuilder.java

@@ -24,14 +24,14 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
 
 import java.io.IOException;
 
-public class GlobalAggregationBuilder extends AggregationBuilder<GlobalAggregationBuilder> {
+public class GlobalAggregationBuilder extends AbstractAggregationBuilder<GlobalAggregationBuilder> {
     public static final String NAME = InternalGlobal.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregationBuilder.java

@@ -26,7 +26,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
@@ -34,7 +34,7 @@ import org.elasticsearch.search.aggregations.support.AggregationContext;
 import java.io.IOException;
 import java.util.Objects;
 
-public class NestedAggregationBuilder extends AggregationBuilder<NestedAggregationBuilder> {
+public class NestedAggregationBuilder extends AbstractAggregationBuilder<NestedAggregationBuilder> {
     public static final String NAME = InternalNested.TYPE.name();
     public static final ParseField AGGREGATION_FIELD_NAME = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ReverseNestedAggregationBuilder.java

@@ -26,7 +26,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
@@ -34,7 +34,7 @@ import org.elasticsearch.search.aggregations.support.AggregationContext;
 import java.io.IOException;
 import java.util.Objects;
 
-public class ReverseNestedAggregationBuilder extends AggregationBuilder<ReverseNestedAggregationBuilder> {
+public class ReverseNestedAggregationBuilder extends AbstractAggregationBuilder<ReverseNestedAggregationBuilder> {
     public static final String NAME = InternalReverseNested.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregationBuilder.java

@@ -26,7 +26,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
@@ -34,7 +34,7 @@ import org.elasticsearch.search.aggregations.support.AggregationContext;
 import java.io.IOException;
 import java.util.Objects;
 
-public class SamplerAggregationBuilder extends AggregationBuilder<SamplerAggregationBuilder> {
+public class SamplerAggregationBuilder extends AbstractAggregationBuilder<SamplerAggregationBuilder> {
     public static final String NAME = InternalSampler.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/metrics/scripted/ScriptedMetricAggregationBuilder.java

@@ -29,7 +29,7 @@ import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.script.Script;
 import org.elasticsearch.script.ScriptParameterParser;
 import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
@@ -40,7 +40,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
-public class ScriptedMetricAggregationBuilder extends AggregationBuilder<ScriptedMetricAggregationBuilder> {
+public class ScriptedMetricAggregationBuilder extends AbstractAggregationBuilder<ScriptedMetricAggregationBuilder> {
 
     public static final String NAME = InternalScriptedMetric.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/metrics/tophits/TopHitsAggregationBuilder.java

@@ -29,8 +29,8 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.script.Script;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregationInitializationException;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.AggregationContext;
@@ -51,7 +51,7 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 
-public class TopHitsAggregationBuilder extends AggregationBuilder<TopHitsAggregationBuilder> {
+public class TopHitsAggregationBuilder extends AbstractAggregationBuilder<TopHitsAggregationBuilder> {
     public static final String NAME = InternalTopHits.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 15 - 45
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/PipelineAggregatorBuilder.java → core/src/main/java/org/elasticsearch/search/aggregations/pipeline/AbstractPipelineAggregatorBuilder.java

@@ -18,13 +18,12 @@
  */
 package org.elasticsearch.search.aggregations.pipeline;
 
-import org.elasticsearch.action.support.ToXContentToBytes;
 import org.elasticsearch.common.ParseField;
-import org.elasticsearch.common.io.stream.NamedWriteable;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -33,52 +32,32 @@ import java.util.Map;
 import java.util.Objects;
 
 /**
- * A factory that knows how to create an {@link PipelineAggregator} of a
- * specific type.
+ * Base implementation of a {@link PipelineAggregatorBuilder}.
  */
-public abstract class PipelineAggregatorBuilder<PAB extends PipelineAggregatorBuilder<PAB>> extends ToXContentToBytes
-        implements NamedWriteable {
+public abstract class AbstractPipelineAggregatorBuilder<PAB extends AbstractPipelineAggregatorBuilder<PAB>>
+        extends PipelineAggregatorBuilder {
 
     /**
      * Field shared by many parsers.
      */
     public static final ParseField BUCKETS_PATH_FIELD = new ParseField("buckets_path");
 
-    protected final String name;
     protected final String type;
-    protected final String[] bucketsPaths;
     protected Map<String, Object> metaData;
 
-    /**
-     * Constructs a new pipeline aggregator factory.
-     *
-     * @param name
-     *            The aggregation name
-     * @param type
-     *            The aggregation type
-     */
-    protected PipelineAggregatorBuilder(String name, String type, String[] bucketsPaths) {
-        if (name == null) {
-            throw new IllegalArgumentException("[name] must not be null: [" + name + "]");
-        }
+    protected AbstractPipelineAggregatorBuilder(String name, String type, String[] bucketsPaths) {
+        super(name, bucketsPaths);
         if (type == null) {
             throw new IllegalArgumentException("[type] must not be null: [" + name + "]");
         }
-        if (bucketsPaths == null) {
-            throw new IllegalArgumentException("[bucketsPaths] must not be null: [" + name + "]");
-        }
-        this.name = name;
         this.type = type;
-        this.bucketsPaths = bucketsPaths;
     }
 
     /**
      * Read from a stream.
      */
-    protected PipelineAggregatorBuilder(StreamInput in, String type) throws IOException {
-        name = in.readString();
-        this.type = type;
-        bucketsPaths = in.readStringArray();
+    protected AbstractPipelineAggregatorBuilder(StreamInput in, String type) throws IOException {
+        this(in.readString(), type, in.readStringArray());
         metaData = in.readMap();
     }
 
@@ -92,10 +71,6 @@ public abstract class PipelineAggregatorBuilder<PAB extends PipelineAggregatorBu
 
     protected abstract void doWriteTo(StreamOutput out) throws IOException;
 
-    public String name() {
-        return name;
-    }
-
     public String type() {
         return type;
     }
@@ -104,8 +79,9 @@ public abstract class PipelineAggregatorBuilder<PAB extends PipelineAggregatorBu
      * Validates the state of this factory (makes sure the factory is properly
      * configured)
      */
+    @Override
     public final void validate(AggregatorFactory<?> parent, AggregatorFactory<?>[] factories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         doValidate(parent, factories, pipelineAggregatorFactories);
     }
 
@@ -116,29 +92,23 @@ public abstract class PipelineAggregatorBuilder<PAB extends PipelineAggregatorBu
      *
      * @return The created aggregator
      */
+    @Override
     public final PipelineAggregator create() throws IOException {
         PipelineAggregator aggregator = createInternal(this.metaData);
         return aggregator;
     }
 
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] factories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
     }
 
     @SuppressWarnings("unchecked")
+    @Override
     public PAB setMetaData(Map<String, Object> metaData) {
         this.metaData = metaData;
         return (PAB) this;
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public String[] getBucketsPaths() {
-        return bucketsPaths;
-    }
-
     @Override
     public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
         builder.startObject(getName());
@@ -164,7 +134,7 @@ public abstract class PipelineAggregatorBuilder<PAB extends PipelineAggregatorBu
     }
 
     /**
-     * @return <code>true</code> if the {@link PipelineAggregatorBuilder}
+     * @return <code>true</code> if the {@link AbstractPipelineAggregatorBuilder}
      *         overrides the XContent rendering of the bucketPath option.
      */
     protected boolean overrideBucketsPath() {
@@ -187,7 +157,7 @@ public abstract class PipelineAggregatorBuilder<PAB extends PipelineAggregatorBu
         if (getClass() != obj.getClass())
             return false;
         @SuppressWarnings("unchecked")
-        PipelineAggregatorBuilder<PAB> other = (PipelineAggregatorBuilder<PAB>) obj;
+        AbstractPipelineAggregatorBuilder<PAB> other = (AbstractPipelineAggregatorBuilder<PAB>) obj;
         if (!Objects.equals(name, other.name))
             return false;
         if (!Objects.equals(type, other.type))

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/BucketHelpers.java

@@ -156,7 +156,7 @@ public class BucketHelpers {
         try {
             Object propertyValue = bucket.getProperty(agg.getName(), aggPathAsList);
             if (propertyValue == null) {
-                throw new AggregationExecutionException(PipelineAggregatorBuilder.BUCKETS_PATH_FIELD.getPreferredName()
+                throw new AggregationExecutionException(AbstractPipelineAggregatorBuilder.BUCKETS_PATH_FIELD.getPreferredName()
                         + " must reference either a number value or a single value numeric metric aggregation");
             } else {
                 double value;
@@ -165,7 +165,7 @@ public class BucketHelpers {
                 } else if (propertyValue instanceof InternalNumericMetricsAggregation.SingleValue) {
                     value = ((InternalNumericMetricsAggregation.SingleValue) propertyValue).value();
                 } else {
-                    throw new AggregationExecutionException(PipelineAggregatorBuilder.BUCKETS_PATH_FIELD.getPreferredName()
+                    throw new AggregationExecutionException(AbstractPipelineAggregatorBuilder.BUCKETS_PATH_FIELD.getPreferredName()
                             + " must reference either a number value or a single value numeric metric aggregation, got: "
                             + propertyValue.getClass().getCanonicalName());
                 }

+ 2 - 1
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/PipelineAggregator.java

@@ -28,6 +28,7 @@ import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
 import org.elasticsearch.search.aggregations.InternalAggregation.Type;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.Map;
@@ -55,7 +56,7 @@ public abstract class PipelineAggregator implements Streamable {
          * @throws java.io.IOException
          *             When parsing fails
          */
-        PipelineAggregatorBuilder<?> parse(String pipelineAggregatorName, QueryParseContext context)
+        PipelineAggregatorBuilder parse(String pipelineAggregatorName, QueryParseContext context)
                 throws IOException;
     }
 

+ 4 - 3
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/BucketMetricsPipelineAggregatorBuilder.java

@@ -24,9 +24,10 @@ import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.List;
@@ -34,7 +35,7 @@ import java.util.Map;
 import java.util.Objects;
 
 public abstract class BucketMetricsPipelineAggregatorBuilder<AF extends BucketMetricsPipelineAggregatorBuilder<AF>>
-        extends PipelineAggregatorBuilder<AF> {
+        extends AbstractPipelineAggregatorBuilder<AF> {
 
     private String format = null;
     private GapPolicy gapPolicy = GapPolicy.SKIP;
@@ -106,7 +107,7 @@ public abstract class BucketMetricsPipelineAggregatorBuilder<AF extends BucketMe
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/avg/AvgBucketPipelineAggregatorBuilder.java

@@ -24,8 +24,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
@@ -60,7 +60,7 @@ public class AvgBucketPipelineAggregatorBuilder extends BucketMetricsPipelineAgg
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/max/MaxBucketPipelineAggregatorBuilder.java

@@ -24,8 +24,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
@@ -60,7 +60,7 @@ public class MaxBucketPipelineAggregatorBuilder extends BucketMetricsPipelineAgg
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/min/MinBucketPipelineAggregatorBuilder.java

@@ -24,8 +24,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
@@ -60,7 +60,7 @@ public class MinBucketPipelineAggregatorBuilder extends BucketMetricsPipelineAgg
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 3
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/percentile/PercentilesBucketPipelineAggregatorBuilder.java

@@ -27,13 +27,12 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
 import java.io.IOException;
-import java.text.ParseException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -97,7 +96,7 @@ public class PercentilesBucketPipelineAggregatorBuilder
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/stats/StatsBucketPipelineAggregatorBuilder.java

@@ -24,9 +24,9 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
@@ -62,7 +62,7 @@ public class StatsBucketPipelineAggregatorBuilder extends BucketMetricsPipelineA
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/stats/extended/ExtendedStatsBucketPipelineAggregatorBuilder.java

@@ -24,9 +24,9 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
 import java.io.IOException;
@@ -85,7 +85,7 @@ public class ExtendedStatsBucketPipelineAggregatorBuilder
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/sum/SumBucketPipelineAggregatorBuilder.java

@@ -24,8 +24,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregatorBuilder;
 
@@ -60,7 +60,7 @@ public class SumBucketPipelineAggregatorBuilder extends BucketMetricsPipelineAgg
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketscript/BucketScriptPipelineAggregatorBuilder.java

@@ -29,9 +29,9 @@ import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.script.Script;
 import org.elasticsearch.script.Script.ScriptField;
 import org.elasticsearch.search.DocValueFormat;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -46,7 +46,7 @@ import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.FORMAT;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.GAP_POLICY;
 
-public class BucketScriptPipelineAggregatorBuilder extends PipelineAggregatorBuilder<BucketScriptPipelineAggregatorBuilder> {
+public class BucketScriptPipelineAggregatorBuilder extends AbstractPipelineAggregatorBuilder<BucketScriptPipelineAggregatorBuilder> {
     public static final String NAME = BucketScriptPipelineAggregator.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/bucketselector/BucketSelectorPipelineAggregatorBuilder.java

@@ -28,9 +28,9 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.script.Script;
 import org.elasticsearch.script.Script.ScriptField;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -44,7 +44,7 @@ import java.util.TreeMap;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.BUCKETS_PATH;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.GAP_POLICY;
 
-public class BucketSelectorPipelineAggregatorBuilder extends PipelineAggregatorBuilder<BucketSelectorPipelineAggregatorBuilder> {
+public class BucketSelectorPipelineAggregatorBuilder extends AbstractPipelineAggregatorBuilder<BucketSelectorPipelineAggregatorBuilder> {
     public static final String NAME = BucketSelectorPipelineAggregator.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 4 - 3
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/cumulativesum/CumulativeSumPipelineAggregatorBuilder.java

@@ -28,9 +28,10 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.bucket.histogram.AbstractHistogramAggregatorFactory;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsParser;
 
 import java.io.IOException;
@@ -42,7 +43,7 @@ import java.util.Objects;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.BUCKETS_PATH;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.FORMAT;
 
-public class CumulativeSumPipelineAggregatorBuilder extends PipelineAggregatorBuilder<CumulativeSumPipelineAggregatorBuilder> {
+public class CumulativeSumPipelineAggregatorBuilder extends AbstractPipelineAggregatorBuilder<CumulativeSumPipelineAggregatorBuilder> {
     public static final String NAME = CumulativeSumPipelineAggregator.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 
@@ -98,7 +99,7 @@ public class CumulativeSumPipelineAggregatorBuilder extends PipelineAggregatorBu
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatorFactories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatorFactories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 4 - 3
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/derivative/DerivativePipelineAggregatorBuilder.java

@@ -30,12 +30,13 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.bucket.histogram.AbstractHistogramAggregatorFactory;
 import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregatorFactory;
 import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.joda.time.DateTimeZone;
 
 import java.io.IOException;
@@ -44,7 +45,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
-public class DerivativePipelineAggregatorBuilder extends PipelineAggregatorBuilder<DerivativePipelineAggregatorBuilder> {
+public class DerivativePipelineAggregatorBuilder extends AbstractPipelineAggregatorBuilder<DerivativePipelineAggregatorBuilder> {
     public static final String NAME = DerivativePipelineAggregator.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 
@@ -156,7 +157,7 @@ public class DerivativePipelineAggregatorBuilder extends PipelineAggregatorBuild
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatoractories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatoractories) {
         if (bucketsPaths.length != 1) {
             throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
                     + " must contain a single entry for aggregation [" + name + "]");

+ 4 - 3
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/movavg/MovAvgPipelineAggregatorBuilder.java

@@ -29,10 +29,11 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.bucket.histogram.AbstractHistogramAggregatorFactory;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.movavg.models.MovAvgModel;
 import org.elasticsearch.search.aggregations.pipeline.movavg.models.MovAvgModelBuilder;
 import org.elasticsearch.search.aggregations.pipeline.movavg.models.SimpleModel;
@@ -48,7 +49,7 @@ import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.FORMAT;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.GAP_POLICY;
 
-public class MovAvgPipelineAggregatorBuilder extends PipelineAggregatorBuilder<MovAvgPipelineAggregatorBuilder> {
+public class MovAvgPipelineAggregatorBuilder extends AbstractPipelineAggregatorBuilder<MovAvgPipelineAggregatorBuilder> {
     public static final String NAME = MovAvgPipelineAggregator.TYPE.name();
     public static final ParseField AGGREGATION_FIELD_NAME = new ParseField(NAME);
 
@@ -256,7 +257,7 @@ public class MovAvgPipelineAggregatorBuilder extends PipelineAggregatorBuilder<M
 
     @Override
     public void doValidate(AggregatorFactory<?> parent, AggregatorFactory<?>[] aggFactories,
-            List<PipelineAggregatorBuilder<?>> pipelineAggregatoractories) {
+            List<PipelineAggregatorBuilder> pipelineAggregatoractories) {
         if (minimize != null && minimize && !model.canBeMinimized()) {
             // If the user asks to minimize, but this model doesn't support
             // it, throw exception

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/serialdiff/SerialDiffPipelineAggregatorBuilder.java

@@ -27,9 +27,9 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.DocValueFormat;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -40,7 +40,7 @@ import java.util.Objects;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.BUCKETS_PATH;
 import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregator.Parser.FORMAT;
 
-public class SerialDiffPipelineAggregatorBuilder extends PipelineAggregatorBuilder<SerialDiffPipelineAggregatorBuilder> {
+public class SerialDiffPipelineAggregatorBuilder extends AbstractPipelineAggregatorBuilder<SerialDiffPipelineAggregatorBuilder> {
     public static final String NAME = SerialDiffPipelineAggregator.TYPE.name();
     public static final ParseField AGGREGATION_NAME_FIELD = new ParseField(NAME);
 

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java

@@ -31,7 +31,7 @@ import org.elasticsearch.script.ScriptContext;
 import org.elasticsearch.script.SearchScript;
 import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.aggregations.AggregationInitializationException;
-import org.elasticsearch.search.aggregations.AggregationBuilder;
+import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
@@ -47,7 +47,7 @@ import java.util.Objects;
  *
  */
 public abstract class ValuesSourceAggregationBuilder<VS extends ValuesSource, AB extends ValuesSourceAggregationBuilder<VS, AB>>
-        extends AggregationBuilder<AB> {
+        extends AbstractAggregationBuilder<AB> {
 
     public static abstract class LeafOnly<VS extends ValuesSource, AB extends ValuesSourceAggregationBuilder<VS, AB>>
             extends ValuesSourceAggregationBuilder<VS, AB> {

+ 2 - 2
core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java

@@ -44,7 +44,7 @@ import org.elasticsearch.script.Script;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorParsers;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.fetch.source.FetchSourceContext;
 import org.elasticsearch.search.highlight.HighlightBuilder;
 import org.elasticsearch.search.internal.SearchContext;
@@ -600,7 +600,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
     /**
      * Add an aggregation to perform as part of the search.
      */
-    public SearchSourceBuilder aggregation(AggregationBuilder<?> aggregation) {
+    public SearchSourceBuilder aggregation(AggregationBuilder aggregation) {
             if (aggregations == null) {
             aggregations = AggregatorFactories.builder();
             }

+ 3 - 3
core/src/test/java/org/elasticsearch/search/aggregations/BaseAggregationTestCase.java

@@ -79,7 +79,7 @@ import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
 import static org.elasticsearch.test.ClusterServiceUtils.setState;
 import static org.hamcrest.Matchers.equalTo;
 
-public abstract class BaseAggregationTestCase<AB extends AggregationBuilder<AB>> extends ESTestCase {
+public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuilder<AB>> extends ESTestCase {
 
     protected static final String STRING_FIELD_NAME = "mapped_string";
     protected static final String INT_FIELD_NAME = "mapped_int";
@@ -237,7 +237,7 @@ public abstract class BaseAggregationTestCase<AB extends AggregationBuilder<AB>>
         assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
         assertEquals(testAgg.type.name(), parser.currentName());
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
-        AggregationBuilder<?> newAgg = aggParsers.parser(testAgg.getType(), ParseFieldMatcher.STRICT).parse(testAgg.name, parseContext);
+        AggregationBuilder newAgg = aggParsers.parser(testAgg.getType(), ParseFieldMatcher.STRICT).parse(testAgg.name, parseContext);
         assertSame(XContentParser.Token.END_OBJECT, parser.currentToken());
         assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
@@ -257,7 +257,7 @@ public abstract class BaseAggregationTestCase<AB extends AggregationBuilder<AB>>
         try (BytesStreamOutput output = new BytesStreamOutput()) {
             output.writeNamedWriteable(testAgg);
             try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), namedWriteableRegistry)) {
-                AggregationBuilder<?> deserialized = in.readNamedWriteable(AggregationBuilder.class);
+                AggregationBuilder deserialized = in.readNamedWriteable(AggregationBuilder.class);
                 assertEquals(testAgg, deserialized);
                 assertEquals(testAgg.hashCode(), deserialized.hashCode());
                 assertNotSame(testAgg, deserialized);

+ 6 - 6
core/src/test/java/org/elasticsearch/search/aggregations/BasePipelineAggregationTestCase.java

@@ -59,7 +59,7 @@ import org.elasticsearch.script.ScriptModule;
 import org.elasticsearch.script.ScriptService;
 import org.elasticsearch.script.ScriptSettings;
 import org.elasticsearch.search.SearchModule;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
+import org.elasticsearch.search.aggregations.pipeline.AbstractPipelineAggregatorBuilder;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.test.IndexSettingsModule;
 import org.elasticsearch.test.InternalSettingsPlugin;
@@ -80,7 +80,7 @@ import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
 import static org.elasticsearch.test.ClusterServiceUtils.setState;
 import static org.hamcrest.Matchers.equalTo;
 
-public abstract class BasePipelineAggregationTestCase<AF extends PipelineAggregatorBuilder> extends ESTestCase {
+public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelineAggregatorBuilder<AF>> extends ESTestCase {
 
     protected static final String STRING_FIELD_NAME = "mapped_string";
     protected static final String INT_FIELD_NAME = "mapped_int";
@@ -234,13 +234,13 @@ public abstract class BasePipelineAggregationTestCase<AF extends PipelineAggrega
         logger.info("Content string: {}", contentString);
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
-        assertEquals(testAgg.name(), parser.currentName());
+        assertEquals(testAgg.getName(), parser.currentName());
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
         assertEquals(testAgg.type(), parser.currentName());
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
-        PipelineAggregatorBuilder<?> newAgg = aggParsers.pipelineParser(testAgg.getWriteableName(), ParseFieldMatcher.STRICT)
-                .parse(testAgg.name(), parseContext);
+        PipelineAggregatorBuilder newAgg = aggParsers.pipelineParser(testAgg.getWriteableName(), ParseFieldMatcher.STRICT)
+                .parse(testAgg.getName(), parseContext);
         assertSame(XContentParser.Token.END_OBJECT, parser.currentToken());
         assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
@@ -260,7 +260,7 @@ public abstract class BasePipelineAggregationTestCase<AF extends PipelineAggrega
         try (BytesStreamOutput output = new BytesStreamOutput()) {
             output.writeNamedWriteable(testAgg);
             try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), namedWriteableRegistry)) {
-                PipelineAggregatorBuilder<?> deserializedQuery = in.readNamedWriteable(PipelineAggregatorBuilder.class);
+                PipelineAggregatorBuilder deserializedQuery = in.readNamedWriteable(PipelineAggregatorBuilder.class);
                 assertEquals(deserializedQuery, testAgg);
                 assertEquals(deserializedQuery.hashCode(), testAgg.hashCode());
                 assertNotSame(deserializedQuery, testAgg);

+ 1 - 1
core/src/test/java/org/elasticsearch/search/aggregations/pipeline/bucketmetrics/AbstractBucketMetricsTestCase.java

@@ -22,7 +22,7 @@ package org.elasticsearch.search.aggregations.pipeline.bucketmetrics;
 import org.elasticsearch.search.aggregations.BasePipelineAggregationTestCase;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
 
-public abstract class AbstractBucketMetricsTestCase<PAF extends BucketMetricsPipelineAggregatorBuilder>
+public abstract class AbstractBucketMetricsTestCase<PAF extends BucketMetricsPipelineAggregatorBuilder<PAF>>
         extends BasePipelineAggregationTestCase<PAF> {
 
     @Override

+ 4 - 4
core/src/test/java/org/elasticsearch/search/aggregations/pipeline/moving/avg/MovAvgTests.java

@@ -24,8 +24,8 @@ import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.index.query.QueryParseContext;
 import org.elasticsearch.search.aggregations.BasePipelineAggregationTestCase;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.movavg.MovAvgPipelineAggregatorBuilder;
 import org.elasticsearch.search.aggregations.pipeline.movavg.models.EwmaModel;
 import org.elasticsearch.search.aggregations.pipeline.movavg.models.HoltLinearModel;
@@ -110,13 +110,13 @@ public class MovAvgTests extends BasePipelineAggregationTestCase<MovAvgPipelineA
         QueryParseContext parseContext = new QueryParseContext(queriesRegistry, parser, parseFieldMatcher);
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
-        assertEquals(expected.name(), parser.currentName());
+        assertEquals(expected.getName(), parser.currentName());
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
         assertEquals(expected.type(), parser.currentName());
         assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
-        PipelineAggregatorBuilder<?> newAgg = aggParsers.pipelineParser(expected.getWriteableName(), ParseFieldMatcher.STRICT)
-                .parse(expected.name(), parseContext);
+        PipelineAggregatorBuilder newAgg = aggParsers.pipelineParser(expected.getWriteableName(), ParseFieldMatcher.STRICT)
+                .parse(expected.getName(), parseContext);
         assertSame(XContentParser.Token.END_OBJECT, parser.currentToken());
         assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
         assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());

+ 2 - 2
modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateRequestBuilder.java

@@ -28,7 +28,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.highlight.HighlightBuilder;
 import org.elasticsearch.search.sort.SortBuilder;
 
@@ -170,7 +170,7 @@ public class PercolateRequestBuilder extends ActionRequestBuilder<PercolateReque
      * Delegates to
      * {@link PercolateSourceBuilder#addAggregation(AggregationBuilder)}
      */
-    public PercolateRequestBuilder addAggregation(AggregationBuilder<?> aggregationBuilder) {
+    public PercolateRequestBuilder addAggregation(AggregationBuilder aggregationBuilder) {
         sourceBuilder().addAggregation(aggregationBuilder);
         return this;
     }

+ 7 - 7
modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateSourceBuilder.java

@@ -30,7 +30,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
-import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilder;
+import org.elasticsearch.search.aggregations.PipelineAggregatorBuilder;
 import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.elasticsearch.search.highlight.HighlightBuilder;
 import org.elasticsearch.search.sort.ScoreSortBuilder;
@@ -56,8 +56,8 @@ public class PercolateSourceBuilder extends ToXContentToBytes {
     private List<SortBuilder<?>> sorts;
     private Boolean trackScores;
     private HighlightBuilder highlightBuilder;
-    private List<AggregationBuilder<?>> aggregationBuilders;
-    private List<PipelineAggregatorBuilder<?>> pipelineAggregationBuilders;
+    private List<AggregationBuilder> aggregationBuilders;
+    private List<PipelineAggregatorBuilder> pipelineAggregationBuilders;
 
     /**
      * Sets the document to run the percolate queries against.
@@ -129,7 +129,7 @@ public class PercolateSourceBuilder extends ToXContentToBytes {
     /**
      * Add an aggregation definition.
      */
-    public PercolateSourceBuilder addAggregation(AggregationBuilder<?> aggregationBuilder) {
+    public PercolateSourceBuilder addAggregation(AggregationBuilder aggregationBuilder) {
         if (aggregationBuilders == null) {
             aggregationBuilders = new ArrayList<>();
         }
@@ -140,7 +140,7 @@ public class PercolateSourceBuilder extends ToXContentToBytes {
     /**
      * Add an aggregation definition.
      */
-    public PercolateSourceBuilder addAggregation(PipelineAggregatorBuilder<?> aggregationBuilder) {
+    public PercolateSourceBuilder addAggregation(PipelineAggregatorBuilder aggregationBuilder) {
         if (pipelineAggregationBuilders == null) {
             pipelineAggregationBuilders = new ArrayList<>();
         }
@@ -178,12 +178,12 @@ public class PercolateSourceBuilder extends ToXContentToBytes {
             builder.field("aggregations");
             builder.startObject();
             if (aggregationBuilders != null) {
-                for (AggregationBuilder<?> aggregation : aggregationBuilders) {
+                for (AggregationBuilder aggregation : aggregationBuilders) {
                     aggregation.toXContent(builder, params);
                 }
             }
             if (pipelineAggregationBuilders != null) {
-                for (PipelineAggregatorBuilder<?> aggregation : pipelineAggregationBuilders) {
+                for (PipelineAggregatorBuilder aggregation : pipelineAggregationBuilders) {
                     aggregation.toXContent(builder, params);
                 }
             }