Skip to content

Commit d7f00fc

Browse files
committed
JavaEngine: Add all missing Javadocs
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent f6dd3f4 commit d7f00fc

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

src/main/java/org/scijava/plugins/scripting/java/JavaEngine.java

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ public class JavaEngine extends AbstractScriptEngine {
9696
private final static String DEFAULT_GROUP_ID = "net.imagej";
9797
private final static String DEFAULT_VERSION = "1.0.0-SNAPSHOT";
9898

99+
/**
100+
* The key to specify how to indent the XML written out by Xalan.
101+
*/
99102
private final static String XALAN_INDENT_AMOUNT = "{http://xml.apache.org/xslt}indent-amount";
103+
100104
{
101105
engineScopeBindings = new JavaEngineBindings();
102106
}
@@ -110,11 +114,31 @@ public class JavaEngine extends AbstractScriptEngine {
110114
@Parameter
111115
private JavaService javaService;
112116

117+
/**
118+
* Compiles and runs the specified {@code .java} class.
119+
* <p>
120+
* The currently active {@link JavaService} is responsible for running the
121+
* class.
122+
* </p>
123+
*
124+
* @param script the source code for a Java class
125+
* @return null
126+
*/
113127
@Override
114128
public Object eval(String script) throws ScriptException {
115129
return eval(new StringReader(script));
116130
}
117131

132+
/**
133+
* Compiles and runs the specified {@code .java} class.
134+
* <p>
135+
* The currently active {@link JavaService} is responsible for running the
136+
* class.
137+
* </p>
138+
*
139+
* @param reader the reader producing the source code for a Java class
140+
* @return null
141+
*/
118142
@Override
119143
public Object eval(Reader reader) throws ScriptException {
120144
final String path = (String)get(FILENAME);
@@ -169,6 +193,12 @@ public Object eval(Reader reader) throws ScriptException {
169193
return null;
170194
}
171195

196+
/**
197+
* Compiles the specified {@code .java} file.
198+
*
199+
* @param file the source code
200+
* @param errorWriter where to write the errors
201+
*/
172202
public void compile(final File file, final Writer errorWriter) {
173203
try {
174204
final Builder builder = new Builder(file, null, errorWriter);
@@ -207,6 +237,17 @@ public void makeJar(final File file, final boolean includeSources, final File ou
207237
}
208238
}
209239

240+
/**
241+
* Reports an exception.
242+
* <p>
243+
* If a writer for errors is specified (e.g. when being called from the script
244+
* editor), we should just print the error and return. Otherwise, we'll throw
245+
* the exception back at the caller.
246+
* </p>
247+
*
248+
* @param t the exception
249+
* @param errorWriter the error writer, or null
250+
*/
210251
private void printOrThrow(Throwable t, Writer errorWriter) {
211252
RuntimeException e = t instanceof RuntimeException ? (RuntimeException) t
212253
: new RuntimeException(t);
@@ -218,6 +259,11 @@ private void printOrThrow(Throwable t, Writer errorWriter) {
218259
err.flush();
219260
}
220261

262+
/**
263+
* A wrapper around a (possibly only temporary) project.
264+
*
265+
* @author Johannes Schindelin
266+
*/
221267
private class Builder {
222268
private final PrintStream err;
223269
private final File temporaryDirectory;
@@ -280,6 +326,9 @@ public void println(final String line) throws IOException {
280326
}
281327
}
282328

329+
/**
330+
* Cleans up the project, if it was only temporary.
331+
*/
283332
private void cleanup() {
284333
if (err != null)
285334
err.close();
@@ -292,6 +341,24 @@ private void cleanup() {
292341
}
293342
}
294343

344+
/**
345+
* Returns a Maven POM associated with a {@code .java} file.
346+
* <p>
347+
* If the file is not part of a valid Maven project, one will be generated.
348+
* </p>
349+
*
350+
* @param env the {@link BuildEnvironment}
351+
* @param file the {@code .java} file
352+
* @param mainClass the name of the class to execute
353+
* @return the Maven POM
354+
* @throws IOException
355+
* @throws ParserConfigurationException
356+
* @throws SAXException
357+
* @throws ScriptException
358+
* @throws TransformerConfigurationException
359+
* @throws TransformerException
360+
* @throws TransformerFactoryConfigurationError
361+
*/
295362
private MavenProject getMavenProject(final BuildEnvironment env,
296363
final File file, final String mainClass) throws IOException,
297364
ParserConfigurationException, SAXException, ScriptException,
@@ -310,6 +377,13 @@ private MavenProject getMavenProject(final BuildEnvironment env,
310377
return writeTemporaryProject(env, new FileReader(file));
311378
}
312379

380+
/**
381+
* Determines the class name of a Java class given its source code.
382+
*
383+
* @param file the source code
384+
* @return the class name including the package
385+
* @throws IOException
386+
*/
313387
private static String getFullClassName(final File file) throws IOException {
314388
String name = file.getName();
315389
if (!name.endsWith(".java")) {
@@ -349,6 +423,19 @@ private static String getFullClassName(final File file) throws IOException {
349423
return packageName + name; // the 'package' statement must be the first in the file
350424
}
351425

426+
/**
427+
* Makes a temporary Maven project for a virtual {@code .java} file.
428+
*
429+
* @param env the {@link BuildEnvironment} to store the generated Maven POM
430+
* @param reader the virtual {@code .java} file
431+
* @return the generated Maven POM
432+
* @throws IOException
433+
* @throws ParserConfigurationException
434+
* @throws SAXException
435+
* @throws TransformerConfigurationException
436+
* @throws TransformerException
437+
* @throws TransformerFactoryConfigurationError
438+
*/
352439
private static MavenProject writeTemporaryProject(final BuildEnvironment env,
353440
final Reader reader) throws IOException, ParserConfigurationException,
354441
SAXException, TransformerConfigurationException, TransformerException,
@@ -382,6 +469,18 @@ private static MavenProject writeTemporaryProject(final BuildEnvironment env,
382469
return fakePOM(env, directory, artifactId, mainClass, true);
383470
}
384471

472+
/**
473+
* Fakes a sensible, valid {@code artifactId}.
474+
* <p>
475+
* Given a name for a project or {@code .java} file, this function generated a
476+
* proper {@code artifactId} for use in faked Maven POMs.
477+
* </p>
478+
*
479+
* @param env the associated {@link BuildEnvironment} (to avoid duplicate
480+
* {@code artifactId}s)
481+
* @param name the project name
482+
* @return the generated {@code artifactId}
483+
*/
385484
private static String fakeArtifactId(final BuildEnvironment env, final String name) {
386485
int dot = name.indexOf('.');
387486
final String prefix = dot < 0 ? name : dot == 0 ? "dependency" : name.substring(0, dot);
@@ -396,6 +495,29 @@ private static String fakeArtifactId(final BuildEnvironment env, final String na
396495
}
397496
}
398497

498+
/**
499+
* Fakes a single Maven POM for a given dependency.
500+
* <p>
501+
* When discovering possible dependencies on the class path, we do not
502+
* necessarily deal with proper Maven-generated artifacts. To be able to use
503+
* them for single {@code .java} "scripts", we simply fake Maven POMs for
504+
* those files.
505+
* </p>
506+
*
507+
* @param env the {@link BuildEnvironment} to house the faked POM
508+
* @param directory the directory associated with the Maven project
509+
* @param artifactId the {@code artifactId} of the dependency
510+
* @param mainClass the main class, if any
511+
* @param writePOM whether to write the Maven POM as {@code pom.xml} into the
512+
* specified directory
513+
* @return the faked POM
514+
* @throws IOException
515+
* @throws ParserConfigurationException
516+
* @throws SAXException
517+
* @throws TransformerConfigurationException
518+
* @throws TransformerException
519+
* @throws TransformerFactoryConfigurationError
520+
*/
399521
private static MavenProject fakePOM(final BuildEnvironment env,
400522
final File directory, final String artifactId, final String mainClass, boolean writePOM)
401523
throws IOException, ParserConfigurationException, SAXException,
@@ -453,13 +575,37 @@ private static MavenProject fakePOM(final BuildEnvironment env,
453575
return env.parse(new ByteArrayInputStream(out.toByteArray()), directory, null, null);
454576
}
455577

578+
/**
579+
* Writes out the specified XML element.
580+
*
581+
* @param document the XML document
582+
* @param parent the parent node
583+
* @param tag the tag to append
584+
* @param content the content of the tag to append
585+
* @return the appended node
586+
*/
456587
private static Element append(final Document document, final Element parent, final String tag, final String content) {
457588
Element child = document.createElement(tag);
458589
if (content != null) child.appendChild(document.createCDATASection(content));
459590
parent.appendChild(child);
460591
return child;
461592
}
462593

594+
/**
595+
* Discovers all current class path elements and offers them as faked Maven
596+
* POMs.
597+
* <p>
598+
* When constructing an in-memory Maven POM for a single {@code .java} file,
599+
* we need to make sure that all class path elements are available to the
600+
* compiler. Since we use MiniMaven to compile everything (in order to be
601+
* consistent, and also to be able to generate Maven projects conveniently, to
602+
* turn hacky projects into proper ones), we need to put all of that into the
603+
* Maven context, i.e. fake Maven POMs for all the dependencies.
604+
* </p>
605+
*
606+
* @param env the {@link BuildEnvironment} in which the faked POMs are stored
607+
* @return the list of dependencies, as {@link Coordinate}s
608+
*/
463609
private static List<Coordinate> getAllDependencies(final BuildEnvironment env) {
464610
final List<Coordinate> result = new ArrayList<Coordinate>();
465611
for (ClassLoader loader = env.getClass().getClassLoader(); loader != null; loader = loader.getParent()) {
@@ -479,13 +625,49 @@ private static List<Coordinate> getAllDependencies(final BuildEnvironment env) {
479625
return result;
480626
}
481627

628+
/**
629+
* Fakes a Maven POM in memory for a specified dependency.
630+
* <p>
631+
* When compiling bare {@code .java} files, we need to fake a full-blown Maven
632+
* project, including full-blown Maven dependencies for all of the files
633+
* present on the current class path.
634+
* </p>
635+
*
636+
* @param env the {@link BuildEnvironment} for storing the faked Maven POM
637+
* @param file the dependency
638+
* @return the {@link Coordinate} specifying the dependency
639+
*/
482640
private static Coordinate fakeDependency(final BuildEnvironment env, final File file) {
483641
final String artifactId = fakeArtifactId(env, file.getName());
484642
Coordinate dependency = new Coordinate(DEFAULT_GROUP_ID, artifactId, "1.0.0");
485643
env.fakePOM(file, dependency);
486644
return dependency;
487645
}
488646

647+
/**
648+
* Figures out the class path given a {@code .jar} file generated by the
649+
* {@code maven-surefire-plugin}.
650+
* <p>
651+
* A little-known feature of JAR files is that their manifest can specify
652+
* additional class path elements in a {@code Class-Path} entry. The
653+
* {@code maven-surefire-plugin} makes extensive use of that: the URLs of the
654+
* of the active {@link URLClassLoader} will consist of only a single
655+
* {@code .jar} file that is empty except for a manifest whose sole purpose is
656+
* to specify the dependencies.
657+
* </p>
658+
* <p>
659+
* This method can be used to discover those additional class path elements.
660+
* </p>
661+
*
662+
* @param file the {@code .jar} file generated by the
663+
* {@code maven-surefire-plugin}
664+
* @param baseURL the {@link URL} of the {@code .jar} file, needed for class
665+
* path elements specified as relative paths
666+
* @param env the {@link BuildEnvironment}, to store the Maven POMs faked for
667+
* the class path elements
668+
* @param result the list of dependencies to which the discovered dependencies
669+
* are added
670+
*/
489671
private static void getSurefireBooterURLs(final File file, final URL baseURL,
490672
final BuildEnvironment env, final List<Coordinate> result)
491673
{

0 commit comments

Comments
 (0)