FileDocCategorySizeDatePackage
Jsr199JavaCompiler.javaAPI DocGlassfish v2 API12827Tue May 15 17:49:40 BST 2007org.apache.jasper.compiler

Jsr199JavaCompiler

public class Jsr199JavaCompiler extends Object implements JavaCompiler
Invoke Java Compiler per JSR 199, using in-memory storage for both the input Java source and the generated bytecodes.
author
Kin-man Chung

Fields Summary
private List
cpath
private JspRuntimeContext
rtctxt
private ArrayList
classFiles
private ArrayList
options
private CharArrayWriter
charArrayWriter
private org.apache.jasper.JspCompilationContext
ctxt
private String
javaFileName
private String
javaEncoding
private ErrorDispatcher
errDispatcher
Constructors Summary
Methods Summary
public JavacErrorDetail[]compile(java.lang.String className, Node.Nodes pageNodes)


        final String source = charArrayWriter.toString();

        javax.tools.JavaCompiler javac = ToolProvider.getSystemJavaCompiler();

        DiagnosticCollector<JavaFileObject> diagnostics =
            new DiagnosticCollector<JavaFileObject>();
        StandardJavaFileManager stdFileManager =
                    javac.getStandardFileManager(diagnostics, null, null);

        String name = className.substring(className.lastIndexOf('.")+1);

        JavaFileObject[] sourceFiles = {
            new SimpleJavaFileObject(
                    URI.create("string:///" + name.replace('.",'/") +
                               Kind.SOURCE.extension),
                    Kind.SOURCE) {
                public CharSequence getCharContent(boolean ignore) {
                    return source;
                }
            }
        };

        try {
            stdFileManager.setLocation(StandardLocation.CLASS_PATH, this.cpath);
        } catch (IOException e) {
        }

        JavaFileManager javaFileManager = getJavaFileManager(stdFileManager);
        javax.tools.JavaCompiler.CompilationTask ct =
            javac.getTask(null,
                          javaFileManager,
                          diagnostics,
                          options,
                          null, 
                          Arrays.asList(sourceFiles));

        try {
            javaFileManager.close();
        } catch (IOException ex) {
        }

        if (ct.call()) {
            for (BytecodeFile bytecodeFile: classFiles) {
                rtctxt.setBytecode(bytecodeFile.getClassName(),
                                   bytecodeFile.getBytecode());
            }
            return null;
        }

        // There are compilation errors!
        ArrayList<JavacErrorDetail> problems =
            new ArrayList<JavacErrorDetail>();
        for (Diagnostic dm: diagnostics.getDiagnostics()) {
            problems.add(ErrorDispatcher.createJavacError(
                source,
                pageNodes,
                new StringBuffer(dm.getMessage(null)),
                (int) dm.getLineNumber()));
        }
        return problems.toArray(new JavacErrorDetail[0]);
    
public voiddoJavaFile(boolean keep)


        if (! keep)
            return;

        try {
            Writer writer = new OutputStreamWriter(
                                    new FileOutputStream(javaFileName),
                                    javaEncoding);
            writer.write(charArrayWriter.toString());
            writer.close();
        } catch (UnsupportedEncodingException ex) {
            errDispatcher.jspError("jsp.error.needAlternateJavaEncoding",
                                   javaEncoding);
        } catch (IOException ex) {
            throw new JasperException(ex);
        }

    
public longgetClassLastModified()

        String className = ctxt.getFullClassName();
        return rtctxt.getBytecodeBirthTime(className);
    
private javax.tools.JavaFileManagergetJavaFileManager(javax.tools.JavaFileManager fm)


        return new ForwardingJavaFileManager<JavaFileManager>(fm) {

/*
            @Override
            public FileObject getFileForOutput(Location location,
                                               String packageName,
                                               String relativeName,
                                               FileObject sibling){
                System.out.println(" At getFileForOutput: location = " +
                    location + " pachageName = " + packageName +
                    " relativeName = " + relativeName +
                    " sibling = " + sibling);
                return getOutputFile(relativeName, null);
            }
*/

            @Override
            public JavaFileObject getJavaFileForOutput(Location location,
                                                       String className,
                                                       Kind kind,
                                                       FileObject sibling){
                return getOutputFile(className,
                    URI.create("file:///" + className.replace('.",'/") + kind));
            }

            @Override
            public String inferBinaryName(Location location,
                                          JavaFileObject file) {

                if (file instanceof BytecodeFile) {
                    return ((BytecodeFile)file).getClassName();
                }
                return super.inferBinaryName(location, file);
            }

            @Override
            public Iterable<JavaFileObject> list(Location location,
                                         String packageName,
                                         Set<Kind> kinds,
                                         boolean recurse)
                    throws IOException {

                if (location == StandardLocation.CLASS_PATH &&
                        packageName.startsWith(Constants.JSP_PACKAGE_NAME)) {

		    // TODO: Need to handle the case where some of the classes
                    // are on disk

                    Map<String,ArrayList<Object/*JavaFileObject*/>> packageMap =
                        rtctxt.getPackageMap();
                    ArrayList/*<JavaFileObject>*/ packageFiles
                            = packageMap.get(packageName);
                    if (packageFiles != null) {
                        return packageFiles;
                    }
                }
                Iterable<JavaFileObject> lst =
                    super.list(location, packageName, kinds, recurse);

                return lst;
            }
        };

    
public java.io.WritergetJavaWriter(java.lang.String javaFileName, java.lang.String javaEncoding)

        this.javaFileName = javaFileName;
        this.javaEncoding = javaEncoding;
        this.charArrayWriter = new CharArrayWriter();
        return this.charArrayWriter;
    
private javax.tools.JavaFileObjectgetOutputFile(java.lang.String className, java.net.URI uri)


        BytecodeFile classFile = new BytecodeFile(uri, className);

        // File the class file away, by its package name
        String packageName = className.substring(0, className.lastIndexOf("."));
        Map<String, ArrayList<Object /*JavaFileObject*/>> packageMap =
            rtctxt.getPackageMap();
        ArrayList<Object/*JavaFileObject*/> packageFiles = packageMap.get(packageName);
        if (packageFiles == null) {
            packageFiles = new ArrayList<Object/*JavaFileObject*/>();
            packageMap.put(packageName, packageFiles);
        }
        packageFiles.add(classFile);
        classFiles.add(classFile);
        return classFile;
    
public voidinit(org.apache.jasper.JspCompilationContext ctxt, ErrorDispatcher errDispatcher, boolean suppressLogging)


       
                      
                       
        this.ctxt = ctxt;
        this.errDispatcher = errDispatcher;
        rtctxt = ctxt.getRuntimeContext();
        options.add("-proc:none");  // Disable annotation processing
    
public voidsaveClassFile(java.lang.String className, java.lang.String classFileName)

        for (BytecodeFile bytecodeFile: classFiles) {
            String c = bytecodeFile.getClassName();
            String f = classFileName;
            if (!className.equals(c)) {
                // Compute inner class file name
                f = f.substring(0, f.lastIndexOf(File.separator)+1) +
                    c.substring(c.lastIndexOf('.")+1) + ".class";
            }
            rtctxt.saveBytecode(c, f);
        }
    
public voidsetClassPath(java.util.List path)

        this.cpath = path;
    
public voidsetDebug(boolean debug)

        if (debug) {
            options.add("-g");
        }
    
public voidsetExtdirs(java.lang.String exts)

        options.add("-extdirs");
        options.add(exts);
    
public voidsetSourceVM(java.lang.String sourceVM)

        options.add("-source");
        options.add(sourceVM);
    
public voidsetTargetVM(java.lang.String targetVM)

        options.add("-target");
        options.add(targetVM);