예제 #1
1
 private Object newInstance(Class type) {
   try {
     return type.newInstance();
   } catch (Exception ex) {
     try {
       // Try a private constructor.
       Constructor constructor = type.getDeclaredConstructor();
       constructor.setAccessible(true);
       return constructor.newInstance();
     } catch (SecurityException ignored) {
     } catch (NoSuchMethodException ignored) {
       if (type.isArray())
         throw new SerializationException(
             "Encountered JSON object when expected array of type: " + type.getName(), ex);
       else if (type.isMemberClass() && !Modifier.isStatic(type.getModifiers()))
         throw new SerializationException(
             "Class cannot be created (non-static member class): " + type.getName(), ex);
       else
         throw new SerializationException(
             "Class cannot be created (missing no-arg constructor): " + type.getName(), ex);
     } catch (Exception privateConstructorException) {
       ex = privateConstructorException;
     }
     throw new SerializationException(
         "Error constructing instance of class: " + type.getName(), ex);
   }
 }
예제 #2
1
  /**
   * Default constructor associates this handler with the queue for the current thread.
   *
   * <p>If there isn't one, this handler won't be able to receive messages.
   */
  public Handler() {
    if (FIND_POTENTIAL_LEAKS) {
      final Class<? extends Handler> klass = getClass();
      if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass())
          && (klass.getModifiers() & Modifier.STATIC) == 0) {
        Log.w(
            TAG,
            "The following Handler class should be static or leaks might occur: "
                + klass.getCanonicalName());
      }
    }
    // @wujl commented

    mLooper = Looper.myLooper();
    if (mLooper == null) {
      throw new RuntimeException(
          "Can't create handler inside thread that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;

    // #wujl
    // @wujl added
    // mLooper = null;
    // mQueue = null;
    // #wujl
    mCallback = null;
  }
예제 #3
0
 public static int getNesting(Class<?> clazz) {
   if (clazz.isMemberClass() && !isStatic(clazz)) {
     return 1 + getNesting(clazz.getDeclaringClass());
   } else {
     return 0;
   }
 }
예제 #4
0
 public static boolean isCacheable(Annotation[] annotations) {
   for (Annotation qualifier : annotations) {
     Class<?> clazz = qualifier.getClass();
     if (clazz.isAnonymousClass() || (clazz.isMemberClass() && isStatic(clazz))) {
       return false;
     }
   }
   return true;
 }
    private boolean isEnclosingClassParameter() {

      if (enclosingClassCache == null) {
        Class<T> owningType = entity.getType();
        this.enclosingClassCache =
            owningType.isMemberClass() && type.getType().equals(owningType.getEnclosingClass());
      }

      return enclosingClassCache;
    }
  protected List<JavaMethod> initMethods() {
    List<JavaMethod> methodMap = new ArrayList<JavaMethod>();

    // Get all methods for interfaces: normally, even if it is possible in Java
    // to override a method into a inherited interface, there is no meaning
    // to do so (we just ignore potential compilation issues with generated AS3
    // classes for this case since it is always possible to remove the method
    // re-declaration in the child interface).
    Method[] methods = null;
    ParameterizedType[] declaringTypes = GenericTypeUtil.getDeclaringTypes(type);

    if (type.isInterface()) methods = type.getMethods();
    else methods = type.getDeclaredMethods();

    for (Method method : methods) {
      if (shouldGenerateMethod(method)) {
        JavaMethod javaMethod =
            new JavaMethod(method, MethodType.OTHER, this.provider, declaringTypes);

        for (Class<?> clazz : javaMethod.getParameterTypes()) {
          if (clazz.isMemberClass() && !clazz.isEnum()) {
            throw new UnsupportedOperationException(
                "Inner classes are not supported (except enums): " + clazz);
          }
        }
        for (ClientType paramType : javaMethod.getClientParameterTypes())
          addToImports(provider.getJavaImports(paramType, false));

        Class<?> clazz = javaMethod.getReturnType();
        if (clazz.isMemberClass() && !clazz.isEnum()) {
          throw new UnsupportedOperationException(
              "Inner classes are not supported (except enums): " + clazz);
        }
        if (!clazz.equals(Void.class) && !clazz.equals(void.class))
          addToImports(provider.getJavaImports(javaMethod.getClientReturnType(), false));

        methodMap.add(javaMethod);
      }
    }

    return methodMap;
  }
예제 #7
0
  @Test
  public void expressions() throws Exception {
    Map<Class<?>, Object> args = Maps.newHashMap();
    args.put(Object.class, "obj");
    args.put(BeanPath.class, new EntityPathBase<Object>(Object.class, "obj"));
    args.put(Class.class, Integer.class);
    args.put(Class[].class, new Class<?>[] {Object.class, Object.class});
    args.put(java.util.Date.class, new java.util.Date(0));
    args.put(java.sql.Date.class, new java.sql.Date(0));
    args.put(java.sql.Time.class, new java.sql.Time(0));
    args.put(java.sql.Timestamp.class, new java.sql.Timestamp(0));
    args.put(Expression.class, Expressions.enumPath(Gender.class, "e"));
    args.put(
        Expression[].class,
        new Expression<?>[] {Expressions.enumPath(Gender.class, "e"), Expressions.stringPath("s")});
    args.put(FactoryExpression.class, Projections.tuple(Expressions.stringPath("str")));
    args.put(GroupExpression.class, GroupBy.avg(Expressions.numberPath(Integer.class, "num")));
    args.put(Number.class, 1);
    args.put(Operator.class, Ops.AND);
    args.put(Path.class, Expressions.stringPath("str"));
    args.put(PathBuilderValidator.class, PathBuilderValidator.DEFAULT);
    args.put(PathMetadata.class, PathMetadataFactory.forVariable("obj"));
    args.put(PathInits.class, PathInits.DEFAULT);
    args.put(Predicate.class, Expressions.path(Object.class, "obj").isNull());
    args.put(QueryMetadata.class, new DefaultQueryMetadata());
    args.put(String.class, "obj");

    Reflections reflections = new Reflections();
    Set<Class<? extends Expression>> types = reflections.getSubTypesOf(Expression.class);
    for (Class<?> type : types) {
      if (!type.isInterface()
          && !type.isMemberClass()
          && !Modifier.isAbstract(type.getModifiers())) {
        for (Constructor<?> c : type.getConstructors()) {
          Object[] parameters = new Object[c.getParameterTypes().length];
          for (int i = 0; i < c.getParameterTypes().length; i++) {
            parameters[i] =
                Objects.requireNonNull(
                    args.get(c.getParameterTypes()[i]), c.getParameterTypes()[i].getName());
          }
          c.setAccessible(true);
          Object o = c.newInstance(parameters);
          assertEquals(o, Serialization.serialize(o));
        }
      }
    }
  }
예제 #8
0
  /**
   * @return Return true if the given type can be managed by the driver, and subsequently by the UI.
   *     <p>E.g. of managed types are: int, Integer, java.lang.Integer, org.kie.SomeClass,
   *     List<Integer>, java.util.List<org.kie.SomeClass>
   *     <p>e.g. of not manged types are: int[], java.util.List<List<String>>, List<Map<String,
   *     org.kie.SomeClass>>
   */
  public static boolean isManagedType(Type type, ClassTypeResolver classTypeResolver)
      throws ModelDriverException {

    // quickest checks first.
    if (type.isPrimitive()) {
      return true;
    }

    if (type.isArray()) {
      return false;
    }

    if (type.isParameterized() && type.getTypeArguments().size() > 1) {
      return false;
    }

    try {

      Class<?> clazz = classTypeResolver.resolveType(type.getName());

      if (clazz.isAnonymousClass() || clazz.isLocalClass() || clazz.isMemberClass()) {
        return false;
      }

      if (type.isParameterized()) {
        Class<?> bag = classTypeResolver.resolveType(type.getName());
        if (!Collection.class.isAssignableFrom(bag)) {
          return false;
        }

        return isSimpleClass(((List<Type>) type.getTypeArguments()).get(0));
      }

      return true;

    } catch (ClassNotFoundException e) {
      throw new ModelDriverException(
          "Class could not be resolved for name: " + type.getName() + ". " + e.getMessage(), e);
    }
  }
  private void treatPatchClass(CtClass patchCtClass) throws ClassNotFoundException {
    Class<?> clazz = Class.forName(patchCtClass.getName(), true, classLoader);
    PatchClass patchClass = GwtReflectionUtils.getAnnotation(clazz, PatchClass.class);

    if (!Patcher.class.isAssignableFrom(clazz) || !hasDefaultConstructor(clazz)) {
      throw new RuntimeException(
          "The @"
              + PatchClass.class.getSimpleName()
              + " annotated class '"
              + clazz.getName()
              + "' must implements "
              + Patcher.class.getSimpleName()
              + " interface and provide an empty constructor");
    }

    Patcher patcher = (Patcher) GwtReflectionUtils.instantiateClass(clazz);

    for (Class<?> c : patchClass.value()) {
      String targetName =
          c.isMemberClass()
              ? c.getDeclaringClass().getCanonicalName() + "$" + c.getSimpleName()
              : c.getCanonicalName();
      if (patchers.get(targetName) != null) {
        logger.error("Two patches for same class " + targetName);
        throw new RuntimeException("Two patches for same class " + targetName);
      }
      patchers.put(targetName, patcher);
      logger.debug("Add patch for class " + targetName + " : " + clazz.getCanonicalName());
    }
    for (String s : patchClass.classes()) {
      if (patchers.get(s) != null) {
        logger.error("Two patches for same class " + s);
        throw new RuntimeException("Two patches for same class " + s);
      }
      patchers.put(s, patcher);
      logger.debug("Add patch for class " + s + " : " + clazz.getCanonicalName());
    }
  }
예제 #10
0
 /** Create an instance based on a Class. */
 public TypeName(Class<?> cls) {
   int dim = 0;
   Class<?> inner = cls;
   while (inner.isArray()) {
     inner = cls.getComponentType();
     dim += 1;
   }
   dimensions = dim;
   Class<?> parent = cls;
   int nesting = 0;
   while (parent.isMemberClass()) {
     nesting++;
     parent = parent.getDeclaringClass();
   }
   nestingLevel = nesting;
   baseQualifiedName = adaptQualifiedName(cls.getCanonicalName());
   baseBinaryName = cls.getName();
   primitive = cls.isPrimitive();
   shortName = buildShortName();
   qualifiedName = buildQualifiedName();
   binaryName = buildBinaryName();
   varargs = false;
 }
예제 #11
0
  /**
   * Searches available constructor.
   *
   * @param jdiffDes constructor description to find.
   * @return reflected constructor, or null if not found.
   */
  @SuppressWarnings("unchecked")
  private Constructor<?> findMatchingConstructor(JDiffConstructor jdiffDes) {
    for (Constructor<?> c : mClass.getDeclaredConstructors()) {
      Type[] params = c.getGenericParameterTypes();
      boolean isStaticClass = ((mClass.getModifiers() & Modifier.STATIC) != 0);

      int startParamOffset = 0;
      int numberOfParams = params.length;

      // non-static inner class -> skip implicit parent pointer
      // as first arg
      if (mClass.isMemberClass() && !isStaticClass && params.length >= 1) {
        startParamOffset = 1;
        --numberOfParams;
      }

      ArrayList<String> jdiffParamList = jdiffDes.mParamList;
      if (jdiffParamList.size() == numberOfParams) {
        boolean isFound = true;
        // i counts jdiff params, j counts reflected params
        int i = 0;
        int j = startParamOffset;
        while (i < jdiffParamList.size()) {
          if (!compareParam(jdiffParamList.get(i), params[j])) {
            isFound = false;
            break;
          }
          ++i;
          ++j;
        }
        if (isFound) {
          return c;
        }
      }
    }
    return null;
  }
예제 #12
0
  /**
   * This method is used to filter classes that are added to the {@link DeployedUnit}. When this
   * method is used, only classes that are meant to be used with serialization are added to the
   * deployment. This feature can be used to, for example, make sure that
   * non-serialization-compatible classes (such as interfaces), do not complicate the use of a
   * deployment with the remote services (REST/JMS/WS). Note to other developers, it's possible that
   * classpath problems may arise, because of either classloader or lazy class resolution problems:
   * I simply don't know enough about the inner workings of the JAXB implementations (plural!) to
   * figure this out.
   *
   * @param deployedUnit The {@link DeployedUnit} to which the classes are added. The {@link
   *     DeployedUnit} to which the classes are added. The {@link DeployedUnit} to which the classes
   *     are added.
   * @param classToAdd The class to add to the {@link DeployedUnit}.
   */
  private static void filterClassesAddedToDeployedUnit(
      DeployedUnit deployedUnit, Class classToAdd) {

    if (classToAdd.isInterface()
        || classToAdd.isAnnotation()
        || classToAdd.isLocalClass()
        || classToAdd.isMemberClass()) {
      return;
    }

    boolean jaxbClass = false;
    boolean remoteableClass = false;
    // @XmlRootElement and @XmlType may be used with inheritance
    for (Annotation anno : classToAdd.getAnnotations()) {
      if (XmlRootElement.class.equals(anno.annotationType())) {
        jaxbClass = true;
        break;
      }
      if (XmlType.class.equals(anno.annotationType())) {
        jaxbClass = true;
        break;
      }
    }
    // @Remotable is not inheritable, and may not be used as such
    for (Annotation anno : classToAdd.getDeclaredAnnotations()) {
      if (Remotable.class.equals(anno.annotationType())) {
        remoteableClass = true;
        break;
      }
    }

    if (jaxbClass || remoteableClass) {
      DeployedUnitImpl deployedUnitImpl = (DeployedUnitImpl) deployedUnit;
      deployedUnitImpl.addClass(classToAdd);
    }
  }
예제 #13
0
  @BeforeClass
  public static void beforeClass() throws Exception {
    List<Class<?>> analysisClasses = getClassesForPackage("org.apache.lucene.analysis");
    tokenizers = new ArrayList<Constructor<? extends Tokenizer>>();
    tokenfilters = new ArrayList<Constructor<? extends TokenFilter>>();
    charfilters = new ArrayList<Constructor<? extends CharFilter>>();
    for (final Class<?> c : analysisClasses) {
      final int modifiers = c.getModifiers();
      if (
      // don't waste time with abstract classes or deprecated known-buggy ones
      Modifier.isAbstract(modifiers)
          || !Modifier.isPublic(modifiers)
          || c.isSynthetic()
          || c.isAnonymousClass()
          || c.isMemberClass()
          || c.isInterface()
          || c.isAnnotationPresent(Deprecated.class)
          || !(Tokenizer.class.isAssignableFrom(c)
              || TokenFilter.class.isAssignableFrom(c)
              || CharFilter.class.isAssignableFrom(c))) {
        continue;
      }

      for (final Constructor<?> ctor : c.getConstructors()) {
        // don't test synthetic or deprecated ctors, they likely have known bugs:
        if (ctor.isSynthetic()
            || ctor.isAnnotationPresent(Deprecated.class)
            || brokenConstructors.get(ctor) == ALWAYS) {
          continue;
        }
        if (Tokenizer.class.isAssignableFrom(c)) {
          assertTrue(
              ctor.toGenericString() + " has unsupported parameter types",
              allowedTokenizerArgs.containsAll(Arrays.asList(ctor.getParameterTypes())));
          tokenizers.add(castConstructor(Tokenizer.class, ctor));
        } else if (TokenFilter.class.isAssignableFrom(c)) {
          assertTrue(
              ctor.toGenericString() + " has unsupported parameter types",
              allowedTokenFilterArgs.containsAll(Arrays.asList(ctor.getParameterTypes())));
          tokenfilters.add(castConstructor(TokenFilter.class, ctor));
        } else if (CharFilter.class.isAssignableFrom(c)) {
          assertTrue(
              ctor.toGenericString() + " has unsupported parameter types",
              allowedCharFilterArgs.containsAll(Arrays.asList(ctor.getParameterTypes())));
          charfilters.add(castConstructor(CharFilter.class, ctor));
        } else {
          fail("Cannot get here");
        }
      }
    }

    final Comparator<Constructor<?>> ctorComp =
        new Comparator<Constructor<?>>() {
          @Override
          public int compare(Constructor<?> arg0, Constructor<?> arg1) {
            return arg0.toGenericString().compareTo(arg1.toGenericString());
          }
        };
    Collections.sort(tokenizers, ctorComp);
    Collections.sort(tokenfilters, ctorComp);
    Collections.sort(charfilters, ctorComp);
    if (VERBOSE) {
      System.out.println("tokenizers = " + tokenizers);
      System.out.println("tokenfilters = " + tokenfilters);
      System.out.println("charfilters = " + charfilters);
    }
  }
예제 #14
0
  private void addClass(Class<?> classZ) {
    if (classZ.isInterface()
        || classZ.isMemberClass()
        || classZ.isEnum()
        || classZ.isAnnotation()
        || classZ.isAnonymousClass()) return;
    int modify = classZ.getModifiers();
    if (Modifier.isAbstract(modify) || (!Modifier.isPublic(modify))) return;
    IocBean iocBean = classZ.getAnnotation(IocBean.class);
    if (iocBean != null) {
      if (log.isDebugEnabled()) log.debugf("Found a Class with Ioc-Annotation : %s", classZ);

      // 采用 @IocBean->name
      String beanName = iocBean.name();
      if (Strings.isBlank(beanName)) {
        // 否则采用 @InjectName
        InjectName innm = classZ.getAnnotation(InjectName.class);
        if (null != innm && !Strings.isBlank(innm.value())) {
          beanName = innm.value();
        }
        // 大哥(姐),您都不设啊!? 那就用 simpleName 吧
        else {
          beanName = Strings.lowerFirst(classZ.getSimpleName());
        }
      }

      if (map.containsKey(beanName))
        throw Lang.makeThrow(
            IocException.class,
            "Duplicate beanName=%s, by %s !!  Have been define by %s !!",
            beanName,
            classZ,
            map.get(beanName).getClass());

      IocObject iocObject = new IocObject();
      iocObject.setType(classZ);
      map.put(beanName, iocObject);

      iocObject.setSingleton(iocBean.singleton());
      if (!Strings.isBlank(iocBean.scope())) iocObject.setScope(iocBean.scope());

      // 看看构造函数都需要什么函数
      String[] args = iocBean.args();
      // if (null == args || args.length == 0)
      // args = iocBean.param();
      if (null != args && args.length > 0)
        for (String value : args) iocObject.addArg(convert(value));

      // 设置Events
      IocEventSet eventSet = new IocEventSet();
      iocObject.setEvents(eventSet);
      if (!Strings.isBlank(iocBean.create())) eventSet.setCreate(iocBean.create().trim().intern());
      if (!Strings.isBlank(iocBean.depose())) eventSet.setDepose(iocBean.depose().trim().intern());
      if (!Strings.isBlank(iocBean.fetch())) eventSet.setFetch(iocBean.fetch().trim().intern());

      // 处理字段(以@Inject方式,位于字段)
      List<String> fieldList = new ArrayList<String>();
      Mirror<?> mirror = Mirror.me(classZ);
      Field[] fields = mirror.getFields(Inject.class);
      for (Field field : fields) {
        Inject inject = field.getAnnotation(Inject.class);
        // 无需检查,因为字段名是唯一的
        // if(fieldList.contains(field.getName()))
        // throw duplicateField(classZ,field.getName());
        IocField iocField = new IocField();
        iocField.setName(field.getName());
        IocValue iocValue;
        if (Strings.isBlank(inject.value())) {
          iocValue = new IocValue();
          iocValue.setType(IocValue.TYPE_REFER);
          iocValue.setValue(field.getName());
        } else iocValue = convert(inject.value());
        iocField.setValue(iocValue);
        iocObject.addField(iocField);
        fieldList.add(iocField.getName());
      }
      // 处理字段(以@Inject方式,位于set方法)
      Method[] methods;
      try {
        methods = classZ.getMethods();
      } catch (Exception e) {
        // 如果获取失败,就忽略之
        log.info("Fail to call getMethods(), miss class or Security Limit, ignore it", e);
        methods = new Method[0];
      }
      for (Method method : methods) {
        Inject inject = method.getAnnotation(Inject.class);
        if (inject == null) continue;
        // 过滤特殊方法
        int m = method.getModifiers();
        if (Modifier.isAbstract(m) || (!Modifier.isPublic(m)) || Modifier.isStatic(m)) continue;
        String methodName = method.getName();
        if (methodName.startsWith("set")
            && methodName.length() > 3
            && method.getParameterTypes().length == 1) {
          IocField iocField = new IocField();
          iocField.setName(Strings.lowerFirst(methodName.substring(3)));
          if (fieldList.contains(iocField.getName()))
            throw duplicateField(classZ, iocField.getName());
          IocValue iocValue;
          if (Strings.isBlank(inject.value())) {
            iocValue = new IocValue();
            iocValue.setType(IocValue.TYPE_REFER);
            iocValue.setValue(Strings.lowerFirst(methodName.substring(3)));
          } else iocValue = convert(inject.value());
          iocField.setValue(iocValue);
          iocObject.addField(iocField);
          fieldList.add(iocField.getName());
        }
      }
      // 处理字段(以@IocBean.field方式)
      String[] flds = iocBean.fields();
      if (flds != null && flds.length > 0) {
        for (String fieldInfo : flds) {
          if (fieldList.contains(fieldInfo)) throw duplicateField(classZ, fieldInfo);
          IocField iocField = new IocField();
          if (fieldInfo.contains(":")) { // dao:jndi:dataSource/jdbc形式
            String[] datas = fieldInfo.split(":", 2);
            // 完整形式, 与@Inject完全一致了
            iocField.setName(datas[0]);
            iocField.setValue(convert(datas[1]));
            iocObject.addField(iocField);
          } else {
            // 基本形式, 引用与自身同名的bean
            iocField.setName(fieldInfo);
            IocValue iocValue = new IocValue();
            iocValue.setType(IocValue.TYPE_REFER);
            iocValue.setValue(fieldInfo);
            iocField.setValue(iocValue);
            iocObject.addField(iocField);
          }
          fieldList.add(iocField.getName());
        }
      }
    } else {
      if (log.isWarnEnabled()) {
        Field[] fields = classZ.getDeclaredFields();
        for (Field field : fields)
          if (field.getAnnotation(Inject.class) != null) {
            log.warnf(
                "class(%s) don't has @IocBean, but field(%s) has @Inject! Miss @IocBean ??",
                classZ.getName(), field.getName());
            break;
          }
      }
    }
  }
 @Test
 public void testIsMemberClass() throws Exception {
   for (Class<?> type : standardTypes) {
     assertThat(describe(type).isMemberClass(), is(type.isMemberClass()));
   }
 }
예제 #16
0
 private boolean isInnerClass(Class<?> clazz) {
   return clazz.isMemberClass() && !isStatic(clazz);
 }
예제 #17
0
 protected void basicValidate() {
   boolean isStatic = Modifier.isStatic(clazz.getModifiers());
   if (!isStatic && clazz.isMemberClass())
     throw new MappingException(
         "Cannot use non-static inner class: " + clazz + ". Please make static.");
 }
  @SuppressWarnings("rawtypes")
  @Test
  public void searchAndTest() {
    Reflections reflections = new Reflections("org.estatio.dom");

    System.out.println("EstatioDomainObjectContractTestAll_jdoAnnotations");

    Set<Class<? extends UdoDomainObject>> subtypes =
        reflections.getSubTypesOf(UdoDomainObject.class);
    for (Class<? extends UdoDomainObject> subtype : subtypes) {
      if (subtype.isAnonymousClass()
          || subtype.isLocalClass()
          || subtype.isMemberClass()
          || subtype.getName().endsWith("ForTesting")) {
        // skip (probably a testing class)
        continue;
      }
      if (UdoDomainObject.class == subtype || EstatioDomainObject.class == subtype) {
        // skip
        continue;
      }

      System.out.println(">>> " + subtype.getName());

      // must have a @PersistenceCapable(identityType=...) annotation
      final PersistenceCapable persistenceCapable = subtype.getAnnotation(PersistenceCapable.class);
      assertThat(
          "Class "
              + subtype.getName()
              + " inherits from EstatioDomainObject "
              + "but is not annotated with @PersistenceCapable",
          persistenceCapable,
          is(not(nullValue())));
      IdentityType identityType = persistenceCapable.identityType();
      assertThat(
          "Class "
              + subtype.getName()
              + " @PersistenceCapable annotation "
              + "does not specify the identityType",
          identityType,
          is(not(nullValue())));

      if (identityType == IdentityType.DATASTORE) {
        // NOT mandatory to have a @DatastoreIdentity, but if does, then @DatastoreIdentity(...,
        // column="id")
        final DatastoreIdentity datastoreIdentity = subtype.getAnnotation(DatastoreIdentity.class);
        if (datastoreIdentity != null) {
          assertThat(
              "Class "
                  + subtype.getName()
                  + " @DataStoreIdentity annotation does not specify column=\"id\"",
              datastoreIdentity.column(),
              is("id"));
        }
      }

      Inheritance inheritance = subtype.getAnnotation(Inheritance.class);

      if (inheritance != null && inheritance.strategy() == InheritanceStrategy.SUPERCLASS_TABLE) {
        // must NOT have a @Discriminator(..., column="discriminator")
        final Annotation[] declaredAnnotations = subtype.getDeclaredAnnotations();
        for (Annotation declaredAnnotation : declaredAnnotations) {
          if (declaredAnnotation.annotationType() == Discriminator.class) {
            Assert.fail(
                "Class "
                    + subtype.getName()
                    + " inherits from "
                    + subtype.getSuperclass().getName()
                    + "and has (incorrectly) been annotated with @Discriminator");
          }
        }

        // check if supertype has discriminator

        // must have a @Discriminator(..., column="discriminator") on one of its supertypes
        final Discriminator superDiscriminator =
            subtype.getSuperclass().getAnnotation(Discriminator.class);
        assertThat(
            "Class "
                + subtype.getSuperclass().getName()
                + " is inherited by "
                + subtype.getName()
                + "but is not annotated with @Discriminator",
            superDiscriminator,
            is(not(nullValue())));

        assertThat(
            "Class "
                + subtype.getName()
                + " @Discriminator annotation does not specify column=\"discriminator\"",
            superDiscriminator.column(),
            is("discriminator"));
      }

      if (subtype.getSuperclass().equals(UdoDomainObject.class)) {
        // must have a @Version(..., column="version")
        final Version version = getAnnotationOfTypeOfItsSupertypes(subtype, Version.class);

        assertThat(
            "Class "
                + subtype.getName()
                + " inherits from EstatioMutableObject "
                + "but is not annotated with @Version",
            version,
            is(not(nullValue())));

        assertThat(
            "Class "
                + subtype.getName()
                + " @Version annotation does not specify have column=\"version\"",
            version.column(),
            is("version"));
      }
    }
  }
  @SuppressWarnings({"rawtypes", "unchecked"})
  public static <T> ConstructorAccess<T> get(Class<T> type) {
    try {
      type.getConstructor((Class[]) null);
    } catch (Exception ex) {
      if (type.isMemberClass() && !Modifier.isStatic(type.getModifiers()))
        throw new RuntimeException(
            "Class cannot be created (non-static member class): " + type.getName());
      else
        throw new RuntimeException(
            "Class cannot be created (missing no-arg constructor): " + type.getName());
    }

    AccessClassLoader loader = AccessClassLoader.get(type);

    String className = type.getName();
    String accessClassName = className + "ConstructorAccess";
    if (accessClassName.startsWith("java.")) accessClassName = "reflectasm." + accessClassName;
    Class accessClass = null;
    try {
      accessClass = loader.loadClass(accessClassName);
    } catch (ClassNotFoundException ignored) {
    }
    if (accessClass == null) {
      String accessClassNameInternal = accessClassName.replace('.', '/');
      String classNameInternal = className.replace('.', '/');

      ClassWriter cw = new ClassWriter(0);
      cw.visit(
          V1_1,
          ACC_PUBLIC + ACC_SUPER,
          accessClassNameInternal,
          null,
          "com/esotericsoftware/reflectasm/ConstructorAccess",
          null);
      MethodVisitor mv;
      {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(
            INVOKESPECIAL, "com/esotericsoftware/reflectasm/ConstructorAccess", "<init>", "()V");
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
      }
      {
        mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "()Ljava/lang/Object;", null, null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, classNameInternal);
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "<init>", "()V");
        mv.visitInsn(ARETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
      }
      cw.visitEnd();
      byte[] data = cw.toByteArray();
      accessClass = loader.defineClass(accessClassName, data);
    }
    try {
      return (ConstructorAccess) accessClass.newInstance();
    } catch (Exception ex) {
      throw new RuntimeException(
          "Error constructing constructor access class: " + accessClassName, ex);
    }
  }