This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.scripting.java-2.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-java.git
commit cfd7362dec59153539584c428eb2d3740fca3a58 Author: Carsten Ziegeler <[email protected]> AuthorDate: Fri Mar 19 08:56:14 2010 +0000 SLING-874 : Use new commons compiler for java servlet scripting git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/scripting/java@925142 13f79535-47bb-0310-9956-ffa450edef68 --- NOTICE | 2 +- pom.xml | 27 +- .../sling/scripting/java/CompilationContext.java | 233 ---------------- .../apache/sling/scripting/java/CompilerError.java | 161 ----------- .../org/apache/sling/scripting/java/Options.java | 139 ---------- .../sling/scripting/java/ServletWrapper.java | 259 ------------------ .../sling/scripting/java/impl/CompilationUnit.java | 180 +++++++++++++ .../sling/scripting/java/impl/CompilerError.java | 100 +++++++ .../sling/scripting/java/impl/CompilerOptions.java | 49 ++++ .../scripting/java/{ => impl}/CompilerUtil.java | 22 +- .../java/{ => impl}/JavaScriptEngineFactory.java | 99 ++++--- .../java/{ => impl}/JavaServletConfig.java | 2 +- .../java/{ => impl}/JavaServletContext.java | 2 +- .../scripting/java/{ => impl}/ServletCache.java | 2 +- .../sling/scripting/java/impl/ServletWrapper.java | 242 +++++++++++++++++ .../scripting/java/{ => impl}/SlingIOProvider.java | 110 +++++--- .../sling/scripting/java/jdt/CompilationUnit.java | 299 --------------------- .../scripting/java/jdt/EclipseJavaCompiler.java | 118 -------- src/main/resources/META-INF/NOTICE | 2 +- .../OSGI-INF/metatype/metatype.properties | 4 - 20 files changed, 714 insertions(+), 1338 deletions(-) diff --git a/NOTICE b/NOTICE index 4b1c970..2cce499 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache Sling Java Scripting Support -Copyright 2008-2009 The Apache Software Foundation +Copyright 2008-2010 The Apache Software Foundation Apache Sling is based on source code originally developed by Day Software (http://www.day.com/). diff --git a/pom.xml b/pom.xml index e8cdc34..db84dac 100644 --- a/pom.xml +++ b/pom.xml @@ -52,21 +52,11 @@ <extensions>true</extensions> <configuration> <instructions> - <Import-Package> - !org.eclipse.*, * - </Import-Package> <Private-Package> - org.apache.sling.scripting.java, - org.apache.sling.scripting.java.jdt, - org.eclipse.jdt.* + org.apache.sling.scripting.java.impl </Private-Package> - <ScriptEngine-Name>${pom.name}</ScriptEngine-Name> <ScriptEngine-Version>${pom.version}</ScriptEngine-Version> - - <Embed-Dependency> - jasper* - </Embed-Dependency> </instructions> </configuration> </plugin> @@ -78,9 +68,9 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <configuration> - <!-- No javadocs --> + <!-- No javadocs --> <excludePackageNames> - org.apache.sling.scripting + org.apache.sling.scripting.java.impl </excludePackageNames> </configuration> </plugin> @@ -92,23 +82,26 @@ <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.api</artifactId> <version>2.0.8</version> + <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.scripting.api</artifactId> <version>2.0.2-incubator</version> + <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.commons.classloader</artifactId> <version>1.0.0</version> + <scope>provided</scope> </dependency> - <!-- We use the same eclipse jdt as the jsp bundle --> <dependency> - <groupId>org.apache.tomcat</groupId> - <artifactId>jasper-jdt</artifactId> - <version>6.0.18</version> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.compiler</artifactId> + <version>1.0.0</version> + <scope>provided</scope> </dependency> <dependency> diff --git a/src/main/java/org/apache/sling/scripting/java/CompilationContext.java b/src/main/java/org/apache/sling/scripting/java/CompilationContext.java deleted file mode 100644 index 6efe3f3..0000000 --- a/src/main/java/org/apache/sling/scripting/java/CompilationContext.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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.sling.scripting.java; - -import java.util.List; - -import javax.servlet.ServletException; - -import org.apache.sling.scripting.java.jdt.EclipseJavaCompiler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - */ -public class CompilationContext { - - private Logger logger = LoggerFactory.getLogger(getClass()); - - /** The name of the generated class. */ - private final String className; - - /** The path to the servlet. */ - private final String sourcePath; - - /** The mapped path. */ - private final String mappedSourcePath; - - /** Compilation options. */ - private final Options options; - - /** The compiler instance. */ - private final EclipseJavaCompiler compiler; - - /** Sling IO Provider. */ - private final SlingIOProvider ioProvider; - - private ServletCache servletCache; - - private volatile long lastModificationTest = 0L; - private int removed = 0; - - private Class<?> servletClass; - - private final ServletWrapper wrapper; - - /** - * A new compilation context. - * @param sourcePath The path to the servlet source. - * @param options The compiler options - * @param provider The Sling IO Provider - * @param servletCache - */ - public CompilationContext(final String sourcePath, - final Options options, - final SlingIOProvider provider, - ServletCache servletCache, - final ServletWrapper wrapper) { - this.sourcePath = sourcePath; - this.mappedSourcePath = CompilerUtil.mapSourcePath(this.sourcePath); - this.className = CompilerUtil.makeClassPath(this.mappedSourcePath); - - this.options = options; - this.ioProvider = provider; - this.compiler = new EclipseJavaCompiler(this); - - this.servletCache = servletCache; - this.wrapper = wrapper; - } - - /** - * Options - */ - public Options getCompilerOptions() { - return options; - } - - /** - * Provider - */ - public SlingIOProvider getIOProvider() { - return this.ioProvider; - } - - /** - * Return the path to the java servlet source file - * @return The source file path. - */ - public String getSourcePath() { - return this.sourcePath; - } - - public String getJavaClassName() { - return this.mappedSourcePath.replace('/', '.'); - } - - /** - * Return the path to the generated class file. - * @return The class file path. - */ - public String getClassFilePath() { - return this.className; - } - - public void incrementRemoved() { - if (removed == 0 && servletCache != null) { - servletCache.removeWrapper(sourcePath); - } - removed++; - } - - public boolean isRemoved() { - if (removed > 1 ) { - return true; - } - return false; - } - - public long getLastModificationTest() { - return this.lastModificationTest; - } - - public void clearLastModificationTest() { - this.lastModificationTest = 0; - } - - /** - * Check if the compiled class file is older than the source file - */ - public boolean isOutDated() { - if ( this.lastModificationTest > 0 ) { - return false; - } - final long sourceLastModified = this.ioProvider.lastModified(getSourcePath()); - - final long targetLastModified = this.ioProvider.lastModified(getCompleteClassPath()); - if (targetLastModified < 0) { - return true; - } - - if (targetLastModified < sourceLastModified) { - if (logger.isDebugEnabled()) { - logger.debug("Compiler: outdated: " + getClassFilePath() + " " - + targetLastModified); - } - return true; - } - - return false; - - } - - private String getCompleteClassPath() { - return options.getDestinationPath() + getClassFilePath() + ".class"; - } - - // ==================== Compile and reload ==================== - - public boolean compile() throws Exception { - if (this.isOutDated()) { - try { - final List<CompilerError> errors = this.compiler.compile(); - if ( errors != null ) { - throw CompilerException.create(errors); - } - this.wrapper.setCompilationException(null); - return true; - } catch (Exception ex) { - // Cache compilation exception - this.wrapper.setCompilationException(ex); - throw ex; - } finally { - this.lastModificationTest = System.currentTimeMillis(); - } - } - this.lastModificationTest = System.currentTimeMillis(); - return false; - } - - /** - * Load the class. - */ - public Class<?> load() - throws ServletException { - final String name = this.getClassFilePath().substring(1).replace('/', '.'); - try { - servletClass = this.options.getClassLoader().loadClass(name); - } catch (ClassNotFoundException cex) { - throw new ServletException("Servlet class not found: " + name, cex); - } catch (Exception ex) { - throw new ServletException("Unable to compile servlet: " + name, ex); - } - removed = 0; - return servletClass; - } - - protected final static class CompilerException extends ServletException { - - public static CompilerException create(List<CompilerError> errors) { - final StringBuilder buffer = new StringBuilder(); - buffer.append("Compilation errors:\n"); - for(final CompilerError e : errors) { - buffer.append(e.getFile()); - buffer.append(", line "); - buffer.append(e.getStartLine()); - buffer.append(", column "); - buffer.append(e.getStartColumn()); - buffer.append(" : " ); - buffer.append(e.getMessage()); - buffer.append("\n"); - } - return new CompilerException(buffer.toString()); - } - - public CompilerException(final String message) { - super(message); - } - } -} diff --git a/src/main/java/org/apache/sling/scripting/java/CompilerError.java b/src/main/java/org/apache/sling/scripting/java/CompilerError.java deleted file mode 100644 index e29f67c..0000000 --- a/src/main/java/org/apache/sling/scripting/java/CompilerError.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.sling.scripting.java; - -/** - * This class encapsulates an error message produced by a programming language - * processor (whether interpreted or compiled) - * @version $Id$ - * @since 2.0 - */ - -public class CompilerError { - /** - * Is this a severe error or a warning? - */ - private boolean error; - /** - * The start line number of the offending program text - */ - private int startline; - /** - * The start column number of the offending program text - */ - private int startcolumn; - /** - * The end line number of the offending program text - */ - private int endline; - /** - * The end column number of the offending program text - */ - private int endcolumn; - /** - * The name of the file containing the offending program text - */ - private String file; - /** - * The actual error text produced by the language processor - */ - private String message; - - /** - * The error message constructor. - * - * @param file The name of the file containing the offending program text - * @param error The actual error text produced by the language processor - * @param startline The start line number of the offending program text - * @param startcolumn The start column number of the offending program text - * @param endline The end line number of the offending program text - * @param endcolumn The end column number of the offending program text - * @param message The actual error text produced by the language processor - */ - public CompilerError( - String file, - boolean error, - int startline, - int startcolumn, - int endline, - int endcolumn, - String message - ) - { - this.file = file; - this.error = error; - this.startline = startline; - this.startcolumn = startcolumn; - this.endline = endline; - this.endcolumn = endcolumn; - this.message = message; - } - - /** - * The error message constructor. - * - * @param message The actual error text produced by the language processor - */ - public CompilerError(String message) { - this.message = message; - } - - /** - * Return the filename associated with this compiler error. - * - * @return The filename associated with this compiler error - */ - public String getFile() { - return file; - } - - /** - * Assert whether this is a severe error or a warning - * - * @return Whether the error is severe - */ - public boolean isError() { - return error; - } - - /** - * Return the starting line number of the program text originating this error - * - * @return The starting line number of the program text originating this error - */ - public int getStartLine() { - return startline; - } - - /** - * Return the starting column number of the program text originating this - * error - * - * @return The starting column number of the program text originating this - * error - */ - public int getStartColumn() { - return startcolumn; - } - - /** - * Return the ending line number of the program text originating this error - * - * @return The ending line number of the program text originating this error - */ - public int getEndLine() { - return endline; - } - - /** - * Return the ending column number of the program text originating this - * error - * - * @return The ending column number of the program text originating this - * error - */ - public int getEndColumn() { - return endcolumn; - } - - /** - * Return the message produced by the language processor - * - * @return The message produced by the language processor - */ - public String getMessage() { - return message; - } -} diff --git a/src/main/java/org/apache/sling/scripting/java/Options.java b/src/main/java/org/apache/sling/scripting/java/Options.java deleted file mode 100644 index 4dea523..0000000 --- a/src/main/java/org/apache/sling/scripting/java/Options.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.sling.scripting.java; - -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.Properties; - -import org.osgi.service.component.ComponentContext; - - -/** - * A class to hold all init parameters specific to the compiler - */ -public class Options { - - private static final String PROPERTY_JAVA_ENCODING = "javaEncoding"; - - private static final String PROPERTY_COMPILER_SOURCE_V_M = "compilerSourceVM"; - - private static final String PROPERTY_COMPILER_TARGET_V_M = "compilerTargetVM"; - - private static final String PROPERTY_CLASSDEBUGINFO = "classdebuginfo"; - - /** Default source and target VM version (value is "1.5"). */ - private static final String DEFAULT_VM_VERSION = "1.5"; - - /** - * Do we want to include debugging information in the class file? - */ - private final boolean classDebugInfo; - - /** - * Compiler target VM. - */ - private final String compilerTargetVM; - - /** - * The compiler source VM. - */ - private final String compilerSourceVM; - - /** - * Java platform encoding to generate the servlet. - */ - private final String javaEncoding; - - /** - * Classloader - */ - private final ClassLoader classLoader; - - /** - * Create an compiler options object using data available from - * the component configuration. - */ - public Options(final ComponentContext componentContext, - final ClassLoader classLoader) { - - this.classLoader = classLoader; - - // generate properties - final Properties properties = new Properties(); - // set default values first - properties.put(PROPERTY_CLASSDEBUGINFO, "true"); - properties.put(PROPERTY_COMPILER_TARGET_V_M, DEFAULT_VM_VERSION); - properties.put(PROPERTY_COMPILER_SOURCE_V_M, DEFAULT_VM_VERSION); - properties.put(PROPERTY_JAVA_ENCODING, "UTF-8"); - - // now check component properties - Dictionary<?, ?> config = componentContext.getProperties(); - Enumeration<?> enumeration = config.keys(); - while (enumeration.hasMoreElements()) { - String key = (String) enumeration.nextElement(); - if (key.startsWith("java.")) { - Object value = config.get(key); - if (value != null) { - properties.put(key.substring("java.".length()), - value.toString()); - } - } - } - - this.classDebugInfo = Boolean.valueOf(properties.get(PROPERTY_CLASSDEBUGINFO).toString()); - this.compilerTargetVM = properties.get(PROPERTY_COMPILER_TARGET_V_M).toString(); - this.compilerSourceVM = properties.get(PROPERTY_COMPILER_SOURCE_V_M).toString(); - this.javaEncoding = properties.get(PROPERTY_JAVA_ENCODING).toString(); - } - - /** - * Return the destination directory. - */ - public String getDestinationPath() { - return ":"; - } - - /** - * Should class files be compiled with debug information? - */ - public boolean getClassDebugInfo() { - return this.classDebugInfo; - } - - public ClassLoader getClassLoader() { - return this.classLoader; - } - - /** - * @see Options#getCompilerTargetVM - */ - public String getCompilerTargetVM() { - return this.compilerTargetVM; - } - - /** - * @see Options#getCompilerSourceVM - */ - public String getCompilerSourceVM() { - return this.compilerSourceVM; - } - - public String getJavaEncoding() { - return this.javaEncoding; - } -} diff --git a/src/main/java/org/apache/sling/scripting/java/ServletWrapper.java b/src/main/java/org/apache/sling/scripting/java/ServletWrapper.java deleted file mode 100644 index a315648..0000000 --- a/src/main/java/org/apache/sling/scripting/java/ServletWrapper.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * 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.sling.scripting.java; - -import java.io.FileNotFoundException; -import java.io.IOException; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.SingleThreadModel; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.sling.api.SlingException; -import org.apache.sling.api.SlingHttpServletRequest; -import org.apache.sling.api.SlingIOException; -import org.apache.sling.api.SlingServletException; -import org.apache.sling.api.scripting.SlingBindings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - - */ - -public class ServletWrapper { - - /** The logger. */ - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private final String servletUri; - - /** The servlet config. */ - private ServletConfig config; - - private Servlet theServlet; - private long available = 0L; - private Exception compileException; - private CompilationContext ctxt; - - /** - * A wrapper for servlets. - */ - public ServletWrapper(final ServletConfig config, - final Options options, - final SlingIOProvider ioProvider, - final String servletPath, - final ServletCache servletCache) { - this.config = config; - this.servletUri = servletPath; - this.ctxt = new CompilationContext(servletUri, options, - ioProvider, servletCache, this); - } - - public CompilationContext getCompilationContext() { - return this.ctxt; - } - - /** - * Get the servlet. - * @throws ServletException - * @throws IOException - * @throws FileNotFoundException - */ - private void getServlet() - throws ServletException { - destroy(); - - Servlet servlet = null; - - try { - final Class<?> servletClass = ctxt.load(); - servlet = (Servlet) servletClass.newInstance(); - } catch (IllegalAccessException e) { - throw new ServletException(e); - } catch (InstantiationException e) { - throw new ServletException(e); - } catch (ServletException se) { - throw se; - } catch (Exception e) { - throw new ServletException(e); - } - - servlet.init(config); - - theServlet = servlet; - } - - /** - * Sets the compilation exception for this ServletWrapper. - * - * @param je The compilation exception - */ - public void setCompilationException(final Exception je) { - this.compileException = je; - } - - /** - * @param bindings - * @throws SlingIOException - * @throws SlingServletException - * @throws IllegalArgumentException if the Jasper Precompile controller - * request parameter has an illegal value. - */ - public void service(SlingBindings bindings) { - final SlingHttpServletRequest request = bindings.getRequest(); - final Object oldValue = request.getAttribute(SlingBindings.class.getName()); - try { - request.setAttribute(SlingBindings.class.getName(), bindings); - service(request, bindings.getResponse()); - } catch (SlingException se) { - // rethrow as is - throw se; - } catch (IOException ioe) { - throw new SlingIOException(ioe); - } catch (ServletException se) { - throw new SlingServletException(se); - } finally { - request.setAttribute(SlingBindings.class.getName(), oldValue); - } - } - - /** - * Call the servlet. - * @param request The current request. - * @param response The current response. - * @throws ServletException - * @throws IOException - * @throws FileNotFoundException - */ - private void service(HttpServletRequest request, - HttpServletResponse response) - throws ServletException, IOException { - try { - - if (ctxt.isRemoved()) { - throw new FileNotFoundException(servletUri); - } - - if ((available > 0L) && (available < Long.MAX_VALUE)) { - if (available > System.currentTimeMillis()) { - response.setDateHeader("Retry-After", available); - response.sendError - (HttpServletResponse.SC_SERVICE_UNAVAILABLE, - "Servlet unavailable."); - logger.error("Java servlet {} is unavailable.", this.servletUri); - return; - } - // Wait period has expired. Reset. - available = 0; - } - - // check for compilation - if (ctxt.getLastModificationTest() == 0 ) { - synchronized (this) { - if (ctxt.getLastModificationTest() == 0 ) { - if ( ctxt.compile() ) { - // (re)load the servlet class - getServlet(); - } - - } else if (compileException != null) { - // Throw cached compilation exception - throw compileException; - } - } - } else if (compileException != null) { - // Throw cached compilation exception - throw compileException; - } - - } catch (FileNotFoundException ex) { - ctxt.incrementRemoved(); - try { - response.sendError(HttpServletResponse.SC_NOT_FOUND, - ex.getMessage()); - logger.error("Java servlet {} not found.", this.servletUri); - } catch (IllegalStateException ise) { - logger.error("Java servlet source not found." + - ex.getMessage(), ex); - } - return; - } catch (SlingException ex) { - throw ex; - } catch (ServletException ex) { - throw ex; - } catch (IOException ex) { - throw ex; - } catch (IllegalStateException ex) { - throw ex; - } catch (Exception ex) { - throw new ServletException(ex); - } - - try { - - // invoke the servlet - if (theServlet instanceof SingleThreadModel) { - // sync on the wrapper so that the freshness - // of the page is determined right before servicing - synchronized (this) { - theServlet.service(request, response); - } - } else { - theServlet.service(request, response); - } - - } catch (UnavailableException ex) { - int unavailableSeconds = ex.getUnavailableSeconds(); - if (unavailableSeconds <= 0) { - unavailableSeconds = 60; // Arbitrary default - } - available = System.currentTimeMillis() + - (unavailableSeconds * 1000L); - response.sendError - (HttpServletResponse.SC_SERVICE_UNAVAILABLE, - ex.getMessage()); - logger.error("Java servlet {} is unavailable.", this.servletUri); - return; - } catch (SlingException ex) { - throw ex; - } catch (ServletException ex) { - throw ex; - } catch (IOException ex) { - throw ex; - } catch (IllegalStateException ex) { - throw ex; - } catch (Exception ex) { - throw new ServletException(ex); - } - } - - /** - * Destroy the servlet. - */ - public void destroy() { - if (theServlet != null) { - theServlet.destroy(); - theServlet = null; - } - } -} diff --git a/src/main/java/org/apache/sling/scripting/java/impl/CompilationUnit.java b/src/main/java/org/apache/sling/scripting/java/impl/CompilationUnit.java new file mode 100644 index 0000000..86660af --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/java/impl/CompilationUnit.java @@ -0,0 +1,180 @@ +/* + * 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.sling.scripting.java.impl; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.sling.commons.compiler.ClassWriter; +import org.apache.sling.commons.compiler.CompileUnit; +import org.apache.sling.commons.compiler.CompilerEnvironment; +import org.apache.sling.commons.compiler.ErrorHandler; + + +public class CompilationUnit + implements CompileUnit, CompilerEnvironment, ErrorHandler, ClassWriter { + + private final SlingIOProvider ioProvider; + private final String className; + private final String sourceFile; + + /** The list of compile errors - this is created lazily. */ + private List<CompilerError> errors; + + public CompilationUnit(String sourceFile, + String className, + SlingIOProvider ioProvider) { + this.className = className; + this.sourceFile = sourceFile; + this.ioProvider = ioProvider; + } + + /** + * @see org.apache.sling.commons.compiler.CompileUnit#getSourceFileName() + */ + public String getSourceFileName() { + return getMainTypeName() + ".java"; + } + + /** + * @see org.apache.sling.commons.compiler.CompileUnit#getSourceFileContents() + */ + public char[] getSourceFileContents() { + char[] result = null; + InputStream fr = null; + try { + fr = ioProvider.getInputStream(this.sourceFile); + final Reader reader = new BufferedReader(new InputStreamReader(fr, ioProvider.getOptions().getJavaEncoding())); + try { + char[] chars = new char[8192]; + StringBuilder buf = new StringBuilder(); + int count; + while ((count = reader.read(chars, 0, chars.length)) > 0) { + buf.append(chars, 0, count); + } + result = new char[buf.length()]; + buf.getChars(0, result.length, result, 0); + } finally { + reader.close(); + } + } catch (IOException e) { + this.onError(e.getMessage(), this.sourceFile, 0, 0); + } + return result; + } + + /** + * @see org.apache.sling.commons.compiler.CompileUnit#getMainTypeName() + */ + public String getMainTypeName() { + int dot = className.lastIndexOf('.'); + if (dot > 0) { + return className.substring(dot + 1); + } + return className; + } + + /** + * @see org.apache.sling.commons.compiler.CompilerEnvironment#isPackage(java.lang.String) + */ + public boolean isPackage(String result) { + if (result.equals(this.className)) { + return false; + } + String resourceName = result.replace('.', '/') + ".class"; + if ( resourceName.startsWith("/") ) { + resourceName = resourceName.substring(1); + } + final InputStream is = this.ioProvider.getClassLoader().getResourceAsStream(resourceName); + if ( is != null ) { + try { + is.close(); + } catch (IOException ignore) {} + } + return is == null; + } + + /** + * @see org.apache.sling.commons.compiler.CompilerEnvironment#findClass(java.lang.String) + */ + public byte[] findClass(String name) throws Exception { + final String resourceName = name.replace('.', '/') + ".class"; + final InputStream is = this.ioProvider.getClassLoader().getResourceAsStream(resourceName); + if (is != null) { + try { + byte[] buf = new byte[8192]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length); + int count; + while ((count = is.read(buf, 0, buf.length)) > 0) { + baos.write(buf, 0, count); + } + baos.flush(); + return baos.toByteArray(); + } finally { + try { + is.close(); + } catch (IOException ignore) {} + } + } + return null; + } + + /** + * @see org.apache.sling.commons.compiler.CompilerEnvironment#cleanup() + */ + public void cleanup() { + // EMPTY + } + + /** + * @see org.apache.sling.commons.compiler.ErrorHandler#onError(java.lang.String, java.lang.String, int, int) + */ + public void onError(String msg, String sourceFile, int line, int position) { + if ( errors == null ) { + errors = new ArrayList<CompilerError>(); + } + errors.add(new CompilerError(sourceFile, line, position, msg)); + } + + /** + * @see org.apache.sling.commons.compiler.ErrorHandler#onWarning(java.lang.String, java.lang.String, int, int) + */ + public void onWarning(String msg, String sourceFile, int line, int position) { + // we ignore warnings + } + + /** + * @see org.apache.sling.commons.compiler.ClassWriter#write(java.lang.String, byte[]) + */ + public void write(String name, byte[] data) throws Exception { + final OutputStream os = this.ioProvider.getOutputStream('/' + name.replace('.', '/') + ".class"); + os.write(data); + os.close(); + } + + /** Return the list of errors. */ + public List<CompilerError> getErrors() throws IOException { + return errors; + } +} diff --git a/src/main/java/org/apache/sling/scripting/java/impl/CompilerError.java b/src/main/java/org/apache/sling/scripting/java/impl/CompilerError.java new file mode 100644 index 0000000..4f7dcb9 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/java/impl/CompilerError.java @@ -0,0 +1,100 @@ +/* + * 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.sling.scripting.java.impl; + +/** + * This class encapsulates an error message produced by a programming language + * processor (whether interpreted or compiled) + */ +public class CompilerError { + + /** + * The start line number of the offending program text + */ + private final int startline; + + /** + * The start column number of the offending program text + */ + private final int startcolumn; + + /** + * The name of the file containing the offending program text + */ + private final String file; + + /** + * The actual error text produced by the language processor + */ + private final String message; + + /** + * The error message constructor. + * + * @param file The name of the file containing the offending program text + * @param startline The start line number of the offending program text + * @param startcolumn The start column number of the offending program text + * @param message The actual error text produced by the language processor + */ + public CompilerError(final String file, + final int startline, + final int startcolumn, + final String message) { + this.file = file; + this.startline = startline; + this.startcolumn = startcolumn; + this.message = message; + } + + /** + * Return the filename associated with this compiler error. + * + * @return The filename associated with this compiler error + */ + public String getFile() { + return file; + } + + /** + * Return the starting line number of the program text originating this error + * + * @return The starting line number of the program text originating this error + */ + public int getStartLine() { + return startline; + } + + /** + * Return the starting column number of the program text originating this + * error + * + * @return The starting column number of the program text originating this + * error + */ + public int getStartColumn() { + return startcolumn; + } + + /** + * Return the message produced by the language processor + * + * @return The message produced by the language processor + */ + public String getMessage() { + return message; + } +} diff --git a/src/main/java/org/apache/sling/scripting/java/impl/CompilerOptions.java b/src/main/java/org/apache/sling/scripting/java/impl/CompilerOptions.java new file mode 100644 index 0000000..18ce68e --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/java/impl/CompilerOptions.java @@ -0,0 +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.sling.scripting.java.impl; + +import java.util.Dictionary; + +import org.apache.sling.commons.compiler.Options; + +public class CompilerOptions extends Options { + + private String encoding; + + /** + * Create an compiler options object using data available from + * the component configuration. + */ + public static CompilerOptions createOptions(final Dictionary<String, Object> props) { + CompilerOptions opts = new CompilerOptions(); + + final Boolean classDebugInfo = (Boolean)props.get(JavaScriptEngineFactory.PROPERTY_CLASSDEBUGINFO); + opts.setGenerateDebugInfo(classDebugInfo != null ? classDebugInfo : true); + + final String sourceVM = (String) props.get(JavaScriptEngineFactory.PROPERTY_COMPILER_SOURCE_V_M); + opts.setSourceVersion(sourceVM != null && sourceVM.length() > 0 ? sourceVM : JavaScriptEngineFactory.DEFAULT_VM_VERSION); + + final String encoding = (String) props.get(JavaScriptEngineFactory.PROPERTY_ENCODING); + opts.encoding = encoding != null && encoding.length() > 0 ? encoding : "UTF-8"; + + return opts; + } + + public String getJavaEncoding() { + return this.encoding; + } +} diff --git a/src/main/java/org/apache/sling/scripting/java/CompilerUtil.java b/src/main/java/org/apache/sling/scripting/java/impl/CompilerUtil.java similarity index 86% rename from src/main/java/org/apache/sling/scripting/java/CompilerUtil.java rename to src/main/java/org/apache/sling/scripting/java/impl/CompilerUtil.java index f7d2805..3dd271f 100644 --- a/src/main/java/org/apache/sling/scripting/java/CompilerUtil.java +++ b/src/main/java/org/apache/sling/scripting/java/impl/CompilerUtil.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.scripting.java; +package org.apache.sling.scripting.java.impl; public class CompilerUtil { @@ -38,27 +38,13 @@ public class CompilerUtil { } /** - * Create the class name from the source name - * @param sourcePath The source path - * @return The corresponding class file path. - */ - public static String makeClassPath(String sourcePath) { - String str = sourcePath; - if (str.endsWith(".java")) { - str = str.substring(0, str.length() - 5); - } - return str; - } - - - /** * Converts the given identifier to a legal Java identifier * * @param identifier Identifier to convert * * @return Legal Java identifier corresponding to the given identifier */ - public static final String makeJavaIdentifier(String identifier) { + private static final String makeJavaIdentifier(String identifier) { StringBuilder modifiedIdentifier = new StringBuilder(identifier.length()); if (!Character.isJavaIdentifierStart(identifier.charAt(0))) { @@ -83,7 +69,7 @@ public class CompilerUtil { /** * Mangle the specified character to create a legal Java class name. */ - public static final String mangleChar(char ch) { + private static final String mangleChar(char ch) { char[] result = new char[5]; result[0] = '_'; result[1] = Character.forDigit((ch >> 12) & 0xf, 16); @@ -108,7 +94,7 @@ public class CompilerUtil { /** * Test whether the argument is a Java keyword */ - public static boolean isJavaKeyword(String key) { + private static boolean isJavaKeyword(String key) { int i = 0; int j = javaKeywords.length; while (i < j) { diff --git a/src/main/java/org/apache/sling/scripting/java/JavaScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java similarity index 77% rename from src/main/java/org/apache/sling/scripting/java/JavaScriptEngineFactory.java rename to src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java index d6f1f1a..81e167f 100644 --- a/src/main/java/org/apache/sling/scripting/java/JavaScriptEngineFactory.java +++ b/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java @@ -14,10 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.scripting.java; +package org.apache.sling.scripting.java.impl; import static org.apache.sling.api.scripting.SlingBindings.SLING; +import java.io.IOException; import java.io.Reader; import java.util.Dictionary; import java.util.Hashtable; @@ -28,9 +29,11 @@ import javax.script.ScriptEngine; import javax.script.ScriptException; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; +import javax.servlet.ServletException; import org.apache.sling.api.SlingConstants; import org.apache.sling.api.SlingException; +import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingIOException; import org.apache.sling.api.SlingServletException; import org.apache.sling.api.resource.ResourceResolver; @@ -40,14 +43,13 @@ import org.apache.sling.api.scripting.SlingScriptConstants; import org.apache.sling.api.scripting.SlingScriptHelper; import org.apache.sling.commons.classloader.ClassLoaderWriter; import org.apache.sling.commons.classloader.DynamicClassLoaderManager; +import org.apache.sling.commons.compiler.JavaCompiler; import org.apache.sling.scripting.api.AbstractScriptEngineFactory; import org.apache.sling.scripting.api.AbstractSlingScriptEngine; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * The Java engine @@ -57,17 +59,22 @@ import org.slf4j.LoggerFactory; * @scr.property name="service.vendor" value="The Apache Software Foundation" * @scr.service interface="javax.script.ScriptEngineFactory" * - * @scr.property name="java.javaEncoding" value="UTF-8" - * @scr.property name="java.compilerSourceVM" value="1.5" - * @scr.property name="java.compilerTargetVM" value="1.5" - * @scr.property name="java.classdebuginfo" value="true" type="Boolean" + * @scr.property nameRef="PROPERTY_COMPILER_SOURCE_V_M" valueRef="DEFAULT_VM_VERSION" + * @scr.property nameRef="PROPERTY_CLASSDEBUGINFO" value="true" type="Boolean" + * @scr.property nameRef="PROPERTY_ENCODING" value="UTF-8" */ public class JavaScriptEngineFactory extends AbstractScriptEngineFactory implements EventHandler { - /** default logger */ - private final Logger logger = LoggerFactory.getLogger(getClass()); + public static final String PROPERTY_COMPILER_SOURCE_V_M = "java.compilerSourceVM"; + + public static final String PROPERTY_CLASSDEBUGINFO = "java.classdebuginfo"; + + public static final String PROPERTY_ENCODING = "java.javaEncoding"; + + /** Default source and target VM version (value is "1.5"). */ + public static final String DEFAULT_VM_VERSION = "1.5"; /** * @scr.reference @@ -75,6 +82,11 @@ public class JavaScriptEngineFactory private DynamicClassLoaderManager dynamicClassLoaderManager; /** + * @scr.reference + */ + private JavaCompiler javaCompiler; + + /** * The class loader */ private ClassLoader javaClassLoader; @@ -91,11 +103,6 @@ public class JavaScriptEngineFactory private ServletConfig servletConfig; - private ServletCache servletCache; - - /** Compiler options. */ - private Options compilerOptions; - private ServiceRegistration eventHandlerRegistration; public static final String SCRIPT_TYPE = "java"; @@ -132,17 +139,19 @@ public class JavaScriptEngineFactory * Activate this engine * @param componentContext */ + @SuppressWarnings("unchecked") protected void activate(final ComponentContext componentContext) { - this.ioProvider = new SlingIOProvider(this.classLoaderWriter); - this.servletCache = new ServletCache(); - + this.ioProvider = new SlingIOProvider(this.classLoaderWriter, + this.javaCompiler, + this.javaClassLoader, + CompilerOptions.createOptions(componentContext.getProperties())); this.javaServletContext = new JavaServletContext(ioProvider, slingServletContext); this.servletConfig = new JavaServletConfig(javaServletContext, componentContext.getProperties()); - this.compilerOptions = new Options(componentContext, - this.javaClassLoader); + + // register event handler final Dictionary<String, String> props = new Hashtable<String, String>(); props.put("event.topics","org/apache/sling/api/resource/*"); props.put("service.description","Java Servlet Script Modification Handler"); @@ -150,9 +159,6 @@ public class JavaScriptEngineFactory this.eventHandlerRegistration = componentContext.getBundleContext() .registerService(EventHandler.class.getName(), this, props); - if (logger.isDebugEnabled()) { - logger.debug("JavaServletScriptEngine.activate()"); - } } /** @@ -160,22 +166,16 @@ public class JavaScriptEngineFactory * @param componentContext */ protected void deactivate(final ComponentContext componentContext) { - if (logger.isDebugEnabled()) { - logger.debug("JavaServletScriptEngine.deactivate()"); - } - if ( this.eventHandlerRegistration != null ) { this.eventHandlerRegistration.unregister(); this.eventHandlerRegistration = null; } - if ( this.servletCache != null ) { - this.servletCache.destroy(); - this.servletCache = null; + if ( this.ioProvider != null ) { + this.ioProvider.destroy(); + this.ioProvider = null; } - ioProvider = null; javaServletContext = null; servletConfig = null; - compilerOptions = null; } /** @@ -189,19 +189,35 @@ public class JavaScriptEngineFactory private void callServlet(final Bindings bindings, final SlingScriptHelper scriptHelper, final ScriptContext context) { + // create a SlingBindings object + final SlingBindings slingBindings = new SlingBindings(); + slingBindings.putAll(bindings); + ResourceResolver resolver = (ResourceResolver) context.getAttribute(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER, SlingScriptConstants.SLING_SCOPE); if ( resolver == null ) { resolver = scriptHelper.getScript().getScriptResource().getResourceResolver(); } ioProvider.setRequestResourceResolver(resolver); + + final SlingHttpServletRequest request = slingBindings.getRequest(); + final Object oldValue = request.getAttribute(SlingBindings.class.getName()); try { final ServletWrapper servlet = getWrapperAdapter(scriptHelper); - // create a SlingBindings object - final SlingBindings slingBindings = new SlingBindings(); - slingBindings.putAll(bindings); - servlet.service(slingBindings); + + request.setAttribute(SlingBindings.class.getName(), bindings); + servlet.service(request, slingBindings.getResponse()); + } catch (SlingException se) { + // rethrow as is + throw se; + } catch (IOException ioe) { + throw new SlingIOException(ioe); + } catch (ServletException se) { + throw new SlingServletException(se); + } catch (Exception ex) { + throw new SlingException(ex) {}; } finally { + request.setAttribute(SlingBindings.class.getName(), oldValue); ioProvider.resetRequestResourceResolver(); } } @@ -211,20 +227,21 @@ public class JavaScriptEngineFactory SlingScript script = scriptHelper.getScript(); final String scriptName = script.getScriptResource().getPath(); - ServletWrapper wrapper = this.servletCache.getWrapper(scriptName); + ServletWrapper wrapper = this.ioProvider.getServletCache().getWrapper(scriptName); if (wrapper != null) { return wrapper; } synchronized (this) { - wrapper = this.servletCache.getWrapper(scriptName); + wrapper = this.ioProvider.getServletCache().getWrapper(scriptName); if (wrapper != null) { return wrapper; } wrapper = new ServletWrapper(servletConfig, - this.compilerOptions, ioProvider, scriptName, this.servletCache); - this.servletCache.addWrapper(scriptName, wrapper); + ioProvider, + scriptName); + this.ioProvider.getServletCache().addWrapper(scriptName, wrapper); return wrapper; } @@ -280,9 +297,9 @@ public class JavaScriptEngineFactory } private void handleModification(final String scriptName) { - final ServletWrapper wrapper = this.servletCache.getWrapper(scriptName); + final ServletWrapper wrapper = this.ioProvider.getServletCache().getWrapper(scriptName); if ( wrapper != null ) { - wrapper.getCompilationContext().clearLastModificationTest(); + wrapper.handleModification(); } } diff --git a/src/main/java/org/apache/sling/scripting/java/JavaServletConfig.java b/src/main/java/org/apache/sling/scripting/java/impl/JavaServletConfig.java similarity index 98% rename from src/main/java/org/apache/sling/scripting/java/JavaServletConfig.java rename to src/main/java/org/apache/sling/scripting/java/impl/JavaServletConfig.java index 48f305e..9949098 100644 --- a/src/main/java/org/apache/sling/scripting/java/JavaServletConfig.java +++ b/src/main/java/org/apache/sling/scripting/java/impl/JavaServletConfig.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.sling.scripting.java; +package org.apache.sling.scripting.java.impl; import java.util.Collections; import java.util.Dictionary; diff --git a/src/main/java/org/apache/sling/scripting/java/JavaServletContext.java b/src/main/java/org/apache/sling/scripting/java/impl/JavaServletContext.java similarity index 99% rename from src/main/java/org/apache/sling/scripting/java/JavaServletContext.java rename to src/main/java/org/apache/sling/scripting/java/impl/JavaServletContext.java index 8b1969a..7f8a02d 100644 --- a/src/main/java/org/apache/sling/scripting/java/JavaServletContext.java +++ b/src/main/java/org/apache/sling/scripting/java/impl/JavaServletContext.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.scripting.java; +package org.apache.sling.scripting.java.impl; import java.io.InputStream; import java.net.MalformedURLException; diff --git a/src/main/java/org/apache/sling/scripting/java/ServletCache.java b/src/main/java/org/apache/sling/scripting/java/impl/ServletCache.java similarity index 97% rename from src/main/java/org/apache/sling/scripting/java/ServletCache.java rename to src/main/java/org/apache/sling/scripting/java/impl/ServletCache.java index 9755621..02e01d5 100644 --- a/src/main/java/org/apache/sling/scripting/java/ServletCache.java +++ b/src/main/java/org/apache/sling/scripting/java/impl/ServletCache.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.sling.scripting.java; +package org.apache.sling.scripting.java.impl; import java.util.Iterator; import java.util.Map; diff --git a/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java b/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java new file mode 100644 index 0000000..536f4c5 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java @@ -0,0 +1,242 @@ +/* + * 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.sling.scripting.java.impl; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.SingleThreadModel; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.sling.commons.compiler.CompileUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class wraps the java servlet and handles its compilation, + * instantiation, invocation und destruction. + */ +public class ServletWrapper { + + /** The logger. */ + private final Logger logger = LoggerFactory.getLogger(getClass()); + + /** The servlet config. */ + private final ServletConfig config; + + /** Sling IO Provider. */ + private final SlingIOProvider ioProvider; + + /** The name of the generated class. */ + private final String className; + + /** The path to the servlet. */ + private final String sourcePath; + + private volatile long lastModificationTest = 0L; + + private volatile Class<?> servletClass; + + private volatile Servlet theServlet; + + private long available = 0L; + + private volatile Exception compileException; + + /** + * A wrapper for servlets. + */ + public ServletWrapper(final ServletConfig config, + final SlingIOProvider ioProvider, + final String servletPath) { + this.config = config; + this.ioProvider = ioProvider; + this.sourcePath = servletPath; + this.className = CompilerUtil.mapSourcePath(this.sourcePath).substring(1).replace('/', '.'); + } + + /** + * Get the servlet. + * @throws ServletException + * @throws IOException + * @throws FileNotFoundException + */ + private void getServlet() + throws IllegalAccessException, InstantiationException, ClassNotFoundException, ServletException { + destroy(); + + this.servletClass = this.ioProvider.getClassLoader().loadClass(this.className); + final Servlet servlet = (Servlet) servletClass.newInstance(); + servlet.init(config); + + theServlet = servlet; + } + + /** + * Call the servlet. + * @param request The current request. + * @param response The current response. + * @throws ServletException + * @throws IOException + */ + public void service(HttpServletRequest request, + HttpServletResponse response) + throws Exception { + try { + if ((available > 0L) && (available < Long.MAX_VALUE)) { + if (available > System.currentTimeMillis()) { + response.setDateHeader("Retry-After", available); + response.sendError + (HttpServletResponse.SC_SERVICE_UNAVAILABLE, + "Servlet unavailable."); + logger.error("Java servlet {} is unavailable.", this.sourcePath); + return; + } + // Wait period has expired. Reset. + available = 0; + } + + // check for compilation + if (this.lastModificationTest == 0 ) { + synchronized (this) { + if (this.lastModificationTest == 0 ) { + try { + if ( this.compile() || this.theServlet == null ) { + // clear exception + this.compileException = null; + // (re)load the servlet class + getServlet(); + } + } catch (Exception ex) { + // store exception for futher access attempts + this.compileException = ex; + throw ex; + } finally { + this.lastModificationTest = System.currentTimeMillis(); + } + } else if (compileException != null) { + // Throw cached compilation exception + throw compileException; + } + } + } else if (compileException != null) { + // Throw cached compilation exception + throw compileException; + } + + // invoke the servlet + if (theServlet instanceof SingleThreadModel) { + // sync on the wrapper so that the freshness + // of the page is determined right before servicing + synchronized (this) { + theServlet.service(request, response); + } + } else { + theServlet.service(request, response); + } + + } catch (UnavailableException ex) { + int unavailableSeconds = ex.getUnavailableSeconds(); + if (unavailableSeconds <= 0) { + unavailableSeconds = 60; // Arbitrary default + } + available = System.currentTimeMillis() + + (unavailableSeconds * 1000L); + response.sendError + (HttpServletResponse.SC_SERVICE_UNAVAILABLE, + ex.getMessage()); + logger.error("Java servlet {} is unavailable.", this.sourcePath); + return; + } + } + + /** + * Destroy the servlet. + */ + public void destroy() { + if (theServlet != null) { + theServlet.destroy(); + theServlet = null; + } + } + + /** Handle the modification. */ + public void handleModification() { + this.lastModificationTest = 0; + } + + /** + * Check if the compiled class file is older than the source file + */ + private boolean isOutDated() { + if ( this.lastModificationTest > 0 ) { + return false; + } + final long sourceLastModified = this.ioProvider.lastModified(this.sourcePath); + + final long targetLastModified = this.ioProvider.lastModified('/' + this.className.replace('.', '/') + ".class"); + if (targetLastModified < 0) { + return true; + } + + return targetLastModified < sourceLastModified; + } + + private boolean compile() throws Exception { + if (this.isOutDated()) { + final CompilationUnit unit = new CompilationUnit(this.sourcePath, className, ioProvider); + this.ioProvider.getCompiler().compile(new CompileUnit[] {unit}, unit, unit, unit, ioProvider.getOptions()); + + final List<CompilerError> errors = unit.getErrors(); + if ( errors != null && errors.size() > 0 ) { + throw CompilerException.create(errors); + } + return true; + } + return false; + } + + protected final static class CompilerException extends ServletException { + + public static CompilerException create(List<CompilerError> errors) { + final StringBuilder buffer = new StringBuilder(); + buffer.append("Compilation errors:\n"); + for(final CompilerError e : errors) { + buffer.append(e.getFile()); + buffer.append(", line "); + buffer.append(e.getStartLine()); + buffer.append(", column "); + buffer.append(e.getStartColumn()); + buffer.append(" : " ); + buffer.append(e.getMessage()); + buffer.append("\n"); + } + return new CompilerException(buffer.toString()); + } + + public CompilerException(final String message) { + super(message); + } + } +} diff --git a/src/main/java/org/apache/sling/scripting/java/SlingIOProvider.java b/src/main/java/org/apache/sling/scripting/java/impl/SlingIOProvider.java similarity index 66% rename from src/main/java/org/apache/sling/scripting/java/SlingIOProvider.java rename to src/main/java/org/apache/sling/scripting/java/impl/SlingIOProvider.java index 4e07e44..836ac2e 100644 --- a/src/main/java/org/apache/sling/scripting/java/SlingIOProvider.java +++ b/src/main/java/org/apache/sling/scripting/java/impl/SlingIOProvider.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.sling.scripting.java; +package org.apache.sling.scripting.java.impl; import java.io.FileNotFoundException; import java.io.IOException; @@ -31,6 +31,7 @@ import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.commons.classloader.ClassLoaderWriter; +import org.apache.sling.commons.compiler.JavaCompiler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,16 +40,43 @@ import org.slf4j.LoggerFactory; */ public class SlingIOProvider { - /** default log */ - private final Logger log = LoggerFactory.getLogger(SlingIOProvider.class); + /** Default logger */ + private final Logger logger = LoggerFactory.getLogger(SlingIOProvider.class); private ThreadLocal<ResourceResolver> requestResourceResolver; private final ClassLoaderWriter classLoaderWriter; - SlingIOProvider(final ClassLoaderWriter classLoaderWriter) { + private final JavaCompiler compiler; + + private final CompilerOptions options; + + /** + * Classloader + */ + private final ClassLoader classLoader; + + /** + * Servlet cache. + */ + private final ServletCache servletCache = new ServletCache(); + + /** + * Constructor. + */ + SlingIOProvider(final ClassLoaderWriter classLoaderWriter, + final JavaCompiler compiler, + final ClassLoader classLoader, + final CompilerOptions options) { this.requestResourceResolver = new ThreadLocal<ResourceResolver>(); this.classLoaderWriter = classLoaderWriter; + this.compiler = compiler; + this.classLoader = classLoader; + this.options = options; + } + + void destroy() { + this.servletCache.destroy(); } void setRequestResourceResolver(ResourceResolver resolver) { @@ -61,6 +89,22 @@ public class SlingIOProvider { // ---------- IOProvider interface ----------------------------------------- + public JavaCompiler getCompiler() { + return this.compiler; + } + + public ClassLoader getClassLoader() { + return this.classLoader; + } + + public CompilerOptions getOptions() { + return this.options; + } + + public ServletCache getServletCache() { + return this.servletCache; + } + /** * Returns an InputStream for the file name which is looked up with the * ResourceProvider and retrieved from the Resource if the StreamProvider @@ -68,11 +112,7 @@ public class SlingIOProvider { */ public InputStream getInputStream(String fileName) throws FileNotFoundException, IOException { - if ( fileName.startsWith(":") ) { - return this.classLoaderWriter.getInputStream(fileName.substring(1)); - } try { - Resource resource = getResourceInternal(fileName); if (resource == null) { throw new FileNotFoundException("Cannot find " + fileName); @@ -98,8 +138,8 @@ public class SlingIOProvider { * returned. */ public long lastModified(String fileName) { - if ( fileName.startsWith(":") ) { - return this.classLoaderWriter.getLastModified(fileName.substring(1)); + if ( fileName.endsWith(".class") ) { + return this.classLoaderWriter.getLastModified(fileName); } try { Resource resource = getResourceInternal(fileName); @@ -110,7 +150,7 @@ public class SlingIOProvider { } } catch (SlingException se) { - log.error("Cannot get last modification time for " + fileName, se); + logger.error("Cannot get last modification time for " + fileName, se); } // fallback to "non-existant" in case of problems @@ -121,36 +161,31 @@ public class SlingIOProvider { * Returns an output stream to write to the repository. */ public OutputStream getOutputStream(String fileName) { - return this.classLoaderWriter.getOutputStream(fileName.substring(1)); + return this.classLoaderWriter.getOutputStream(fileName); } - /* package */URL getURL(String path) throws MalformedURLException { + public URL getURL(String path) throws MalformedURLException { try { - Resource resource = getResourceInternal(path); - return (resource != null) ? resource.adaptTo(URL.class) : null; + final Resource resource = getResourceInternal(path); + return resource != null ? resource.adaptTo(URL.class) : null; } catch (SlingException se) { throw (MalformedURLException) new MalformedURLException( "Cannot get URL for " + path).initCause(se); } } - /* package */Set<String> getResourcePaths(String path) { - Set<String> paths = new HashSet<String>(); - - ResourceResolver resolver = requestResourceResolver.get(); - if (resolver != null) { - try { - Resource resource = resolver.getResource(cleanPath(path)); - if (resource != null) { - Iterator<Resource> entries = resolver.listChildren(resource); - while (entries.hasNext()) { - paths.add(entries.next().getPath()); - } + public Set<String> getResourcePaths(final String path) { + final Set<String> paths = new HashSet<String>(); + try { + final Resource resource = getResourceInternal(path); + if (resource != null) { + final Iterator<Resource> entries = resource.getResourceResolver().listChildren(resource); + while (entries.hasNext()) { + paths.add(entries.next().getPath()); } - } catch (SlingException se) { - log.warn("getResourcePaths: Cannot list children of " + path, - se); } + } catch (SlingException se) { + logger.warn("Unable to get resource at path " + path, se); } return paths.isEmpty() ? null : paths; @@ -159,23 +194,10 @@ public class SlingIOProvider { private Resource getResourceInternal(String path) throws SlingException { ResourceResolver resolver = requestResourceResolver.get(); if (resolver != null) { - return resolver.getResource(cleanPath(path)); + return resolver.getResource(path); } return null; } - // ---------- internal ----------------------------------------------------- - - private String cleanPath(String path) { - // replace backslash by slash - path = path.replace('\\', '/'); - - // cut off trailing slash - while (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - - return path; - } } diff --git a/src/main/java/org/apache/sling/scripting/java/jdt/CompilationUnit.java b/src/main/java/org/apache/sling/scripting/java/jdt/CompilationUnit.java deleted file mode 100644 index cbcae2c..0000000 --- a/src/main/java/org/apache/sling/scripting/java/jdt/CompilationUnit.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * 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.sling.scripting.java.jdt; - -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.util.LinkedList; -import java.util.List; -import java.util.StringTokenizer; - -import org.apache.sling.scripting.java.CompilerError; -import org.apache.sling.scripting.java.Options; -import org.apache.sling.scripting.java.SlingIOProvider; -import org.eclipse.jdt.core.compiler.IProblem; -import org.eclipse.jdt.internal.compiler.ClassFile; -import org.eclipse.jdt.internal.compiler.CompilationResult; -import org.eclipse.jdt.internal.compiler.ICompilerRequestor; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; -import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; -import org.eclipse.jdt.internal.compiler.env.INameEnvironment; -import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; - - -public class CompilationUnit - implements ICompilationUnit, INameEnvironment, ICompilerRequestor { - - private final Options options; - private final SlingIOProvider ioProvider; - private final String className; - private final String sourceFile; - - /** The list of compile errors. */ - private final List<CompilerError> errors = new LinkedList<CompilerError>(); - - public CompilationUnit(String sourceFile, - String className, - Options options, - SlingIOProvider ioProvider) { - this.className = className; - this.sourceFile = sourceFile; - this.ioProvider = ioProvider; - this.options = options; - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName() - */ - public char[] getFileName() { - int slash = sourceFile.lastIndexOf('/'); - if (slash > 0) { - return sourceFile.substring(slash + 1).toCharArray(); - } - return sourceFile.toCharArray(); - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents() - */ - public char[] getContents() { - char[] result = null; - InputStream fr = null; - try { - fr = ioProvider.getInputStream(this.sourceFile); - final Reader reader = new BufferedReader(new InputStreamReader(fr, this.options.getJavaEncoding())); - try { - char[] chars = new char[8192]; - StringBuilder buf = new StringBuilder(); - int count; - while ((count = reader.read(chars, 0, chars.length)) > 0) { - buf.append(chars, 0, count); - } - result = new char[buf.length()]; - buf.getChars(0, result.length, result, 0); - } finally { - reader.close(); - } - } catch (IOException e) { - handleError(-1, -1, e.getMessage()); - } - return result; - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName() - */ - public char[] getMainTypeName() { - int dot = className.lastIndexOf('.'); - if (dot > 0) { - return className.substring(dot + 1).toCharArray(); - } - return className.toCharArray(); - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName() - */ - public char[][] getPackageName() { - StringTokenizer izer = new StringTokenizer(className.replace('/', '.'), "."); - char[][] result = new char[izer.countTokens()-1][]; - for (int i = 0; i < result.length; i++) { - String tok = izer.nextToken(); - result[i] = tok.toCharArray(); - } - return result; - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#findType(char[][]) - */ - public NameEnvironmentAnswer findType(char[][] compoundTypeName) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < compoundTypeName.length; i++) { - if (i > 0) { - result.append("."); - } - result.append(compoundTypeName[i]); - } - return findType(result.toString()); - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#findType(char[], char[][]) - */ - public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < packageName.length; i++) { - if (i > 0) { - result.append("."); - } - result.append(packageName[i]); - } - result.append("."); - result.append(typeName); - return findType(result.toString()); - } - - /** - * @param className - * @return - */ - private NameEnvironmentAnswer findType(String className) { - try { - if (className.equals(this.className)) { - ICompilationUnit compilationUnit = this; - return new NameEnvironmentAnswer(compilationUnit, null); - } - String resourceName = className.replace('.', '/') + ".class"; - InputStream is = options.getClassLoader().getResourceAsStream(resourceName); - if (is != null) { - byte[] classBytes; - byte[] buf = new byte[8192]; - ByteArrayOutputStream baos = - new ByteArrayOutputStream(buf.length); - int count; - while ((count = is.read(buf, 0, buf.length)) > 0) { - baos.write(buf, 0, count); - } - baos.flush(); - classBytes = baos.toByteArray(); - char[] fileName = className.toCharArray(); - ClassFileReader classFileReader = - new ClassFileReader(classBytes, fileName, - true); - return - new NameEnvironmentAnswer(classFileReader, null); - } - } catch (IOException exc) { - handleError(-1, -1, exc.getMessage()); - } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) { - handleError(-1, -1, exc.getMessage()); - } - return null; - } - - private boolean isPackage(String result) { - if (result.equals(this.className)) { - return false; - } - String resourceName = result.replace('.', '/') + ".class"; - if ( resourceName.startsWith("/") ) { - resourceName = resourceName.substring(1); - } - final InputStream is = options.getClassLoader().getResourceAsStream(resourceName); - if ( is != null ) { - try { - is.close(); - } catch (IOException ignore) {} - } - return is == null; - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#isPackage(char[][], char[]) - */ - public boolean isPackage(char[][] parentPackageName, char[] packageName) { - if (Character.isUpperCase(packageName[0])) { - return false; - } - final StringBuilder builder = new StringBuilder(); - if (parentPackageName != null) { - for (int i = 0; i < parentPackageName.length; i++) { - if (i > 0) { - builder.append("."); - } - builder.append(parentPackageName[i]); - } - } - if (!isPackage(builder.toString())) { - return false; - } - builder.append("."); - builder.append(packageName); - - return isPackage(builder.toString()); - } - - /** - * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#cleanup() - */ - public void cleanup() { - // EMPTY - } - - /** - * @see org.eclipse.jdt.internal.compiler.ICompilerRequestor#acceptResult(org.eclipse.jdt.internal.compiler.CompilationResult) - */ - public void acceptResult(CompilationResult result) { - try { - if (result.hasErrors()) { - IProblem[] errors = result.getErrors(); - for (int i = 0; i < errors.length; i++) { - IProblem error = errors[i]; - handleError(error.getSourceLineNumber(), -1, error.getMessage()); - } - } else { - ClassFile[] classFiles = result.getClassFiles(); - for (int i = 0; i < classFiles.length; i++) { - ClassFile classFile = classFiles[i]; - char[][] compoundName = classFile.getCompoundName(); - StringBuilder className = new StringBuilder(); - for (int j = 0; j < compoundName.length; j++) { - if (j > 0) { - className.append("."); - } - className.append(compoundName[j]); - } - byte[] bytes = classFile.getBytes(); - final StringBuilder b = new StringBuilder(this.options.getDestinationPath()); - b.append('/'); - b.append(className.toString().replace('.', '/')); - b.append(".class"); - OutputStream fout = ioProvider.getOutputStream(b.toString()); - BufferedOutputStream bos = new BufferedOutputStream(fout); - bos.write(bytes); - bos.close(); - } - } - } catch (IOException exc) { - handleError(-1, -1, exc.getLocalizedMessage()); - } - } - - private void handleError(int line, int column, Object errorMessage) { - if (column < 0) { - column = 0; - } - errors.add(new CompilerError(this.sourceFile, - true, - line, - column, - line, - column, - errorMessage.toString())); - } - - public List<CompilerError> getErrors() throws IOException { - return errors; - } -} diff --git a/src/main/java/org/apache/sling/scripting/java/jdt/EclipseJavaCompiler.java b/src/main/java/org/apache/sling/scripting/java/jdt/EclipseJavaCompiler.java deleted file mode 100644 index 8ed73af..0000000 --- a/src/main/java/org/apache/sling/scripting/java/jdt/EclipseJavaCompiler.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.sling.scripting.java.jdt; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.apache.sling.scripting.java.CompilationContext; -import org.apache.sling.scripting.java.CompilerError; -import org.apache.sling.scripting.java.Options; -import org.apache.sling.scripting.java.SlingIOProvider; -import org.eclipse.jdt.internal.compiler.Compiler; -import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; -import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; -import org.eclipse.jdt.internal.compiler.IProblemFactory; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; - -/** - * Eclipse Java Compiler - * - * @version $Id$ - */ -public class EclipseJavaCompiler { - - /** The io provider. */ - private final SlingIOProvider ioProvider; - - /** The compiler options. */ - private final Options compilerOptions; - - /** The compilation context. */ - private final CompilationContext context; - - /** - * Construct a new java compiler. - * @param context - */ - public EclipseJavaCompiler(final CompilationContext context) { - this.ioProvider = context.getIOProvider(); - this.compilerOptions = context.getCompilerOptions(); - this.context = context; - } - - private CompilerOptions getCompilerOptions() { - CompilerOptions options = new CompilerOptions(); - final Map<String, String> settings = new HashMap<String, String>(); - settings.put(CompilerOptions.OPTION_LineNumberAttribute, - CompilerOptions.GENERATE); - settings.put(CompilerOptions.OPTION_SourceFileAttribute, - CompilerOptions.GENERATE); - settings.put(CompilerOptions.OPTION_ReportDeprecation, - CompilerOptions.IGNORE); - settings.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE); - settings.put(CompilerOptions.OPTION_Encoding, this.compilerOptions.getJavaEncoding()); - if (this.compilerOptions.getClassDebugInfo()) { - settings.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); - } - if ( this.compilerOptions.getCompilerSourceVM().equals("1.6") ) { - settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); - } else { - settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); - } - if ( this.compilerOptions.getCompilerTargetVM().equals("1.6") ) { - settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); - settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); - } else { - settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); - settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); - } - - options.set(settings); - return options; - } - - /** - * Compile the java class. - * @return null if no error occured, a list of errors otherwise. - * @throws IOException - */ - public List<CompilerError> compile() throws IOException { - final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems(); - final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); - final CompilationUnit unit = new CompilationUnit(this.context.getSourcePath(), - this.context.getJavaClassName(), - this.context.getCompilerOptions(), - this.ioProvider); - - final Compiler compiler = new Compiler(unit, - policy, - getCompilerOptions(), - unit, - problemFactory); - compiler.compile(new CompilationUnit[] {unit}); - if ( unit.getErrors().size() == 0 ) { - return null; - } - return unit.getErrors(); - } - -} diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE index 4b1c970..2cce499 100644 --- a/src/main/resources/META-INF/NOTICE +++ b/src/main/resources/META-INF/NOTICE @@ -1,5 +1,5 @@ Apache Sling Java Scripting Support -Copyright 2008-2009 The Apache Software Foundation +Copyright 2008-2010 The Apache Software Foundation Apache Sling is based on source code originally developed by Day Software (http://www.day.com/). diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties index dad70ff..8b87cf2 100644 --- a/src/main/resources/OSGI-INF/metatype/metatype.properties +++ b/src/main/resources/OSGI-INF/metatype/metatype.properties @@ -37,7 +37,3 @@ java.javaEncoding.description = Encoding to be used to read the source files. \ java.compilerSourceVM.name = Source VM java.compilerSourceVM.description = Java Specification to be used to read \ the source files. - -java.compilerTargetVM.name = Target VM -java.compilerTargetVM.description = Java Specification to be used to generate \ - the compiled output. -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
