diff --git a/pom.xml b/pom.xml index 893a968ca..8065fba5a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ scijava-common - 2.85.1-SNAPSHOT + 2.86.1-SNAPSHOT SciJava Common SciJava 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. diff --git a/src/main/java/org/scijava/convert/AbstractConverter.java b/src/main/java/org/scijava/convert/AbstractConverter.java index 08699df4f..1fb2cade1 100644 --- a/src/main/java/org/scijava/convert/AbstractConverter.java +++ b/src/main/java/org/scijava/convert/AbstractConverter.java @@ -98,19 +98,9 @@ public boolean canConvert(final Object src, final Type dest) { public boolean canConvert(final Object src, final Class dest) { if (src == null) return false; final Class srcClass = src.getClass(); - return canConvert(srcClass, dest); } - @Override - public boolean canConvert(final Class src, final Class dest) { - if (src == null) return false; - final Class saneSrc = Types.box(src); - final Class saneDest = Types.box(dest); - return Types.isAssignable(saneSrc, getInputType()) && - Types.isAssignable(getOutputType(), saneDest); - } - @Override public Object convert(final Object src, final Type dest) { final Class destClass = Types.raw(dest); @@ -148,6 +138,16 @@ public Class getType() { // -- Deprecated API -- + @Override + @Deprecated + public boolean canConvert(final Class src, final Class dest) { + if (src == null) return false; + final Class saneSrc = Types.box(src); + final Class saneDest = Types.box(dest); + return Types.isAssignable(saneSrc, getInputType()) && + Types.isAssignable(getOutputType(), saneDest); + } + @Override @Deprecated public boolean canConvert(final Class src, final Type dest) { diff --git a/src/main/java/org/scijava/log/AbstractLogService.java b/src/main/java/org/scijava/log/AbstractLogService.java index e813e10e3..e749bf59a 100644 --- a/src/main/java/org/scijava/log/AbstractLogService.java +++ b/src/main/java/org/scijava/log/AbstractLogService.java @@ -104,7 +104,7 @@ public LogSource getSource() { @Override public int getLevel() { if (classAndPackageLevels.isEmpty()) return currentLevel; - return getLevelForClass(CallingClassUtils.getCallingClass().getName(), + return getLevelForClass(CallingClassUtils.getCallingClassName(), currentLevel); } diff --git a/src/main/java/org/scijava/log/CallingClassUtils.java b/src/main/java/org/scijava/log/CallingClassUtils.java index 5bcf98460..66bef3263 100644 --- a/src/main/java/org/scijava/log/CallingClassUtils.java +++ b/src/main/java/org/scijava/log/CallingClassUtils.java @@ -29,6 +29,8 @@ package org.scijava.log; +import org.scijava.Context; + /** * Utility class for getting the calling class of a method. * @@ -43,12 +45,44 @@ private CallingClassUtils() { } /** + * Inspects the stack trace to return the name of the class that calls + * this method, but ignores every class annotated with @IgnoreAsCallingClass. + *

+ * If every class on the stack trace is annotated, then the class at the + * root of the stack trace is returned. + */ + public static String getCallingClassName() { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + for (int i = 1; i < stackTrace.length - 2; i++) { + String className = stackTrace[i].getClassName(); + if (!hasIgnoreAsCallingClassAnnotation(className)) return className; + } + return stackTrace[stackTrace.length - 1].getClassName(); + } + + private static boolean hasIgnoreAsCallingClassAnnotation(String className) { + try { + Class< ? > clazz = Context.getClassLoader().loadClass(className); + return clazz.isAnnotationPresent(IgnoreAsCallingClass.class); + } + catch (ClassNotFoundException ignore) { + return false; + } + } + + /** + * @deprecated Use {@link #getCallingClassName()} instead. + * + * Warning: This method throws a IllegalStateException as soon as it comes + * across a class that can't be loaded with the default class loader. + * * Inspects the stack trace to return the class that calls this method, but * ignores every class annotated with @IgnoreAsCallingClass. * * @throws IllegalStateException if every method on the stack, is in a class * annotated with @IgnoreAsCallingClass. */ + @Deprecated public static Class getCallingClass() { try { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); diff --git a/src/main/java/org/scijava/log/IgnoreAsCallingClass.java b/src/main/java/org/scijava/log/IgnoreAsCallingClass.java index d6ff175f1..62aefe2db 100644 --- a/src/main/java/org/scijava/log/IgnoreAsCallingClass.java +++ b/src/main/java/org/scijava/log/IgnoreAsCallingClass.java @@ -34,7 +34,7 @@ /** * Classes annotated with {@link IgnoreAsCallingClass} are ignored by - * {@link CallingClassUtils#getCallingClass()}. + * {@link CallingClassUtils#getCallingClassName()}. * * @author Matthias Arzt */ diff --git a/src/main/java/org/scijava/script/ScriptREPL.java b/src/main/java/org/scijava/script/ScriptREPL.java index d6c10adfd..edfafa538 100644 --- a/src/main/java/org/scijava/script/ScriptREPL.java +++ b/src/main/java/org/scijava/script/ScriptREPL.java @@ -69,6 +69,8 @@ public class ScriptREPL { private final PrintStream out; + private String languagePreference = null; + /** List of interpreter-friendly script languages. */ private List languages; @@ -88,6 +90,15 @@ public ScriptREPL(final Context context, final OutputStream out) { (PrintStream) out : new PrintStream(out); } + public ScriptREPL(final Context context, final String language) { + this(context, language, System.out); + } + + public ScriptREPL(final Context context, final String language, final OutputStream out) { + this(context, out); + languagePreference = language; + } + /** * Gets the list of languages compatible with the REPL. *

@@ -162,12 +173,35 @@ public void initialize(final boolean verbose) { } out.println("Have fun!"); out.println(); - lang(langs.get(0).getLanguageName()); + + if(languagePreference != null) { + selectPreferredLanguage(langs); + } else { + lang(langs.get(0).getLanguageName()); + } } - else if (!langs.isEmpty()) lang(langs.get(0)); + else if (!langs.isEmpty()) { + if(languagePreference != null) { + selectPreferredLanguage(langs); + } else { + lang(langs.get(0)); + } + } + populateBindings(interpreter.getBindings()); } + private void selectPreferredLanguage(List langs) { + final ScriptLanguage preference = langs + .stream().filter(lang -> languagePreference.equals(lang.getLanguageName())) + .findAny().orElse(null); + if(preference != null) { + lang(preference); + } else { + lang(langs.get(0).getLanguageName()); + } + } + /** Outputs the prompt. */ public void prompt() { out.print(interpreter == null || interpreter.isReady() ? "> " : "\\ "); @@ -310,8 +344,15 @@ public static void main(final String... args) throws Exception { // make a SciJava application context final Context context = new Context(); - // create the script interpreter - final ScriptREPL scriptCLI = new ScriptREPL(context); + // see if we have a preferred language + // and create the script interpreter + final ScriptREPL scriptCLI; + if(args.length > 0) { + final String preference = args[0]; + scriptCLI = new ScriptREPL(context, preference); + } else { + scriptCLI = new ScriptREPL(context); + } // start the REPL scriptCLI.loop(); diff --git a/src/test/java/org/scijava/io/event/DataEventTest.java b/src/test/java/org/scijava/io/event/DataEventTest.java index 45568b12e..e2d9457cd 100644 --- a/src/test/java/org/scijava/io/event/DataEventTest.java +++ b/src/test/java/org/scijava/io/event/DataEventTest.java @@ -28,15 +28,20 @@ */ package org.scijava.io.event; -import org.junit.Test; - import static org.junit.Assert.assertEquals; +import java.io.File; +import java.io.IOException; + +import org.junit.Test; + public class DataEventTest { @Test - public void testDeprecatedMethods() { - String localPath = "/local/absolute/path.txt"; + public void testDeprecatedMethods() throws IOException { + File tmpFile = File.createTempFile("path", "txt"); + tmpFile.deleteOnExit(); + String localPath = tmpFile.getAbsolutePath(); Object obj = null; DataOpenedEvent openedEvent = new DataOpenedEvent(localPath, obj); DataSavedEvent savedEvent = new DataSavedEvent(localPath, obj); diff --git a/src/test/java/org/scijava/log/CallingClassUtilsTest.java b/src/test/java/org/scijava/log/CallingClassUtilsTest.java index a23f8fee0..ff6d3df24 100644 --- a/src/test/java/org/scijava/log/CallingClassUtilsTest.java +++ b/src/test/java/org/scijava/log/CallingClassUtilsTest.java @@ -31,6 +31,8 @@ import org.junit.Test; +import java.util.function.Supplier; + import static org.junit.Assert.assertEquals; /** @@ -41,26 +43,26 @@ public class CallingClassUtilsTest { @Test public void testGetCallingClass() { - Class callingClass = CallingClassUtils.getCallingClass(); - assertEquals(this.getClass(), callingClass); + String callingClass = CallingClassUtils.getCallingClassName(); + assertEquals(this.getClass().getName(), callingClass); } @Test public void testIgnoreAsCallingClass() { - assertEquals(ClassA.class, ClassA.returnGetCallingClass()); - assertEquals(this.getClass(), ClassB.returnGetCallingClass()); + assertEquals(ClassA.class.getName(), ClassA.returnGetCallingClass()); + assertEquals(this.getClass().getName(), ClassB.returnGetCallingClass()); } public static class ClassA { - static Class returnGetCallingClass() { - return CallingClassUtils.getCallingClass(); + static String returnGetCallingClass() { + return CallingClassUtils.getCallingClassName(); } } @IgnoreAsCallingClass private static class ClassB { - static Class returnGetCallingClass() { - return CallingClassUtils.getCallingClass(); + static String returnGetCallingClass() { + return CallingClassUtils.getCallingClassName(); } } }