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 + -
显示快捷键?