コード例 #1
0
 private static <T> void mergeStagedChainInner(List<CtClass<T>> chain) {
   if (chain.size() == 1) return;
   reverse(chain);
   CtClass<T> toMerge = chain.get(0);
   for (int i = 1; i < chain.size(); i++) {
     CtClass<T> mergeInto = chain.get(i);
     replaceInstantiatedTypeParams(toMerge, mergeInto);
     toMerge
         .getAnnotations()
         .stream()
         .forEach(
             (CtAnnotation<? extends Annotation> a) -> {
               if (mergeInto.getAnnotation(a.getActualAnnotation().getClass()) == null)
                 add(mergeInto, a, mergeInto::addAnnotation);
             });
     toMerge.getSuperInterfaces().forEach(mergeInto::addSuperInterface);
     toMerge
         .getAnonymousExecutables()
         .forEach(b -> add(mergeInto, b, mergeInto::addAnonymousExecutable));
     toMerge.getNestedTypes().forEach(nt -> add(mergeInto, nt, mergeInto::addNestedType));
     toMerge.getFields().forEach(f -> add(mergeInto, f, mergeInto::addField));
     for (CtMethod<?> methodToMerge : toMerge.getMethods()) {
       processMethod(mergeInto, toMerge, methodToMerge);
     }
     final CtClass<T> finalToMerge = toMerge;
     mergeInto.getConstructors().forEach(c -> processConstructor(c, finalToMerge));
     mergeInto.setSuperclass(toMerge.getSuperclass());
     toMerge = mergeInto;
   }
 }
コード例 #2
0
 private static boolean checkOnlyDefaultConstructor(CtClass<?> ctClass) {
   Set<? extends CtConstructor<?>> constructors = ctClass.getConstructors();
   if (constructors.size() > 1) return false;
   if (constructors.isEmpty()) return true;
   CtConstructor<?> constructor = constructors.iterator().next();
   return constructor.isImplicit();
 }
コード例 #3
0
ファイル: Enhancer.java プロジェクト: freewind/play-aaa
  private void enhance_(ApplicationClass applicationClass, boolean buildAuthorityRegistryOnly)
      throws Exception {
    Plugin.trace("about to enhance applicationClass: %s", applicationClass);
    CtClass ctClass = makeClass(applicationClass);
    Set<CtBehavior> s = new HashSet<CtBehavior>();
    s.addAll(Arrays.asList(ctClass.getDeclaredMethods()));
    s.addAll(Arrays.asList(ctClass.getMethods()));
    s.addAll(Arrays.asList(ctClass.getConstructors()));
    s.addAll(Arrays.asList(ctClass.getDeclaredConstructors()));
    for (final CtBehavior ctBehavior : s) {
      if (!Modifier.isPublic(ctBehavior.getModifiers())
          || javassist.Modifier.isAbstract(ctBehavior.getModifiers())) {
        continue;
      }

      boolean needsEnhance = false;
      RequireRight rr = null;
      RequirePrivilege rp = null;
      RequireAccounting ra = null;
      boolean allowSystem = false;
      Object[] aa = ctBehavior.getAnnotations();
      for (Object o : aa) {
        if (o instanceof RequirePrivilege) {
          needsEnhance = true;
          rp = (RequirePrivilege) o;
          continue;
        }
        if (o instanceof RequireRight) {
          needsEnhance = true;
          rr = (RequireRight) o;
          continue;
        }
        if (o instanceof AllowSystemAccount) {
          allowSystem = true;
          continue;
        }
        if (o instanceof RequireAccounting) {
          needsEnhance = true;
          ra = (RequireAccounting) o;
        }
      }
      if (!needsEnhance) continue;

      String key = ctBehavior.getLongName();
      String errMsg = String.format("Error enhancing class %s.%s: ", ctClass, ctBehavior);
      // process rr & rp
      if (null != rr || null != rp) {
        // check before/after enhancement
        Authority.registAuthoriable_(key, rr, rp);
        if (!buildAuthorityRegistryOnly) {
          // verify if before attribute of rr and rp is consistent
          if (null != rr && null != rp && (rr.before() != rp.before())) {
            String reason = "The before setting of RequireRight and RequirePrivilege doesn't match";
            throw new RuntimeException(errMsg + reason);
          }
          boolean before = true;
          if (null != rr) before = rr.before();
          if (null != rp) before = rp.before();
          // try best to guess the target object
          String curObj = "";
          if (null != rr) {
            // target object only impact dynamic access checking, hence rr shall not be null
            boolean isConstructor = ctBehavior instanceof CtConstructor;
            boolean isStatic = false;
            if (!isConstructor) isStatic = Modifier.isStatic(ctBehavior.getModifiers());
            int paraCnt = ctBehavior.getParameterTypes().length;
            int id = rr.target();
            // calibrate target id
            if (0 == id) {
              if (isConstructor) {
                id = -1;
              } else if (isStatic) {
                if (paraCnt > 0) id = 1;
                else id = -1;
              }
            } else if (id > paraCnt) {
              id = paraCnt;
            }
            // speculate cur target statement
            String sid = null;
            if (id == -1) sid = "_";
            if (id > -1) sid = String.valueOf(id);
            if (null != sid) {
              curObj =
                  "play.modules.aaa.PlayDynamicRightChecker.setObjectIfNoCurrent($" + sid + ");";
            }

            if (-1 == id) before = false;
          }
          // check permission enhancement
          if (before) {
            ctBehavior.insertBefore(
                curObj
                    + " play.modules.aaa.enhancer.Enhancer.Authority.checkPermission(\""
                    + key
                    + "\", "
                    + Boolean.toString(allowSystem)
                    + ");");
          } else {
            ctBehavior.insertAfter(
                curObj
                    + " play.modules.aaa.enhancer.Enhancer.Authority.checkPermission(\""
                    + key
                    + "\", "
                    + Boolean.toString(allowSystem)
                    + ");");
          }
        }
      }

      if (buildAuthorityRegistryOnly) continue;

      // process ra
      if (null != ra) {
        CtClass[] paraTypes = ctBehavior.getParameterTypes();
        String sParam = null;
        if (0 < paraTypes.length) {
          sParam = "new Object[0]";
        } else {
          sParam = "{$$}";
        }
        String msg = ra.value();
        if (null == msg || "".equals(msg)) msg = key;
        if (ra.before()) {
          ctBehavior.insertBefore(
              "play.modules.aaa.utils.Accounting.info(\""
                  + msg
                  + "\", "
                  + Boolean.toString(allowSystem)
                  + ", "
                  + sParam
                  + ");");
        } else {
          ctBehavior.insertAfter(
              "play.modules.aaa.utils.Accounting.info(\""
                  + msg
                  + "\", "
                  + Boolean.toString(allowSystem)
                  + ", "
                  + sParam
                  + ");");
        }
        CtClass etype = ClassPool.getDefault().get("java.lang.Exception");
        ctBehavior.addCatch(
            "{play.modules.aaa.utils.Accounting.error($e, \""
                + msg
                + "\", "
                + Boolean.toString(allowSystem)
                + ", "
                + sParam
                + "); throw $e;}",
            etype);
      }
    }

    if (buildAuthorityRegistryOnly) return;

    applicationClass.enhancedByteCode = ctClass.toBytecode();
    ctClass.detach();
  }