Skip to content

Commit 2536222

Browse files
committed
Merge branch 'plugin-blacklist'
This adds support for blacklisting plugins from the plugin index, even when they are present on the classpath. Initial support is via the scijava.plugin.blacklist system property. If it proves to work well, we can expand the public API to control the blacklist per context.
2 parents e3619bf + e7becba commit 2536222

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

src/main/java/org/scijava/plugin/DefaultPluginFinder.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@
3131

3232
package org.scijava.plugin;
3333

34+
import java.util.ArrayList;
3435
import java.util.HashMap;
3536
import java.util.List;
37+
import java.util.regex.Pattern;
38+
import java.util.regex.PatternSyntaxException;
3639

3740
import org.scijava.annotations.Index;
3841
import org.scijava.annotations.IndexItem;
@@ -51,6 +54,8 @@ public class DefaultPluginFinder implements PluginFinder {
5154
/** Class loader to use when querying the annotation indexes. */
5255
private final ClassLoader customClassLoader;
5356

57+
private final PluginBlacklist blacklist;
58+
5459
// -- Constructors --
5560

5661
public DefaultPluginFinder() {
@@ -59,6 +64,7 @@ public DefaultPluginFinder() {
5964

6065
public DefaultPluginFinder(final ClassLoader classLoader) {
6166
customClassLoader = classLoader;
67+
blacklist = new SysPropBlacklist();
6268
}
6369

6470
// -- PluginFinder methods --
@@ -77,6 +83,7 @@ public HashMap<String, Throwable> findPlugins(
7783

7884
// create a PluginInfo object for each item in the index
7985
for (final IndexItem<Plugin> item : annotationIndex) {
86+
if (blacklist.contains(item.className())) continue;
8087
try {
8188
final PluginInfo<?> info = createInfo(item, classLoader);
8289
plugins.add(info);
@@ -109,4 +116,47 @@ private ClassLoader getClassLoader() {
109116
return Thread.currentThread().getContextClassLoader();
110117
}
111118

119+
// -- Helper classes --
120+
121+
private interface PluginBlacklist {
122+
boolean contains(String className);
123+
}
124+
125+
/**
126+
* A blacklist defined by the {@code scijava.plugin.blacklist} system
127+
* property, formatted as a colon-separated list of regexes.
128+
* <p>
129+
* If a plugin class matches any of the regexes, it is excluded from the
130+
* plugin index.
131+
* </p>
132+
*/
133+
private class SysPropBlacklist implements PluginBlacklist {
134+
private final List<Pattern> patterns;
135+
136+
public SysPropBlacklist() {
137+
final String sysProp = System.getProperty("scijava.plugin.blacklist");
138+
final String[] regexes = //
139+
sysProp == null ? new String[0] : sysProp.split(":");
140+
patterns = new ArrayList<Pattern>(regexes.length);
141+
for (final String regex : regexes) {
142+
try {
143+
patterns.add(Pattern.compile(regex));
144+
}
145+
catch (final PatternSyntaxException exc) {
146+
// NB: Ignore this malformed pattern.
147+
}
148+
}
149+
}
150+
151+
// -- PluginBlacklist methods --
152+
153+
@Override
154+
public boolean contains(final String className) {
155+
for (final Pattern pattern : patterns) {
156+
if (pattern.matcher(className).matches()) return true;
157+
}
158+
return false;
159+
}
160+
}
161+
112162
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugin;
33+
34+
import static org.junit.Assert.assertNull;
35+
import static org.junit.Assert.assertSame;
36+
37+
import org.junit.Test;
38+
import org.scijava.Context;
39+
40+
/**
41+
* Tests {@link PluginFinder}.
42+
*
43+
* @author Curtis Rueden
44+
*/
45+
public class PluginFinderTest {
46+
47+
/**
48+
* Tests that the {@code scijava.plugin.blacklist} system property works to
49+
* exclude plugins from the index, even when they are on the classpath.
50+
*/
51+
@Test
52+
public void testPluginBlacklistSystemProperty() {
53+
// check that the plugin is there, normally
54+
Context context = new Context(PluginService.class);
55+
PluginService pluginService = context.service(PluginService.class);
56+
PluginInfo<SciJavaPlugin> plugin = //
57+
pluginService.getPlugin(BlacklistedPlugin.class);
58+
assertSame(BlacklistedPlugin.class.getName(), plugin.getClassName());
59+
context.dispose();
60+
61+
// blacklist the plugin, then check that it is absent
62+
System.setProperty("scijava.plugin.blacklist", ".*BlacklistedPlugin");
63+
context = new Context(PluginService.class);
64+
pluginService = context.service(PluginService.class);
65+
plugin = pluginService.getPlugin(BlacklistedPlugin.class);
66+
assertNull(plugin);
67+
context.dispose();
68+
69+
// reset the system
70+
System.getProperties().remove("scijava.plugin.blacklist");
71+
}
72+
73+
@Plugin(type = SciJavaPlugin.class)
74+
public static class BlacklistedPlugin implements SciJavaPlugin {
75+
// NB: No implementation needed.
76+
}
77+
78+
}

src/test/java/org/scijava/plugin/PluginIndexTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public void testGetPluginsOfClass() {
7373
final PluginInfo<SciJavaPlugin> plugin =
7474
pluginService.getPlugin(FooBar.class);
7575
assertSame(testPlugin, plugin);
76+
77+
context.dispose();
7678
}
7779

7880
/**
@@ -102,6 +104,8 @@ public void testGetPluginsOfClassString() {
102104

103105
final PluginInfo<SciJavaPlugin> plugin = pluginService.getPlugin(fakeClass);
104106
assertSame(testPlugin, plugin);
107+
108+
context.dispose();
105109
}
106110

107111
/** A dummy plugin for testing the plugin service. */

0 commit comments

Comments
 (0)