コード例 #1
0
  /**
   * Return all classes which extend our Command interface.
   *
   * @return
   */
  private Set<Class<? extends Command>> getCommandClasses() {
    if (commandClasses != null) return commandClasses;

    commandClasses = reflections.getSubTypesOf(Command.class);
    Set<Class<? extends BaseCommand>> baseCommandClasses =
        reflections.getSubTypesOf(BaseCommand.class);
    for (Class<? extends BaseCommand> bc : baseCommandClasses) {
      commandClasses.add((Class<? extends Command>) bc);
    }

    if (commandClasses == null || commandClasses.size() == 0) {
      log.severe("No command classes found, HSP will not be able to register commands!");
    }

    return commandClasses;
  }
コード例 #2
0
ファイル: SymbolTest.java プロジェクト: Nocky/OkapiBarcode
  /**
   * Finds all test resources and returns the information that JUnit needs to dynamically create the
   * corresponding test cases.
   *
   * @return the test data needed to dynamically create the test cases
   */
  @Parameters(name = "test {index}: {5}: {6}")
  public static List<Object[]> data() {

    String filter = System.getProperty("okapi.symbol.test");

    String backend = "uk.org.okapibarcode.backend";
    Reflections reflections = new Reflections(backend);
    Set<Class<? extends Symbol>> symbols = reflections.getSubTypesOf(Symbol.class);

    List<Object[]> data = new ArrayList<>();
    for (Class<? extends Symbol> symbol : symbols) {
      String symbolName = symbol.getSimpleName().toLowerCase();
      if (filter == null || filter.equals(symbolName)) {
        String dir = "src/test/resources/" + backend.replace('.', '/') + "/" + symbolName;
        for (File file : getPropertiesFiles(dir)) {
          String fileBaseName = file.getName().replaceAll(".properties", "");
          File codewordsFile = new File(file.getParentFile(), fileBaseName + ".codewords");
          File pngFile = new File(file.getParentFile(), fileBaseName + ".png");
          File errorFile = new File(file.getParentFile(), fileBaseName + ".error");
          data.add(
              new Object[] {
                symbol, file, codewordsFile, pngFile, errorFile, symbolName, fileBaseName
              });
        }
      }
    }

    return data;
  }
コード例 #3
0
  @Test
  public void testCommands() {

    Reflections reflections = new Reflections("com.greatmancode.craftconomy3.commands");
    for (Class<? extends CommandExecutor> clazz :
        reflections.getSubTypesOf(CommandExecutor.class)) {
      try {
        CommandExecutor instance = clazz.newInstance();
        if (instance.help() == null) {
          fail("Help is null for: " + clazz.getName());
        }
        if (instance.maxArgs() < 0) {
          fail("Fail maxArgs for class: " + clazz.getName());
        }
        if (instance.minArgs() < 0) {
          fail("Fail minArgs for class: " + clazz.getName());
        }
        if (instance.maxArgs() < instance.minArgs()) {
          fail("Fail maxArgs less than minArgs for class:" + clazz.getName());
        }
        if (instance.getPermissionNode() != null) {
          if (!instance.getPermissionNode().contains("craftconomy")) {
            fail("Fail permissionNode for class: " + clazz.getName());
          }
        }
        if (!instance.playerOnly() && instance.playerOnly()) {
          fail("Fail playerOnly. Should never get this..");
        }
      } catch (InstantiationException e) {
        fail(e.getMessage());
      } catch (IllegalAccessException e) {
        fail(e.getMessage());
      }
    }
  }
コード例 #4
0
 public Set<String> findServiceImplementations(
     Class<?> serviceClass, ClassLoader classpathResourceLoader) {
   return ImmutableSet.copyOf(
       transform(
           intersection(
               reflections.getTypesAnnotatedWith(markerAnnotation),
               reflections.getSubTypesOf(serviceClass)),
           new ClassToName()));
 }
コード例 #5
0
  private List<Class<? extends Job>> getJobClasses(Class annotation) {
    Set<Class<? extends Job>> jobs =
        (Set<Class<? extends Job>>) reflections.getSubTypesOf(Job.class);
    Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(annotation);

    return Sets.intersection(new HashSet<Class<? extends Job>>(jobs), annotatedClasses)
        .immutableCopy()
        .asList();
  }
コード例 #6
0
 private Class<? extends JobConfiguration> getJobConfigurationClass(String type) {
   Set<Class<? extends JobConfiguration>> subTypes =
       reflections.getSubTypesOf(JobConfiguration.class);
   return subTypes
       .stream()
       .filter(clazz -> clazz.getSimpleName().toUpperCase().contains(type))
       .findFirst()
       .orElseThrow(() -> new InvalidPropertyException("Unsupported job type " + type));
 }
コード例 #7
0
 static {
   final Reflections reflections = new Reflections("uk.ac.ebi.interpro.scan.model");
   final Set<Class<? extends Match>> allClasses = reflections.getSubTypesOf(Match.class);
   for (Class clazz : allClasses) {
     if (!Modifier.isAbstract(clazz.getModifiers())) { // Concrete only.
       CONCRETE_MATCH_CLASSES.add(clazz.getSimpleName());
     }
   }
 }
コード例 #8
0
  @Programmatic
  @Override
  public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T> type) {
    Vfs.setDefaultURLTypes(getUrlTypes());

    final Reflections reflections =
        new Reflections(
            ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader()),
            ClasspathHelper.forClass(Object.class),
            new SubTypesScanner(false));
    return reflections.getSubTypesOf(type);
  }
コード例 #9
0
  @Parameterized.Parameters
  public static Collection<Class<? extends CompoundPredicate>>
      getCompoundPredicateImplementations() {
    // locate all classes which implement CompoundPredicate and exercise them
    Reflections reflections =
        new Reflections(
            new ConfigurationBuilder()
                .forPackages("com.hazelcast.query.impl.predicates")
                .addScanners(new SubTypesScanner())
                .build());

    return reflections.getSubTypesOf(CompoundPredicate.class);
  }
コード例 #10
0
ファイル: FoxBot.java プロジェクト: GunfighterJ/FoxBot
  private void registerCommands() {
    try {
      for (Class clazz : reflections.getSubTypesOf(Command.class)) {
        ClassLoader.getSystemClassLoader().loadClass(clazz.getName());
        Constructor clazzConstructor = clazz.getConstructor(this.getClass());
        Command command = (Command) clazzConstructor.newInstance(this);

        this.getPluginManager().registerCommand(command);
      }
    } catch (Exception ex) {
      // This can never happen.
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    }
  }
コード例 #11
0
  public DisambiguationExtractorFactory() throws InstantiationException, IllegalAccessException {

    nameToId = new HashMap<String, String>();
    idToName = new IdentityHashMap<String, String>();

    Reflections reflections = new Reflections(THIS_PACKAGE);

    Set<Class<? extends DisambiguationExtractor>> classes =
        reflections.getSubTypesOf(DisambiguationExtractor.class);

    @SuppressWarnings("unchecked")
    Class<? extends DisambiguationExtractor>[] ar = classes.toArray(new Class[classes.size()]);

    String name, eid;
    for (Class<? extends DisambiguationExtractor> c : ar) {
      name = c.getSimpleName();

      // if this is not extractor
      if (!name.startsWith("EX_")) {
        continue;
      }

      DisambiguationExtractor e = c.newInstance();
      eid = e.getId();

      // all extractors must have id
      if (eid == null || eid.isEmpty()) {
        String m = "Creating extractor: " + name + " with no id value given (null).";
        logger.error(m);
        throw new IllegalStateException(m);
      }

      nameToId.put(name, eid);

      // checking, if every extractors has unique id
      if (idToName.containsKey(eid)) {
        String m =
            "Some extractors have the same id: "
                + eid
                + ": "
                + name
                + ", "
                + idToName.get(eid)
                + ".";
        logger.error(m);
        throw new IllegalStateException(m);
      }
      idToName.put(eid, name);
    }
  }
コード例 #12
0
ファイル: PackageInspector.java プロジェクト: kvg/INDIANA
  /**
   * Get the set of classes that extend the specified type.
   *
   * @return the set of classes that extend the type
   */
  public Set<Class<? extends ClassType>> getExtendingClasses() {
    Set<Class<? extends ClassType>> extendingClasses = reflections.getSubTypesOf(classType);
    Set<Class<? extends ClassType>> nonAbstractClasses = new HashSet<Class<? extends ClassType>>();

    for (Class<? extends ClassType> c : extendingClasses) {
      if (!Modifier.isAbstract(c.getModifiers())) {
        if (c.getPackage().getName().contains(packageName)) {
          nonAbstractClasses.add(c);
        }
      }
    }

    return nonAbstractClasses;
  }
コード例 #13
0
 /** 找到所有的子类,不包括接口 */
 @SuppressWarnings("unchecked")
 public <T> List<Class<? extends T>> findSubClass(final Class<T> classInterface) {
   Set<Class<? extends T>> classSet = reflections.getSubTypesOf(classInterface);
   List<Class<? extends T>> classList = Lists.newArrayList();
   for (Class<? extends T> clazz : classSet) {
     int modifier = clazz.getModifiers();
     if (classInterface.isAssignableFrom(clazz)
         && !Modifier.isInterface(modifier)
         && !Modifier.isAbstract(modifier)
         && Modifier.isPublic(modifier)) {
       classList.add(clazz);
     }
   }
   return classList;
 }
コード例 #14
0
  public static <T extends Object> Set<Class<? extends T>> getSubTypesOfInterface(
      Class<T> interficie) throws Exception {

    Set<Class<? extends T>> implementations;
    implementations = (Set<Class<? extends T>>) classesCache.get(interficie);

    if (implementations == null) {
      implementations = new HashSet<Class<? extends T>>();
      Reflections ref = getReflections();
      Set<Class<? extends T>> tmp = ref.getSubTypesOf(interficie);
      implementations.addAll(tmp);
      classesCache.put(interficie, implementations);
    }

    return implementations;
  }
コード例 #15
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));
        }
      }
    }
  }
コード例 #16
0
  /*
   * Scan the classpath looking for JAX-RS Application sub-classes
   */
  private static Set<Class<? extends Application>> findJaxrsApplicationClasses() {
    logger.info("Scanning classpath to find JAX-RS Application classes");

    final Collection<URL> systemPropertyURLs = ClasspathHelper.forJavaClassPath();
    final Collection<URL> classLoaderURLs = ClasspathHelper.forClassLoader();

    Set<URL> classpathURLs = new HashSet<URL>();

    copyValidClasspathEntries(systemPropertyURLs, classpathURLs);
    copyValidClasspathEntries(classLoaderURLs, classpathURLs);

    logger.debug("Classpath URLs to be scanned: " + classpathURLs);

    Reflections reflections = new Reflections(classpathURLs, new SubTypesScanner());

    return reflections.getSubTypesOf(Application.class);
  }
コード例 #17
0
ファイル: ModuleController.java プロジェクト: bcorrigan/Goat
  /**
   * Build the list of all public classes in package goat.module.
   *
   * <p>This gets sort of ugly. It sure would be nice if the java reflection API could give us a
   * list of all classes in a package, wouldn't it?
   */
  private void buildAllModulesList() {
    if (bot.isTesting()) return;

    Reflections reflections = new Reflections("goat");
    Set<Class<? extends Module>> allModules = reflections.getSubTypesOf(Module.class);

    ArrayList<String> tempList = new ArrayList<String>();
    for (Class<? extends Module> modClass : allModules) {
      tempList.add(modClass.getName());
    }
    Collections.sort(tempList);
    System.out.println("Available Modules: ");
    for (String modName : tempList) {
      System.out.println("   " + modName);
    }
    System.out.println();
  }
コード例 #18
0
  /**
   * Scans an internal Katharsis package for controllers and then instantiates them.
   *
   * @return an instance of {@link ControllerRegistry} with initialized controllers
   * @throws Exception initialization exception
   */
  public ControllerRegistry build() throws Exception {

    Reflections reflections = new Reflections("io.katharsis.dispatcher.controller");

    Set<Class<? extends BaseController>> controllerClasses =
        reflections.getSubTypesOf(BaseController.class);

    List<BaseController> controllers = new LinkedList<>();
    for (Class<? extends BaseController> controllerClass : controllerClasses) {
      if (!Modifier.isAbstract(controllerClass.getModifiers())) {
        BaseController controller = getController(controllerClass);
        controllers.add(controller);
      }
    }

    return new ControllerRegistry(controllers);
  }
コード例 #19
0
ファイル: SSDManager.java プロジェクト: CarsomyrJ/SSDPlayer
  /**
   * Initialize SSD manager using given configuration
   *
   * @param xmlGetter - configuration getter
   */
  public static void initializeManager(XMLGetter xmlGetter) {
    if (managersMap == null) {
      Reflections reflections = new Reflections(SSDManager.class.getPackage().getName());
      // We use here raw type and do the casting in order for the code to compile.
      @SuppressWarnings("rawtypes")
      Set<Class<? extends SSDManager>> subTypesAux = reflections.getSubTypesOf(SSDManager.class);
      Object auxObj = subTypesAux;
      @SuppressWarnings("unchecked")
      Set<Class<? extends SSDManager<?, ?, ?, ?, ?>>> subTypes =
          (Set<Class<? extends SSDManager<?, ?, ?, ?, ?>>>) auxObj;

      Map<String, SSDManager<?, ?, ?, ?, ?>> managers =
          new HashMap<String, SSDManager<?, ?, ?, ?, ?>>();
      Map<String, SSDManager<?, ?, ?, ?, ?>> simulators =
          new HashMap<String, SSDManager<?, ?, ?, ?, ?>>();
      for (Class<? extends SSDManager<?, ?, ?, ?, ?>> clazz : subTypes) {
        if (!Modifier.isAbstract(clazz.getModifiers())) {
          try {
            System.out.println("Initializing " + clazz.getSimpleName());
            SSDManager<?, ?, ?, ?, ?> manager = clazz.newInstance();
            manager.initValues(xmlGetter);
            if (manager instanceof VisualizationSSDManager) {
              simulators.put(manager.getManagerName(), manager);
              simulatorsList.add(manager.getManagerName());
            } else {
              managers.put(manager.getManagerName(), manager);
              managersList.add(manager.getManagerName());
            }
            manager.statisticsGetters = manager.initStatisticsGetters();
            System.out.println(
                "Finished initializing "
                    + clazz.getSimpleName()
                    + " - "
                    + manager.getManagerName());
          } catch (Throwable e) {
            e.printStackTrace();
          }
        }
      }
      Collections.sort(simulatorsList);
      Collections.sort(managersList);
      managersMap = managers;
      simulatorsMap = simulators;
    }
  }
コード例 #20
0
ファイル: PluginManager.java プロジェクト: johandahlberg/gatk
  /**
   * Create a new plugin manager.
   *
   * @param pluginType Core type for a plugin.
   * @param pluginCategory Provides a category name to the plugin. Must not be null.
   * @param pluginSuffix Provides a suffix that will be trimmed off when converting to a plugin
   *     name. Can be null.
   * @param classpath Custom class path to search for classes.
   */
  public PluginManager(
      Class pluginType, String pluginCategory, String pluginSuffix, List<URL> classpath) {
    this.pluginCategory = pluginCategory;
    this.pluginSuffix = pluginSuffix;

    this.plugins = new ArrayList<Class<? extends PluginType>>();
    this.interfaces = new ArrayList<Class<? extends PluginType>>();

    Reflections reflections;
    if (classpath == null) {
      reflections = defaultReflections;
    } else {
      addClasspath(classpath);
      reflections =
          new Reflections(
              new ConfigurationBuilder().setUrls(classpath).setScanners(new SubTypesScanner()));
    }

    // Load all classes types filtering them by concrete.
    @SuppressWarnings("unchecked")
    Set<Class<? extends PluginType>> allTypes = reflections.getSubTypesOf(pluginType);
    for (Class<? extends PluginType> type : allTypes) {
      // The plugin manager does not support anonymous classes; to be a plugin, a class must have a
      // name.
      if (JVMUtils.isAnonymous(type)) continue;

      if (JVMUtils.isConcrete(type)) plugins.add(type);
      else interfaces.add(type);
    }

    pluginsByName = new TreeMap<String, Class<? extends PluginType>>();
    for (Class<? extends PluginType> pluginClass : plugins) {
      String pluginName = getName(pluginClass);
      pluginsByName.put(pluginName, pluginClass);
    }

    // sort the plugins so the order of elements is deterministic
    sortPlugins(plugins);
    sortPlugins(interfaces);
  }
コード例 #21
0
 private void loadMessages() {
   final Reflections reflections = new Reflections();
   final Set<Class<? extends MessageQueueData>> subTypes =
       reflections.getSubTypesOf(MessageQueueData.class);
   subTypes.forEach(this::loadMessageClass);
 }
コード例 #22
0
ファイル: ModuleManager.java プロジェクト: vemacs/SkypeBot
  public static void loadModules(String modulePackage) {
    Reflections r = new Reflections(modulePackage);
    Set<Class<? extends Module>> classes = r.getSubTypesOf(Module.class);

    classes.forEach(ModuleManager::registerModule);
  }
コード例 #23
0
  private static Set<Class<? extends Bug>> getAllBugsInPackage() {
    Reflections reflections = new Reflections(BugsFactory.class.getPackage().getName());

    return reflections.getSubTypesOf(Bug.class);
  }
コード例 #24
0
  @Override
  public void beforeStart(final Application application) {
    final Reflections reflections =
        new Reflections(
            new ConfigurationBuilder()
                .filterInputsBy(new FilterBuilder.Exclude(FilterBuilder.prefix("com.google")))
                .addUrls(ClasspathHelper.forClassLoader(application.classloader()))
                .addScanners(new SubTypesScanner()));

    // automatic Guice module detection
    Set<Class<? extends AbstractModule>> guiceModules =
        reflections.getSubTypesOf(AbstractModule.class);
    for (Class<? extends Module> moduleClass : guiceModules) {
      try {
        if (!moduleClass.isAnonymousClass()) {
          modules.add(moduleClass.newInstance());
        }
      } catch (InstantiationException e) {
        throw Throwables.propagate(e);
      } catch (IllegalAccessException e) {
        throw Throwables.propagate(e);
      }
    }

    modules.add(
        new AbstractModule() {
          @Override
          protected void configure() {
            bind(Application.class).toInstance(application);
            bind(Reflections.class).toInstance(reflections);

            Names.bindProperties(
                this.binder(),
                fromKeys(
                    application.configuration().keys(),
                    new Function<String, String>() {
                      @Override
                      public String apply(String key) {
                        // remove after https://play.lighthouseapp.com/projects/82401/tickets/372 is
                        // fixed
                        if (key.contains("akka")) return null;

                        return application.configuration().getString(key);
                      }
                    }));

            for (Class<? extends Controller> controllerClass :
                reflections.getSubTypesOf(Controller.class)) {
              requestStaticInjection(controllerClass);
            }

            // bind all services
            Multibinder<Service> serviceBinder = Multibinder.newSetBinder(binder(), Service.class);
            for (Class<? extends Service> serviceImplClass :
                reflections.getSubTypesOf(AbstractService.class)) {
              serviceBinder.addBinding().to(serviceImplClass).asEagerSingleton();
            }
            for (Class<? extends Service> serviceImplClass :
                reflections.getSubTypesOf(AbstractIdleService.class)) {
              serviceBinder.addBinding().to(serviceImplClass).asEagerSingleton();
            }
            for (Class<? extends Service> serviceImplClass :
                reflections.getSubTypesOf(AbstractExecutionThreadService.class)) {
              serviceBinder.addBinding().to(serviceImplClass).asEagerSingleton();
            }

            // bind actor - todo use reflections for this

            // start/stop services after injection and on shutdown of the Play app
            bindListener(
                MoreMatchers.subclassesOf(Service.class),
                new TypeListener() {
                  @Override
                  public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
                    typeEncounter.register(
                        new InjectionListener<I>() {
                          @Override
                          public void afterInjection(final I i) {
                            onStartListeners.add(
                                new OnStartListener() {
                                  @Override
                                  public void onApplicationStart(
                                      Application application, Injector injector) {
                                    Logger.info(String.format("Starting %s", i.toString()));
                                    ((Service) i).start();

                                    onStopListeners.add(
                                        new OnStopListener() {
                                          @Override
                                          public void onApplicationStop(Application application) {
                                            Logger.info(String.format("Stopping %s", i.toString()));
                                            ((Service) i).stop();
                                          }
                                        });
                                  }
                                });
                          }
                        });
                  }
                });
          }
        });
  }
コード例 #25
0
 private InterfaceAndImplementations findImplementationForInterface(Class theInterface) {
   return new InterfaceAndImplementations(
       theInterface, (Set<Class>) reflections.getSubTypesOf(theInterface));
 }
コード例 #26
0
ファイル: Utility.java プロジェクト: gdos/jace
 public static Set<Class> findAllSubclasses(Class clazz) {
   return reflections.getSubTypesOf(clazz);
 }
コード例 #27
0
  @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"));
      }
    }
  }