@@ -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