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/24 20:44:41 UTC
svn commit: r1365215 - in /lucene/dev/branches/lucene2510:
lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/
lucene/analysis/common/src/java/org/apache/lucene/analysis/util/
solr/core/src/java/org/apache/solr/analysis/ solr/core/src/j...
Author: uschindler
Date: Tue Jul 24 18:44:40 2012
New Revision: 1365215
URL: http://svn.apache.org/viewvc?rev=1365215&view=rev
Log:
LUCENE-2510: Make the SOLR backwards layer be implemented directly inside SolrResourceLoader (sorry for the generics and still needed suppress warnings... - maybe somebody has an idea for the map inside map)
Removed:
lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/analysis/AnalysisPluginLoader.java
Modified:
lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java
lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java
lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
Modified: lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java (original)
+++ lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java Tue Jul 24 18:44:40 2012
@@ -152,7 +152,6 @@ public class SynonymFilterFactory extend
return parser.build();
}
- // nocommit: spi-hack solr.xxx and o.a.solr.analysis.xxx via a delegator
// (there are no tests for this functionality)
private TokenizerFactory loadTokenizerFactory(ResourceLoader loader, String cname){
TokenizerFactory tokFactory = loader.newInstance(cname, TokenizerFactory.class);
Modified: lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java (original)
+++ lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java Tue Jul 24 18:44:40 2012
@@ -28,7 +28,7 @@ import org.apache.lucene.util.SPIClassIt
* Helper class for loading named SPIs from classpath (e.g. Tokenizers, TokenStreams).
* @lucene.internal
*/
-final class AnalysisSPILoader<S extends AbstractAnalysisFactory> {
+public final class AnalysisSPILoader<S extends AbstractAnalysisFactory> {
private final Map<String,Class<? extends S>> services;
private final Class<S> clazz;
@@ -37,9 +37,17 @@ final class AnalysisSPILoader<S extends
this(clazz, new String[] { clazz.getSimpleName() });
}
+ public AnalysisSPILoader(Class<S> clazz, ClassLoader loader) {
+ this(clazz, new String[] { clazz.getSimpleName() }, loader);
+ }
+
public AnalysisSPILoader(Class<S> clazz, String[] suffixes) {
+ this(clazz, suffixes, Thread.currentThread().getContextClassLoader());
+ }
+
+ public AnalysisSPILoader(Class<S> clazz, String[] suffixes, ClassLoader classloader) {
this.clazz = clazz;
- final SPIClassIterator<S> loader = SPIClassIterator.get(clazz);
+ final SPIClassIterator<S> loader = SPIClassIterator.get(clazz, classloader);
final LinkedHashMap<String,Class<? extends S>> services = new LinkedHashMap<String,Class<? extends S>>();
while (loader.hasNext()) {
final Class<? extends S> service = loader.next();
Modified: lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java (original)
+++ lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java Tue Jul 24 18:44:40 2012
@@ -29,13 +29,23 @@ import org.apache.lucene.analysis.CharFi
public abstract class CharFilterFactory extends AbstractAnalysisFactory {
private static final AnalysisSPILoader<CharFilterFactory> loader =
- new AnalysisSPILoader<CharFilterFactory>(CharFilterFactory.class);
+ getSPILoader(Thread.currentThread().getContextClassLoader());
- /** looks up a charfilter by name */
+ /**
+ * 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);
}
Modified: lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java (original)
+++ lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java Tue Jul 24 18:44:40 2012
@@ -28,19 +28,29 @@ import org.apache.lucene.analysis.TokenS
public abstract class TokenFilterFactory extends AbstractAnalysisFactory {
private static final AnalysisSPILoader<TokenFilterFactory> loader =
- new AnalysisSPILoader<TokenFilterFactory>(TokenFilterFactory.class,
- new String[] { "TokenFilterFactory", "FilterFactory" });
+ getSPILoader(Thread.currentThread().getContextClassLoader());
- /** looks up a tokenfilter by name */
+ /**
+ * 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 */
+ /** returns a list of all available tokenfilter names from context classpath */
public static Set<String> availableTokenFilters() {
return loader.availableServices();
}
Modified: lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java (original)
+++ lucene/dev/branches/lucene2510/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java Tue Jul 24 18:44:40 2012
@@ -29,18 +29,28 @@ import java.util.Set;
public abstract class TokenizerFactory extends AbstractAnalysisFactory {
private static final AnalysisSPILoader<TokenizerFactory> loader =
- new AnalysisSPILoader<TokenizerFactory>(TokenizerFactory.class);
+ getSPILoader(Thread.currentThread().getContextClassLoader());
- /** looks up a tokenizer by name */
+ /**
+ * 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 */
+ /** returns a list of all available tokenizer names from context classpath */
public static Set<String> availableTokenizers() {
return loader.availableServices();
}
Modified: lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java (original)
+++ lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java Tue Jul 24 18:44:40 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,33 @@ 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<?>>();
+ 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);
+ }
+ AnalysisSPILoader<? extends AbstractAnalysisFactory> loader = spiLoaders.get(expectedType);
+ if (loader != null) {
+ // it's a correct expected type for analysis! Let's go on!
+ try {
+ @SuppressWarnings("unchecked")
+ final Class<? extends T> cl = (Class<? extends T>) loader.lookupClass(m.group(4));
+ return clazz = cl;
+ } 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/branches/lucene2510/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java?rev=1365215&r1=1365214&r2=1365215&view=diff
==============================================================================
--- lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java (original)
+++ lucene/dev/branches/lucene2510/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java Tue Jul 24 18:44:40 2012
@@ -22,7 +22,6 @@ import org.apache.lucene.analysis.core.K
import org.apache.lucene.analysis.core.KeywordTokenizerFactory;
import org.apache.lucene.analysis.util.*;
import org.apache.lucene.util.Version;
-import org.apache.solr.analysis.AnalysisPluginLoader;
import org.apache.solr.analysis.TokenizerChain;
import org.apache.solr.common.SolrException;
import org.apache.solr.util.DOMUtil;
@@ -263,16 +262,11 @@ public final class FieldTypePluginLoader
final ArrayList<CharFilterFactory> charFilters
= new ArrayList<CharFilterFactory>();
- AnalysisPluginLoader<CharFilterFactory> charFilterLoader =
- new AnalysisPluginLoader<CharFilterFactory>
+ AbstractPluginLoader<CharFilterFactory> charFilterLoader =
+ new AbstractPluginLoader<CharFilterFactory>
("[schema.xml] analyzer/charFilter", CharFilterFactory.class, false, false) {
@Override
- protected Class<? extends CharFilterFactory> lookupSPI(String name) {
- return CharFilterFactory.lookupClass(name);
- }
-
- @Override
protected void init(CharFilterFactory plugin, Node node) throws Exception {
if( plugin != null ) {
final Map<String,String> params = DOMUtil.toMapExcept(node.getAttributes(),"class");
@@ -301,15 +295,9 @@ public final class FieldTypePluginLoader
final ArrayList<TokenizerFactory> tokenizers
= new ArrayList<TokenizerFactory>(1);
- AnalysisPluginLoader<TokenizerFactory> tokenizerLoader =
- new AnalysisPluginLoader<TokenizerFactory>
+ AbstractPluginLoader<TokenizerFactory> tokenizerLoader =
+ new AbstractPluginLoader<TokenizerFactory>
("[schema.xml] analyzer/tokenizer", TokenizerFactory.class, false, false) {
-
- @Override
- protected Class<? extends TokenizerFactory> lookupSPI(String name) {
- return TokenizerFactory.lookupClass(name);
- }
-
@Override
protected void init(TokenizerFactory plugin, Node node) throws Exception {
if( !tokenizers.isEmpty() ) {
@@ -344,15 +332,9 @@ public final class FieldTypePluginLoader
final ArrayList<TokenFilterFactory> filters
= new ArrayList<TokenFilterFactory>();
- AnalysisPluginLoader<TokenFilterFactory> filterLoader =
- new AnalysisPluginLoader<TokenFilterFactory>("[schema.xml] analyzer/filter", TokenFilterFactory.class, false, false)
+ AbstractPluginLoader<TokenFilterFactory> filterLoader =
+ new AbstractPluginLoader<TokenFilterFactory>("[schema.xml] analyzer/filter", TokenFilterFactory.class, false, false)
{
-
- @Override
- protected Class<? extends TokenFilterFactory> lookupSPI(String name) {
- return TokenFilterFactory.lookupClass(name);
- }
-
@Override
protected void init(TokenFilterFactory plugin, Node node) throws Exception {
if( plugin != null ) {