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);
     }
   }
 }
Example #5
0
 /*  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();
  }