lucene-solr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject svn commit: r633360 - in /lucene/solr/trunk: client/java/solrj/src/org/apache/solr/client/solrj/embedded/ client/java/solrj/src/org/apache/solr/client/solrj/request/ client/java/solrj/test/org/apache/solr/client/solrj/ example/multicore/ src/java/org/a...
Date Tue, 04 Mar 2008 04:06:20 GMT
Author: ryan
Date: Mon Mar  3 20:06:17 2008
New Revision: 633360

URL: http://svn.apache.org/viewvc?rev=633360&view=rev
Log:
SOLR-350 -- manage multiple cores.  This implements persist, load and unload.

Added:
    lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java   (with props)
Modified:
    lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
    lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/request/MultiCoreRequest.java
    lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java
    lucene/solr/trunk/example/multicore/multicore.xml
    lucene/solr/trunk/src/java/org/apache/solr/common/params/MultiCoreParams.java
    lucene/solr/trunk/src/java/org/apache/solr/core/Config.java
    lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
    lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
    lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
    lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java
    lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java
    lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
    lucene/solr/trunk/src/test/org/apache/solr/servlet/SolrRequestParserTest.java
    lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/DirectSolrConnection.java
    lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java
    lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrRequestParsers.java

Modified: lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java (original)
+++ lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java Mon Mar  3 20:06:17 2008
@@ -84,7 +84,7 @@
     _invariantParams.set( CommonParams.WT, _processor.getWriterType() );
     _invariantParams.set( CommonParams.VERSION, "2.2" );
     
-    return new SolrRequestParsers( true, Long.MAX_VALUE );
+    return new SolrRequestParsers( null );
   }
 
   @Override

Modified: lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/request/MultiCoreRequest.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/request/MultiCoreRequest.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/request/MultiCoreRequest.java (original)
+++ lucene/solr/trunk/client/java/solrj/src/org/apache/solr/client/solrj/request/MultiCoreRequest.java Mon Mar  3 20:06:17 2008
@@ -20,9 +20,9 @@
 import java.io.IOException;
 import java.util.Collection;
 
+import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.response.MultiCoreResponse;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.MultiCoreParams;
@@ -32,13 +32,50 @@
 
 /**
  * 
- * @version $Id$
+ * @version $Id: MultiCoreRequest.java 606335 2007-12-21 22:23:39Z ryan $
  * @since solr 1.3
  */
 public class MultiCoreRequest extends SolrRequest
 {
-  private MultiCoreParams.MultiCoreAction action = null;
-  private String core = null;
+  protected String core = null;
+  protected MultiCoreParams.MultiCoreAction action = null;
+  
+  //a create core request
+  public static class Create extends MultiCoreRequest {
+    protected String instanceDir;
+    protected String configName = null;
+    protected String schemaName = null;
+    
+    public Create() {
+      action = MultiCoreAction.CREATE;
+    }
+    
+    public void setInstanceDir(String instanceDir) { this.instanceDir = instanceDir; }
+    public void setSchemaName(String schema) { this.schemaName = schema; }
+    public void setConfigName(String config) { this.configName = config; }
+    
+    public String getInstanceDir() { return instanceDir; }
+    public String getSchemaName()  { return schemaName; }
+    public String getConfigName()  { return configName; }
+    
+    @Override
+    public SolrParams getParams() {
+      if( action == null ) {
+        throw new RuntimeException( "no action specified!" );
+      }
+      ModifiableSolrParams params = new ModifiableSolrParams();
+      params.set( MultiCoreParams.ACTION, action.toString() );
+      params.set( MultiCoreParams.CORE, core );
+      params.set( MultiCoreParams.INSTANCE_DIR, instanceDir);
+      if (configName != null) {
+        params.set( MultiCoreParams.CONFIG, configName);
+      }
+      if (schemaName != null) {
+        params.set( MultiCoreParams.SCHEMA, schemaName);
+      }
+      return params;
+    }
+  }
   
   public MultiCoreRequest()
   {
@@ -88,7 +125,7 @@
   public Collection<ContentStream> getContentStreams() throws IOException {
     return null;
   }
-  
+
   @Override
   public MultiCoreResponse process(SolrServer server) throws SolrServerException, IOException 
   {
@@ -115,6 +152,14 @@
     MultiCoreRequest req = new MultiCoreRequest();
     req.setCoreParam( name );
     req.setAction( MultiCoreAction.STATUS );
+    return req.process( server );
+  }
+  
+  public static MultiCoreResponse createCore( String name, String instanceDir, SolrServer server ) throws SolrServerException, IOException 
+  {
+    MultiCoreRequest.Create req = new MultiCoreRequest.Create();
+    req.setCoreParam( name );
+    req.setInstanceDir(instanceDir);
     return req.process( server );
   }
 }

Modified: lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java (original)
+++ lucene/solr/trunk/client/java/solrj/test/org/apache/solr/client/solrj/MultiCoreExampleTestBase.java Mon Mar  3 20:06:17 2008
@@ -17,6 +17,8 @@
 
 package org.apache.solr.client.solrj;
 
+import java.io.File;
+
 import org.apache.solr.client.solrj.request.MultiCoreRequest;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
@@ -37,6 +39,12 @@
   @Override public String getSchemaFile()     { return getSolrHome()+"core0/conf/schema.xml";     }
   @Override public String getSolrConfigFile() { return getSolrHome()+"core0/conf/solrconfig.xml"; }
   
+  @Override public void setUp() throws Exception {
+//    File src = new File(getSolrHome(), "multicore-base.xml");
+//    File dest = new File(getSolrHome(), "multicore.xml");
+//    org.apache.solr.core.MultiCore.fileCopy(src, dest);
+    super.setUp();
+  }
 
   @Override
   protected final SolrServer getSolrServer()

Modified: lucene/solr/trunk/example/multicore/multicore.xml
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/example/multicore/multicore.xml?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/example/multicore/multicore.xml (original)
+++ lucene/solr/trunk/example/multicore/multicore.xml Mon Mar  3 20:06:17 2008
@@ -17,16 +17,15 @@
 -->
 
 <!--
- All paths are relative to the instaliation path
+ All (relative) paths are relative to the installation path
   
   adminPath: RequestHandler path to manage multicores.  
     If 'null', cores will not be managable via REST
     
-  persistent: Save changes made via the REST API to this file?
-  
-  sharedLib: path to a lib files that will be shared across all cores
+  persistent: Save changes made via the API to this file
+  sharedLib: path to a lib directory that will be shared across all cores
 -->
 <multicore adminPath="/admin/multicore" persistent="true" >
   <core name="core0" instanceDir="core0" default="true"/>
-  <core name="core1" instanceDir="core1" />
+  <core name="core1" instanceDir="core1"/>
 </multicore>

Modified: lucene/solr/trunk/src/java/org/apache/solr/common/params/MultiCoreParams.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/common/params/MultiCoreParams.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/common/params/MultiCoreParams.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/common/params/MultiCoreParams.java Mon Mar  3 20:06:17 2008
@@ -32,14 +32,29 @@
   /** The name of the the core to swap names with **/
   public final static String WITH = "with";
   
+  /** If you rename something, what is the new name **/
+  public final static String NAME = "name";
+  
   /** What action **/
   public final static String ACTION = "action";
   
+  /** If you specify a schema, what is its name **/
+  public final static String SCHEMA = "schema";
+  
+  /** If you specify a config, what is its name **/
+  public final static String CONFIG = "config";
+  
+  /** Specifies a core instance dir. */
+  public final static String INSTANCE_DIR = "instanceDir";
+  
   public enum MultiCoreAction {
     STATUS,  
     LOAD,
     UNLOAD,
     RELOAD,
+    CREATE,
+    DROP,
+    PERSIST,
     SWAP;
     
     public static MultiCoreAction get( String p )

Modified: lucene/solr/trunk/src/java/org/apache/solr/core/Config.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/Config.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/Config.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/Config.java Mon Mar  3 20:06:17 2008
@@ -51,11 +51,38 @@
     this( null, name, is, prefix );
   }
 
+  /**
+   * Builds a config from a resource name with no xpath prefix.
+   * @param loader
+   * @param name
+   * @throws javax.xml.parsers.ParserConfigurationException
+   * @throws java.io.IOException
+   * @throws org.xml.sax.SAXException
+   */
   public Config(SolrResourceLoader loader, String name) throws ParserConfigurationException, IOException, SAXException 
   {
     this( loader, name, null, null );
   }
   
+  /**
+   * Builds a config:
+   * <p>
+   * Note that the 'name' parameter is used to obtain a valid input stream if no valid one is provided through 'is'.
+   * If no valid stream is provided, a valid SolrResourceLoader instance should be provided through 'loader' so
+   * the resource can be opened (@see SolrResourceLoader#openResource); if no SolrResourceLoader instance is provided, a default one
+   * will be created.
+   * </p>
+   * <p>
+   * Consider passing a non-null 'name' parameter in all use-cases since it is used for logging & exception reporting.
+   * </p>
+   * @param loader the resource loader used to obtain an input stream if 'is' is null
+   * @param name the resource name used if the input stream 'is' is null
+   * @param is the resource as a stream
+   * @param prefix an optional prefix that will be preprended to all non-absolute xpath expressions
+   * @throws javax.xml.parsers.ParserConfigurationException
+   * @throws java.io.IOException
+   * @throws org.xml.sax.SAXException
+   */
   public Config(SolrResourceLoader loader, String name, InputStream is, String prefix) throws ParserConfigurationException, IOException, SAXException 
   {
     if( loader == null ) {
@@ -63,14 +90,12 @@
     }
     this.loader = loader;
     this.name = name;
-    this.prefix = prefix;
-    
-    if (prefix!=null && !prefix.endsWith("/")) prefix += '/';
+    this.prefix = (prefix != null && !prefix.endsWith("/"))? prefix + '/' : prefix;
     InputStream lis = is;
     try {
-      if (lis == null)
-        lis = loader.openResource(name);
-      
+      if (lis == null) {
+        lis = loader.openConfig(name);
+      }
       javax.xml.parsers.DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
       doc = builder.parse(lis);
 
@@ -80,8 +105,7 @@
     	throw e;
     } finally {
       // if this opens the resource, it also closes it
-      if (lis != is)
-        lis.close();
+      if (lis != is)  lis.close();
     }
   }
   
@@ -93,6 +117,17 @@
     return loader;
   }
 
+  /**
+   * @since solr 1.3
+   */
+  public String getResourceName() {
+    return name;
+  }
+
+  public String getName() {
+    return name;
+  }
+  
   public Document getDocument() {
     return doc;
   }
@@ -206,13 +241,6 @@
     return val!=null ? Float.parseFloat(val) : def;
   }
 
-  /**
-   * @return the XML filename
-   */
-  public String getName() {
-    return name;
-  }
-  
   // The following functions were moved to ResourceLoader
   //-----------------------------------------------------------------------------
   

Added: lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java?rev=633360&view=auto
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java (added)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java Mon Mar  3 20:06:17 2008
@@ -0,0 +1,116 @@
+/**
+ * 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.core;
+
+/**
+ * A Solr core descriptor
+ * @since solr 1.3
+ */
+public class CoreDescriptor implements Cloneable {
+  protected String name;
+  protected String instanceDir;
+  protected String configName;
+  protected String schemaName;
+  protected SolrCore core = null;
+
+  public CoreDescriptor() {}
+  
+  /** Initialize defaults from instance directory. */
+  public void init(String name, String instanceDir) {
+    if (name == null) {
+      throw new RuntimeException("Core needs a name");
+    }
+    if (instanceDir == null) {
+      throw new NullPointerException("Missing required \'instanceDir\'");
+    }
+    this.name = name;
+    if (!instanceDir.endsWith("/")) instanceDir = instanceDir + "/";
+    this.instanceDir = instanceDir;
+    this.configName = getDefaultConfigName();
+    this.schemaName = getDefaultSchemaName();
+  }
+
+  public CoreDescriptor(CoreDescriptor descr) {
+    this.name = descr.name;
+    this.instanceDir = descr.instanceDir;
+    this.configName = descr.configName;
+    this.schemaName = descr.schemaName;
+  }
+  
+  /**@return the default config name. */
+  public String getDefaultConfigName() {
+    return "solrconfig.xml";
+  }
+  
+  /**@return the default schema name. */
+  public String getDefaultSchemaName() {
+    return "schema.xml";
+  }
+  
+  /**@return the default data directory. */
+  public String getDefaultDataDir() {
+    return this.instanceDir + "data/";
+  }
+  
+  /**@return the core name. */
+  public String getName() {
+    return name;
+  }
+  
+  /** Sets the core name. */
+  public void setName(String name) {
+    this.name = name;
+  }
+  
+  /**@return the core instance directory. */
+  public String getInstanceDir() {
+    return instanceDir;
+  }
+  
+  /**Sets the core configuration resource name. */
+  public void setConfigName(String name) {
+    if (name == null || name.length() == 0)
+      throw new IllegalArgumentException("name can not be null or empty");
+    this.configName = name;
+  }
+  
+  /**@return the core configuration resource name. */
+  public String getConfigName() {
+    return this.configName;
+  }  
+
+  /**Sets the core schema resource name. */
+  public void setSchemaName(String name) {
+    if (name == null || name.length() == 0)
+      throw new IllegalArgumentException("name can not be null or empty");
+    this.schemaName = name; 
+  }
+  
+  /**@return the core schema resource name. */
+  public String getSchemaName() {
+    return this.schemaName;
+  }
+  
+  public SolrCore getCore() {
+    return core;
+  }
+  
+  public void setCore(SolrCore core) {
+    this.core = core;
+  }
+}

Propchange: lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lucene/solr/trunk/src/java/org/apache/solr/core/CoreDescriptor.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/MultiCore.java Mon Mar  3 20:06:17 2008
@@ -17,12 +17,16 @@
 
 package org.apache.solr.core;
 
+import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.channels.FileChannel;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.logging.Logger;
 
@@ -31,6 +35,7 @@
 
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.DOMUtil;
+import org.apache.solr.common.util.XML;
 import org.apache.solr.handler.admin.MultiCoreHandler;
 import org.apache.solr.schema.IndexSchema;
 import org.w3c.dom.Node;
@@ -48,10 +53,8 @@
   private static final MultiCore instance = new MultiCore();
   
   // Synchronized map of all cores
-  private final Map<String, SolrCore> cores =
-      Collections.synchronizedMap( new HashMap<String, SolrCore>() );
+  private final Map<String, CoreDescriptor> cores = new LinkedHashMap<String, CoreDescriptor>();
   
-  private SolrCore defaultCore = null;
   private boolean enabled = false;
   private boolean persistent = false;
   private String adminPath = null;
@@ -59,6 +62,7 @@
   private File configFile = null;
   private String libDir = null;
   private ClassLoader libLoader = null;
+  private SolrResourceLoader loader = null;
   
   // no one else can make the registry
   private MultiCore() { }
@@ -72,71 +76,61 @@
    */
   public void load(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException {
     this.configFile = configFile;
-    Config cfg = new Config( new SolrResourceLoader(dir), 
-        null, new FileInputStream( configFile ), null );
+    this.loader = new SolrResourceLoader(dir);
+    FileInputStream cfgis = new FileInputStream(configFile);
+    try {
+      Config cfg = new Config(loader, null, cfgis, null);
     
-    persistent = cfg.getBool( "multicore/@persistent", false );
-    adminPath  = cfg.get(     "multicore/@adminPath", null );
-    libDir     = cfg.get(     "multicore/@sharedLib", null);
-    if (libDir != null) {
-      // relative dir to conf
-      File f = new File(dir, libDir);
-      libDir = f.getPath(); 
-      log.info( "loading shared library: "+f.getAbsolutePath() );
-      libLoader = SolrResourceLoader.createClassLoader(f, null);
-    }
-    
-    if( adminPath != null ) {
-      multiCoreHandler = new MultiCoreHandler();
-    }
-    
-    boolean hasDefault = false;
-    NodeList nodes = (NodeList)cfg.evaluate("multicore/core", XPathConstants.NODESET);
-    for (int i=0; i<nodes.getLength(); i++) {
-      Node node = nodes.item(i);
+      persistent = cfg.getBool( "multicore/@persistent", false );
+      adminPath  = cfg.get(     "multicore/@adminPath", null );
+      libDir     = cfg.get(     "multicore/@sharedLib", null);
       
-      try {
-        String name         = DOMUtil.getAttr(node,"name", "Core needs a name" );
-        String instanceDir  = DOMUtil.getAttr(node,"instanceDir", "Missing required 'instanceDir'" );
-        String dataDir      = DOMUtil.getAttr(node,"dataDir", null );
-        String defaultStr   = DOMUtil.getAttr(node,"default", null );
-        
-        // Make the instanceDir relative to the core config
-        File idir = new File( dir, instanceDir );
-        instanceDir = idir.getPath();
-        
-        // Initialize the solr config
-        SolrResourceLoader solrLoader = new SolrResourceLoader(instanceDir, libLoader);
-        SolrConfig solrConfig = new SolrConfig( solrLoader, SolrConfig.DEFAULT_CONF_FILE, null );
-        IndexSchema schema = new IndexSchema(solrConfig, instanceDir+"/conf/schema.xml");
-        SolrCore core = new SolrCore( name, dataDir, solrConfig, schema );
-        
-        // Register the new core
-        SolrCore old = this.register( core );
-        if( old != null ) {
-          throw new RuntimeException( cfg.getName() +
-                  " registers multiple cores to the same name: "+name );
-        }
-        
-        if( "true".equalsIgnoreCase( defaultStr ) ) {
-          if( hasDefault ) {
-            throw new RuntimeException( 
-                "multicore.xml defines multiple default cores. "+
-                getDefaultCore().getName() + " and " + core.getName() );
+      if (libDir != null) {
+        // relative dir to conf
+        File f = new File(dir, libDir);
+        libDir = f.getPath(); 
+        log.info( "loading shared library: "+f.getAbsolutePath() );
+        libLoader = SolrResourceLoader.createClassLoader(f, null);
+      }
+      
+      if( adminPath != null ) {
+        multiCoreHandler = new MultiCoreHandler();
+      }
+      
+      NodeList nodes = (NodeList)cfg.evaluate("multicore/core", XPathConstants.NODESET);
+      synchronized (cores) {
+        for (int i=0; i<nodes.getLength(); i++) {
+          Node node = nodes.item(i);
+          try {
+            CoreDescriptor p = new CoreDescriptor();
+            p.init(DOMUtil.getAttr(node, "name", null), DOMUtil.getAttr(node, "instanceDir", null));
+            // deal with optional settings
+            String opt = DOMUtil.getAttr(node, "config", null);
+            if (opt != null) {
+              p.setConfigName(opt);
+            }
+            opt = DOMUtil.getAttr(node, "schema", null);
+            if (opt != null) {
+              p.setSchemaName(opt);
+            }
+            CoreDescriptor old = cores.get(p.getName());
+            if (old != null && old.getName() != null && old.getName().equals(p.getName())) {
+              throw new RuntimeException( cfg.getName() +
+                " registers multiple cores to the same name: " + p.name);
+            }
+            p.setCore(create(p));
+          }
+          catch (Throwable ex) {
+            SolrConfig.severeErrors.add( ex );
+            SolrException.logOnce(log,null,ex);
           }
-          defaultCore = core;
-          hasDefault = true;
         }
-      } 
-      catch( Throwable ex ) {
-        SolrConfig.severeErrors.add( ex );
-        SolrException.logOnce(log,null,ex);
       }
     }
-    
-    if( !hasDefault ) {
-      throw new RuntimeException( 
-          "multicore.xml must define at least one default core" );
+    finally {
+      if (cfgis != null) {
+        try { cfgis.close(); } catch (Exception xany) {}
+      }
     }
     enabled = true;
   }
@@ -144,7 +138,11 @@
   /** Stops all cores. */
   public void shutdown() {
     synchronized(cores) {
-      for( SolrCore core : cores.values() ) {
+      for(Map.Entry<String,CoreDescriptor> e : cores.entrySet()) {
+        SolrCore core = e.getValue().getCore();
+        if (core == null) continue;
+        String key = e.getKey();
+        if (core.getName().equals(key))
         core.close();
       }
       cores.clear();
@@ -165,11 +163,11 @@
     return instance;
   }
   
-  public SolrCore register( SolrCore core ) {
-    if( core == null ) {
+  public CoreDescriptor register( CoreDescriptor descr ) {
+    if( descr == null ) {
       throw new RuntimeException( "Can not register a null core." );
     }
-    String name = core.getName();
+    String name = descr.getName();
     if( name == null || 
         name.length() < 1 ||
         name.indexOf( '/'  ) >= 0 ||
@@ -177,16 +175,18 @@
       throw new RuntimeException( "Invalid core name: "+name );
     }
     
-    SolrCore old = cores.put(name, core);
+    CoreDescriptor old = cores.put(name, descr);
     if( old == null ) {
       log.info( "registering core: "+name );
-    } else {
+      return null;
+    } 
+    else {
       log.info( "replacing core: "+name );
+      return old;
     }
-    return old;
   }
-
-  public void swap(SolrCore c0, SolrCore c1) {
+  
+  public void swap(CoreDescriptor c0, CoreDescriptor c1) {
     if( c0 == null || c1 == null ) {
       throw new RuntimeException( "Can not swap a null core." );
     }
@@ -196,12 +196,45 @@
       cores.put(n0, c1);
       cores.put(n1, c0);
       c0.setName( n1 );
+      if (c0.getCore() != null)
+        c0.getCore().setName(n1);
       c1.setName( n0 );
+      if (c1.getCore() != null)
+        c1.getCore().setName(n0);
     }
     log.info( "swaped: "+c0.getName() + " with " + c1.getName() );
   }
 
   /**
+   * Creates a new core based on a descriptor.
+   *
+   * @param dcore a core descriptor
+   * @return the newly created core
+   * @throws javax.xml.parsers.ParserConfigurationException
+   * @throws java.io.IOException
+   * @throws org.xml.sax.SAXException
+   */
+  public SolrCore create(CoreDescriptor dcore)  throws ParserConfigurationException, IOException, SAXException {
+    // Make the instanceDir relative to the multicore instanceDir if not absolute
+    File idir = new File(dcore.getInstanceDir());
+    if (!idir.isAbsolute()) {
+      idir = new File(loader.getInstanceDir(), dcore.getInstanceDir());
+    }
+    String instanceDir = idir.getPath();
+    
+    // Initialize the solr config
+    SolrResourceLoader solrLoader = new SolrResourceLoader(instanceDir, libLoader);
+    SolrConfig config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
+    IndexSchema schema = new IndexSchema(config, dcore.getSchemaName(), null);
+    SolrCore core = new SolrCore(dcore.getName(), null, config, schema);
+    dcore.setCore(core);
+    
+    // Register the new core
+    CoreDescriptor old = this.register(dcore);
+    return core;
+  }
+  
+  /**
    * While the new core is loading, requests will continue to be dispatched to
    * and processed by the old core
    * 
@@ -210,36 +243,51 @@
    * @throws IOException
    * @throws SAXException
    */
-  public void reload(SolrCore core) throws ParserConfigurationException, IOException, SAXException 
-  {
-    SolrResourceLoader loader = new SolrResourceLoader( core.getResourceLoader().getInstanceDir() );
-    SolrConfig config = new SolrConfig( loader, core.getConfigFile(), null );
-    IndexSchema schema = new IndexSchema( config, core.getSchemaFile() );
-    SolrCore loaded = new SolrCore( core.getName(), core.getDataDir(), config, schema );
-    this.register( loaded );
-    
-    // TODO? -- add some kind of hook to close the core after all references are 
-    // gone...  is finalize() enough?
-  }
-
-  public void remove( String name ) 
-  {
-    cores.remove( name );
+  public void reload(CoreDescriptor dcore) throws ParserConfigurationException, IOException, SAXException {
+    create(new CoreDescriptor(dcore));
   }
     
-  public SolrCore getDefaultCore() {
-    return defaultCore;
+  // TODO? -- add some kind of hook to close the core after all references are 
+  // gone...  is finalize() enough?
+  public void remove( String name ) {
+    synchronized(cores) {
+      CoreDescriptor dcore = cores.remove( name );
+      if (dcore == null) {
+        return;
+      }
+      
+      SolrCore core = dcore.getCore();
+      if (core != null) {
+        core.close();
+      }
+    }
   }
   
   /**
    * @return a Collection of registered SolrCores
    */
   public Collection<SolrCore> getCores() {
+    java.util.List<SolrCore> l = new java.util.ArrayList<SolrCore>();
+    for(CoreDescriptor descr : this.cores.values()) {
+      if (descr.getCore() != null)
+        l.add(descr.getCore());
+    }
+    return l;
+  }
+  
+  public Collection<CoreDescriptor> getDescriptors() {
     return cores.values();
   }
   
   public SolrCore getCore(String name) {
-    return cores.get( name );
+    CoreDescriptor dcore = getDescriptor( name );
+    return (dcore == null) ? null : dcore.getCore();
+  }
+  
+  public CoreDescriptor getDescriptor(String name) {
+    synchronized(cores) {
+      return cores.get( name );
+    }
   }
   
   public boolean isEnabled() {
@@ -272,5 +320,123 @@
   
   public File getConfigFile() {
     return configFile;
+  }
+  
+  /** Persists the multicore config file. */
+  public void persist() {
+    File tmpFile = null;
+    try {
+      // write in temp first
+      tmpFile = File.createTempFile("multicore", ".xml", configFile.getParentFile());
+      java.io.FileOutputStream out = new java.io.FileOutputStream(tmpFile);
+      synchronized(cores) {
+        Writer writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
+        persist(writer);
+        writer.flush();
+        writer.close();
+        out.close();
+        // rename over origin or copy it it this fails
+        if (tmpFile.renameTo(configFile))
+          tmpFile = null;
+        else
+          fileCopy(tmpFile, configFile);
+      }
+    } 
+    catch(java.io.FileNotFoundException xnf) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, xnf);
+    } 
+    catch(java.io.IOException xio) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, xio);
+    } 
+    finally {
+      if (tmpFile != null) {
+        if (!tmpFile.delete())
+          tmpFile.deleteOnExit();
+      }
+    }
+  }
+  
+  /** Write the multicore configuration through a writer.*/
+  void persist(Writer writer) throws IOException {
+    writer.write("<?xml version='1.0' encoding='UTF-8'?>");
+    writer.write("\n");
+    writer.write("<multicore adminPath='");
+    XML.escapeAttributeValue(adminPath, writer);
+    writer.write('\'');
+    if (this.libDir != null) {
+      writer.write(" libDir='");
+      XML.escapeAttributeValue(libDir, writer);
+      writer.write('\'');
+    }
+    writer.write(" persistent='");
+    if (isPersistent()) {
+      writer.write("true'");
+    }
+    else {
+      writer.write("false'");
+    }
+    writer.write(">\n");
+    
+    // for all cores...(synchronized on cores by caller)
+    for (Map.Entry<String, CoreDescriptor> entry : cores.entrySet()) {
+      persist(writer, entry.getValue());
+    }
+    writer.write("</multicore>\n");
+  }
+  
+  /** Writes the multicore configuration node for a given core. */
+  void persist(Writer writer, CoreDescriptor dcore) throws IOException {
+    writer.write("  <core");
+    writer.write (" name='");
+    XML.escapeAttributeValue(dcore.getName(), writer);
+    writer.write("' instanceDir='");
+    XML.escapeAttributeValue(dcore.getInstanceDir(), writer);
+    writer.write('\'');
+    //write config (if not default)
+    String opt = dcore.getConfigName();
+    if (opt != null && !opt.equals(dcore.getDefaultConfigName())) {
+      writer.write(" config='");
+      XML.escapeAttributeValue(opt, writer);
+      writer.write('\'');
+    }
+    //write schema (if not default)
+    opt = dcore.getSchemaName();
+    if (opt != null && !opt.equals(dcore.getDefaultSchemaName())) {
+      writer.write(" schema='");
+      XML.escapeAttributeValue(opt, writer);
+      writer.write('\'');
+    }
+    writer.write("/>\n"); // core
+  }
+  
+  /** Copies a src file to a dest file:
+   *  used to circumvent the platform discrepancies regarding renaming files.
+   */
+  public static void fileCopy(File src, File dest) throws IOException {
+    IOException xforward = null;
+    FileInputStream fis =  null;
+    FileOutputStream fos = null;
+    FileChannel fcin = null;
+    FileChannel fcout = null;
+    try {
+      fis = new FileInputStream(src);
+      fos = new FileOutputStream(dest);
+      fcin = fis.getChannel();
+      fcout = fos.getChannel();
+      // do the file copy
+      fcin.transferTo(0, fcin.size(), fcout);
+    } 
+    catch(IOException xio) {
+      xforward = xio;
+    } 
+    finally {
+      if (fis   != null) try { fis.close(); fis = null; } catch(IOException xio) {}
+      if (fos   != null) try { fos.close(); fos = null; } catch(IOException xio) {}
+      if (fcin  != null && fcin.isOpen() ) try { fcin.close();  fcin = null;  } catch(IOException xio) {}
+      if (fcout != null && fcout.isOpen()) try { fcout.close(); fcout = null; } catch(IOException xio) {}
+    }
+    if (xforward != null) {
+      throw xforward;
+    }
   }
 }

Modified: lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrConfig.java Mon Mar  3 20:06:17 2008
@@ -18,7 +18,6 @@
 package org.apache.solr.core;
 
 import org.apache.solr.common.util.NamedList;
-import org.apache.solr.handler.PingRequestHandler;
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
 
@@ -52,19 +51,10 @@
 
   public static final String DEFAULT_CONF_FILE = "solrconfig.xml";
 
-  /**
-   * Singleton containing all configuration.
-   * Compatibility feature for single-core (pre-solr215 patch) code.
-   * Most usage should be converted by:
-   * - using the configuration directly when used in Abstract{Tokeinizer,TokenFilter}Factory.init().
-   * - getting the configuration through the owning core if accessible (SolrCore.getSolrConfig()).
-   * - getting the core by name then its configuration as above
-   */
+  // Compatibility feature for single-core (pre-solr{215,350} patch); should go away at solr-2.0
   @Deprecated
   public static SolrConfig config = null; 
 
-  public final String configFile;
-
   /**
    * Singleton keeping track of configuration errors
    */
@@ -73,30 +63,50 @@
   /** Creates a default instance from the solrconfig.xml. */
   public SolrConfig()
   throws ParserConfigurationException, IOException, SAXException {
-    this( new SolrResourceLoader(null), DEFAULT_CONF_FILE, null );
+    this( (SolrResourceLoader) null, DEFAULT_CONF_FILE, null );
   }
-  /** Creates a configuration instance from a file. */
-  public SolrConfig(String file)
+  
+  /** Creates a configuration instance from a configuration name.
+   * A default resource loader will be created (@see SolrResourceLoader)
+   *@param name the configuration name used by the loader
+   */
+  public SolrConfig(String name)
   throws ParserConfigurationException, IOException, SAXException {
-    this( new SolrResourceLoader(null), file, null);
+    this( (SolrResourceLoader) null, name, null);
   }
 
-  @Deprecated
-  public SolrConfig(String file, InputStream is)
+  /** Creates a configuration instance from a configuration name and stream.
+   * A default resource loader will be created (@see SolrResourceLoader).
+   * If the stream is null, the resource loader will open the configuration stream.
+   * If the stream is not null, no attempt to load the resource will occur (the name is not used).
+   *@param name the configuration name
+   *@param is the configuration stream
+   */
+  public SolrConfig(String name, InputStream is)
   throws ParserConfigurationException, IOException, SAXException {
-    this( new SolrResourceLoader(null), file, is );
+    this( (SolrResourceLoader) null, name, is );
   }
   
-  /** Creates a configuration instance from an input stream. */
-  public SolrConfig(String instanceDir, String file, InputStream is)
+  /** Creates a configuration instance from an instance directory, configuration name and stream.
+   *@param instanceDir the directory used to create the resource loader
+   *@param name the configuration name used by the loader if the stream is null
+   *@param is the configuration stream 
+   */
+  public SolrConfig(String instanceDir, String name, InputStream is)
   throws ParserConfigurationException, IOException, SAXException {
-    this(new SolrResourceLoader(instanceDir), file, is);
+    this(new SolrResourceLoader(instanceDir), name, is);
   }
   
-  SolrConfig(SolrResourceLoader loader, String file, InputStream is)
+   /** Creates a configuration instance from a resource loader, a configuration name and a stream.
+   * If the stream is null, the resource loader will open the configuration stream.
+   * If the stream is not null, no attempt to load the resource will occur (the name is not used).
+   *@param loader the resource loader
+   *@param name the configuration name
+   *@param is the configuration stream
+   */
+  SolrConfig(SolrResourceLoader loader, String name, InputStream is)
   throws ParserConfigurationException, IOException, SAXException {
-    super(loader, file, is, "/config/");
-    this.configFile = file;
+    super(loader, name, is, "/config/");
     defaultIndexConfig = new SolrIndexConfig(this, null, null);
     mainIndexConfig = new SolrIndexConfig(this, "mainIndex", defaultIndexConfig);
     
@@ -123,7 +133,7 @@
     pingQueryParams = readPingQueryParams(this);
 
     httpCachingConfig = new HttpCachingConfig(this);
-    Config.log.info("Loaded SolrConfig: " + file);
+    Config.log.info("Loaded SolrConfig: " + name);
     
     // TODO -- at solr 2.0. this should go away
     config = this;

Modified: lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java Mon Mar  3 20:06:17 2008
@@ -43,7 +43,6 @@
 import org.apache.solr.common.util.DOMUtil;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.handler.PingRequestHandler;
 import org.apache.solr.handler.component.DebugComponent;
 import org.apache.solr.handler.component.FacetComponent;
 import org.apache.solr.handler.component.HighlightComponent;
@@ -91,7 +90,6 @@
   private final SolrConfig solrConfig;
   private final IndexSchema schema;
   private final String dataDir;
-  private final String index_path;
   private final UpdateHandler updateHandler;
   private final long startTime;
   private final RequestHandlers reqHandlers;
@@ -118,23 +116,68 @@
     }
   }
 
-  public SolrConfig getSolrConfig() {
-    return solrConfig;
-  }
   
   /**
+   * The SolrResourceLoader used to load all resources for this core.
    * @since solr 1.3
    */
   public SolrResourceLoader getResourceLoader() {
     return solrConfig.getResourceLoader();
   }
 
+  /**
+   * Gets the configuration resource name used by this core instance.
+   * @since solr 1.3
+   */
+  public String getConfigResource() {
+    return solrConfig.getResourceName();
+  }
+  
+  /**
+   * Gets the configuration resource name used by this core instance.
+   * @see getConfigResource
+   */
+  @Deprecated
   public String getConfigFile() {
-    return solrConfig.configFile;
+    return solrConfig.getResourceName();
+  }
+  /**
+   * Gets the configuration object used by this core instance.
+   */
+  public SolrConfig getSolrConfig() {
+    return solrConfig;
   }
   
+  /**
+   * Gets the schema resource name used by this core instance.
+   * @since solr 1.3
+   */
+  public String getSchemaResource() {
+    return schema.getResourceName();
+  }
+
+  /**
+   * Gets the schema resource name used by this core instance.
+   * @see getSchemaResource
+   */
+  @Deprecated
   public String getSchemaFile() {
-    return schema.getSchemaFile();
+    return schema.getResourceName();
+  }
+  
+  /**
+   * Gets the schema object used by this core instance.
+   */
+  public IndexSchema getSchema() { 
+    return schema;
+  }
+  
+  public String getDataDir() {
+    return dataDir;
+  }
+  
+  public String getIndexDir() {
+    return dataDir + "index/";
   }
   
   public String getName() {
@@ -183,9 +226,6 @@
     newSearcherListeners = parseListener("//listener[@event=\"newSearcher\"]");
   }
 
-  public IndexSchema getSchema() { return schema; }
-  public String getDataDir() { return dataDir; }
-  public String getIndexDir() { return index_path; }
 
   // gets a non-caching searcher
   public SolrIndexSearcher newSearcher(String name) throws IOException {
@@ -305,19 +345,19 @@
       instance = this;   // set singleton
       this.setName( name );
       SolrResourceLoader loader = config.getResourceLoader();
-      if (dataDir ==null) {
-        dataDir = config.get("dataDir",loader.getInstanceDir()+"data");
-      }
+      if (dataDir == null)
+        dataDir = config.get("dataDir",loader.getInstanceDir()+"data/");
+      else
+        dataDir = SolrResourceLoader.normalizeDir(dataDir);
 
       log.info(logid+"Opening new SolrCore at " + loader.getInstanceDir() + ", dataDir="+dataDir);
 
       if (schema==null) {
-        schema = new IndexSchema(config, "schema.xml");
+        schema = new IndexSchema(config, IndexSchema.DEFAULT_SCHEMA_FILE, null);
       }
 
       this.schema = schema;
       this.dataDir = dataDir;
-      this.index_path = dataDir + "/" + "index";
       this.solrConfig = config;
       this.startTime = System.currentTimeMillis();
       this.maxWarmingSearchers = config.getInt("query/maxWarmingSearchers",Integer.MAX_VALUE);
@@ -665,7 +705,7 @@
     // if this fails, we need to decrement onDeckSearchers again.
     SolrIndexSearcher tmp;
     try {
-      tmp = new SolrIndexSearcher(this, schema, "main", index_path, true);
+      tmp = new SolrIndexSearcher(this, schema, "main", getIndexDir(), true);
     } catch (Throwable th) {
       synchronized(searcherLock) {
         onDeckSearchers--;

Modified: lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java Mon Mar  3 20:06:17 2008
@@ -70,7 +70,8 @@
    * <p>
    * This loader will delegate to the context classloader when possible,
    * otherwise it will attempt to resolve resources using any jar files
-   * found in the "lib/" directory in the "Solr Home" directory.
+   * found in the "lib/" directory in the specified instance directory.
+   * If the instance directory is not specified (=null), SolrResourceLoader#locateInstanceDir will provide one.
    * <p>
    */
   public SolrResourceLoader( String instanceDir, ClassLoader parent )
@@ -110,37 +111,55 @@
     this( instanceDir, null );
   }
   
-  protected static String normalizeDir(String path) {
-    if (path==null) return null;
-    if ( !(path.endsWith("/") || path.endsWith("\\")) ) {
-      path+='/';
-    }
-    return path;
+  /** Ensures a directory name allways ends with a '/'. */
+  public  static String normalizeDir(String path) {
+    return ( path != null && (!(path.endsWith("/") || path.endsWith("\\"))) )? path + '/' : path;
   }
 
   public String getConfigDir() {
     return instanceDir + "conf/";
   }
 
+  /** Opens a schema resource by its name.
+   * Override this method to customize loading schema resources.
+   *@return the stream for the named schema
+   */
+  public InputStream openSchema(String name) {
+    return openResource(name);
+  }
+  
+  /** Opens a config resource by its name.
+   * Override this method to customize loading config resources.
+   *@return the stream for the named configuration
+   */
+  public InputStream openConfig(String name) {
+    return openResource(name);
+  }
+  
+  /** Opens any resource by its name.
+   * By default, this will look in multiple locations to load the resource:
+   * $configDir/$resource (if resource is not absolute)
+   * $CWD/$resource
+   * otherwise, it will look for it in any jar accessible through the class loader.
+   * Override this method to customize loading resources.
+   *@return the stream for the named resource
+   */
   public InputStream openResource(String resource) {
     InputStream is=null;
-    
     try {
-      File f = new File(resource);
+      File f0 = new File(resource);
+      File f = f0;
       if (!f.isAbsolute()) {
-        // try $CWD/conf/
+        // try $CWD/$configDir/$resource
         f = new File(getConfigDir() + resource);
       }
       if (f.isFile() && f.canRead()) {
         return new FileInputStream(f);
-      } else {
-        // try $CWD
-        f = new File(resource);
-        if (f.isFile() && f.canRead()) {
-          return new FileInputStream(f);
-        }
+      } else if (f != f0) { // no success with $CWD/$configDir/$resource
+        if (f0.isFile() && f0.canRead())
+          return new FileInputStream(f0);
       }
-      
+      // delegate to the class loader (looking into $INSTANCE_DIR/lib jars)
       is = classLoader.getResourceAsStream(resource);
     } catch (Exception e) {
       throw new RuntimeException("Error opening " + resource, e);
@@ -257,7 +276,12 @@
     }
     waitingForResources.clear();
   }
-
+  /**
+   * Determines the instanceDir from the environment.
+   * Tries JNDI (java:comp/env/solr/home) then system property (solr.solr.home);
+   * if both fail, defaults to solr/
+   * @return the instance directory name
+   */
   /**
    * Finds the instanceDir based on looking up the value in one of three places:
    * <ol>

Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/MultiCoreHandler.java Mon Mar  3 20:06:17 2008
@@ -28,6 +28,7 @@
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.MultiCore;
 import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.CoreDescriptor;
 import org.apache.solr.handler.RequestHandlerBase;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryResponse;
@@ -64,6 +65,7 @@
       throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
           "MultiCore support must be enabled at startup." );
     }
+    boolean do_persist = false;
     
     // Pick the action
     SolrParams params = req.getParams();
@@ -78,68 +80,101 @@
       }
     }
     
-    // Select the core
     SolrCore core = null;
-    String cname = params.get( MultiCoreParams.CORE );
-    if( cname != null ) {
-      core = manager.getCore( cname );
-      if( core == null ) {
-        throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
-            "Unknown core: "+cname );
-      }
-    }
-    
-    // Handle a Status Request
+    // Handle a core creation
     //---------------------------------------------------------
-    if( action == MultiCoreAction.STATUS ) {
-      SolrCore defaultCore = manager.getDefaultCore();
-      NamedList<Object> status = new SimpleOrderedMap<Object>();
-      if( core == null ) {
-        for( SolrCore c : manager.getCores() ) {
-          status.add( c.getName(), getCoreStatus( c, c==defaultCore ) );
-        }
-      }
-      else {
-        status.add( core.getName(), getCoreStatus( core, core==defaultCore ) );
-      }
-      rsp.add( "status", status );
-    }
-    else if( core == null ) {
-      throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
-        "Action '"+action+"' requires a core name." );
+    if (action == MultiCoreAction.CREATE) {
+      CoreDescriptor dcore = new CoreDescriptor();
+      dcore.init(params.get(MultiCoreParams.NAME),
+                params.get(MultiCoreParams.INSTANCE_DIR));
+      
+      // fillup optional parameters
+      String opts = params.get(MultiCoreParams.CONFIG);
+      if (opts != null)
+        dcore.setConfigName(opts);
+      
+      opts = params.get(MultiCoreParams.SCHEMA);
+      if (opts != null)
+        dcore.setSchemaName(opts);
+      
+      core = manager.create(dcore);
+      rsp.add("core", core.getName());
+      do_persist = manager.isPersistent();
     }
     else {
-      switch( action ) {
-      
-      case RELOAD: {
-        manager.reload( core );
-        break;
-      } 
-
-      case SWAP: {
-        String name = required.get( MultiCoreParams.WITH );
-        SolrCore swap = manager.getCore( name );
-        if( swap == null ) {
+      // Select the core
+      String cname = params.get( MultiCoreParams.CORE );
+      if( cname != null ) {
+        core = manager.getCore(cname);
+        if( core == null ) {
           throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
-              "Unknown core: "+name );
+              "Unknown core: "+cname );
         }
-        manager.swap( core, swap );
-        break;
-      } 
-        
-      default:
-        throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
-            "TODO: IMPLEMENT: " + action );
       }
 
-      // Should we persist the changes?
-      if( params.getBool( MultiCoreParams.PERSISTENT, manager.isPersistent() ) ) {
-        rsp.add( "TODO", "SAVE THE CHANGES: "+manager.getConfigFile().getAbsolutePath() );
+      // Handle a Status Request
+      //---------------------------------------------------------
+      if( action == MultiCoreAction.STATUS ) {
+        do_persist = false; // no state change
+        NamedList<Object> status = new SimpleOrderedMap<Object>();
+        if( core == null ) {
+          for (CoreDescriptor d : manager.getDescriptors()) {
+            status.add(d.getName(), getCoreStatus( d.getCore() ) );
+          }
+        } 
+        else {
+          status.add(core.getName(), getCoreStatus(core) );
+        }
+        rsp.add( "status", status );
+      } 
+      else if (core == null) {
+        throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
+          "Action '"+action+"' requires a core name." );
+      } 
+      else {
+        // Handle all other
+        //---------------------------------------------------------
+        do_persist = params.getBool(MultiCoreParams.PERSISTENT, manager.isPersistent());
+        switch( action ) {
+          case RELOAD: {
+            manager.reload( manager.getDescriptor( core.getName() ) );
+            do_persist = false; // no change on reload
+            break;
+          }
+  
+          case SWAP: {
+            String name = required.get( MultiCoreParams.WITH );
+            CoreDescriptor swap = manager.getDescriptor( name );
+            
+            if( swap == null ) {
+              throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
+                  "Unknown core: "+name );
+            }
+            manager.swap( manager.getDescriptor( core.getName() ), swap );
+            break;
+          } 
+        
+          case PERSIST: {
+            do_persist = true;
+            break;
+          } 
+          
+          default: {
+            throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
+                "TODO: IMPLEMENT: " + action );
+          }
+        } // switch
       }
     }
+    
+    // Should we persist the changes?
+    if (do_persist) {
+      manager.persist();
+      rsp.add("saved", manager.getConfigFile().getAbsolutePath());
+    }
   }
   
-  private static NamedList<Object> getCoreStatus( SolrCore core, boolean isDefault ) throws IOException
+  private static NamedList<Object> getCoreStatus( SolrCore core ) throws IOException
   {
     NamedList<Object> info = new SimpleOrderedMap<Object>();
     info.add( "name", core.getName() );
@@ -147,7 +182,6 @@
     info.add( "dataDir", core.getDataDir() );
     info.add( "startTime", new Date( core.getStartTime() ) );
     info.add( "uptime", System.currentTimeMillis()-core.getStartTime() );
-    info.add( "isDefault", isDefault );
     RefCounted<SolrIndexSearcher> searcher = core.getSearcher();
     info.add( "index", LukeRequestHandler.getIndexInfo( searcher.get().getReader(), false ) );
     searcher.decref();

Modified: lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/schema/IndexSchema.java Mon Mar  3 20:06:17 2008
@@ -45,6 +45,7 @@
 import javax.xml.xpath.XPathFactory;
 import java.io.InputStream;
 import java.io.Reader;
+import java.io.IOException;
 import java.util.*;
 import java.util.logging.Logger;
 
@@ -59,7 +60,7 @@
 
   final static Logger log = Logger.getLogger(IndexSchema.class.getName());
   private final SolrConfig solrConfig;
-  private final String schemaFile;
+  private final String resourceName;
   private String name;
   private float version;
 
@@ -70,17 +71,33 @@
    * @see Config#openResource
    */
   @Deprecated
-  public IndexSchema(SolrConfig solrConfig, String schemaFile) {
-    this(solrConfig, solrConfig.getResourceLoader().openResource(schemaFile));
+  public IndexSchema(SolrConfig solrConfig, String name) {
+    this(solrConfig, name, null);
   }
-  
-  public IndexSchema(SolrConfig solrConfig, InputStream is) {
+    /**
+   * Constructs a schema using the specified resource name and stream.
+   * If the is stream is null, the resource loader will load the schema resource by name.
+   * @see SolrResourceLoader#openSchema
+   * By default, this follows the normal config path directory searching rules.
+   * @see Config#openResource
+   */
+  public IndexSchema(SolrConfig solrConfig, String name, InputStream is) {
     this.solrConfig = solrConfig;
-    this.schemaFile = DEFAULT_SCHEMA_FILE;
-    
-    readSchema(is);
-    
+    if (name == null)
+      name = DEFAULT_SCHEMA_FILE;
+    this.resourceName = name;
     SolrResourceLoader loader = solrConfig.getResourceLoader();
+    InputStream lis = is;
+    if (lis == null)
+      lis = loader.openSchema(name);
+    readSchema(lis);
+    if (lis != is) {
+      try {
+        lis.close();
+      }
+      catch(IOException xio) {} // ignore
+    }
+    
     loader.inform( loader );
   }
 
@@ -88,26 +105,42 @@
     return solrConfig;
   }
   
+  
+  /** Gets the name of the resource used to instantiate this schema. */
+  public String getResourceName() {
+    return resourceName;
+  }
+  
+  /** Gets the name of the schema as specified in the schema resource. */
+  public String getSchemaName() {
+    return name;
+  }
+  
+  float getVersion() {
+    return version;
+  }
+  
   /**
    * Direct access to the InputStream for the schemaFile used by this instance.
-   *
    * @see Config#openResource
    */
   @Deprecated
   public InputStream getInputStream() {
-    return solrConfig.getResourceLoader().openResource(schemaFile);
+    return solrConfig.getResourceLoader().openResource(resourceName);
   }
 
-  /** Gets the name of the schema file. */
+  /** Gets the name of the schema file.
+   * @see IndexSchema#getResourceName
+   */
+  @Deprecated
   public String getSchemaFile() {
-    return schemaFile;
+    return resourceName;
   }
 
-  float getVersion() {
-    return version;
-  }
-
-  /** The Name of this schema (as specified in the schema file) */
+  /** The Name of this schema (as specified in the schema file)
+   * @see IndexSchema#getSchemaName
+   */
+  @Deprecated
   public String getName() { return name; }
 
   private final HashMap<String, SchemaField> fields = new HashMap<String,SchemaField>();
@@ -282,6 +315,7 @@
       return getAnalyzer(fieldName).tokenStream(fieldName,reader);
     }
 
+    @Override
     public int getPositionIncrementGap(String fieldName) {
       return getAnalyzer(fieldName).getPositionIncrementGap(fieldName);
     }
@@ -289,6 +323,7 @@
 
 
   private class SolrQueryAnalyzer extends SolrIndexAnalyzer {
+    @Override
     protected HashMap<String,Analyzer> analyzerCache() {
       HashMap<String,Analyzer> cache = new HashMap<String,Analyzer>();
        for (SchemaField f : getFields().values()) {
@@ -298,6 +333,7 @@
       return cache;
     }
 
+    @Override
     protected Analyzer getAnalyzer(String fieldName)
     {
       Analyzer analyzer = analyzers.get(fieldName);
@@ -309,12 +345,9 @@
     log.info("Reading Solr Schema");
 
     try {
-      /***
-      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-      Document document = builder.parse(getInputStream());
-      ***/
-
-      Config schemaConf = new Config("schema", is, "/schema/");
+      // pass the config resource loader to avoid building an empty one for no reason:
+      // in the current case though, the stream is valid so we wont load the resource by name
+      Config schemaConf = new Config(solrConfig.getResourceLoader(), "schema", is, "/schema/");
       Document document = schemaConf.getDocument();
       final XPath xpath = schemaConf.getXPath();
 

Modified: lucene/solr/trunk/src/test/org/apache/solr/servlet/SolrRequestParserTest.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/servlet/SolrRequestParserTest.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/servlet/SolrRequestParserTest.java (original)
+++ lucene/solr/trunk/src/test/org/apache/solr/servlet/SolrRequestParserTest.java Mon Mar  3 20:06:17 2008
@@ -35,7 +35,6 @@
 import org.apache.solr.common.params.MultiMapSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.ContentStream;
-import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.util.AbstractSolrTestCase;
 
@@ -48,7 +47,7 @@
 
   public void setUp() throws Exception {
     super.setUp();
-    parser = new SolrRequestParsers( true, Long.MAX_VALUE );
+    parser = new SolrRequestParsers( h.getCore().getSolrConfig() );
   }
   
   public void testStreamBody() throws Exception

Modified: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/DirectSolrConnection.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/DirectSolrConnection.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/DirectSolrConnection.java (original)
+++ lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/DirectSolrConnection.java Mon Mar  3 20:06:17 2008
@@ -41,7 +41,7 @@
  * DirectSolrConnection provides an interface to solr that is similar to 
  * the the HTTP interface, but does not require an HTTP connection.
  * 
- * This class is designed to be as simple as possible and alow for more flexibility
+ * This class is designed to be as simple as possible and allow for more flexibility
  * in how you interface to solr.
  * 
  * @version $Id$
@@ -57,8 +57,7 @@
    */
   public DirectSolrConnection()
   {
-    core = SolrCore.getSolrCore();
-    parser = new SolrRequestParsers( true, Long.MAX_VALUE );
+    this( SolrCore.getSolrCore() );
   }
 
   /**
@@ -67,7 +66,7 @@
   public DirectSolrConnection( SolrCore c )
   {
     core = c;
-    parser = new SolrRequestParsers( true, Long.MAX_VALUE );
+    parser = new SolrRequestParsers( c.getSolrConfig() );
   }
 
   /**
@@ -99,16 +98,16 @@
       }
     }
     
-    // Initalize SolrConfig
+    // Initialize SolrConfig
     SolrConfig config = null;
     try {
       config = new SolrConfig(instanceDir, SolrConfig.DEFAULT_CONF_FILE, null);
       instanceDir = config.getResourceLoader().getInstanceDir();
 
       // If the Data directory is specified, initialize SolrCore directly
-      IndexSchema schema = new IndexSchema(config, instanceDir+"/conf/schema.xml");
+      IndexSchema schema = new IndexSchema(config, instanceDir+"/conf/schema.xml", null);
       core = new SolrCore( null, dataDir, config, schema );
-      parser = new SolrRequestParsers( true, Long.MAX_VALUE );
+      parser = new SolrRequestParsers( config );
     } 
     catch (Exception ee) {
       throw new RuntimeException(ee);

Modified: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrDispatchFilter.java Mon Mar  3 20:06:17 2008
@@ -21,6 +21,8 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.Collection;
+import java.util.WeakHashMap;
 import java.util.logging.Logger;
 import java.util.logging.Level;
 
@@ -35,7 +37,6 @@
 
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.core.Config;
 import org.apache.solr.core.MultiCore;
 import org.apache.solr.core.SolrConfig;
 import org.apache.solr.core.SolrCore;
@@ -49,6 +50,8 @@
 
 /**
  * This filter looks at the incoming URL maps them to handlers defined in solrconfig.xml
+ * 
+ * @since solr 1.2
  */
 public class SolrDispatchFilter implements Filter 
 {
@@ -56,10 +59,9 @@
   
   protected SolrCore singlecore;
   protected MultiCore multicore;
-  protected SolrRequestParsers parsers;
-  protected boolean handleSelect = false;
   protected String pathPrefix = null; // strip this from the beginning of a path
   protected String abortErrorMessage = null;
+  protected final WeakHashMap<SolrCore, SolrRequestParsers> parsers = new WeakHashMap<SolrCore, SolrRequestParsers>();
   protected String solrConfigFilename = null;
   
   public void init(FilterConfig config) throws ServletException 
@@ -72,8 +74,6 @@
       this.pathPrefix = config.getInitParameter( "path-prefix" );
       this.solrConfigFilename = config.getInitParameter("solrconfig-filename");
       
-      // Find a valid solr core
-      SolrCore core = null;
       multicore = MultiCore.getRegistry();
       if( multicore.isEnabled() ) {
         log.info( "Using existing multicore configuration" );
@@ -86,9 +86,18 @@
           multicore.load( instanceDir, multiconfig );
         }
       }
+      
+      abortOnConfigurationError = false;
       if( multicore.isEnabled() ) {
         singlecore = null;
-        core = multicore.getDefaultCore();
+        
+        // if any core aborts on startup, then abort
+        for( SolrCore c : multicore.getCores() ) {
+          if( c.getSolrConfig().getBool( "abortOnConfigurationError",false) ) {
+            abortOnConfigurationError = true;
+            break;
+          }
+        }
       }
       else {
         if (this.solrConfigFilename==null) {
@@ -96,28 +105,8 @@
         } else {
           singlecore = new SolrCore( null, null, new SolrConfig(this.solrConfigFilename), null);
         }
-        core = singlecore;
       }
-      
       log.info("user.dir=" + System.getProperty("user.dir"));
-      
-      // Read global configuration
-      // Only the first registered core configures the following attributes 
-      Config globalConfig = core.getSolrConfig();
-
-      long uploadLimitKB = globalConfig.getInt( 
-          "requestDispatcher/requestParsers/@multipartUploadLimitInKB", 2000 ); // 2MB default
-      
-      boolean enableRemoteStreams = globalConfig.getBool( 
-          "requestDispatcher/requestParsers/@enableRemoteStreaming", false ); 
-
-      parsers = new SolrRequestParsers( enableRemoteStreams, uploadLimitKB );
-      
-      // Let this filter take care of /select?xxx format
-      this.handleSelect = globalConfig.getBool( "requestDispatcher/@handleSelect", false ); 
-      
-      // should it keep going if we hit an error?
-      abortOnConfigurationError = globalConfig.getBool("abortOnConfigurationError",true);
     }
     catch( Throwable t ) {
       // catch this so our filter still works
@@ -197,50 +186,72 @@
         SolrRequestHandler handler = null;
         SolrCore core = singlecore;
         if( core == null ) {
-          // Perhaps this is a muli-core admin page?
+          // Perhaps this is a multi-core admin page?
+          if( path.equals( "/" ) ) {
+            chain.doFilter(request, response);
+            return;  
+          }
           if( path.equals( multicore.getAdminPath() ) ) {
             handler = multicore.getMultiCoreHandler();
+            
+            // pick a core to use for output
+            Collection<SolrCore> cores = multicore.getCores();
+            if( cores != null && cores.size() > 0 ) {
+              core = cores.iterator().next();
+            }
+            if( core == null ) {
+              throw new RuntimeException( "Can not find a valid core for the multicore admin handler" );
+            }
           }
           else {
             idx = path.indexOf( "/", 1 );
-            if( idx > 1 ) {
-              // try to get the corename as a request parameter first
-              String corename = path.substring( 1, idx );
-              path = path.substring( idx );
-              core = multicore.getCore( corename );
-              // invalid core name is ok.  It could fall through to some other request
+            if( idx <= 1 ) {
+              idx = path.length();
+            }
+            
+            // try to get the corename as a request parameter first
+            String corename = path.substring( 1, idx );
+            path = path.substring( idx );
+            core = multicore.getCore( corename );
+            
+            if( path.length() == 0 ) {
+              path = "/";
+            }
+            
+            if( core == null ) {
+              throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown core: "+corename );
             }
           }
         }
         
-        if( core != null ) {
-          // Only try to parse the handler *if* a valid core exists
-          // when multi-core is enabled, the path can lead to a null core.
-          if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid path
-            handler = core.getRequestHandler( path );
-          }
-          if( handler == null && handleSelect ) {
-            if( "/select".equals( path ) || "/select/".equals( path ) ) {
-              solrReq = parsers.parse( core, path, req );
-              String qt = solrReq.getParams().get( CommonParams.QT );
-              if( qt != null && qt.startsWith( "/" ) ) {
-                throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Invalid query type.  Do not use /select to access: "+qt);
-              }
-              handler = core.getRequestHandler( qt );
-              if( handler == null ) {
-                throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);
-              }
+        SolrRequestParsers parser = parsers.get( core );
+        if( parser == null ) {
+          parser = new SolrRequestParsers( core.getSolrConfig() );
+          parsers.put( core, parser );
+        }
+        
+        // Only try to parse the handler *if* a valid core exists
+        // when multi-core is enabled, the path can lead to a null core.
+        if( handler == null && path.length() > 1 ) { // don't match "" or "/" as valid path
+          handler = core.getRequestHandler( path );
+        }
+        if( handler == null && parser.isHandleSelect() ) {
+          if( "/select".equals( path ) || "/select/".equals( path ) ) {
+            solrReq = parser.parse( core, path, req );
+            String qt = solrReq.getParams().get( CommonParams.QT );
+            if( qt != null && qt.startsWith( "/" ) ) {
+              throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Invalid query type.  Do not use /select to access: "+qt);
+            }
+            handler = core.getRequestHandler( qt );
+            if( handler == null ) {
+              throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);
             }
           }
         }
         
-        if( handler != null ) {
-          if( core == null ) {
-            core = multicore.getDefaultCore();
-          }
-          
+        if( handler != null ) {          
           if( solrReq == null ) {
-            solrReq = parsers.parse( core, path, req );
+            solrReq = parser.parse( core, path, req );
           }
           
           final SolrConfig conf = core.getSolrConfig();
@@ -253,8 +264,7 @@
           // unless we have been explicitly told not to, do cache validation
           if (!conf.getHttpCachingConfig().isNever304()) {
             // if we've confirmed cache validation, return immediately
-            if (HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq,
-                                                            req,resp)) {
+            if (HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq, req,resp)) {
               return;
             }
           }
@@ -287,11 +297,11 @@
         // the servlet/jsp can retrieve it
         else {
           req.setAttribute("org.apache.solr.SolrCore", core);
-          
-          // Modify the request so each core gets its own /admin
+
+          // Let each core have its own admin page...
           if( singlecore == null && path.startsWith( "/admin" ) ) {
             req.getRequestDispatcher( path ).forward( request, response );
-            return;
+            return; 
           }
         }
       }
@@ -343,20 +353,6 @@
 
   //---------------------------------------------------------------------
   //---------------------------------------------------------------------
-
-  /**
-   * Should the filter handle /select even if it is not mapped in solrconfig.xml
-   * 
-   * This will use consistent error handling for /select?qt=xxx and /update/xml
-   * 
-   */
-  public boolean isHandleSelect() {
-    return handleSelect;
-  }
-
-  public void setHandleSelect(boolean handleSelect) {
-    this.handleSelect = handleSelect;
-  }
 
   /**
    * set the prefix for all paths.  This is useful if you want to apply the

Modified: lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrRequestParsers.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrRequestParsers.java?rev=633360&r1=633359&r2=633360&view=diff
==============================================================================
--- lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrRequestParsers.java (original)
+++ lucene/solr/trunk/src/webapp/src/org/apache/solr/servlet/SolrRequestParsers.java Mon Mar  3 20:06:17 2008
@@ -42,6 +42,7 @@
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.ContentStream;
 import org.apache.solr.common.util.ContentStreamBase;
+import org.apache.solr.core.Config;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.ServletSolrParams;
 import org.apache.solr.request.SolrQueryRequest;
@@ -60,17 +61,38 @@
   
   private HashMap<String, SolrRequestParser> parsers;
   private boolean enableRemoteStreams = false;
+  private boolean handleSelect = true;
   private StandardRequestParser standard;
   
-  public SolrRequestParsers( boolean enableRemoteStreams, long uploadLimitKB )
+  /**
+   * Pass in an xml configuration.  A null configuration will enable
+   * everythign with maximum values.
+   */
+  public SolrRequestParsers( Config globalConfig )
   {
-    this.enableRemoteStreams = enableRemoteStreams;
-   
+    long uploadLimitKB = 1048;  // 2MB default
+    if( globalConfig == null ) {
+      uploadLimitKB = Long.MAX_VALUE; 
+      enableRemoteStreams = true;
+      handleSelect = true;
+    }
+    else {
+      uploadLimitKB = globalConfig.getInt( 
+          "requestDispatcher/requestParsers/@multipartUploadLimitInKB", (int)uploadLimitKB );
+      
+      enableRemoteStreams = globalConfig.getBool( 
+          "requestDispatcher/requestParsers/@enableRemoteStreaming", false ); 
+  
+      // Let this filter take care of /select?xxx format
+      handleSelect = globalConfig.getBool( 
+          "requestDispatcher/@handleSelect", handleSelect ); 
+    }
+       
     MultipartRequestParser multi = new MultipartRequestParser( uploadLimitKB );
     RawRequestParser raw = new RawRequestParser();
     standard = new StandardRequestParser( multi, raw );
     
-    // I don't see a need to have this publically configured just yet
+    // I don't see a need to have this publicly configured just yet
     // adding it is trivial
     parsers = new HashMap<String, SolrRequestParser>();
     parsers.put( MULTIPART, multi );
@@ -178,6 +200,14 @@
       }
     }
     return new MultiMapSolrParams( map );
+  }
+
+  public boolean isHandleSelect() {
+    return handleSelect;
+  }
+
+  public void setHandleSelect(boolean handleSelect) {
+    this.handleSelect = handleSelect;
   }
 }
 



Mime
View raw message