/* Copyright 2013 Endgame, Inc. * * Licensed 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.facet.termlist; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.HashedBytesArray; import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilderString; import org.elasticsearch.search.facet.Facet; import org.elasticsearch.search.facet.InternalFacet; import org.elasticsearch.search.facet.terms.TermsFacet.ComparatorType; import org.elasticsearch.search.facet.terms.TermsFacet.Entry; import org.elasticsearch.search.facet.terms.strings.InternalStringTermsFacet.TermEntry; /** * InternalTermListFacet * Only handle Strings * */ public class InternalTermListFacet extends InternalFacet implements TermListFacet { private final String type = "term_list"; private static final BytesReference STREAM_TYPE = new HashedBytesArray(TermListFacet.TYPE.getBytes()); private Object[] strings; private boolean sort; /** * Instantiates a new internal string term list facet. * * @param facetName the facet name * @param strings the strings */ public InternalTermListFacet(final String facetName, final Object[] strings, boolean sort) { super(facetName); this.strings = strings; this.sort = sort; } /** * Instantiates a new internal term list facet. */ private InternalTermListFacet() { } /** * Register streams. */ public static void registerStream() { Streams.registerStream(STREAM, STREAM_TYPE); } /** The stream. */ static Stream STREAM = new Stream() { @Override public Facet readFacet(StreamInput in) throws IOException { return readTermListFacet(in); } }; /** * Read term list facet. * * @param in * the input stream * @return the internal term list facet * @throws IOException * Signals that an I/O exception has occurred. */ public static InternalTermListFacet readTermListFacet(final StreamInput in) throws IOException { final InternalTermListFacet facet = new InternalTermListFacet(); facet.readFrom(in); return facet; } @Override public void writeTo(final StreamOutput out) throws IOException { int size = strings.length; super.writeTo(out); out.writeVInt(size); for (int i = 0; i < size; i++) { out.writeString((String) strings[i]); } } @Override public void readFrom(final StreamInput in) throws IOException { super.readFrom(in); final int size = in.readVInt(); strings = new Object[size]; for (int i = 0; i < size; i++) { strings[i] = in.readString(); } } /** * Output JSON fields */ static final class Fields { /** The Constant _TYPE. */ static final XContentBuilderString _TYPE = new XContentBuilderString("_type"); /** The Constant ENTRIES. */ static final XContentBuilderString ENTRIES = new XContentBuilderString("entries"); } @Override public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException { builder.startObject(this.getName()); builder.field(Fields._TYPE, TermListFacet.TYPE); builder.array(Fields.ENTRIES, strings); builder.endObject(); return builder; } @Override public String getType() { return type; } @Override public BytesReference streamType() { return STREAM_TYPE; } @Override public Facet reduce(ReduceContext context) { return myReduce(this.getName(), context.facets()); } /** * Takes a list of facets and returns a new facet containing the merged data from all of them. * * @param name the facet name * @param facets the facets * @return the resulting reduced facet */ public Facet myReduce(final String name, final List<Facet> facets) { final Set<String> reducedStrings = new HashSet<String>(); for(final Facet facet : facets) { final InternalTermListFacet itlf = (InternalTermListFacet) facet; for(final Object obj : itlf.strings) { reducedStrings.add(obj.toString()); } } String[] strArr = reducedStrings.toArray( new String[ reducedStrings.size() ] ); if(sort) Arrays.sort( strArr ); return new InternalTermListFacet(name, strArr, sort ); } @Override public Iterator<Object> iterator() { return entries().iterator(); } @Override public List<Object> entries() { return Arrays.asList(strings); } @Override public List<? extends Object> getEntries() { return entries(); } }