diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index e6316b30910..46461d0356d 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -342,9 +342,12 @@ New Features
* SOLR-2523: Added support in SolrJ to easily interact with range facets.
The range facet response can be parsed and is retrievable from the
- QueryResponse class. The SolrQuery has convenient methods for using
+ QueryResponse class. The SolrQuery class has convenient methods for using
range facets. (Martijn van Groningen)
+* SOLR-2637: Added support for group result parsing in SolrJ.
+ (Tao Cheng, Martijn van Groningen)
+
Optimizations
----------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/XMLResponseParser.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/XMLResponseParser.java
index d17b3e647fe..27c01a1c995 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/XMLResponseParser.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/XMLResponseParser.java
@@ -17,23 +17,7 @@
package org.apache.solr.client.solrj.impl;
-import java.io.Reader;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-
import org.apache.solr.client.solrj.ResponseParser;
-import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
@@ -41,6 +25,19 @@ import org.apache.solr.common.util.DateUtil;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.XMLErrorLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
/**
*
@@ -306,10 +303,10 @@ public class XMLResponseParser extends ResponseParser
if( !type.isLeaf ) {
switch( type ) {
- case LST: vals.add( readNamedList( parser ) ); continue;
- case ARR: vals.add( readArray( parser ) ); continue;
- case RESULT: vals.add( readDocuments( parser ) ); continue;
- case DOC: vals.add( readDocument( parser ) ); continue;
+ case LST: vals.add( readNamedList( parser ) ); depth--; continue;
+ case ARR: vals.add( readArray( parser ) ); depth--; continue;
+ case RESULT: vals.add( readDocuments( parser ) ); depth--; continue;
+ case DOC: vals.add( readDocument( parser ) ); depth--; continue;
}
throw new XMLStreamException( "branch element not handled!", parser.getLocation() );
}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/response/Group.java b/solr/solrj/src/java/org/apache/solr/client/solrj/response/Group.java
new file mode 100644
index 00000000000..2ee0389fbc6
--- /dev/null
+++ b/solr/solrj/src/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 group.offset and group.limit parameters.
+ *
+ * @return the documents to be displayed that belong to this group
+ */
+ public SolrDocumentList getResult() {
+ return _result;
+ }
+
+}
\ No newline at end of file
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/response/GroupCommand.java b/solr/solrj/src/java/org/apache/solr/client/solrj/response/GroupCommand.java
new file mode 100644
index 00000000000..80c7726e0da
--- /dev/null
+++ b/solr/solrj/src/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:
+ *
+ *
group.field
+ *
group.func
+ *
group.query
+ *
+ *
+ * An instance of this class contains:
+ *
+ *
The name of this command. This can be the field, function or query grouped by.
+ *
The total number of documents that have matched.
+ *
The total number of groups that have matched.
+ *
The groups to be displayed. Depending on the start and rows parameter.
+ *
+ *
+ * In case of group.query only one group is present and ngroups is always null.
+ *
+ * @since solr 3.4
+ */
+public class GroupCommand implements Serializable {
+
+ private final String _name;
+ private final List _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 start and rows parameters.
+ *
+ * @return the groups to be displayed.
+ */
+ public List 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 null if the group.ngroups parameter is unset or false or
+ * if this is a group command query (parameter = group.query).
+ *
+ * @return the total number of groups found for this command.
+ */
+ public Integer getNGroups() {
+ return _ngroups;
+ }
+
+}
\ No newline at end of file
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/response/GroupResponse.java b/solr/solrj/src/java/org/apache/solr/client/solrj/response/GroupResponse.java
new file mode 100644
index 00000000000..9ec54622252
--- /dev/null
+++ b/solr/solrj/src/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:
+ *
+ *
group.field
+ *
group.func
+ *
group.query
+ *
+ *
+ * @since solr 3.4
+ */
+public class GroupResponse implements Serializable {
+
+ private final List _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 getValues() {
+ return _values;
+ }
+}
\ No newline at end of file
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java b/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
index d38d8611a92..8c838751a8a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
@@ -21,6 +21,7 @@ import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
import java.util.*;
@@ -43,6 +44,10 @@ public class QueryResponse extends SolrResponseBase
private NamedList