You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by to...@apache.org on 2019/06/30 03:29:02 UTC
[lucene-solr] branch branch_8x updated: LUCENE-8894: Add APIs to
tokenizer/charfilter/tokenfilter factories to get their SPI names from
concrete classes
This is an automated email from the ASF dual-hosted git repository.
tomoko pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/branch_8x by this push:
new 7e05bd7 LUCENE-8894: Add APIs to tokenizer/charfilter/tokenfilter factories to get their SPI names from concrete classes
7e05bd7 is described below
commit 7e05bd717309088d3b35cba6be0f70fd14b3c8d0
Author: Tomoko Uchida <to...@apache.org>
AuthorDate: Sun Jun 30 12:19:48 2019 +0900
LUCENE-8894: Add APIs to tokenizer/charfilter/tokenfilter factories to get their SPI names from concrete classes
---
lucene/CHANGES.txt | 2 ++
.../analysis/util/AbstractAnalysisFactory.java | 22 ++++++++++++
.../lucene/analysis/util/AnalysisSPILoader.java | 22 ++++--------
.../lucene/analysis/util/CharFilterFactory.java | 9 +++++
.../lucene/analysis/util/TokenFilterFactory.java | 11 +++++-
.../lucene/analysis/util/TokenizerFactory.java | 11 +++++-
.../analysis/util/TestAbstractAnalysisFactory.java | 41 ++++++++++++++++++++++
7 files changed, 100 insertions(+), 18 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index d8c2b62..5916656 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -111,6 +111,8 @@ Improvements
* LUCENE-8855: Add Accountable to some Query implementations (ab, Adrien Grand)
+* LUCENE-8894: Add APIs to find SPI names for Tokenizer/CharFilter/TokenFilter factory classes. (Tomoko Uchida)
+
Optimizations
* LUCENE-8796: Use exponential search instead of binary search in
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java
index 954f300..4253018 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java
@@ -21,6 +21,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
@@ -32,6 +34,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -336,4 +339,23 @@ public abstract class AbstractAnalysisFactory {
public void setExplicitLuceneMatchVersion(boolean isExplicitLuceneMatchVersion) {
this.isExplicitLuceneMatchVersion = isExplicitLuceneMatchVersion;
}
+
+ /**
+ * Looks up SPI name (static "NAME" field) with appropriate modifiers.
+ * Also it must be a String class and declared in the concrete class.
+ * @return the SPI name
+ * @throws NoSuchFieldException - if the "NAME" field is not defined.
+ * @throws IllegalAccessException - if the "NAME" field is inaccessible.
+ * @throws IllegalStateException - if the "NAME" field does not have appropriate modifiers or isn't a String field.
+ */
+ static String lookupSPIName(Class<? extends AbstractAnalysisFactory> service) throws NoSuchFieldException, IllegalAccessException, IllegalStateException {
+ final Field field = service.getField("NAME");
+ int modifier = field.getModifiers();
+ if (Modifier.isStatic(modifier) && Modifier.isFinal(modifier) &&
+ field.getType().equals(String.class) &&
+ Objects.equals(field.getDeclaringClass(), service)) {
+ return ((String) field.get(null));
+ }
+ throw new IllegalStateException("No SPI name defined.");
+ }
}
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java
index 57c4250..39c2c5a 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java
@@ -17,9 +17,7 @@
package org.apache.lucene.analysis.util;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Locale;
@@ -83,21 +81,13 @@ public final class AnalysisSPILoader<S extends AbstractAnalysisFactory> {
String originalName = null;
Throwable cause = null;
try {
- // Lookup "NAME" field with appropriate modifiers.
- // Also it must be a String class and declared in the service class.
- final Field field = service.getField("NAME");
- int modifier = field.getModifiers();
- if (Modifier.isStatic(modifier) && Modifier.isFinal(modifier) &&
- field.getType().equals(String.class) &&
- Objects.equals(field.getDeclaringClass(), service)) {
- originalName = ((String)field.get(null));
- name = originalName.toLowerCase(Locale.ROOT);
- if (!isValidName(originalName)) {
- throw new ServiceConfigurationError("The name " + originalName + " for " + service.getName() +
- " is invalid: Allowed characters are (English) alphabet, digits, and underscore. It should be started with an alphabet.");
- }
+ originalName = AbstractAnalysisFactory.lookupSPIName(service);
+ name = originalName.toLowerCase(Locale.ROOT);
+ if (!isValidName(originalName)) {
+ throw new ServiceConfigurationError("The name " + originalName + " for " + service.getName() +
+ " is invalid: Allowed characters are (English) alphabet, digits, and underscore. It should be started with an alphabet.");
}
- } catch (NoSuchFieldException | IllegalAccessException e) {
+ } catch (NoSuchFieldException | IllegalAccessException | IllegalStateException e) {
cause = e;
}
if (name == null) {
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
index 7a5eccb..722025c 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
@@ -49,6 +49,15 @@ public abstract class CharFilterFactory extends AbstractAnalysisFactory {
return loader.availableServices();
}
+ /** looks up a SPI name for the specified char filter factory */
+ public static String findSPIName(Class<? extends CharFilterFactory> serviceClass) {
+ try {
+ return lookupSPIName(serviceClass);
+ } catch (NoSuchFieldException | IllegalAccessException | IllegalStateException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
/**
* Reloads the factory list from the given {@link ClassLoader}.
* Changes to the factories are visible after the method ends, all
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
index 72c4070..1d7d5c7 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
@@ -47,7 +47,16 @@ public abstract class TokenFilterFactory extends AbstractAnalysisFactory {
public static Set<String> availableTokenFilters() {
return loader.availableServices();
}
-
+
+ /** looks up a SPI name for the specified token filter factory */
+ public static String findSPIName(Class<? extends TokenFilterFactory> serviceClass) {
+ try {
+ return lookupSPIName(serviceClass);
+ } catch (NoSuchFieldException | IllegalAccessException | IllegalStateException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
/**
* Reloads the factory list from the given {@link ClassLoader}.
* Changes to the factories are visible after the method ends, all
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
index 8b3e1f9..2cd3a15 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
@@ -49,7 +49,16 @@ public abstract class TokenizerFactory extends AbstractAnalysisFactory {
public static Set<String> availableTokenizers() {
return loader.availableServices();
}
-
+
+ /** looks up a SPI name for the specified tokenizer factory */
+ public static String findSPIName(Class<? extends TokenizerFactory> serviceClass) {
+ try {
+ return lookupSPIName(serviceClass);
+ } catch (NoSuchFieldException | IllegalAccessException | IllegalStateException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
/**
* Reloads the factory list from the given {@link ClassLoader}.
* Changes to the factories are visible after the method ends, all
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestAbstractAnalysisFactory.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestAbstractAnalysisFactory.java
new file mode 100644
index 0000000..b8d028e
--- /dev/null
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestAbstractAnalysisFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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.lucene.analysis.util;
+
+import org.apache.lucene.analysis.charfilter.HTMLStripCharFilterFactory;
+import org.apache.lucene.analysis.core.LowerCaseFilterFactory;
+import org.apache.lucene.analysis.core.WhitespaceTokenizerFactory;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestAbstractAnalysisFactory extends LuceneTestCase {
+
+ public void testLookupTokenizerSPIName() throws NoSuchFieldException, IllegalAccessException {
+ assertEquals("whitespace", AbstractAnalysisFactory.lookupSPIName(WhitespaceTokenizerFactory.class));
+ assertEquals("whitespace", TokenizerFactory.findSPIName(WhitespaceTokenizerFactory.class));
+ }
+
+ public void testLookupCharFilterSPIName() throws NoSuchFieldException, IllegalAccessException {
+ assertEquals("htmlStrip", AbstractAnalysisFactory.lookupSPIName(HTMLStripCharFilterFactory.class));
+ assertEquals("htmlStrip", CharFilterFactory.findSPIName(HTMLStripCharFilterFactory.class));
+ }
+
+ public void testLookupTokenFilterSPIName() throws NoSuchFieldException, IllegalAccessException{
+ assertEquals("lowercase", AbstractAnalysisFactory.lookupSPIName(LowerCaseFilterFactory.class));
+ assertEquals("lowercase", TokenFilterFactory.findSPIName(LowerCaseFilterFactory.class));
+ }
+}