From 952a4c843994bfeebb4038d4208f8a7985ac27ef Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Sat, 14 Dec 2019 15:10:31 +0100
Subject: [PATCH 001/264] Make DynamicCommand work when not in plugin index
This enables some new use cases: e.g. it becomes possible to make a
DynamicCommand anonymous subclass as a local variable in a method,
for the purpose of using it once, without registering it in the context.
---
src/main/java/org/scijava/command/DynamicCommand.java | 3 ++-
src/main/java/org/scijava/command/DynamicCommandInfo.java | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/scijava/command/DynamicCommand.java b/src/main/java/org/scijava/command/DynamicCommand.java
index a8bf63220..c4601f35f 100644
--- a/src/main/java/org/scijava/command/DynamicCommand.java
+++ b/src/main/java/org/scijava/command/DynamicCommand.java
@@ -79,7 +79,8 @@ public abstract class DynamicCommand extends DefaultMutableModule implements
public DynamicCommandInfo getInfo() {
if (info == null) {
// NB: Create dynamic metadata lazily.
- final CommandInfo commandInfo = commandService.getCommand(getClass());
+ CommandInfo commandInfo = commandService.getCommand(getClass());
+ if (commandInfo == null) commandInfo = new CommandInfo(getClass());
info = new DynamicCommandInfo(commandInfo, getClass());
}
return info;
diff --git a/src/main/java/org/scijava/command/DynamicCommandInfo.java b/src/main/java/org/scijava/command/DynamicCommandInfo.java
index a45f4b1ac..790f7064a 100644
--- a/src/main/java/org/scijava/command/DynamicCommandInfo.java
+++ b/src/main/java/org/scijava/command/DynamicCommandInfo.java
@@ -51,9 +51,9 @@
* Helper class for maintaining a {@link DynamicCommand}'s associated
* {@link ModuleInfo}.
*
- * The {@link CommandService} has a plain {@link CommandInfo} object in its
- * index, populated from the {@link DynamicCommand}'s @{@link Plugin}
- * annotation. So this class adapts that object, delegating to it for the
+ * This class wraps a plain {@link CommandInfo} object (e.g. from the
+ * {@link CommandService}'s index, present due to an @{@link Plugin} annotation
+ * on the {@link DynamicCommand} class), delegating to it for the
* {@link UIDetails} methods. The plain {@link CommandInfo} cannot be used
* as-is, however, because we need to override the {@link ModuleInfo} methods as
* well as provide metadata manipulation functionality such as
From 7146669092a7436744622204b0cb49057128369b Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Sat, 14 Dec 2019 15:21:03 +0100
Subject: [PATCH 002/264] Add convenient way to build input-only commands
The idea is to build up the inputs with code dynamically in Java, run
the command (which does nothing when executed) to exploit the module
preprocessing chain, and then harvest the final input values.
In this way, the user can be prompted for inputs dynamically from Java
code, roughly similar to the ij.gui.GenericDialog class of ImageJ 1.x.
---
.../org/scijava/command/DynamicCommand.java | 2 +-
src/main/java/org/scijava/command/Inputs.java | 105 ++++++++++++++++++
2 files changed, 106 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/org/scijava/command/Inputs.java
diff --git a/src/main/java/org/scijava/command/DynamicCommand.java b/src/main/java/org/scijava/command/DynamicCommand.java
index c4601f35f..ce2848139 100644
--- a/src/main/java/org/scijava/command/DynamicCommand.java
+++ b/src/main/java/org/scijava/command/DynamicCommand.java
@@ -63,7 +63,7 @@ public abstract class DynamicCommand extends DefaultMutableModule implements
private CommandService commandService;
@Parameter
- private PluginService pluginService;
+ protected PluginService pluginService;
@Parameter
protected ModuleService moduleService;
diff --git a/src/main/java/org/scijava/command/Inputs.java b/src/main/java/org/scijava/command/Inputs.java
new file mode 100644
index 000000000..f34f00aed
--- /dev/null
+++ b/src/main/java/org/scijava/command/Inputs.java
@@ -0,0 +1,105 @@
+/*
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2017 Board of Regents of the University of
+ * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
+ * Institute of Molecular Cell Biology and Genetics, University of
+ * Konstanz, and KNIME GmbH.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package org.scijava.command;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import org.scijava.Context;
+import org.scijava.module.process.PreprocessorPlugin;
+
+/**
+ * A way to build a dynamic set of inputs, whose values are then harvested by
+ * the preprocessing framework.
+ *
+ * The {@link #run()} method of this command does nothing. If you want something
+ * custom to happen during execution, use a normal {@link Command} instead:
+ * either implement {@link Command directly}, or extend {@link ContextCommand}
+ * or {@link DynamicCommand}.
+ *
+ *
+ * @author Curtis Rueden
+ */
+public final class Inputs extends DynamicCommand {
+
+ public Inputs(final Context context) {
+ context.inject(this);
+ }
+
+ public Map harvest() {
+ try {
+ final List pre = //
+ pluginService.createInstancesOfType(PreprocessorPlugin.class);
+ return moduleService.run(this, true, pre, null).get().getInputs();
+ }
+ catch (final InterruptedException | ExecutionException exc) {
+ throw new RuntimeException(exc);
+ }
+ }
+}
From ca7bf72c17260f18f597775d2041b991189015f0 Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Thu, 28 May 2020 10:40:03 +0200
Subject: [PATCH 003/264] AbstractInputHarvester: make getObjects() not return
duplicates
* both the convertService and the objectService attach objects of a
given type to the result list of AbstractInputHarvester:getObjects
* this results into the same objects being in the list twice
* using a set avoids duplicates in the list
---
.../java/org/scijava/widget/AbstractInputHarvester.java | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/scijava/widget/AbstractInputHarvester.java b/src/main/java/org/scijava/widget/AbstractInputHarvester.java
index c17f3f6b7..582b72b77 100644
--- a/src/main/java/org/scijava/widget/AbstractInputHarvester.java
+++ b/src/main/java/org/scijava/widget/AbstractInputHarvester.java
@@ -30,7 +30,9 @@
package org.scijava.widget;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.scijava.AbstractContextual;
import org.scijava.convert.ConvertService;
@@ -129,10 +131,10 @@ private WidgetModel addInput(final InputPanel
inputPanel,
@SuppressWarnings("unchecked")
private List> getObjects(final Class> type) {
@SuppressWarnings("rawtypes")
- List compatibleInputs =
- new ArrayList(convertService.getCompatibleInputs(type));
+ Set compatibleInputs =
+ new HashSet(convertService.getCompatibleInputs(type));
compatibleInputs.addAll(objectService.getObjects(type));
- return compatibleInputs;
+ return new ArrayList<>(compatibleInputs);
}
}
From 9d3a6e647e1b7991a120f0a2b87052bda9a93ceb Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Sat, 14 Dec 2019 17:56:54 +0100
Subject: [PATCH 004/264] Add unit tests for Inputs class
Co-authored-by: Deborah Schmidt
---
src/main/java/org/scijava/command/Inputs.java | 2 +-
.../scijava/plugin/DefaultPluginService.java | 3 +-
.../java/org/scijava/command/InputsTest.java | 170 ++++++++++++++++++
3 files changed, 173 insertions(+), 2 deletions(-)
create mode 100644 src/test/java/org/scijava/command/InputsTest.java
diff --git a/src/main/java/org/scijava/command/Inputs.java b/src/main/java/org/scijava/command/Inputs.java
index f34f00aed..ad7ba18f4 100644
--- a/src/main/java/org/scijava/command/Inputs.java
+++ b/src/main/java/org/scijava/command/Inputs.java
@@ -96,7 +96,7 @@ public Map harvest() {
try {
final List pre = //
pluginService.createInstancesOfType(PreprocessorPlugin.class);
- return moduleService.run(this, true, pre, null).get().getInputs();
+ return moduleService.run(this, pre, null).get().getInputs();
}
catch (final InterruptedException | ExecutionException exc) {
throw new RuntimeException(exc);
diff --git a/src/main/java/org/scijava/plugin/DefaultPluginService.java b/src/main/java/org/scijava/plugin/DefaultPluginService.java
index 45fcdf656..24612e3d4 100644
--- a/src/main/java/org/scijava/plugin/DefaultPluginService.java
+++ b/src/main/java/org/scijava/plugin/DefaultPluginService.java
@@ -239,7 +239,8 @@ public List createInstances(
return p;
}
catch (final Throwable t) {
- final String errorMessage = "Cannot create plugin: " + info;
+ final String errorMessage = //
+ "Cannot create plugin: " + info.getClassName();
if (log.isDebug()) log.debug(errorMessage, t);
else log.error(errorMessage);
}
diff --git a/src/test/java/org/scijava/command/InputsTest.java b/src/test/java/org/scijava/command/InputsTest.java
new file mode 100644
index 000000000..8c06e0bbe
--- /dev/null
+++ b/src/test/java/org/scijava/command/InputsTest.java
@@ -0,0 +1,170 @@
+/*
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2017 Board of Regents of the University of
+ * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
+ * Institute of Molecular Cell Biology and Genetics, University of
+ * Konstanz, and KNIME GmbH.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package org.scijava.command;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.scijava.Context;
+import org.scijava.InstantiableException;
+import org.scijava.log.LogLevel;
+import org.scijava.log.LogService;
+import org.scijava.module.Module;
+import org.scijava.module.ModuleItem;
+import org.scijava.module.MutableModuleItem;
+import org.scijava.module.process.AbstractPreprocessorPlugin;
+import org.scijava.module.process.PreprocessorPlugin;
+import org.scijava.plugin.PluginInfo;
+import org.scijava.plugin.PluginService;
+import org.scijava.widget.InputHarvester;
+import org.scijava.widget.NumberWidget;
+
+/**
+ * Tests {@link Inputs}.
+ *
+ * @author Curtis Rueden
+ * @author Deborah Schmidt
+ */
+public class InputsTest {
+
+ private Context context;
+
+ @Before
+ public void setUp() {
+ context = new Context();
+ context.service(PluginService.class);
+ }
+
+ @After
+ public void tearDown() {
+ context.dispose();
+ }
+
+ /** Tests single input, no configuration. */
+ @Test
+ public void testSingleInput() {
+ setExpected(new HashMap() {{
+ put("sigma", 3.9f);
+ }});
+ Inputs inputs = new Inputs(context);
+ inputs.getInfo().setName("testSingleInput");//TEMP
+ inputs.addInput("sigma", Float.class);
+ float sigma = (Float) inputs.harvest().get("sigma");
+ assertEquals(3.9f, sigma, 0);
+ }
+
+ /** Tests two inputs, no configuration. */
+ @Test
+ public void testTwoInputs() {
+ setExpected(new HashMap() {{
+ put("name", "Chuckles");
+ put("age", 37);
+ }});
+ Inputs inputs = new Inputs(context);
+ inputs.getInfo().setName("testTwoInputs");//TEMP
+ inputs.addInput("name", String.class);
+ inputs.addInput("age", Integer.class);
+ Map values = inputs.harvest();
+ String name = (String) values.get("name");
+ int age = (Integer) values.get("age");
+ assertEquals("Chuckles", name);
+ assertEquals(37, age);
+ }
+
+ /** Tests inputs with configuration. */
+ @Test
+ public void testWithConfiguration() {
+ setExpected(new HashMap() {{
+ put("word", "brown");
+ put("opacity", 0.8);
+ }});
+ Inputs inputs = new Inputs(context);
+ inputs.getInfo().setName("testWithConfiguration");//TEMP
+ MutableModuleItem wordInput = inputs.addInput("word", String.class);
+ wordInput.setLabel("Favorite word");
+ wordInput.setChoices(Arrays.asList("quick", "brown", "fox"));
+ wordInput.setDefaultValue("fox");
+ MutableModuleItem opacityInput = inputs.addInput("opacity", Double.class);
+ opacityInput.setMinimumValue(0.0);
+ opacityInput.setMaximumValue(1.0);
+ opacityInput.setDefaultValue(0.5);
+ opacityInput.setWidgetStyle(NumberWidget.SCROLL_BAR_STYLE);
+ inputs.harvest();
+ String word = wordInput.getValue(inputs);
+ double opacity = opacityInput.getValue(inputs);
+ assertEquals("brown", word);
+ assertEquals(0.8, opacity, 0);
+ }
+
+ public void setExpected(final Map expected) {
+ final PluginInfo info =
+ new PluginInfo(MockInputHarvester.class,
+ PreprocessorPlugin.class)
+ {
+ @Override
+ public PreprocessorPlugin createInstance() throws InstantiableException {
+ final PreprocessorPlugin pp = super.createInstance();
+ ((MockInputHarvester) pp).setExpected(expected);
+ return pp;
+ }
+ };
+ info.setPriority(InputHarvester.PRIORITY);
+ context.service(PluginService.class).addPlugin(info);
+ }
+
+ public static class MockInputHarvester extends AbstractPreprocessorPlugin {
+ private Map expected;
+ public void setExpected(final Map expected) {
+ this.expected = expected;
+ }
+
+ @Override
+ public void process(final Module module) {
+ for (final ModuleItem> input : module.getInfo().inputs()) {
+ if (module.isInputResolved(input.getName())) continue;
+ final String name = input.getName();
+ if (!expected.containsKey(name)) {
+ throw new AssertionError("No value for input: " + input.getName());
+ }
+ final Object value = expected.get(name);
+ module.setInput(name, value);
+ }
+ }
+ }
+}
From 950c3f3b5a4437015baf5455514db8c5a84df4df Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Fri, 3 Jul 2020 11:30:39 -0500
Subject: [PATCH 005/264] Rename blacklist to blocklist
See e.g. https://twitter.com/leahculver/status/1269109776983547904
---
.../scijava/plugin/DefaultPluginFinder.java | 18 +++++++++---------
.../org/scijava/plugin/PluginFinderTest.java | 18 +++++++++---------
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/scijava/plugin/DefaultPluginFinder.java b/src/main/java/org/scijava/plugin/DefaultPluginFinder.java
index d703119a8..3cb59909e 100644
--- a/src/main/java/org/scijava/plugin/DefaultPluginFinder.java
+++ b/src/main/java/org/scijava/plugin/DefaultPluginFinder.java
@@ -53,7 +53,7 @@ public class DefaultPluginFinder implements PluginFinder {
/** Class loader to use when querying the annotation indexes. */
private final ClassLoader customClassLoader;
- private final PluginBlacklist blacklist;
+ private final PluginBlocklist blocklist;
// -- Constructors --
@@ -63,7 +63,7 @@ public DefaultPluginFinder() {
public DefaultPluginFinder(final ClassLoader classLoader) {
customClassLoader = classLoader;
- blacklist = new SysPropBlacklist();
+ blocklist = new SysPropBlocklist();
}
// -- PluginFinder methods --
@@ -82,7 +82,7 @@ public HashMap findPlugins(
// create a PluginInfo object for each item in the index
for (final IndexItem item : annotationIndex) {
- if (blacklist.contains(item.className())) continue;
+ if (blocklist.contains(item.className())) continue;
try {
final PluginInfo> info = createInfo(item, classLoader);
plugins.add(info);
@@ -117,23 +117,23 @@ private ClassLoader getClassLoader() {
// -- Helper classes --
- private interface PluginBlacklist {
+ private interface PluginBlocklist {
boolean contains(String className);
}
/**
- * A blacklist defined by the {@code scijava.plugin.blacklist} system
+ * A blocklist defined by the {@code scijava.plugin.blocklist} system
* property, formatted as a colon-separated list of regexes.
*
* If a plugin class matches any of the regexes, it is excluded from the
* plugin index.
*
*/
- private class SysPropBlacklist implements PluginBlacklist {
+ private class SysPropBlocklist implements PluginBlocklist {
private final List patterns;
- public SysPropBlacklist() {
- final String sysProp = System.getProperty("scijava.plugin.blacklist");
+ public SysPropBlocklist() {
+ final String sysProp = System.getProperty("scijava.plugin.blocklist");
final String[] regexes = //
sysProp == null ? new String[0] : sysProp.split(":");
patterns = new ArrayList<>(regexes.length);
@@ -147,7 +147,7 @@ public SysPropBlacklist() {
}
}
- // -- PluginBlacklist methods --
+ // -- PluginBlocklist methods --
@Override
public boolean contains(final String className) {
diff --git a/src/test/java/org/scijava/plugin/PluginFinderTest.java b/src/test/java/org/scijava/plugin/PluginFinderTest.java
index 89170b5bc..6df16a8d7 100644
--- a/src/test/java/org/scijava/plugin/PluginFinderTest.java
+++ b/src/test/java/org/scijava/plugin/PluginFinderTest.java
@@ -43,33 +43,33 @@
public class PluginFinderTest {
/**
- * Tests that the {@code scijava.plugin.blacklist} system property works to
+ * Tests that the {@code scijava.plugin.blocklist} system property works to
* exclude plugins from the index, even when they are on the classpath.
*/
@Test
- public void testPluginBlacklistSystemProperty() {
+ public void testPluginBlocklistSystemProperty() {
// check that the plugin is there, normally
Context context = new Context(PluginService.class);
PluginService pluginService = context.service(PluginService.class);
PluginInfo plugin = //
- pluginService.getPlugin(BlacklistedPlugin.class);
- assertSame(BlacklistedPlugin.class.getName(), plugin.getClassName());
+ pluginService.getPlugin(BlocklistedPlugin.class);
+ assertSame(BlocklistedPlugin.class.getName(), plugin.getClassName());
context.dispose();
- // blacklist the plugin, then check that it is absent
- System.setProperty("scijava.plugin.blacklist", ".*BlacklistedPlugin");
+ // blocklist the plugin, then check that it is absent
+ System.setProperty("scijava.plugin.blocklist", ".*BlocklistedPlugin");
context = new Context(PluginService.class);
pluginService = context.service(PluginService.class);
- plugin = pluginService.getPlugin(BlacklistedPlugin.class);
+ plugin = pluginService.getPlugin(BlocklistedPlugin.class);
assertNull(plugin);
context.dispose();
// reset the system
- System.getProperties().remove("scijava.plugin.blacklist");
+ System.getProperties().remove("scijava.plugin.blocklist");
}
@Plugin(type = SciJavaPlugin.class)
- public static class BlacklistedPlugin implements SciJavaPlugin {
+ public static class BlocklistedPlugin implements SciJavaPlugin {
// NB: No implementation needed.
}
From 460927a3c946eb7c2cb7fd9c01b3a359bd2306ef Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Fri, 3 Jul 2020 11:37:16 -0500
Subject: [PATCH 006/264] Bump to next development cycle
Signed-off-by: Curtis Rueden
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index ed7bd2a5f..43d085481 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
scijava-common
- 2.83.4-SNAPSHOT
+ 2.83.5-SNAPSHOTSciJava CommonSciJava Common is a shared library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by downstream projects in the SciJava ecosystem, such as ImageJ and SCIFIO.
From d200f608e601a5cb70865fea27c3844bcef1b8c4 Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Thu, 16 Jul 2020 13:50:27 -0500
Subject: [PATCH 007/264] POM: bump minor version
The Inputs class is new API.
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 43d085481..92757258f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
scijava-common
- 2.83.5-SNAPSHOT
+ 2.84.0-SNAPSHOTSciJava CommonSciJava Common is a shared library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by downstream projects in the SciJava ecosystem, such as ImageJ and SCIFIO.
From b42b473d5943c0b64df49eb3cb13de53da9c30d5 Mon Sep 17 00:00:00 2001
From: Emil Melnikov
Date: Fri, 31 Jul 2020 15:19:30 +0200
Subject: [PATCH 008/264] Fix DynamicCommand.getOutput
---
src/main/java/org/scijava/command/DynamicCommand.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/org/scijava/command/DynamicCommand.java b/src/main/java/org/scijava/command/DynamicCommand.java
index e8146faca..c9919ef33 100644
--- a/src/main/java/org/scijava/command/DynamicCommand.java
+++ b/src/main/java/org/scijava/command/DynamicCommand.java
@@ -93,7 +93,7 @@ public Object getInput(final String name) {
@Override
public Object getOutput(final String name) {
final Field field = getInfo().getOutputField(name);
- if (field == null) return super.getInput(name);
+ if (field == null) return super.getOutput(name);
return ClassUtils.getValue(field, this);
}
From a5993b3a9cd9c634881b4c30c47ac95884ff451d Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Wed, 5 Aug 2020 11:38:16 -0500
Subject: [PATCH 009/264] ModuleRunner: do not rethrow caught exceptions
Apparently this is a bad practice. Better to use chaining.
---
src/main/java/org/scijava/module/ModuleRunner.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/scijava/module/ModuleRunner.java b/src/main/java/org/scijava/module/ModuleRunner.java
index d514afa54..b8ec3a20a 100644
--- a/src/main/java/org/scijava/module/ModuleRunner.java
+++ b/src/main/java/org/scijava/module/ModuleRunner.java
@@ -124,12 +124,10 @@ public Module call() {
run();
}
catch (final RuntimeException exc) {
- if (log != null) log.error("Module threw exception", exc);
- throw exc;
+ throw new RuntimeException("Module threw exception", exc);
}
catch (final Error err) {
- if (log != null) log.error("Module threw error", err);
- throw err;
+ throw new RuntimeException("Module threw error", err);
}
return module;
}
From b7285c5f807891097b5405b270952fcd32f2253c Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Sat, 7 Jun 2014 13:19:45 -0500
Subject: [PATCH 010/264] Use Location, not String, in the I/O API
This is much more elegant. It is also a very breaking change.
Co-authored-by: Deborah Schmidt
---
.../java/org/scijava/io/AbstractIOPlugin.java | 41 ++++++++++++-
.../java/org/scijava/io/DefaultIOService.java | 30 +++++++++-
.../scijava/io/DefaultRecentFileService.java | 7 ++-
src/main/java/org/scijava/io/IOPlugin.java | 34 +++++++++--
src/main/java/org/scijava/io/IOService.java | 59 ++++++++++++++++---
.../org/scijava/io/event/DataOpenedEvent.java | 16 ++---
.../org/scijava/io/event/DataSavedEvent.java | 12 ++--
.../java/org/scijava/io/event/IOEvent.java | 18 +++---
.../org/scijava/script/io/ScriptIOPlugin.java | 11 +++-
.../org/scijava/text/io/TextIOPlugin.java | 15 +++--
.../ui/dnd/FileDragAndDropHandler.java | 9 +--
.../java/org/scijava/io/DummyTextFormat.java | 22 +++++++
.../java/org/scijava/io/IOServiceTest.java | 38 ++++++++++++
src/test/resources/org/scijava/io/test.txt | 1 +
14 files changed, 256 insertions(+), 57 deletions(-)
create mode 100644 src/test/java/org/scijava/io/DummyTextFormat.java
create mode 100644 src/test/java/org/scijava/io/IOServiceTest.java
create mode 100644 src/test/resources/org/scijava/io/test.txt
diff --git a/src/main/java/org/scijava/io/AbstractIOPlugin.java b/src/main/java/org/scijava/io/AbstractIOPlugin.java
index 6ccd92f2c..9d314f8a3 100644
--- a/src/main/java/org/scijava/io/AbstractIOPlugin.java
+++ b/src/main/java/org/scijava/io/AbstractIOPlugin.java
@@ -29,15 +29,50 @@
package org.scijava.io;
+import org.scijava.io.location.Location;
+import org.scijava.io.location.LocationService;
import org.scijava.plugin.AbstractHandlerPlugin;
+import org.scijava.plugin.Parameter;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
/**
* Abstract base class for {@link IOPlugin}s.
*
* @author Curtis Rueden
*/
-public abstract class AbstractIOPlugin extends AbstractHandlerPlugin
- implements IOPlugin
+public abstract class AbstractIOPlugin extends
+ AbstractHandlerPlugin implements IOPlugin
{
- // NB: No implementation needed.
+
+ @Parameter
+ private LocationService locationService;
+
+ @Override
+ public boolean supportsOpen(final String source) {
+ try {
+ return supportsOpen(locationService.resolve(source));
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean supportsSave(final String destination) {
+ try {
+ return supportsSave(locationService.resolve(destination));
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public void save(final D data, final String destination) throws IOException {
+ try {
+ save(data, locationService.resolve(destination));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
}
diff --git a/src/main/java/org/scijava/io/DefaultIOService.java b/src/main/java/org/scijava/io/DefaultIOService.java
index c71896453..bfdaf35a2 100644
--- a/src/main/java/org/scijava/io/DefaultIOService.java
+++ b/src/main/java/org/scijava/io/DefaultIOService.java
@@ -30,10 +30,13 @@
package org.scijava.io;
import java.io.IOException;
+import java.net.URISyntaxException;
import org.scijava.event.EventService;
import org.scijava.io.event.DataOpenedEvent;
import org.scijava.io.event.DataSavedEvent;
+import org.scijava.io.location.Location;
+import org.scijava.io.location.LocationService;
import org.scijava.log.LogService;
import org.scijava.plugin.AbstractHandlerService;
import org.scijava.plugin.Parameter;
@@ -47,7 +50,7 @@
*/
@Plugin(type = Service.class)
public final class DefaultIOService
- extends AbstractHandlerService> implements IOService
+ extends AbstractHandlerService> implements IOService
{
@Parameter
@@ -56,10 +59,31 @@ public final class DefaultIOService
@Parameter
private EventService eventService;
- // -- IOService methods --
+ @Parameter
+ private LocationService locationService;
@Override
public Object open(final String source) throws IOException {
+ try {
+ return open(locationService.resolve(source));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void save(final Object data, final String destination)
+ throws IOException
+ {
+ try {
+ save(data, locationService.resolve(destination));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public Object open(final Location source) throws IOException {
final IOPlugin> opener = getOpener(source);
if (opener == null) {
log.error("No opener IOPlugin found for " + source + ".");
@@ -77,7 +101,7 @@ public Object open(final String source) throws IOException {
}
@Override
- public void save(final Object data, final String destination)
+ public void save(final Object data, final Location destination)
throws IOException
{
final IOPlugin
- *
+ *
* @param source The source (e.g., file path) from which to data should be
* loaded.
* @return An object representing the loaded data, or null if the source is
@@ -86,6 +104,20 @@ default IOPlugin getSaver(final D data, final String destination) {
*/
Object open(String source) throws IOException;
+ /**
+ * Loads data from the given location.
+ *
+ * The opener to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getOpener(Location)}.
+ *
+ *
+ * @param source The location from which to data should be loaded.
+ * @return An object representing the loaded data, or null if the source is
+ * not supported.
+ * @throws IOException if something goes wrong loading the data.
+ */
+ Object open(Location source) throws IOException;
+
/**
* Saves data to the given destination. The nature of the destination is left
* intentionally general, but the most common example is a file path.
@@ -93,7 +125,7 @@ default IOPlugin getSaver(final D data, final String destination) {
* The saver to use is automatically determined based on available
* {@link IOPlugin}s; see {@link #getSaver(Object, String)}.
*
- *
+ *
* @param data The data to be saved to the destination.
* @param destination The destination (e.g., file path) to which data should
* be saved.
@@ -101,6 +133,19 @@ default IOPlugin getSaver(final D data, final String destination) {
*/
void save(Object data, String destination) throws IOException;
+ /**
+ * Saves data to the given location.
+ *
+ * The saver to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getSaver(Object, Location)}.
+ *
+ *
+ * @param data The data to be saved to the destination.
+ * @param destination The destination location to which data should be saved.
+ * @throws IOException if something goes wrong saving the data.
+ */
+ void save(Object data, Location destination) throws IOException;
+
// -- HandlerService methods --
@Override
@@ -110,7 +155,7 @@ default Class> getPluginType() {
}
@Override
- default Class getType() {
- return String.class;
+ default Class getType() {
+ return Location.class;
}
}
diff --git a/src/main/java/org/scijava/io/event/DataOpenedEvent.java b/src/main/java/org/scijava/io/event/DataOpenedEvent.java
index 7af006c5a..4cf613856 100644
--- a/src/main/java/org/scijava/io/event/DataOpenedEvent.java
+++ b/src/main/java/org/scijava/io/event/DataOpenedEvent.java
@@ -29,22 +29,18 @@
package org.scijava.io.event;
+
+import org.scijava.io.location.Location;
+
/**
- * An event indicating that data has been opened from a source.
+ * An event indicating that data has been opened from a location.
*
* @author Curtis Rueden
*/
public class DataOpenedEvent extends IOEvent {
- public DataOpenedEvent(final String source, final Object data) {
- super(source, data);
- }
-
- // -- DataOpenedEvent methods --
-
- /** Gets the source from which data was opened. */
- public String getSource() {
- return getDescriptor();
+ public DataOpenedEvent(final Location location, final Object data) {
+ super(location, data);
}
}
diff --git a/src/main/java/org/scijava/io/event/DataSavedEvent.java b/src/main/java/org/scijava/io/event/DataSavedEvent.java
index cd6d22439..fe4b7abc3 100644
--- a/src/main/java/org/scijava/io/event/DataSavedEvent.java
+++ b/src/main/java/org/scijava/io/event/DataSavedEvent.java
@@ -29,6 +29,9 @@
package org.scijava.io.event;
+
+import org.scijava.io.location.Location;
+
/**
* An event indicating that data has been saved to a destination.
*
@@ -36,15 +39,8 @@
*/
public class DataSavedEvent extends IOEvent {
- public DataSavedEvent(final String destination, final Object data) {
+ public DataSavedEvent(final Location destination, final Object data) {
super(destination, data);
}
- // -- DataSavedEvent methods --
-
- /** Gets the destination to which data was saved. */
- public String getDestination() {
- return getDescriptor();
- }
-
}
diff --git a/src/main/java/org/scijava/io/event/IOEvent.java b/src/main/java/org/scijava/io/event/IOEvent.java
index 1a62e6fca..9228c94a4 100644
--- a/src/main/java/org/scijava/io/event/IOEvent.java
+++ b/src/main/java/org/scijava/io/event/IOEvent.java
@@ -30,6 +30,7 @@
package org.scijava.io.event;
import org.scijava.event.SciJavaEvent;
+import org.scijava.io.location.Location;
/**
* An event indicating that I/O (e.g., opening or saving) has occurred.
@@ -38,20 +39,20 @@
*/
public abstract class IOEvent extends SciJavaEvent {
- /** The data descriptor (source or destination). */
- private final String descriptor;
+ /** The data location (source or destination). */
+ private final Location location;
/** The data for which I/O took place. */
private final Object data;
- public IOEvent(final String descriptor, final Object data) {
- this.descriptor = descriptor;
+ public IOEvent(final Location location, final Object data) {
+ this.location = location;
this.data = data;
}
- /** Gets the data descriptor (source or destination). */
- public String getDescriptor() {
- return descriptor;
+ /** Gets the data location (source or destination). */
+ public Location getLocation() {
+ return location;
}
/** Gets the data for which I/O took place. */
@@ -63,7 +64,8 @@ public Object getData() {
@Override
public String toString() {
- return super.toString() + "\n\tdescriptor = " + data + "\n\tdata = " + data;
+ return super.toString() + "\n\tlocation = " + location + "\n\tdata = " +
+ data;
}
}
diff --git a/src/main/java/org/scijava/script/io/ScriptIOPlugin.java b/src/main/java/org/scijava/script/io/ScriptIOPlugin.java
index 56d201770..f881dc429 100644
--- a/src/main/java/org/scijava/script/io/ScriptIOPlugin.java
+++ b/src/main/java/org/scijava/script/io/ScriptIOPlugin.java
@@ -33,6 +33,8 @@
import org.scijava.io.AbstractIOPlugin;
import org.scijava.io.IOPlugin;
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
import org.scijava.plugin.Parameter;
import org.scijava.script.ScriptService;
@@ -55,13 +57,16 @@ public Class getDataType() {
}
@Override
- public boolean supportsOpen(final String source) {
+ public boolean supportsOpen(final Location source) {
if (scriptService == null) return false; // no service for opening scripts
- return scriptService.canHandleFile(source);
+ // TODO: Update ScriptService to use Location instead of File.
+ if (!(source instanceof FileLocation)) return false;
+ final FileLocation loc = (FileLocation) source;
+ return scriptService.canHandleFile(loc.getFile());
}
@Override
- public String open(final String source) throws IOException {
+ public String open(final Location source) throws IOException {
if (scriptService == null) return null; // no service for opening scripts
// TODO: Use the script service to open the file in the script editor.
return null;
diff --git a/src/main/java/org/scijava/text/io/TextIOPlugin.java b/src/main/java/org/scijava/text/io/TextIOPlugin.java
index 3d2c64172..523ff2c34 100644
--- a/src/main/java/org/scijava/text/io/TextIOPlugin.java
+++ b/src/main/java/org/scijava/text/io/TextIOPlugin.java
@@ -29,12 +29,13 @@
package org.scijava.text.io;
-import java.io.File;
import java.io.IOException;
import org.scijava.Priority;
import org.scijava.io.AbstractIOPlugin;
import org.scijava.io.IOPlugin;
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
import org.scijava.text.TextService;
@@ -59,15 +60,19 @@ public Class getDataType() {
}
@Override
- public boolean supportsOpen(final String source) {
+ public boolean supportsOpen(final Location source) {
if (textService == null) return false; // no service for opening text files
- return textService.supports(new File(source));
+ if (!(source instanceof FileLocation)) return false;
+ final FileLocation loc = (FileLocation) source;
+ return textService.supports(loc.getFile());
}
@Override
- public String open(final String source) throws IOException {
+ public String open(final Location source) throws IOException {
if (textService == null) return null; // no service for opening text files
- return textService.asHTML(new File(source));
+ if (!(source instanceof FileLocation)) throw new IllegalArgumentException();
+ final FileLocation loc = (FileLocation) source;
+ return textService.asHTML(loc.getFile());
}
}
diff --git a/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java b/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java
index 2076c6a20..02289b6e4 100644
--- a/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java
+++ b/src/main/java/org/scijava/ui/dnd/FileDragAndDropHandler.java
@@ -36,6 +36,7 @@
import org.scijava.display.Display;
import org.scijava.display.DisplayService;
import org.scijava.io.IOService;
+import org.scijava.io.location.FileLocation;
import org.scijava.log.LogService;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
@@ -68,7 +69,8 @@ public boolean supports(final File file) {
if (!super.supports(file)) return false;
// verify that the file can be opened somehow
- return ioService.getOpener(file.getAbsolutePath()) != null;
+ final FileLocation loc = new FileLocation(file);
+ return ioService.getOpener(loc) != null;
}
@Override
@@ -78,13 +80,12 @@ public boolean drop(final File file, final Display> display) {
if (file == null) return true; // trivial case
// load the data
- final String filename = file.getAbsolutePath();
final Object data;
try {
- data = ioService.open(filename);
+ data = ioService.open(new FileLocation(file));
}
catch (final IOException exc) {
- if (log != null) log.error("Error opening file: " + filename, exc);
+ if (log != null) log.error("Error opening file: " + file, exc);
return false;
}
diff --git a/src/test/java/org/scijava/io/DummyTextFormat.java b/src/test/java/org/scijava/io/DummyTextFormat.java
new file mode 100644
index 000000000..21729843f
--- /dev/null
+++ b/src/test/java/org/scijava/io/DummyTextFormat.java
@@ -0,0 +1,22 @@
+package org.scijava.io;
+
+import org.scijava.plugin.Plugin;
+import org.scijava.text.AbstractTextFormat;
+import org.scijava.text.TextFormat;
+
+import java.util.Collections;
+import java.util.List;
+
+@Plugin(type = TextFormat.class)
+public class DummyTextFormat extends AbstractTextFormat {
+
+ @Override
+ public List getExtensions() {
+ return Collections.singletonList("txt");
+ }
+
+ @Override
+ public String asHTML(String text) {
+ return text;
+ }
+}
diff --git a/src/test/java/org/scijava/io/IOServiceTest.java b/src/test/java/org/scijava/io/IOServiceTest.java
new file mode 100644
index 000000000..55ebcf774
--- /dev/null
+++ b/src/test/java/org/scijava/io/IOServiceTest.java
@@ -0,0 +1,38 @@
+package org.scijava.io;
+
+import org.junit.Test;
+import org.scijava.Context;
+import org.scijava.io.location.FileLocation;
+import org.scijava.plugin.PluginInfo;
+import org.scijava.text.TextFormat;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class IOServiceTest {
+
+ @Test
+ public void testTextFile() throws IOException {
+ // create context, add dummy text format
+ final Context ctx = new Context();
+ ctx.getPluginIndex().add(new PluginInfo<>(DummyTextFormat.class, TextFormat.class));
+ final IOService io = ctx.getService(IOService.class);
+
+ // open text file from resources as String
+ String localFile = getClass().getResource("test.txt").getPath();
+ Object obj = io.open(localFile);
+ assertNotNull(obj);
+ String content = obj.toString();
+ assertTrue(content.contains("content"));
+
+ // open text file from resources as FileLocation
+ obj = io.open(new FileLocation(localFile));
+ assertNotNull(obj);
+ assertEquals(content, obj.toString());
+ }
+}
diff --git a/src/test/resources/org/scijava/io/test.txt b/src/test/resources/org/scijava/io/test.txt
new file mode 100644
index 000000000..d95f3ad14
--- /dev/null
+++ b/src/test/resources/org/scijava/io/test.txt
@@ -0,0 +1 @@
+content
From 0bcbce32adee756dee8d2e77fee29371b2451e48 Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 13:45:10 +0200
Subject: [PATCH 011/264] POM: update to pom-scijava 29.2.1
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 92757258f..df8282af0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.scijavapom-scijava
- 28.0.0
+ 29.2.1
From acbb65dd5b2a285ad01aa7cedf69854f20458290 Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 13:45:40 +0200
Subject: [PATCH 012/264] AbstractIOPlugin: add open(String destination) method
---
src/main/java/org/scijava/io/AbstractIOPlugin.java | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/main/java/org/scijava/io/AbstractIOPlugin.java b/src/main/java/org/scijava/io/AbstractIOPlugin.java
index 9d314f8a3..98dd6fef7 100644
--- a/src/main/java/org/scijava/io/AbstractIOPlugin.java
+++ b/src/main/java/org/scijava/io/AbstractIOPlugin.java
@@ -75,4 +75,14 @@ public void save(final D data, final String destination) throws IOException {
throw new IOException(e);
}
}
+
+ @Override
+ public D open(final String destination) throws IOException {
+ try {
+ return open(locationService.resolve(destination));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
+
}
From 59061954cde14ac20d20beefa4f4b66416352d57 Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 13:54:30 +0200
Subject: [PATCH 013/264] Make test class for IOServiceTest inline class
---
.../java/org/scijava/io/DummyTextFormat.java | 22 -------------------
.../java/org/scijava/io/IOServiceTest.java | 19 ++++++++++++++--
2 files changed, 17 insertions(+), 24 deletions(-)
delete mode 100644 src/test/java/org/scijava/io/DummyTextFormat.java
diff --git a/src/test/java/org/scijava/io/DummyTextFormat.java b/src/test/java/org/scijava/io/DummyTextFormat.java
deleted file mode 100644
index 21729843f..000000000
--- a/src/test/java/org/scijava/io/DummyTextFormat.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.scijava.io;
-
-import org.scijava.plugin.Plugin;
-import org.scijava.text.AbstractTextFormat;
-import org.scijava.text.TextFormat;
-
-import java.util.Collections;
-import java.util.List;
-
-@Plugin(type = TextFormat.class)
-public class DummyTextFormat extends AbstractTextFormat {
-
- @Override
- public List getExtensions() {
- return Collections.singletonList("txt");
- }
-
- @Override
- public String asHTML(String text) {
- return text;
- }
-}
diff --git a/src/test/java/org/scijava/io/IOServiceTest.java b/src/test/java/org/scijava/io/IOServiceTest.java
index 55ebcf774..bd3f7a3af 100644
--- a/src/test/java/org/scijava/io/IOServiceTest.java
+++ b/src/test/java/org/scijava/io/IOServiceTest.java
@@ -4,11 +4,12 @@
import org.scijava.Context;
import org.scijava.io.location.FileLocation;
import org.scijava.plugin.PluginInfo;
+import org.scijava.text.AbstractTextFormat;
import org.scijava.text.TextFormat;
-import org.xml.sax.SAXException;
-import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -35,4 +36,18 @@ public void testTextFile() throws IOException {
assertNotNull(obj);
assertEquals(content, obj.toString());
}
+
+
+ public static class DummyTextFormat extends AbstractTextFormat {
+
+ @Override
+ public List getExtensions() {
+ return Collections.singletonList("txt");
+ }
+
+ @Override
+ public String asHTML(String text) {
+ return text;
+ }
+ }
}
From 7d4a580b8ed7456e52b3aa4bf4d7aebd69a996cd Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 21:55:09 +0200
Subject: [PATCH 014/264] Re-add reprecated methods
* they were removed in favor of using Location instead of String for IO
handling
* they are re-added to restore backwards compatibility
---
.../org/scijava/io/event/DataOpenedEvent.java | 22 ++++++++++++++++
.../org/scijava/io/event/DataSavedEvent.java | 21 ++++++++++++++++
.../java/org/scijava/io/event/IOEvent.java | 22 ++++++++++++++++
.../org/scijava/io/event/DataEventTest.java | 25 +++++++++++++++++++
4 files changed, 90 insertions(+)
create mode 100644 src/test/java/org/scijava/io/event/DataEventTest.java
diff --git a/src/main/java/org/scijava/io/event/DataOpenedEvent.java b/src/main/java/org/scijava/io/event/DataOpenedEvent.java
index 4cf613856..2d9c50929 100644
--- a/src/main/java/org/scijava/io/event/DataOpenedEvent.java
+++ b/src/main/java/org/scijava/io/event/DataOpenedEvent.java
@@ -30,6 +30,7 @@
package org.scijava.io.event;
+import org.scijava.io.location.FileLocation;
import org.scijava.io.location.Location;
/**
@@ -43,4 +44,25 @@ public DataOpenedEvent(final Location location, final Object data) {
super(location, data);
}
+ /**
+ * @deprecated use {@link #DataOpenedEvent(Location, Object)} instead
+ */
+ @Deprecated
+ public DataOpenedEvent(final String source, final Object data) {
+ this(new FileLocation(source), data);
+ }
+
+ /**
+ * @deprecated use {@link #getLocation} instead
+ */
+ @Deprecated
+ public String getSource() {
+ try {
+ FileLocation fileLocation = (FileLocation) getLocation();
+ return fileLocation.getFile().getAbsolutePath();
+ } catch(ClassCastException e) {
+ return getLocation().getURI().toString();
+ }
+ }
+
}
diff --git a/src/main/java/org/scijava/io/event/DataSavedEvent.java b/src/main/java/org/scijava/io/event/DataSavedEvent.java
index fe4b7abc3..600eccafc 100644
--- a/src/main/java/org/scijava/io/event/DataSavedEvent.java
+++ b/src/main/java/org/scijava/io/event/DataSavedEvent.java
@@ -30,6 +30,7 @@
package org.scijava.io.event;
+import org.scijava.io.location.FileLocation;
import org.scijava.io.location.Location;
/**
@@ -43,4 +44,24 @@ public DataSavedEvent(final Location destination, final Object data) {
super(destination, data);
}
+ /**
+ * @deprecated use {@link #DataSavedEvent(Location, Object)} instead
+ */
+ @Deprecated
+ public DataSavedEvent(final String destination, final Object data) {
+ this(new FileLocation(destination), data);
+ }
+
+ /**
+ * @deprecated use {@link #getLocation} instead
+ */
+ @Deprecated
+ public String getDestination() {
+ try {
+ FileLocation fileLocation = (FileLocation) getLocation();
+ return fileLocation.getFile().getAbsolutePath();
+ } catch(ClassCastException e) {
+ return getLocation().getURI().toString();
+ }
+ }
}
diff --git a/src/main/java/org/scijava/io/event/IOEvent.java b/src/main/java/org/scijava/io/event/IOEvent.java
index 9228c94a4..89bfe0f27 100644
--- a/src/main/java/org/scijava/io/event/IOEvent.java
+++ b/src/main/java/org/scijava/io/event/IOEvent.java
@@ -30,6 +30,7 @@
package org.scijava.io.event;
import org.scijava.event.SciJavaEvent;
+import org.scijava.io.location.FileLocation;
import org.scijava.io.location.Location;
/**
@@ -45,6 +46,14 @@ public abstract class IOEvent extends SciJavaEvent {
/** The data for which I/O took place. */
private final Object data;
+ /**
+ * @deprecated use {@link #IOEvent(Location, Object)} instead
+ */
+ @Deprecated
+ public IOEvent(final String descriptor, final Object data) {
+ this(new FileLocation(descriptor), data);
+ }
+
public IOEvent(final Location location, final Object data) {
this.location = location;
this.data = data;
@@ -68,4 +77,17 @@ public String toString() {
data;
}
+ /**
+ * @deprecated use {@link #getLocation()} instead
+ */
+ @Deprecated
+ public String getDescriptor() {
+ try {
+ FileLocation fileLocation = (FileLocation) getLocation();
+ return fileLocation.getFile().getAbsolutePath();
+ } catch(ClassCastException e) {
+ return getLocation().getURI().toString();
+ }
+ }
+
}
diff --git a/src/test/java/org/scijava/io/event/DataEventTest.java b/src/test/java/org/scijava/io/event/DataEventTest.java
new file mode 100644
index 000000000..8e2ce0aa0
--- /dev/null
+++ b/src/test/java/org/scijava/io/event/DataEventTest.java
@@ -0,0 +1,25 @@
+package org.scijava.io.event;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class DataEventTest {
+
+ @Test
+ public void testDeprecatedMethods() {
+ String localPath = "/local/absolute/path.txt";
+ Object obj = null;
+ DataOpenedEvent openedEvent = new DataOpenedEvent(localPath, obj);
+ DataSavedEvent savedEvent = new DataSavedEvent(localPath, obj);
+ assertEquals(localPath, openedEvent.getSource());
+ assertEquals(localPath, savedEvent.getDestination());
+
+// String remotepath = "https://remote.org/path.txt";
+// openedEvent = new DataOpenedEvent(remotepath, obj);
+// savedEvent = new DataSavedEvent(remotepath, obj);
+// assertEquals(remotepath, openedEvent.getSource());
+// assertEquals(remotepath, savedEvent.getDestination());
+ }
+
+}
From d255cdd1df501c5a2afcd37ec9569e307737d32b Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 22:11:16 +0200
Subject: [PATCH 015/264] IOService: add default body to open(Location) and
save(Object, Location)
- this restores backwards-compatibility
---
src/main/java/org/scijava/io/IOService.java | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/scijava/io/IOService.java b/src/main/java/org/scijava/io/IOService.java
index 4e49f4aee..0d6ad9340 100644
--- a/src/main/java/org/scijava/io/IOService.java
+++ b/src/main/java/org/scijava/io/IOService.java
@@ -116,7 +116,9 @@ default IOPlugin getSaver(D data, Location destination) {
* not supported.
* @throws IOException if something goes wrong loading the data.
*/
- Object open(Location source) throws IOException;
+ default Object open(Location source) throws IOException {
+ throw new UnsupportedOperationException();
+ }
/**
* Saves data to the given destination. The nature of the destination is left
@@ -144,7 +146,9 @@ default IOPlugin getSaver(D data, Location destination) {
* @param destination The destination location to which data should be saved.
* @throws IOException if something goes wrong saving the data.
*/
- void save(Object data, Location destination) throws IOException;
+ default void save(Object data, Location destination) throws IOException {
+ throw new UnsupportedOperationException();
+ }
// -- HandlerService methods --
From 5a83bcdbba7ab0d77fa552f1555c2b3b1ab5c66e Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 16:32:20 +0200
Subject: [PATCH 016/264] Add TypedIOService
This is an interface which can be used to write IOServices opening and
saving a specific type. The TypedIOServiceTest class demonstrates how to
do that with an exemplary TextIOService.
So far, IO services like DatasetIOService or TableIOServcie don't share
a common IOService interface.
---
.../scijava/io/AbstractTypedIOService.java | 140 +++++++++++++++
.../java/org/scijava/io/TypedIOService.java | 168 ++++++++++++++++++
.../org/scijava/io/TypedIOServiceTest.java | 61 +++++++
3 files changed, 369 insertions(+)
create mode 100644 src/main/java/org/scijava/io/AbstractTypedIOService.java
create mode 100644 src/main/java/org/scijava/io/TypedIOService.java
create mode 100644 src/test/java/org/scijava/io/TypedIOServiceTest.java
diff --git a/src/main/java/org/scijava/io/AbstractTypedIOService.java b/src/main/java/org/scijava/io/AbstractTypedIOService.java
new file mode 100644
index 000000000..45403af49
--- /dev/null
+++ b/src/main/java/org/scijava/io/AbstractTypedIOService.java
@@ -0,0 +1,140 @@
+/*
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package org.scijava.io;
+
+import org.scijava.io.location.Location;
+import org.scijava.io.location.LocationService;
+import org.scijava.plugin.AbstractHandlerService;
+import org.scijava.plugin.Parameter;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+/**
+ * Abstract base class for typed {@link IOPlugin}s.
+ *
+ * @author Curtis Rueden
+ * @author Deborah Schmidt
+ */
+public abstract class AbstractTypedIOService extends AbstractHandlerService> implements TypedIOService
+{
+
+ @Parameter
+ private LocationService locationService;
+
+ @Parameter
+ private IOService ioService;
+
+ @Override
+ public D open(String source) throws IOException {
+ try {
+ return open(locationService.resolve(source));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public D open(Location source) throws IOException {
+ IOPlugin> opener = ioService().getOpener(source);
+ try {
+ Class ignored = (Class) opener.getDataType();
+ return (D) opener.open(source);
+ }
+ catch(ClassCastException e) {
+ throw new UnsupportedOperationException("No compatible opener found.");
+ }
+ }
+
+ @Override
+ public void save(D data, String destination) throws IOException {
+ try {
+ save(data, locationService.resolve(destination));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void save(D data, Location destination) throws IOException {
+ IOPlugin saver = ioService().getSaver(data, destination);
+ if (saver != null) {
+ saver.save(data, destination);
+ }
+ else {
+ throw new UnsupportedOperationException("No compatible saver found.");
+ }
+ }
+
+ @Override
+ public boolean canOpen(String source) {
+ try {
+ return canOpen(locationService.resolve(source));
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean canOpen(Location source) {
+ IOPlugin> opener = ioService().getOpener(source);
+ if (opener == null) return false;
+ try {
+ Class ignored = (Class) (opener.getDataType());
+ return true;
+ } catch(ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean canSave(D data, String source) {
+ try {
+ return canSave(data, locationService.resolve(source));
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean canSave(D data, Location destination) {
+ IOPlugin saver = ioService.getSaver(data, destination);
+ if (saver == null) return false;
+ return saver.supportsSave(destination);
+ }
+
+ protected LocationService locationService() {
+ return locationService;
+ }
+
+ protected IOService ioService() {
+ return ioService;
+ }
+}
diff --git a/src/main/java/org/scijava/io/TypedIOService.java b/src/main/java/org/scijava/io/TypedIOService.java
new file mode 100644
index 000000000..550edd67a
--- /dev/null
+++ b/src/main/java/org/scijava/io/TypedIOService.java
@@ -0,0 +1,168 @@
+/*
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package org.scijava.io;
+
+import java.io.IOException;
+
+import org.scijava.io.location.FileLocation;
+import org.scijava.io.location.Location;
+import org.scijava.plugin.HandlerService;
+import org.scijava.service.SciJavaService;
+
+/**
+ * Interface for high-level data I/O: opening and saving data of a specific type.
+ *
+ * @author Curtis Rueden
+ * @author Deborah Schmidt
+ */
+public interface TypedIOService extends HandlerService>,
+ SciJavaService
+{
+
+ /**
+ * Gets the most appropriate {@link IOPlugin} for opening data from the given
+ * location.
+ */
+ default IOPlugin getOpener(final String source) {
+ return getOpener(new FileLocation(source));
+ }
+
+ /**
+ * Gets the most appropriate {@link IOPlugin} for opening data from the given
+ * location.
+ */
+ default IOPlugin getOpener(Location source) {
+ for (final IOPlugin handler : getInstances()) {
+ if (handler.supportsOpen(source)) return handler;
+ }
+ return null;
+ }
+
+ /**
+ * Gets the most appropriate {@link IOPlugin} for saving data to the given
+ * location.
+ */
+ default IOPlugin getSaver(final D data, final String destination) {
+ return getSaver(data, new FileLocation(destination));
+ }
+
+ /**
+ * Gets the most appropriate {@link IOPlugin} for saving data to the given
+ * location.
+ */
+ default IOPlugin getSaver(D data, Location destination) {
+ for (final IOPlugin> handler : getInstances()) {
+ if (handler.supportsSave(data, destination)) {
+ return (IOPlugin) handler;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Loads data from the given source. For extensibility, the nature of the
+ * source is left intentionally general, but two common examples include file
+ * paths and URLs.
+ *
+ * The opener to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getOpener(String)}.
+ *
+ *
+ * @param source The source (e.g., file path) from which to data should be
+ * loaded.
+ * @return An object representing the loaded data, or null if the source is
+ * not supported.
+ * @throws IOException if something goes wrong loading the data.
+ */
+ D open(String source) throws IOException;
+
+ /**
+ * Loads data from the given location.
+ *
+ * The opener to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getOpener(Location)}.
+ *
+ *
+ * @param source The location from which to data should be loaded.
+ * @return An object representing the loaded data, or null if the source is
+ * not supported.
+ * @throws IOException if something goes wrong loading the data.
+ */
+ D open(Location source) throws IOException;
+
+ /**
+ * Saves data to the given destination. The nature of the destination is left
+ * intentionally general, but the most common example is a file path.
+ *
+ * The saver to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getSaver(Object, String)}.
+ *
+ *
+ * @param data The data to be saved to the destination.
+ * @param destination The destination (e.g., file path) to which data should
+ * be saved.
+ * @throws IOException if something goes wrong saving the data.
+ */
+ void save(D data, String destination) throws IOException;
+
+ /**
+ * Saves data to the given location.
+ *
+ * The saver to use is automatically determined based on available
+ * {@link IOPlugin}s; see {@link #getSaver(Object, Location)}.
+ *
+ *
+ * @param data The data to be saved to the destination.
+ * @param destination The destination location to which data should be saved.
+ * @throws IOException if something goes wrong saving the data.
+ */
+ void save(D data, Location destination) throws IOException;
+
+ boolean canOpen(String source);
+
+ boolean canOpen(Location source);
+
+ boolean canSave(D data, String destination);
+
+ boolean canSave(D data, Location destination);
+
+ // -- HandlerService methods --
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ default Class> getPluginType() {
+ return (Class) IOPlugin.class;
+ }
+
+ @Override
+ default Class getType() {
+ return Location.class;
+ }
+}
diff --git a/src/test/java/org/scijava/io/TypedIOServiceTest.java b/src/test/java/org/scijava/io/TypedIOServiceTest.java
new file mode 100644
index 000000000..e72324c60
--- /dev/null
+++ b/src/test/java/org/scijava/io/TypedIOServiceTest.java
@@ -0,0 +1,61 @@
+package org.scijava.io;
+
+import org.junit.Test;
+import org.scijava.Context;
+import org.scijava.plugin.PluginInfo;
+import org.scijava.plugin.PluginService;
+import org.scijava.plugin.SciJavaPlugin;
+import org.scijava.service.SciJavaService;
+import org.scijava.text.AbstractTextFormat;
+import org.scijava.text.TextFormat;
+import org.scijava.text.TextService;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TypedIOServiceTest {
+
+ @Test
+ public void testTextFile() throws IOException {
+ // create context, add dummy text format
+ final Context ctx = new Context();
+ ctx.getPluginIndex().add(new PluginInfo<>(DummyTextFormat.class, TextFormat.class));
+ ctx.getPluginIndex().add(new PluginInfo<>(DefaultTextIOService.class, TextIOService.class));
+ TextIOService instance = (TextIOService) ctx.getService(PluginService.class).createInstance(ctx.getPluginIndex().get(TextIOService.class).get(0));
+ ctx.getServiceIndex().add(instance);
+
+ // try to get the TextIOService
+ final TextIOService io = ctx.service(TextIOService.class);
+ assertNotNull(io);
+
+ // open text file from resources as String
+ String localFile = getClass().getResource("test.txt").getPath();
+ String obj = io.open(localFile);
+ assertNotNull(obj);
+ assertTrue(obj.contains("content"));
+ }
+
+ interface TextIOService extends TypedIOService {
+ }
+
+ public static class DefaultTextIOService extends AbstractTypedIOService implements TextIOService {
+ }
+
+ public static class DummyTextFormat extends AbstractTextFormat {
+
+ @Override
+ public List getExtensions() {
+ return Collections.singletonList("txt");
+ }
+
+ @Override
+ public String asHTML(String text) {
+ return text;
+ }
+
+ }
+}
From bba50af44bc437670fb482d4e7959c32c3e14565 Mon Sep 17 00:00:00 2001
From: frauzufall
Date: Wed, 12 Aug 2020 17:24:32 +0200
Subject: [PATCH 017/264] Adding TextIOService with default implementation
* .. which was originally implemented in the TypedIOServiceTest for
testing the TypedIOService architecture
---
.../scijava/text/io/DefaultTextIOService.java | 43 +++++++++++++++++++
.../org/scijava/text/io/TextIOService.java | 40 +++++++++++++++++
.../java/org/scijava/ContextCreationTest.java | 1 +
.../org/scijava/io/TypedIOServiceTest.java | 14 +-----
4 files changed, 85 insertions(+), 13 deletions(-)
create mode 100644 src/main/java/org/scijava/text/io/DefaultTextIOService.java
create mode 100644 src/main/java/org/scijava/text/io/TextIOService.java
diff --git a/src/main/java/org/scijava/text/io/DefaultTextIOService.java b/src/main/java/org/scijava/text/io/DefaultTextIOService.java
new file mode 100644
index 000000000..509216a3c
--- /dev/null
+++ b/src/main/java/org/scijava/text/io/DefaultTextIOService.java
@@ -0,0 +1,43 @@
+/*
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package org.scijava.text.io;
+
+import org.scijava.io.AbstractTypedIOService;
+import org.scijava.plugin.Plugin;
+import org.scijava.service.Service;
+
+/**
+ * Default {@link TextIOService} implementation for opening and saving text data
+ *
+ * @author Deborah Schmidt
+ */
+@Plugin(type = Service.class)
+public class DefaultTextIOService extends AbstractTypedIOService implements TextIOService {
+}
diff --git a/src/main/java/org/scijava/text/io/TextIOService.java b/src/main/java/org/scijava/text/io/TextIOService.java
new file mode 100644
index 000000000..c87d2847a
--- /dev/null
+++ b/src/main/java/org/scijava/text/io/TextIOService.java
@@ -0,0 +1,40 @@
+/*
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
+
+package org.scijava.text.io;
+
+import org.scijava.io.TypedIOService;
+
+/**
+ * {@link TypedIOService} for opening and saving text data
+ *
+ * @author Deborah Schmidt
+ */
+public interface TextIOService extends TypedIOService {
+}
diff --git a/src/test/java/org/scijava/ContextCreationTest.java b/src/test/java/org/scijava/ContextCreationTest.java
index 4fd266e4b..ccf76e426 100644
--- a/src/test/java/org/scijava/ContextCreationTest.java
+++ b/src/test/java/org/scijava/ContextCreationTest.java
@@ -114,6 +114,7 @@ public void testFull() {
org.scijava.startup.DefaultStartupService.class,
org.scijava.task.DefaultTaskService.class,
org.scijava.text.DefaultTextService.class,
+ org.scijava.text.io.DefaultTextIOService.class,
org.scijava.thread.DefaultThreadService.class,
org.scijava.tool.DefaultToolService.class,
org.scijava.ui.DefaultUIService.class,
diff --git a/src/test/java/org/scijava/io/TypedIOServiceTest.java b/src/test/java/org/scijava/io/TypedIOServiceTest.java
index e72324c60..de64730e2 100644
--- a/src/test/java/org/scijava/io/TypedIOServiceTest.java
+++ b/src/test/java/org/scijava/io/TypedIOServiceTest.java
@@ -3,12 +3,9 @@
import org.junit.Test;
import org.scijava.Context;
import org.scijava.plugin.PluginInfo;
-import org.scijava.plugin.PluginService;
-import org.scijava.plugin.SciJavaPlugin;
-import org.scijava.service.SciJavaService;
import org.scijava.text.AbstractTextFormat;
import org.scijava.text.TextFormat;
-import org.scijava.text.TextService;
+import org.scijava.text.io.TextIOService;
import java.io.IOException;
import java.util.Collections;
@@ -24,9 +21,6 @@ public void testTextFile() throws IOException {
// create context, add dummy text format
final Context ctx = new Context();
ctx.getPluginIndex().add(new PluginInfo<>(DummyTextFormat.class, TextFormat.class));
- ctx.getPluginIndex().add(new PluginInfo<>(DefaultTextIOService.class, TextIOService.class));
- TextIOService instance = (TextIOService) ctx.getService(PluginService.class).createInstance(ctx.getPluginIndex().get(TextIOService.class).get(0));
- ctx.getServiceIndex().add(instance);
// try to get the TextIOService
final TextIOService io = ctx.service(TextIOService.class);
@@ -39,12 +33,6 @@ public void testTextFile() throws IOException {
assertTrue(obj.contains("content"));
}
- interface TextIOService extends TypedIOService {
- }
-
- public static class DefaultTextIOService extends AbstractTypedIOService implements TextIOService {
- }
-
public static class DummyTextFormat extends AbstractTextFormat {
@Override
From 1b38b35f5050147570c5e2d33161ebfd3dbedcae Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Thu, 13 Aug 2020 12:45:25 -0500
Subject: [PATCH 018/264] Fix out-of-sync license headers
---
src/main/java/org/scijava/command/Inputs.java | 9 ++----
.../java/org/scijava/io/TypedIOService.java | 4 +--
.../scijava/text/io/DefaultTextIOService.java | 4 +--
.../org/scijava/text/io/TextIOService.java | 4 +--
.../java/org/scijava/command/InputsTest.java | 9 ++----
.../java/org/scijava/io/IOServiceTest.java | 28 +++++++++++++++++++
.../org/scijava/io/TypedIOServiceTest.java | 28 +++++++++++++++++++
.../org/scijava/io/event/DataEventTest.java | 28 +++++++++++++++++++
8 files changed, 96 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/scijava/command/Inputs.java b/src/main/java/org/scijava/command/Inputs.java
index ad7ba18f4..a686bf4ff 100644
--- a/src/main/java/org/scijava/command/Inputs.java
+++ b/src/main/java/org/scijava/command/Inputs.java
@@ -2,20 +2,17 @@
* #%L
* SciJava Common shared library for SciJava software.
* %%
- * Copyright (C) 2009 - 2017 Board of Regents of the University of
- * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
- * Institute of Molecular Cell Biology and Genetics, University of
- * Konstanz, and KNIME GmbH.
+ * Copyright (C) 2009 - 2020 SciJava developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
diff --git a/src/main/java/org/scijava/io/TypedIOService.java b/src/main/java/org/scijava/io/TypedIOService.java
index 550edd67a..ca27e9bf7 100644
--- a/src/main/java/org/scijava/io/TypedIOService.java
+++ b/src/main/java/org/scijava/io/TypedIOService.java
@@ -6,13 +6,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
diff --git a/src/main/java/org/scijava/text/io/DefaultTextIOService.java b/src/main/java/org/scijava/text/io/DefaultTextIOService.java
index 509216a3c..e29a1c796 100644
--- a/src/main/java/org/scijava/text/io/DefaultTextIOService.java
+++ b/src/main/java/org/scijava/text/io/DefaultTextIOService.java
@@ -6,13 +6,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
diff --git a/src/main/java/org/scijava/text/io/TextIOService.java b/src/main/java/org/scijava/text/io/TextIOService.java
index c87d2847a..d196c893a 100644
--- a/src/main/java/org/scijava/text/io/TextIOService.java
+++ b/src/main/java/org/scijava/text/io/TextIOService.java
@@ -6,13 +6,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
diff --git a/src/test/java/org/scijava/command/InputsTest.java b/src/test/java/org/scijava/command/InputsTest.java
index 8c06e0bbe..f53146d26 100644
--- a/src/test/java/org/scijava/command/InputsTest.java
+++ b/src/test/java/org/scijava/command/InputsTest.java
@@ -2,20 +2,17 @@
* #%L
* SciJava Common shared library for SciJava software.
* %%
- * Copyright (C) 2009 - 2017 Board of Regents of the University of
- * Wisconsin-Madison, Broad Institute of MIT and Harvard, Max Planck
- * Institute of Molecular Cell Biology and Genetics, University of
- * Konstanz, and KNIME GmbH.
+ * Copyright (C) 2009 - 2020 SciJava developers.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
diff --git a/src/test/java/org/scijava/io/IOServiceTest.java b/src/test/java/org/scijava/io/IOServiceTest.java
index bd3f7a3af..5e39835ea 100644
--- a/src/test/java/org/scijava/io/IOServiceTest.java
+++ b/src/test/java/org/scijava/io/IOServiceTest.java
@@ -1,3 +1,31 @@
+/*-
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
package org.scijava.io;
import org.junit.Test;
diff --git a/src/test/java/org/scijava/io/TypedIOServiceTest.java b/src/test/java/org/scijava/io/TypedIOServiceTest.java
index de64730e2..affbbf66d 100644
--- a/src/test/java/org/scijava/io/TypedIOServiceTest.java
+++ b/src/test/java/org/scijava/io/TypedIOServiceTest.java
@@ -1,3 +1,31 @@
+/*-
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
package org.scijava.io;
import org.junit.Test;
diff --git a/src/test/java/org/scijava/io/event/DataEventTest.java b/src/test/java/org/scijava/io/event/DataEventTest.java
index 8e2ce0aa0..45568b12e 100644
--- a/src/test/java/org/scijava/io/event/DataEventTest.java
+++ b/src/test/java/org/scijava/io/event/DataEventTest.java
@@ -1,3 +1,31 @@
+/*-
+ * #%L
+ * SciJava Common shared library for SciJava software.
+ * %%
+ * Copyright (C) 2009 - 2020 SciJava developers.
+ * %%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * #L%
+ */
package org.scijava.io.event;
import org.junit.Test;
From 6d6eec59b8a147a996dbdcd9568de7ac845e8a73 Mon Sep 17 00:00:00 2001
From: Curtis Rueden
Date: Thu, 13 Aug 2020 12:48:15 -0500
Subject: [PATCH 019/264] Bump to next development cycle
Signed-off-by: Curtis Rueden
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index df8282af0..8b8fef07a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
scijava-common
- 2.84.0-SNAPSHOT
+ 2.84.1-SNAPSHOTSciJava CommonSciJava Common is a shared library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by downstream projects in the SciJava ecosystem, such as ImageJ and SCIFIO.
From 9970cef348faa343e6870981d1c1702604419b1e Mon Sep 17 00:00:00 2001
From: Mark Hiner
Date: Fri, 14 Aug 2020 13:18:20 -0500
Subject: [PATCH 020/264] Context: code formatting
Using the ImageJ style preferences
---
src/main/java/org/scijava/Context.java | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/scijava/Context.java b/src/main/java/org/scijava/Context.java
index 638230db1..e4d2bda14 100644
--- a/src/main/java/org/scijava/Context.java
+++ b/src/main/java/org/scijava/Context.java
@@ -445,7 +445,8 @@ public static List> serviceClassList(
* @see ClassLoader#getSystemClassLoader()
*/
public static ClassLoader getClassLoader() {
- final ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
+ final ClassLoader contextCL = Thread.currentThread()
+ .getContextClassLoader();
return contextCL != null ? contextCL : ClassLoader.getSystemClassLoader();
}
@@ -570,8 +571,8 @@ private static PluginIndex plugins(final boolean empty) {
}
private static List> services(final boolean empty) {
- if (empty) return Collections.>emptyList();
- return Arrays.>asList(Service.class);
+ if (empty) return Collections.> emptyList();
+ return Arrays.> asList(Service.class);
}
private static boolean strict() {
From a63cd8ff51938186c7a5ca3a0a4c0a2fae1493ba Mon Sep 17 00:00:00 2001
From: Mark Hiner
Date: Fri, 14 Aug 2020 13:18:46 -0500
Subject: [PATCH 021/264] Make Context AutoCloseable
This will provide developers hints that the Context should be disposed
after creation.
See https://github.com/scijava/scijava-common/pull/394
---
src/main/java/org/scijava/Context.java | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/scijava/Context.java b/src/main/java/org/scijava/Context.java
index e4d2bda14..2576b4c37 100644
--- a/src/main/java/org/scijava/Context.java
+++ b/src/main/java/org/scijava/Context.java
@@ -58,7 +58,7 @@
* @author Curtis Rueden
* @see Service
*/
-public class Context implements Disposable {
+public class Context implements Disposable, AutoCloseable {
// -- Constants --
@@ -248,6 +248,13 @@ public Context(final Collection> serviceClasses,
* those of lower priority). See {@link ServiceHelper#loadServices()} for more
* information.
*
+ *
+ * NB: Instiantiation of a Context has an implied requirement of a
+ * corresponding call to {@link Context#dispose()} at the end of the SciJava
+ * applicaton's lifecycle. This cleans up any remaining resources and allows
+ * the JVM to exit gracefully. This is called automatically when constructed as
+ * an {@link AutoCloseable}.
+ *
*
* @param serviceClasses A collection of types that implement the
* {@link Service} interface (e.g., {@code DisplayService.class}).
@@ -423,6 +430,13 @@ public void dispose() {
}
}
+ // -- AutoCloseable methods --
+
+ @Override
+ public void close() throws Exception {
+ dispose();
+ }
+
// -- Utility methods --
/**
From b9e7b951d1b57919f8ec45ce2f5a7a2ce5716bdd Mon Sep 17 00:00:00 2001
From: Jan Eglinger
Date: Thu, 30 Apr 2020 15:50:39 +0200
Subject: [PATCH 022/264] Add WidgetStyle utility class to centralize style
logic
This should replace isStyle() implementations and other case logic around (possibly multiple) style attributes of parameters.
Also add a test exercising this utility class.
---
.../scijava/widget/DefaultWidgetModel.java | 7 +-
.../java/org/scijava/widget/WidgetStyle.java | 35 ++++++++++
.../org/scijava/script/ScriptInfoTest.java | 6 +-
.../org/scijava/widget/WidgetStyleTest.java | 68 +++++++++++++++++++
4 files changed, 108 insertions(+), 8 deletions(-)
create mode 100644 src/main/java/org/scijava/widget/WidgetStyle.java
create mode 100644 src/test/java/org/scijava/widget/WidgetStyleTest.java
diff --git a/src/main/java/org/scijava/widget/DefaultWidgetModel.java b/src/main/java/org/scijava/widget/DefaultWidgetModel.java
index ffb19061f..1a768d5d7 100644
--- a/src/main/java/org/scijava/widget/DefaultWidgetModel.java
+++ b/src/main/java/org/scijava/widget/DefaultWidgetModel.java
@@ -129,12 +129,7 @@ public String getWidgetLabel() {
@Override
public boolean isStyle(final String style) {
- final String widgetStyle = getItem().getWidgetStyle();
- if (widgetStyle == null) return style == null;
- for (final String s : widgetStyle.split(",")) {
- if (s.equals(style)) return true;
- }
- return false;
+ return WidgetStyle.isStyle(getItem(), style);
}
@Override
diff --git a/src/main/java/org/scijava/widget/WidgetStyle.java b/src/main/java/org/scijava/widget/WidgetStyle.java
new file mode 100644
index 000000000..346262d01
--- /dev/null
+++ b/src/main/java/org/scijava/widget/WidgetStyle.java
@@ -0,0 +1,35 @@
+package org.scijava.widget;
+
+import org.scijava.module.ModuleItem;
+
+public class WidgetStyle {
+ private WidgetStyle() {
+ // prevent instantiation of utility class
+ }
+
+ public static boolean isStyle(String widgetStyle, String target) {
+ if (widgetStyle == null || target == null)
+ return widgetStyle == target;
+ for (final String s : widgetStyle.split(",")) {
+ if (s.trim().toLowerCase().equals(target.toLowerCase())) return true;
+ }
+ return false;
+ }
+
+ public static boolean isStyle(ModuleItem> item, String target) {
+ return isStyle(item.getWidgetStyle(), target);
+ }
+
+ public static String[] getStyleModifiers(String widgetStyle, String target) {
+ if (widgetStyle == null || target == null)
+ return null;
+ String[] styles = widgetStyle.split(",");
+ for (String s : styles) {
+ if (s.trim().toLowerCase().startsWith(target.toLowerCase())) {
+ String suffix = s.split(":")[1];
+ return suffix.split("/");
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/test/java/org/scijava/script/ScriptInfoTest.java b/src/test/java/org/scijava/script/ScriptInfoTest.java
index 38c0ffa2f..678996628 100644
--- a/src/test/java/org/scijava/script/ScriptInfoTest.java
+++ b/src/test/java/org/scijava/script/ScriptInfoTest.java
@@ -65,6 +65,7 @@
import org.scijava.test.TestUtils;
import org.scijava.util.DigestUtils;
import org.scijava.util.FileUtils;
+import org.scijava.widget.WidgetStyle;
/**
* Tests {@link ScriptInfo}.
@@ -251,7 +252,7 @@ public void testParameters() {
final String script = "" + //
"#@ LogService (required = false) log\n" + //
"#@ int (label=\"Slider Value\", softMin=5, softMax=15, " + //
- "stepSize=3, value=11, style=\"slider\") sliderValue\n" + //
+ "stepSize=3, value=11, style=\" slidEr,\") sliderValue\n" + //
"#@ String (persist = false, family='Carnivora', " + //
"choices={'quick brown fox', 'lazy dog'}) animal\n" + //
"#@ Double (autoFill = false) notAutoFilled\n" + //
@@ -269,7 +270,8 @@ public void testParameters() {
final ModuleItem> sliderValue = info.getInput("sliderValue");
assertItem("sliderValue", int.class, "Slider Value", ItemIO.INPUT, true,
- true, null, "slider", 11, null, null, 5, 15, 3.0, noChoices, sliderValue);
+ true, null, " slidEr,", 11, null, null, 5, 15, 3.0, noChoices, sliderValue);
+ assertTrue("Case-insensitive trimmed style", WidgetStyle.isStyle(sliderValue, "slider"));
final ModuleItem> animal = info.getInput("animal");
final List animalChoices = //
diff --git a/src/test/java/org/scijava/widget/WidgetStyleTest.java b/src/test/java/org/scijava/widget/WidgetStyleTest.java
new file mode 100644
index 000000000..d7b3c0564
--- /dev/null
+++ b/src/test/java/org/scijava/widget/WidgetStyleTest.java
@@ -0,0 +1,68 @@
+package org.scijava.widget;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Enclosed.class)
+public class WidgetStyleTest {
+
+ @RunWith(Parameterized.class)
+ public static class TestIsStyle {
+
+ static String[] styleStrings = { "foo, bar, someThing", " FOO, BAR, SOMEthing ", "foo ", " bar",
+ "trash, sOmEtHiNg", null };
+
+ static String[] stylesToTest = { "foo", "bar", "someThing", null };
+
+ static boolean[][] stylesToHave = { // foo, bar, someThing
+ new boolean[] { true, true, true, false }, new boolean[] { true, true, true, false },
+ new boolean[] { true, false, false, false }, new boolean[] { false, true, false, false },
+ new boolean[] { false, false, true, false }, new boolean[] { false, false, false, true } };
+
+ @Parameters(name = "{0}")
+ public static List