You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2021/03/10 09:45:43 UTC
[lucene] 02/21: SOLR-14151: Support for packages in schema.xml
This is an automated email from the ASF dual-hosted git repository.
dweiss pushed a commit to branch jira/solr14155
in repository https://gitbox.apache.org/repos/asf/lucene.git
commit 2bec9e348d78032e739614c806bc58aac47c635b
Author: noble <no...@apache.org>
AuthorDate: Thu Dec 26 12:37:48 2019 +1100
SOLR-14151: Support for packages in schema.xml
---
.../src/java/org/apache/solr/core/ConfigSet.java | 15 ++-
.../org/apache/solr/core/ConfigSetService.java | 3 +-
.../src/java/org/apache/solr/core/PluginInfo.java | 47 ++++-----
.../java/org/apache/solr/core/PluginLoader.java | 30 ++++++
.../src/java/org/apache/solr/core/SolrCore.java | 19 +++-
.../org/apache/solr/core/SolrResourceLoader.java | 15 ++-
.../org/apache/solr/schema/CurrencyFieldType.java | 2 +-
.../apache/solr/schema/FieldTypePluginLoader.java | 12 ++-
.../java/org/apache/solr/schema/IndexSchema.java | 105 ++++++++++++++++++++-
.../org/apache/solr/schema/ManagedIndexSchema.java | 2 +-
.../org/apache/solr/schema/PreAnalyzedField.java | 5 +-
.../solr/util/plugin/AbstractPluginLoader.java | 11 ++-
.../org/apache/solr/core/TestCodecSupport.java | 4 +-
13 files changed, 217 insertions(+), 53 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSet.java b/solr/core/src/java/org/apache/solr/core/ConfigSet.java
index e0c9fe4..bfd5867 100644
--- a/solr/core/src/java/org/apache/solr/core/ConfigSet.java
+++ b/solr/core/src/java/org/apache/solr/core/ConfigSet.java
@@ -16,6 +16,8 @@
*/
package org.apache.solr.core;
+import java.util.function.Supplier;
+
import org.apache.solr.common.util.NamedList;
import org.apache.solr.schema.IndexSchema;
@@ -28,17 +30,17 @@ public class ConfigSet {
private final SolrConfig solrconfig;
- private final IndexSchema indexSchema;
+ private volatile Supplier<IndexSchema> indexSchemaSupplier;
private final NamedList properties;
private final boolean trusted;
- public ConfigSet(String name, SolrConfig solrConfig, IndexSchema indexSchema,
- NamedList properties, boolean trusted) {
+ public ConfigSet(String name, SolrConfig solrConfig, Supplier<IndexSchema> indexSchemaSupplier,
+ NamedList properties, boolean trusted) {
this.name = name;
this.solrconfig = solrConfig;
- this.indexSchema = indexSchema;
+ this.indexSchemaSupplier = indexSchemaSupplier;
this.properties = properties;
this.trusted = trusted;
}
@@ -51,8 +53,11 @@ public class ConfigSet {
return solrconfig;
}
+ public Supplier<IndexSchema> getIndexSchemaSupplier() {
+ return indexSchemaSupplier;
+ }
public IndexSchema getIndexSchema() {
- return indexSchema;
+ return indexSchemaSupplier.get();
}
public NamedList getProperties() {
diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
index bc0d4a9..9fa2f12 100644
--- a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
+++ b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
@@ -88,8 +88,7 @@ public abstract class ConfigSetService {
) ? false: true;
SolrConfig solrConfig = createSolrConfig(dcore, coreLoader, trusted);
- IndexSchema schema = createIndexSchema(dcore, solrConfig);
- return new ConfigSet(configName(dcore), solrConfig, schema, properties, trusted);
+ return new ConfigSet(configName(dcore), solrConfig, () -> createIndexSchema(dcore, solrConfig), properties, trusted);
} catch (Exception e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
"Could not load conf for core " + dcore.getName() +
diff --git a/solr/core/src/java/org/apache/solr/core/PluginInfo.java b/solr/core/src/java/org/apache/solr/core/PluginInfo.java
index bb290e1..afe4073 100644
--- a/solr/core/src/java/org/apache/solr/core/PluginInfo.java
+++ b/solr/core/src/java/org/apache/solr/core/PluginInfo.java
@@ -25,7 +25,6 @@ import java.util.Map;
import org.apache.solr.common.MapSerializable;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.common.util.Pair;
import org.apache.solr.util.DOMUtil;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -52,9 +51,9 @@ public class PluginInfo implements MapSerializable {
public PluginInfo(String type, Map<String, String> attrs, NamedList initArgs, List<PluginInfo> children) {
this.type = type;
this.name = attrs.get(NAME);
- Pair<String, String> parsed = parseClassName(attrs.get(CLASS_NAME));
- this.className = parsed.second();
- this.pkgName = parsed.first();
+ ClassName parsed = new ClassName(attrs.get(CLASS_NAME));
+ this.className = parsed.klas;
+ this.pkgName = parsed.pkg;
this.initArgs = initArgs;
attributes = unmodifiableMap(attrs);
this.children = children == null ? Collections.<PluginInfo>emptyList(): unmodifiableList(children);
@@ -63,29 +62,35 @@ public class PluginInfo implements MapSerializable {
/** class names can be prefixed with package name e.g: my_package:my.pkg.Class
* This checks if it is a package name prefixed classname.
- * the return value has first = package name & second = class name
*/
- static Pair<String,String > parseClassName(String name) {
- String pkgName = null;
- String className = name;
- if (name != null) {
- int colonIdx = name.indexOf(':');
- if (colonIdx > -1) {
- pkgName = name.substring(0, colonIdx);
- className = name.substring(colonIdx + 1);
+
+ public static class ClassName {
+ public final String pkg;
+ public final String klas;
+
+ public ClassName(String name) {
+ String pkgName = null;
+ String className = name;
+ if (name != null) {
+ int colonIdx = name.indexOf(':');
+ if (colonIdx > -1) {
+ pkgName = name.substring(0, colonIdx);
+ className = name.substring(colonIdx + 1);
+ }
}
- }
- return new Pair<>(pkgName, className);
+ this.klas = className;
+ this.pkg = pkgName;
+ }
}
public PluginInfo(Node node, String err, boolean requireName, boolean requireClass) {
type = node.getNodeName();
name = DOMUtil.getAttr(node, NAME, requireName ? err : null);
- Pair<String, String> parsed = parseClassName(DOMUtil.getAttr(node, CLASS_NAME, requireClass ? err : null));
- className = parsed.second();
- pkgName = parsed.first();
+ ClassName parsed = new ClassName(DOMUtil.getAttr(node, CLASS_NAME, requireClass ? err : null));
+ className = parsed.klas;
+ pkgName = parsed.pkg;
initArgs = DOMUtil.childNodesToNamedList(node);
attributes = unmodifiableMap(DOMUtil.toMap(node.getAttributes()));
children = loadSubPlugins(node);
@@ -115,9 +120,9 @@ public class PluginInfo implements MapSerializable {
}
this.type = type;
this.name = (String) m.get(NAME);
- Pair<String, String> parsed = parseClassName((String) m.get(CLASS_NAME));
- this.className = parsed.second();
- this.pkgName = parsed.first();
+ ClassName parsed = new ClassName((String) m.get(CLASS_NAME));
+ this.className = parsed.klas;
+ this.pkgName = parsed.pkg;
attributes = unmodifiableMap(m);
this.children = Collections.<PluginInfo>emptyList();
isFromSolrConfig = true;
diff --git a/solr/core/src/java/org/apache/solr/core/PluginLoader.java b/solr/core/src/java/org/apache/solr/core/PluginLoader.java
new file mode 100644
index 0000000..ef0bd94
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/core/PluginLoader.java
@@ -0,0 +1,30 @@
+/*
+ * 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.core;
+
+/**A generic interface to load classes
+ *
+ */
+public interface PluginLoader {
+
+ <T> T newInstance(String cname, Class<T> expectedType, String... subpackages);
+
+ <T> T newInstance(String cName, Class<T> expectedType, String[] subPackages, Class[] params, Object[] args);
+
+ <T> Class<? extends T> findClass(String cname, Class<T> expectedType);
+}
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index 2c6b175..e7c1be5 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -56,6 +56,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Supplier;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Timer;
@@ -173,6 +174,7 @@ import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.apache.lucene.util.IOUtils.closeWhileHandlingException;
import static org.apache.solr.common.params.CommonParams.NAME;
import static org.apache.solr.common.params.CommonParams.PATH;
@@ -238,6 +240,7 @@ public final class SolrCore implements SolrInfoBean, Closeable {
public volatile boolean searchEnabled = true;
public volatile boolean indexEnabled = true;
public volatile boolean readOnly = false;
+ private final Supplier<IndexSchema> schemaSupplier;
private PackageListeners packageListeners = new PackageListeners(this);
@@ -688,7 +691,7 @@ public final class SolrCore implements SolrInfoBean, Closeable {
CoreDescriptor cd = new CoreDescriptor(name, getCoreDescriptor());
cd.loadExtraProperties(); //Reload the extra properties
core = new SolrCore(coreContainer, getName(), getDataDir(), coreConfig.getSolrConfig(),
- coreConfig.getIndexSchema(), coreConfig.getProperties(),
+ () -> coreConfig.getIndexSchema(), coreConfig.getProperties(),
cd, updateHandler, solrDelPolicy, currentCore, true);
// we open a new IndexWriter to pick up the latest config
@@ -897,7 +900,7 @@ public final class SolrCore implements SolrInfoBean, Closeable {
}
public SolrCore(CoreContainer coreContainer, CoreDescriptor cd, ConfigSet coreConfig) {
- this(coreContainer, cd.getName(), null, coreConfig.getSolrConfig(), coreConfig.getIndexSchema(), coreConfig.getProperties(),
+ this(coreContainer, cd.getName(), null, coreConfig.getSolrConfig(), coreConfig.getIndexSchemaSupplier(), coreConfig.getProperties(),
cd, null, null, null, false);
}
@@ -905,6 +908,11 @@ public final class SolrCore implements SolrInfoBean, Closeable {
return coreContainer;
}
+ public void refreshSchema() {
+ IndexSchema old = schema;
+ schema = schemaSupplier.get();
+ closeWhileHandlingException(old);
+ }
/**
* Creates a new core and register it in the list of cores. If a core with the
@@ -912,11 +920,11 @@ public final class SolrCore implements SolrInfoBean, Closeable {
*
* @param dataDir the index directory
* @param config a solr config instance
- * @param schema a solr schema instance
+ * @param schemaSupplier a solr schema {@link Supplier}
* @since solr 1.3
*/
public SolrCore(CoreContainer coreContainer, String name, String dataDir, SolrConfig config,
- IndexSchema schema, NamedList configSetProperties,
+ Supplier<IndexSchema> schemaSupplier, NamedList configSetProperties,
CoreDescriptor coreDescriptor, UpdateHandler updateHandler,
IndexDeletionPolicyWrapper delPolicy, SolrCore prev, boolean reload) {
@@ -924,6 +932,7 @@ public final class SolrCore implements SolrInfoBean, Closeable {
this.coreContainer = coreContainer;
+ this.schemaSupplier = schemaSupplier;
final CountDownLatch latch = new CountDownLatch(1);
try {
@@ -935,6 +944,7 @@ public final class SolrCore implements SolrInfoBean, Closeable {
MDCLoggingContext.setCore(this);
resourceLoader = config.getResourceLoader();
+ resourceLoader.core = this;
this.solrConfig = config;
this.configSetProperties = configSetProperties;
// Initialize the metrics manager
@@ -959,6 +969,7 @@ public final class SolrCore implements SolrInfoBean, Closeable {
log.info("[{}] Opening new SolrCore at [{}], dataDir=[{}]", logid, resourceLoader.getInstancePath(),
this.dataDir);
+ IndexSchema schema = schemaSupplier.get();
checkVersionFieldExistsInSchema(schema, coreDescriptor);
// initialize core metrics
diff --git a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
index a57660e..46e2ecf 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
@@ -83,7 +83,7 @@ import org.slf4j.LoggerFactory;
/**
* @since solr 1.3
*/
-public class SolrResourceLoader implements ResourceLoader, Closeable {
+public class SolrResourceLoader implements ResourceLoader, PluginLoader, Closeable {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
static final String project = "solr";
@@ -118,6 +118,9 @@ public class SolrResourceLoader implements ResourceLoader, Closeable {
// (such as the SolrZkClient) when XML docs are being parsed.
private RestManager.Registry managedResourceRegistry;
+ //package private , only to be used from SolrCore
+ SolrCore core;
+
public synchronized RestManager.Registry getManagedResourceRegistry() {
if (managedResourceRegistry == null) {
managedResourceRegistry = new RestManager.Registry();
@@ -149,6 +152,15 @@ public class SolrResourceLoader implements ResourceLoader, Closeable {
}
+ /**
+ * This could be null if it is not associated with a core yet
+ *
+ */
+ public SolrCore getCore() {
+ return core;
+
+ }
+
public SolrResourceLoader(Path instanceDir) {
this(instanceDir, null, null);
@@ -615,6 +627,7 @@ public class SolrResourceLoader implements ResourceLoader, Closeable {
private static final Class[] NO_CLASSES = new Class[0];
private static final Object[] NO_OBJECTS = new Object[0];
+ @Override
public <T> T newInstance(String cname, Class<T> expectedType, String... subpackages) {
return newInstance(cname, expectedType, subpackages, NO_CLASSES, NO_OBJECTS);
}
diff --git a/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java b/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java
index 4e59212..0511830 100644
--- a/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java
@@ -121,7 +121,7 @@ public class CurrencyFieldType extends FieldType implements SchemaAware, Resourc
}
try {
Class<? extends ExchangeRateProvider> c
- = schema.getResourceLoader().findClass(exchangeRateProviderClass, ExchangeRateProvider.class);
+ = schema.getPluginLoader().findClass(exchangeRateProviderClass, ExchangeRateProvider.class);
provider = c.getConstructor().newInstance();
provider.init(args);
} catch (Exception e) {
diff --git a/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java b/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
index 781e199..b72b835 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
@@ -34,6 +34,7 @@ import org.apache.lucene.analysis.util.TokenizerFactory;
import org.apache.lucene.util.Version;
import org.apache.solr.analysis.TokenizerChain;
import org.apache.solr.common.SolrException;
+import org.apache.solr.core.PluginLoader;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.util.DOMUtil;
@@ -78,7 +79,7 @@ public final class FieldTypePluginLoader
@Override
- protected FieldType create( SolrResourceLoader loader,
+ protected FieldType create( PluginLoader loader,
String name,
String className,
Node node ) throws Exception {
@@ -192,6 +193,7 @@ public final class FieldTypePluginLoader
private Analyzer readAnalyzer(Node node) throws XPathExpressionException {
final SolrResourceLoader loader = schema.getResourceLoader();
+ final PluginLoader pluginLoader = schema.getPluginLoader();
// parent node used to be passed in as "fieldtype"
// if (!fieldtype.hasChildNodes()) return null;
@@ -226,7 +228,7 @@ public final class FieldTypePluginLoader
try {
// No need to be core-aware as Analyzers are not in the core-aware list
- final Class<? extends Analyzer> clazz = loader.findClass(analyzerName, Analyzer.class);
+ final Class<? extends Analyzer> clazz = pluginLoader.findClass(analyzerName, Analyzer.class);
Analyzer analyzer = clazz.getConstructor().newInstance();
final String matchVersionStr = DOMUtil.getAttr(attrs, LUCENE_MATCH_VERSION_PARAM);
@@ -256,7 +258,7 @@ public final class FieldTypePluginLoader
("[schema.xml] analyzer/charFilter", CharFilterFactory.class, false, false) {
@Override
- protected CharFilterFactory create(SolrResourceLoader loader, String name, String className, Node node) throws Exception {
+ protected CharFilterFactory create(PluginLoader loader, String name, String className, Node node) throws Exception {
final Map<String,String> params = DOMUtil.toMap(node.getAttributes());
String configuredVersion = params.remove(LUCENE_MATCH_VERSION_PARAM);
params.put(LUCENE_MATCH_VERSION_PARAM, parseConfiguredVersion(configuredVersion, CharFilterFactory.class.getSimpleName()).toString());
@@ -306,7 +308,7 @@ public final class FieldTypePluginLoader
("[schema.xml] analyzer/tokenizer", TokenizerFactory.class, false, false) {
@Override
- protected TokenizerFactory create(SolrResourceLoader loader, String name, String className, Node node) throws Exception {
+ protected TokenizerFactory create(PluginLoader loader, String name, String className, Node node) throws Exception {
final Map<String,String> params = DOMUtil.toMap(node.getAttributes());
String configuredVersion = params.remove(LUCENE_MATCH_VERSION_PARAM);
params.put(LUCENE_MATCH_VERSION_PARAM, parseConfiguredVersion(configuredVersion, TokenizerFactory.class.getSimpleName()).toString());
@@ -360,7 +362,7 @@ public final class FieldTypePluginLoader
new AbstractPluginLoader<TokenFilterFactory>("[schema.xml] analyzer/filter", TokenFilterFactory.class, false, false)
{
@Override
- protected TokenFilterFactory create(SolrResourceLoader loader, String name, String className, Node node) throws Exception {
+ protected TokenFilterFactory create(PluginLoader loader, String name, String className, Node node) throws Exception {
final Map<String,String> params = DOMUtil.toMap(node.getAttributes());
String configuredVersion = params.remove(LUCENE_MATCH_VERSION_PARAM);
params.put(LUCENE_MATCH_VERSION_PARAM, parseConfiguredVersion(configuredVersion, TokenFilterFactory.class.getSimpleName()).toString());
diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
index 5f213d3..407c4d1 100644
--- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
@@ -19,6 +19,7 @@ package org.apache.solr.schema;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
+import java.io.Closeable;
import java.io.IOException;
import java.io.Writer;
import java.lang.invoke.MethodHandles;
@@ -60,9 +61,13 @@ import org.apache.solr.common.util.Cache;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.Pair;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.core.PluginInfo;
+import org.apache.solr.core.PluginLoader;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.core.XmlConfigFile;
+import org.apache.solr.pkg.PackageListeners;
+import org.apache.solr.pkg.PackageLoader;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.response.SchemaXmlWriter;
import org.apache.solr.response.SolrQueryResponse;
@@ -91,7 +96,7 @@ import static java.util.Collections.singletonMap;
*
*
*/
-public class IndexSchema {
+public class IndexSchema implements Closeable {
public static final String COPY_FIELD = "copyField";
public static final String COPY_FIELDS = COPY_FIELD + "s";
public static final String DEFAULT_SCHEMA_FILE = "schema.xml";
@@ -133,6 +138,7 @@ public class IndexSchema {
protected final Version luceneVersion;
protected float version;
protected final SolrResourceLoader loader;
+ protected final PluginLoader pluginLoader;
protected Map<String,SchemaField> fields = new HashMap<>();
protected Map<String,FieldType> fieldTypes = new HashMap<>();
@@ -163,6 +169,7 @@ public class IndexSchema {
*/
protected Map<SchemaField, Integer> copyFieldTargetCounts = new HashMap<>();
+
/**
* Constructs a schema using the specified resource name and stream.
* @see SolrResourceLoader#openSchema
@@ -181,9 +188,95 @@ public class IndexSchema {
}
}
+ public PluginLoader getPluginLoader(){
+ return pluginLoader;
+ }
protected IndexSchema(Version luceneVersion, SolrResourceLoader loader) {
this.luceneVersion = Objects.requireNonNull(luceneVersion);
this.loader = loader;
+ if(loader.getCore() == null) {
+ this.pluginLoader = loader;
+ } else {
+ PackageAwarePluginLoader papl = new PackageAwarePluginLoader(loader.getCore());
+ this.pluginLoader = papl;
+ }
+ }
+
+ class PackageAwarePluginLoader implements PluginLoader, Closeable {
+ final SolrCore core;
+ private final List<PackageListeners.Listener> listeners = new ArrayList<>();
+ Runnable reloadSchemaRunnable = () -> getCore().refreshSchema();
+
+
+ PackageAwarePluginLoader(SolrCore core) {
+ this.core = core;
+ }
+
+ SolrCore getCore() {
+ return core;
+ }
+
+ @Override
+ public <T> T newInstance(String cname, Class<T> expectedType, String... subpackages) {
+ return getIt(cname, expectedType, pkgloader -> pkgloader.newInstance(cname, expectedType, subpackages));
+ }
+
+ private <T> T getIt(String cname, Class expectedType, Function<SolrResourceLoader, T> fun) {
+ PluginInfo.ClassName className = new PluginInfo.ClassName(cname);
+ if (className.pkg == null) {
+ return fun.apply(loader);
+ } else {
+ SolrResourceLoader pkgloader = core.getResourceLoader(className.pkg);
+ T inst = fun.apply(pkgloader);
+ PackageListeners.Listener listener = new PackageListeners.Listener() {
+ PluginInfo info = new PluginInfo(expectedType.getSimpleName(), singletonMap("class", cname));
+
+ @Override
+ public String packageName() {
+ return className.pkg;
+ }
+
+ @Override
+ public PluginInfo pluginInfo() {
+ return info;
+ }
+
+ @Override
+ public void changed(PackageLoader.Package pkg, PackageListeners.Ctx ctx) {
+ Runnable old = ctx.getPostProcessor(PackageAwarePluginLoader.class.getName());// just want to do one refresh for every package laod
+ if (old == null) ctx.addPostProcessor(PackageAwarePluginLoader.class.getName(), reloadSchemaRunnable);
+ }
+
+ @Override
+ public PackageLoader.Package.Version getPackageVersion() {
+ return null;
+ }
+ };
+ listeners.add(listener);
+ core.getPackageListeners().addListener(listener);
+ return inst;
+ }
+ }
+
+ @Override
+ public <T> Class<? extends T> findClass(String cname, Class<T> expectedType) {
+ return getIt(cname, expectedType, (Function<SolrResourceLoader, Class<? extends T>>) loader -> loader.findClass(cname, expectedType));
+ }
+
+ @Override
+ public <T> T newInstance(String cName, Class<T> expectedType, String[] subPackages, Class[] params, Object[] args) {
+ return getIt(cName, expectedType, loader -> loader.newInstance(cName, expectedType, subPackages, params, args));
+ }
+
+
+
+ @Override
+ public void close() throws IOException {
+ for (PackageListeners.Listener l : listeners) {
+ core.getPackageListeners().removeListener(l);
+ }
+
+ }
}
/**
@@ -497,7 +590,7 @@ public class IndexSchema {
if (similarityFactory == null) {
final Class<?> simClass = SchemaSimilarityFactory.class;
// use the loader to ensure proper SolrCoreAware handling
- similarityFactory = loader.newInstance(simClass.getName(), SimilarityFactory.class);
+ similarityFactory = pluginLoader.newInstance(simClass.getName(), SimilarityFactory.class);
similarityFactory.init(new ModifiableSolrParams());
} else {
isExplicitSimilarity = true;
@@ -971,7 +1064,7 @@ public class IndexSchema {
dynamicCopyFields = temp;
}
- static SimilarityFactory readSimilarity(SolrResourceLoader loader, Node node) {
+ static SimilarityFactory readSimilarity(PluginLoader loader, Node node) {
if (node==null) {
return null;
} else {
@@ -1981,4 +2074,10 @@ public class IndexSchema {
return decoders.computeIfAbsent(ft, f -> PayloadUtils.getPayloadDecoder(ft));
}
+ @Override
+ public void close() throws IOException {
+ if (pluginLoader instanceof PackageAwarePluginLoader) {
+ ((PackageAwarePluginLoader) pluginLoader).close();
+ }
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
index 57b0c90..d65ece9 100644
--- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
@@ -1272,7 +1272,7 @@ public final class ManagedIndexSchema extends IndexSchema {
Map<String,FieldType> newFieldTypes = new HashMap<>();
List<SchemaAware> schemaAwareList = new ArrayList<>();
FieldTypePluginLoader typeLoader = new FieldTypePluginLoader(this, newFieldTypes, schemaAwareList);
- typeLoader.loadSingle(loader, FieldTypeXmlAdapter.toNode(options));
+ typeLoader.loadSingle(pluginLoader, FieldTypeXmlAdapter.toNode(options));
FieldType ft = newFieldTypes.get(typeName);
if (!schemaAwareList.isEmpty())
schemaAware.addAll(schemaAwareList);
diff --git a/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java b/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java
index 00da7ed..9a5683f 100644
--- a/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java
+++ b/solr/core/src/java/org/apache/solr/schema/PreAnalyzedField.java
@@ -15,6 +15,7 @@
* limitations under the License.
*/
package org.apache.solr.schema;
+
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
@@ -36,8 +37,8 @@ import org.apache.lucene.queries.function.valuesource.SortedSetFieldSource;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedSetSelector;
import org.apache.lucene.util.AttributeFactory;
-import org.apache.lucene.util.AttributeSource.State;
import org.apache.lucene.util.AttributeSource;
+import org.apache.lucene.util.AttributeSource.State;
import org.apache.solr.analysis.SolrAnalyzer;
import org.apache.solr.response.TextResponseWriter;
import org.apache.solr.search.QParser;
@@ -79,7 +80,7 @@ public class PreAnalyzedField extends TextField implements HasImplicitIndexAnaly
parser = new SimplePreAnalyzedParser();
} else {
try {
- Class<? extends PreAnalyzedParser> implClazz = schema.getResourceLoader().findClass(implName, PreAnalyzedParser.class);
+ Class<? extends PreAnalyzedParser> implClazz = schema.getPluginLoader().findClass(implName, PreAnalyzedParser.class);
Constructor<?> c = implClazz.getConstructor(new Class<?>[0]);
parser = (PreAnalyzedParser) c.newInstance(new Object[0]);
} catch (Exception e) {
diff --git a/solr/core/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java b/solr/core/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
index 1243017..5be8ab4 100644
--- a/solr/core/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
+++ b/solr/core/src/java/org/apache/solr/util/plugin/AbstractPluginLoader.java
@@ -23,7 +23,7 @@ import java.util.Objects;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.core.SolrResourceLoader;
+import org.apache.solr.core.PluginLoader;
import org.apache.solr.util.DOMUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -86,11 +86,11 @@ public abstract class AbstractPluginLoader<T>
* @param node - the XML node defining this plugin
*/
@SuppressWarnings("unchecked")
- protected T create( SolrResourceLoader loader, String name, String className, Node node ) throws Exception
+ protected T create(PluginLoader loader, String name, String className, Node node ) throws Exception
{
return loader.newInstance(className, pluginClassType, getDefaultPackages());
}
-
+
/**
* Register a plugin with a given name.
* @return The plugin previously registered to this name, or null
@@ -135,7 +135,7 @@ public abstract class AbstractPluginLoader<T>
* If a default element is defined, it will be returned from this function.
*
*/
- public T load( SolrResourceLoader loader, NodeList nodes )
+ public T load(PluginLoader loader, NodeList nodes )
{
List<PluginInitInfo> info = new ArrayList<>();
T defaultPlugin = null;
@@ -223,7 +223,7 @@ public abstract class AbstractPluginLoader<T>
* The created class for the plugin will be returned from this function.
*
*/
- public T loadSingle(SolrResourceLoader loader, Node node) {
+ public T loadSingle(PluginLoader loader, Node node) {
List<PluginInitInfo> info = new ArrayList<>();
T plugin = null;
@@ -280,4 +280,5 @@ public abstract class AbstractPluginLoader<T>
this.node = node;
}
}
+
}
diff --git a/solr/core/src/test/org/apache/solr/core/TestCodecSupport.java b/solr/core/src/test/org/apache/solr/core/TestCodecSupport.java
index a3daeb8..ec9eef4 100644
--- a/solr/core/src/test/org/apache/solr/core/TestCodecSupport.java
+++ b/solr/core/src/test/org/apache/solr/core/TestCodecSupport.java
@@ -30,7 +30,6 @@ import org.apache.lucene.util.TestUtil;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
-import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.IndexSchemaFactory;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.util.TestHarness;
@@ -203,7 +202,6 @@ public class TestCodecSupport extends SolrTestCaseJ4 {
assertEquals("Unexpected codec factory for this test.", "solr.SchemaCodecFactory", config.get("codecFactory/@class"));
assertNull("Unexpected configuration of codec factory for this test. Expecting empty element",
config.getNode("codecFactory", false).getFirstChild());
- IndexSchema schema = IndexSchemaFactory.buildIndexSchema("schema_codec.xml", config);
CoreContainer coreContainer = h.getCoreContainer();
@@ -211,7 +209,7 @@ public class TestCodecSupport extends SolrTestCaseJ4 {
CoreDescriptor cd = new CoreDescriptor(newCoreName, testSolrHome.resolve(newCoreName),
coreContainer.getContainerProperties(), coreContainer.isZooKeeperAware());
c = new SolrCore(coreContainer, cd,
- new ConfigSet("fakeConfigset", config, schema, null, true));
+ new ConfigSet("fakeConfigset", config, () -> IndexSchemaFactory.buildIndexSchema("schema_codec.xml", config), null, true));
assertNull(coreContainer.registerCore(cd, c, false, false));
h.coreName = newCoreName;
assertEquals("We are not using the correct core", "solrconfig_codec2.xml", h.getCore().getConfigResource());