/** * @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()); } } }