javaclassgenerator.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 465 行

JAVA
465
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.java.gen;import com.caucho.java.JavaCompiler;import com.caucho.java.JavaWriter;import com.caucho.loader.DynamicClassLoader;import com.caucho.loader.SimpleLoader;import com.caucho.loader.enhancer.EnhancingClassLoader;import com.caucho.server.util.CauchoSystem;import com.caucho.util.CharBuffer;import com.caucho.util.L10N;import com.caucho.vfs.MergePath;import com.caucho.vfs.Path;import com.caucho.vfs.Vfs;import com.caucho.vfs.WriteStream;import java.io.IOException;import java.lang.reflect.Method;import java.lang.reflect.Constructor;import java.util.ArrayList;import java.util.logging.Level;import java.util.logging.Logger;/** * Factory for generating Java classes. */public class JavaClassGenerator {  private static final L10N L = new L10N(JavaClassGenerator.class);  private static final Logger log    = Logger.getLogger(JavaClassGenerator.class.getName());    // Parent class loader  private ClassLoader _parentLoader;  // class loader  private ClassLoader _loader;  private String _encoding;    // The search path  private Path _searchPath;  // The work directory  private Path _workPath;  private ArrayList<String> _pendingFiles = new ArrayList<String>();  private String _initMethod = "_caucho_init";  private String _isModifiedMethod = "_caucho_is_modified";  /**   * Sets the full generated class.   */  public static String cleanClassName(String className)  {    StringBuilder cb = new StringBuilder();        for (int i = 0; i < className.length(); i++) {      char ch = className.charAt(i);      if (ch == '.' || ch == '/')	cb.append('.');      else if (Character.isJavaIdentifierPart(ch))	cb.append(ch);      else	cb.append('_');    }    return cb.toString();  }  /**   * Returns the default merge path   */  public static Path getDefaultSearchPath()  {    MergePath mergePath = new MergePath();        mergePath.addMergePath(Vfs.lookup());    mergePath.addClassPath();    return mergePath;  }    /**   * Sets the search path.   */  public void setSearchPath(Path path)  {    _searchPath = path;  }  /**   * Returns the assigned search path.   */  public Path getSearchPath()  {    return _searchPath;  }    public void setEncoding(String encoding)  {    _encoding = encoding;  }    /**   * Sets the parent class loader.   *   * @param loader parent class loader   */  public void setParentLoader(ClassLoader loader)  {    if (loader instanceof EnhancingClassLoader) {      EnhancingClassLoader enhancingLoader = (EnhancingClassLoader) loader;    }        _parentLoader = loader;  }    /**   * Sets the class loader.   *   * @param loader parent class loader   */  public void setLoader(ClassLoader loader)  {    _loader = loader;  }    /**   * Gets the class loader.   */  public ClassLoader getClassLoader()  {    return _loader;    /*    if (_loader == null) {      _loader = SimpleLoader.create(getParentLoader(),				    getWorkDir());    }        return _loader;    */  }  /**   * Sets the parent class loader.   *   * @return the parent class loader   */  public ClassLoader getParentLoader()  {    if (_parentLoader == null)      _parentLoader = Thread.currentThread().getContextClassLoader();        return _parentLoader;  }  /**   * Sets the parent class loader.   *   * @return the parent class loader   */  public ClassLoader getPreloadLoader()  {    return Thread.currentThread().getContextClassLoader();      /*      if (_preloadLoader instanceof EnhancingClassLoader) {	EnhancingClassLoader enhancingLoader;	enhancingLoader = (EnhancingClassLoader) _preloadLoader;	_preloadLoader = enhancingLoader.getRawLoader();      }      */  }  /**   * Sets the work path for the generated class.   */  public void setWorkDir(Path workPath)  {    _workPath = workPath;  }    /**   * Returns the class dir for the generated class.   */  public Path getWorkDir()  {    if (_workPath == null)      return CauchoSystem.getWorkPath();    else      return _workPath;  }  /**   * Try to preload the class.   *   * @return true if the preloaded class is still valid.   */  public Class preload(String fullClassName)  {    try {      Class cl = loadClass(fullClassName, true);      if (cl != null) {        // force validation of the class        Constructor []ctors = cl.getConstructors();      }      return cl;    } catch (ClassNotFoundException e) {      log.log(Level.FINEST, e.toString(), e);            return null;    } catch (ClassFormatError e) {      log.log(Level.FINEST, e.toString(), e);            return null;    }  }  public Path getClassFilePath(String className)  {    String classPathName = className.replace('.', '/') + ".class";        return getWorkDir().lookup(classPathName);  }  /**   * Call to generate the java source.   */  public void generate(GenClass javaClass)    throws Exception  {    String className = javaClass.getFullClassName();    String javaPathName = className.replace('.', '/') + ".java";    String classPathName = className.replace('.', '/') + ".class";    Path javaPath = getWorkDir().lookup(javaPathName);    Path classPath = getWorkDir().lookup(classPathName);    try {      classPath.remove();    } catch (IOException e) {    }    javaPath.getParent().mkdirs();    WriteStream os = javaPath.openWrite();    try {      if (_encoding != null)	os.setEncoding(_encoding);      else	os.setEncoding("JAVA");            JavaWriter out = new JavaWriter(os);      javaClass.generate(out);    } finally {      os.close();    }    _pendingFiles.add(javaPathName);  }  public void addPendingFile(String javaPath)  {    _pendingFiles.add(javaPath);  }  /**   * Compiles the Java code   */  public Class compile(String fullClassName)    throws Exception  {    compileJava(fullClassName);        return loadClass(fullClassName, false);  }    /**   * Compiles the class.   */  public void compileJava(String fullClassName)    throws IOException, ClassNotFoundException  {    JavaCompiler compiler = JavaCompiler.create(getPreloadLoader());    compiler.setClassLoader(getPreloadLoader());    compiler.setClassDir(getWorkDir());    if (_encoding != null)      compiler.setEncoding(_encoding);    compiler.compile(fullClassName.replace('.', '/') + ".java", null);  }    /**   * Compiles the pending files   */  public void compilePendingJava()    throws IOException, ClassNotFoundException  {    JavaCompiler compiler = JavaCompiler.create(getPreloadLoader());    compiler.setClassLoader(getPreloadLoader());    compiler.setClassDir(getWorkDir());    if (_encoding != null)      compiler.setEncoding(_encoding);    String []files = new String[_pendingFiles.size()];    _pendingFiles.toArray(files);    _pendingFiles.clear();    compiler.compileBatch(files);  }  /**   * Loads the generated class.  If any class dependencies have   * changed, return null.   */  public Class loadClass(String fullClassName)    throws ClassNotFoundException  {    return loadClass(fullClassName, false);  }  /**   * Loads the generated class.  If any class dependencies have   * changed, return null.   */  public Class loadClass(String fullClassName, boolean preload)    throws ClassNotFoundException  {    DynamicClassLoader preloadLoader = null;        try {      ClassLoader loader;      if (preload) {	preloadLoader = SimpleLoader.create(getPreloadLoader(),					    getWorkDir(),					    fullClassName);	// needed for cases like Amber enhancing	preloadLoader.setServletHack(true);	loader = preloadLoader;      }      else {	// XXX: because of automatic instantiation, might cause trouble	loader = getClassLoader();	if (loader == null) {	  loader = SimpleLoader.create(getParentLoader(),				       getWorkDir(),				       fullClassName);	}      }      Class cl = Class.forName(fullClassName, false, loader);      if (cl == null)	return null;            if (! preload)	return cl;      if (isModified(cl))	return null;      if (_loader != null)	loader = _loader;      else {	loader = SimpleLoader.create(getParentLoader(),				     getWorkDir(),				     fullClassName);      }      return Class.forName(fullClassName, false, loader);    } catch (RuntimeException e) {      if (! preload)	throw e;      else	return null;    } catch (Error e) {      if (! preload)	throw e;      else	return null;    } catch (ClassNotFoundException e) {      if (! preload)	throw e;      else	return null;    } finally {      if (preloadLoader != null)	preloadLoader.destroy();    }  }  /**   * Returns true if the class is modified.   */  public boolean isModified(Class cl)  {    Path searchPath = getSearchPath();          if (searchPath == null)      searchPath = getDefaultSearchPath();    Thread thread = Thread.currentThread();    ClassLoader oldLoader = thread.getContextClassLoader();    try {      if (_parentLoader != null)	thread.setContextClassLoader(_parentLoader);	      Method method = cl.getMethod(_initMethod, new Class[] { Path.class });      method.invoke(null, new Object[] { searchPath });      method = cl.getMethod(_isModifiedMethod, new Class[0]);      Boolean value = (Boolean) method.invoke(null, new Object[] {});      return value.booleanValue();    } catch (NoSuchMethodException e) {      return false;    } catch (Throwable e) {      log.warning(e.toString());            return true;    } finally {      thread.setContextClassLoader(oldLoader);    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?