You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by ry...@apache.org on 2008/07/26 02:20:44 UTC

svn commit: r679936 - in /lucene/solr/trunk: example/solr/conf/ src/java/org/apache/solr/core/ src/java/org/apache/solr/handler/ src/java/org/apache/solr/update/processor/ src/test/org/apache/solr/update/processor/ src/test/test-files/solr/conf/

Author: ryan
Date: Fri Jul 25 17:20:44 2008
New Revision: 679936

URL: http://svn.apache.org/viewvc?rev=679936&view=rev
Log:
SOLR-660 -- simplify the UpdateRequestProcessorFactory framework and use standard initialization techniques

Added:
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java
Removed:
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java
Modified:
    lucene/solr/trunk/example/solr/conf/solrconfig.xml
    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/CSVRequestHandler.java
    lucene/solr/trunk/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
    lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
    lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
    lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml

Modified: lucene/solr/trunk/example/solr/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/example/solr/conf/solrconfig.xml?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/example/solr/conf/solrconfig.xml (original)
+++ lucene/solr/trunk/example/solr/conf/solrconfig.xml Fri Jul 25 17:20:44 2008
@@ -610,25 +610,15 @@
        The response format differs from solr1.1 formatting and returns a standard error code.
        
        To enable solr1.1 behavior, remove the /update handler or change its path
-       
-       "update.processor.class" is the class name for the UpdateRequestProcessor.  It is initalized
-       only once.  This can not be changed for each request.
-    -->
-  <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" >
-    <!--
-    <str name="update.processor.class">org.apache.solr.handler.UpdateRequestProcessor</str>
     -->
-  </requestHandler>
+  <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" />
 
   <!--
    Analysis request handler.  Since Solr 1.3.  Use to returnhow a document is analyzed.  Useful
    for debugging and as a token server for other types of applications
    -->
-  <requestHandler name="/analysis" class="solr.AnalysisRequestHandler" >
-    <!--
-    <str name="update.processor.class">org.apache.solr.handler.UpdateRequestProcessor</str>
-    -->
-  </requestHandler>
+  <requestHandler name="/analysis" class="solr.AnalysisRequestHandler" />
+  
 
   <!-- CSV update handler, loaded on demand -->
   <requestHandler name="/update/csv" class="solr.CSVRequestHandler" startup="lazy" />

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=679936&r1=679935&r2=679936&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 Fri Jul 25 17:20:44 2008
@@ -40,7 +40,9 @@
 import org.apache.solr.update.DirectUpdateHandler;
 import org.apache.solr.update.SolrIndexWriter;
 import org.apache.solr.update.UpdateHandler;
-import org.apache.solr.update.processor.ChainedUpdateProcessorFactory;
+import org.apache.solr.update.processor.LogUpdateProcessorFactory;
+import org.apache.solr.update.processor.RunUpdateProcessorFactory;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
 import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
 import org.apache.solr.util.RefCounted;
 import org.apache.solr.util.plugin.AbstractPluginLoader;
@@ -52,6 +54,9 @@
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.*;
@@ -79,7 +84,7 @@
   private final RequestHandlers reqHandlers;
   private final SolrHighlighter highlighter;
   private final Map<String,SearchComponent> searchComponents;
-  private final Map<String,UpdateRequestProcessorFactory> updateProcessors;
+  private final Map<String,UpdateRequestProcessorChain> updateProcessorChains;
   private final Map<String,SolrInfoMBean> infoRegistry = new java.util.HashMap<String,SolrInfoMBean>();
   
   public long getStartTime() { return startTime; }
@@ -408,7 +413,7 @@
       this.searchComponents = loadSearchComponents( config );
 
       // Processors initialized before the handlers
-      updateProcessors = loadUpdateProcessors();
+      updateProcessorChains = loadUpdateProcessorChains();
       reqHandlers = new RequestHandlers(this);
       reqHandlers.initHandlersFromConfig( solrConfig );
   
@@ -458,30 +463,71 @@
   /**
    * Load the request processors configured in solrconfig.xml
    */
-  private Map<String, UpdateRequestProcessorFactory> loadUpdateProcessors() {
-    final Map<String,UpdateRequestProcessorFactory> map = new HashMap<String, UpdateRequestProcessorFactory>();
+  private Map<String,UpdateRequestProcessorChain> loadUpdateProcessorChains() {
+    final Map<String,UpdateRequestProcessorChain> map = new HashMap<String, UpdateRequestProcessorChain>();
     
-    // If this is a more general use-case, this could be a regular type
-    final SolrCore thiscore = this;
-    AbstractPluginLoader<UpdateRequestProcessorFactory> loader 
-      = new AbstractPluginLoader<UpdateRequestProcessorFactory>( "updateRequestProcessor" ) {
-
-      @Override
-      protected void init(UpdateRequestProcessorFactory plugin, Node node) throws Exception {
-        plugin.init( thiscore, node );
-      }
-
-      @Override
-      protected UpdateRequestProcessorFactory register(String name, UpdateRequestProcessorFactory plugin) throws Exception {
-        return map.put( name, plugin );
+    final String parsingErrorText = "Parsing Update Request Processor Chain";
+    UpdateRequestProcessorChain def = null;
+    
+    // This is kinda ugly, but at least it keeps the xpath logic in one place
+    // away from the Processors themselves.  
+    XPath xpath = solrConfig.getXPath();
+    NodeList nodes = (NodeList)solrConfig.evaluate("updateRequestProcessorChain", XPathConstants.NODESET);
+    boolean requireName = nodes.getLength() > 1;
+    if (nodes !=null ) {
+      for (int i=0; i<nodes.getLength(); i++) {
+        Node node = nodes.item(i);
+        String name       = DOMUtil.getAttr(node,"name", requireName?parsingErrorText:null);
+        boolean isDefault = "true".equals( DOMUtil.getAttr(node,"default", null ) );
+        
+        NodeList links = null;
+        try {
+          links = (NodeList)xpath.evaluate("processor", node, XPathConstants.NODESET);
+        } 
+        catch (XPathExpressionException e) {
+          throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,"Error reading processors",e,false);
+        }
+        if( links == null || links.getLength() < 1 ) {
+          throw new RuntimeException( "updateRequestProcessorChain require at least one processor");
+        }
+        
+        // keep a list of the factories...
+        final ArrayList<UpdateRequestProcessorFactory> factories = new ArrayList<UpdateRequestProcessorFactory>(links.getLength());
+        // Load and initialize the plugin chain
+        AbstractPluginLoader<UpdateRequestProcessorFactory> loader 
+            = new AbstractPluginLoader<UpdateRequestProcessorFactory>( "processor chain", false, false ) {
+          @Override
+          protected void init(UpdateRequestProcessorFactory plugin, Node node) throws Exception {
+            plugin.init( (node==null)?null:DOMUtil.childNodesToNamedList(node) );
+          }
+    
+          @Override
+          protected UpdateRequestProcessorFactory register(String name, UpdateRequestProcessorFactory plugin) throws Exception {
+            factories.add( plugin );
+            return null;
+          }
+        };
+        loader.load( solrConfig.getResourceLoader(), links );
+        
+        
+        UpdateRequestProcessorChain chain = new UpdateRequestProcessorChain( 
+            factories.toArray( new UpdateRequestProcessorFactory[factories.size()] ) );
+        if( isDefault || nodes.getLength()==1 ) {
+          def = chain;
+        }
+        if( name != null ) {
+          map.put(name, chain);
+        }
       }
-    };
-
-    NodeList nodes = (NodeList)solrConfig.evaluate("updateRequestProcessor/factory", XPathConstants.NODESET);
-    UpdateRequestProcessorFactory def = loader.load( solrConfig.getResourceLoader(), nodes ); 
+    }
+    
     if( def == null ) {
-      def = new ChainedUpdateProcessorFactory(); // the default
-      def.init( thiscore, null );
+      // construct the default chain
+      UpdateRequestProcessorFactory[] factories = new UpdateRequestProcessorFactory[] {
+        new RunUpdateProcessorFactory(),
+        new LogUpdateProcessorFactory()
+      };
+      def = new UpdateRequestProcessorChain( factories );
     }
     map.put( null, def );
     map.put( "", def );
@@ -489,16 +535,16 @@
   }
   
   /**
-   * @return an update processor registered to the given name.  Throw an exception if this factory is undefined
-   */
-  public UpdateRequestProcessorFactory getUpdateProcessorFactory( String name )
+   * @return an update processor registered to the given name.  Throw an exception if this chain is undefined
+   */    
+  public UpdateRequestProcessorChain getUpdateProcessingChain( final String name )
   {
-    UpdateRequestProcessorFactory factory = updateProcessors.get( name );
-    if( factory == null ) {
+    UpdateRequestProcessorChain chain = updateProcessorChains.get( name );
+    if( chain == null ) {
       throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
-          "unknown UpdateProcessorFactory: "+name );
+          "unknown UpdateRequestProcessorChain: "+name );
     }
-    return factory;
+    return chain;
   }
 
   /**

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=679936&r1=679935&r2=679936&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 Fri Jul 25 17:20:44 2008
@@ -47,6 +47,7 @@
 import org.apache.solr.request.QueryResponseWriter;
 import org.apache.solr.request.SolrRequestHandler;
 import org.apache.solr.schema.FieldType;
+import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
 import org.apache.solr.util.plugin.ResourceLoaderAware;
 import org.apache.solr.util.plugin.SolrCoreAware;
 import org.apache.solr.spelling.SpellingQueryConverter;
@@ -370,7 +371,8 @@
       SolrCoreAware.class, new Class[] {
         SolrRequestHandler.class,
         QueryResponseWriter.class,
-        SearchComponent.class
+        SearchComponent.class,
+        UpdateRequestProcessorFactory.class
       }
     );
 

Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/CSVRequestHandler.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/CSVRequestHandler.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/handler/CSVRequestHandler.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/handler/CSVRequestHandler.java Fri Jul 25 17:20:44 2008
@@ -28,6 +28,7 @@
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.update.*;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
 import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
 import org.apache.solr.update.processor.UpdateRequestProcessor;
 import org.apache.commons.csv.CSVStrategy;
@@ -47,10 +48,10 @@
 
   public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
     SolrParams params = req.getParams();
-    UpdateRequestProcessorFactory processorFactory =
-            req.getCore().getUpdateProcessorFactory( params.get( UpdateParams.UPDATE_PROCESSOR ) );
+    UpdateRequestProcessorChain processorChain =
+            req.getCore().getUpdateProcessingChain( params.get( UpdateParams.UPDATE_PROCESSOR ) );
 
-    UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, null);
+    UpdateRequestProcessor processor = processorChain.createProcessor(req, rsp);
 
     try {
       CSVLoader loader = new SingleThreadedCSVLoader(req, processor);

Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java Fri Jul 25 17:20:44 2008
@@ -50,8 +50,8 @@
 import org.apache.solr.update.AddUpdateCommand;
 import org.apache.solr.update.CommitUpdateCommand;
 import org.apache.solr.update.DeleteUpdateCommand;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
 import org.apache.solr.update.processor.UpdateRequestProcessor;
-import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
 
 /**
  * Add documents to solr using the STAX XML parser.
@@ -96,7 +96,7 @@
     catch( IllegalArgumentException ex ) {
       // Other implementations will likely throw this exception since "reuse-instance"
       // isimplementation specific.
-      log.fine( "Unable to set the 'reuse-instance' property for the input factory: "+inputFactory );
+      log.fine( "Unable to set the 'reuse-instance' property for the input chain: "+inputFactory );
     }
   }
   
@@ -106,10 +106,10 @@
     RequestHandlerUtils.addExperimentalFormatWarning( rsp );
     
     SolrParams params = req.getParams();
-    UpdateRequestProcessorFactory processorFactory = 
-      req.getCore().getUpdateProcessorFactory( params.get( UpdateParams.UPDATE_PROCESSOR ) );
+    UpdateRequestProcessorChain processingChain = 
+      req.getCore().getUpdateProcessingChain( params.get( UpdateParams.UPDATE_PROCESSOR ) );
     
-    UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, null);
+    UpdateRequestProcessor processor = processingChain.createProcessor(req, rsp);
     Iterable<ContentStream> streams = req.getContentStreams();
     if( streams == null ) {
       if( !RequestHandlerUtils.handleCommit(processor, params, false) ) {
@@ -381,13 +381,13 @@
       SolrCore core = SolrCore.getSolrCore();
 
       // Old style requests do not choose a custom handler
-      UpdateRequestProcessorFactory processorFactory = core.getUpdateProcessorFactory( null );
+      UpdateRequestProcessorChain processorFactory = core.getUpdateProcessingChain( null );
       
       SolrParams params = new MapSolrParams( new HashMap<String, String>() );
       SolrQueryRequestBase req = new SolrQueryRequestBase( core, params ) {};
       SolrQueryResponse rsp = new SolrQueryResponse(); // ignored
       XMLStreamReader parser = inputFactory.createXMLStreamReader(input);
-      UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, null);
+      UpdateRequestProcessor processor = processorFactory.createProcessor(req, rsp);
       this.processUpdate( processor, parser );
       processor.finish();
       output.write("<result status=\"0\"></result>");

Modified: lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java Fri Jul 25 17:20:44 2008
@@ -23,16 +23,13 @@
 import java.util.logging.Level;
 
 import org.apache.solr.common.params.SolrParams;
-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.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryResponse;
 import org.apache.solr.update.AddUpdateCommand;
 import org.apache.solr.update.CommitUpdateCommand;
 import org.apache.solr.update.DeleteUpdateCommand;
-import org.w3c.dom.Node;
 
 /**
  * A logging processor.  This keeps track of all commands that have passed through
@@ -47,9 +44,8 @@
   int maxNumToLog = 8;
   
   @Override
-  public void init( final SolrCore core, final Node node ) {
-    if( node != null ) {
-      NamedList<Object> args = DOMUtil.childNodesToNamedList( node );
+  public void init( final NamedList args ) {
+    if( args != null ) {
       SolrParams params = SolrParams.toSolrParams( args );
       maxNumToLog = params.getInt( "maxNumToLog", maxNumToLog );
     }
@@ -70,7 +66,6 @@
 class LogUpdateProcessor extends UpdateRequestProcessor {
   private final SolrQueryRequest req;
   private final SolrQueryResponse rsp;
-  private final UpdateRequestProcessor next;
   private final NamedList<Object> toLog;
 
   int numAdds;
@@ -83,9 +78,9 @@
   private final int maxNumToLog;
 
   public LogUpdateProcessor(SolrQueryRequest req, SolrQueryResponse rsp, LogUpdateProcessorFactory factory, UpdateRequestProcessor next) {
+    super( next );
     this.req = req;
     this.rsp = rsp;
-    this.next = next;
     maxNumToLog = factory.maxNumToLog;  // TODO: make configurable
     // TODO: make log level configurable as well, or is that overkill?
     // (ryan) maybe?  I added it mostly to show that it *can* be configurable

Modified: lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java Fri Jul 25 17:20:44 2008
@@ -19,7 +19,6 @@
 
 import java.io.IOException;
 
-import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryResponse;
 import org.apache.solr.update.AddUpdateCommand;
@@ -27,8 +26,6 @@
 import org.apache.solr.update.DeleteUpdateCommand;
 import org.apache.solr.update.DocumentBuilder;
 import org.apache.solr.update.UpdateHandler;
-import org.w3c.dom.Node;
-
 
 
 /**
@@ -39,18 +36,13 @@
 public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory 
 {
   @Override
-  public void init( final SolrCore core, final Node node ) {
-    
-  }
-
-  @Override
   public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) 
   {
     return new RunUpdateProcessor(req, next);
   }
 }
 
-class RunUpdateProcessor extends NoOpUpdateProcessor 
+class RunUpdateProcessor extends UpdateRequestProcessor 
 {
   private final SolrQueryRequest req;
   private final UpdateHandler updateHandler;

Modified: lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java Fri Jul 25 17:20:44 2008
@@ -33,17 +33,34 @@
  * Perhaps you continue adding an error message (without indexing the document)...
  * perhaps you throw an error and halt indexing (remove anything already indexed??)
  * 
- * This implementation (the default) passes the request command (as is) to the updateHandler
- * and adds debug info to the response.
+ * By default, this just passes the request to the next processor in the chain.
  * 
  * @since solr 1.3
  */
 public abstract class UpdateRequestProcessor {
   protected static Logger log = Logger.getLogger(UpdateRequestProcessor.class.getName());
 
-  public abstract void processAdd(AddUpdateCommand cmd) throws IOException;
-  public abstract void processDelete(DeleteUpdateCommand cmd) throws IOException;
-  public abstract void processCommit(CommitUpdateCommand cmd) throws IOException;
-  public abstract void finish() throws IOException;
+  protected final UpdateRequestProcessor next;
+
+  public UpdateRequestProcessor( UpdateRequestProcessor next) {
+    this.next = next;
+  }
+
+  public void processAdd(AddUpdateCommand cmd) throws IOException {
+    if (next != null) next.processAdd(cmd);
+  }
+
+  public void processDelete(DeleteUpdateCommand cmd) throws IOException {
+    if (next != null) next.processDelete(cmd);
+  }
+
+  public void processCommit(CommitUpdateCommand cmd) throws IOException
+  {
+    if (next != null) next.processCommit(cmd);
+  }
+
+  public void finish() throws IOException {
+    if (next != null) next.finish();    
+  }
 }
 

Added: lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java?rev=679936&view=auto
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java (added)
+++ lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java Fri Jul 25 17:20:44 2008
@@ -0,0 +1,61 @@
+/**
+ * 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.update.processor;
+
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrQueryResponse;
+
+/**
+ * An UpdateRequestProcessorFactory that constructs a chain of UpdateRequestProcessor.
+ * 
+ * This is the default implementation and can be configured via solrconfig.xml with:
+ * 
+ * <updateRequestProcessors name="key" default="true">
+ *   <processor class="PathToClass1" />
+ *   <processor class="PathToClass2" />
+ *   <processor class="solr.LogUpdateProcessorFactory" >
+ *     <int name="maxNumToLog">100</int>
+ *   </processor>
+ *   <processor class="solr.RunUpdateProcessorFactory" />
+ * </updateRequestProcessors>
+ * 
+ * @since solr 1.3
+ */
+public final class UpdateRequestProcessorChain 
+{
+  final UpdateRequestProcessorFactory[] chain;
+  
+  public UpdateRequestProcessorChain( UpdateRequestProcessorFactory[] chain ) {
+    this.chain = chain;
+  }
+
+  public UpdateRequestProcessor createProcessor(SolrQueryRequest req, SolrQueryResponse rsp) 
+  {
+    UpdateRequestProcessor processor = null;
+    UpdateRequestProcessor last = null;
+    for (int i = chain.length-1; i>=0; i--) {
+      processor = chain[i].getInstance(req, rsp, last);
+      last = processor == null ? last : processor;
+    }
+    return last;
+  }
+
+  public UpdateRequestProcessorFactory[] getFactories() {
+    return chain;
+  }
+}

Modified: lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java Fri Jul 25 17:20:44 2008
@@ -17,19 +17,24 @@
 
 package org.apache.solr.update.processor;
 
+import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryResponse;
-import org.w3c.dom.Node;
+import org.apache.solr.util.plugin.NamedListInitializedPlugin;
+import org.apache.solr.util.plugin.SolrCoreAware;
 
 /**
- * A factory to generate UpdateRequestProcessors for each request.  
+ * A factory to generate an UpdateRequestProcessor for each request.  
+ * 
+ * If the factory needs access to {@link SolrCore} in initialization, it could 
+ * implement {@link SolrCoreAware}
  * 
  * @since solr 1.3
  */
-public abstract class UpdateRequestProcessorFactory 
+public abstract class UpdateRequestProcessorFactory implements NamedListInitializedPlugin
 {    
-  public void init( final SolrCore core, final Node node )
+  public void init( NamedList args )
   {
     // could process the Node
   }

Modified: lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java (original)
+++ lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java Fri Jul 25 17:20:44 2008
@@ -17,14 +17,11 @@
 
 package org.apache.solr.update.processor;
 
-import org.apache.solr.common.util.DOMUtil;
 import org.apache.solr.common.util.NamedList;
-import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryResponse;
 import org.apache.solr.update.processor.UpdateRequestProcessor;
 import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
-import org.w3c.dom.Node;
 
 
 /**
@@ -35,11 +32,9 @@
   public NamedList args = null;
   
   @Override
-  public void init( final SolrCore core, final Node node )
+  public void init( NamedList args )
   {
-    if( node != null ) {
-      args = DOMUtil.childNodesToNamedList( node );
-    }
+    this.args = args;
   }
 
   @Override

Modified: lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java (original)
+++ lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java Fri Jul 25 17:20:44 2008
@@ -18,7 +18,7 @@
 package org.apache.solr.update.processor;
 
 import org.apache.solr.core.SolrCore;
-import org.apache.solr.update.processor.ChainedUpdateProcessorFactory;
+import org.apache.solr.update.processor.UpdateRequestProcessorChain;
 import org.apache.solr.util.AbstractSolrTestCase;
 
 /**
@@ -35,22 +35,21 @@
     SolrCore core = h.getCore();
 
     // make sure it loaded the factories
-    ChainedUpdateProcessorFactory chained = 
-      (ChainedUpdateProcessorFactory)core.getUpdateProcessorFactory( "standard" );
+    UpdateRequestProcessorChain chained = core.getUpdateProcessingChain( "standard" );
     
-    // Make sure it got 3 items and configured the Log factory ok
-    assertEquals( 3, chained.factory.length );
-    LogUpdateProcessorFactory log = (LogUpdateProcessorFactory)chained.factory[0];
+    // Make sure it got 3 items and configured the Log chain ok
+    assertEquals( 3, chained.chain.length );
+    LogUpdateProcessorFactory log = (LogUpdateProcessorFactory)chained.chain[0];
     assertEquals( 100, log.maxNumToLog );
     
     
-    CustomUpdateRequestProcessorFactory custom = 
-      (CustomUpdateRequestProcessorFactory)core.getUpdateProcessorFactory( null );
-
-    assertEquals( custom, core.getUpdateProcessorFactory( "" ) );
-    assertEquals( custom, core.getUpdateProcessorFactory( "custom" ) );
+    UpdateRequestProcessorChain custom = core.getUpdateProcessingChain( null );
+    CustomUpdateRequestProcessorFactory link = (CustomUpdateRequestProcessorFactory) custom.chain[0];
+    
+    assertEquals( custom, core.getUpdateProcessingChain( "" ) );
+    assertEquals( custom, core.getUpdateProcessingChain( "custom" ) );
     
     // Make sure the NamedListArgs got through ok
-    assertEquals( "{name={n8=88,n9=99}}", custom.args.toString() );
+    assertEquals( "{name={n8=88,n9=99}}", link.args.toString() );
   }
 }

Modified: lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml?rev=679936&r1=679935&r2=679936&view=diff
==============================================================================
--- lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml (original)
+++ lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml Fri Jul 25 17:20:44 2008
@@ -19,31 +19,31 @@
 
 <config>
 
- <updateRequestProcessor>
-   <factory name="standard" class="solr.ChainedUpdateProcessorFactory" >
-     <chain class="solr.LogUpdateProcessorFactory" >
-      <int name="maxNumToLog">100</int>
-     </chain>
-     <chain class="solr.CustomUpdateRequestProcessorFactory" >
-      <lst name="name">
-        <str name="n1">x1</str>
-        <str name="n2">x2</str>
-      </lst>
-     </chain>
-     <chain class="solr.CustomUpdateRequestProcessorFactory" >
-      <lst name="name">
-        <str name="nA">xA</str>
-        <str name="nA">xA</str>
-      </lst>
-     </chain>
-   </factory>
+<updateRequestProcessorChain name="standard">
+  <processor class="solr.LogUpdateProcessorFactory" >
+   <int name="maxNumToLog">100</int>
+  </processor>
+  <processor class="solr.CustomUpdateRequestProcessorFactory" >
+   <lst name="name">
+     <str name="n1">x1</str>
+     <str name="n2">x2</str>
+   </lst>
+  </processor>
+  <processor class="solr.CustomUpdateRequestProcessorFactory" >
+   <lst name="name">
+     <str name="nA">xA</str>
+     <str name="nA">xA</str>
+   </lst>
+  </processor>
+</updateRequestProcessorChain>
    
-   <factory name="custom" class="solr.CustomUpdateRequestProcessorFactory" default="true" >
+<updateRequestProcessorChain name="custom" default="true" >
+   <processor class="solr.CustomUpdateRequestProcessorFactory">
     <lst name="name">
       <str name="n8">88</str>
       <str name="n9">99</str>
     </lst>
-   </factory>
- </updateRequestProcessor>
+   </processor>
+</updateRequestProcessorChain>
 
 </config>