From 49c055b05f5d46340eeade887744ab72bbba7525 Mon Sep 17 00:00:00 2001
From: Curtis Rueden
* In the case of AWT-based applications (e.g., Java on the desktop), this is
* typically the AWT Event Dispatch Thread (EDT). However, ultimately the
@@ -141,7 +141,8 @@ void invoke(Runnable code) throws InterruptedException,
InvocationTargetException;
/**
- * Queues the given code for later execution in a special dispatch thread.
+ * Queues the given code for later execution in a special dispatch thread,
+ * returning immediately.
*
* In the case of AWT-based applications (e.g., Java on the desktop), this is
* typically the AWT Event Dispatch Thread (EDT). However, ultimately the
From ec4f6e0336148bd10f0fd3538d9b1cac216a9f82 Mon Sep 17 00:00:00 2001
From: Curtis Rueden
From 02b59b0398e408c18a3025b365e7bbc1c698ea72 Mon Sep 17 00:00:00 2001
From: Curtis Rueden
+ * This method wraps around, i.e. it returns {@code null} when there is no
+ * more-recent command in the history.
+ *
+ * This method wraps around, i.e. it returns {@code null} when there is no
+ * less-recent command in the history.
+ *
- * This method wraps around, i.e. it returns {@code null} when there is no
- * more-recent command in the history.
- *
- * This method wraps around, i.e. it returns {@code null} when there is no
- * less-recent command in the history.
- *
* There are many kinds of services, but most of them share one common
* characteristic: they provide API specific to a particular type of plugin. A
- * few examples from ImageJ:
+ * few examples:
*
diff --git a/src/main/java/org/scijava/script/ScriptModule.java b/src/main/java/org/scijava/script/ScriptModule.java
index 92cf3ced9..d00b7ab5e 100644
--- a/src/main/java/org/scijava/script/ScriptModule.java
+++ b/src/main/java/org/scijava/script/ScriptModule.java
@@ -50,7 +50,6 @@
import org.scijava.module.Module;
import org.scijava.module.ModuleItem;
import org.scijava.plugin.Parameter;
-import org.scijava.util.FileUtils;
/**
* A {@link Module} which executes a script.
@@ -76,9 +75,6 @@ public class ScriptModule extends AbstractModule implements Contextual {
@Parameter
private LogService log;
- /** Script language in which the script should be executed. */
- private ScriptLanguage scriptLanguage;
-
/** Script engine with which the script should be executed. */
private ScriptEngine scriptEngine;
@@ -96,22 +92,6 @@ public ScriptModule(final ScriptInfo info) {
// -- ScriptModule methods --
- /** Gets the scripting language of the script. */
- public ScriptLanguage getLanguage() {
- if (scriptLanguage == null) {
- // infer the language from the script path's extension
- final String path = getInfo().getPath();
- final String extension = FileUtils.getExtension(path);
- scriptLanguage = scriptService.getLanguageByExtension(extension);
- }
- return scriptLanguage;
- }
-
- /** Overrides the script language to use when executing the script. */
- public void setLanguage(final ScriptLanguage scriptLanguage) {
- this.scriptLanguage = scriptLanguage;
- }
-
/** Sets the writer used to record the standard output stream. */
public void setOutputWriter(final Writer output) {
this.output = output;
@@ -125,7 +105,7 @@ public void setErrorWriter(final Writer error) {
/** Gets the script engine used to execute the script. */
public ScriptEngine getEngine() {
if (scriptEngine == null) {
- scriptEngine = getLanguage().getScriptEngine();
+ scriptEngine = getInfo().getLanguage().getScriptEngine();
}
return scriptEngine;
}
@@ -185,7 +165,7 @@ public void run() {
}
// populate output values
- final ScriptLanguage language = getLanguage();
+ final ScriptLanguage language = getInfo().getLanguage();
for (final ModuleItem> item : getInfo().outputs()) {
final String name = item.getName();
final Object value;
@@ -230,4 +210,17 @@ public void setContext(final Context context) {
context.inject(this);
}
+ // -- Deprecated methods --
+
+ /** @deprecated Use {@link ScriptInfo#getLanguage()} instead. */
+ @Deprecated
+ public ScriptLanguage getLanguage() {
+ return getInfo().getLanguage();
+ }
+
+ /** @deprecated Use {@link ScriptInfo#setLanguage(ScriptLanguage)} instead. */
+ @Deprecated
+ public void setLanguage(final ScriptLanguage scriptLanguage) {
+ getInfo().setLanguage(scriptLanguage);
+ }
}
From e467c5d30435c5614974afabd2fc0819aac6b09d Mon Sep 17 00:00:00 2001
From: Curtis Rueden
@@ -335,11 +342,6 @@ public void parseParameters() {
}
}
- /** Gets whether the return value is appended as an additional output. */
- public boolean isReturnValueAppended() {
- return appendReturnValue;
- }
-
// -- ModuleInfo methods --
@Override
From 012b00d4fe92587973e304c264081a7749b93c31 Mon Sep 17 00:00:00 2001
From: Curtis Rueden
+ * Typically, these plugins look for special directives in the script itself
+ * beginning with distinctive character sequences like {@code #@}, and then
+ * perform some action in response.
+ *
- * This class is responsible for parsing the script for parameters. See
- * {@link #parseParameters()} for details.
- *
- * This method is called automatically the first time any parameter accessor
- * method is called ({@link #getInput}, {@link #getOutput}, {@link #inputs()},
- * {@link #outputs()}, etc.). Subsequent calls will reparse the parameters.
- *
- * SciJava's scripting framework supports specifying @{@link Parameter}-style
- * inputs and outputs in a preamble. The format is a simplified version of the
- * Java @{@link Parameter} annotation syntax. The following syntaxes are
- * supported:
- *
- * Where:
- *
- * See the @{@link Parameter} annotation for a list of valid attributes.
- *
- * Here are a few examples:
- *
- * Parameters will be parsed and filled just like @{@link Parameter}-annotated
- * fields in {@link Command}s.
- *
+ * SciJava's scripting framework supports specifying @{@link Parameter}-style
+ * inputs and outputs in a preamble. The format is a simplified version of the
+ * Java @{@link Parameter} annotation syntax. The following syntaxes are
+ * supported:
+ *
+ * Where:
+ *
+ * See the @{@link Parameter} annotation for a list of valid attributes.
+ *
+ * Here are a few examples:
+ *
+ * Parameters will be parsed and filled just like @{@link Parameter}-annotated
+ * fields in {@link Command}s.
+ *
* Where:
*
* See the @{@link Parameter} annotation for a list of valid attributes.
@@ -88,10 +87,10 @@
* Here are a few examples:
*
@@ -129,6 +128,14 @@ public void begin(final ScriptInfo scriptInfo) {
@Override
public void process(final String line) {
+ // parse new-style parameters starting with @# anywhere in the script.
+ if (line.matches("^#@.*")) {
+ final int at = line.indexOf('@');
+ parseParam(line.substring(at + 1));
+ return;
+ }
+
+ // parse old-style parameters in the initial script header
if (header) {
// NB: Check if line contains an '@' with no prior alphameric
// characters. This assumes that only non-alphanumeric characters can
@@ -170,10 +177,11 @@ private void parseParam(final String param, final Map
+ * This method provides a facade to byte buffer allocation that enables
+ *
*
- *
- *
- *
- *
- *
- *
+ *
+ *
+ *
+ *
+ *
+ *
- *
*
- *
*
- *
* FileChannel.map() usage on platforms where it's unlikely to
+ * give us problems and heap allocation where it is.
+ *
+ * First, two bytes are written to out as if by the {@code writeShort} method + * giving the number of bytes to follow. This value is the number of bytes + * actually written out, not the length of the string. Following the length, + * each character of the string is output, in sequence, using the modified + * UTF-8 encoding for the character. If no exception is thrown, the counter + * {@code written} is incremented by the total number of bytes written to the + * output stream. This will be at least two plus the length of {@code str}, + * and at most two plus thrice the length of {@code str}. + *
+ * + * @param str a string to be written. + * @param out destination to write to + * @return The number of bytes written out. + * @throws IOException if an I/O error occurs. + */ + public static int writeUTF(final String str, final DataOutput out) + throws IOException + { + // HACK: Strangely, DataOutputStream.writeUTF(String, DataOutput) + // has package-private access. We work around it via reflection. + try { + return (Integer) utfMethod().invoke(null, str, out); + } + catch (final IllegalAccessException | IllegalArgumentException + | InvocationTargetException exc) + { + throw new IllegalStateException( + "Cannot invoke DataOutputStream.writeUTF(String, DataOutput)", exc); + } + } + + // -- Helper methods -- + + /** Gets the {@link #utfMethod} field, initializing if needed. */ + private static Method utfMethod() { + if (utfMethod == null) initUTFMethod(); + return utfMethod; + } + + /** Initializes the {@link #utfMethod} field. */ + private static synchronized void initUTFMethod() { + if (utfMethod != null) return; + try { + final Method m = DataOutputStream.class.getDeclaredMethod("writeUTF", + String.class, DataOutput.class); + m.setAccessible(true); + utfMethod = m; + } + catch (final NoSuchMethodException | SecurityException exc) { + throw new IllegalStateException( + "No usable DataOutputStream.writeUTF(String, DataOutput)", exc); + } + } +} From e702e9195d878477eae011f70fdaff708ecf125c Mon Sep 17 00:00:00 2001 From: Curtis Rueden+ * In the case of reading, attempting to read the returned number of bytes is + * guaranteed not to throw {@link EOFException}. However, be aware that the + * following methods might still process fewer bytes than indicated + * by this method: + *
+ *+ * In the case of writing, attempting to write the returned number of bytes is + * guaranteed not to expand the length of the handle; i.e., the write will + * only overwrite bytes already within the handle's bounds. + *
* - * @param count Number of bytes to read. - * @return The actual number of bytes available to be read. + * @param count Desired number of bytes to read/write. + * @return The actual number of bytes which could be safely read/written, + * which might be less than the requested value. * @throws IOException If something goes wrong with the check. */ default long available(final long count) throws IOException { @@ -109,8 +128,8 @@ default void ensureReadable(final long count) throws IOException { } /** - * Ensures that the handle has the correct length to be written to and extends - * it as required. + * Ensures that the handle has the correct length to be written to, and + * extends it as required. * * @param count Number of bytes to write. * @return {@code true} if the handle's length was sufficient, or @@ -202,7 +221,7 @@ default int read(final ByteBuffer buf, final int len) throws IOException { } /** - * Writes up to {@code buf.remaining()} bytes of data from the given + * Writes {@code buf.remaining()} bytes of data from the given * {@link ByteBuffer} to the stream. */ default void write(final ByteBuffer buf) throws IOException { @@ -210,7 +229,8 @@ default void write(final ByteBuffer buf) throws IOException { } /** - * Writes up to len bytes of data from the given ByteBuffer to the stream. + * Writes {@code len} bytes of data from the given {@link ByteBuffer} to the + * stream. */ default void write(final ByteBuffer buf, final int len) throws IOException @@ -227,7 +247,6 @@ default void write(final ByteBuffer buf, final int len) } } - /** Reads a string of arbitrary length, terminated by a null char. */ default String readCString() throws IOException { final String line = findString("\0"); From 795295b64a09c647a24363b2144a4a2c72061948 Mon Sep 17 00:00:00 2001 From: Gabriel Einsdorf
* In the case of reading, attempting to read the returned number of bytes is
@@ -104,9 +104,9 @@ public interface DataHandle
- * By default, this method will return {@code true} always, since the type is - * known to be compatible. But individual implementations may have other - * requirements beyond class assignability. + * By default, this method will return {@code true} iff the data is assignable + * to the associated type given by {@link #getType()}. But individual + * implementations may have other requirements beyond class assignability. *
*/ - default boolean supports(@SuppressWarnings("unused") T data) { - return true; + default boolean supports(final T data) { + // NB: Even though the compiler will often guarantee that only data + // of type T is provided here, we still need the runtime check + // for cases where the exact type is not known to compiler -- + // e.g., if the object was manufactured by reflection. + return getType().isInstance(data); } /** Gets the type associated with the object. */ diff --git a/src/main/java/org/scijava/plugin/AbstractTypedPlugin.java b/src/main/java/org/scijava/plugin/AbstractTypedPlugin.java index ac29ee129..75fe7a7c5 100644 --- a/src/main/java/org/scijava/plugin/AbstractTypedPlugin.java +++ b/src/main/java/org/scijava/plugin/AbstractTypedPlugin.java @@ -47,11 +47,8 @@ public abstract class AbstractTypedPlugin+ * No guarantee is made about the exact nature of the checksum (e.g., SHA-1 or + * MD5), only that the value is deterministic for this particular location + * with its current contents. In other words: if a checksum differs from a + * previous inquiry, you can be sure the contents have changed; conversely, if + * the checksum is still the same, the contents are highly likely to be + * unchanged. + *
+ * + * @return The checksum, or null if the handle does not support this feature. + * @throws IOException If something goes wrong when accessing the checksum. + */ + default String checksum() throws IOException { + return null; + } + /** Returns the current offset in the stream. */ long offset() throws IOException; diff --git a/src/main/java/org/scijava/io/handle/FileHandle.java b/src/main/java/org/scijava/io/handle/FileHandle.java index 1c3348ce9..02c16492e 100644 --- a/src/main/java/org/scijava/io/handle/FileHandle.java +++ b/src/main/java/org/scijava/io/handle/FileHandle.java @@ -34,6 +34,7 @@ import java.io.IOException; import java.io.RandomAccessFile; +import java.util.Date; import org.scijava.io.location.FileLocation; import org.scijava.plugin.Plugin; @@ -89,6 +90,12 @@ public boolean exists() { return get().getFile().exists(); } + @Override + public Date lastModified() { + final long lastModified = get().getFile().lastModified(); + return lastModified == 0 ? null : new Date(lastModified); + } + @Override public long offset() throws IOException { return raf().getFilePointer(); From 63cf9dc2b62a728bbe31a6feec077acd6e439202 Mon Sep 17 00:00:00 2001 From: Curtis Rueden+ * Note that it is still possible to prioritize something earlier + * than this value (e.g., for testing purposes), although doing so strongly + * discouraged in production. + *
+ */ + public static final double FIRST = +1e300; + + /** Priority for items that very strongly prefer to be sorted early. */ + public static final double EXTREMELY_HIGH = +1000000; /** Priority for items that strongly prefer to be sorted early. */ - public static final double VERY_HIGH_PRIORITY = +10000; + public static final double VERY_HIGH = +10000; /** Priority for items that prefer to be sorted earlier. */ - public static final double HIGH_PRIORITY = +100; + public static final double HIGH = +100; /** Default priority for items. */ - public static final double NORMAL_PRIORITY = 0; + public static final double NORMAL = 0; /** Priority for items that prefer to be sorted later. */ - public static final double LOW_PRIORITY = -100; + public static final double LOW = -100; /** Priority for items that strongly prefer to be sorted late. */ - public static final double VERY_LOW_PRIORITY = -10000; + public static final double VERY_LOW = -10000; - /** Priority for items that must be sorted last. */ - public static final double LAST_PRIORITY = Double.NEGATIVE_INFINITY; + /** Priority for items that very strongly prefer to be sorted late. */ + public static final double EXTREMELY_LOW = -1000000; + + /** Priority for items that must be sorted last. + *+ * Note that it is still possible to prioritize something later + * than this value (e.g., for testing purposes), although doing so strongly + * discouraged in production. + *
+ */ + public static final double LAST = -1e300; /** * Compares two {@link Prioritized} objects. @@ -109,4 +128,33 @@ public static boolean inject(final Object o, final double priority) { return true; } + // -- Deprecated -- + + /** @deprecated Use {@link #FIRST} instead. */ + @Deprecated + public static final double FIRST_PRIORITY = Double.POSITIVE_INFINITY; + + /** @deprecated Use {@link #VERY_HIGH} instead. */ + @Deprecated + public static final double VERY_HIGH_PRIORITY = +10000; + + /** @deprecated Use {@link #HIGH} instead. */ + @Deprecated + public static final double HIGH_PRIORITY = +100; + + /** @deprecated Use {@link #NORMAL} instead. */ + @Deprecated + public static final double NORMAL_PRIORITY = 0; + + /** @deprecated Use {@link #LOW} instead. */ + @Deprecated + public static final double LOW_PRIORITY = -100; + + /** @deprecated Use {@link #VERY_LOW} instead. */ + @Deprecated + public static final double VERY_LOW_PRIORITY = -10000; + + /** @deprecated Use {@link #LAST} instead. */ + @Deprecated + public static final double LAST_PRIORITY = Double.NEGATIVE_INFINITY; } diff --git a/src/main/java/org/scijava/app/SciJavaApp.java b/src/main/java/org/scijava/app/SciJavaApp.java index 51da39f7a..12c049697 100644 --- a/src/main/java/org/scijava/app/SciJavaApp.java +++ b/src/main/java/org/scijava/app/SciJavaApp.java @@ -42,7 +42,7 @@ * @see AppService */ @Plugin(type = App.class, name = SciJavaApp.NAME, - priority = Priority.LOW_PRIORITY) + priority = Priority.LOW) public class SciJavaApp extends AbstractApp { public static final String NAME = "SciJava"; diff --git a/src/main/java/org/scijava/cache/DefaultCacheService.java b/src/main/java/org/scijava/cache/DefaultCacheService.java index c5f952499..4111a45a6 100644 --- a/src/main/java/org/scijava/cache/DefaultCacheService.java +++ b/src/main/java/org/scijava/cache/DefaultCacheService.java @@ -43,7 +43,7 @@ /** * Trivial {@link CacheService} implementation. Wraps a {@link WeakHashMap} */ -@Plugin(type = Service.class, priority = Priority.VERY_LOW_PRIORITY) +@Plugin(type = Service.class, priority = Priority.VERY_LOW) public class DefaultCacheService extends AbstractService implements CacheService { diff --git a/src/main/java/org/scijava/convert/ArrayConverters.java b/src/main/java/org/scijava/convert/ArrayConverters.java index 803486705..70b0d927c 100644 --- a/src/main/java/org/scijava/convert/ArrayConverters.java +++ b/src/main/java/org/scijava/convert/ArrayConverters.java @@ -54,7 +54,7 @@ public class ArrayConverters { // -- Integer array converters -- - @Plugin(type = Converter.class, priority = Priority.HIGH_PRIORITY) + @Plugin(type = Converter.class, priority = Priority.HIGH) public static class IntArrayWrapper extends PrimitiveArrayWrapper