| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.jexl2; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.lang.reflect.Method; |
| import java.net.URL; |
| import java.net.URLClassLoader; |
| |
| /** |
| * Helper class to test GC / reference interactions. |
| * Dynamically creates a class by compiling generated source Java code and |
| * load it through a dedicated class loader. |
| */ |
| public class ClassCreator { |
| private final JexlEngine jexl; |
| private final File base; |
| private File packageDir = null; |
| private int seed = 0; |
| private String className = null; |
| private String sourceName = null; |
| private ClassLoader loader = null; |
| public static final boolean canRun = comSunToolsJavacMain(); |
| /** |
| * Check if we can invoke Sun's java compiler. |
| * @return true if it is possible, false otherwise |
| */ |
| private static boolean comSunToolsJavacMain() { |
| try { |
| Class<?> javac = ClassCreatorTest.class.getClassLoader().loadClass("com.sun.tools.javac.Main"); |
| return javac != null; |
| } catch (Exception xany) { |
| return false; |
| } |
| } |
| |
| public ClassCreator(JexlEngine theJexl, File theBase) throws Exception { |
| jexl = theJexl; |
| base = theBase; |
| } |
| |
| |
| public void clear() { |
| seed = 0; |
| packageDir = null; |
| className = null; |
| sourceName = null; |
| packageDir = null; |
| loader = null; |
| } |
| |
| public void setSeed(int s) { |
| seed = s; |
| className = "foo" + s; |
| sourceName = className + ".java"; |
| packageDir = new File(base, seed + "/org/apache/commons/jexl2/generated"); |
| packageDir.mkdirs(); |
| loader = null; |
| } |
| |
| public String getClassName() { |
| return "org.apache.commons.jexl2.generated." + className; |
| } |
| |
| public Class<?> getClassInstance() throws Exception { |
| return getClassLoader().loadClass("org.apache.commons.jexl2.generated." + className); |
| } |
| |
| public ClassLoader getClassLoader() throws Exception { |
| if (loader == null) { |
| URL classpath = (new File(base, Integer.toString(seed))).toURI().toURL(); |
| loader = new URLClassLoader(new URL[]{classpath}, null); |
| } |
| return loader; |
| } |
| |
| public Class<?> createClass() throws Exception { |
| // generate, compile & validate |
| generate(); |
| Class<?> clazz = compile(); |
| if (clazz == null) { |
| throw new Exception("failed to compile foo" + seed); |
| } |
| Object v = validate(clazz); |
| if (v instanceof Integer && ((Integer) v).intValue() == seed) { |
| return clazz; |
| } |
| throw new Exception("failed to validate foo" + seed); |
| } |
| |
| void generate() throws Exception { |
| FileWriter aWriter = new FileWriter(new File(packageDir, sourceName), false); |
| aWriter.write("package org.apache.commons.jexl2.generated;"); |
| aWriter.write("public class " + className + "{\n"); |
| aWriter.write("private int value ="); |
| aWriter.write(Integer.toString(seed)); |
| aWriter.write(";\n"); |
| aWriter.write(" public void setValue(int v) {"); |
| aWriter.write(" value = v;"); |
| aWriter.write(" }\n"); |
| aWriter.write(" public int getValue() {"); |
| aWriter.write(" return value;"); |
| aWriter.write(" }\n"); |
| aWriter.write(" }\n"); |
| aWriter.flush(); |
| aWriter.close(); |
| } |
| |
| Class<?> compile() throws Exception { |
| String source = packageDir.getPath() + "/" + sourceName; |
| Class<?> javac = getClassLoader().loadClass("com.sun.tools.javac.Main"); |
| if (javac == null) { |
| return null; |
| } |
| Integer r = (Integer) jexl.invokeMethod(javac, "compile", source); |
| if (r.intValue() >= 0) { |
| return getClassLoader().loadClass("org.apache.commons.jexl2.generated." + className); |
| } |
| return null; |
| } |
| |
| Object validate(Class<?> clazz) throws Exception { |
| Class<?> params[] = {}; |
| Object paramsObj[] = {}; |
| Object iClass = clazz.newInstance(); |
| Method thisMethod = clazz.getDeclaredMethod("getValue", params); |
| return thisMethod.invoke(iClass, paramsObj); |
| } |
| } |