2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
18
package org.apache.solr.handler.component;
20
import static org.apache.solr.common.params.CommonParams.FQ;
21
import java.io.IOException;
25
import org.apache.lucene.search.Query;
26
import org.apache.solr.common.util.NamedList;
27
import org.apache.solr.common.util.SimpleOrderedMap;
28
import org.apache.solr.search.QueryParsing;
29
import org.apache.solr.util.SolrPluginUtils;
32
* Adds debugging information to a request.
34
* @version $Id: DebugComponent.java 1065312 2011-01-30 16:08:25Z rmuir $
37
public class DebugComponent extends SearchComponent
39
public static final String COMPONENT_NAME = "debug";
42
public void prepare(ResponseBuilder rb) throws IOException
47
@SuppressWarnings("unchecked")
49
public void process(ResponseBuilder rb) throws IOException
52
NamedList stdinfo = SolrPluginUtils.doStandardDebug( rb.req,
53
rb.getQueryString(), rb.getQuery(), rb.getResults().docList);
55
NamedList info = rb.getDebugInfo();
57
rb.setDebugInfo( stdinfo );
61
info.addAll( stdinfo );
64
if (rb.getQparser() != null) {
65
rb.getQparser().addDebugInfo(rb.getDebugInfo());
68
if (null != rb.getDebugInfo() ) {
69
if (null != rb.getFilters() ) {
70
info.add("filter_queries",rb.req.getParams().getParams(FQ));
71
List<String> fqs = new ArrayList<String>(rb.getFilters().size());
72
for (Query fq : rb.getFilters()) {
73
fqs.add(QueryParsing.toString(fq, rb.req.getSchema()));
75
info.add("parsed_filter_queries",fqs);
78
// Add this directly here?
79
rb.rsp.add("debug", rb.getDebugInfo() );
86
public void modifyRequest(ResponseBuilder rb, SearchComponent who, ShardRequest sreq) {
87
if (!rb.isDebug()) return;
89
// Turn on debug to get explain only when retrieving fields
90
if ((sreq.purpose & ShardRequest.PURPOSE_GET_FIELDS) != 0) {
91
sreq.purpose |= ShardRequest.PURPOSE_GET_DEBUG;
92
sreq.params.set("debugQuery", "true");
94
sreq.params.set("debugQuery", "false");
99
public void handleResponses(ResponseBuilder rb, ShardRequest sreq) {
102
private Set<String> excludeSet = new HashSet<String>(Arrays.asList("explain"));
105
public void finishStage(ResponseBuilder rb) {
106
if (rb.isDebug() && rb.stage == ResponseBuilder.STAGE_GET_FIELDS) {
107
NamedList info = null;
108
NamedList explain = new SimpleOrderedMap();
110
Map.Entry<String, Object>[] arr = new NamedList.NamedListEntry[rb.resultIds.size()];
112
for (ShardRequest sreq : rb.finished) {
113
if ((sreq.purpose & ShardRequest.PURPOSE_GET_DEBUG) == 0) continue;
114
for (ShardResponse srsp : sreq.responses) {
115
NamedList sdebug = (NamedList)srsp.getSolrResponse().getResponse().get("debug");
116
info = (NamedList)merge(sdebug, info, excludeSet);
118
NamedList sexplain = (NamedList)sdebug.get("explain");
120
for (int i=0; i<sexplain.size(); i++) {
121
String id = sexplain.getName(i);
122
// TODO: lookup won't work for non-string ids... String vs Float
123
ShardDoc sdoc = rb.resultIds.get(id);
124
int idx = sdoc.positionInResponse;
125
arr[idx] = new NamedList.NamedListEntry<Object>( id, sexplain.getVal(i));
130
explain = HighlightComponent.removeNulls(new SimpleOrderedMap(arr));
133
info = new SimpleOrderedMap();
135
int idx = info.indexOf("explain",0);
137
info.setVal(idx, explain);
139
info.add("explain", explain);
142
rb.setDebugInfo(info);
143
rb.rsp.add("debug", rb.getDebugInfo() );
148
Object merge(Object source, Object dest, Set<String> exclude) {
149
if (source == null) return dest;
151
if (source instanceof NamedList) {
152
dest = source instanceof SimpleOrderedMap ? new SimpleOrderedMap() : new NamedList();
158
if (dest instanceof Collection) {
159
if (source instanceof Collection) {
160
((Collection)dest).addAll((Collection)source);
162
((Collection)dest).add(source);
165
} else if (source instanceof Number) {
166
if (dest instanceof Number) {
167
if (source instanceof Double || dest instanceof Double) {
168
return ((Number)source).doubleValue() + ((Number)dest).doubleValue();
170
return ((Number)source).longValue() + ((Number)dest).longValue();
173
} else if (source instanceof String) {
174
if (source.equals(dest)) {
182
if (source instanceof NamedList && dest instanceof NamedList) {
183
NamedList tmp = new NamedList();
184
NamedList sl = (NamedList)source;
185
NamedList dl = (NamedList)dest;
186
for (int i=0; i<sl.size(); i++) {
187
String skey = sl.getName(i);
188
if (exclude != null && exclude.contains(skey)) continue;
189
Object sval = sl.getVal(i);
192
// optimize case where elements are in same position
194
String dkey = dl.getName(i);
195
if (skey == dkey || (skey!=null && skey.equals(dkey))) {
201
didx = dl.indexOf(skey, 0);
205
tmp.add(skey, merge(sval, null, null));
207
dl.setVal(didx, merge(sval, dl.getVal(didx), null));
214
// merge unlike elements in a list
215
List t = new ArrayList();
223
/////////////////////////////////////////////
225
////////////////////////////////////////////
228
public String getDescription() {
229
return "Debug Information";
233
public String getVersion() {
234
return "$Revision: 1065312 $";
238
public String getSourceId() {
239
return "$Id: DebugComponent.java 1065312 2011-01-30 16:08:25Z rmuir $";
243
public String getSource() {
244
return "$URL: http://svn.apache.org/repos/asf/lucene/dev/tags/lucene_solr_3_5_0/solr/core/src/java/org/apache/solr/handler/component/DebugComponent.java $";
248
public URL[] getDocs() {