示例#1
0
  /**
   * @param entityManagerFactory the entity manager factory
   * @param jdbcAdaptor the JDBC Adaptor
   * @param metadata the metadata
   * @since $version
   * @author hceylan
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  public MetamodelImpl(
      EntityManagerFactoryImpl entityManagerFactory,
      JdbcAdaptor jdbcAdaptor,
      MetadataImpl metadata) {
    super();

    this.emf = entityManagerFactory;
    this.jdbcAdaptor = jdbcAdaptor;

    final List<ManagedTypeMetadata> entities = Lists.newArrayList(metadata.getEntityMappings());
    final List<ManagedTypeMetadata> sortedEntities = Lists.newArrayList();

    // sort so that the embeddables are first
    Collections.sort(
        entities,
        new Comparator<ManagedTypeMetadata>() {

          @Override
          public int compare(ManagedTypeMetadata o1, ManagedTypeMetadata o2) {
            if (o1 instanceof EmbeddableMetadata) {
              return -1;
            }

            if (o2 instanceof EmbeddableMetadata) {
              return 1;
            }

            return 0;
          }
        });

    // sort by inheritance
    try {
      while (entities.size() > 0) {
        for (final Iterator<ManagedTypeMetadata> i = entities.iterator(); i.hasNext(); ) {
          final ManagedTypeMetadata entity = i.next();
          final Class<?> c1 = this.emf.getClassloader().loadClass(entity.getClassName());

          boolean independent = true;
          for (final ManagedTypeMetadata entity2 : entities) {
            if (entity == entity2) {
              continue;
            }

            final Class<?> c2 = this.emf.getClassloader().loadClass(entity2.getClassName());

            if (c2.isAssignableFrom(c1)) {
              independent = false;
              break;
            }
          }

          if (independent) {
            i.remove();
            sortedEntities.add(entity);
          }
        }
      }
    } catch (final Exception e) {
    } // not possible at this stage

    for (final ManagedTypeMetadata type : sortedEntities) {
      try {
        final Class<?> clazz = this.emf.getClassloader().loadClass(type.getClassName());

        ManagedTypeImpl<?> parent = null;

        // locate the parent
        Class<?> currentClass = clazz.getSuperclass();
        while ((currentClass != Object.class) && (parent == null)) {
          parent = this.managedType(currentClass);
          currentClass = currentClass.getSuperclass();
        }

        if (type instanceof EntityMetadata) {
          // make sure it extends an identifiable type
          if ((parent != null) && !(parent instanceof IdentifiableTypeImpl)) {
            throw new MappingException(
                "Entities can only extend MappedSuperclasses or other Entities.",
                type.getLocator(),
                parent.getLocator());
          }

          final EntityTypeImpl entity =
              new EntityTypeImpl(this, (IdentifiableTypeImpl) parent, clazz, (EntityMetadata) type);

          this.entities.put(entity.getJavaType(), entity);
          this.entitiesByName.put(entity.getName(), entity);
          this.entitiesByName.put(entity.getJavaType().getName(), entity);
        } else if (type instanceof MappedSuperclassMetadata) {
          // make sure it extends a mapped superclass type
          if ((parent != null) && !(parent instanceof MappedSuperclassTypeImpl)) {
            throw new MappingException(
                "MappedSuperclasses can only extend other MappedSuperclasses.",
                type.getLocator(),
                parent.getLocator());
          }

          final MappedSuperclassTypeImpl mappedSuperclass =
              new MappedSuperclassTypeImpl(
                  this, (MappedSuperclassTypeImpl) parent, clazz, (MappedSuperclassMetadata) type);
          this.mappedSuperclasses.put(mappedSuperclass.getJavaType(), mappedSuperclass);
        }
        if (type instanceof EmbeddableMetadata) {
          // make sure it extends a embeddable type
          if ((parent != null) && !(parent instanceof EmbeddableTypeImpl)) {
            throw new MappingException(
                "Embeddables can only extend a other Embeddables.",
                type.getLocator(),
                parent.getLocator());
          }

          final EmbeddableTypeImpl embeddable =
              new EmbeddableTypeImpl(this, clazz, (EmbeddableMetadata) type);
          this.embeddables.put(embeddable.getJavaType(), embeddable);
        }

      } catch (final ClassNotFoundException e) {
      } // not possible at this time
    }

    this.callbackManager = new CallbackManager(metadata.getEntityListeners());

    this.addNamedQueries(metadata.getNamedQueries());
    for (final ManagedTypeMetadata entity : entities) {
      if (entity instanceof EntityMetadata) {
        this.addNamedQueries(((EntityMetadata) entity).getNamedQueries());
      }
    }
  }