amberenhancer.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 743 行 · 第 1/2 页

JAVA
743
字号
    throws Exception  {    String className = type.getBeanClass().getName();    if (! isModified(className))      return;        JavaClassGenerator javaGen = new JavaClassGenerator();    javaGen.setWorkDir(getWorkDir());    String extClassName = type.getBeanClass().getName() + "__ResinExt";    type.setInstanceClassName(extClassName);    type.setEnhanced(true);    _pendingClassNames.add(type.getInstanceClassName());    generateJava(javaGen, type);  }  /**   * Generates the type.   */  public void generateJava(JavaClassGenerator javaGen,                           AbstractEnhancedType type)    throws Exception  {    if (type.isGenerated())      return;    type.setGenerated(true);    _prepare.renameClass(type.getBeanClass().getName(),                         type.getBeanClass().getName());    GenClass javaClass = new GenClass(type.getInstanceClassName());    javaClass.setSuperClassName(type.getBeanClass().getName());    javaClass.addImport("java.util.logging.*");    javaClass.addImport("com.caucho.amber.manager.*");    javaClass.addImport("com.caucho.amber.entity.*");    javaClass.addImport("com.caucho.amber.type.*");    ClassComponent componentGenerator      = type.getComponentGenerator();    if (componentGenerator instanceof AmberMappedComponent) {      AmberMappedComponent entityGenerator	= (AmberMappedComponent) componentGenerator;            // type is EntityType or MappedSuperclassType      javaClass.addInterfaceName(type.getComponentInterfaceName());      type.setEnhanced(true);      entityGenerator.setRelatedType((EntityType) type);      entityGenerator.setBaseClassName(type.getBeanClass().getName());      //String extClassName = gen.getBaseClassName() + "__ResinExt";      // type.setInstanceClassName(extClassName);      entityGenerator.setExtClassName(type.getInstanceClassName());      javaClass.addComponent(componentGenerator);    }    else if (type instanceof ListenerType) {      javaClass.addInterfaceName("com.caucho.amber.entity.Listener");      type.setEnhanced(true);      ListenerComponent listener = new ListenerComponent();      listener.setListenerType((ListenerType) type);      listener.setBaseClassName(type.getBeanClass().getName());      listener.setExtClassName(type.getInstanceClassName());      javaClass.addComponent(listener);    }    else if (componentGenerator instanceof EmbeddableComponent) {      EmbeddableComponent embeddable	= (EmbeddableComponent) componentGenerator;            javaClass.addInterfaceName("com.caucho.amber.entity.Embeddable");      type.setEnhanced(true);      embeddable.setEmbeddableType((EmbeddableType) type);      embeddable.setBaseClassName(type.getBeanClass().getName());      embeddable.setExtClassName(type.getInstanceClassName());      javaClass.addComponent(embeddable);    }    javaGen.generate(javaClass);    // _pendingClassNames.add(extClassName);  }  private boolean isModified(String className)  {    Thread thread = Thread.currentThread();    ClassLoader oldLoader = thread.getContextClassLoader();        try {      ClassLoader loader = _amberContainer.getParentClassLoader();      ClassLoader tempLoader	= ((DynamicClassLoader) loader).getNewTempClassLoader();      DynamicClassLoader workLoader	= SimpleLoader.create(tempLoader, getPostWorkDir());      workLoader.setServletHack(true);	      Class cl = Class.forName(className.replace('/', '.'),			       false,			       workLoader);      thread.setContextClassLoader(tempLoader);	        Method init = cl.getMethod("_caucho_init", new Class[] { Path.class });      Method modified = cl.getMethod("_caucho_is_modified", new Class[0]);      init.invoke(null, Vfs.lookup());      return (Boolean) modified.invoke(null);    } catch (Exception e) {      log.log(Level.FINEST, e.toString(), e);    } catch (Throwable e) {      log.log(Level.FINER, e.toString(), e);    } finally {      thread.setContextClassLoader(oldLoader);    }    return true;  }  /**   * Compiles the pending classes.   */  public void compile()    throws Exception  {    if (_pendingClassNames.size() == 0)      return;    ArrayList<String> classNames = new ArrayList<String>(_pendingClassNames);    _pendingClassNames.clear();    String []javaFiles = new String[classNames.size()];    for (int i = 0; i < classNames.size(); i++) {      String className = classNames.get(i);      String javaName = className.replace('.', '/') + ".java";      javaFiles[i] = javaName;    }    EntityGenerator gen = new EntityGenerator();    gen.setSearchPath(_configDirectory);    // XXX:    // gen.setClassDir(getPath());    JavaCompiler compiler = gen.getCompiler();    compiler.setClassDir(getWorkDir());    compiler.compileBatch(javaFiles);    for (int i = 0; i < classNames.size(); i++) {      String extClassName = classNames.get(i);      int tail = extClassName.length() - "__ResinExt".length();      String baseClassName = extClassName.substring(0, tail);      // fixup(baseClassName, extClassName);    }  }  /**   * Enhances the class.   */  public void postEnhance(JavaClass baseClass)    throws Exception  {    String className = baseClass.getThisClass();    ArrayList<FieldMap> fieldMaps = new ArrayList<FieldMap>();    Class thisClass = _amberContainer.loadTempClass(className.replace('/', '.'));    if (thisClass == null)      return;    // Cache entity JClass for next fixup.    Class entityClass = thisClass;    // Field-based fixup.    do {      BeanType type;      type = _amberContainer.getEntity(thisClass.getName());      if (type == null)        type = _amberContainer.getMappedSuperclass(thisClass.getName());      if (type == null)        type = _amberContainer.getEmbeddable(thisClass.getName());      if (type == null || ! type.isFieldAccess())        continue;            if (type instanceof EmbeddableType)	continue;      if (type instanceof EntityType) {        EntityType entityType = (EntityType) type;	/*        for (AmberField field : entityType.getId().getKeys()) {          fieldMaps.add(new FieldMap(baseClass, field.getName()));        }	*/      }      for (AmberField field : type.getFields()) {        fieldMaps.add(new FieldMap(baseClass, field.getName()));      }    } while ((thisClass = thisClass.getSuperclass()) != null);    if (fieldMaps.size() > 0) {      FieldFixupAnalyzer analyzer = new FieldFixupAnalyzer(fieldMaps);      for (JavaMethod javaMethod : baseClass.getMethodList()) {	if (javaMethod.getName().startsWith("__caucho_get_"))	  continue;	else if (javaMethod.getName().startsWith("__caucho_set_"))	  continue;	else if (javaMethod.getName().startsWith("__caucho_super_"))	  continue;	        CodeVisitor visitor = new CodeVisitor(baseClass, javaMethod.getCode());        visitor.analyze(analyzer, true);      }    }  }  /**   * Parses the configuration file.   */  public void configure(AbstractEnhancedType type)    throws ConfigException, IOException  {  }  static class FieldMap {    private int _fieldRef = -1;    private int _getterRef;    private int _setterRef;    FieldMap(com.caucho.bytecode.JavaClass baseClass,             String fieldName)    {      ConstantPool pool = baseClass.getConstantPool();      FieldRefConstant fieldRef = pool.getFieldRef(fieldName);      if (fieldRef == null)        return;      _fieldRef = fieldRef.getIndex();      MethodRefConstant methodRef;      String getterName = "__caucho_get_" + fieldName;      methodRef = pool.addMethodRef(baseClass.getThisClass(),                                    getterName,                                    "()" + fieldRef.getType());      _getterRef = methodRef.getIndex();      String setterName = "__caucho_set_" + fieldName;      methodRef = pool.addMethodRef(baseClass.getThisClass(),                                    setterName,                                    "(" + fieldRef.getType() + ")V");      _setterRef = methodRef.getIndex();    }    int getFieldRef()    {      return _fieldRef;    }    int getGetterRef()    {      return _getterRef;    }    int getSetterRef()    {      return _setterRef;    }  }  static class FieldFixupAnalyzer extends Analyzer {    private ArrayList<FieldMap> _fieldMap;    FieldFixupAnalyzer(ArrayList<FieldMap> fieldMap)    {      _fieldMap = fieldMap;    }    int getGetter(int fieldRef)    {      for (int i = _fieldMap.size() - 1; i >= 0; i--) {        FieldMap fieldMap = _fieldMap.get(i);        if (fieldMap.getFieldRef() == fieldRef)          return fieldMap.getGetterRef();      }      return -1;    }    public void analyze(CodeVisitor visitor)    {      switch (visitor.getOpcode()) {      case CodeVisitor.GETFIELD:        int getter = getGetter(visitor.getShortArg());        if (getter > 0) {          visitor.setByteArg(0, CodeVisitor.INVOKEVIRTUAL);          visitor.setShortArg(1, getter);        }        break;      case CodeVisitor.PUTFIELD:        int setter = getSetter(visitor.getShortArg());        if (setter > 0) {          visitor.setByteArg(0, CodeVisitor.INVOKEVIRTUAL);          visitor.setShortArg(1, setter);        }        break;      }    }    int getSetter(int fieldRef)    {      for (int i = _fieldMap.size() - 1; i >= 0; i--) {        FieldMap fieldMap = _fieldMap.get(i);        if (fieldMap.getFieldRef() == fieldRef)          return fieldMap.getSetterRef();      }      return -1;    }  }  @Override  public String toString()  {    return getClass().getSimpleName() + "[" + _configDirectory + "]";  }}

⌨️ 快捷键说明

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