You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ry...@apache.org on 2011/03/26 04:18:35 UTC

svn commit: r1085633 - in /lucene/dev/trunk/solr: example/solr/conf/ src/java/org/apache/solr/core/ src/java/org/apache/solr/response/transform/ src/java/org/apache/solr/search/ src/test/org/apache/solr/ src/test/org/apache/solr/client/solrj/ src/test/...

Author: ryan
Date: Sat Mar 26 03:18:34 2011
New Revision: 1085633

URL: http://svn.apache.org/viewvc?rev=1085633&view=rev
Log:
SOLR-1566, using factories to create transformers

Added:
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocIdAugmenterFactory.java   (with props)
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenterFactory.java   (with props)
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ShardAugmenterFactory.java   (with props)
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformerFactory.java   (with props)
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueAugmenterFactory.java   (with props)
Removed:
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocIdAugmenter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueAugmenter.java
Modified:
    lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml
    lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrConfig.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrCore.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformer.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformers.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ScoreAugmenter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformContext.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/ConvertedLegacyTest.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java

Modified: lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml (original)
+++ lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml Sat Mar 26 03:18:34 2011
@@ -1494,6 +1494,28 @@
      <valueSourceParser name="myfunc" 
                         class="com.mycompany.MyValueSourceParser" />
     -->
+    
+  
+  <!-- Document Transformers
+       http://wiki.apache.org/solr/DocTransformers
+    -->
+  <!--
+     Could be something like:
+     <transformer name="db" class="com.mycompany.LoadFromDatabaseTransformer" >
+       <int name="connection">jdbc://....</int>
+     </transformer>
+     
+     To add a constant value to all docs, use:
+     <transformer name="mytrans2" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
+       <int name="value">5</int>
+     </transformer>
+     
+     If you want the user to still be able to change it with _value:something_ use this:
+     <transformer name="mytrans3" class="org.apache.solr.response.transform.ValueAugmenterFactory" >
+       <double name="defaultValue">5</double>
+     </transformer>
+    -->
+    
 
   <!-- Legacy config for the admin interface -->
   <admin>

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrConfig.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrConfig.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrConfig.java Sat Mar 26 03:18:34 2011
@@ -27,6 +27,7 @@ import org.apache.solr.request.LocalSolr
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestHandler;
 import org.apache.solr.response.QueryResponseWriter;
+import org.apache.solr.response.transform.TransformerFactory;
 
 import org.apache.solr.search.CacheConfig;
 import org.apache.solr.search.FastLRUCache;
@@ -190,6 +191,7 @@ public class SolrConfig extends Config {
      loadPluginInfo(QParserPlugin.class,"queryParser",true, true);
      loadPluginInfo(QueryResponseWriter.class,"queryResponseWriter",true, true);
      loadPluginInfo(ValueSourceParser.class,"valueSourceParser",true, true);
+     loadPluginInfo(TransformerFactory.class,"transformer",true, true);
      loadPluginInfo(SearchComponent.class,"searchComponent",true, true);
      loadPluginInfo(QueryConverter.class,"queryConverter",true, true);
 
@@ -396,7 +398,7 @@ public class SolrConfig extends Config {
    * @param type The key is FQN of the plugin class there are a few  known types : SolrFormatter, SolrFragmenter
    * SolrRequestHandler,QParserPlugin, QueryResponseWriter,ValueSourceParser,
    * SearchComponent, QueryConverter, SolrEventListener, DirectoryFactory,
-   * IndexDeletionPolicy, IndexReaderFactory
+   * IndexDeletionPolicy, IndexReaderFactory, {@link TransformerFactory}
    */
   public List<PluginInfo> getPluginInfos(String  type){
     List<PluginInfo> result = pluginStore.get(type);

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrCore.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/core/SolrCore.java Sat Mar 26 03:18:34 2011
@@ -33,16 +33,7 @@ import org.apache.solr.handler.component
 import org.apache.solr.highlight.SolrHighlighter;
 import org.apache.solr.request.*;
 import org.apache.solr.response.*;
-import org.apache.solr.response.BinaryResponseWriter;
-import org.apache.solr.response.JSONResponseWriter;
-import org.apache.solr.response.PHPResponseWriter;
-import org.apache.solr.response.PHPSerializedResponseWriter;
-import org.apache.solr.response.PythonResponseWriter;
-import org.apache.solr.response.QueryResponseWriter;
-import org.apache.solr.response.RawResponseWriter;
-import org.apache.solr.response.RubyResponseWriter;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.response.XMLResponseWriter;
+import org.apache.solr.response.transform.TransformerFactory;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.search.QParserPlugin;
 import org.apache.solr.search.SolrFieldCacheMBean;
@@ -507,6 +498,7 @@ public final class SolrCore implements S
     initWriters();
     initQParsers();
     initValueSourceParsers();
+    initTransformerFactories();
 
     this.searchComponents = Collections.unmodifiableMap(loadSearchComponents());
 
@@ -1455,6 +1447,34 @@ public final class SolrCore implements S
       }
     }
   }
+  
+
+  private final HashMap<String, TransformerFactory> transformerFactories = new HashMap<String, TransformerFactory>();
+  
+  /** Configure the TransformerFactory plugins */
+  private void initTransformerFactories() {
+    // Load any transformer factories
+    initPlugins(transformerFactories,TransformerFactory.class);
+    
+    // Tell each transformer what its name is
+    for( Map.Entry<String, TransformerFactory> entry : TransformerFactory.defaultFactories.entrySet() ) {
+      try {
+        String name = entry.getKey();
+        if (null == valueSourceParsers.get(name)) {
+          TransformerFactory f = entry.getValue();
+          transformerFactories.put(name, f);
+          // f.init(null); default ones don't need init
+        }
+      } catch (Exception e) {
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+      }
+    }
+  }
+  
+  public TransformerFactory getTransformerFactory(String name) {
+    return transformerFactories.get(name);
+  }
+  
 
   /**
    * @param registry The map to which the instance should be added to. The key is the name attribute

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocIdAugmenterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocIdAugmenterFactory.java?rev=1085633&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocIdAugmenterFactory.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocIdAugmenterFactory.java Sat Mar 26 03:18:34 2011
@@ -0,0 +1,62 @@
+/**
+ * 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.response.transform;
+
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+
+/**
+ * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
+ * @since solr 4.0
+ */
+public class DocIdAugmenterFactory extends TransformerFactory
+{
+  @Override
+  public DocTransformer create(String field, String arg) {
+    if( arg != null ) {
+      throw new SolrException( ErrorCode.BAD_REQUEST,
+          "DocIdAugmenter does not take any arguments" );
+    }
+    return new DocIdAugmenter( field );
+  }
+}
+
+class DocIdAugmenter extends DocTransformer
+{
+  final String name;
+
+  public DocIdAugmenter( String display )
+  {
+    this.name = display;
+  }
+
+  @Override
+  public String getName()
+  {
+    return name;
+  }
+
+  @Override
+  public void transform(SolrDocument doc, int docid) {
+    if( docid >= 0 ) {
+      doc.setField( name, docid );
+    }
+  }
+}
+
+

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformer.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformer.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformer.java Sat Mar 26 03:18:34 2011
@@ -23,11 +23,17 @@ import org.apache.solr.common.SolrDocume
 
 /**
  * New instance for each request
- * 
+ *
  * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
  */
 public abstract class DocTransformer
 {
+  public abstract String getName();
   public void setContext( TransformContext context ) {}
   public abstract void transform(SolrDocument doc, int docid) throws IOException;
+
+  @Override
+  public String toString() {
+    return getName();
+  }
 }

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformers.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformers.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformers.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/DocTransformers.java Sat Mar 26 03:18:34 2011
@@ -19,19 +19,36 @@ package org.apache.solr.response.transfo
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.solr.common.SolrDocument;
 
 /**
  * Transform a document before it gets sent out
- * 
+ *
  * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
  */
 public class DocTransformers extends DocTransformer
 {
   final List<DocTransformer> children = new ArrayList<DocTransformer>();
 
+  @Override
+  public String getName()
+  {
+    StringBuilder str = new StringBuilder();
+    str.append( "Transformers[" );
+    Iterator<DocTransformer> iter = children.iterator();
+    while( iter.hasNext() ) {
+      str.append( iter.next().getName() );
+      if( iter.hasNext() ) {
+        str.append( "," );
+      }
+    }
+    str.append( "]" );
+    return str.toString();
+  }
+
   public void addTransformer( DocTransformer a ) {
     children.add( a );
   }

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenterFactory.java?rev=1085633&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenterFactory.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ExplainAugmenterFactory.java Sat Mar 26 03:18:34 2011
@@ -0,0 +1,112 @@
+/**
+ * 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.response.transform;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.Explanation;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.util.SolrPluginUtils;
+
+/**
+ * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
+ * @since solr 4.0
+ */
+public class ExplainAugmenterFactory extends TransformerFactory
+{
+  public static enum Style {
+    nl,
+    text,
+    html
+  };
+
+  protected Style defaultStyle = null;
+
+  @Override
+  public void init(NamedList args) {
+    super.init(args);
+    if( defaultUserArgs != null ) {
+      defaultStyle = getStyle( defaultUserArgs );
+    }
+    else {
+      defaultStyle = Style.nl;
+    }
+  }
+
+  public static Style getStyle( String str )
+  {
+    try {
+      return Style.valueOf( str );
+    }
+    catch( Exception ex ) {
+      throw new SolrException( ErrorCode.BAD_REQUEST,
+          "Unknown Explain Style: "+str );
+    }
+  }
+
+  @Override
+  public DocTransformer create(String field, String arg) {
+    Style style = (arg==null)?defaultStyle:getStyle(arg);
+    return new ExplainAugmenter( field, style );
+  }
+
+
+  static class ExplainAugmenter extends TransformerWithContext
+  {
+    final String name;
+    final Style style;
+
+    public ExplainAugmenter( String display, Style style )
+    {
+      this.name = display;
+      this.style = style;
+    }
+
+    @Override
+    public String getName()
+    {
+      return name;
+    }
+
+    @Override
+    public void transform(SolrDocument doc, int docid) {
+      if( context != null && context.query != null ) {
+        try {
+          Explanation exp = context.searcher.explain(context.query, docid);
+          if( style == Style.nl ) {
+            doc.setField( name, SolrPluginUtils.explanationToNamedList(exp) );
+          }
+          else if( style == Style.html ) {
+            doc.setField( name, exp.toHtml() );
+          }
+          else {
+            doc.setField( name, exp.toString() );
+          }
+        }
+        catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+  }
+}
+
+
+

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/RenameFieldsTransformer.java Sat Mar 26 03:18:34 2011
@@ -35,6 +35,21 @@ public class RenameFieldsTransformer ext
   }
 
   @Override
+  public String getName()
+  {
+    StringBuilder str = new StringBuilder();
+    str.append( "Rename[" );
+    for( int i=0; i< rename.size(); i++ ) {
+      if( i > 0 ) {
+        str.append( "," );
+      }
+      str.append( rename.getName(i) ).append( ">>" ).append( rename.getVal( i ) );
+    }
+    str.append( "]" );
+    return str.toString();
+  }
+
+  @Override
   public void transform(SolrDocument doc, int docid) {
     for( int i=0; i<rename.size(); i++ ) {
       Object v = doc.remove( rename.getName(i) );

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ScoreAugmenter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ScoreAugmenter.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ScoreAugmenter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ScoreAugmenter.java Sat Mar 26 03:18:34 2011
@@ -34,6 +34,12 @@ public class ScoreAugmenter extends Tran
   }
 
   @Override
+  public String getName()
+  {
+    return name;
+  }
+
+  @Override
   public void transform(SolrDocument doc, int docid) {
     if( context != null && context.wantsScores ) {
       if( context.iterator != null ) {

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ShardAugmenterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ShardAugmenterFactory.java?rev=1085633&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ShardAugmenterFactory.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ShardAugmenterFactory.java Sat Mar 26 03:18:34 2011
@@ -0,0 +1,34 @@
+/**
+ * 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.response.transform;
+
+
+/**
+ * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
+ * @since solr 4.0
+ */
+public class ShardAugmenterFactory extends TransformerFactory
+{
+  @Override
+  public DocTransformer create(String field, String arg) {
+    String id = "TODO... find ID";
+    // Maybe it is stored in the context?
+    // is it a request variable?
+    return new ValueAugmenter( field, id );
+  }
+}
+

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformContext.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformContext.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformContext.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformContext.java Sat Mar 26 03:18:34 2011
@@ -22,7 +22,7 @@ import org.apache.solr.search.SolrIndexS
 
 /**
  * Environment variables for the transformed documents
- * 
+ *
  * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
  * @since solr 4.0
  */

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformerFactory.java?rev=1085633&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformerFactory.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/TransformerFactory.java Sat Mar 26 03:18:34 2011
@@ -0,0 +1,48 @@
+/**
+ * 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.response.transform;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.util.plugin.NamedListInitializedPlugin;
+
+/**
+ * New instance for each request
+ *
+ * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
+ */
+public abstract class TransformerFactory implements NamedListInitializedPlugin
+{
+  protected String defaultUserArgs = null;
+
+  public void init(NamedList args) {
+    defaultUserArgs = (String)args.get( "args" );
+  }
+
+  public abstract DocTransformer create(String field, String args);
+
+  public static final Map<String,TransformerFactory> defaultFactories = new HashMap<String,TransformerFactory>();
+  static {
+    defaultFactories.put( "explain", new ExplainAugmenterFactory() );
+    defaultFactories.put( "value", new ValueAugmenterFactory() );
+    defaultFactories.put( "docid", new DocIdAugmenterFactory() );
+    defaultFactories.put( "shard", new ShardAugmenterFactory() );
+  }
+}

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueAugmenterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueAugmenterFactory.java?rev=1085633&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueAugmenterFactory.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueAugmenterFactory.java Sat Mar 26 03:18:34 2011
@@ -0,0 +1,98 @@
+/**
+ * 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.response.transform;
+
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.util.DateUtil;
+import org.apache.solr.common.util.NamedList;
+
+/**
+ * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
+ * @since solr 4.0
+ */
+public class ValueAugmenterFactory extends TransformerFactory
+{
+  protected Object value = null;
+  protected Object defaultValue = null;
+
+  @Override
+  public void init(NamedList args) {
+    value = args.get( "value" );
+    if( value == null ) {
+      defaultValue = args.get( "deaultValue" );
+    }
+  }
+
+  public static Object getObjectFrom( String str )
+  {
+    int idx = str.indexOf( ':' );
+    if( idx > 0 ) {
+      String type = str.substring(0,idx);
+      String val = str.substring(idx+1);
+      try {
+        if( "int".equals( type ) ) return Integer.valueOf( val );
+        if( "double".equals( type ) ) return Double.valueOf( val );
+        if( "float".equals( type ) ) return Float.valueOf( val );
+        if( "date".equals( type ) ) return DateUtil.parseDate(val);
+      }
+      catch( Exception ex ) {
+        throw new SolrException( ErrorCode.BAD_REQUEST,
+            "Unable to parse "+type+"="+val, ex );
+      }
+    }
+    return str;
+  }
+
+  @Override
+  public DocTransformer create(String field, String arg) {
+    Object val = value;
+    if( val == null ) {
+      val = (arg==null)?defaultValue:getObjectFrom(arg);
+      if( val == null ) {
+        throw new SolrException( ErrorCode.BAD_REQUEST,
+            "ValueAugmenter is missing a value -- should be defined in solrconfig or inline" );
+      }
+    }
+    return new ValueAugmenter( field, val );
+  }
+}
+
+class ValueAugmenter extends DocTransformer
+{
+  final String name;
+  final Object value;
+
+  public ValueAugmenter( String name, Object value )
+  {
+    this.name = name;
+    this.value = value;
+  }
+
+  @Override
+  public String getName()
+  {
+    return name;
+  }
+
+  @Override
+  public void transform(SolrDocument doc, int docid) {
+    doc.setField( name, value );
+  }
+}
+

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/response/transform/ValueSourceAugmenter.java Sat Mar 26 03:18:34 2011
@@ -22,7 +22,7 @@ import org.apache.solr.search.function.V
 
 /**
  * Add values from a ValueSource (function query etc)
- * 
+ *
  * NOT really sure how or if this could work...
  *
  * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
@@ -42,6 +42,17 @@ public class ValueSourceAugmenter extend
   }
 
   @Override
+  public String getName()
+  {
+    return name;
+  }
+
+  @Override
+  public void setContext( TransformContext context ) {
+    // maybe we do something here?
+  }
+
+  @Override
   public void transform(SolrDocument doc, int docid) {
     // TODO, should know what the real type is -- not always string
     // how do we get to docvalues?

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/QueryParsing.java Sat Mar 26 03:18:34 2011
@@ -693,7 +693,7 @@ public class QueryParsing {
         pos++;
         while (pos < end) {
           ch = val.charAt(pos);
-          if (!Character.isJavaIdentifierPart(ch) && ch != '.') {
+          if (!Character.isJavaIdentifierPart(ch) && ch != '.' && ch != ':') {
             break;
           }
           pos++;

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/ReturnFields.java Sat Mar 26 03:18:34 2011
@@ -27,17 +27,15 @@ import org.apache.lucene.queryParser.Par
 import org.apache.lucene.search.Query;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
-import org.apache.solr.common.params.ShardParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.core.SolrCore;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.transform.DocIdAugmenter;
 import org.apache.solr.response.transform.DocTransformer;
 import org.apache.solr.response.transform.DocTransformers;
-import org.apache.solr.response.transform.ExplainAugmenter;
 import org.apache.solr.response.transform.RenameFieldsTransformer;
 import org.apache.solr.response.transform.ScoreAugmenter;
-import org.apache.solr.response.transform.ValueAugmenter;
+import org.apache.solr.response.transform.TransformerFactory;
 import org.apache.solr.response.transform.ValueSourceAugmenter;
 import org.apache.solr.search.function.FunctionQuery;
 import org.apache.solr.search.function.QueryValueSource;
@@ -47,26 +45,21 @@ import org.slf4j.LoggerFactory;
 
 /**
  * A class representing the return fields
- * 
+ *
  * @version $Id: JSONResponseWriter.java 1065304 2011-01-30 15:10:15Z rmuir $
  * @since solr 4.0
  */
 public class ReturnFields
 {
   static final Logger log = LoggerFactory.getLogger( ReturnFields.class );
-  
+
   // Special Field Keys
   public static final String SCORE = "score";
-  // some special syntax for these guys?
-  // Should these have factories... via plugin utils...
-  public static final String DOCID = "_docid_";
-  public static final String SHARD = "_shard_";
-  public static final String EXPLAIN = "_explain_";
 
   private final List<String> globs = new ArrayList<String>(1);
   private final Set<String> fields = new LinkedHashSet<String>(); // order is important for CSVResponseWriter
   private Set<String> okFieldNames = new HashSet<String>(); // Collection of everything that could match
-  
+
   private DocTransformer transformer;
   private boolean _wantsScore = false;
   private boolean _wantsAllFields = false;
@@ -76,7 +69,7 @@ public class ReturnFields
   }
 
   public ReturnFields(SolrQueryRequest req) {
-    this( req.getParams().get(CommonParams.FL), req );
+    this( req.getParams().getParams(CommonParams.FL), req );
   }
 
   public ReturnFields(String fl, SolrQueryRequest req) {
@@ -97,12 +90,12 @@ public class ReturnFields
         parseFieldList( new String[]{fl}, req);
       }
     }
-    req.getCore().log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);  
+    SolrCore.log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);
   }
 
   public ReturnFields(String[] fl, SolrQueryRequest req) {
     parseFieldList(fl, req);
-    req.getCore().log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);  
+    SolrCore.log.info("fields=" + fields + "\t globs="+globs + "\t transformer="+transformer);
   }
 
   private void parseFieldList(String[] fl, SolrQueryRequest req) {
@@ -124,12 +117,12 @@ public class ReturnFields
       }
       augmenters.addTransformer( new RenameFieldsTransformer( rename ) );
     }
-    
+
     // Legacy behavior? "score" == "*,score"  Distributed tests for this
     if( fields.size() == 1 && _wantsScore ) {
       _wantsAllFields = true;
     }
-    
+
     if( !_wantsAllFields ) {
       if( !globs.isEmpty() ) {
         // TODO??? need to fill up the fields with matching field names in the index
@@ -140,7 +133,7 @@ public class ReturnFields
       }
       okFieldNames.addAll( fields );
     }
-        
+
     if( augmenters.size() == 1 ) {
       transformer = augmenters.getTransformer(0);
     }
@@ -177,26 +170,7 @@ public class ReturnFields
             start = sp.pos;
           } else {
             if (ch==' ' || ch == ',' || ch==0) {
-              String disp = (key==null) ? field : key; 
-              fields.add( field ); // need to put in the map to maintain order for things like CSVResponseWriter
-              okFieldNames.add( field );
-              okFieldNames.add( key );
-              // a valid field name
-              if(SCORE.equals(field)) {
-                _wantsScore = true;
-                augmenters.addTransformer( new ScoreAugmenter( disp ) );
-              }
-              else if( DOCID.equals( field ) ) {
-                augmenters.addTransformer( new DocIdAugmenter( disp ) );
-              }
-              else if( SHARD.equals( field ) ) {
-                String id = "TODO! getshardid???";
-                augmenters.addTransformer( new ValueAugmenter( disp, id ) );
-              }
-              else if( EXPLAIN.equals( field ) ) {
-                // TODO? pass params to transformers?
-                augmenters.addTransformer( new ExplainAugmenter( disp, ExplainAugmenter.Style.NL ) );
-              }
+              addField( field, key, augmenters, req );
               continue;
             }
             // an invalid field name... reset the position pointer to retry
@@ -211,8 +185,7 @@ public class ReturnFields
           ch = sp.ch();
           if (field != null && (ch==' ' || ch == ',' || ch==0)) {
             rename.add(field, key);
-            okFieldNames.add( field );
-            okFieldNames.add( key );
+            addField( field, key, augmenters, req );
             continue;
           }
           // an invalid field name... reset the position pointer to retry
@@ -296,7 +269,7 @@ public class ReturnFields
               key = sp.val.substring(start, sp.pos);
             }
           }
-          
+
           augmenters.addTransformer( new ValueSourceAugmenter( key, parser, vs ) );
         }
         catch (ParseException e) {
@@ -322,7 +295,40 @@ public class ReturnFields
       throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname", e);
     }
   }
-  
+
+  private void addField( String field, String key, DocTransformers augmenters, SolrQueryRequest req )
+  {
+    String disp = (key==null) ? field : key;
+    fields.add( field ); // need to put in the map to maintain order for things like CSVResponseWriter
+    okFieldNames.add( field );
+    okFieldNames.add( key );
+    // a valid field name
+    if(SCORE.equals(field)) {
+      _wantsScore = true;
+      augmenters.addTransformer( new ScoreAugmenter( disp ) );
+    }
+    else if( field.charAt(0)=='_'&& field.charAt(field.length()-1)=='_' ) {
+      String name = field;
+      String args = null;
+      int idx = field.indexOf( ':' );
+      if( idx > 0 ) {
+        name = field.substring(1,idx);
+        args = field.substring(idx+1,field.length()-1);
+      }
+      else {
+        name = field.substring(1,field.length()-1 );
+      }
+
+      TransformerFactory factory = req.getCore().getTransformerFactory( name );
+      if( factory != null ) {
+        augmenters.addTransformer( factory.create(disp, args) );
+      }
+      else {
+        // unknown field?
+      }
+    }
+  }
+
   public Set<String> getLuceneFieldNames()
   {
     return (_wantsAllFields || fields.isEmpty()) ? null : fields;
@@ -332,7 +338,7 @@ public class ReturnFields
   {
     return _wantsAllFields;
   }
-  
+
   public boolean wantsScore()
   {
     return _wantsScore;

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/ConvertedLegacyTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/ConvertedLegacyTest.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/ConvertedLegacyTest.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/ConvertedLegacyTest.java Sat Mar 26 03:18:34 2011
@@ -1122,12 +1122,12 @@ public class ConvertedLegacyTest extends
             ,"//float[.='1.4142135']"
             );
     args = new HashMap<String,String>();
-    args.put("fl","  ");
+    args.put("fl","fname_s,score");
     req = new LocalSolrQueryRequest(h.getCore(), "id:44",
                                     "standard", 0, 10, args);
     assertQ(req
-            ,"//str[.='Yonik']  "
-            ,"//float[.='1.4142135']"
+            ,"//str[.='Yonik']"
+            ,"//float[.='2.9459102']"
             );
 
     // test addition of score field

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/client/solrj/SolrExampleTests.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/client/solrj/SolrExampleTests.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/client/solrj/SolrExampleTests.java Sat Mar 26 03:18:34 2011
@@ -405,7 +405,7 @@ abstract public class SolrExampleTests e
     
     SolrQuery query = new SolrQuery();
     query.setQuery( "*:*" );
-    query.set( CommonParams.FL, "id,price,_docid_,_explain_,score" );
+    query.set( CommonParams.FL, "id,price,_docid_,_explain:nl_,score,aaa=_value:aaa_,ten=_value:int:10_" );
     query.addSortField( "price", SolrQuery.ORDER.asc );
     QueryResponse rsp = server.query( query );
     
@@ -424,8 +424,12 @@ abstract public class SolrExampleTests e
     assertTrue( "should be bigger ["+id1+","+id2+"]", id2 > id1 );
     
     // The score from explain should be the same as the score
-    NamedList explain = (NamedList)out1.getFieldValue( "_explain_" );
+    NamedList explain = (NamedList)out1.getFieldValue( "_explain:nl_" );
     assertEquals( out1.get( "score"), explain.get( "value" ) );
+    
+    // Augmented _value_ with alias
+    assertEquals( "aaa", out1.get( "aaa" ) );
+    assertEquals( 10, ((Integer)out1.get( "ten" )).intValue() );
   }
 
  @Test

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java?rev=1085633&r1=1085632&r2=1085633&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java Sat Mar 26 03:18:34 2011
@@ -17,7 +17,6 @@
 package org.apache.solr.search;
 
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.response.transform.ExplainAugmenter;
 import org.apache.solr.response.transform.ScoreAugmenter;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -69,7 +68,7 @@ public class TestSolrQueryParser extends
     rf = new ReturnFields( req("fl", "_explain_") );
     assertFalse( rf.wantsScore() );
     assertFalse( rf.wantsField( "id" ) );
-    assertTrue( rf.getTransformer() instanceof ExplainAugmenter );
+    assertEquals( "_explain_", rf.getTransformer().getName() );
 
     // Check that we want wildcards
     rf = new ReturnFields( req("fl", "id,aaa*,*bbb") );
@@ -78,13 +77,5 @@ public class TestSolrQueryParser extends
     assertTrue( rf.wantsField( "xxxbbb" ) );
     assertFalse( rf.wantsField( "aa" ) );
     assertFalse( rf.wantsField( "bb" ) );
-
-    
-    // From ConvertedLegacyTest, maybe we drop support?
-    rf = new ReturnFields( req("fl", "  ") );
-    assertTrue( rf.wantsScore() );
-    assertTrue( rf.wantsField( "xxx" ) );
-    assertTrue( rf.wantsAllFields() );
-    assertTrue( rf.getTransformer() instanceof ScoreAugmenter );
   }
 }