You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2012/08/14 00:05:07 UTC

svn commit: r1372648 - in /lucene/dev/branches/branch_4x: ./ lucene/ lucene/analysis/ lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/ lucene/analysis/phonetic/src/jav...

Author: dsmiley
Date: Mon Aug 13 22:05:06 2012
New Revision: 1372648

URL: http://svn.apache.org/viewvc?rev=1372648&view=rev
Log:
LUCENE-4303 Use ResourceLoader not Class.forName

Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/lucene/   (props changed)
    lucene/dev/branches/branch_4x/lucene/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_4x/lucene/analysis/   (props changed)
    lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java
    lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java
    lucene/dev/branches/branch_4x/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java
    lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java
    lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/test/org/apache/lucene/analysis/phonetic/TestPhoneticFilterFactory.java

Modified: lucene/dev/branches/branch_4x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/CHANGES.txt?rev=1372648&r1=1372647&r2=1372648&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/lucene/CHANGES.txt Mon Aug 13 22:05:06 2012
@@ -56,6 +56,10 @@ Bug Fixes
   upgraded to 3.x, then to Lucene 4.0-ALPHA or -BETA, you should run 
   CheckIndex. If it fails, then you need to upgrade again to 4.0  (Robert Muir)
 
+* LUCENE-4303: PhoneticFilterFactory and SnowballPorterFilterFactory load their
+  encoders / stemmers via the ResourceLoader now instead of Class.forName().
+  Solr users should now no longer have to embed these in its war. (David Smiley)
+
 Build
 
 * LUCENE-3985: Upgrade to randomizedtesting 2.0.0. Added support for 

Modified: lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java?rev=1372648&r1=1372647&r2=1372648&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java (original)
+++ lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java Mon Aug 13 22:05:06 2012
@@ -44,7 +44,7 @@ public final class SnowballFilter extend
 
   private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
   private final KeywordAttribute keywordAttr = addAttribute(KeywordAttribute.class);
-  
+
   public SnowballFilter(TokenStream input, SnowballProgram stemmer) {
     super(input);
     this.stemmer = stemmer;
@@ -62,7 +62,9 @@ public final class SnowballFilter extend
    */
   public SnowballFilter(TokenStream in, String name) {
     super(in);
-    try {      
+    //Class.forName is frowned upon in place of the ResourceLoader but in this case,
+    // the factory will use the other constructor so that the program is already loaded.
+    try {
       Class<? extends SnowballProgram> stemClass =
         Class.forName("org.tartarus.snowball.ext." + name + "Stemmer").asSubclass(SnowballProgram.class);
       stemmer = stemClass.newInstance();

Modified: lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java?rev=1372648&r1=1372647&r2=1372648&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java (original)
+++ lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java Mon Aug 13 22:05:06 2012
@@ -46,35 +46,28 @@ public class SnowballPorterFilterFactory
   public static final String PROTECTED_TOKENS = "protected";
 
   private String language = "English";
-  private Class<?> stemClass;
-
+  private Class<? extends SnowballProgram> stemClass;
+  private CharArraySet protectedWords = null;
 
+  @Override
   public void inform(ResourceLoader loader) throws IOException {
+    String cfgLanguage = args.get("language");
+    if (cfgLanguage != null)
+      language = cfgLanguage;
+
+    String className = "org.tartarus.snowball.ext." + language + "Stemmer";
+    stemClass = loader.newInstance(className, SnowballProgram.class).getClass();
+
     String wordFiles = args.get(PROTECTED_TOKENS);
     if (wordFiles != null) {
       protectedWords = getWordSet(loader, wordFiles, false);
     }
   }
 
-  private CharArraySet protectedWords = null;
-
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    final String cfgLanguage = args.get("language");
-    if(cfgLanguage!=null) language = cfgLanguage;
-
-    try {
-      stemClass = Class.forName("org.tartarus.snowball.ext." + language + "Stemmer");
-    } catch (ClassNotFoundException e) {
-      throw new IllegalArgumentException("Can't find class for stemmer language " + language, e);
-    }
-  }
-  
   public TokenFilter create(TokenStream input) {
     SnowballProgram program;
     try {
-      program = (SnowballProgram)stemClass.newInstance();
+      program = stemClass.newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Error instantiating stemmer for language " + language + "from class " + stemClass, e);
     }

Modified: lucene/dev/branches/branch_4x/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java?rev=1372648&r1=1372647&r2=1372648&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java (original)
+++ lucene/dev/branches/branch_4x/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java Mon Aug 13 22:05:06 2012
@@ -27,6 +27,7 @@ import org.apache.lucene.analysis.MockTo
 import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
 import org.apache.lucene.analysis.util.CharFilterFactory;
+import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.analysis.util.MultiTermAwareComponent;
 import org.apache.lucene.analysis.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
@@ -114,11 +115,15 @@ public class TestFactories extends BaseT
   }
   
   /** tries to initialize a factory with no arguments */
-  private boolean initialize(AbstractAnalysisFactory factory) {
+  private boolean initialize(AbstractAnalysisFactory factory) throws IOException {
     boolean success = false;
     try {
       factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
       factory.init(Collections.<String,String>emptyMap());
+      if (factory instanceof ResourceLoaderAware) {
+        ResourceLoaderAware resourceLoaderAware = (ResourceLoaderAware) factory;
+          resourceLoaderAware.inform(new ClasspathResourceLoader(factory.getClass()));
+      }
       success = true;
     } catch (IllegalArgumentException ignored) {
       // its ok if we dont provide the right parameters to throw this

Modified: lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java?rev=1372648&r1=1372647&r2=1372648&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java (original)
+++ lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java Mon Aug 13 22:05:06 2012
@@ -17,6 +17,7 @@ package org.apache.lucene.analysis.phone
  * limitations under the License.
  */
 
+import java.io.IOException;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
@@ -26,7 +27,8 @@ import java.util.Map;
 import org.apache.commons.codec.Encoder;
 import org.apache.commons.codec.language.*;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.phonetic.PhoneticFilter;
+import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
@@ -57,6 +59,7 @@ import org.apache.lucene.analysis.util.T
  * @see PhoneticFilter
  */
 public class PhoneticFilterFactory extends TokenFilterFactory
+  implements ResourceLoaderAware
 {
   public static final String ENCODER = "encoder";
   public static final String INJECT = "inject"; // boolean
@@ -75,18 +78,17 @@ public class PhoneticFilterFactory exten
     registry.put("ColognePhonetic".toUpperCase(Locale.ROOT), ColognePhonetic.class);
   }
 
-  protected boolean inject = true;
-  protected String name = null;
-  protected Class<? extends Encoder> clazz = null;
-  protected Method setMaxCodeLenMethod = null;
-  protected Integer maxCodeLength = null;
+  boolean inject = true; //accessed by the test
+  private String name = null;
+  private Class<? extends Encoder> clazz = null;
+  private Method setMaxCodeLenMethod = null;
+  private Integer maxCodeLength = null;
 
   @Override
-  public void init(Map<String,String> args) {
-    super.init( args );
+  public void inform(ResourceLoader loader) throws IOException {
 
     inject = getBoolean(INJECT, true);
-    
+
     String name = args.get( ENCODER );
     if( name == null ) {
       throw new IllegalArgumentException("Missing required parameter: " + ENCODER
@@ -94,7 +96,7 @@ public class PhoneticFilterFactory exten
     }
     clazz = registry.get(name.toUpperCase(Locale.ROOT));
     if( clazz == null ) {
-      clazz = resolveEncoder(name);
+      clazz = resolveEncoder(name, loader);
     }
 
     String v = args.get(MAX_CODE_LENGTH);
@@ -110,17 +112,15 @@ public class PhoneticFilterFactory exten
     getEncoder();//trigger initialization for potential problems to be thrown now
   }
 
-  private Class<? extends Encoder> resolveEncoder(String name) {
+  private Class<? extends Encoder> resolveEncoder(String name, ResourceLoader loader) {
     String lookupName = name;
     if (name.indexOf('.') == -1) {
       lookupName = PACKAGE_CONTAINING_ENCODERS + name;
     }
     try {
-      return Class.forName(lookupName).asSubclass(Encoder.class);
-    } catch (ClassNotFoundException cnfe) {
-      throw new IllegalArgumentException("Unknown encoder: " + name + " must be full class name or one of " + registry.keySet(), cnfe);
-    } catch (ClassCastException e) {
-      throw new IllegalArgumentException("Not an encoder: " + name + " must be full class name or one of " + registry.keySet(), e);
+      return loader.newInstance(lookupName, Encoder.class).getClass();
+    } catch (RuntimeException e) {
+      throw new IllegalArgumentException("Error loading encoder '" + name + "': must be full class name or one of " + registry.keySet(), e);
     }
   }
 

Modified: lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/test/org/apache/lucene/analysis/phonetic/TestPhoneticFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/test/org/apache/lucene/analysis/phonetic/TestPhoneticFilterFactory.java?rev=1372648&r1=1372647&r2=1372648&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/test/org/apache/lucene/analysis/phonetic/TestPhoneticFilterFactory.java (original)
+++ lucene/dev/branches/branch_4x/lucene/analysis/phonetic/src/test/org/apache/lucene/analysis/phonetic/TestPhoneticFilterFactory.java Mon Aug 13 22:05:06 2012
@@ -17,6 +17,7 @@ package org.apache.lucene.analysis.phone
  * limitations under the License.
  */
 
+import java.io.IOException;
 import java.io.StringReader;
 import java.util.HashMap;
 import java.util.Map;
@@ -27,6 +28,7 @@ import org.apache.lucene.analysis.BaseTo
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.util.LuceneTestCase.Slow;
 
 
@@ -41,48 +43,54 @@ public class TestPhoneticFilterFactory e
   /**
    * Case: default
    */
-  public void testFactory()
-  {
+  public void testFactory() throws IOException {
     Map<String,String> args = new HashMap<String, String>();
     
     PhoneticFilterFactory ff = new PhoneticFilterFactory();
     
     args.put( PhoneticFilterFactory.ENCODER, "Metaphone" );
     ff.init( args );
+    ff.inform(new ClasspathResourceLoader(ff.getClass()));
     assertTrue( ff.getEncoder() instanceof Metaphone );
     assertTrue( ff.inject ); // default
 
     args.put( PhoneticFilterFactory.INJECT, "false" );
     ff.init( args );
+    ff.inform(new ClasspathResourceLoader(ff.getClass()));
     assertFalse( ff.inject );
 
     args.put( PhoneticFilterFactory.MAX_CODE_LENGTH, "2");
-    ff.init( args );
-    assertEquals(2,((Metaphone) ff.getEncoder()).getMaxCodeLen());
+    ff.init(args);
+    ff.inform(new ClasspathResourceLoader(ff.getClass()));
+    assertEquals(2, ((Metaphone) ff.getEncoder()).getMaxCodeLen());
   }
   
   /**
    * Case: Failures and Exceptions
    */
-  public void testFactoryCaseFailure()
-  {
+  public void testFactoryCaseFailure() throws IOException {
     Map<String,String> args = new HashMap<String, String>();
     
     PhoneticFilterFactory ff = new PhoneticFilterFactory();
+    ClasspathResourceLoader loader = new ClasspathResourceLoader(ff.getClass());
+
     try {
       ff.init( args );
+      ff.inform( loader );
       fail( "missing encoder parameter" );
     }
     catch( Exception ex ) {}
     args.put( PhoneticFilterFactory.ENCODER, "XXX" );
     try {
       ff.init( args );
+      ff.inform( loader );
       fail( "unknown encoder parameter" );
     }
     catch( Exception ex ) {}
     args.put( PhoneticFilterFactory.ENCODER, "org.apache.commons.codec.language.NonExistence" );
     try {
       ff.init( args );
+      ff.inform( loader );
       fail( "unknown encoder parameter" );
     }
     catch( Exception ex ) {}
@@ -91,14 +99,15 @@ public class TestPhoneticFilterFactory e
   /**
    * Case: Reflection
    */
-  public void testFactoryCaseReflection()
-  {
+  public void testFactoryCaseReflection() throws IOException {
     Map<String,String> args = new HashMap<String, String>();
     
     PhoneticFilterFactory ff = new PhoneticFilterFactory();
+    ClasspathResourceLoader loader = new ClasspathResourceLoader(ff.getClass());
 
     args.put( PhoneticFilterFactory.ENCODER, "org.apache.commons.codec.language.Metaphone" );
     ff.init( args );
+    ff.inform( loader );
     assertTrue( ff.getEncoder() instanceof Metaphone );
     assertTrue( ff.inject ); // default
 
@@ -106,12 +115,14 @@ public class TestPhoneticFilterFactory e
     // so this effectively tests reflection without package name
     args.put( PhoneticFilterFactory.ENCODER, "Caverphone2" );
     ff.init( args );
+    ff.inform( loader );
     assertTrue( ff.getEncoder() instanceof Caverphone2 );
     assertTrue( ff.inject ); // default
     
     // cross check with registry
     args.put( PhoneticFilterFactory.ENCODER, "Caverphone" );
     ff.init( args );
+    ff.inform( loader );
     assertTrue( ff.getEncoder() instanceof Caverphone2 );
     assertTrue( ff.inject ); // default
   }
@@ -158,6 +169,7 @@ public class TestPhoneticFilterFactory e
     args.put("inject", inject);
     PhoneticFilterFactory factory = new PhoneticFilterFactory();
     factory.init(args);
+    factory.inform(new ClasspathResourceLoader(factory.getClass()));
     TokenStream stream = factory.create(tokenizer);
     assertTokenStreamContents(stream, expected);
   }