// this GwtCreateHandler has been introduced to make possible the
  // instanciation of abstract classes
  // that gwt-test-utils doesn't patch right now
  public Object create(Class<?> classLiteral) throws Exception {
    if (classLiteral.isAnnotation()
        || classLiteral.isArray()
        || classLiteral.isEnum()
        || classLiteral.isInterface()
        || !Modifier.isAbstract(classLiteral.getModifiers())) {
      return null;
    }

    Class<?> newClass = cache.get(classLiteral);

    if (newClass != null) {
      return newClass.newInstance();
    }

    CtClass ctClass = GwtClassPool.getCtClass(classLiteral);
    CtClass subClass = GwtClassPool.get().makeClass(classLiteral.getCanonicalName() + "SubClass");

    subClass.setSuperclass(ctClass);

    for (CtMethod m : ctClass.getDeclaredMethods()) {
      if (javassist.Modifier.isAbstract(m.getModifiers())) {
        CtMethod copy = new CtMethod(m, subClass, null);
        subClass.addMethod(copy);
      }
    }

    GwtPatcherUtils.patch(subClass, null);

    newClass = subClass.toClass(GwtClassLoader.get(), null);
    cache.put(classLiteral, newClass);

    return newClass.newInstance();
  }
  public static void patch(CtClass c, IPatcher patcher) throws Exception {
    treatClassToPatch(c);

    if (patcher != null) {
      patcher.initClass(c);
    }

    for (CtMethod m : c.getDeclaredMethods()) {
      boolean wasAbstract = false;
      String newBody = null;
      if (Modifier.isAbstract(m.getModifiers())) {
        m.setModifiers(m.getModifiers() - Modifier.ABSTRACT);
        wasAbstract = true;
      }
      if (patcher != null) {
        newBody = patcher.getNewBody(m);
      }
      if (newBody != null) {
        if (newBody.startsWith(AutomaticPatcher.INSERT_BEFORE)) {
          GwtPatcherUtils.insertBefore(
              m, newBody.substring(AutomaticPatcher.INSERT_BEFORE.length()));
        } else if (newBody.startsWith(AutomaticPatcher.INSERT_AFTER)) {
          GwtPatcherUtils.insertAfter(m, newBody.substring(AutomaticPatcher.INSERT_AFTER.length()));
        } else {
          GwtPatcherUtils.replaceImplementation(m, newBody);
        }
      } else if (wasAbstract) {
        if (patcher != null) {
          m.setBody(
              "{ throw new "
                  + UnsupportedOperationException.class.getName()
                  + "(\"Abstract method '"
                  + c.getSimpleName()
                  + "."
                  + m.getName()
                  + "()' is not patched by "
                  + patcher.getClass().getName()
                  + "\"); }");
        } else {
          m.setBody(
              "{ throw new "
                  + UnsupportedOperationException.class.getName()
                  + "(\"Abstract method '"
                  + c.getSimpleName()
                  + "."
                  + m.getName()
                  + "()' is not patched by any declared "
                  + IPatcher.class.getSimpleName()
                  + " instance\"); }");
        }
      }
    }

    if (patcher != null) {
      patcher.finalizeClass(c);
    }
  }
Exemple #3
0
  @Test(groups = "unit", timeOut = 1000)
  public void test() throws ClassNotFoundException {
    final Collection<Class<?>> descriptionClasses = Lists.newArrayList();
    final URL url =
        AnnotationTests.class.getClassLoader().getResource("META-INF/jobs/persistence.xml");
    final String jpaConfigContents = InputContexts.toString(InputContexts.forUrl(url));
    final List<Class<? extends ActivityDescription>> activityDescriptionsMapped =
        Lists.newArrayList();
    for (final Class<? extends ActivityFactory<?>> factoryClass : FACTORIES) {
      // Make sure the class is make as a ManageBean to DI context picks it up.
      assert factoryClass.getAnnotation(ManagedBean.class) != null
          : "Factory class " + factoryClass + " is not annotated with @ManagedBean";

      // assert factoryClass.getDeclaredConstructors().length == 1;
      boolean foundInjectedConstructor = false;
      for (Constructor<?> constructor : factoryClass.getDeclaredConstructors()) {
        if (constructor.getParameterTypes().length == 0
            || constructor.getAnnotation(Inject.class) != null) {
          foundInjectedConstructor = true;
        }
      }
      assert foundInjectedConstructor;

      final ActivityFactoryFor factoryAnnotation =
          factoryClass.getAnnotation(ActivityFactoryFor.class);
      // Make sure this class specifies which ActivityDescription it acts an ActivityFactory for.
      assert factoryAnnotation != null;
      final Class<? extends ActivityDescription> descriptionClass = factoryAnnotation.value();
      activityDescriptionsMapped.add(descriptionClass);
      assert ActivityDescription.class.isAssignableFrom(descriptionClass);
      // Make sure there are not multiple descriptions per factory
      assert !descriptionClasses.contains(descriptionClass);

      // Make sure the description can be persisted
      assert descriptionClass.getAnnotation(Entity.class) != null
          : descriptionClass + " is not annotated with entity.";
      assert jpaConfigContents.contains(descriptionClass.getCanonicalName())
          : "Class " + descriptionClass.getCanonicalName() + " not found in JPA configuration.";
    }

    final Pattern pattern = Pattern.compile("\\<class\\>.*\\<");
    final Matcher matcher = pattern.matcher(jpaConfigContents);
    int start = 0;
    while (matcher.find(start)) {
      final int startIdx = matcher.start() + "<class>".length();
      final int endIdx = jpaConfigContents.indexOf("<", startIdx);
      final String classStr = jpaConfigContents.substring(startIdx, endIdx);
      final Class<?> clazz = Class.forName(classStr);
      if (ActivityDescription.class.isAssignableFrom(clazz)) {
        if (!Modifier.isAbstract(clazz.getModifiers())) {
          assert activityDescriptionsMapped.contains(clazz)
              : "No activity factory found for description class " + clazz;
        }
      }
      start = endIdx;
    }
  }
Exemple #4
0
 /**
  * Return whether or not the class has a method with the given name
  *
  * @param theClass the class to inspect
  * @param theName the name of the method to look for
  * @return true if the class contains the method, false otherwise
  */
 private static boolean hasMethod(CtClass theClass, String theName) {
   try {
     return theClass.getDeclaredMethod(theName) != null
         && !Modifier.isAbstract(theClass.getDeclaredMethod(theName).getModifiers());
   } catch (NotFoundException e) {
     try {
       if (theClass.getSuperclass() != null) {
         return hasMethod(theClass.getSuperclass(), theName);
       } else {
         return false;
       }
     } catch (NotFoundException e1) {
       return false;
     }
   }
 }
  public ObjBase makeValue(ObjectId id, DBObject rawData, Class<? extends ObjBase> c) {

    if (Modifier.isAbstract(c.getModifiers()) || Modifier.isInterface(c.getModifiers())) {
      // extract declared schema from result, use that class
      Object schemaId = rawData.get(ReservedFieldNames.SCHEMA);
      try {
        c = (Class<ObjBase>) ClassUtil.findClass(schemaId.toString());
      } catch (ClassNotFoundException ex) {
        log.warn("Could not find fallback schema {}", schemaId);
        return null;
      }
    }

    ObjBase value = makeStub(id, c, rawData);
    // update stub with the rest of the data,
    if (value != null && !(value instanceof Swappable))
      try {
        unmarshaller.unmarshall(Bson.createDocument(rawData), value, this);
      } catch (MarshallingException me) {
        log.warn(me.getMessage(), me);
      }

    return value;
  }
Exemple #6
0
  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();
  }
 private boolean isJAXRSEntity(Class<?> javaClass, Class<? extends Annotation> annotation) {
   if (!hasAnnotation(javaClass, annotation)) return false;
   if (javaClass.isInterface() || Modifier.isAbstract(javaClass.getModifiers())) return false;
   return true;
 }
Exemple #8
0
  /**
   * Get the bean proeprties from the given class
   *
   * @param thePool the class pool to use when creating new fields
   * @param theClass the class the new fields will belong to
   * @param theInterface the original bean class
   * @return a Map of the bean property names with the new field for the property as the value
   * @throws javassist.CannotCompileException thrown if there is an error generating the methods
   * @throws javassist.NotFoundException thrown if there is an error generating the methods
   */
  private static <T> Map<String, CtField> properties(
      final ClassPool thePool, final CtClass theClass, final Class<T> theInterface)
      throws NotFoundException, CannotCompileException {
    Map<String, CtField> aMap = new HashMap<String, CtField>();

    for (Method aMethod : theInterface.getDeclaredMethods()) {

      // see if we've already processed this method.  Normal .equals for a method will not work
      // because the classes have to be the same,
      // what we want is the semantics of isAssignableFrom, not .equals between the classes
      // declaring the methods.  Thus, the FINDER
      // predicate implementation does exactly that.  It's a copy of the Method.equals function, but
      // with the .equals for the declaring
      // class changed to isAssignableFrom so we get the expected behavior.
      FINDER.method = aMethod;

      if (Iterables2.find(processedMethods, FINDER)) {
        continue;
      }

      // we want to ignore methods with implementations, we should not override them.
      if (!Modifier.isAbstract(aMethod.getModifiers())) {

        // mark the method as one we've already handled in case we get this method again on a
        // superclass/interface
        processedMethods.add(aMethod);
        continue;
      }

      if (!aMethod.getName().startsWith("get")
          && !aMethod.getName().startsWith("is")
          && !aMethod.getName().startsWith("has")
          && !aMethod.getName().startsWith("set")) {

        if (EmpireOptions.STRICT_MODE) {
          throw new IllegalArgumentException(
              "Non-bean style methods found, implementations for them cannot not be generated");
        } else {
          LOGGER.warn(
              "Non-bean style methods found, implementations for them cannot not be generated : "
                  + aMethod.getName());
        }
      }

      String aProp = aMethod.getName().substring(aMethod.getName().startsWith("is") ? 2 : 3);

      aProp = String.valueOf(aProp.charAt(0)).toLowerCase() + aProp.substring(1);

      Class aType = null;
      Type generics = null;

      if (aMethod.getName().startsWith("get")
          || aMethod.getName().startsWith("is")
          || aMethod.getName().startsWith("has")) {
        aType = aMethod.getReturnType();
        generics = aMethod.getGenericReturnType();
      } else if (aMethod.getName().startsWith("set") && aMethod.getParameterTypes().length > 0) {
        aType = aMethod.getParameterTypes()[0];

        if (aMethod.getGenericParameterTypes() != null
            && aMethod.getGenericParameterTypes().length > 0) {
          generics = aMethod.getGenericParameterTypes()[0];
        }
      }

      if (aType != null) {
        CtField aNewField = new CtField(thePool.get(aType.getName()), aProp, theClass);

        if (generics != null && generics instanceof ParameterizedTypeImpl) {
          for (Type t : ((ParameterizedTypeImpl) generics).getActualTypeArguments()) {
            String aFlag = "";
            String aName;

            if (t instanceof WildcardTypeImpl) {
              WildcardTypeImpl aWildcard = (WildcardTypeImpl) t;
              // trying to suss out super v extends w/o resorting to string munging.
              if (aWildcard.getLowerBounds().length == 0 && aWildcard.getUpperBounds().length > 0) {
                // no lower bounds afaik indicates ? extends Foo
                aFlag = "+";
                aName = ((Class) aWildcard.getUpperBounds()[0]).getName();
              } else if (aWildcard.getLowerBounds().length > 0) {
                // lower & upper bounds I believe indicates something of the form Foo super Bar
                aFlag = "-";
                aName = ((Class) aWildcard.getLowerBounds()[0]).getName();
              } else {
                throw new CannotCompileException(
                    "Unknown or unsupported type signature found: " + t);
              }
            } else {
              aName = ((Class) t).getName();
            }

            aNewField
                .getFieldInfo()
                .addAttribute(
                    new SignatureAttribute(
                        aNewField.getFieldInfo().getConstPool(),
                        "L"
                            + aType.getName().replace('.', '/')
                            + "<"
                            + aFlag
                            + "L"
                            + aName.replace('.', '/')
                            + ";>;"));
          }
        }

        aMap.put(aProp, aNewField);
      }

      // mark the method as one we've already handled in case we get this method again on a
      // superclass/interface
      processedMethods.add(aMethod);
    }

    return aMap;
  }