Author: cziegeler
Date: Fri Mar 19 16:14:09 2010
New Revision: 925301

URL: http://svn.apache.org/viewvc?rev=925301&view=rev
Log:
SLING-1452 : Use new commons compiler

Modified:
    sling/trunk/contrib/jcr/compiler/NOTICE
    sling/trunk/contrib/jcr/compiler/pom.xml
    
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/JcrJavaCompiler.java
    
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/FileClassWriter.java
    
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrClassWriter.java
    
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrJavaCompilerImpl.java
    sling/trunk/contrib/jcr/compiler/src/main/resources/META-INF/NOTICE

Modified: sling/trunk/contrib/jcr/compiler/NOTICE
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/NOTICE?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- sling/trunk/contrib/jcr/compiler/NOTICE (original)
+++ sling/trunk/contrib/jcr/compiler/NOTICE Fri Mar 19 16:14:09 2010
@@ -1,5 +1,5 @@
 Apache Sling Java Compiler
-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/).

Modified: sling/trunk/contrib/jcr/compiler/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/pom.xml?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- sling/trunk/contrib/jcr/compiler/pom.xml (original)
+++ sling/trunk/contrib/jcr/compiler/pom.xml Fri Mar 19 16:14:09 2010
@@ -57,7 +57,7 @@
                 <configuration>
                     <instructions>
                         <Export-Package>
-                            org.apache.sling.jcr.compiler;version=1.0.0
+                            org.apache.sling.jcr.compiler;version=2.0.0
                         </Export-Package>
                         <Private-Package>
                             org.apache.sling.jcr.compiler.impl
@@ -72,13 +72,13 @@
            <dependency>
              <groupId>org.apache.sling</groupId>
              <artifactId>org.apache.sling.commons.compiler</artifactId>
-             <version>1.0.0</version>
+             <version>1.0.1-SNAPSHOT</version>
              <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.sling</groupId>
                <artifactId>org.apache.sling.commons.classloader</artifactId>
-               <version>1.0.0</version>
+               <version>1.1.0</version>
           <scope>provided</scope>
            </dependency>
         <dependency>
@@ -102,12 +102,10 @@
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
-            <scope>test</scope>
         </dependency>
     </dependencies>
 </project>

Modified: 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/JcrJavaCompiler.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/JcrJavaCompiler.java?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/JcrJavaCompiler.java
 (original)
+++ 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/JcrJavaCompiler.java
 Fri Mar 19 16:14:09 2010
@@ -17,6 +17,7 @@
 package org.apache.sling.jcr.compiler;
 
 import org.apache.sling.commons.compiler.ErrorHandler;
+import org.apache.sling.commons.compiler.Options;
 
 /**
  * The <code>JcrJavaCompiler</code> compiles Java source code stored in the
@@ -24,11 +25,15 @@ import org.apache.sling.commons.compiler
  */
 public interface JcrJavaCompiler {
 
-    boolean compile(String[] srcFiles, String outputDir, ErrorHandler 
errorHandler,
-                    boolean generateDebug, String javaVersion) throws 
Exception;
-
-    boolean compile(String[] srcFiles, String outputDir,
-                           ErrorHandler errorHandler, boolean generateDebug,
-                           String javaVersion, ClassLoader 
complementaryClassLoader)
-            throws Exception;
+    /**
+     * @param srcFiles
+     * @param outputDir - optional
+     * @param errorHandler
+     * @param options - optional
+     * @since 2.0
+     */
+    boolean compile(String[] srcFiles,
+                    String   outputDir,
+                    ErrorHandler errorHandler,
+                    Options options);
 }

Modified: 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/FileClassWriter.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/FileClassWriter.java?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/FileClassWriter.java
 (original)
+++ 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/FileClassWriter.java
 Fri Mar 19 16:14:09 2010
@@ -19,47 +19,69 @@ package org.apache.sling.jcr.compiler.im
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
-import org.apache.sling.commons.compiler.ClassWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class FileClassWriter implements ClassWriter {
-    
-    /** Logger instance */
-    private static final Logger log = 
LoggerFactory.getLogger(FileClassWriter.class);
+import org.apache.sling.commons.classloader.ClassLoaderWriter;
+
+class FileClassWriter implements ClassLoaderWriter {
+
+    private final File outputDir;
 
-    private File outputDir;
-    
     FileClassWriter(File outputDir) {
         this.outputDir = outputDir;
     }
 
-    /* (non-Javadoc)
-     * @see 
org.apache.sling.commons.compiler.ClassWriter#write(java.lang.String, byte[])
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#getOutputStream(java.lang.String)
      */
-    public void write(String className, byte[] data) throws Exception {
-        File classFile = new File(outputDir, className.replace('.', '/') + 
".class");
+    public OutputStream getOutputStream(final String path) {
+        final String fileName;
+        if ( path.startsWith("/") ) {
+            fileName = path.substring(1);
+        } else {
+            fileName = path;
+        }
+        File classFile = new File(outputDir, fileName.replace('/', 
File.separatorChar));
         if (!classFile.getParentFile().exists()) {
             classFile.getParentFile().mkdirs();
         }
-        FileOutputStream out = new FileOutputStream(classFile);
-        boolean succeeded = false;
         try {
-            out.write(data);
-            succeeded = true;
-        } catch (IOException e) {
-            log.error("Failed to persist " + className + " at path " + 
classFile.getPath(), e);
-            // re-throw
-            throw e;
-        } finally {
-            try {
-                out.close();
-            } catch (IOException ignore) {
-            }
-            if (!succeeded) {
-                classFile.delete();
-            }
+            return new FileOutputStream(classFile);
+        } catch (IOException ioe) {
+            return null;
         }
     }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#delete(java.lang.String)
+     */
+    public boolean delete(String path) {
+        // we don't need to implement this one
+        return false;
+    }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#getInputStream(java.lang.String)
+     */
+    public InputStream getInputStream(String path) throws IOException {
+        // we don't need to implement this one
+        return null;
+    }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#getLastModified(java.lang.String)
+     */
+    public long getLastModified(String path) {
+        // we don't need to implement this one
+        return 0;
+    }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#rename(java.lang.String, 
java.lang.String)
+     */
+    public boolean rename(String oldPath, String newPath) {
+        // we don't need to implement this one
+        return false;
+    }
 }

Modified: 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrClassWriter.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrClassWriter.java?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrClassWriter.java
 (original)
+++ 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrClassWriter.java
 Fri Mar 19 16:14:09 2010
@@ -17,65 +17,219 @@
 package org.apache.sling.jcr.compiler.impl;
 
 import java.io.ByteArrayInputStream;
-import java.util.Calendar;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
+import javax.jcr.Item;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 
-import org.apache.sling.commons.compiler.ClassWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class JcrClassWriter implements ClassWriter {
-    
-    /** Logger instance */
-    private static final Logger log = 
LoggerFactory.getLogger(JcrClassWriter.class);
+import org.apache.sling.commons.classloader.ClassLoaderWriter;
+
+class JcrClassWriter implements ClassLoaderWriter {
+
+    private final Node outputFolder;
+
+    private static final String NT_FOLDER = "nt:folder";
 
-    private Node outputFolder;
-    
     JcrClassWriter(Node outputFolder) {
         this.outputFolder = outputFolder;
     }
 
-    /* (non-Javadoc)
-     * @see 
org.apache.sling.commons.compiler.ClassWriter#write(java.lang.String, byte[])
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#getOutputStream(java.lang.String)
      */
-    public void write(String className, byte[] data) throws Exception {
-        synchronized (outputFolder.getSession()) {
-            boolean succeeded = false;
-            try {
-                Node folder = outputFolder;
-                String[] names = className.split("\\.");
-                for (int i = 0; i < names.length - 1; i++) {
-                    if (folder.hasNode(names[i])) {
-                        folder = folder.getNode(names[i]);
-                    } else {
-                        folder = folder.addNode(names[i], "nt:folder");
+    public OutputStream getOutputStream(String path) {
+        return new RepositoryOutputStream(this.outputFolder, path);
+    }
+
+    /**
+     * Creates a folder hierarchy in the repository.
+     * We synchronize this method to reduce potential conflics.
+     * Although each write uses its own session it might occur
+     * that more than one session tries to create the same path
+     * (or parent path) at the same time. By synchronizing this
+     * we avoid this situation - however this method is written
+     * in a failsafe manner anyway.
+     */
+    private static boolean mkdirs(final Session session, String path) {
+        try {
+            // quick test
+            if (session.itemExists(path) && session.getItem(path).isNode()) {
+                return true;
+            }
+
+            // check path walking it down
+            Node current = session.getRootNode();
+            String[] names = path.split("/");
+            for (int i = 0; i < names.length; i++) {
+                if (names[i] == null || names[i].length() == 0) {
+                    continue;
+                } else if (current.hasNode(names[i])) {
+                    current = current.getNode(names[i]);
+                } else {
+                    final Node parentNode = current;
+                    try {
+                        // adding the node could cause an exception
+                        // for example if another thread tries to
+                        // create the node "at the same time"
+                        current = parentNode.addNode(names[i], NT_FOLDER);
+                        session.save();
+                    } catch (RepositoryException re) {
+                        // let's first refresh the session
+                        // we don't catch an exception here, because if
+                        // session refresh fails, we might have a serious 
problem!
+                        session.refresh(false);
+                        // let's check if the node is available now
+                        if ( parentNode.hasNode(names[i]) ) {
+                            current = parentNode.getNode(names[i]);
+                        } else {
+                            // we try it one more time to create the node - 
and fail otherwise
+                            current = parentNode.addNode(names[i], NT_FOLDER);
+                            session.save();
+                        }
                     }
                 }
-                String classFileName = names[names.length - 1] + ".class";
-                if (folder.hasNode(classFileName)) {
-                    folder.getNode(classFileName).remove();
-                }
-                Node file = folder.addNode(classFileName, "nt:file");
-                Node content = file.addNode("jcr:content", "nt:resource");
+            }
 
-                content.setProperty("jcr:mimeType", 
"application/octet-stream");
-                content.setProperty("jcr:data", new 
ByteArrayInputStream(data));
-                content.setProperty("jcr:lastModified", 
Calendar.getInstance());
-                succeeded = true;
+            return true;
+
+        } catch (RepositoryException re) {
+            // discard changes
+            try {
+                session.refresh(false);
             } catch (RepositoryException e) {
-                String p = outputFolder.getPath() + "/" + 
className.replace('.', '/') + ".class";
-                log.error("Failed to persist " + className + " at path " + p, 
e);
-                // re-throw
-                throw e;
-            } finally {
-                if (succeeded) {
-                    outputFolder.save();
+                // we simply ignore this
+            }
+        }
+
+        // false in case of error or no need to create
+        return false;
+    }
+
+    private static final class RepositoryOutputStream extends 
ByteArrayOutputStream {
+
+        private final String fileName;
+
+        private final Node outputFolder;
+
+        RepositoryOutputStream(final Node outputFolder,
+                               final String fileName) {
+            this.outputFolder = outputFolder;
+            this.fileName = fileName;
+        }
+
+        /**
+         * @see java.io.ByteArrayOutputStream#close()
+         */
+        public void close() throws IOException {
+            super.close();
+
+            try {
+                String fullPath = this.outputFolder.getPath();
+                if ( !fileName.startsWith("/") ) {
+                    fullPath = fullPath + '/';
+                }
+                fullPath = fullPath + fileName;
+
+                final int lastPos = fullPath.lastIndexOf('/');
+                final String path = (lastPos == -1 ? null : 
fullPath.substring(0, lastPos));
+                final String name = (lastPos == -1 ? fullPath : 
fullPath.substring(lastPos + 1));
+                if ( lastPos != -1 ) {
+                    if ( !JcrClassWriter.mkdirs(outputFolder.getSession(), 
path) ) {
+                        throw new IOException("Unable to create path for " + 
path);
+                    }
+                }
+                Node fileNode = null;
+                Node contentNode = null;
+                Node parentNode = null;
+                if (outputFolder.getSession().itemExists(fullPath)) {
+                    final Item item = 
outputFolder.getSession().getItem(fullPath);
+                    if (item.isNode()) {
+                        final Node node = item.isNode() ? (Node) item : 
item.getParent();
+                        if ("jcr:content".equals(node.getName())) {
+                            // replace the content properties of the 
jcr:content
+                            // node
+                            parentNode = node;
+                            contentNode = node;
+                        } else if (node.isNodeType("nt:file")) {
+                            // try to set the content properties of jcr:content
+                            // node
+                            parentNode = node;
+                            contentNode = node.getNode("jcr:content");
+                        } else { // fileName is a node
+                            // try to set the content properties of the node
+                            parentNode = node;
+                            contentNode = node;
+                        }
+                    } else {
+                        // replace property with an nt:file node (if possible)
+                        parentNode = item.getParent();
+                        item.remove();
+                        outputFolder.getSession().save();
+                        fileNode = parentNode.addNode(name, "nt:file");
+                    }
                 } else {
-                    outputFolder.refresh(false);
+                    if (lastPos <= 0) {
+                        parentNode = outputFolder.getSession().getRootNode();
+                    } else {
+                        Item parent = outputFolder.getSession().getItem(path);
+                        if (!parent.isNode()) {
+                            throw new IOException("Parent at " + path + " is 
not a node.");
+                        }
+                        parentNode = (Node) parent;
+                    }
+                    fileNode = parentNode.addNode(name, "nt:file");
                 }
+
+                // if we have a file node, create the contentNode
+                if (fileNode != null) {
+                    contentNode = fileNode.addNode("jcr:content", 
"nt:resource");
+                }
+
+                contentNode.setProperty("jcr:lastModified", 
System.currentTimeMillis());
+                contentNode.setProperty("jcr:data", new 
ByteArrayInputStream(buf, 0, size()));
+                contentNode.setProperty("jcr:mimeType", 
"application/octet-stream");
+
+                outputFolder.getSession().save();
+            } catch (RepositoryException re) {
+                throw (IOException)new IOException("Cannot write file " + 
fileName + ", reason: " + re.toString()).initCause(re);
             }
         }
     }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#delete(java.lang.String)
+     */
+    public boolean delete(String path) {
+        // we don't need to implement this one
+        return false;
+    }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#getInputStream(java.lang.String)
+     */
+    public InputStream getInputStream(String path) throws IOException {
+        // we don't need to implement this one
+        return null;
+    }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#getLastModified(java.lang.String)
+     */
+    public long getLastModified(String path) {
+        // we don't need to implement this one
+        return 0;
+    }
+
+    /**
+     * @see 
org.apache.sling.commons.classloader.ClassLoaderWriter#rename(java.lang.String, 
java.lang.String)
+     */
+    public boolean rename(String oldPath, String newPath) {
+        // we don't need to implement this one
+        return false;
+    }
 }

Modified: 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrJavaCompilerImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrJavaCompilerImpl.java?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrJavaCompilerImpl.java
 (original)
+++ 
sling/trunk/contrib/jcr/compiler/src/main/java/org/apache/sling/jcr/compiler/impl/JcrJavaCompilerImpl.java
 Fri Mar 19 16:14:09 2010
@@ -16,252 +16,146 @@
  */
 package org.apache.sling.jcr.compiler.impl;
 
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayWriter;
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
-import java.net.URL;
+import java.io.StringReader;
+import java.io.StringWriter;
 
 import javax.jcr.Item;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
-import org.apache.sling.commons.compiler.ClassWriter;
-import org.apache.sling.commons.compiler.CompileUnit;
-import org.apache.sling.commons.compiler.CompilerEnvironment;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.commons.classloader.ClassLoaderWriter;
+import org.apache.sling.commons.compiler.CompilationUnit;
 import org.apache.sling.commons.compiler.ErrorHandler;
 import org.apache.sling.commons.compiler.JavaCompiler;
 import org.apache.sling.commons.compiler.Options;
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.jcr.compiler.JcrJavaCompiler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * <code>JcrJavaCompilerImpl</code> ...
  *
- * @scr.component metatype="no"
- * @scr.service interface="org.apache.sling.jcr.compiler.JcrJavaCompiler"
  */
+...@component
+...@service(value=JcrJavaCompiler.class)
 public class JcrJavaCompilerImpl implements JcrJavaCompiler {
 
-    /** Logger instance */
-    private final Logger log = 
LoggerFactory.getLogger(JcrJavaCompilerImpl.class);
-
-    /** @scr.reference */
+    @Reference
     protected JavaCompiler compiler;
 
-    /** @scr.reference */
-    protected DynamicClassLoaderManager dynamicClassLoaderManager;
-
-    /** The class loader used to compile the classes. */
-    protected ClassLoader javaClassLoader;
-
-    /** @scr.reference */
+    @Reference
     protected SlingRepository repository;
 
-    /** The session. */
-    private Session session;
-
-    //------------------------------------------------------< JcrJavaCompiler >
-
-    /* (non-Javadoc)
-     * @see 
org.apache.sling.jcr.compiler.JcrJavaCompiler#compile(java.lang.String[], 
java.lang.String, org.apache.sling.commons.compiler.ErrorHandler, boolean, 
java.lang.String)
+    /**
+     * @see 
org.apache.sling.jcr.compiler.JcrJavaCompiler#compile(java.lang.String[], 
java.lang.String, org.apache.sling.commons.compiler.ErrorHandler, 
org.apache.sling.commons.compiler.Options)
      */
-    public boolean compile(String[] srcFiles, String outputDir,
-            ErrorHandler errorHandler, boolean generateDebug, String 
javaVersion)
-            throws Exception {
-        return compile(srcFiles, outputDir, errorHandler, generateDebug, 
javaVersion, null);
-    }
-
+    public boolean compile(final String[] srcFiles,
+                           final String outputDir,
+                           final ErrorHandler errorHandler,
+                           final Options compilerOptions) {
+        // make sure we have options
+        final Options options = (compilerOptions == null ? new Options() : new 
Options(compilerOptions));
+        // open session
+        Session session = null;
+        try {
+            session = this.repository.loginAdministrative(null);
 
-    /* (non-Javadoc)
-     * @see 
org.apache.sling.jcr.compiler.JcrJavaCompiler#compile(java.lang.String[], 
java.lang.String, org.apache.sling.commons.compiler.ErrorHandler, boolean, 
java.lang.String, java.lang.ClassLoader complementaryClassLoader)
-     */
-    public boolean compile(String[] srcFiles, String outputDir,
-            ErrorHandler errorHandler, boolean generateDebug,
-            String javaVersion, final ClassLoader complementaryClassLoader)
-            throws Exception {
-
-        final ClassLoader currentClassLoader = javaClassLoader;
-        final CompilerEnvironment compilerEnvironment;
-        if (complementaryClassLoader == null) {
-            compilerEnvironment = new 
JcrCompilerEnvironment(currentClassLoader);
-        } else {
-            ClassLoader loader = new ClassLoader(currentClassLoader) {
-                protected Class<?> findClass(String name)
-                        throws ClassNotFoundException {
-                    return complementaryClassLoader.loadClass(name);
+            // create class loader write if output dir is specified
+            ClassLoaderWriter classWriter;
+            if ( outputDir == null ) {
+                classWriter = null;
+            } else if (outputDir.startsWith("file://")) {
+                // write class files to local file system;
+                // only subdirectories of the system temp dir
+                // will be accepted
+                File tempDir = new File(System.getProperty("java.io.tmpdir"));
+                File outDir = new 
File(outputDir.substring("file://".length()));
+                if (!outDir.isAbsolute()) {
+                    outDir = new File(tempDir, 
outputDir.substring("file://".length()));
                 }
-
-                protected URL findResource(String name) {
-                    return complementaryClassLoader.getResource(name);
+                if 
(!outDir.getCanonicalPath().startsWith(tempDir.getCanonicalPath())) {
+                    throw new IOException("illegal outputDir (not a temp dir): 
" + outputDir);
+                }
+                outDir.mkdir();
+                classWriter = new FileClassWriter(outDir);
+            } else {
+                // write class files to the repository  (default)
+                if (!session.itemExists(outputDir)) {
+                    throw new IOException("outputDir does not exist: " + 
outputDir);
                 }
-            };
-            compilerEnvironment = new JcrCompilerEnvironment(loader);
-        }
-
-        return compileInternal(srcFiles, outputDir, compilerEnvironment,
-            errorHandler, generateDebug, javaVersion);
-    }
-
-    public boolean compileInternal(String[] srcFiles,
-            String outputDir, CompilerEnvironment compilerEnvironment,
-            ErrorHandler errorHandler, boolean generateDebug, String 
javaVersion)
-            throws Exception {
-
-        if (javaVersion == null) {
-            javaVersion = System.getProperty("java.specification.version");
-        }
-
-        if (outputDir == null) {
-            throw new Exception("outputDir can not be null");
-        }
-
-        ErrorHandlerWrapper handler = new ErrorHandlerWrapper(errorHandler);
-
-        ClassWriter classWriter;
-        if (outputDir.startsWith("file://")) {
-            // write class files to local file system;
-            // only subdirectories of the system temp dir
-            // will be accepted
-            File tempDir = new File(System.getProperty("java.io.tmpdir"));
-            File outDir = new File(outputDir.substring("file://".length()));
-            if (!outDir.isAbsolute()) {
-                outDir = new File(tempDir, 
outputDir.substring("file://".length()));
-            }
-            if 
(!outDir.getCanonicalPath().startsWith(tempDir.getCanonicalPath())) {
-                throw new Exception("illegal outputDir (not a temp dir): " + 
outputDir);
-            }
-            outDir.mkdir();
-            classWriter = new FileClassWriter(outDir);
-        } else {
-            // write class files to the repository  (default)
-            if (!session.itemExists(outputDir)) {
-                throw new Exception("outputDir does not exist: " + outputDir);
-            }
 
-            Item item = session.getItem(outputDir);
-            if (item.isNode()) {
-                Node folder = (Node) item;
-                if (!folder.isNodeType("nt:folder")) {
-                    throw new Exception("outputDir must be a node of type 
nt:folder");
+                Item item = session.getItem(outputDir);
+                if (item.isNode()) {
+                    Node folder = (Node) item;
+                    if (!folder.isNodeType("nt:folder")) {
+                        throw new IOException("outputDir must be a node of 
type nt:folder");
+                    }
+                    classWriter = new JcrClassWriter(folder);
+                } else {
+                    throw new IOException("outputDir must be a node of type 
nt:folder");
                 }
-                classWriter = new JcrClassWriter(folder);
-            } else {
-                throw new Exception("outputDir must be a node of type 
nt:folder");
             }
-        }
-
-        CompileUnit[] units = new CompileUnit[srcFiles.length];
-        for (int i = 0; i < units.length; i++) {
-            units[i] = createCompileUnit(srcFiles[i]);
-        }
-
-        compiler.compile(units, compilerEnvironment, classWriter, handler,
-                new Options(javaVersion, generateDebug));
-
-        return handler.getNumErrors() == 0;
-    }
-
-    //--------------------------------------------------< CompilerEnvironment >
 
-    private static class JcrCompilerEnvironment implements CompilerEnvironment 
{
-
-        private final ClassLoader classLoader;
-
-        JcrCompilerEnvironment(final ClassLoader classLoader) {
-            this.classLoader = classLoader;
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see
-         * org.apache.sling.commons.compiler.CompilerEnvironment#findClass(java
-         * .lang.String)
-         */
-        public byte[] findClass(String className) throws Exception {
-            InputStream in = 
this.classLoader.getResourceAsStream(className.replace(
-                '.', '/')
-                + ".class");
-            if (in == null) {
-                return null;
+            // create compilation units
+            CompilationUnit[] units = new CompilationUnit[srcFiles.length];
+            for (int i = 0; i < units.length; i++) {
+                units[i] = createCompileUnit(srcFiles[i], session);
             }
-            ByteArrayOutputStream out = new ByteArrayOutputStream(0x7fff);
 
-            try {
-                byte[] buffer = new byte[0x1000];
-                int read = 0;
-                while ((read = in.read(buffer)) > 0) {
-                    out.write(buffer, 0, read);
-                }
-            } finally {
-                // out.close();
-                in.close();
+            if ( classWriter != null ) {
+                options.put(Options.KEY_CLASS_LOADER_WRITER, classWriter);
             }
 
-            return out.toByteArray();
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see
-         * org.apache.sling.commons.compiler.CompilerEnvironment#isPackage(java
-         * .lang.String)
-         */
-        public boolean isPackage(String packageName) {
-            InputStream in = 
this.classLoader.getResourceAsStream(packageName.replace(
-                '.', '/')
-                + ".class");
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException ignore) {
-                }
-                return false;
-            }
-            // FIXME need a better way to determine whether a name resolves
-            // to a package
-            int pos = packageName.lastIndexOf('.');
-            if (pos != -1) {
-                if (Character.isUpperCase(packageName.substring(pos + 
1).charAt(
-                    0))) {
-                    return false;
-                }
+            // and compile
+            return compiler.compile(units, errorHandler, options);
+        } catch (final IOException ioe) {
+            errorHandler.onError("Error while accessing repository: " + 
ioe.getMessage(),
+                    srcFiles[0], 0, 0);
+            return false;
+        } catch (final RepositoryException re) {
+            errorHandler.onError("Error while accessing repository: " + 
re.getMessage(),
+                    srcFiles[0], 0, 0);
+            return false;
+        } finally {
+            if ( session != null ) {
+                session.logout();
             }
-            return true;
         }
-
-        /*
-         * (non-Javadoc)
-         * @see org.apache.sling.commons.compiler.CompilerEnvironment#cleanup()
-         */
-        public void cleanup() {
-        }
-
     }
 
     //--------------------------------------------------------< misc. helpers >
 
-    private CompileUnit createCompileUnit(final String sourceFile) throws 
Exception {
-        final char[] chars = readTextResource(sourceFile);
+    private CompilationUnit createCompileUnit(final String sourceFile, final 
Session session)
+    throws RepositoryException, IOException {
+        final String source = readTextResource(sourceFile, session);
+        final String packageName = extractPackageName(source);
 
-        return new CompileUnit() {
+        return new CompilationUnit() {
 
-            public String getSourceFileName() {
-                return sourceFile;
+            /**
+             * @see 
org.apache.sling.commons.compiler.CompilationUnit#getMainClassName()
+             */
+            public String getMainClassName() {
+                return packageName + '.' + this.getMainTypeName();
             }
 
-            public char[] getSourceFileContents() {
-                return chars;
+            /**
+             * @see 
org.apache.sling.commons.compiler.CompilationUnit#getSource()
+             */
+            public Reader getSource() throws IOException {
+                return new StringReader(source);
             }
 
-            public String getMainTypeName() {
+            private String getMainTypeName() {
                 String className;
                 int pos = sourceFile.lastIndexOf(".java");
                 if (pos != -1) {
@@ -275,118 +169,42 @@ public class JcrJavaCompilerImpl impleme
         };
     }
 
-    private char[] readTextResource(String resourcePath)
-            throws RepositoryException, IOException {
-        String relPropPath = resourcePath.substring(1)
-                + "/jcr:content/jcr:data";
-        InputStream in = 
session.getRootNode().getProperty(relPropPath).getStream();
-        Reader reader = new InputStreamReader(in);
-        CharArrayWriter writer = new CharArrayWriter(0x7fff);
+    private String extractPackageName(final String contents) {
+        BufferedReader reader = new BufferedReader(new StringReader(contents));
         try {
-            char[] buffer = new char[0x1000];
-            int read = 0;
-            while ((read = reader.read(buffer)) > 0) {
-                writer.write(buffer, 0, read);
+            String line;
+            while ((line = reader.readLine()) != null) {
+                line = line.trim();
+                if (line.startsWith("package")) {
+                    line = line.substring("package".length());
+                    line = line.substring(0, line.lastIndexOf(';'));
+                    return line.trim();
+                }
             }
-            return writer.toCharArray();
-        } finally {
-            //writer.close();
-            reader.close();
-        }
-    }
-
-    //--------------------------------------------------------< inner classes >
-
-    class ErrorHandlerWrapper implements ErrorHandler {
-
-        ErrorHandler handler;
-        int errors;
-        int warnings;
-
-        ErrorHandlerWrapper(ErrorHandler handler) {
-            this.handler = handler;
-            errors = 0;
-            warnings = 0;
-        }
-
-        int getNumErrors() {
-            return errors;
-        }
-
-        int getNumWarnings() {
-            return warnings;
-        }
-
-        public void onError(String msg, String sourceFile, int line, int 
position) {
-            log.debug("Error in " + sourceFile + ", line " + line + ", pos. " 
+ position + ": " + msg);
-            errors++;
-            handler.onError(msg, sourceFile, line, position);
-        }
-
-        public void onWarning(String msg, String sourceFile, int line, int 
position) {
-            log.debug("Warning in " + sourceFile + ", line " + line + ", pos. 
" + position + ": " + msg);
-            warnings++;
-            handler.onWarning(msg, sourceFile, line, position);
-        }
-    }
-
-    /**
-     * Bind the class load provider.
-     * @param rclp the new provider
-     */
-    protected void bindDynamicClassLoaderManager(DynamicClassLoaderManager 
rclp) {
-        if ( this.javaClassLoader != null ) {
-            this.ungetClassLoader();
-        }
-        this.getClassLoader(rclp);
-    }
-
-    /**
-     * Unbind the class loader provider.
-     * @param rclp the old provider
-     */
-    protected void unbindDynamicClassLoaderManager(DynamicClassLoaderManager 
rclp) {
-        if ( this.dynamicClassLoaderManager == rclp ) {
-            this.ungetClassLoader();
+        } catch (IOException e) {
+            // should never get here...
         }
-    }
 
-    /**
-     * Get the class loader
-     */
-    private void getClassLoader(DynamicClassLoaderManager rclp) {
-        this.dynamicClassLoaderManager = rclp;
-        this.javaClassLoader = rclp.getDynamicClassLoader();
+        // no package declaration found
+        return "";
     }
 
-    /**
-     * Unget the class loader
-     */
-    private void ungetClassLoader() {
-        this.dynamicClassLoaderManager = null;
-        this.javaClassLoader = null;
-    }
-
-    protected void bindRepository(final SlingRepository repo) {
-        if ( this.session != null ) {
-            this.session.logout();
-            this.session = null;
-        }
+    private String readTextResource(final String resourcePath, final Session 
session)
+    throws RepositoryException, IOException {
+        final String relPropPath = resourcePath.substring(1) + 
"/jcr:content/jcr:data";
+        final InputStream in = 
session.getRootNode().getProperty(relPropPath).getStream();
+        final Reader reader = new InputStreamReader(in, "UTF-8");
+        final StringWriter writer = new StringWriter();
         try {
-            this.session = repo.loginAdministrative(null);
-        } catch (RepositoryException re) {
-            log.error("Unable to open admin session.", re);
-        }
-        this.repository = repo;
-    }
-
-    protected void unbindRepository(final SlingRepository repo) {
-        if ( this.repository == repo ) {
-            if ( this.session != null ) {
-                this.session.logout();
-                this.session = null;
+            final char[] buffer = new char[2048];
+            int read = 0;
+            while ((read = reader.read(buffer)) > 0) {
+                writer.write(buffer, 0, read);
             }
-            this.repository = null;
+            writer.close();
+            return writer.toString();
+        } finally {
+            try { reader.close(); } catch (IOException ignore) {}
         }
     }
 }

Modified: sling/trunk/contrib/jcr/compiler/src/main/resources/META-INF/NOTICE
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/jcr/compiler/src/main/resources/META-INF/NOTICE?rev=925301&r1=925300&r2=925301&view=diff
==============================================================================
--- sling/trunk/contrib/jcr/compiler/src/main/resources/META-INF/NOTICE 
(original)
+++ sling/trunk/contrib/jcr/compiler/src/main/resources/META-INF/NOTICE Fri Mar 
19 16:14:09 2010
@@ -1,5 +1,5 @@
 Apache Sling Java Compiler
-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/).


Reply via email to