From 57f695b14d8ad9f156bc06518a8c86058b813bd5 Mon Sep 17 00:00:00 2001 From: Tomoko Uchida Date: Sat, 27 Nov 2021 15:36:38 +0900 Subject: [PATCH] LUCENE-10261: clean up reflection stuff in luke module and make minor adjustments (#480) --- .../components/AnalysisPanelProvider.java | 2 - .../menubar/OpenIndexDialogFactory.java | 18 +-- .../search/AnalyzerPaneProvider.java | 6 +- .../luke/models/analysis/AnalysisImpl.java | 10 +- .../luke/util/reflection/ClassScanner.java | 113 ------------------ .../util/reflection/SubtypeCollector.java | 102 ---------------- .../luke/util/reflection/package-info.java | 19 --- .../models/analysis/TestAnalysisImpl.java | 8 +- 8 files changed, 20 insertions(+), 258 deletions(-) delete mode 100644 lucene/luke/src/java/org/apache/lucene/luke/util/reflection/ClassScanner.java delete mode 100644 lucene/luke/src/java/org/apache/lucene/luke/util/reflection/SubtypeCollector.java delete mode 100644 lucene/luke/src/java/org/apache/lucene/luke/util/reflection/package-info.java diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/AnalysisPanelProvider.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/AnalysisPanelProvider.java index 97abc968b31..d443265f4b6 100644 --- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/AnalysisPanelProvider.java +++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/AnalysisPanelProvider.java @@ -37,7 +37,6 @@ import javax.swing.JSplitPane; import javax.swing.JTextArea; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.custom.CustomAnalyzer; -import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.luke.app.desktop.MessageBroker; import org.apache.lucene.luke.app.desktop.components.dialog.analysis.AnalysisChainDialogFactory; import org.apache.lucene.luke.app.desktop.components.dialog.analysis.TokenAttributeDialogFactory; @@ -100,7 +99,6 @@ public final class AnalysisPanelProvider implements AnalysisTabOperator { this.messageBroker = MessageBroker.getInstance(); this.analysisModel = new AnalysisFactory().newInstance(); - analysisModel.createAnalyzerFromClassName(StandardAnalyzer.class.getName()); this.simpleResult = new SimpleAnalyzeResultPanelProvider(tokenAttrDialogFactory).get(); this.stepByStepResult = new StepByStepAnalyzeResultPanelProvider(tokenAttrDialogFactory).get(); diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java index 8ed2bd825af..9627a158638 100644 --- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java +++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java @@ -29,12 +29,9 @@ import java.lang.invoke.MethodHandles; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.stream.Collectors; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; @@ -59,8 +56,8 @@ import org.apache.lucene.luke.app.desktop.util.MessageUtils; import org.apache.lucene.luke.app.desktop.util.StyleConstants; import org.apache.lucene.luke.models.LukeException; import org.apache.lucene.luke.util.LoggerFactory; -import org.apache.lucene.luke.util.reflection.ClassScanner; -import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.MMapDirectory; +import org.apache.lucene.store.NIOFSDirectory; import org.apache.lucene.util.NamedThreadFactory; import org.apache.lucene.util.SuppressForbidden; @@ -258,16 +255,7 @@ public final class OpenIndexDialogFactory implements DialogOpener.DialogFactory } private String[] supportedDirImpls() { - // supports FS-based built-in implementations - ClassScanner scanner = new ClassScanner("org.apache.lucene.store", getClass().getClassLoader()); - Set> clazzSet = scanner.scanSubTypes(FSDirectory.class); - - List clazzNames = new ArrayList<>(); - clazzNames.add(FSDirectory.class.getName()); - clazzNames.addAll(clazzSet.stream().map(Class::getName).collect(Collectors.toList())); - - String[] result = new String[clazzNames.size()]; - return clazzNames.toArray(result); + return new String[] {MMapDirectory.class.getName(), NIOFSDirectory.class.getName()}; } private JPanel buttons() { diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/fragments/search/AnalyzerPaneProvider.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/fragments/search/AnalyzerPaneProvider.java index 75c7c2728f2..d6c77c057a3 100644 --- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/fragments/search/AnalyzerPaneProvider.java +++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/fragments/search/AnalyzerPaneProvider.java @@ -37,19 +37,19 @@ import javax.swing.JSeparator; import javax.swing.JTextField; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.custom.CustomAnalyzer; -import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.luke.app.desktop.components.ComponentOperatorRegistry; import org.apache.lucene.luke.app.desktop.components.TabSwitcherProxy; import org.apache.lucene.luke.app.desktop.components.TabbedPaneProvider; import org.apache.lucene.luke.app.desktop.util.FontUtils; import org.apache.lucene.luke.app.desktop.util.MessageUtils; +import org.apache.lucene.luke.models.analysis.AnalysisFactory; /** Provider of the Analyzer pane */ public final class AnalyzerPaneProvider implements AnalyzerTabOperator { private final TabSwitcherProxy tabSwitcher; - private final JLabel analyzerNameLbl = new JLabel(StandardAnalyzer.class.getName()); + private final JLabel analyzerNameLbl = new JLabel(); private final JList charFilterList = new JList<>(); @@ -59,6 +59,8 @@ public final class AnalyzerPaneProvider implements AnalyzerTabOperator { public AnalyzerPaneProvider() { this.tabSwitcher = TabSwitcherProxy.getInstance(); + this.analyzerNameLbl.setText( + new AnalysisFactory().newInstance().currentAnalyzer().getClass().getName()); ComponentOperatorRegistry.getInstance().register(AnalyzerTabOperator.class, this); } diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java b/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java index 7c5c0015bcc..e68383c507e 100644 --- a/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java +++ b/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java @@ -50,7 +50,7 @@ import org.apache.lucene.util.IOUtils; /** Default implementation of {@link AnalysisImpl} */ public final class AnalysisImpl implements Analysis { - private Analyzer analyzer; + private Analyzer analyzer = defaultAnalyzer(); @Override public void addExternalJars(List jarFiles) { @@ -152,6 +152,14 @@ public final class AnalysisImpl implements Analysis { } } + private Analyzer defaultAnalyzer() { + try { + return CustomAnalyzer.builder().withTokenizer("standard").build(); + } catch (IOException e) { + throw new LukeException("Failed to build custom analyzer.", e); + } + } + @Override public Analyzer buildCustomAnalyzer(CustomAnalyzerConfig config) { Objects.requireNonNull(config); diff --git a/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/ClassScanner.java b/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/ClassScanner.java deleted file mode 100644 index ec199b70288..00000000000 --- a/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/ClassScanner.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.luke.util.reflection; - -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import org.apache.logging.log4j.Logger; -import org.apache.lucene.luke.util.LoggerFactory; -import org.apache.lucene.util.NamedThreadFactory; - -/** Utility class for scanning class files in jars. */ -public class ClassScanner { - - private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private final String packageName; - private final ClassLoader[] classLoaders; - - public ClassScanner(String packageName, ClassLoader... classLoaders) { - this.packageName = packageName; - this.classLoaders = classLoaders; - } - - public Set> scanSubTypes(Class superType) { - final int numThreads = Runtime.getRuntime().availableProcessors(); - - List> collectors = new ArrayList<>(); - for (int i = 0; i < numThreads; i++) { - collectors.add(new SubtypeCollector(superType, packageName, classLoaders)); - } - - try { - List urls = getJarUrls(); - for (int i = 0; i < urls.size(); i++) { - collectors.get(i % numThreads).addUrl(urls.get(i)); - } - - ExecutorService executorService = - Executors.newFixedThreadPool(numThreads, new NamedThreadFactory("scanner-scan-subtypes")); - for (SubtypeCollector collector : collectors) { - executorService.submit(collector); - } - - try { - executorService.shutdown(); - executorService.awaitTermination(10, TimeUnit.SECONDS); - } catch ( - @SuppressWarnings("unused") - InterruptedException e) { - } finally { - executorService.shutdownNow(); - } - - Set> types = new HashSet<>(); - for (SubtypeCollector collector : collectors) { - types.addAll(collector.getTypes()); - } - return types; - } catch (IOException e) { - log.error("Cannot load jar file entries", e); - } - return Collections.emptySet(); - } - - private List getJarUrls() throws IOException { - List urls = new ArrayList<>(); - String resourceName = resourceName(packageName); - for (ClassLoader loader : classLoaders) { - for (Enumeration e = loader.getResources(resourceName); e.hasMoreElements(); ) { - URL url = e.nextElement(); - // extract jar file path from the resource name - int index = url.getPath().lastIndexOf(".jar"); - if (index > 0) { - String path = url.getPath().substring(0, index + 4); - urls.add(new URL(path)); - } - } - } - return urls; - } - - private static String resourceName(String packageName) { - if (packageName == null || packageName.equals("")) { - return packageName; - } - return packageName.replace('.', '/'); - } -} diff --git a/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/SubtypeCollector.java b/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/SubtypeCollector.java deleted file mode 100644 index 6969ca3dfcc..00000000000 --- a/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/SubtypeCollector.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.luke.util.reflection; - -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.net.URL; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.jar.JarInputStream; -import java.util.zip.ZipEntry; -import org.apache.logging.log4j.Logger; -import org.apache.lucene.luke.util.LoggerFactory; - -final class SubtypeCollector implements Runnable { - - private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - - private final Set urls = new HashSet<>(); - - private final Class superType; - - private final String packageName; - - private final ClassLoader[] classLoaders; - - private final Set> types = new HashSet<>(); - - SubtypeCollector(Class superType, String packageName, ClassLoader... classLoaders) { - this.superType = superType; - this.packageName = packageName; - this.classLoaders = classLoaders; - } - - void addUrl(URL url) { - urls.add(url); - } - - Set> getTypes() { - return Set.copyOf(types); - } - - @Override - public void run() { - for (URL url : urls) { - try (JarInputStream jis = new JarInputStream(url.openStream())) { - // iterate all zip entry in the jar - ZipEntry entry; - while ((entry = jis.getNextEntry()) != null) { - String name = entry.getName(); - if (name.endsWith(".class") - && name.indexOf('$') < 0 - && !name.contains("package-info") - && !name.startsWith("META-INF")) { - String fqcn = convertToFQCN(name); - if (!fqcn.startsWith(packageName)) { - continue; - } - for (ClassLoader cl : classLoaders) { - try { - Class clazz = Class.forName(fqcn, false, cl); - if (superType.isAssignableFrom(clazz) && !Objects.equals(superType, clazz)) { - types.add(clazz.asSubclass(superType)); - } - break; - } catch ( - @SuppressWarnings("unused") - Throwable e) { - } - } - } - } - } catch (IOException e) { - log.error("Cannot load jar {}", url, e); - } - } - } - - private static String convertToFQCN(String name) { - if (name == null || name.equals("")) { - return name; - } - int index = name.lastIndexOf(".class"); - return name.replace('/', '.').substring(0, index); - } -} diff --git a/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/package-info.java b/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/package-info.java deleted file mode 100644 index fb718bc36a8..00000000000 --- a/lucene/luke/src/java/org/apache/lucene/luke/util/reflection/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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. - */ - -/** Utilities for reflections */ -package org.apache.lucene.luke.util.reflection; diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java b/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java index 5462148f433..3bd789d3b0a 100644 --- a/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java +++ b/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/TestAnalysisImpl.java @@ -125,11 +125,11 @@ public class TestAnalysisImpl extends LuceneTestCase { assertNotNull(tokens); } - @Test(expected = LukeException.class) - public void testAnalyze_not_set() { + public void testAnalyze_default() { AnalysisImpl analysis = new AnalysisImpl(); - String text = "This test must fail."; - analysis.analyze(text); + String text = "Apache Lucene"; + List tokens = analysis.analyze(text); + assertNotNull(tokens); } @Test(expected = LukeException.class)