@Override
  @SuppressWarnings({"unchecked"})
  public void prepare(MetadataSources sources) {
    // create a jandex index from the annotated classes
    Indexer indexer = new Indexer();
    for (Class<?> clazz : sources.getAnnotatedClasses()) {
      indexClass(indexer, clazz.getName().replace('.', '/') + ".class");
    }

    // add package-info from the configured packages
    for (String packageName : sources.getAnnotatedPackages()) {
      indexClass(indexer, packageName.replace('.', '/') + "/package-info.class");
    }

    index = indexer.complete();

    List<JaxbRoot<XMLEntityMappings>> mappings = new ArrayList<JaxbRoot<XMLEntityMappings>>();
    for (JaxbRoot<?> root : sources.getJaxbRootList()) {
      if (root.getRoot() instanceof XMLEntityMappings) {
        mappings.add((JaxbRoot<XMLEntityMappings>) root);
      }
    }
    if (!mappings.isEmpty()) {
      // process the xml configuration
      final OrmXmlParser ormParser = new OrmXmlParser(metadata);
      index = ormParser.parseAndUpdateIndex(mappings, index);
    }

    if (index.getAnnotations(PseudoJpaDotNames.DEFAULT_DELIMITED_IDENTIFIERS) != null) {
      metadata.setGloballyQuotedIdentifiers(true);
    }
  }
  @Override
  public void bindMappingMetadata(MetadataSources sources, List<String> processedEntityNames) {
    AnnotationBindingContext context =
        new AnnotationBindingContext(index, metadata.getServiceRegistry());
    // need to order our annotated entities into an order we can process
    Set<ConfiguredClassHierarchy<EntityClass>> hierarchies =
        ConfiguredClassHierarchyBuilder.createEntityHierarchies(context);

    // now we process each hierarchy one at the time
    Hierarchical parent = null;
    for (ConfiguredClassHierarchy<EntityClass> hierarchy : hierarchies) {
      for (EntityClass entityClass : hierarchy) {
        // for classes annotated w/ @Entity we create a EntityBinding
        if (ConfiguredClassType.ENTITY.equals(entityClass.getConfiguredClassType())) {
          LOG.bindingEntityFromAnnotatedClass(entityClass.getName());
          EntityBinder entityBinder = new EntityBinder(metadata, entityClass, parent);
          EntityBinding binding = entityBinder.bind();
          parent = binding.getEntity();
        }
        // for classes annotated w/ @MappedSuperclass we just create the domain instance
        // the attribute bindings will be part of the first entity subclass
        else if (ConfiguredClassType.MAPPED_SUPERCLASS.equals(
            entityClass.getConfiguredClassType())) {
          parent = new Superclass(entityClass.getName(), parent);
        }
        // for classes which are not annotated at all we create the NonEntity domain class
        // todo - not sure whether this is needed. It might be that we don't need this information
        // (HF)
        else {
          parent = new NonEntity(entityClass.getName(), parent);
        }
      }
    }
  }
 private static void bind(MetadataImpl metadata, AnnotationInstance fetchProfile) {
   String name = JandexHelper.getValueAsString(fetchProfile, "name");
   Set<Fetch> fetches = new HashSet<Fetch>();
   for (AnnotationInstance override :
       JandexHelper.getValueAsArray(fetchProfile, "fetchOverrides")) {
     FetchMode fetchMode = JandexHelper.getValueAsEnum(override, "mode", FetchMode.class);
     if (!fetchMode.equals(org.hibernate.annotations.FetchMode.JOIN)) {
       throw new MappingException("Only FetchMode.JOIN is currently supported");
     }
     fetches.add(
         new Fetch(
             JandexHelper.getValueAsString(override, "entity"),
             JandexHelper.getValueAsString(override, "association"),
             fetchMode.toString().toLowerCase()));
   }
   metadata.addFetchProfile(new FetchProfile(name, fetches));
 }
 private ClassLoaderService classLoaderService() {
   if (classLoaderService == null) {
     classLoaderService = metadata.getServiceRegistry().getService(ClassLoaderService.class);
   }
   return classLoaderService;
 }