Skip to content

Commit f1d2b4d

Browse files
committed
Merge pull request #194 from Squareys/independent-script-readers
Independent Readers in ScriptInfo
2 parents 1d690c2 + 957e7a1 commit f1d2b4d

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

src/main/java/org/scijava/script/ScriptInfo.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.io.FileReader;
3737
import java.io.IOException;
3838
import java.io.Reader;
39+
import java.io.StringReader;
3940
import java.text.SimpleDateFormat;
4041
import java.util.Date;
4142
import java.util.HashMap;
@@ -73,7 +74,7 @@ public class ScriptInfo extends AbstractModuleInfo implements Contextual {
7374
private static final int PARAM_CHAR_MAX = 640 * 1024; // should be enough ;-)
7475

7576
private final String path;
76-
private final BufferedReader reader;
77+
private final String script;
7778

7879
@Parameter
7980
private Context context;
@@ -128,8 +129,17 @@ public ScriptInfo(final Context context, final String path,
128129
{
129130
setContext(context);
130131
this.path = path;
131-
this.reader =
132-
reader == null ? null : new BufferedReader(reader, PARAM_CHAR_MAX);
132+
133+
String script = null;
134+
if (reader != null) {
135+
try {
136+
script = getReaderContentsAsString(reader);
137+
}
138+
catch (final IOException exc) {
139+
log.error("Error reading script: " + path, exc);
140+
}
141+
}
142+
this.script = script;
133143
}
134144

135145
// -- ScriptInfo methods --
@@ -148,14 +158,17 @@ public String getPath() {
148158
}
149159

150160
/**
151-
* Gets the reader which delivers the script's content.
161+
* Gets a reader which delivers the script's content.
152162
* <p>
153163
* This might be null, in which case the content is stored in a file on disk
154164
* given by {@link #getPath()}.
155165
* </p>
156166
*/
157167
public BufferedReader getReader() {
158-
return reader;
168+
if (script == null) {
169+
return null;
170+
}
171+
return new BufferedReader(new StringReader(script), PARAM_CHAR_MAX);
159172
}
160173

161174
/**
@@ -214,12 +227,11 @@ public void parseParameters() {
214227

215228
try {
216229
final BufferedReader in;
217-
if (reader == null) {
230+
if (script == null) {
218231
in = new BufferedReader(new FileReader(getPath()));
219232
}
220233
else {
221-
in = reader;
222-
in.mark(PARAM_CHAR_MAX);
234+
in = getReader();
223235
}
224236
while (true) {
225237
final String line = in.readLine();
@@ -234,8 +246,7 @@ public void parseParameters() {
234246
}
235247
else if (line.matches(".*\\w.*")) break;
236248
}
237-
if (reader == null) in.close();
238-
else in.reset();
249+
in.close();
239250

240251
if (!returnValueDeclared) addReturnValue();
241252
}
@@ -478,4 +489,27 @@ else if ("value".equalsIgnoreCase(key)) {
478489
}
479490
}
480491

492+
/**
493+
* Read entire contents of a Reader and return as String.
494+
*
495+
* @param reader {@link Reader} whose contents should be returned as String.
496+
* Expected to never be <code>null</code>.
497+
* @return contents of reader as String.
498+
* @throws IOException If an I/O error occurs
499+
* @throws NullPointerException If reader is <code>null</code>
500+
*/
501+
private static String getReaderContentsAsString(final Reader reader)
502+
throws IOException, NullPointerException
503+
{
504+
final char[] buffer = new char[8192];
505+
final StringBuilder builder = new StringBuilder();
506+
507+
int read;
508+
while ((read = reader.read(buffer)) != -1) {
509+
builder.append(buffer, 0, read);
510+
}
511+
512+
return builder.toString();
513+
}
514+
481515
}

src/test/java/org/scijava/script/ScriptInfoTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import static org.junit.Assert.assertTrue;
3636
import static org.junit.Assert.fail;
3737

38+
import java.io.BufferedReader;
3839
import java.io.File;
3940
import java.io.IOException;
4041
import java.io.Reader;
@@ -124,6 +125,26 @@ public void testVersion() throws IOException {
124125
FileUtils.deleteRecursively(tmpDir);
125126
}
126127

128+
/**
129+
* Ensures the ScriptInfos Reader can be reused for multiple executions of the
130+
* script.
131+
*/
132+
@Test
133+
public void testReaderSanity() throws Exception {
134+
final String script = "" + //
135+
"% @LogService log\n" + //
136+
"% @OUTPUT Integer output";
137+
138+
ScriptInfo info = new ScriptInfo(context, "hello.bsizes", new StringReader(
139+
script));
140+
BufferedReader reader1 = info.getReader();
141+
BufferedReader reader2 = info.getReader();
142+
143+
assertEquals("Readers are not independent.", reader1.read(), reader2
144+
.read());
145+
146+
}
147+
127148
@Plugin(type = ScriptLanguage.class)
128149
public static class BindingSizes extends AbstractScriptLanguage {
129150

0 commit comments

Comments
 (0)