You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2012/07/25 15:54:17 UTC

svn commit: r1365586 [2/2] - in /lucene/dev/trunk: ./ dev-tools/ dev-tools/eclipse/ lucene/ lucene/analysis/ lucene/analysis/common/ lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ lucene/analysis/common/src/java/org/apache/lucene/analys...

Modified: lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java (original)
+++ lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java Wed Jul 25 13:54:04 2012
@@ -18,6 +18,7 @@ package org.apache.lucene.analysis.util;
  */
 
 import java.io.Reader;
+import java.util.Set;
 
 import org.apache.lucene.analysis.CharFilter;
 
@@ -27,5 +28,32 @@ import org.apache.lucene.analysis.CharFi
  */
 public abstract class CharFilterFactory extends AbstractAnalysisFactory {
 
-  public abstract CharFilter create(Reader input);
+  private static final AnalysisSPILoader<CharFilterFactory> loader =
+      getSPILoader(Thread.currentThread().getContextClassLoader());
+  
+  /**
+   * Used by e.g. Apache Solr to get a correctly configured instance
+   * of {@link AnalysisSPILoader} from Solr's classpath.
+   * @lucene.internal
+   */
+  public static AnalysisSPILoader<CharFilterFactory> getSPILoader(ClassLoader classloader) {
+    return new AnalysisSPILoader<CharFilterFactory>(CharFilterFactory.class, classloader);
+  }
+  
+  /** looks up a charfilter by name from context classpath */
+  public static CharFilterFactory forName(String name) {
+    return loader.newInstance(name);
+  }
+  
+  /** looks up a charfilter class by name from context classpath */
+  public static Class<? extends CharFilterFactory> lookupClass(String name) {
+    return loader.lookupClass(name);
+  }
+  
+  /** returns a list of all available charfilter names */
+  public static Set<String> availableCharFilters() {
+    return loader.availableServices();
+  }
+
+  public abstract Reader create(Reader input);
 }

Modified: lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java (original)
+++ lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java Wed Jul 25 13:54:04 2012
@@ -17,6 +17,8 @@ package org.apache.lucene.analysis.util;
  * limitations under the License.
  */
 
+import java.util.Set;
+
 import org.apache.lucene.analysis.TokenStream;
 
 /**
@@ -25,6 +27,34 @@ import org.apache.lucene.analysis.TokenS
  */
 public abstract class TokenFilterFactory extends AbstractAnalysisFactory {
 
+  private static final AnalysisSPILoader<TokenFilterFactory> loader =
+      getSPILoader(Thread.currentThread().getContextClassLoader());
+  
+  /**
+   * Used by e.g. Apache Solr to get a correctly configured instance
+   * of {@link AnalysisSPILoader} from Solr's classpath.
+   * @lucene.internal
+   */
+  public static AnalysisSPILoader<TokenFilterFactory> getSPILoader(ClassLoader classloader) {
+    return new AnalysisSPILoader<TokenFilterFactory>(TokenFilterFactory.class,
+      new String[] { "TokenFilterFactory", "FilterFactory" }, classloader);
+  }
+  
+  /** looks up a tokenfilter by name from context classpath */
+  public static TokenFilterFactory forName(String name) {
+    return loader.newInstance(name);
+  }
+  
+  /** looks up a tokenfilter class by name from context classpath */
+  public static Class<? extends TokenFilterFactory> lookupClass(String name) {
+    return loader.lookupClass(name);
+  }
+  
+  /** returns a list of all available tokenfilter names from context classpath */
+  public static Set<String> availableTokenFilters() {
+    return loader.availableServices();
+  }
+  
   /** Transform the specified input TokenStream */
   public abstract TokenStream create(TokenStream input);
 }

Modified: lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java (original)
+++ lucene/dev/trunk/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java Wed Jul 25 13:54:04 2012
@@ -20,6 +20,7 @@ package org.apache.lucene.analysis.util;
 import org.apache.lucene.analysis.Tokenizer;
 
 import java.io.Reader;
+import java.util.Set;
 
 /**
  * Abstract parent class for analysis factories that create {@link Tokenizer}
@@ -27,6 +28,33 @@ import java.io.Reader;
  */
 public abstract class TokenizerFactory extends AbstractAnalysisFactory {
 
+  private static final AnalysisSPILoader<TokenizerFactory> loader =
+      getSPILoader(Thread.currentThread().getContextClassLoader());
+  
+  /**
+   * Used by e.g. Apache Solr to get a correctly configured instance
+   * of {@link AnalysisSPILoader} from Solr's classpath.
+   * @lucene.internal
+   */
+  public static AnalysisSPILoader<TokenizerFactory> getSPILoader(ClassLoader classloader) {
+    return new AnalysisSPILoader<TokenizerFactory>(TokenizerFactory.class, classloader);
+  }
+  
+  /** looks up a tokenizer by name from context classpath */
+  public static TokenizerFactory forName(String name) {
+    return loader.newInstance(name);
+  }
+  
+  /** looks up a tokenizer class by name from context classpath */
+  public static Class<? extends TokenizerFactory> lookupClass(String name) {
+    return loader.lookupClass(name);
+  }
+  
+  /** returns a list of all available tokenizer names from context classpath */
+  public static Set<String> availableTokenizers() {
+    return loader.availableServices();
+  }
+  
   /** Creates a TokenStream of the specified input */
   public abstract Tokenizer create(Reader input);
 }

Modified: lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java (original)
+++ lucene/dev/trunk/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java Wed Jul 25 13:54:04 2012
@@ -235,7 +235,7 @@ public class TestRandomChains extends Ba
   private static <T> Constructor<T> castConstructor(Class<T> instanceClazz, Constructor<?> ctor) {
     return (Constructor<T>) ctor;
   }
-  private static void getClassesForPackage(String pckgname, List<Class<?>> classes) throws Exception {
+  static void getClassesForPackage(String pckgname, List<Class<?>> classes) throws Exception {
     final ClassLoader cld = TestRandomChains.class.getClassLoader();
     final String path = pckgname.replace('.', '/');
     final Enumeration<URL> resources = cld.getResources(path);

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java Wed Jul 25 13:54:04 2012
@@ -22,7 +22,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.LinkedHashMap;
 import java.util.Set;
-import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
 
 /**
  * Helper class for loading named SPIs from classpath (e.g. Codec, PostingsFormat).
@@ -32,63 +32,52 @@ import java.util.ServiceLoader;
 public final class NamedSPILoader<S extends NamedSPILoader.NamedSPI> implements Iterable<S> {
 
   private final Map<String,S> services;
-
-  /** This field is a hack for LuceneTestCase to get access
-   * to the modifiable map (to work around bugs in IBM J9) */
-  @SuppressWarnings("unused")
-  @Deprecated
-  // Hackidy-Häck-Hack for bugs in IBM J9 ServiceLoader
-  private final Map<String,S> modifiableServices;
-  
   private final Class<S> clazz;
 
   public NamedSPILoader(Class<S> clazz) {
     this.clazz = clazz;
-    final ServiceLoader<S> loader = ServiceLoader.load(clazz);
+    final SPIClassIterator<S> loader = SPIClassIterator.get(clazz);
     final LinkedHashMap<String,S> services = new LinkedHashMap<String,S>();
-    for (final S service : loader) {
-      final String name = service.getName();
-      // only add the first one for each name, later services will be ignored
-      // this allows to place services before others in classpath to make 
-      // them used instead of others
-      if (!services.containsKey(name)) {
-        assert checkServiceName(name);
-        services.put(name, service);
+    while (loader.hasNext()) {
+      final Class<? extends S> c = loader.next();
+      try {
+        final S service = c.newInstance();
+        final String name = service.getName();
+        // only add the first one for each name, later services will be ignored
+        // this allows to place services before others in classpath to make 
+        // them used instead of others
+        if (!services.containsKey(name)) {
+          checkServiceName(name);
+          services.put(name, service);
+        }
+      } catch (Exception e) {
+        throw new ServiceConfigurationError("Cannot instantiate SPI class: " + c.getName(), e);
       }
     }
-    this.modifiableServices = services; // hack, remove when IBM J9 is fixed!
     this.services = Collections.unmodifiableMap(services);
   }
   
   /**
    * Validates that a service name meets the requirements of {@link NamedSPI}
    */
-  public static boolean checkServiceName(String name) {
+  public static void checkServiceName(String name) {
     // based on harmony charset.java
     if (name.length() >= 128) {
       throw new IllegalArgumentException("Illegal service name: '" + name + "' is too long (must be < 128 chars).");
     }
-    for (int i = 0; i < name.length(); i++) {
+    for (int i = 0, len = name.length(); i < len; i++) {
       char c = name.charAt(i);
-      if (!isLetter(c) && !isDigit(c)) {
+      if (!isLetterOrDigit(c)) {
         throw new IllegalArgumentException("Illegal service name: '" + name + "' must be simple ascii alphanumeric.");
       }
     }
-    return true;
   }
   
-  /*
-   * Checks whether a character is a letter (ascii) which are defined in the spec.
-   */
-  private static boolean isLetter(char c) {
-      return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
-  }
-
-  /*
-   * Checks whether a character is a digit (ascii) which are defined in the spec.
+  /**
+   * Checks whether a character is a letter or digit (ascii) which are defined in the spec.
    */
-  private static boolean isDigit(char c) {
-      return ('0' <= c && c <= '9');
+  private static boolean isLetterOrDigit(char c) {
+    return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9');
   }
   
   public S lookup(String name) {

Modified: lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleSetupAndRestoreClassEnv.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleSetupAndRestoreClassEnv.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleSetupAndRestoreClassEnv.java (original)
+++ lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleSetupAndRestoreClassEnv.java Wed Jul 25 13:54:04 2012
@@ -87,33 +87,6 @@ final class TestRuleSetupAndRestoreClass
     restoreProperties.put("solr.solr.home", System.getProperty("solr.solr.home"));
     restoreProperties.put("solr.data.dir", System.getProperty("solr.data.dir"));
 
-    // enable the Lucene 3.x PreflexRW codec explicitly, to work around bugs in IBM J9 / Harmony ServiceLoader:
-    try {
-      final java.lang.reflect.Field spiLoaderField = Codec.class.getDeclaredField("loader");
-      spiLoaderField.setAccessible(true);
-      final Object spiLoader = spiLoaderField.get(null);
-      final java.lang.reflect.Field modifiableServicesField = NamedSPILoader.class.getDeclaredField("modifiableServices");
-      modifiableServicesField.setAccessible(true);
-      /* note: re-enable this if we make a Lucene4x impersonator 
-      @SuppressWarnings({"unchecked","rawtypes"}) final Map<String,Codec> serviceMap =
-        (Map) modifiableServicesField.get(spiLoader);
-      if (!(Codec.forName("Lucene3x") instanceof PreFlexRWCodec)) {
-        if (Constants.JAVA_VENDOR.startsWith("IBM")) {
-          // definitely a buggy version
-          System.err.println("ERROR: Your VM's java.util.ServiceLoader implementation is buggy"+
-            " and does not respect classpath order, please report this to the vendor.");
-        } else {
-          // could just be a classpath issue
-          System.err.println("ERROR: fix your classpath to have tests-framework.jar before lucene-core.jar!"+
-              " If you have already done this, then your VM's java.util.ServiceLoader implementation is buggy"+
-              " and does not respect classpath order, please report this to the vendor.");
-        }
-        serviceMap.put("Lucene3x", new PreFlexRWCodec());
-      } */
-    } catch (Exception e) {
-      throw new RuntimeException("Cannot access internals of Codec and NamedSPILoader classes", e);
-    }
-    
     // if verbose: print some debugging stuff about which codecs are loaded.
     if (VERBOSE) {
       Set<String> codecs = Codec.availableCodecs();

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Wed Jul 25 13:54:04 2012
@@ -81,6 +81,13 @@ New Features
   already exist.  To assert that the document must exist, use the optimistic
   concurrency feature by specifying a _version_ of 1.  (yonik)
 
+* LUCENE-2510, LUCENE-4044: Migrated Solr's Tokenizer-, TokenFilter-, and
+  CharFilterFactories to the lucene-analysis module. To add new analysis
+  modules to Solr (like ICU, SmartChinese, Morfologik,...), just drop in
+  the JAR files from Lucene's binary distribution into your Solr instance's
+  lib folder. The factories are automatically made available with SPI.
+  (Chris Male, Robert Muir, Uwe Schindler)
+
 
 Bug Fixes
 ----------------------

Modified: lucene/dev/trunk/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/SolrStopwordsCarrot2LexicalDataFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/SolrStopwordsCarrot2LexicalDataFactory.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/SolrStopwordsCarrot2LexicalDataFactory.java (original)
+++ lucene/dev/trunk/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/SolrStopwordsCarrot2LexicalDataFactory.java Wed Jul 25 13:54:04 2012
@@ -23,8 +23,8 @@ import java.util.Set;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.util.CharArraySet;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
-import org.apache.solr.analysis.CommonGramsFilterFactory;
-import org.apache.solr.analysis.StopFilterFactory;
+import org.apache.lucene.analysis.commongrams.CommonGramsFilterFactory;
+import org.apache.lucene.analysis.core.StopFilterFactory;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.schema.IndexSchema;
 import org.carrot2.core.LanguageCode;

Modified: lucene/dev/trunk/solr/contrib/uima/src/test-files/uima/uima-tokenizers-schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/uima/src/test-files/uima/uima-tokenizers-schema.xml?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/uima/src/test-files/uima/uima-tokenizers-schema.xml (original)
+++ lucene/dev/trunk/solr/contrib/uima/src/test-files/uima/uima-tokenizers-schema.xml Wed Jul 25 13:54:04 2012
@@ -299,14 +299,14 @@
 
     <fieldType name="uima_sentences" class="solr.TextField" positionIncrementGap="100">
       <analyzer>
-        <tokenizer class="org.apache.solr.uima.analysis.UIMAAnnotationsTokenizerFactory"
+        <tokenizer class="solr.UIMAAnnotationsTokenizerFactory"
                    descriptorPath="/uima/AggregateSentenceAE.xml" tokenType="org.apache.uima.SentenceAnnotation"/>
       </analyzer>
     </fieldType>
 
     <fieldType name="uima_nouns" class="solr.TextField" positionIncrementGap="100">
       <analyzer>
-        <tokenizer class="org.apache.solr.uima.analysis.UIMATypeAwareAnnotationsTokenizerFactory"
+        <tokenizer class="solr.UIMATypeAwareAnnotationsTokenizerFactory"
                    descriptorPath="/uima/AggregateSentenceAE.xml" tokenType="org.apache.uima.TokenAnnotation"
                    featurePath="posTag"/>
         <filter class="solr.TypeTokenFilterFactory" types="uima/stoptypes.txt" />

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java Wed Jul 25 13:54:04 2012
@@ -20,6 +20,7 @@ package org.apache.solr.analysis;
 
 import java.io.Reader;
 
+import org.apache.lucene.analysis.charfilter.HTMLStripCharFilterFactory;
 import org.apache.lucene.analysis.util.CharFilterFactory;
 
 /**

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java Wed Jul 25 13:54:04 2012
@@ -29,11 +29,16 @@ import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
+import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
 import org.apache.lucene.analysis.util.CharFilterFactory;
 import org.apache.lucene.analysis.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 import org.apache.lucene.analysis.util.TokenizerFactory;
+import org.apache.lucene.analysis.util.AnalysisSPILoader;
+import org.apache.lucene.util.WeakIdentityMap;
 import org.apache.solr.common.ResourceLoader;
 import org.apache.solr.handler.admin.CoreAdminHandler;
 import org.apache.solr.handler.component.ShardHandlerFactory;
@@ -366,8 +371,15 @@ public class SolrResourceLoader implemen
   /*
    * A static map of short class name to fully qualified class name 
    */
-  private static Map<String, String> classNameCache = new ConcurrentHashMap<String, String>();
+  private static final Map<String, String> classNameCache = new ConcurrentHashMap<String, String>();
 
+  // A static map of AnalysisSPILoaders, keyed by ClassLoader used (because it can change during Solr lifetime) and expected base class:
+  private static final WeakIdentityMap<ClassLoader, Map<Class<?>,AnalysisSPILoader<?>>> expectedTypesSPILoaders = WeakIdentityMap.newConcurrentHashMap();
+
+  // Using this pattern, legacy analysis components from previous Solr versions are identified and delegated to SPI loader:
+  private static final Pattern legacyAnalysisPattern = 
+      Pattern.compile("((\\Q"+base+".analysis.\\E)|(\\Q"+project+".\\E))([\\p{L}_$][\\p{L}\\p{N}_$]+?)(TokenFilter|Filter|Tokenizer|CharFilter)Factory");
+      
   /**
    * This method loads a class either with it's FQN or a short-name (solr.class-simplename or class-simplename).
    * It tries to load the class with the name that is given first and if it fails, it tries all the known
@@ -394,6 +406,32 @@ public class SolrResourceLoader implemen
       }
     }
     Class<? extends T> clazz = null;
+    
+    // first try legacy analysis patterns, now replaced by Lucene's Analysis package:
+    final Matcher m = legacyAnalysisPattern.matcher(cname);
+    if (m.matches()) {
+      log.trace("Trying to load class from analysis SPI");
+      // retrieve the map of classLoader -> expectedType -> SPI from cache / regenerate cache
+      Map<Class<?>,AnalysisSPILoader<?>> spiLoaders = expectedTypesSPILoaders.get(classLoader);
+      if (spiLoaders == null) {
+        spiLoaders = new IdentityHashMap<Class<?>,AnalysisSPILoader<?>>(3);
+        spiLoaders.put(CharFilterFactory.class, CharFilterFactory.getSPILoader(classLoader));
+        spiLoaders.put(TokenizerFactory.class, TokenizerFactory.getSPILoader(classLoader));
+        spiLoaders.put(TokenFilterFactory.class, TokenFilterFactory.getSPILoader(classLoader));
+        expectedTypesSPILoaders.put(classLoader, spiLoaders);
+      }
+      @SuppressWarnings("unchecked") final AnalysisSPILoader<? extends T> loader =
+        (AnalysisSPILoader<? extends T>) spiLoaders.get(expectedType);
+      if (loader != null) {
+        // it's a correct expected type for analysis! Let's go on!
+        try {
+          return clazz = loader.lookupClass(m.group(4));
+        } catch (IllegalArgumentException ex) { 
+          // ok, we fall back to legacy loading
+        }
+      }
+    }
+    
     // first try cname == full name
     try {
       return Class.forName(cname, true, classLoader).asSubclass(expectedType);

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java Wed Jul 25 13:54:04 2012
@@ -19,9 +19,9 @@ package org.apache.solr.schema;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.core.KeywordAnalyzer;
+import org.apache.lucene.analysis.core.KeywordTokenizerFactory;
 import org.apache.lucene.analysis.util.*;
 import org.apache.lucene.util.Version;
-import org.apache.solr.analysis.KeywordTokenizerFactory;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.util.DOMUtil;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java Wed Jul 25 13:54:04 2012
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.core.StopFilterFactory;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 import org.apache.lucene.queries.function.BoostedQuery;
 import org.apache.lucene.queries.function.FunctionQuery;
@@ -36,7 +37,6 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.queryparser.classic.ParseException;
 import org.apache.lucene.queryparser.classic.QueryParser;
 import org.apache.lucene.search.*;
-import org.apache.solr.analysis.StopFilterFactory;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.search.SolrQueryParser.MagicFieldName;
 import org.apache.solr.common.params.DisMaxParams;

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestMultiWordSynonyms.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestMultiWordSynonyms.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestMultiWordSynonyms.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestMultiWordSynonyms.java Wed Jul 25 13:54:04 2012
@@ -20,6 +20,7 @@ package org.apache.solr.analysis;
 import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.synonym.SynonymFilterFactory;
 import org.apache.lucene.analysis.util.ResourceLoader;
 
 import java.io.ByteArrayInputStream;

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestWordDelimiterFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestWordDelimiterFilterFactory.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestWordDelimiterFilterFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/analysis/TestWordDelimiterFilterFactory.java Wed Jul 25 13:54:04 2012
@@ -1,3 +1,5 @@
+package org.apache.solr.analysis;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,8 +17,6 @@
  * limitations under the License.
  */
 
-package org.apache.solr.analysis;
-
 import java.io.StringReader;
 import java.util.HashMap;
 import java.util.Map;
@@ -25,6 +25,7 @@ import org.apache.lucene.analysis.BaseTo
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.solr.SolrTestCaseJ4;
+import org.apache.lucene.analysis.miscellaneous.WordDelimiterFilterFactory;
 import org.apache.lucene.analysis.util.ResourceLoader;
 import org.apache.solr.core.SolrResourceLoader;
 import org.junit.BeforeClass;
@@ -33,6 +34,7 @@ import org.junit.Test;
 /**
  * New WordDelimiterFilter tests... most of the tests are in ConvertedLegacyTest
  */
+// TODO: add a low-level test for this factory
 public class TestWordDelimiterFilterFactory extends SolrTestCaseJ4 {
 
   @BeforeClass

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java Wed Jul 25 13:54:04 2012
@@ -20,8 +20,8 @@ package org.apache.solr.core;
 import junit.framework.Assert;
 
 import org.apache.lucene.util.LuceneTestCase;
-import org.apache.solr.analysis.KeywordTokenizerFactory;
-import org.apache.solr.analysis.NGramFilterFactory;
+import org.apache.lucene.analysis.core.KeywordTokenizerFactory;
+import org.apache.lucene.analysis.ngram.NGramFilterFactory;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.handler.admin.LukeRequestHandler;
 import org.apache.solr.handler.component.FacetComponent;

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MultiTermTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MultiTermTest.java?rev=1365586&r1=1365585&r2=1365586&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MultiTermTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/MultiTermTest.java Wed Jul 25 13:54:04 2012
@@ -18,6 +18,12 @@ package org.apache.solr.schema;
  */
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.charfilter.MappingCharFilterFactory;
+import org.apache.lucene.analysis.core.KeywordTokenizerFactory;
+import org.apache.lucene.analysis.core.LowerCaseFilterFactory;
+import org.apache.lucene.analysis.core.WhitespaceTokenizerFactory;
+import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilterFactory;
+import org.apache.lucene.analysis.miscellaneous.TrimFilterFactory;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.analysis.*;