PageRenderTime 8ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/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
Possible License(s): LGPL-3.0, Apache-2.0, GPL-3.0, GPL-2.0, AGPL-3.0, JSON, BSD-3-Clause
  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. */
  17. package 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. import java.io.File;
  27. import javax.tools.JavaCompiler;
  28. import javax.tools.JavaFileObject;
  29. import javax.tools.SimpleJavaFileObject;
  30. import javax.tools.ToolProvider;
  31. import java.io.IOException;
  32. import java.net.URI;
  33. import java.net.URISyntaxException;
  34. import java.net.URL;
  35. import java.net.URLClassLoader;
  36. import java.util.Arrays;
  37. import mpv5.globals.LocalSettings;
  38. import mpv5.logging.Log;
  39. /**
  40. * Writes class files on the fly to disk, and makes them available for the JVM.
  41. * <li/>Added caching of class files
  42. */
  43. public final class RuntimeCompiler {
  44. /**
  45. * Compile from within this JVM without spawning javac.exe or a separate JVM.
  46. *
  47. * @param source points to source, possibly in RAM.
  48. *
  49. * @return status of the compile, true all went perfectly without error.
  50. * @throws java.io.IOException if trouble writing class files.
  51. */
  52. private static boolean compile(JavaFileObject... source) {
  53. final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  54. final JavaCompiler.CompilationTask task = compiler.getTask(null /* default System.err */,
  55. null /* standard file manager,
  56. If we wrote our own we could control the location
  57. of the generated class files. */,
  58. null /* standard DiagnosticListener */,
  59. Arrays.asList(new String[]{"-d", LocalSettings.getProperty(LocalSettings.CACHE_DIR)}),// specify dir for class files
  60. null /* no annotation classes */,
  61. // we must convert JavaFileObject... to Iterable<? extends JavaFileObject>
  62. Arrays.asList(source) /* source code */);
  63. return task.call();
  64. }
  65. /**
  66. * Generate a program on the fly and compile it
  67. *
  68. * @param className The name of the class
  69. * @param classString The string representation of the class
  70. *
  71. * @param packageName
  72. * @param recompile
  73. * @return
  74. * @throws java.io.IOException if problems writing class files.
  75. * @throws ClassNotFoundException if generated class cannot be found.
  76. * @throws IllegalAccessException if try to instantiate a class we are not permitted to access.
  77. * @throws InstantiationException if cant instantiate class
  78. * @throws java.net.URISyntaxException if malformed class name.
  79. */
  80. public static Class getClassFor(final String className, final String classString, final String packageName, boolean recompile) throws URISyntaxException,
  81. IOException,
  82. ClassNotFoundException,
  83. IllegalAccessException,
  84. InstantiationException {
  85. //Do dont recompile the same file over and over again
  86. if (recompile || !new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR) + File.separator + packageName.replace(".", File.separator) + File.separator + className + ".class").exists()) {
  87. final boolean status = compile(new TempResidentJavaFileObject(className, classString));
  88. Log.Debug(RuntimeCompiler.class, "Compiled class: " + className + " Status: " + status + "\n" +classString);
  89. }
  90. ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
  91. ClassLoader newCL = new URLClassLoader(new URL[]{new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR) + File.separator).toURI().toURL()}, oldCL);
  92. Class tempFileClass = null;
  93. try {
  94. tempFileClass = newCL.loadClass(packageName + "." + className);
  95. } catch (ClassNotFoundException classNotFoundException) {
  96. Log.Debug(classNotFoundException);
  97. throw classNotFoundException;
  98. }
  99. return tempFileClass;
  100. }
  101. public static Class getClassFor(final String className, final String classString, final String packageName) throws URISyntaxException,
  102. IOException,
  103. ClassNotFoundException,
  104. IllegalAccessException,
  105. InstantiationException {
  106. return getClassFor(className, classString, packageName, false);
  107. }
  108. /**
  109. * Instantiates a new Object for the given class
  110. * @param clazz
  111. * @return
  112. * @throws InstantiationException
  113. * @throws IllegalAccessException
  114. */
  115. public static Object getObjectFor(Class clazz) throws InstantiationException, IllegalAccessException {
  116. return clazz.newInstance();
  117. }
  118. }
  119. /**
  120. * Represents the source text of a Java program in a temp dir
  121. */
  122. class TempResidentJavaFileObject extends SimpleJavaFileObject {
  123. /**
  124. * source text of the program to be compiled
  125. */
  126. private final String programText;
  127. /**
  128. * constructor
  129. *
  130. * @param className class name, without package
  131. * @param programText text of the program.
  132. *
  133. * @throws java.net.URISyntaxException if malformed class name.
  134. */
  135. @SuppressWarnings({"SameParameterValue"})
  136. public TempResidentJavaFileObject(String className, String programText) throws URISyntaxException {
  137. super(new URI(className + ".java"), Kind.SOURCE);
  138. this.programText = programText;
  139. }
  140. /**
  141. * Get the text of the java program
  142. *
  143. * @param ignoreEncodingErrors ignored.
  144. */
  145. @Override
  146. public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
  147. return programText;
  148. }
  149. }