PageRenderTime 215ms CodeModel.GetById 112ms app.highlight 8ms RepoModel.GetById 92ms app.codeStats 1ms

/src/mpv5/compiler/RuntimeCompiler.java

http://mp-rechnungs-und-kundenverwaltung.googlecode.com/
Java | 165 lines | 69 code | 15 blank | 81 comment | 2 complexity | f62185a2e719573bff404c1f51c9d9db MD5 | raw file
  1/*
  2 *  This file is part of YaBS.
  3 *
  4 *      YaBS is free software: you can redistribute it and/or modify
  5 *      it under the terms of the GNU General Public License as published by
  6 *      the Free Software Foundation, either version 3 of the License, or
  7 *      (at your option) any later version.
  8 *
  9 *      YaBS is distributed in the hope that it will be useful,
 10 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *      GNU General Public License for more details.
 13 *
 14 *      You should have received a copy of the GNU General Public License
 15 *      along with YaBS.  If not, see <http://www.gnu.org/licenses/>.
 16 */
 17package mpv5.compiler;
 18/*
 19 * Original code:
 20 *
 21 * Copyright: (c) 2009 Roedy Green, Canadian Mind Products, http://mindprod.com
 22 *
 23 * Licence: This software may be copied and used freely for any purpose but military.
 24 *          http://mindprod.com/contact/nonmil.html
 25
 26 */
 27import java.io.File;
 28import javax.tools.JavaCompiler;
 29import javax.tools.JavaFileObject;
 30import javax.tools.SimpleJavaFileObject;
 31import javax.tools.ToolProvider;
 32import java.io.IOException;
 33import java.net.URI;
 34import java.net.URISyntaxException;
 35import java.net.URL;
 36import java.net.URLClassLoader;
 37import java.util.Arrays;
 38import mpv5.globals.LocalSettings;
 39import mpv5.logging.Log;
 40
 41/**
 42 * Writes class files on the fly to disk, and makes them available for the JVM.
 43 * <li/>Added caching of class files
 44 */
 45public final class RuntimeCompiler {
 46
 47    /**
 48     * Compile from within this JVM without spawning javac.exe or a separate JVM.
 49     *
 50     * @param source points to source, possibly in RAM.
 51     *
 52     * @return status of the compile, true all went perfectly without error.
 53     * @throws java.io.IOException if trouble writing class files.
 54     */
 55    private static boolean compile(JavaFileObject... source) {
 56        final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
 57
 58        final JavaCompiler.CompilationTask task = compiler.getTask(null /* default System.err */,
 59                null /* standard file manager,
 60                If we wrote our own we could control the location
 61                of the generated  class files. */,
 62                null /* standard DiagnosticListener */,
 63                Arrays.asList(new String[]{"-d", LocalSettings.getProperty(LocalSettings.CACHE_DIR)}),// specify dir for class files
 64                null /* no annotation classes */,
 65                // we must convert JavaFileObject... to Iterable<? extends JavaFileObject>
 66                Arrays.asList(source) /* source code */);
 67        return task.call();
 68    }
 69
 70    /**
 71     * Generate a program on the fly and compile it
 72     *
 73     * @param className The name of the class
 74     * @param classString The string representation of the class
 75     *
 76     * @param packageName
 77     * @param recompile 
 78     * @return
 79     * @throws java.io.IOException         if problems writing class files.
 80     * @throws ClassNotFoundException      if generated class cannot be found.
 81     * @throws IllegalAccessException      if try to instantiate a class we are not permitted to access.
 82     * @throws InstantiationException      if cant instantiate class
 83     * @throws java.net.URISyntaxException if malformed class name.
 84     */
 85    public static Class getClassFor(final String className, final String classString, final String packageName, boolean recompile) throws URISyntaxException,
 86            IOException,
 87            ClassNotFoundException,
 88            IllegalAccessException,
 89            InstantiationException {
 90
 91        //Do dont recompile the same file over and over again
 92        if (recompile || !new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR) + File.separator + packageName.replace(".", File.separator)  + File.separator + className + ".class").exists()) {
 93            final boolean status = compile(new TempResidentJavaFileObject(className, classString));
 94            Log.Debug(RuntimeCompiler.class, "Compiled class: " + className + " Status: " + status + "\n" +classString);
 95        }
 96        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
 97        ClassLoader newCL = new URLClassLoader(new URL[]{new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR) + File.separator).toURI().toURL()}, oldCL);
 98        Class tempFileClass = null;
 99        try {
100            tempFileClass = newCL.loadClass(packageName + "." + className);
101        } catch (ClassNotFoundException classNotFoundException) {
102            Log.Debug(classNotFoundException);
103            throw classNotFoundException;
104        }
105
106        return tempFileClass;
107    }
108    
109     public static Class getClassFor(final String className, final String classString, final String packageName) throws URISyntaxException,
110            IOException,
111            ClassNotFoundException,
112            IllegalAccessException,
113            InstantiationException {
114
115       
116
117        return getClassFor(className, classString, packageName, false);
118    }
119
120    /**
121     * Instantiates a new Object for the given class
122     * @param clazz
123     * @return
124     * @throws InstantiationException
125     * @throws IllegalAccessException
126     */
127    public static Object getObjectFor(Class clazz) throws InstantiationException, IllegalAccessException {
128        return clazz.newInstance();
129    }
130}
131
132/**
133 * Represents the source text of a Java program in a temp dir
134 */
135class TempResidentJavaFileObject extends SimpleJavaFileObject {
136
137    /**
138     * source text of the program to be compiled
139     */
140    private final String programText;
141
142    /**
143     * constructor
144     *
145     * @param className   class name, without package
146     * @param programText text of the program.
147     *
148     * @throws java.net.URISyntaxException if malformed class name.
149     */
150    @SuppressWarnings({"SameParameterValue"})
151    public TempResidentJavaFileObject(String className, String programText) throws URISyntaxException {
152        super(new URI(className + ".java"), Kind.SOURCE);
153        this.programText = programText;
154    }
155
156    /**
157     * Get the text of the java program
158     *
159     * @param ignoreEncodingErrors ignored.
160     */
161    @Override
162    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
163        return programText;
164    }
165}