private void transformParameterizedGetMemcacheServiceMethod(CtClass clazz) throws NotFoundException, CannotCompileException { CtMethod method = clazz.getDeclaredMethod( "getMemcacheService", new CtClass[] {clazz.getClassPool().get("java.lang.String")}); method.setBody("return new org.jboss.capedwarf.memcache.InfinispanMemcacheService($1);"); }
private void findAndRemoveMethod(CtClass ctClass, CtField ctField, String className) { try { CtMethod ctMethod = ctClass.getDeclaredMethod( ctField.getName(), new CtClass[] {ctClass.getClassPool().get(className)}); ctClass.getClassFile().getMethods().remove(ctMethod.getMethodInfo()); } catch (Exception e) { } }
protected void enhanceAttributesAccess(Map<String, CtField> fieldsMap, CtClass managedCtClass) throws Exception { final ConstPool constPool = managedCtClass.getClassFile().getConstPool(); final ClassPool classPool = managedCtClass.getClassPool(); for (Object oMethod : managedCtClass.getClassFile().getMethods()) { final MethodInfo methodInfo = (MethodInfo) oMethod; final String methodName = methodInfo.getName(); // skip methods added by enhancement, and abstract methods (methods without any code) if (methodName.startsWith(DROOLS_PREFIX) || methodInfo.getCodeAttribute() == null) { continue; } try { final CodeIterator itr = methodInfo.getCodeAttribute().iterator(); while (itr.hasNext()) { final int index = itr.next(); final int op = itr.byteAt(index); if (op != Opcode.PUTFIELD && op != Opcode.GETFIELD) { continue; } final String fieldName = constPool.getFieldrefName(itr.u16bitAt(index + 1)); CtField ctField = fieldsMap.get(fieldName); if (ctField == null) { continue; } // if we are in constructors, only need to intercept assignment statement for Reactive // Collection/List/... (regardless they may be final) if (methodInfo.isConstructor() && !(isCtFieldACollection(ctField))) { continue; } if (op == Opcode.PUTFIELD) { // addMethod is a safe add, if constant already present it return the existing value // without adding. final int methodIndex = addMethod(constPool, writeMethods.get(fieldName)); itr.writeByte(Opcode.INVOKEVIRTUAL, index); itr.write16bit(methodIndex, index + 1); } } methodInfo.getCodeAttribute().setAttribute(MapMaker.make(classPool, methodInfo)); } catch (BadBytecode bb) { final String msg = String.format( "Unable to perform field access transformation in method [%s]", methodName); throw new Exception(msg, bb); } } }
private static boolean isCtClassSerializable( JarArchiveComparatorOptions options, CtClass clazz, JarArchiveComparator jarArchiveComparator) { ClassPool pool = clazz.getClassPool(); try { return clazz.subtypeOf(pool.get("java.io.Serializable")); } catch (NotFoundException e) { if (options.isIgnoreMissingClasses()) { return false; } else { throw JApiCmpException.forClassLoading(e, clazz.getName(), jarArchiveComparator); } } }
/* 49: */ /* 50: */ public int transform(CtClass clazz, int pos, CodeIterator iterator, ConstPool cp) /* 51: */ throws BadBytecode /* 52: */ { /* 53: 68 */ int c = iterator.byteAt(pos); /* 54: 69 */ if ((c == 185) || (c == 183) || (c == 184) || (c == 182)) /* 55: */ { /* 56: 71 */ int index = iterator.u16bitAt(pos + 1); /* 57: 72 */ String cname = cp.eqMember(this.methodname, this.methodDescriptor, index); /* 58: 73 */ if ((cname != null) && (matchClass(cname, clazz.getClassPool()))) /* 59: */ { /* 60: 74 */ int ntinfo = cp.getMemberNameAndType(index); /* 61: 75 */ pos = match(c, pos, iterator, cp.getNameAndTypeDescriptor(ntinfo), cp); /* 62: */ } /* 63: */ } /* 64: 80 */ return pos; /* 65: */ }
/** * Creates a new static class field, for the declaring class of the callee method. * * @param ctClass the class * @param ctMethod the method * @return the name of the field */ private String addCalleeMethodDeclaringClassField(final CtClass ctClass, final CtMethod ctMethod) throws NotFoundException, CannotCompileException { String fieldName = TransformationUtil.STATIC_CLASS_FIELD + TransformationUtil.DELIMITER + "method" + TransformationUtil.DELIMITER + ctMethod.getDeclaringClass().getName().replace('.', '_'); boolean hasField = false; CtField[] fields = ctClass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { CtField field = fields[i]; if (field.getName().equals(fieldName)) { hasField = true; break; } } if (!hasField) { CtField field = new CtField(ctClass.getClassPool().get("java.lang.Class"), fieldName, ctClass); field.setModifiers(Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL); ctClass.addField( field, "java.lang.Class#forName(\"" + ctMethod.getDeclaringClass().getName().replace('/', '.') + "\")"); } return fieldName; }
private CtClass instrumentClass( AspectManager manager, AOPClassPool pool, CtClass clazz, boolean isLoadedClass) throws NotFoundException, Exception { if (pool.isClassLoadedButNotWoven(clazz.getName())) { return null; } try { CtClass superClass = clazz.getSuperclass(); if (superClass != null && !Instrumentor.implementsAdvised(clazz)) { ClassPool superPool = superClass.getClassPool(); if (superPool instanceof AOPClassPool) { AspectManager aspectManager = manager; if (manager instanceof Domain && superPool != pool) { // We are in a scoped classloader and the superclass is not aspectManager = AspectManager.instance(superPool.getClassLoader()); } instrumentClass(aspectManager, (AOPClassPool) superPool, superClass, false); } } if (manager.isNonAdvisableClassName(clazz.getName())) { return null; } if (clazz.isArray()) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, isArray: " + clazz.getName()); pool.flushClass(clazz.getName()); return null; } if (clazz.isInterface()) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, isInterface: " + clazz.getName()); // pool.flushClass(info.getClassName()); clazz.prune(); return null; } if (clazz.isFrozen()) { if (isAdvised(pool, clazz)) return null; if (verbose && logger.isDebugEnabled()) logger.debug("warning, isFrozen: " + clazz.getName() + " " + clazz.getClassPool()); if (!isLoadedClass) { // What's the point of this? clazz = obtainCtClassInfo(pool, clazz.getName(), null); } else return null; // info.getClazz().defrost(); } boolean transformed = clazz.isModified(); if (!transformed) { ClassAdvisor advisor = AdvisorFactory.getClassAdvisor(clazz, manager); Instrumentor instrumentor = InstrumentorFactory.getInstrumentor( pool, manager, manager.dynamicStrategy.getJoinpointClassifier(), manager.dynamicStrategy.getDynamicTransformationObserver(clazz)); if (!Instrumentor.isTransformable(clazz)) { if (verbose && logger.isDebugEnabled()) logger.debug("cannot compile, implements Untransformable: " + clazz.getName()); // Flushing the generated invocation classes breaks things further down the line // pool.flushClass(info.getClassName()); return null; } manager.attachMetaData(advisor, clazz, true); manager.applyInterfaceIntroductions(advisor, clazz); transformed = instrumentor.transform(clazz, advisor); } if (transformed) { return clazz; } if (isLoadedClass) { pool.setClassLoadedButNotWoven(clazz.getName()); } return null; } catch (Exception e) { throw new RuntimeException("Error converting class ", e); } finally { } }
/* Hibernate 的关联关系太复杂了。要么你区分控制端和被控制端。要么你必须在使用的时候将两端都设置好关联关系。 对于mappedBy也是一个无语的设计。为什么我要通过它来区分控制端? */ @Override public void enhance(CtClass ctClass) throws Exception { CtField[] fields = ctClass.getDeclaredFields(); // String entityListener = "javax.persistence.EntityListeners"; // if (ctClass.hasAnnotation(EntityCallback.class)) { // EntityCallback entityListeners = (EntityCallback) // ctClass.getAnnotation(EntityCallback.class); // String clzzName = entityListeners.value(); // CtClass clzz = ServiceFramwork.classPool.get(clzzName); // enhanceJPACallback(clzz); // AnnotationsAttribute annotationsAttribute = // EnhancerHelper.getAnnotations(ctClass); // ArrayMemberValue arrayMemberValue = new // ArrayMemberValue(annotationsAttribute.getConstPool()); // ClassMemberValue[] clzzes = new ClassMemberValue[]{new ClassMemberValue(clzzName, // annotationsAttribute.getConstPool())}; // arrayMemberValue.setValue(clzzes); // EnhancerHelper.createAnnotation(annotationsAttribute, EntityListeners.class, // map("value", arrayMemberValue)); // // } else { // // } enhanceJPACallback(ctClass); for (CtField ctField : fields) { if (EnhancerHelper.hasAnnotation(ctField, "javax.persistence.OneToOne")) { DBInfo dbInfo = ServiceFramwork.injector.getInstance(DBInfo.class); Map<String, String> columns = dbInfo.tableColumns.get(ctClass.getSimpleName()); String clzzName = findAssociatedClassName(ctField); CtField mappedByField = findAssociatedField(ctClass, clzzName); if (!columns.containsKey(ctField.getName() + "_id")) { setMappedBy(ctField, mappedByField.getName(), "OneToOne"); } else { setMappedBy(mappedByField, mappedByField.getName(), "OneToOne"); } setCascad(mappedByField, "OneToOne"); setCascad(ctField, "OneToOne"); String mappedByClassName = clzzName; String mappedByFieldName = mappedByField.getName(); findAndRemoveMethod(ctClass, ctField, mappedByClassName); findAndRemoveMethod(ctClass, ctField.getName()); CtMethod wow = CtMethod.make( format( "public net.csdn.jpa.association.Association {}() {" + "net.csdn.jpa.association.Association obj = new net.csdn.jpa.association.Association(this,\"{}\",\"{}\",\"{}\");return obj;" + " }", ctField.getName(), ctField.getName(), mappedByFieldName, "javax.persistence.OneToOne"), ctClass); ctClass.addMethod(wow); CtMethod wow2 = CtMethod.make( format( "public {} {}({} obj) {" + " this.attr(\"{}\",obj);" + " obj.attr(\"{}\",this);" + " return this;" + " }", ctClass.getName(), ctField.getName(), mappedByClassName, ctField.getName(), mappedByFieldName), ctClass); ctClass.addMethod(wow2); } if (EnhancerHelper.hasAnnotation(ctField, "javax.persistence.OneToMany")) { String clzzName = findAssociatedClassName(ctField); String mappedByFieldName = findAssociatedFieldName(ctClass, clzzName); String mappedByClassName = ctClass.getName(); // 如果没有设置mappedBy我们帮他设置吧 setMappedBy(ctField, mappedByFieldName, "OneToMany"); setCascad(ctField, "OneToMany"); findAndRemoveMethod(ctClass, ctField, mappedByClassName); findAndRemoveMethod(ctClass, ctField.getName()); String propertyName = mappedByFieldName.substring(0, 1).toUpperCase() + mappedByFieldName.substring(1); String getter = "set" + propertyName; CtMethod wow = CtMethod.make( format( "public net.csdn.jpa.association.Association {}() {" + "net.csdn.jpa.association.Association obj = new net.csdn.jpa.association.Association(this,\"{}\",\"{}\",\"{}\");return obj;" + " }", ctField.getName(), ctField.getName(), mappedByFieldName, "javax.persistence.OneToMany"), ctClass); ctClass.addMethod(wow); CtMethod wow2 = CtMethod.make( format( "public {} {}({} obj) {" + " this.{}.add(obj);" + " obj.{}(this);" + " return this;" + " }", ctClass.getName(), ctField.getName(), clzzName, ctField.getName(), getter), ctClass); ctClass.addMethod(wow2); } if (EnhancerHelper.hasAnnotation(ctField, "javax.persistence.ManyToOne")) { String clzzName = ctField.getType().getName(); String mappedByFieldName = findAssociatedFieldName(ctClass, clzzName); String mappedByClassName = ctClass.getName(); // 默认设置为cascade = CascadeType.PERSIST setCascad(ctField, "ManyToOne"); findAndRemoveMethod(ctClass, ctField, mappedByClassName); findAndRemoveMethod(ctClass, ctField.getName()); String propertyName = mappedByFieldName.substring(0, 1).toUpperCase() + mappedByFieldName.substring(1); String getter = "get" + propertyName; CtMethod wow = CtMethod.make( format( "public net.csdn.jpa.association.Association {}() {" + "net.csdn.jpa.association.Association obj = new net.csdn.jpa.association.Association(this,\"{}\",\"{}\",\"{}\");return obj;" + " }", ctField.getName(), ctField.getName(), mappedByFieldName, "javax.persistence.ManyToOne"), ctClass); ctClass.addMethod(wow); CtMethod wow2 = CtMethod.make( format( "public {} {}({} obj) {" + " this.{} = obj;" + " obj.{}().add(this);" + " return this;" + " }", ctClass.getName(), ctField.getName(), clzzName, ctField.getName(), getter), ctClass); ctClass.addMethod(wow2); } if (EnhancerHelper.hasAnnotation(ctField, "javax.persistence.ManyToMany")) { String clzzName = findAssociatedClassName(ctField); String mappedByFieldName = findAssociatedFieldName(ctClass, clzzName); String mappedByClassName = ctClass.getName(); CtField other = findAssociatedField(ctClass, clzzName); DBInfo dbInfo = ServiceFramwork.injector.getInstance(DBInfo.class); String otherClassSimpleName = findAssociatedClass(ctClass.getClassPool(), ctField).getSimpleName(); String maybeTable1 = ctClass.getSimpleName() + "_" + otherClassSimpleName; String maybeTable2 = otherClassSimpleName + "_" + ctClass.getSimpleName(); String finalTableName = dbInfo.tableNames.contains(maybeTable1) ? maybeTable1 : maybeTable2; setCascad(ctField, "ManyToMany"); boolean isMaster = false; if (!ctField.hasAnnotation(ManyToManyHint.class)) { if (dbInfo.tableNames.contains(maybeTable1)) { setMappedBy(other, ctField.getName(), "ManyToMany"); isMaster = true; finalTableName = maybeTable1; } if (dbInfo.tableNames.contains(maybeTable2)) { setMappedBy(ctField, mappedByFieldName, "ManyToMany"); finalTableName = maybeTable2; } setManyToManyHint(other); } findAndRemoveMethod(ctClass, ctField, mappedByClassName); findAndRemoveMethod(ctClass, ctField.getName()); String propertyName = mappedByFieldName.substring(0, 1).toUpperCase() + mappedByFieldName.substring(1); String getter = "get" + propertyName; CtMethod wow = CtMethod.make( format( "public net.csdn.jpa.association.Association {}() {" + "net.csdn.jpa.association.Association obj = new net.csdn.jpa.association.Association(this,\"{}\",\"{}\",\"{}\",\"{}\",\"{}\");return obj;" + " }", ctField.getName(), ctField.getName(), mappedByFieldName, "javax.persistence.ManyToMany", finalTableName, isMaster), ctClass); ctClass.addMethod(wow); CtMethod wow2 = CtMethod.make( format( "public {} {}({} obj) {" + " {}.add(obj);" + " obj.{}().add(this);" + " return this;" + " }", ctClass.getName(), ctField.getName(), clzzName, ctField.getName(), getter), ctClass); ctClass.addMethod(wow2); } } ctClass.defrost(); }