Author: ryan
Date: Fri Jul 13 09:48:00 2007
New Revision: 556064

URL: http://svn.apache.org/viewvc?view=rev&rev=556064
Log:
SOLR-269 -- adding UpdateRequestProcessor as a top level plugin managed by 
SolrCore.  This sets up a default processing chain.

Added:
    lucene/solr/trunk/src/java/org/apache/solr/update/processor/
    
lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java
   (with props)
    
lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
   (with props)
    
lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java
   (with props)
    
lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
   (with props)
    
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java
   (with props)
    
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
   (with props)
    lucene/solr/trunk/src/test/org/apache/solr/update/processor/
    
lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
   (with props)
    
lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
   (with props)
    lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml 
  (with props)
Removed:
    
lucene/solr/trunk/src/java/org/apache/solr/handler/UpdateRequestProcessor.java
    
lucene/solr/trunk/src/java/org/apache/solr/handler/UpdateRequestProcessorFactory.java
Modified:
    lucene/solr/trunk/CHANGES.txt
    lucene/solr/trunk/src/java/org/apache/solr/common/params/UpdateParams.java
    lucene/solr/trunk/src/java/org/apache/solr/core/Config.java
    lucene/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java
    lucene/solr/trunk/src/java/org/apache/solr/core/SolrCore.java
    lucene/solr/trunk/src/java/org/apache/solr/handler/RequestHandlerUtils.java
    
lucene/solr/trunk/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java
    lucene/solr/trunk/src/java/org/apache/solr/update/AddUpdateCommand.java
    
lucene/solr/trunk/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java

Modified: lucene/solr/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Fri Jul 13 09:48:00 2007
@@ -73,10 +73,10 @@
     within a single request.  For example, sending:
      <delete><id>1</id><id>2</id></delete> will delete both 1 and 2. (ryan)
 
-11. SOLR-269: Added UpdateRequestProcessor to the XmlUpdateRequestHandler.
-    This provides a reasonable place to pre-process documents after they are
-    parsed and before they are committed to the index.  This is a good place
-    for custom document manipulation or document based authorization. (ryan)
+11. SOLR-269: Added UpdateRequestProcessor plugin framework.  This provides
+    a reasonable place to process documents after they are parsed and 
+    before they are committed to the index.  This is a good place for custom 
+    document manipulation or document based authorization. (yonik, ryan)
 
 12. SOLR-260: Converting to a standard PluginLoader framework.  This reworks
     RequestHandlers, FieldTypes, and QueryResponseWriters to share the same

Modified: 
lucene/solr/trunk/src/java/org/apache/solr/common/params/UpdateParams.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/common/params/UpdateParams.java?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/common/params/UpdateParams.java 
(original)
+++ lucene/solr/trunk/src/java/org/apache/solr/common/params/UpdateParams.java 
Fri Jul 13 09:48:00 2007
@@ -39,4 +39,7 @@
   
   /** Commit everything after the command completes */
   public static String OPTIMIZE = "optimize";
+
+  /** Select the update processor to use.  A RequestHandler may or may not 
respect this parameter */
+  public static final String UPDATE_PROCESSOR = "update.processor";
 }

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?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/Config.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/Config.java Fri Jul 13 
09:48:00 2007
@@ -192,7 +192,7 @@
 
   private static final String project = "solr";
   private static final String base = "org.apache" + "." + project;
-  private static final String[] packages = 
{"","analysis.","schema.","handler.","search.","update.","core.","request.","util."};
+  private static final String[] packages = 
{"","analysis.","schema.","handler.","search.","update.","core.","request.","update.processor.","util."};
 
   public static Class findClass(String cname, String... subpackages) {
     ClassLoader loader = getClassLoader();

Modified: lucene/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java 
(original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/RequestHandlers.java Fri 
Jul 13 09:48:00 2007
@@ -126,7 +126,7 @@
   {
     final RequestHandlers handlers = this;
     AbstractPluginLoader<SolrRequestHandler> loader = 
-      new AbstractPluginLoader<SolrRequestHandler>( "[solrconfig.xml] 
requestHandler", true )
+      new AbstractPluginLoader<SolrRequestHandler>( "[solrconfig.xml] 
requestHandler", true, true )
     {
       @Override
       protected SolrRequestHandler create( String name, String className, Node 
node ) throws Exception

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?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- 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 13 
09:48:00 2007
@@ -57,7 +57,10 @@
 import org.apache.solr.update.SolrIndexConfig;
 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.UpdateRequestProcessorFactory;
 import org.apache.solr.util.RefCounted;
+import org.apache.solr.util.plugin.AbstractPluginLoader;
 import org.apache.solr.util.plugin.NamedListPluginLoader;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -79,6 +82,7 @@
   private static final long startTime = System.currentTimeMillis();
   private final RequestHandlers reqHandlers = new RequestHandlers();
   private final SolrHighlighter highlighter;
+  private final Map<String,UpdateRequestProcessorFactory> updateProcessors;
   
   public long getStartTime() { return startTime; }
 
@@ -209,6 +213,9 @@
       
       initWriters();
       
+      // Processors initialized before the handlers
+      updateProcessors = loadUpdateProcessors();
+      
       reqHandlers.initHandlersFromConfig( SolrConfig.config );
 
       // TODO? could select the highlighter implementation
@@ -228,6 +235,51 @@
         throw new RuntimeException(e);
       }
     }
+  }
+
+  /**
+   * Load the request processors configured in solrconfig.xml
+   */
+  private Map<String, UpdateRequestProcessorFactory> loadUpdateProcessors() {
+    final Map<String,UpdateRequestProcessorFactory> map = new HashMap<String, 
UpdateRequestProcessorFactory>();
+    
+    // If this is a more general use-case, this could be a regular type
+    AbstractPluginLoader<UpdateRequestProcessorFactory> loader 
+      = new AbstractPluginLoader<UpdateRequestProcessorFactory>( 
"updateRequestProcessor" ) {
+
+      @Override
+      protected void init(UpdateRequestProcessorFactory plugin, Node node) 
throws Exception {
+        plugin.init( node );
+      }
+
+      @Override
+      protected UpdateRequestProcessorFactory register(String name, 
UpdateRequestProcessorFactory plugin) throws Exception {
+        return map.put( name, plugin );
+      }
+    };
+
+    NodeList nodes = 
(NodeList)SolrConfig.config.evaluate("updateRequestProcessor/factory", 
XPathConstants.NODESET);
+    UpdateRequestProcessorFactory def = loader.load( nodes ); 
+    if( def == null ) {
+      def = new ChainedUpdateProcessorFactory(); // the default
+      def.init( null );
+    }
+    map.put( null, def );
+    map.put( "", def );
+    return map;
+  }
+  
+  /**
+   * @return an update processor registered to the given name.  Throw an 
exception if this factory is undefined
+   */
+  public UpdateRequestProcessorFactory getUpdateProcessorFactory( String name )
+  {
+    UpdateRequestProcessorFactory factory = updateProcessors.get( name );
+    if( factory == null ) {
+      throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
+          "unknown UpdateProcessorFactory: "+name );
+    }
+    return factory;
   }
 
   public void close() {

Modified: 
lucene/solr/trunk/src/java/org/apache/solr/handler/RequestHandlerUtils.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/RequestHandlerUtils.java?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/handler/RequestHandlerUtils.java 
(original)
+++ lucene/solr/trunk/src/java/org/apache/solr/handler/RequestHandlerUtils.java 
Fri Jul 13 09:48:00 2007
@@ -26,6 +26,7 @@
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryResponse;
 import org.apache.solr.update.CommitUpdateCommand;
+import org.apache.solr.update.processor.UpdateRequestProcessor;
 
 /**
  * Common helper functions for RequestHandlers
@@ -46,7 +47,12 @@
   /**
    * Check the request parameters and decide if it should commit or optimize.
    * If it does, it will check parameters for "waitFlush" and "waitSearcher"
+   * 
+   * Use the update processor version
+   * 
+   * @since solr 1.2
    */
+  @Deprecated
   public static boolean handleCommit( SolrQueryRequest req, SolrQueryResponse 
rsp, boolean force ) throws IOException
   {
     SolrParams params = req.getParams();
@@ -70,6 +76,30 @@
       //else {
       //  rsp.add( "commit", true );
       //}
+      return true;
+    }
+    return false;
+  }
+  
+
+  /**
+   * Check the request parameters and decide if it should commit or optimize.
+   * If it does, it will check parameters for "waitFlush" and "waitSearcher"
+   */
+  public static boolean handleCommit( UpdateRequestProcessor processor, 
SolrParams params, boolean force ) throws IOException
+  {
+    if( params == null ) {
+      params = new MapSolrParams( new HashMap<String, String>() ); 
+    }
+    
+    boolean optimize = params.getBool( UpdateParams.OPTIMIZE, false );
+    boolean commit   = params.getBool( UpdateParams.COMMIT,   false );
+    
+    if( optimize || commit || force ) {
+      CommitUpdateCommand cmd = new CommitUpdateCommand( optimize );
+      cmd.waitFlush    = params.getBool( UpdateParams.WAIT_FLUSH,    
cmd.waitFlush    );
+      cmd.waitSearcher = params.getBool( UpdateParams.WAIT_SEARCHER, 
cmd.waitSearcher );
+      processor.processCommit( cmd );
       return true;
     }
     return false;

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?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- 
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 13 09:48:00 2007
@@ -37,11 +37,11 @@
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.params.MapSolrParams;
 import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.UpdateParams;
 import org.apache.solr.common.util.ContentStream;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.common.util.XML;
-import org.apache.solr.core.Config;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequestBase;
@@ -49,26 +49,18 @@
 import org.apache.solr.update.AddUpdateCommand;
 import org.apache.solr.update.CommitUpdateCommand;
 import org.apache.solr.update.DeleteUpdateCommand;
+import org.apache.solr.update.processor.UpdateRequestProcessor;
+import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
 
 /**
  * Add documents to solr using the STAX XML parser.
- * 
- * To change the UpdateRequestProcessor implementation, add the configuration 
parameter:
- * 
- *  <requestHandler name="/update" class="solr.StaxUpdateRequestHandler" >
- *    <str 
name="update.processor.class">org.apache.solr.handler.UpdateRequestProcessor</str>
- *    <lst name="update.processor.args">
- *     ... (optionally pass in arguments to the factory init method) ...
- *    </lst> 
- *  </requestHandler>
  */
 public class XmlUpdateRequestHandler extends RequestHandlerBase
 {
   public static Logger log = 
Logger.getLogger(XmlUpdateRequestHandler.class.getName());
 
-  public static final String UPDATE_PROCESSOR_FACTORY = 
"update.processor.factory";
-  public static final String UPDATE_PROCESSOR_ARGS    = 
"update.processor.args";
-  
+  public static final String UPDATE_PROCESSOR = "update.processor";
+
   // XML Constants
   public static final String ADD = "add";
   public static final String DELETE = "delete";
@@ -76,7 +68,6 @@
   public static final String COMMIT = "commit";
   public static final String WAIT_SEARCHER = "waitSearcher";
   public static final String WAIT_FLUSH = "waitFlush";
-  public static final String MODE = "mode";
   
   public static final String OVERWRITE = "overwrite";
   public static final String OVERWRITE_COMMITTED = "overwriteCommitted"; // 
@Deprecated
@@ -84,7 +75,6 @@
   public static final String ALLOW_DUPS = "allowDups"; 
   
   private XMLInputFactory inputFactory;
-  private UpdateRequestProcessorFactory processorFactory;
   
   @SuppressWarnings("unchecked")
   @Override
@@ -92,68 +82,60 @@
   {
     super.init(args);
     inputFactory = BaseXMLInputFactory.newInstance();
-  
-    // Initialize the UpdateRequestProcessorFactory
-    NamedList<Object> factoryargs = null;
-    if( args != null ) {
-      String className = (String)args.get( UPDATE_PROCESSOR_FACTORY );
-      factoryargs = (NamedList<Object>)args.get( UPDATE_PROCESSOR_ARGS );
-      if( className != null ) {
-        processorFactory = (UpdateRequestProcessorFactory)Config.newInstance( 
className, new String[]{} );
-      }
-    }
-    if( processorFactory == null ) {
-      processorFactory = new UpdateRequestProcessorFactory();
-    }
-    processorFactory.init( factoryargs );
   }
   
   @Override
   public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) 
throws Exception 
   {
+    RequestHandlerUtils.addExperimentalFormatWarning( rsp );
+    
+    SolrParams params = req.getParams();
+    UpdateRequestProcessorFactory processorFactory = 
+      req.getCore().getUpdateProcessorFactory( params.get( 
UpdateParams.UPDATE_PROCESSOR ) );
+    
+    UpdateRequestProcessor processor = processorFactory.getInstance(req, rsp, 
null);
     Iterable<ContentStream> streams = req.getContentStreams();
     if( streams == null ) {
-      if( !RequestHandlerUtils.handleCommit(req, rsp, false) ) {
+      if( !RequestHandlerUtils.handleCommit(processor, params, false) ) {
         throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "missing 
content stream" );
       }
-      return;
     }
-    
-    RequestHandlerUtils.addExperimentalFormatWarning( rsp );
-    
-    // Cycle through each stream
-    for( ContentStream stream : req.getContentStreams() ) {
-      Reader reader = stream.getReader();
-      try {
-        NamedList out = this.update( req, req.getCore(), reader );
-        rsp.add( "update", out );
-      }
-      finally {
-        IOUtils.closeQuietly(reader);
+    else {
+      // Cycle through each stream
+      for( ContentStream stream : req.getContentStreams() ) {
+        Reader reader = stream.getReader();
+        try {
+          XMLStreamReader parser = inputFactory.createXMLStreamReader(reader);
+          this.processUpdate( processor, parser );
+        }
+        finally {
+          IOUtils.closeQuietly(reader);
+        }
       }
+      
+      // Perhaps commit from the parameters
+      RequestHandlerUtils.handleCommit( processor, params, false );
     }
     
-    // perhaps commit when we are done
-    RequestHandlerUtils.handleCommit(req, rsp, false);
+    // finish the request
+    processor.finish(); 
   }
     
   /**
    * @since solr 1.2
    */
-  NamedList<Object> processUpdate( SolrQueryRequest req, SolrCore core, 
XMLStreamReader parser)
+  void processUpdate( UpdateRequestProcessor processor, XMLStreamReader parser)
     throws XMLStreamException, IOException, FactoryConfigurationError,
           InstantiationException, IllegalAccessException,
           TransformerConfigurationException 
   {
-    UpdateRequestProcessor processor = processorFactory.getInstance( req );
-    
-    AddUpdateCommand addCmd = null;   
+    AddUpdateCommand addCmd = null;
     while (true) {
       int event = parser.next();
       switch (event) {
         case XMLStreamConstants.END_DOCUMENT:
           parser.close();
-          return processor.finish();
+          return;
 
         case XMLStreamConstants.START_ELEMENT:
           String currTag = parser.getLocalName();
@@ -170,8 +152,6 @@
               String attrVal = parser.getAttributeValue(i);
               if (OVERWRITE.equals(attrName)) {
                 overwrite = StrUtils.parseBoolean(attrVal);
-//              } else if (MODE.equals(attrName)) {
-//                addCmd.mode = 
SolrPluginUtils.parseAndValidateFieldModes(attrVal,schema);
               } else if (ALLOW_DUPS.equals(attrName)) {
                 overwrite = !StrUtils.parseBoolean(attrVal);
               } else if ( OVERWRITE_PENDING.equals(attrName) ) {
@@ -197,9 +177,9 @@
           } 
           else if ("doc".equals(currTag)) {
             log.finest("adding doc...");
-            addCmd.indexedId = null;
-            SolrInputDocument doc = readDoc( parser );
-            processor.processAdd( addCmd, doc );
+            addCmd.clear();
+            addCmd.solrDoc = readDoc( parser );
+            processor.processAdd(addCmd);
           } 
           else if ( COMMIT.equals(currTag) || OPTIMIZE.equals(currTag)) {
             log.finest("parsing " + currTag);
@@ -371,14 +351,6 @@
   }
 
   /**
-   * @since solr 1.2
-   */
-  public NamedList<Object> update( SolrQueryRequest req, SolrCore core, Reader 
reader) throws Exception {
-    XMLStreamReader parser = inputFactory.createXMLStreamReader(reader);
-    return processUpdate( req, core, parser);
-  }
-
-  /**
    * A Convenience method for getting back a simple XML string indicating
    * success or failure from an XML formated Update (from the Reader)
    * 
@@ -388,9 +360,17 @@
   public void doLegacyUpdate(Reader input, Writer output) {
     try {
       SolrCore core = SolrCore.getSolrCore();
+
+      // Old style requests do not choose a custom handler
+      UpdateRequestProcessorFactory processorFactory = 
core.getUpdateProcessorFactory( null );
+      
       SolrParams params = new MapSolrParams( new HashMap<String, String>() );
       SolrQueryRequestBase req = new SolrQueryRequestBase( core, params ) {};
-      this.update( req, SolrCore.getSolrCore(), input);
+      SolrQueryResponse rsp = new SolrQueryResponse(); // ignored
+      XMLStreamReader parser = inputFactory.createXMLStreamReader(input);
+      UpdateRequestProcessor processor = processorFactory.getInstance(req, 
rsp, null);
+      this.processUpdate( processor, parser );
+      processor.finish();
       output.write("<result status=\"0\"></result>");
     } 
     catch (Exception ex) {

Modified: 
lucene/solr/trunk/src/java/org/apache/solr/update/AddUpdateCommand.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/AddUpdateCommand.java?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/update/AddUpdateCommand.java 
(original)
+++ lucene/solr/trunk/src/java/org/apache/solr/update/AddUpdateCommand.java Fri 
Jul 13 09:48:00 2007
@@ -18,6 +18,12 @@
 package org.apache.solr.update;
 
 import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.SolrInputField;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.SchemaField;
+
 /**
  * @version $Id$
  */
@@ -26,16 +32,80 @@
    // it will be obtained from the doc.
    public String indexedId;
 
+   // The Lucene document to be indexed
    public Document doc;
+
+   // Higher level SolrInputDocument, normally used to construct the Lucene 
Document
+   // to index.
+   public SolrInputDocument solrDoc;
+
    public boolean allowDups;
    public boolean overwritePending;
    public boolean overwriteCommitted;
 
+   /** Reset state to reuse this object with a different document in the same 
request */
+   public void clear() {
+     doc = null;
+     solrDoc = null;
+     indexedId = null;
+   }
+
+   public SolrInputDocument getSolrInputDocument() {
+     return solrDoc;
+   }
+
+   public Document getLuceneDocument(IndexSchema schema) {
+     if (doc == null && solrDoc != null) {
+       // TODO??  build the doc from the SolrDocument?
+     }
+     return doc;    
+   }
+
+   public String getIndexedId(IndexSchema schema) {
+     if (indexedId == null) {
+       SchemaField sf = schema.getUniqueKeyField();
+       if (sf != null) {
+         if (doc != null) {
+           schema.getUniqueKeyField();
+           Field storedId = doc.getField(sf.getName());
+           indexedId = sf.getType().storedToIndexed(storedId);
+         }
+         if (solrDoc != null) {
+           SolrInputField field = solrDoc.getField(sf.getName());
+           if (field != null) {
+             indexedId = sf.getType().toInternal( 
field.getFirstValue().toString() );
+           }
+         }
+       }
+     }
+     return indexedId;
+   }
+
+   public String getPrintableId(IndexSchema schema) {
+     SchemaField sf = schema.getUniqueKeyField();
+     if (indexedId != null) {
+       return 
schema.getUniqueKeyField().getType().indexedToReadable(indexedId);
+     }
+
+     if (doc != null) {
+       return schema.printableUniqueKey(doc);
+     }
+
+     if (solrDoc != null) {
+       SolrInputField field = solrDoc.getField(sf.getName());
+       if (field != null) {
+         return field.getFirstValue().toString();
+       }
+     }
+     return "(null)";
+   }
+
    public AddUpdateCommand() {
      super("add");
    }
 
-   public String toString() {
+   @Override
+  public String toString() {
      StringBuilder sb = new StringBuilder(commandName);
      sb.append(':');
      if (indexedId !=null) sb.append("id=").append(indexedId);

Added: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java
 (added)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,102 @@
+/**
+ * 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 java.util.ArrayList;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrQueryResponse;
+import org.apache.solr.util.plugin.AbstractPluginLoader;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * An UpdateRequestProcessorFactory that constructs a chain of 
UpdateRequestProcessor.
+ * 
+ * This is the default implementation and can be configured via solrconfig.xml 
with:
+ * 
+ * <updateRequestProcessor>
+ *   <factory name="standard" class="solr.ChainedUpdateProcessorFactory" >
+ *     <chain class="PathToClass1" />
+ *     <chain class="PathToClass2" />
+ *     <chain class="solr.LogUpdateProcessorFactory" >
+ *      <int name="maxNumToLog">100</int>
+ *     </chain>
+ *     <chain class="solr.RunUpdateProcessorFactory" />
+ *   </factory>
+ * </updateRequestProcessor>
+ * 
+ * @since solr 1.3
+ */
+public class ChainedUpdateProcessorFactory extends 
UpdateRequestProcessorFactory 
+{
+  UpdateRequestProcessorFactory[] factory;
+  
+  @Override
+  public void init( Node node ) {
+    final ArrayList<UpdateRequestProcessorFactory> factories = new 
ArrayList<UpdateRequestProcessorFactory>();
+    if( node != null ) {
+      // 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 );
+        }
+  
+        @Override
+        protected UpdateRequestProcessorFactory register(String name, 
UpdateRequestProcessorFactory plugin) throws Exception {
+          factories.add( plugin );
+          return null;
+        }
+      };
+      
+      XPath xpath = XPathFactory.newInstance().newXPath();
+      try {
+        loader.load( (NodeList) xpath.evaluate( "chain", node, 
XPathConstants.NODESET ) );
+      } 
+      catch (XPathExpressionException e) {
+        throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
+            "Error loading processor chain: " + node,e,false);
+      }
+    }
+    
+    // If not configured, make sure it has the default settings
+    if( factories.size() < 1 ) {
+      factories.add( new RunUpdateProcessorFactory() );
+      factories.add( new LogUpdateProcessorFactory() );
+    }
+    factory = factories.toArray( new 
UpdateRequestProcessorFactory[factories.size()] );
+  }
+
+  @Override
+  public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
SolrQueryResponse rsp, UpdateRequestProcessor next) 
+  {
+    UpdateRequestProcessor processor = null;
+    for (int i = factory.length-1; i>=0; i--) {
+      processor = factory[i].getInstance(req, rsp, processor);
+    }
+    return processor;
+  }
+}

Propchange: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/ChainedUpdateProcessorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: 
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?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
 (added)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,161 @@
+/**
+ * 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 java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+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.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
+ * the chain and prints them on finish();
+ * 
+ * If the Log level is not INFO the processor will not be created or added to 
the chain
+ * 
+ * @since solr 1.3
+ */
+public class LogUpdateProcessorFactory extends UpdateRequestProcessorFactory {
+  
+  int maxNumToLog = 8;
+  
+  @Override
+  public void init( Node node ) {
+    if( node != null ) {
+      NamedList<Object> args = DOMUtil.childNodesToNamedList( node );
+      SolrParams params = SolrParams.toSolrParams( args );
+      maxNumToLog = params.getInt( "maxNumToLog", maxNumToLog );
+    }
+  }
+
+  @Override
+  public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
SolrQueryResponse rsp, UpdateRequestProcessor next) {
+    boolean doLog = LogUpdateProcessor.log.isLoggable(Level.INFO);
+    LogUpdateProcessor.log.severe("Will Log=" + doLog);
+    if( doLog ) {
+      // only create the log processor if we will use it
+      return new LogUpdateProcessor(req, rsp, this, next);
+    }
+    return null;
+  }
+}
+
+class LogUpdateProcessor extends UpdateRequestProcessor {
+  private final SolrQueryRequest req;
+  private final SolrQueryResponse rsp;
+  private final UpdateRequestProcessor next;
+  private final NamedList<Object> toLog;
+
+  int numAdds;
+  int numDeletes;
+
+  // hold on to the added list for logging and the response
+  private List<String> adds;
+  private List<String> deletes;
+
+  private final int maxNumToLog;
+
+  public LogUpdateProcessor(SolrQueryRequest req, SolrQueryResponse rsp, 
LogUpdateProcessorFactory factory, UpdateRequestProcessor 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
+
+    this.toLog = new NamedList<Object>();
+  }
+  
+  @Override
+  public void processAdd(AddUpdateCommand cmd) throws IOException {
+    if (next != null) next.processAdd(cmd);
+
+    // Add a list of added id's to the response
+    if (adds == null) {
+      adds = new ArrayList<String>();
+      toLog.add("add",adds);
+    }
+
+    if (adds.size() < maxNumToLog) {
+      adds.add(cmd.getPrintableId(req.getSchema()));
+    }
+
+    numAdds++;
+  }
+
+  @Override
+  public void processDelete( DeleteUpdateCommand cmd ) throws IOException {
+    if (next != null) next.processDelete(cmd);
+
+    if (cmd.id != null) {
+      if (deletes == null) {
+        deletes = new ArrayList<String>();
+        toLog.add("delete",deletes);
+      }
+      if (deletes.size() < maxNumToLog) {
+        deletes.add(cmd.id);
+      }
+    } else {
+      if (toLog.size() < maxNumToLog) {
+        toLog.add("deleteByQuery", cmd.query);
+      }
+    }
+    numDeletes++;
+  }
+
+  @Override
+  public void processCommit( CommitUpdateCommand cmd ) throws IOException {
+    if (next != null) next.processCommit(cmd);
+    
+    toLog.add(cmd.optimize ? "optimize" : "commit", "");
+  }
+
+
+  @Override
+  public void finish() throws IOException {
+    if (next != null) next.finish();
+    
+    // TODO: right now, update requests are logged twice...
+    // this will slow down things compared to Solr 1.2
+    // we should have extra log info on the SolrQueryResponse, to
+    // be logged by SolrCore
+    
+    // if id lists were truncated, show how many more there were
+    if (numAdds > maxNumToLog) {
+      adds.add("...(" + (numAdds-adds.size()) + " more)");
+    }
+    if (numDeletes > maxNumToLog) {
+      deletes.add("...(" + (numDeletes-deletes.size()) + " more)");
+    }
+    long elapsed = rsp.getEndTime() - req.getStartTime();
+    log.info( ""+toLog + " 0 " + (elapsed) );
+  }
+}
+
+
+

Propchange: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java
 (added)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,63 @@
+/**
+ * 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 java.io.IOException;
+
+import org.apache.solr.update.AddUpdateCommand;
+import org.apache.solr.update.CommitUpdateCommand;
+import org.apache.solr.update.DeleteUpdateCommand;
+
+
+/**
+ * A simple processor that does nothing but passes on the command to the next
+ * processor in the chain.  
+ * 
+ * @since solr 1.3
+ */
+public abstract class NoOpUpdateProcessor extends UpdateRequestProcessor 
+{
+  protected final UpdateRequestProcessor next;
+
+  public NoOpUpdateProcessor( UpdateRequestProcessor next) {
+    this.next = next;
+  }
+
+  @Override
+  public void processAdd(AddUpdateCommand cmd) throws IOException {
+    if (next != null) next.processAdd(cmd);
+  }
+
+  @Override
+  public void processDelete(DeleteUpdateCommand cmd) throws IOException {
+    if (next != null) next.processDelete(cmd);
+  }
+
+  @Override
+  public void processCommit(CommitUpdateCommand cmd) throws IOException
+  {
+    if (next != null) next.processCommit(cmd);
+  }
+
+  @Override
+  public void finish() throws IOException {
+    if (next != null) next.finish();    
+  }
+}
+
+

Propchange: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/NoOpUpdateProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: 
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?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
 (added)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,89 @@
+/**
+ * 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 java.io.IOException;
+
+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.apache.solr.update.DocumentBuilder;
+import org.apache.solr.update.UpdateHandler;
+import org.w3c.dom.Node;
+
+
+
+/**
+ * Pass the command to the UpdateHandler without any modifications
+ * 
+ * @since solr 1.3
+ */
+public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory 
+{
+  @Override
+  public void init( Node node ) {
+    
+  }
+
+  @Override
+  public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
SolrQueryResponse rsp, UpdateRequestProcessor next) 
+  {
+    return new RunUpdateProcessor(req, next);
+  }
+}
+
+class RunUpdateProcessor extends NoOpUpdateProcessor 
+{
+  private final SolrQueryRequest req;
+  private final UpdateHandler updateHandler;
+
+  public RunUpdateProcessor(SolrQueryRequest req, UpdateRequestProcessor next) 
{
+    super( next );
+    this.req = req;
+    this.updateHandler = req.getCore().getUpdateHandler();
+  }
+
+  @Override
+  public void processAdd(AddUpdateCommand cmd) throws IOException {
+    cmd.doc = DocumentBuilder.toDocument(cmd.getSolrInputDocument(), 
req.getSchema());
+    updateHandler.addDoc(cmd);
+    super.processAdd(cmd);
+  }
+
+  @Override
+  public void processDelete(DeleteUpdateCommand cmd) throws IOException {
+    if( cmd.id != null ) {
+      updateHandler.delete(cmd);
+    }
+    else {
+      updateHandler.deleteByQuery(cmd);
+    }
+    super.processDelete(cmd);
+  }
+
+  @Override
+  public void processCommit(CommitUpdateCommand cmd) throws IOException
+  {
+    updateHandler.commit(cmd);
+    super.processCommit(cmd);
+  }
+}
+
+

Propchange: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: 
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?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java
 (added)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,49 @@
+/**
+ * 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 java.io.IOException;
+import java.util.logging.Logger;
+
+import org.apache.solr.update.AddUpdateCommand;
+import org.apache.solr.update.CommitUpdateCommand;
+import org.apache.solr.update.DeleteUpdateCommand;
+
+
+/**
+ * This is a good place for subclassed update handlers to process the document 
before it is 
+ * indexed.  You may wish to add/remove fields or check if the requested user 
is allowed to 
+ * update the given document...
+ * 
+ * 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.
+ * 
+ * @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;
+}
+

Propchange: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: 
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?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
 (added)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,38 @@
+/**
+ * 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;
+import org.w3c.dom.Node;
+
+/**
+ * A factory to generate UpdateRequestProcessors for each request.  
+ * 
+ * @since solr 1.3
+ */
+public abstract class UpdateRequestProcessorFactory 
+{    
+  public void init( Node node )
+  {
+    // could process the Node
+  }
+  
+  abstract public UpdateRequestProcessor getInstance( 
+      SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next 
);
+}

Propchange: 
lucene/solr/trunk/src/java/org/apache/solr/update/processor/UpdateRequestProcessorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Modified: 
lucene/solr/trunk/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
URL: 
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java?view=diff&rev=556064&r1=556063&r2=556064
==============================================================================
--- 
lucene/solr/trunk/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
 (original)
+++ 
lucene/solr/trunk/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
 Fri Jul 13 09:48:00 2007
@@ -40,20 +40,22 @@
   
   private final String type;
   private final boolean preRegister;
+  private final boolean requireName;
   
   /**
    * @param type is the 'type' name included in error messages.
    * @param preRegister, if true, this will first register all Plugins, then 
it will initialize them.
    */
-  public AbstractPluginLoader( String type, boolean preRegister )
+  public AbstractPluginLoader( String type, boolean preRegister, boolean 
requireName )
   {
     this.type = type;
     this.preRegister = preRegister;
+    this.requireName = requireName;
   }
 
   public AbstractPluginLoader( String type )
   {
-    this( type, false );
+    this( type, false, true );
   }
   
   /**
@@ -130,7 +132,7 @@
         // In a production environment, we can tolerate an error in some 
request handlers, 
         // still load the others, and have a working system.
         try {
-          String name       = DOMUtil.getAttr(node,"name", type);
+          String name       = DOMUtil.getAttr(node,"name", 
requireName?type:null);
           String className  = DOMUtil.getAttr(node,"class", type);
           String defaultStr = DOMUtil.getAttr(node,"default", null );
             

Added: 
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?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
 (added)
+++ 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,50 @@
+/**
+ * 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.common.util.DOMUtil;
+import org.apache.solr.common.util.NamedList;
+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;
+
+
+/**
+ * A custom class to do custom stuff
+ */
+public class CustomUpdateRequestProcessorFactory extends 
UpdateRequestProcessorFactory 
+{
+  public NamedList args = null;
+  
+  @Override
+  public void init( Node node )
+  {
+    if( node != null ) {
+      args = DOMUtil.childNodesToNamedList( node );
+    }
+  }
+
+  @Override
+  public UpdateRequestProcessor getInstance(SolrQueryRequest req, 
SolrQueryResponse rsp, UpdateRequestProcessor next) {
+    // TODO Auto-generated method stub
+    return null;
+  }
+}
+

Propchange: 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/CustomUpdateRequestProcessorFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
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?view=auto&rev=556064
==============================================================================
--- 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
 (added)
+++ 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
 Fri Jul 13 09:48:00 2007
@@ -0,0 +1,56 @@
+/**
+ * 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.core.SolrCore;
+import org.apache.solr.update.processor.ChainedUpdateProcessorFactory;
+import org.apache.solr.util.AbstractSolrTestCase;
+
+/**
+ * 
+ */
+public class UpdateRequestProcessorFactoryTest extends AbstractSolrTestCase {
+
+  @Override public String getSchemaFile()     { return "schema.xml"; }
+  @Override public String getSolrConfigFile() { return 
"solrconfig-transformers.xml"; }
+  
+
+  public void testConfiguration() throws Exception 
+  {
+    SolrCore core = SolrCore.getSolrCore();
+
+    // make sure it loaded the factories
+    ChainedUpdateProcessorFactory chained = 
+      (ChainedUpdateProcessorFactory)core.getUpdateProcessorFactory( 
"standard" );
+    
+    // Make sure it got 3 items and configured the Log factory ok
+    assertEquals( 3, chained.factory.length );
+    LogUpdateProcessorFactory log = 
(LogUpdateProcessorFactory)chained.factory[0];
+    assertEquals( 100, log.maxNumToLog );
+    
+    
+    CustomUpdateRequestProcessorFactory custom = 
+      (CustomUpdateRequestProcessorFactory)core.getUpdateProcessorFactory( 
null );
+
+    assertEquals( custom, core.getUpdateProcessorFactory( "" ) );
+    assertEquals( custom, core.getUpdateProcessorFactory( "custom" ) );
+    
+    // Make sure the NamedListArgs got through ok
+    assertEquals( "{name={n8=88,n9=99}}", custom.args.toString() );
+  }
+}

Propchange: 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
lucene/solr/trunk/src/test/org/apache/solr/update/processor/UpdateRequestProcessorFactoryTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: 
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?view=auto&rev=556064
==============================================================================
--- lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml 
(added)
+++ lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml 
Fri Jul 13 09:48:00 2007
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+
+<!--
+ 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.
+-->
+
+<config>
+
+ <requestHandler name="custom" class="solr.CustomUpdateRequestHandler" >
+   <str name="update.processor.factory">custom</str>
+ </requestHandler>
+
+ <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>
+   
+   <factory name="custom" class="solr.CustomUpdateRequestProcessorFactory" 
default="true" >
+    <lst name="name">
+      <str name="n8">88</str>
+      <str name="n9">99</str>
+    </lst>
+   </factory>
+ </updateRequestProcessor>
+
+</config>

Propchange: 
lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
lucene/solr/trunk/src/test/test-files/solr/conf/solrconfig-transformers.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL


Reply via email to