001/* 002 * Copyright (C) 2006 Sun Microsystems, Inc. All rights reserved. 003 * Use is subject to license terms. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, are 006 * permitted provided that the following conditions are met: Redistributions of source code 007 * must retain the above copyright notice, this list of conditions and the following disclaimer. 008 * Redistributions in binary form must reproduce the above copyright notice, this list of 009 * conditions and the following disclaimer in the documentation and/or other materials 010 * provided with the distribution. Neither the name of the Sun Microsystems nor the names of 011 * is contributors may be used to endorse or promote products derived from this software 012 * without specific prior written permission. 013 014 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 015 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 016 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 017 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 018 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 019 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 020 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 021 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 022 * POSSIBILITY OF SUCH DAMAGE. 023 */ 024 025/* 026 * JavaCompiler.java 027 * @author A. Sundararajan 028 */ 029 030package org.kepler.scriptengine.java; 031 032import java.io.IOException; 033import java.io.PrintWriter; 034import java.io.Writer; 035import java.util.ArrayList; 036import java.util.List; 037import java.util.Map; 038 039import javax.tools.Diagnostic; 040import javax.tools.DiagnosticCollector; 041import javax.tools.JavaFileObject; 042import javax.tools.StandardJavaFileManager; 043import javax.tools.ToolProvider; 044 045/** 046 * Simple interface to Java compiler using JSR 199 Compiler API. 047 */ 048public class JavaCompiler { 049 private javax.tools.JavaCompiler tool; 050 private StandardJavaFileManager stdManager; 051 052 public JavaCompiler() { 053 tool = ToolProvider.getSystemJavaCompiler(); 054 stdManager = tool.getStandardFileManager(null, null, null); 055 } 056 057 public Map<String, byte[]> compile(String source, String fileName) { 058 PrintWriter err = new PrintWriter(System.err); 059 return compile(source, fileName, err, null, null); 060 } 061 062 public Map<String, byte[]> compile(String fileName, String source, 063 Writer err) { 064 return compile(fileName, source, err, null, null); 065 } 066 067 public Map<String, byte[]> compile(String fileName, String source, 068 Writer err, String sourcePath) { 069 return compile(fileName, source, err, sourcePath, null); 070 } 071 072 /** 073 * compile given String source and return bytecodes as a Map. 074 * 075 * @param fileName source fileName to be used for error messages etc. 076 * @param source Java source as String 077 * @param err error writer where diagnostic messages are written 078 * @param sourcePath location of additional .java source files 079 * @param classPath location of additional .class files 080 */ 081 public Map<String, byte[]> compile(String fileName, String source, 082 Writer err, String sourcePath, String classPath) { 083 // to collect errors, warnings etc. 084 DiagnosticCollector<JavaFileObject> diagnostics = 085 new DiagnosticCollector<JavaFileObject>(); 086 087 // create a new memory JavaFileManager 088 MemoryJavaFileManager manager = new MemoryJavaFileManager(stdManager); 089 090 // prepare the compilation unit 091 List<JavaFileObject> compUnits = new ArrayList<JavaFileObject>(1); 092 compUnits.add(MemoryJavaFileManager.makeStringSource(fileName, source)); 093 094 // javac options 095 List<String> options = new ArrayList<String>(); 096 options.add("-Xlint:all"); 097 options.add("-g:none"); 098 options.add("-deprecation"); 099 if (sourcePath != null) { 100 options.add("-sourcepath"); 101 options.add(sourcePath); 102 } 103 104 if (classPath != null) { 105 options.add("-classpath"); 106 options.add(classPath); 107 } 108 109 //System.out.println("Going to compile: "); 110 //System.out.println(source); 111 112 // create a compilation task 113 javax.tools.JavaCompiler.CompilationTask task = 114 tool.getTask(err, manager, diagnostics, 115 options, null, compUnits); 116 117 if (task.call() == false) { 118 PrintWriter perr = new PrintWriter(err); 119 for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) { 120 perr.println(diagnostic.getMessage(null)); 121 } 122 perr.flush(); 123 return null; 124 } 125 126 Map<String, byte[]> classBytes = manager.getClassBytes(); 127 try { 128 manager.close(); 129 } catch (IOException exp) { 130 } 131 132 return classBytes; 133 } 134}