You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by bh...@apache.org on 2009/12/21 00:01:01 UTC
svn commit: r892677 - in /myfaces/extensions/scripting/trunk/core/core/src:
main/java/org/apache/myfaces/extensions/scripting/compiler/
test/java/org/apache/myfaces/extensions/scripting/compiler/
Author: bhuemer
Date: Sun Dec 20 23:01:01 2009
New Revision: 892677
URL: http://svn.apache.org/viewvc?rev=892677&view=rev
Log:
- Corrected some typos again
- Extended the Groovy compiler
Modified:
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompiler.java
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/JavacCompiler.java
myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/Jsr199Compiler.java
myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompilerTest.java
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompiler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompiler.java?rev=892677&r1=892676&r2=892677&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompiler.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompiler.java Sun Dec 20 23:01:01 2009
@@ -1,19 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.myfaces.extensions.scripting.compiler;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.extensions.scripting.loader.ClassLoaderUtils;
+import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.messages.Message;
+import org.codehaus.groovy.control.messages.SimpleMessage;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
- *
+ * <p>A compiler implementation that can be used to compile Groovy source files.</p>
*
*/
public class GroovyCompiler implements Compiler {
+ /**
+ * The logger instance for this class.
+ */
+ private static final Log logger = LogFactory.getLog(GroovyCompiler.class);
+
// ------------------------------------------ Compiler methods
/**
@@ -21,8 +51,9 @@
*
* @param sourcePath the path to the source directory
* @param targetPath the path to the target directory
- * @param file the relative file name of the class you want to compile
- * @return the compilation result, i.e. as of now only the compiler output
+ * @param file the file of the class you want to compile
+ * @param classLoader the class loader to use to determine the classpath
+ * @return the compilation result
*/
public CompilationResult compile(File sourcePath, File targetPath, String file, ClassLoader classLoader)
throws CompilationException {
@@ -35,7 +66,8 @@
* @param sourcePath the path to the source directory
* @param targetPath the path to the target directory
* @param file the file of the class you want to compile
- * @return the compilation result, i.e. as of now only the compiler output
+ * @param classLoader the class loader to use to determine the classpath
+ * @return the compilation result
*/
public CompilationResult compile(File sourcePath, File targetPath, File file, ClassLoader classLoader)
throws CompilationException {
@@ -45,13 +77,68 @@
buildCompilerConfiguration(sourcePath, targetPath, file, classLoader));
compilationUnit.getConfiguration().setOutput(new PrintWriter(compilerOutput));
compilationUnit.addSource(file);
- compilationUnit.compile();
- return new CompilationResult(compilerOutput.toString());
+ CompilationResult result;
+
+ try {
+ compilationUnit.compile();
+
+ result = new CompilationResult(compilerOutput.toString());
+ } catch (CompilationFailedException ex) {
+ // Register all collected error messages from the Groovy compiler
+ result = new CompilationResult(compilerOutput.toString());
+ ErrorCollector collector = compilationUnit.getErrorCollector();
+ for (int i = 0; i < collector.getErrorCount(); ++i) {
+ result.registerError(convertMessage(collector.getError(i)));
+ }
+ }
+
+ // Register all collected warnings from the Groovy compiler
+ ErrorCollector collector = compilationUnit.getErrorCollector();
+ for (int i = 0; i < collector.getWarningCount(); ++i) {
+ result.registerWarning(convertMessage(collector.getWarning(i)));
+ }
+
+ return result;
}
// ------------------------------------------ Utility methods
+ /**
+ * <p>Converts the given Groovy compiler message into a compilation message that
+ * our compilation API consists of.</p>
+ *
+ * @param message the Groovy compiler message you want to convert
+ *
+ * @return the final converted compilation message
+ */
+ protected CompilationResult.CompilationMessage convertMessage(Message message) {
+ if (message instanceof SimpleMessage) {
+ SimpleMessage simpleMessage = (SimpleMessage) message;
+ return new CompilationResult.CompilationMessage(-1, simpleMessage.getMessage());
+ } else if (message instanceof SyntaxErrorMessage) {
+ SyntaxErrorMessage syntaxErrorMessage = (SyntaxErrorMessage) message;
+ return new CompilationResult.CompilationMessage(
+ syntaxErrorMessage.getCause().getLine(), syntaxErrorMessage.getCause().getMessage());
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "This compiler came across an unknown message kind ['" + message + "']. It will be ignored.");
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * <p>Configures the compiler by building its configuration object.</p>
+ *
+ * @param sourcePath the path to the source directory
+ * @param targetPath the path to the target directory
+ * @param file the file of the class you want to compile
+ * @param classLoader the class loader to use to determine the classpath
+ * @return the compiler configuration
+ */
protected CompilerConfiguration buildCompilerConfiguration(File sourcePath, File targetPath, File file, ClassLoader classLoader) {
CompilerConfiguration configuration = new CompilerConfiguration();
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/JavacCompiler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/JavacCompiler.java?rev=892677&r1=892676&r2=892677&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/JavacCompiler.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/JavacCompiler.java Sun Dec 20 23:01:01 2009
@@ -156,11 +156,11 @@
"compile(String, PrintWriter). Are you sure that you're using a valid Sun JDK?", ex);
}
catch (InvocationTargetException ex) {
- throw new IllegalStateException("An error occured while invoking the compile(String, PrintWriter) method of the " +
+ throw new IllegalStateException("An error occurred while invoking the compile(String, PrintWriter) method of the " +
"Javac compiler class '" + compilerClass + "'. Are you sure that you're using a valid Sun JDK?", ex);
}
catch (IllegalAccessException ex) {
- throw new IllegalStateException("An error occured while invoking the compile(String, PrintWriter) method of the " +
+ throw new IllegalStateException("An error occurred while invoking the compile(String, PrintWriter) method of the " +
"Javac compiler class '" + compilerClass + "'. Are you sure that you're using a valid Sun JDK?", ex);
}
}
@@ -211,7 +211,7 @@
}
/**
- * <p>Returns a possibly newly created classloader that you can use in order to load the
+ * <p>Returns a possibly newly created class loader that you can use in order to load the
* Javac compiler class. Usually the user would have to put the JAR file
* '$JAVA_HOME$/lib/tools.jar' on the classpath but this method recognizes this on its own
* and loads the JAR file if necessary. However, it's not guaranteed that the Javac compiler
@@ -220,7 +220,7 @@
*
* @param toolsJar the location of the JAR file '$JAVA_HOME$/lib/tools.jar' or <code>null</code>
* if you want it to be searched for automatically
- * @return a classloader that you can use in order to load the Javac compiler class
+ * @return a class loader that you can use in order to load the Javac compiler class
* @throws MalformedURLException if an error occurred while constructing the URL
*/
private static ClassLoader createJavacAwareClassLoader(URL toolsJar) throws MalformedURLException {
@@ -230,7 +230,7 @@
if (logger.isDebugEnabled()) {
logger.debug("Seemingly the required JAR file '$JAVA_HOME$/lib/tools.jar' has already been "
+ "put on the classpath as the class '" + JAVAC_MAIN + "' is present. So there's no "
- + "need to create a custom classloader for the Javac compiler.");
+ + "need to create a custom class loader for the Javac compiler.");
}
return ClassLoaderUtils.getDefaultClassLoader();
Modified: myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/Jsr199Compiler.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/Jsr199Compiler.java?rev=892677&r1=892676&r2=892677&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/Jsr199Compiler.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/main/java/org/apache/myfaces/extensions/scripting/compiler/Jsr199Compiler.java Sun Dec 20 23:01:01 2009
@@ -135,7 +135,7 @@
protected List<String> buildCompilerOptions(File sourcePath, File targetPath, ClassLoader classLoader) {
List<String> arguments = new ArrayList<String>();
- // Note that we're knowingly not specifying the sourcepath as the compiler really should compile
+ // Note that we're knowingly not specifying the source path as the compiler really should compile
// only a single file (see 'file'). The dependent classes are available on the classpath anyway.
// Otherwise the compiler would also compile dependent classes, which we want to avoid! This
// would result in different versions of a Class file being in use (the system doesn't know that
@@ -148,7 +148,7 @@
arguments.add("-d");
arguments.add(targetPath.getAbsolutePath());
- // Specify the classpath of the given classloader. This enables the user to write new Java
+ // Specify the classpath of the given class loader. This enables the user to write new Java
// "scripts" that depend on classes that have already been loaded previously. Otherwise he
// wouldn't be able to use for example classes that are available in a library.
arguments.add("-classpath");
Modified: myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompilerTest.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompilerTest.java?rev=892677&r1=892676&r2=892677&view=diff
==============================================================================
--- myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompilerTest.java (original)
+++ myfaces/extensions/scripting/trunk/core/core/src/test/java/org/apache/myfaces/extensions/scripting/compiler/GroovyCompilerTest.java Sun Dec 20 23:01:01 2009
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.myfaces.extensions.scripting.compiler;
import org.apache.myfaces.extensions.scripting.AbstractGeneratorTestCase;
@@ -12,6 +30,11 @@
// ------------------------------------------ Test methods
+ /**
+ * <p>Tests whether it is possible to compile a dynamically generated Groovy source file.</p>
+ *
+ * @throws Exception if an error occurs
+ */
public void testCompileGeneratedFile() throws Exception {
writeFile("/src/main/groovy/org/apache/myfaces/extensions/scripting/HelloWorld.groovy", new String[]{
"package org.apache.myfaces.extensions.scripting; ",
@@ -35,8 +58,78 @@
buildAbsolutePath("/target/test-classes/"), "org/apache/myfaces/extensions/scripting/HelloWorld.class").exists());
}
+ /**
+ * <p>Tests whether compilation fails in case of an invalid Groovy source file.</p>
+ *
+ * @throws Exception if an error occurs
+ */
+ public void testCompileGeneratedFileWithError() throws Exception {
+ writeFile("/src/main/groovy/org/apache/myfaces/extensions/scripting/HelloWorld.groovy", new String[]{
+ "package org.apache.myfaces.extensions.scripting; ",
+ " ",
+ "def class HelloWorld { ",
+ " ",
+ " def static main(String[] args) { ",
+ " System2.out.println(\"Hello World\"); ",
+ " } ",
+ "} "
+ });
+
+ Compiler compiler = new GroovyCompiler();
+ CompilationResult result = compiler.compile(
+ new File(buildAbsolutePath("/src/main/groovy")),
+ new File(buildAbsolutePath("/target/test-classes")),
+ "org/apache/myfaces/extensions/scripting/HelloWorld.groovy", getCurrentClassLoader());
+
+ assertTrue(result.hasErrors());
+ assertFalse(new File(
+ buildAbsolutePath("/target/test-classes/"), "org/apache/myfaces/extensions/scripting/HelloWorld.class").exists());
+ }
+
+ /**
+ * <p>Tests whether it is possible to reference dependencies in the Groovy
+ * source files that have to be resolved using the supplied class loader.</p>
+ *
+ * @throws Exception if an error occurs
+ */
+ public void testCompileFileWithDependencies() throws Exception {
+ writeFile("/src/main/groovy/org/apache/myfaces/extensions/scripting/DummyCompiler.groovy", new String[]{
+ "package org.apache.myfaces.extensions.scripting; ",
+ " ",
+ "import java.io.File; ",
+ "import org.apache.myfaces.extensions.scripting.compiler.Compiler; ",
+ "import org.apache.myfaces.extensions.scripting.compiler.CompilationResult; ",
+ " ",
+ "def class DummyCompiler implements Compiler { ",
+ " ",
+ " def CompilationResult compile(File s, File t, String f, ClassLoader c) { ",
+ " return null; ",
+ " } ",
+ " ",
+ " def CompilationResult compile(File s, File t, File f, ClassLoader c) { ",
+ " return null; ",
+ " } ",
+ "} "
+ });
+
+ Compiler compiler = new GroovyCompiler();
+ CompilationResult result = compiler.compile(
+ new File(buildAbsolutePath("/src/main/groovy")),
+ new File(buildAbsolutePath("/target/test-classes")),
+ "org/apache/myfaces/extensions/scripting/DummyCompiler.groovy", getCurrentClassLoader());
+
+ assertFalse(result.hasErrors());
+ assertTrue(new File(
+ buildAbsolutePath("/target/test-classes/"), "org/apache/myfaces/extensions/scripting/DummyCompiler.class").exists());
+ }
+
// ------------------------------------------ Utility methods
+ /**
+ * <p>Returns the class loader that has loaded this class.</p>
+ *
+ * @return the class loader that has loaded this class
+ */
protected ClassLoader getCurrentClassLoader() {
return getClass().getClassLoader();
}