/**
 * Copyright 2006 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.solr.request;

import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.RefCounted;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrException;

/**
 * Base implementation of <code>SolrQueryRequest</code> that provides some
 * convenience methods for accessing parameters, and manages an IndexSearcher
 * reference.
 *
 * <p>
 * The <code>close()</code> method must be called on any instance of this
 * class once it is no longer in use.
 * </p>
 *
 *
 * @author yonik
 * @version $Id$
 */
public abstract class SolrQueryRequestBase implements SolrQueryRequest {
  @Deprecated
  public static final String QUERY_NAME="q";
  @Deprecated
  public static final String START_NAME="start";
  @Deprecated
  public static final String ROWS_NAME="rows";
  @Deprecated
  public static final String XSL_NAME="xsl";
  @Deprecated
  public static final String QUERYTYPE_NAME="qt";

  protected final SolrCore core;
  protected final SolrParams origParams;
  protected SolrParams params;

  public SolrQueryRequestBase(SolrCore core, SolrParams params) {
    this.core = core;
    this.params = this.origParams = params;
  }

  /** returns the current request parameters */
  public SolrParams getParams() {
    return params;
  }

  /** Returns the original request parameters.  As this
   * does not normally include configured defaults
   * it's more suitable for logging.
   */
  public SolrParams getOriginalParams() {
    return origParams;
  }

  /** Change the parameters for this request.  This does not affect
   *  the original parameters returned by getOriginalParams()
   */
  public void setParams(SolrParams params) {
    this.params = params;
  }

  public String getParam(String name) {
    return params.get(name);
  }

  public String[] getParams(String name) {
    return params.getParams(name);
  }


  public int getIntParam(String name) {
    String s = getParam(name);
    if (s==null) {
      throw new SolrException(500,"Missing required parameter '"+name+"' from " + this);
    }
    return Integer.parseInt(s);
  }

  public int getIntParam(String name, int defval) {
    String s = getParam(name);
    return s==null ? defval : Integer.parseInt(s);
  }

  public String getStrParam(String name) {
    String s = getParam(name);
    if (s==null) {
      throw new SolrException(500,"Missing required parameter '"+name+"' from " + this);
    }
    return s;
  }

  public String getStrParam(String name, String defval) {
    String s = getParam(name);
    return s==null ? defval : s;
  }

  public String getQueryString() {
    return params.get(SolrParams.Q);
  }

  public String getQueryType() {
    return params.get(SolrParams.QT);
  }

  // starting position in matches to return to client
  public int getStart() {
    return params.getInt(SolrParams.START, 0);
  }

  // number of matching documents to return
  @Deprecated
  public int getLimit() {
    return params.getInt(SolrParams.ROWS, 10);
  }


  protected final long startTime=System.currentTimeMillis();
  // Get the start time of this request in milliseconds
  public long getStartTime() {
    return startTime;
  }

  // The index searcher associated with this request
  protected RefCounted<SolrIndexSearcher> searcherHolder;
  public SolrIndexSearcher getSearcher() {
    // should this reach out and get a searcher from the core singleton, or
    // should the core populate one in a factory method to create requests?
    // or there could be a setSearcher() method that Solr calls

    if (searcherHolder==null) {
      searcherHolder = core.getSearcher();
    }

    return searcherHolder.get();
  }

  // The solr core (coordinator, etc) associated with this request
  public SolrCore getCore() {
    return core;
  }

  // The index schema associated with this request
  public IndexSchema getSchema() {
    return core.getSchema();
  }

  /**
   * Frees resources associated with this request, this method <b>must</b>
   * be called when the object is no longer in use.
   */
  public void close() {
    if (searcherHolder!=null) {
      searcherHolder.decref();
    }
  }


  public String getParamString() {
    return origParams.toString();
  }

  public String toString() {
    return this.getClass().getSimpleName() + '{' + params + '}';
  }

}

@@ -857,16 +857,65 @@
 ption;%0A%0A
+import java.util.Map;%0Aimport java.util.HashMap;%0A%0A
 /**%0A * B
@@ -1735,16 +1735,56 @@
  params;
+%0A  protected Map%3CObject,Object%3E context;
 %0A%0A  publ
@@ -1920,261 +1920,213 @@
 %0A%0A  
-/** returns the current request parameters */%0A  public SolrParams getParams() %7B%0A    return params;%0A  %7D%0A%0A  /** Returns the original request parameters.  As this%0A   * does not normally include configured defaults%0A   * it's more suitable for logging.%0A   */
+public Map%3CObject,Object%3E getContext() %7B%0A    // SolrQueryRequest as a whole isn't thread safe, and this isn't either.%0A    if (context==null) context = new HashMap%3CObject,Object%3E();%0A    return context;%0A  %7D%0A
 %0A  p
@@ -2141,32 +2141,24 @@
 lrParams get
-Original
 Params() %7B%0A 
@@ -2163,29 +2163,25 @@
 %0A    return 
-origP
+p
 arams;%0A  %7D%0A%0A
@@ -2186,141 +2186,75 @@
 %0A%0A  
-/** Change the parameters for this request.  This does not affect%0A   *  the o
+public SolrParams getO
 riginal
- p
+P
 aram
-eters returned by getOriginal
+s() %7B%0A    return orig
 Params
-()%0A   */
+;%0A  %7D%0A
 %0A  p

add getContext() to SolrQueryRequest