http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java new file mode 100644 index 0000000..9c542d7 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + +import org.apache.solr.common.util.NamedList; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A response that is returned by processing the {@link org.apache.solr.client.solrj.request.FieldAnalysisRequest}. + * Holds a map of {@link Analysis} objects per field name as well as a map of {@link Analysis} objects per field type. + * + * + * @since solr 1.4 + */ +public class FieldAnalysisResponse extends AnalysisResponseBase { + + private Map<String, Analysis> analysisByFieldTypeName = new HashMap<>(); + private Map<String, Analysis> analysisByFieldName = new HashMap<>(); + + /** + * {@inheritDoc} + */ + @Override + public void setResponse(NamedList<Object> response) { + super.setResponse(response); + + @SuppressWarnings("unchecked") + NamedList<NamedList<NamedList<NamedList<List<NamedList<Object>>>>>> analysisNL + = (NamedList<NamedList<NamedList<NamedList<List<NamedList<Object>>>>>>) response.get("analysis"); + + for (Map.Entry<String, NamedList<NamedList<List<NamedList<Object>>>>> entry + : analysisNL.get("field_types")) { + + analysisByFieldTypeName.put(entry.getKey(), buildAnalysis(entry.getValue())); + } + + for (Map.Entry<String, NamedList<NamedList<List<NamedList<Object>>>>> entry + : analysisNL.get("field_names")) { + + analysisByFieldName.put(entry.getKey(), buildAnalysis(entry.getValue())); + } + } + + private Analysis buildAnalysis(NamedList<NamedList<List<NamedList<Object>>>> value) { + Analysis analysis = new Analysis(); + + NamedList<List<NamedList<Object>>> queryNL = value.get("query"); + List<AnalysisPhase> phases = (queryNL == null) ? null : buildPhases(queryNL); + analysis.setQueryPhases(phases); + + NamedList<List<NamedList<Object>>> indexNL = value.get("index"); + phases = buildPhases(indexNL); + analysis.setIndexPhases(phases); + + return analysis; + } + + /** + * Returns the number of field type analyses. + * + * @return The number of field type analyses. + */ + public int getFieldTypeAnalysisCount() { + return analysisByFieldTypeName.size(); + } + + /** + * Returns the analysis for the given field type or {@code null} if no such analysis exists. + * + * @param fieldTypeName The name of the field type. + * + * @return The analysis for the given field type. + */ + public Analysis getFieldTypeAnalysis(String fieldTypeName) { + return analysisByFieldTypeName.get(fieldTypeName); + } + + /** + * Returns all field type analyses with their associated field types. + * + * @return All field type analyses with their associated field types. + */ + public Iterable<Map.Entry<String, Analysis>> getAllFieldTypeAnalysis() { + return analysisByFieldTypeName.entrySet(); + } + + /** + * Returns the number of field name analyses. + * + * @return The number of field name analyses. + */ + public int getFieldNameAnalysisCount() { + return analysisByFieldName.size(); + } + + /** + * Returns the analysis for the given field name or {@code null} if no such analysis exists. + * + * @param fieldName The field name. + * + * @return The analysis for the given field name. + */ + public Analysis getFieldNameAnalysis(String fieldName) { + return analysisByFieldName.get(fieldName); + } + + /** + * Returns all field name analysese with their associated field names. + * + * @return all field name analysese with their associated field names. + */ + public Iterable<Map.Entry<String, Analysis>> getAllFieldNameAnalysis() { + return analysisByFieldName.entrySet(); + } + + + //================================================= Inner Classes ================================================== + + /** + * The analysis of a field. Holds a list of all the query time analysis phases (if a query analysis was requested) + * as well as index time phases. + */ + public static class Analysis { + + private List<AnalysisPhase> queryPhases; + private List<AnalysisPhase> indexPhases; + + /** + * This class should only be instantiated internally. + */ + private Analysis() { + } + + /** + * Returns the number of query time analysis phases in this analysis or + * {@code -1} if query time analysis doesn't exist. + * + * @return Returns the number of query time analysis phases in this + * analysis or {@code -1} if query time analysis doesn't exist. + */ + public int getQueryPhasesCount() { + return queryPhases == null ? -1 : queryPhases.size(); + } + + /** + * Returns the query time analysis phases for this analysis or {@code null} + * if query time analysis doesn't exist. + * + * + * @return The query time analysis phases for this analysis or {@code null} + * if query time analysis doesn't exist. + * + */ + public Iterable<AnalysisPhase> getQueryPhases() { + return queryPhases; + } + + /** + * Returns the index time analysis phases for this analysis. + * + * @return The index time analysis phases for this analysis. + */ + public int getIndexPhasesCount() { + return indexPhases.size(); + } + + /** + * Returns the index time analysis phases for this analysis. + * + * @return The index time analysis phases for this analysis. + */ + public Iterable<AnalysisPhase> getIndexPhases() { + return indexPhases; + } + + private void setQueryPhases(List<AnalysisPhase> queryPhases) { + this.queryPhases = queryPhases; + } + + private void setIndexPhases(List<AnalysisPhase> indexPhases) { + this.indexPhases = indexPhases; + } + + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java new file mode 100644 index 0000000..9685832 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.solr.client.solrj.response; + +import org.apache.solr.common.util.NamedList; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Holds stats info + * + * + * @since solr 1.4 + */ +public class FieldStatsInfo implements Serializable { + final String name; + + Object min; + Object max; + Object sum; + Long count; + Long countDistinct; + Collection<Object> distinctValues; + Long missing; + Object mean = null; + Double sumOfSquares = null; + Double stddev = null; + + Map<String,List<FieldStatsInfo>> facets; + + public FieldStatsInfo( NamedList<Object> nl, String fname ) + { + name = fname; + + for( Map.Entry<String, Object> entry : nl ) { + if( "min".equals( entry.getKey() ) ) { + min = entry.getValue(); + } + else if( "max".equals( entry.getKey() ) ) { + max = entry.getValue(); + } + else if( "sum".equals( entry.getKey() ) ) { + sum = entry.getValue(); + } + else if( "count".equals( entry.getKey() ) ) { + count = (Long)entry.getValue(); + } + else if ("countDistinct".equals(entry.getKey())) { + countDistinct = (Long) entry.getValue(); + } + else if ("distinctValues".equals(entry.getKey())) { + distinctValues = (Collection<Object>) entry.getValue(); + } + else if( "missing".equals( entry.getKey() ) ) { + missing = (Long)entry.getValue(); + } + else if( "mean".equals( entry.getKey() ) ) { + mean = entry.getValue(); + } + else if( "sumOfSquares".equals( entry.getKey() ) ) { + sumOfSquares = (Double)entry.getValue(); + } + else if( "stddev".equals( entry.getKey() ) ) { + stddev = (Double)entry.getValue(); + } + else if( "facets".equals( entry.getKey() ) ) { + @SuppressWarnings("unchecked") + NamedList<Object> fields = (NamedList<Object>)entry.getValue(); + facets = new HashMap<>(); + for( Map.Entry<String, Object> ev : fields ) { + List<FieldStatsInfo> vals = new ArrayList<>(); + facets.put( ev.getKey(), vals ); + @SuppressWarnings("unchecked") + NamedList<NamedList<Object>> vnl = (NamedList<NamedList<Object>>) ev.getValue(); + for( int i=0; i<vnl.size(); i++ ) { + String n = vnl.getName(i); + vals.add( new FieldStatsInfo( vnl.getVal(i), n ) ); + } + } + } + else { + throw new RuntimeException( "unknown key: "+entry.getKey() + " ["+entry.getValue()+"]" ); + } + } + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append( name ); + sb.append( ": {" ); + if( min != null ) { + sb.append( " min:").append( min ); + } + if( max != null ) { + sb.append( " max:").append( max ); + } + if( sum != null ) { + sb.append( " sum:").append( sum ); + } + if( count != null ) { + sb.append( " count:").append( count ); + } + if (countDistinct != null) { + sb.append(" countDistinct:").append(countDistinct); + } + if (distinctValues != null) { + sb.append(" distinctValues:").append(distinctValues); + } + if( missing != null ) { + sb.append( " missing:").append( missing ); + } + if( mean != null ) { + sb.append( " mean:").append( mean ); + } + if( stddev != null ) { + sb.append( " stddev:").append(stddev); + } + sb.append( " }" ); + return sb.toString(); + } + + public String getName() { + return name; + } + + public Object getMin() { + return min; + } + + public Object getMax() { + return max; + } + + public Object getSum() { + return sum; + } + + public Long getCount() { + return count; + } + + public Long getCountDistinct() { + return countDistinct; + } + + public Collection<Object> getDistinctValues() { + return distinctValues; + } + + public Long getMissing() { + return missing; + } + + public Object getMean() { + return mean; + } + + public Double getStddev() { + return stddev; + } + + public Double getSumOfSquares() { + return sumOfSquares; + } + + public Map<String, List<FieldStatsInfo>> getFacets() { + return facets; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java new file mode 100644 index 0000000..2ee0389 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java @@ -0,0 +1,69 @@ +package org.apache.solr.client.solrj.response; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.common.SolrDocumentList; + +import java.io.Serializable; + +/** + * Represents a group. A group contains a common group value that all documents inside the group share and + * documents that belong to this group. + * + * A group value can be a field value, function result or a query string depending on the {@link GroupCommand}. + * In case of a field value or a function result the value is always a indexed value. + * + * @since solr 3.4 + */ +public class Group implements Serializable { + + private final String _groupValue; + private final SolrDocumentList _result; + + /** + * Creates a Group instance. + * + * @param groupValue The common group value (indexed value) that all documents share. + * @param result The documents to be displayed that belong to this group + */ + public Group(String groupValue, SolrDocumentList result) { + _groupValue = groupValue; + _result = result; + } + + /** + * Returns the common group value that all documents share inside this group. + * This is an indexed value, not a stored value. + * + * @return the common group value + */ + public String getGroupValue() { + return _groupValue; + } + + /** + * Returns the documents to be displayed that belong to this group. + * How many documents are returned depend on the <code>group.offset</code> and <code>group.limit</code> parameters. + * + * @return the documents to be displayed that belong to this group + */ + public SolrDocumentList getResult() { + return _result; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java new file mode 100644 index 0000000..c2c8127 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java @@ -0,0 +1,125 @@ +package org.apache.solr.client.solrj.response; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * This class represents the result of a group command. + * This can be the result of the following parameter: + * <ul> + * <li> group.field + * <li> group.func + * <li> group.query + * </ul> + * + * An instance of this class contains: + * <ul> + * <li> The name of this command. This can be the field, function or query grouped by. + * <li> The total number of documents that have matched. + * <li> The total number of groups that have matched. + * <li> The groups to be displayed. Depending on the start and rows parameter. + * </ul> + * + * In case of <code>group.query</code> only one group is present and ngroups is always <code>null</code>. + * + * @since solr 3.4 + */ +public class GroupCommand implements Serializable { + + private final String _name; + private final List<Group> _values = new ArrayList<>(); + private final int _matches; + private final Integer _ngroups; + + /** + * Creates a GroupCommand instance + * + * @param name The name of this command + * @param matches The total number of documents found for this command + */ + public GroupCommand(String name, int matches) { + _name = name; + _matches = matches; + _ngroups = null; + } + + /** + * Creates a GroupCommand instance. + * + * @param name The name of this command + * @param matches The total number of documents found for this command + * @param nGroups The total number of groups found for this command. + */ + public GroupCommand(String name, int matches, int nGroups) { + _name = name; + _matches = matches; + _ngroups = nGroups; + } + + /** + * Returns the name of this command. This can be the field, function or query grouped by. + * + * @return the name of this command + */ + public String getName() { + return _name; + } + + /** + * Adds a group to this command. + * + * @param group A group to be added + */ + public void add(Group group) { + _values.add(group); + } + + /** + * Returns the groups to be displayed. + * The number of groups returned depend on the <code>start</code> and <code>rows</code> parameters. + * + * @return the groups to be displayed. + */ + public List<Group> getValues() { + return _values; + } + + /** + * Returns the total number of documents found for this command. + * + * @return the total number of documents found for this command. + */ + public int getMatches() { + return _matches; + } + + /** + * Returns the total number of groups found for this command. + * Returns <code>null</code> if the <code>group.ngroups</code> parameter is unset or <code>false</code> or + * if this is a group command query (parameter = <code>group.query</code>). + * + * @return the total number of groups found for this command. + */ + public Integer getNGroups() { + return _ngroups; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java new file mode 100644 index 0000000..210bb5e --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java @@ -0,0 +1,56 @@ +package org.apache.solr.client.solrj.response; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Overall grouping result. Contains a list of {@link GroupCommand} instances that is the result of + * one the following parameters: + * <ul> + * <li>group.field + * <li>group.func + * <li>group.query + * </ul> + * + * @since solr 3.4 + */ +public class GroupResponse implements Serializable { + + private final List<GroupCommand> _values = new ArrayList<>(); + + /** + * Adds a grouping command to the response. + * + * @param command The grouping command to add + */ + public void add(GroupCommand command) { + _values.add(command); + } + + /** + * Returns all grouping commands. + * + * @return all grouping commands + */ + public List<GroupCommand> getValues() { + return _values; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java new file mode 100644 index 0000000..1f91fe8 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java @@ -0,0 +1,85 @@ +package org.apache.solr.client.solrj.response; + +import java.util.List; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Objects of this class will contain the result of all the intervals defined + * for a specific field. + */ +public class IntervalFacet { + + /** + * The field for which interval facets where calculated + */ + private final String field; + + /** + * The list of interval facets calculated for {@link #field} + */ + private final List<Count> intervals; + + IntervalFacet(String field, List<Count> values) { + this.field = field; + this.intervals = values; + } + + /** + * @return The field for which interval facets where calculated + */ + public String getField() { + return field; + } + + /** + * @return The list of interval facets calculated for {@link #field} + */ + public List<Count> getIntervals() { + return intervals; + } + + /** + * Holds counts for facet intervals defined in a field + */ + public static class Count { + /** + * The key of this interval. This is the original + * interval string or the value of the "key" local + * param + */ + private final String key; + /** + * The count of this interval + */ + private final int count; + + Count(String key, int count) { + super(); + this.key = key; + this.count = count; + } + + public String getKey() { + return key; + } + + public int getCount() { + return count; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java new file mode 100644 index 0000000..5d2f328 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + +import org.apache.solr.common.luke.FieldFlag; +import org.apache.solr.common.util.NamedList; + +import java.io.Serializable; +import java.util.*; + + +/** + * This is an incomplete representation of the data returned from Luke + * + * + * @since solr 1.3 + */ +public class LukeResponse extends SolrResponseBase { + + public static class FieldTypeInfo implements Serializable { + String name; + String className; + boolean tokenized; + String analyzer; + List<String> fields; + + + public FieldTypeInfo(String name) { + this.name = name; + fields = Collections.emptyList(); + } + + + public String getAnalyzer() { + return analyzer; + } + + public String getClassName() { + return className; + } + + public List<String> getFields() { + return fields; + } + + public String getName() { + return name; + } + + public boolean isTokenized() { + return tokenized; + }/* + Sample: + types={ignored={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@f94934}, + integer={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@3525a2}, + sfloat={fields=[price, weight],tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@39cf9c}, + text_ws={fields=[cat],tokenized=true,analyzer=TokenizerChain(org.apache.solr.analysis.WhitespaceTokenizerFactory@6d3ca2)}, + alphaOnlySort={fields=[alphaNameSort],tokenized=true,analyzer=TokenizerChain(org.apache.solr.analysis.KeywordTokenizerFactory@a7bd3b, + org.apache.solr.analysis.LowerCaseFilterFactory@78aae2, org.apache.solr.analysis.TrimFilterFactory@1b16a7, + org.apache.solr.analysis.PatternReplaceFilterFactory@6c6b08)},date={fields=[timestamp],tokenized=false, + analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@e6e42e},sint={fields=[popularity], + tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@8ea21d}, + boolean={fields=[inStock],tokenized=false,analyzer=org.apache.solr.schema.BoolField$1@354949}, + textTight={fields=[sku],tokenized=true,analyzer=TokenizerChain(org.apache.solr.analysis.WhitespaceTokenizerFactory@5e88f7, + org.apache.solr.analysis.SynonymFilterFactory@723646, org.apache.solr.analysis.StopFilterFactory@492ff1, + org.apache.solr.analysis.WordDelimiterFilterFactory@eaabad, org.apache.solr.analysis.LowerCaseFilterFactory@ad1355, + org.apache.solr.analysis.EnglishPorterFilterFactory@d03a00, org.apache.solr.analysis.RemoveDuplicatesTokenFilterFactory@900079)}, + long={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@f3b83}, + double={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@c2b07}, + + */ + + @SuppressWarnings("unchecked") + public void read(NamedList<Object> nl) { + for (Map.Entry<String, Object> entry : nl) { + String key = entry.getKey(); + if ("fields".equals(key) && entry.getValue() != null) { + List<String> theFields = (List<String>) entry.getValue(); + fields = new ArrayList<>(theFields); + } else if ("tokenized".equals(key) == true) { + tokenized = Boolean.parseBoolean(entry.getValue().toString()); + } else if ("analyzer".equals(key) == true) { + analyzer = entry.getValue().toString(); + } else if ("className".equals(key) == true) { + className = entry.getValue().toString(); + } + } + } + } + + public static class FieldInfo implements Serializable { + String name; + String type; + String schema; + int docs; + int distinct; + EnumSet<FieldFlag> flags; + boolean cacheableFaceting; + NamedList<Integer> topTerms; + + public FieldInfo(String n) { + name = n; + } + + @SuppressWarnings("unchecked") + public void read(NamedList<Object> nl) { + for (Map.Entry<String, Object> entry : nl) { + if ("type".equals(entry.getKey())) { + type = (String) entry.getValue(); + } + if ("flags".equals(entry.getKey())) { + flags = parseFlags((String) entry.getValue()); + } else if ("schema".equals(entry.getKey())) { + schema = (String) entry.getValue(); + } else if ("docs".equals(entry.getKey())) { + docs = (Integer) entry.getValue(); + } else if ("distinct".equals(entry.getKey())) { + distinct = (Integer) entry.getValue(); + } else if ("cacheableFaceting".equals(entry.getKey())) { + cacheableFaceting = (Boolean) entry.getValue(); + } else if ("topTerms".equals(entry.getKey())) { + topTerms = (NamedList<Integer>) entry.getValue(); + } + } + } + + public static EnumSet<FieldFlag> parseFlags(String flagStr) { + EnumSet<FieldFlag> result = EnumSet.noneOf(FieldFlag.class); + char[] chars = flagStr.toCharArray(); + for (int i = 0; i < chars.length; i++) { + if (chars[i] != '-') { + FieldFlag flag = FieldFlag.getFlag(chars[i]); + result.add(flag); + } + } + return result; + } + + public EnumSet<FieldFlag> getFlags() { + return flags; + } + + public boolean isCacheableFaceting() { + return cacheableFaceting; + } + + public String getType() { + return type; + } + + public int getDistinct() { + return distinct; + } + + public int getDocs() { + return docs; + } + + public String getName() { + return name; + } + + public String getSchema() { + return schema; + } + + public NamedList<Integer> getTopTerms() { + return topTerms; + } + } + + private NamedList<Object> indexInfo; + private Map<String, FieldInfo> fieldInfo; + private Map<String, FieldTypeInfo> fieldTypeInfo; + + @Override + @SuppressWarnings("unchecked") + public void setResponse(NamedList<Object> res) { + super.setResponse(res); + + // Parse indexinfo + indexInfo = (NamedList<Object>) res.get("index"); + + NamedList<Object> schema = (NamedList<Object>) res.get("schema"); + NamedList<Object> flds = (NamedList<Object>) res.get("fields"); + if (flds == null && schema != null ) { + flds = (NamedList<Object>) schema.get("fields"); + } + if (flds != null) { + fieldInfo = new HashMap<>(); + for (Map.Entry<String, Object> field : flds) { + FieldInfo f = new FieldInfo(field.getKey()); + f.read((NamedList<Object>) field.getValue()); + fieldInfo.put(field.getKey(), f); + } + } + + if( schema != null ) { + NamedList<Object> fldTypes = (NamedList<Object>) schema.get("types"); + if (fldTypes != null) { + fieldTypeInfo = new HashMap<>(); + for (Map.Entry<String, Object> fieldType : fldTypes) { + FieldTypeInfo ft = new FieldTypeInfo(fieldType.getKey()); + ft.read((NamedList<Object>) fieldType.getValue()); + fieldTypeInfo.put(fieldType.getKey(), ft); + } + } + } + } + + //---------------------------------------------------------------- + //---------------------------------------------------------------- + + public String getIndexDirectory() { + if (indexInfo == null) return null; + return (String) indexInfo.get("directory"); + } + + public Integer getNumDocs() { + if (indexInfo == null) return null; + return (Integer) indexInfo.get("numDocs"); + } + + public Integer getMaxDoc() { + if (indexInfo == null) return null; + return (Integer) indexInfo.get("maxDoc"); + } + + public Integer getNumTerms() { + if (indexInfo == null) return null; + return (Integer) indexInfo.get("numTerms"); + } + + public Map<String, FieldTypeInfo> getFieldTypeInfo() { + return fieldTypeInfo; + } + + public FieldTypeInfo getFieldTypeInfo(String name) { + return fieldTypeInfo.get(name); + } + + public NamedList<Object> getIndexInfo() { + return indexInfo; + } + + public Map<String, FieldInfo> getFieldInfo() { + return fieldInfo; + } + + public FieldInfo getFieldInfo(String f) { + return fieldInfo.get(f); + } + + //---------------------------------------------------------------- +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java new file mode 100644 index 0000000..3b084f6 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + +import java.io.PrintStream; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +public class PivotField implements Serializable +{ + final String _field; + final Object _value; + final int _count; + final List<PivotField> _pivot; + final Map<String,FieldStatsInfo> _statsInfo; + + /** + * @deprecated Use {@link #PivotField(String,Object,int,List,Map)} with a null <code>statsInfo</code> + */ + @Deprecated + public PivotField( String f, Object v, int count, List<PivotField> pivot) { + this(f, v, count, pivot, null); + } + + public PivotField( String f, Object v, int count, List<PivotField> pivot, Map<String,FieldStatsInfo> statsInfo) + { + _field = f; + _value = v; + _count = count; + _pivot = pivot; + _statsInfo = statsInfo; + } + + public String getField() { + return _field; + } + + public Object getValue() { + return _value; + } + + public int getCount() { + return _count; + } + + public List<PivotField> getPivot() { + return _pivot; + } + + public Map<String,FieldStatsInfo> getFieldStatsInfo() { + return _statsInfo; + } + + @Override + public String toString() + { + return _field + ":" + _value + " ["+_count+"] "+_pivot; + } + + public void write( PrintStream out, int indent ) + { + for( int i=0; i<indent; i++ ) { + out.print( " " ); + } + out.print( _field + "=" + _value + " ("+_count+")" ); + if (null != _statsInfo) { + out.print( "->stats:[" ); + for( FieldStatsInfo fieldStatsInfo : _statsInfo.values() ) { + out.print(fieldStatsInfo.toString()); + out.print(","); + } + out.print("]"); + } + out.println(); + if( _pivot != null ) { + for( PivotField p : _pivot ) { + p.write( out, indent+1 ); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java new file mode 100644 index 0000000..89cd971 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java @@ -0,0 +1,586 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.beans.DocumentObjectBinder; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.params.CursorMarkParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * + * + * @since solr 1.3 + */ +@SuppressWarnings("unchecked") +public class QueryResponse extends SolrResponseBase +{ + // Direct pointers to known types + private NamedList<Object> _header = null; + private SolrDocumentList _results = null; + private NamedList<ArrayList> _sortvalues = null; + private NamedList<Object> _facetInfo = null; + private NamedList<Object> _debugInfo = null; + private NamedList<Object> _highlightingInfo = null; + private NamedList<Object> _spellInfo = null; + private NamedList<Object> _statsInfo = null; + private NamedList<NamedList<Number>> _termsInfo = null; + private String _cursorMarkNext = null; + + // Grouping response + private NamedList<Object> _groupedInfo = null; + private GroupResponse _groupResponse = null; + + private NamedList<Object> _expandedInfo = null; + private Map<String, SolrDocumentList> _expandedResults = null; + + // Facet stuff + private Map<String,Integer> _facetQuery = null; + private List<FacetField> _facetFields = null; + private List<FacetField> _limitingFacets = null; + private List<FacetField> _facetDates = null; + private List<RangeFacet> _facetRanges = null; + private NamedList<List<PivotField>> _facetPivot = null; + private List<IntervalFacet> _intervalFacets = null; + + // Highlight Info + private Map<String,Map<String,List<String>>> _highlighting = null; + + // SpellCheck Response + private SpellCheckResponse _spellResponse = null; + + // Terms Response + private TermsResponse _termsResponse = null; + + // Field stats Response + private Map<String,FieldStatsInfo> _fieldStatsInfo = null; + + // Debug Info + private Map<String,Object> _debugMap = null; + private Map<String,String> _explainMap = null; + + // utility variable used for automatic binding -- it should not be serialized + private transient final SolrClient solrClient; + + public QueryResponse(){ + solrClient = null; + } + + /** + * Utility constructor to set the solrServer and namedList + */ + public QueryResponse( NamedList<Object> res , SolrClient solrClient){ + this.setResponse( res ); + this.solrClient = solrClient; + } + + public QueryResponse(SolrClient solrClient) { + this.solrClient = solrClient; + } + + @Override + public void setResponse( NamedList<Object> res ) + { + super.setResponse( res ); + + // Look for known things + for( int i=0; i<res.size(); i++ ) { + String n = res.getName( i ); + if( "responseHeader".equals( n ) ) { + _header = (NamedList<Object>) res.getVal( i ); + } + else if( "response".equals( n ) ) { + _results = (SolrDocumentList) res.getVal( i ); + } + else if( "sort_values".equals( n ) ) { + _sortvalues = (NamedList<ArrayList>) res.getVal( i ); + } + else if( "facet_counts".equals( n ) ) { + _facetInfo = (NamedList<Object>) res.getVal( i ); + // extractFacetInfo inspects _results, so defer calling it + // in case it hasn't been populated yet. + } + else if( "debug".equals( n ) ) { + _debugInfo = (NamedList<Object>) res.getVal( i ); + extractDebugInfo( _debugInfo ); + } + else if( "grouped".equals( n ) ) { + _groupedInfo = (NamedList<Object>) res.getVal( i ); + extractGroupedInfo( _groupedInfo ); + } + else if("expanded".equals(n)) { + _expandedResults = (Map<String, SolrDocumentList>) res.getVal( i ); + } + else if( "highlighting".equals( n ) ) { + _highlightingInfo = (NamedList<Object>) res.getVal( i ); + extractHighlightingInfo( _highlightingInfo ); + } + else if ( "spellcheck".equals( n ) ) { + _spellInfo = (NamedList<Object>) res.getVal( i ); + extractSpellCheckInfo( _spellInfo ); + } + else if ( "stats".equals( n ) ) { + _statsInfo = (NamedList<Object>) res.getVal( i ); + extractStatsInfo( _statsInfo ); + } + else if ( "terms".equals( n ) ) { + _termsInfo = (NamedList<NamedList<Number>>) res.getVal( i ); + extractTermsInfo( _termsInfo ); + } + else if ( CursorMarkParams.CURSOR_MARK_NEXT.equals( n ) ) { + _cursorMarkNext = (String) res.getVal( i ); + } + } + if(_facetInfo != null) extractFacetInfo( _facetInfo ); + } + + private void extractSpellCheckInfo(NamedList<Object> spellInfo) { + _spellResponse = new SpellCheckResponse(spellInfo); + } + + private void extractTermsInfo(NamedList<NamedList<Number>> termsInfo) { + _termsResponse = new TermsResponse(termsInfo); + } + + private void extractStatsInfo(NamedList<Object> info) { + _fieldStatsInfo = extractFieldStatsInfo(info); + } + + private Map<String, FieldStatsInfo> extractFieldStatsInfo(NamedList<Object> info) { + if( info != null ) { + Map<String, FieldStatsInfo> fieldStatsInfoMap = new TreeMap<>(); + NamedList<NamedList<Object>> ff = (NamedList<NamedList<Object>>) info.get( "stats_fields" ); + if( ff != null ) { + for( Map.Entry<String,NamedList<Object>> entry : ff ) { + NamedList<Object> v = entry.getValue(); + if( v != null ) { + fieldStatsInfoMap.put( entry.getKey(), + new FieldStatsInfo( v, entry.getKey() ) ); + } + } + } + return fieldStatsInfoMap; + } + return null; + } + + private void extractDebugInfo( NamedList<Object> debug ) + { + _debugMap = new LinkedHashMap<>(); // keep the order + for( Map.Entry<String, Object> info : debug ) { + _debugMap.put( info.getKey(), info.getValue() ); + } + + // Parse out interesting bits from the debug info + _explainMap = new HashMap<>(); + NamedList<String> explain = (NamedList<String>)_debugMap.get( "explain" ); + if( explain != null ) { + for( Map.Entry<String, String> info : explain ) { + String key = info.getKey(); + _explainMap.put( key, info.getValue() ); + } + } + } + + private void extractGroupedInfo( NamedList<Object> info ) { + if ( info != null ) { + _groupResponse = new GroupResponse(); + int size = info.size(); + for (int i=0; i < size; i++) { + String fieldName = info.getName(i); + Object fieldGroups = info.getVal(i); + SimpleOrderedMap<Object> simpleOrderedMap = (SimpleOrderedMap<Object>) fieldGroups; + + Object oMatches = simpleOrderedMap.get("matches"); + Object oNGroups = simpleOrderedMap.get("ngroups"); + Object oGroups = simpleOrderedMap.get("groups"); + Object queryCommand = simpleOrderedMap.get("doclist"); + if (oMatches == null) { + continue; + } + + if (oGroups != null) { + Integer iMatches = (Integer) oMatches; + ArrayList<Object> groupsArr = (ArrayList<Object>) oGroups; + GroupCommand groupedCommand; + if (oNGroups != null) { + Integer iNGroups = (Integer) oNGroups; + groupedCommand = new GroupCommand(fieldName, iMatches, iNGroups); + } else { + groupedCommand = new GroupCommand(fieldName, iMatches); + } + + for (Object oGrp : groupsArr) { + SimpleOrderedMap grpMap = (SimpleOrderedMap) oGrp; + Object sGroupValue = grpMap.get( "groupValue"); + SolrDocumentList doclist = (SolrDocumentList) grpMap.get( "doclist"); + Group group = new Group(sGroupValue != null ? sGroupValue.toString() : null, doclist) ; + groupedCommand.add(group); + } + + _groupResponse.add(groupedCommand); + } else if (queryCommand != null) { + Integer iMatches = (Integer) oMatches; + GroupCommand groupCommand; + if (oNGroups != null) { + Integer iNGroups = (Integer) oNGroups; + groupCommand = new GroupCommand(fieldName, iMatches, iNGroups); + } else { + groupCommand = new GroupCommand(fieldName, iMatches); + } + SolrDocumentList docList = (SolrDocumentList) queryCommand; + groupCommand.add(new Group(fieldName, docList)); + _groupResponse.add(groupCommand); + } + } + } + } + + private void extractHighlightingInfo( NamedList<Object> info ) + { + _highlighting = new HashMap<>(); + for( Map.Entry<String, Object> doc : info ) { + Map<String,List<String>> fieldMap = new HashMap<>(); + _highlighting.put( doc.getKey(), fieldMap ); + + NamedList<List<String>> fnl = (NamedList<List<String>>)doc.getValue(); + for( Map.Entry<String, List<String>> field : fnl ) { + fieldMap.put( field.getKey(), field.getValue() ); + } + } + } + + private void extractFacetInfo( NamedList<Object> info ) + { + // Parse the queries + _facetQuery = new LinkedHashMap<>(); + NamedList<Integer> fq = (NamedList<Integer>) info.get( "facet_queries" ); + if (fq != null) { + for( Map.Entry<String, Integer> entry : fq ) { + _facetQuery.put( entry.getKey(), entry.getValue() ); + } + } + + // Parse the facet info into fields + // TODO?? The list could be <int> or <long>? If always <long> then we can switch to <Long> + NamedList<NamedList<Number>> ff = (NamedList<NamedList<Number>>) info.get( "facet_fields" ); + if( ff != null ) { + _facetFields = new ArrayList<>( ff.size() ); + _limitingFacets = new ArrayList<>( ff.size() ); + + long minsize = _results == null ? Long.MAX_VALUE :_results.getNumFound(); + for( Map.Entry<String,NamedList<Number>> facet : ff ) { + FacetField f = new FacetField( facet.getKey() ); + for( Map.Entry<String, Number> entry : facet.getValue() ) { + f.add( entry.getKey(), entry.getValue().longValue() ); + } + + _facetFields.add( f ); + FacetField nl = f.getLimitingFields( minsize ); + if( nl.getValueCount() > 0 ) { + _limitingFacets.add( nl ); + } + } + } + + //Parse date facets + NamedList<NamedList<Object>> df = (NamedList<NamedList<Object>>) info.get("facet_dates"); + if (df != null) { + // System.out.println(df); + _facetDates = new ArrayList<>( df.size() ); + for (Map.Entry<String, NamedList<Object>> facet : df) { + // System.out.println("Key: " + facet.getKey() + " Value: " + facet.getValue()); + NamedList<Object> values = facet.getValue(); + String gap = (String) values.get("gap"); + Date end = (Date) values.get("end"); + FacetField f = new FacetField(facet.getKey(), gap, end); + + for (Map.Entry<String, Object> entry : values) { + try { + f.add(entry.getKey(), Long.parseLong(entry.getValue().toString())); + } catch (NumberFormatException e) { + //Ignore for non-number responses which are already handled above + } + } + + _facetDates.add(f); + } + } + + //Parse range facets + NamedList<NamedList<Object>> rf = (NamedList<NamedList<Object>>) info.get("facet_ranges"); + if (rf != null) { + _facetRanges = new ArrayList<>( rf.size() ); + for (Map.Entry<String, NamedList<Object>> facet : rf) { + NamedList<Object> values = facet.getValue(); + Object rawGap = values.get("gap"); + + RangeFacet rangeFacet; + if (rawGap instanceof Number) { + Number gap = (Number) rawGap; + Number start = (Number) values.get("start"); + Number end = (Number) values.get("end"); + + Number before = (Number) values.get("before"); + Number after = (Number) values.get("after"); + Number between = (Number) values.get("between"); + + rangeFacet = new RangeFacet.Numeric(facet.getKey(), start, end, gap, before, after, between); + } else { + String gap = (String) rawGap; + Date start = (Date) values.get("start"); + Date end = (Date) values.get("end"); + + Number before = (Number) values.get("before"); + Number after = (Number) values.get("after"); + Number between = (Number) values.get("between"); + + rangeFacet = new RangeFacet.Date(facet.getKey(), start, end, gap, before, after, between); + } + + NamedList<Integer> counts = (NamedList<Integer>) values.get("counts"); + for (Map.Entry<String, Integer> entry : counts) { + rangeFacet.addCount(entry.getKey(), entry.getValue()); + } + + _facetRanges.add(rangeFacet); + } + } + + //Parse pivot facets + NamedList pf = (NamedList) info.get("facet_pivot"); + if (pf != null) { + _facetPivot = new NamedList<>(); + for( int i=0; i<pf.size(); i++ ) { + _facetPivot.add( pf.getName(i), readPivots( (List<NamedList>)pf.getVal(i) ) ); + } + } + + //Parse interval facets + NamedList<NamedList<Object>> intervalsNL = (NamedList<NamedList<Object>>) info.get("facet_intervals"); + if (intervalsNL != null) { + _intervalFacets = new ArrayList<>(intervalsNL.size()); + for (Map.Entry<String, NamedList<Object>> intervalField : intervalsNL) { + String field = intervalField.getKey(); + List<IntervalFacet.Count> counts = new ArrayList<IntervalFacet.Count>(intervalField.getValue().size()); + for (Map.Entry<String, Object> interval : intervalField.getValue()) { + counts.add(new IntervalFacet.Count(interval.getKey(), (Integer)interval.getValue())); + } + _intervalFacets.add(new IntervalFacet(field, counts)); + } + } + } + + protected List<PivotField> readPivots( List<NamedList> list ) + { + ArrayList<PivotField> values = new ArrayList<>( list.size() ); + for( NamedList nl : list ) { + // NOTE, this is cheating, but we know the order they are written in, so no need to check + assert "field".equals(nl.getName(0)); + String f = (String)nl.getVal( 0 ); + assert "value".equals(nl.getName(1)); + Object v = nl.getVal( 1 ); + assert "count".equals(nl.getName(2)); + int cnt = ((Integer)nl.getVal( 2 )).intValue(); + + List<PivotField> subPivots = null; + Map<String,FieldStatsInfo> fieldStatsInfos = null; + + if (4 <= nl.size()) { + for(int index = 3; index < nl.size(); index++) { + final String key = nl.getName(index); + final Object val = nl.getVal(index); + switch (key) { + + case "pivot": { + assert null != val : "Server sent back 'null' for sub pivots?"; + assert val instanceof List : "Server sent non-List for sub pivots?"; + + subPivots = readPivots( (List<NamedList>) val ); + break; + } + case "stats": { + assert null != val : "Server sent back 'null' for stats?"; + assert val instanceof NamedList : "Server sent non-NamedList for stats?"; + + fieldStatsInfos = extractFieldStatsInfo((NamedList<Object>) val); + break; + } + default: + throw new RuntimeException( "unknown key in pivot: "+ key+ " ["+val+"]"); + + } + } + } + + values.add( new PivotField( f, v, cnt, subPivots, fieldStatsInfos ) ); + } + return values; + } + + //------------------------------------------------------ + //------------------------------------------------------ + + /** + * Remove the field facet info + */ + public void removeFacets() { + _facetFields = new ArrayList<>(); + } + + //------------------------------------------------------ + //------------------------------------------------------ + + public NamedList<Object> getHeader() { + return _header; + } + + public SolrDocumentList getResults() { + return _results; + } + + public NamedList<ArrayList> getSortValues(){ + return _sortvalues; + } + + public Map<String, Object> getDebugMap() { + return _debugMap; + } + + public Map<String, String> getExplainMap() { + return _explainMap; + } + + public Map<String,Integer> getFacetQuery() { + return _facetQuery; + } + + public Map<String, SolrDocumentList> getExpandedResults(){ + return this._expandedResults; + } + + /** + * Returns the {@link GroupResponse} containing the group commands. + * A group command can be the result of one of the following parameters: + * <ul> + * <li>group.field + * <li>group.func + * <li>group.query + * </ul> + * + * @return the {@link GroupResponse} containing the group commands + */ + public GroupResponse getGroupResponse() { + return _groupResponse; + } + + public Map<String, Map<String, List<String>>> getHighlighting() { + return _highlighting; + } + + public SpellCheckResponse getSpellCheckResponse() { + return _spellResponse; + } + + public TermsResponse getTermsResponse() { + return _termsResponse; + } + + /** + * See also: {@link #getLimitingFacets()} + */ + public List<FacetField> getFacetFields() { + return _facetFields; + } + + public List<FacetField> getFacetDates() { + return _facetDates; + } + + public List<RangeFacet> getFacetRanges() { + return _facetRanges; + } + + public NamedList<List<PivotField>> getFacetPivot() { + return _facetPivot; + } + + public List<IntervalFacet> getIntervalFacets() { + return _intervalFacets; + } + + /** get + * + * @param name the name of the + * @return the FacetField by name or null if it does not exist + */ + public FacetField getFacetField(String name) { + if (_facetFields==null) return null; + for (FacetField f : _facetFields) { + if (f.getName().equals(name)) return f; + } + return null; + } + + public FacetField getFacetDate(String name) { + if (_facetDates == null) + return null; + for (FacetField f : _facetDates) + if (f.getName().equals(name)) + return f; + return null; + } + + /** + * @return a list of FacetFields where the count is less then + * then #getResults() {@link SolrDocumentList#getNumFound()} + * + * If you want all results exactly as returned by solr, use: + * {@link #getFacetFields()} + */ + public List<FacetField> getLimitingFacets() { + return _limitingFacets; + } + + public <T> List<T> getBeans(Class<T> type){ + return solrClient == null ? + new DocumentObjectBinder().getBeans(type,_results): + solrClient.getBinder().getBeans(type, _results); + } + + public Map<String, FieldStatsInfo> getFieldStatsInfo() { + return _fieldStatsInfo; + } + + public String getNextCursorMark() { + return _cursorMarkNext; + } +} + + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java new file mode 100644 index 0000000..52b4e6b --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java @@ -0,0 +1,126 @@ +package org.apache.solr.client.solrj.response; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a range facet result + */ +public abstract class RangeFacet<B, G> { + + private final String name; + private final List<Count> counts = new ArrayList<>(); + + private final B start; + private final B end; + private final G gap; + + private final Number before; + private final Number after; + private final Number between; + + protected RangeFacet(String name, B start, B end, G gap, Number before, Number after, Number between) { + this.name = name; + this.start = start; + this.end = end; + this.gap = gap; + this.before = before; + this.after = after; + this.between = between; + } + + public void addCount(String value, int count) { + counts.add(new Count(value, count, this)); + } + + public String getName() { + return name; + } + + public List<Count> getCounts() { + return counts; + } + + public B getStart() { + return start; + } + + public B getEnd() { + return end; + } + + public G getGap() { + return gap; + } + + public Number getBefore() { + return before; + } + + public Number getAfter() { + return after; + } + + public Number getBetween() { + return between; + } + + public static class Numeric extends RangeFacet<Number, Number> { + + public Numeric(String name, Number start, Number end, Number gap, Number before, Number after, Number between) { + super(name, start, end, gap, before, after, between); + } + + } + + public static class Date extends RangeFacet<java.util.Date, String> { + + public Date(String name, java.util.Date start, java.util.Date end, String gap, Number before, Number after, Number between) { + super(name, start, end, gap, before, after, between); + } + + } + + public static class Count { + + private final String value; + private final int count; + private final RangeFacet rangeFacet; + + public Count(String value, int count, RangeFacet rangeFacet) { + this.value = value; + this.count = count; + this.rangeFacet = rangeFacet; + } + + public String getValue() { + return value; + } + + public int getCount() { + return count; + } + + public RangeFacet getRangeFacet() { + return rangeFacet; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java new file mode 100644 index 0000000..cbd892f --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + +/** + * + * + * @since solr 1.3 + */ +public class SolrPingResponse extends SolrResponseBase +{ + // nothing special now... +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java new file mode 100644 index 0000000..ca59e54 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + +import org.apache.solr.client.solrj.SolrResponse; +import org.apache.solr.common.util.NamedList; + +/** + * + * + * @since solr 1.3 + */ +public class SolrResponseBase extends SolrResponse +{ + private long elapsedTime = -1; + private NamedList<Object> response = null; + private String requestUrl = null; + + @Override + public long getElapsedTime() { + return elapsedTime; + } + + public void setElapsedTime(long elapsedTime) { + this.elapsedTime = elapsedTime; + } + + @Override + public NamedList<Object> getResponse() { + return response; + } + + @Override + public void setResponse(NamedList<Object> response) { + this.response = response; + } + + @Override + public String toString() { + return response.toString(); + } + + public NamedList getResponseHeader() { + return (NamedList) response.get("responseHeader"); + } + + // these two methods are based on the logic in SolrCore.setResponseHeaderValues(...) + public int getStatus() { + NamedList header = getResponseHeader(); + if (header != null) { + return (Integer) header.get("status"); + } + else { + return 0; + } + } + + public int getQTime() { + NamedList header = getResponseHeader(); + if (header != null) { + return (Integer) header.get("QTime"); + } + else { + return 0; + } + } + + public String getRequestUrl() { + return requestUrl; + } + + public void setRequestUrl(String requestUrl) { + this.requestUrl = requestUrl; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java new file mode 100644 index 0000000..a3ae45d --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java @@ -0,0 +1,273 @@ +package org.apache.solr.client.solrj.response; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.common.util.NamedList; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Encapsulates responses from SpellCheckComponent + * + * + * @since solr 1.3 + */ +public class SpellCheckResponse { + private boolean correctlySpelled; + private List<Collation> collations; + private List<Suggestion> suggestions = new ArrayList<>(); + Map<String, Suggestion> suggestionMap = new LinkedHashMap<>(); + + public SpellCheckResponse(NamedList<Object> spellInfo) { + @SuppressWarnings("unchecked") + NamedList<Object> sugg = (NamedList<Object>) spellInfo.get("suggestions"); + if (sugg == null) { + correctlySpelled = true; + return; + } + for (int i = 0; i < sugg.size(); i++) { + String n = sugg.getName(i); + @SuppressWarnings("unchecked") + Suggestion s = new Suggestion(n, (NamedList<Object>) sugg.getVal(i)); + suggestionMap.put(n, s); + suggestions.add(s); + } + + Boolean correctlySpelled = (Boolean) spellInfo.get("correctlySpelled"); + if (correctlySpelled != null) { + this.correctlySpelled = correctlySpelled; + } + + @SuppressWarnings("unchecked") + NamedList<Object> coll = (NamedList<Object>) spellInfo.get("collations"); + if (coll != null) { + // The 'collationInternalRank' values are ignored so we only care 'collation's. + List<Object> collationInfo = coll.getAll("collation"); + collations = new ArrayList<>(collationInfo.size()); + for (Object o : collationInfo) { + if (o instanceof String) { + collations.add(new Collation() + .setCollationQueryString((String) o)); + } else if (o instanceof NamedList) { + @SuppressWarnings("unchecked") + NamedList<Object> expandedCollation = (NamedList<Object>) o; + String collationQuery + = (String) expandedCollation.get("collationQuery"); + int hits = (Integer) expandedCollation.get("hits"); + @SuppressWarnings("unchecked") + NamedList<String> misspellingsAndCorrections + = (NamedList<String>) expandedCollation.get("misspellingsAndCorrections"); + + Collation collation = new Collation(); + collation.setCollationQueryString(collationQuery); + collation.setNumberOfHits(hits); + + for (int ii = 0; ii < misspellingsAndCorrections.size(); ii++) { + String misspelling = misspellingsAndCorrections.getName(ii); + String correction = misspellingsAndCorrections.getVal(ii); + collation.addMisspellingsAndCorrection(new Correction( + misspelling, correction)); + } + collations.add(collation); + } else { + throw new AssertionError( + "Should get Lists of Strings or List of NamedLists here."); + } + } + } + } + + public boolean isCorrectlySpelled() { + return correctlySpelled; + } + + public List<Suggestion> getSuggestions() { + return suggestions; + } + + public Map<String, Suggestion> getSuggestionMap() { + return suggestionMap; + } + + public Suggestion getSuggestion(String token) { + return suggestionMap.get(token); + } + + public String getFirstSuggestion(String token) { + Suggestion s = suggestionMap.get(token); + if (s==null || s.getAlternatives().isEmpty()) return null; + return s.getAlternatives().get(0); + } + + /** + * <p> + * Return the first collated query string. For convenience and backwards-compatibility. Use getCollatedResults() for full data. + * </p> + * @return first collated query string + */ + public String getCollatedResult() { + return collations==null || collations.size()==0 ? null : collations.get(0).collationQueryString; + } + + /** + * <p> + * Return all collations. + * Will include # of hits and misspelling-to-correction details if "spellcheck.collateExtendedResults was true. + * </p> + * @return all collations + */ + public List<Collation> getCollatedResults() { + return collations; + } + + public static class Suggestion { + private String token; + private int numFound; + private int startOffset; + private int endOffset; + private int originalFrequency; + private List<String> alternatives = new ArrayList<>(); + private List<Integer> alternativeFrequencies; + + public Suggestion(String token, NamedList<Object> suggestion) { + this.token = token; + for (int i = 0; i < suggestion.size(); i++) { + String n = suggestion.getName(i); + + if ("numFound".equals(n)) { + numFound = (Integer) suggestion.getVal(i); + } else if ("startOffset".equals(n)) { + startOffset = (Integer) suggestion.getVal(i); + } else if ("endOffset".equals(n)) { + endOffset = (Integer) suggestion.getVal(i); + } else if ("origFreq".equals(n)) { + originalFrequency = (Integer) suggestion.getVal(i); + } else if ("suggestion".equals(n)) { + @SuppressWarnings("unchecked") + List list = (List)suggestion.getVal(i); + if (list.size() > 0 && list.get(0) instanceof NamedList) { + // extended results detected + @SuppressWarnings("unchecked") + List<NamedList> extended = (List<NamedList>)list; + alternativeFrequencies = new ArrayList<>(); + for (NamedList nl : extended) { + alternatives.add((String)nl.get("word")); + alternativeFrequencies.add((Integer)nl.get("freq")); + } + } else { + @SuppressWarnings("unchecked") + List<String> alts = (List<String>) list; + alternatives.addAll(alts); + } + } + } + } + + public String getToken() { + return token; + } + + public int getNumFound() { + return numFound; + } + + public int getStartOffset() { + return startOffset; + } + + public int getEndOffset() { + return endOffset; + } + + public int getOriginalFrequency() { + return originalFrequency; + } + + /** The list of alternatives */ + public List<String> getAlternatives() { + return alternatives; + } + + /** The frequencies of the alternatives in the corpus, or null if this information was not returned */ + public List<Integer> getAlternativeFrequencies() { + return alternativeFrequencies; + } + + } + + public class Collation { + private String collationQueryString; + private List<Correction> misspellingsAndCorrections = new ArrayList<>(); + private long numberOfHits; + + public long getNumberOfHits() { + return numberOfHits; + } + + public void setNumberOfHits(long numberOfHits) { + this.numberOfHits = numberOfHits; + } + + public String getCollationQueryString() { + return collationQueryString; + } + + public Collation setCollationQueryString(String collationQueryString) { + this.collationQueryString = collationQueryString; + return this; + } + + public List<Correction> getMisspellingsAndCorrections() { + return misspellingsAndCorrections; + } + + public Collation addMisspellingsAndCorrection(Correction correction) { + this.misspellingsAndCorrections.add(correction); + return this; + } + + } + + public class Correction { + private String original; + private String correction; + + public Correction(String original, String correction) { + this.original = original; + this.correction = correction; + } + + public String getOriginal() { + return original; + } + + public void setOriginal(String original) { + this.original = original; + } + + public String getCorrection() { + return correction; + } + + public void setCorrection(String correction) { + this.correction = correction; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java new file mode 100644 index 0000000..5d8c0b7 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java @@ -0,0 +1,89 @@ +package org.apache.solr.client.solrj.response; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.solr.common.util.NamedList; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Encapsulates responses from TermsComponent + */ +public class TermsResponse { + private Map<String, List<Term>> termMap = new HashMap<>(); + + public TermsResponse(NamedList<NamedList<Number>> termsInfo) { + for (int i = 0; i < termsInfo.size(); i++) { + String fieldName = termsInfo.getName(i); + List<Term> itemList = new ArrayList<>(); + NamedList<Number> items = termsInfo.getVal(i); + + for (int j = 0; j < items.size(); j++) { + Term t = new Term(items.getName(j), items.getVal(j).longValue()); + itemList.add(t); + } + + termMap.put(fieldName, itemList); + } + } + + /** + * Get's the term list for a given field + * + * @return the term list or null if no terms for the given field exist + */ + public List<Term> getTerms(String field) { + return termMap.get(field); + } + + public Map<String, List<Term>> getTermMap() { + return termMap; + } + + public static class Term { + private String term; + private long frequency; + + public Term(String term, long frequency) { + this.term = term; + this.frequency = frequency; + } + + public String getTerm() { + return term; + } + + public void setTerm(String term) { + this.term = term; + } + + public long getFrequency() { + return frequency; + } + + public void setFrequency(long frequency) { + this.frequency = frequency; + } + + public void addFrequency(long frequency) { + this.frequency += frequency; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java new file mode 100644 index 0000000..7a62bc0 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.solr.client.solrj.response; + + +/** + * TODO -- mostly a stub until we have a defined output format + * + * + * @since solr 1.3 + */ +public class UpdateResponse extends SolrResponseBase +{ + // nothing special now... +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java new file mode 100644 index 0000000..e2bbe3a --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Convenience classes for dealing with various types of Solr responses. + + */ +package org.apache.solr.client.solrj.response; + +
