[hibernate-commits] Hibernate SVN: r17254 - in core/trunk/entitymanager/src/main/java/org/hibernate/ejb: metamodel and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sun Aug 9 14:04:35 EDT 2009


Author: epbernard
Date: 2009-08-09 14:04:35 -0400 (Sun, 09 Aug 2009)
New Revision: 17254

Added:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java
Modified:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java
Log:
EJB-456 have the implementation of Metamodel ready minus some concepts left behind. This has NOT been tested to don't be too excited ladies

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java	2009-08-09 12:54:15 UTC (rev 17253)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -712,7 +712,8 @@
 					cfg.buildSessionFactory(),
 					transactionType,
 					discardOnClose,
-					getSessionInterceptorClass( cfg.getProperties() )
+					getSessionInterceptorClass( cfg.getProperties() ),
+					cfg
 			);
 		}
 		catch (HibernateException e) {

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java	2009-08-09 12:54:15 UTC (rev 17253)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -3,6 +3,7 @@
 
 import java.util.Map;
 import java.util.Set;
+import java.util.Iterator;
 import java.io.Serializable;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContextType;
@@ -12,28 +13,36 @@
 import javax.persistence.spi.PersistenceUnitTransactionType;
 
 import org.hibernate.SessionFactory;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.cfg.Configuration;
 import org.hibernate.ejb.criteria.QueryBuilderImpl;
+import org.hibernate.ejb.metamodel.MetamodelImpl;
 
 /**
  * @author Gavin King
  * @author Emmanuel Bernard
  */
 public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
-	private SessionFactory sessionFactory;
-	private PersistenceUnitTransactionType transactionType;
-	private boolean discardOnClose;
-	private Class sessionInterceptorClass;
-	private QueryBuilderImpl criteriaQueryBuilder;
+	private final SessionFactory sessionFactory;
+	private final PersistenceUnitTransactionType transactionType;
+	private final boolean discardOnClose;
+	private final Class sessionInterceptorClass;
+	private final QueryBuilderImpl criteriaQueryBuilder;
+	private final Metamodel metamodel;
 
 	public EntityManagerFactoryImpl(
 			SessionFactory sessionFactory,
 			PersistenceUnitTransactionType transactionType,
 			boolean discardOnClose,
-			Class sessionInterceptorClass) {
+			Class<?> sessionInterceptorClass,
+			Configuration cfg) {
 		this.sessionFactory = sessionFactory;
 		this.transactionType = transactionType;
 		this.discardOnClose = discardOnClose;
 		this.sessionInterceptorClass = sessionInterceptorClass;
+		@SuppressWarnings( "unchecked" )
+		final Iterator<PersistentClass> classes = cfg.getClassMappings();
+		this.metamodel = new MetamodelImpl( classes );
 		this.criteriaQueryBuilder = new QueryBuilderImpl( this );
 	}
 
@@ -54,8 +63,7 @@
 	}
 
 	public Metamodel getMetamodel() {
-		//FIXME
-		return null;  //To change body of implemented methods use File | Settings | File Templates.
+		return metamodel;  //To change body of implemented methods use File | Settings | File Templates.
 	}
 
 	public void close() {

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,26 @@
+package org.hibernate.ejb.metamodel;
+
+import java.io.Serializable;
+import javax.persistence.metamodel.BasicType;
+import javax.persistence.metamodel.Type;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class BasicTypeImpl<X> implements BasicType<X>, Serializable {
+	private final Class<X> clazz;
+	private PersistenceType persistenceType;
+
+	public PersistenceType getPersistenceType() {
+		return persistenceType;
+	}
+
+	public Class<X> getJavaType() {
+		return clazz;
+	}
+
+	public BasicTypeImpl(Class<X> clazz, PersistenceType persistenceType) {
+		this.clazz = clazz;
+		this.persistenceType = persistenceType;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,21 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.Iterator;
+import java.io.Serializable;
+import javax.persistence.metamodel.EmbeddableType;
+import javax.persistence.metamodel.Type;
+
+import org.hibernate.mapping.Property;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EmbeddableTypeImpl<X> extends ManagedTypeImpl<X> implements EmbeddableType<X>, Serializable {
+	EmbeddableTypeImpl(Class<X> clazz, Iterator<Property> properties, MetadataContext context) {
+		super(clazz, properties, context);
+	}
+
+	public PersistenceType getPersistenceType() {
+		return PersistenceType.EMBEDDABLE;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,196 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.Set;
+import java.io.Serializable;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.IdentifiableType;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.Type;
+
+/**
+ * Delegate to an other EntityType<X>
+ * Helps break infinite loops when creating entity metamodel related to each other
+ * 
+ * @author Emmanuel Bernard
+ */
+public class EntityTypeDelegator<X> implements EntityType<X>, Serializable {
+	private volatile EntityType<X> delegate;
+
+	void setDelegate(EntityType<X> delegate) {
+		this.delegate = delegate;
+	}
+
+	public String getName() {
+		return delegate.getName();
+	}
+
+	public <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
+		return delegate.getId( type );
+	}
+
+	public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
+		return delegate.getVersion( type );
+	}
+
+	public <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> type) {
+		return delegate.getDeclaredId( type );
+	}
+
+	public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
+		return delegate.getDeclaredVersion( type );
+	}
+
+	public IdentifiableType<? super X> getSupertype() {
+		return delegate.getSupertype();
+	}
+
+	public boolean hasSingleIdAttribute() {
+		return delegate.hasSingleIdAttribute();
+	}
+
+	public boolean hasVersionAttribute() {
+		return delegate.hasVersionAttribute();
+	}
+
+	public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
+		return delegate.getIdClassAttributes();
+	}
+
+	public Type<?> getIdType() {
+		return delegate.getIdType();
+	}
+
+	public Set<Attribute<? super X, ?>> getAttributes() {
+		return delegate.getAttributes();
+	}
+
+	public Set<Attribute<X, ?>> getDeclaredAttributes() {
+		return delegate.getDeclaredAttributes();
+	}
+
+	public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
+		return delegate.getSingularAttribute( name, type );
+	}
+
+	public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> type) {
+		return delegate.getDeclaredSingularAttribute( name, type );
+	}
+
+	public Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
+		return delegate.getSingularAttributes();
+	}
+
+	public Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
+		return delegate.getDeclaredSingularAttributes();
+	}
+
+	public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
+		return delegate.getCollection( name, elementType );
+	}
+
+	public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
+		return delegate.getSet( name, elementType );
+	}
+
+	public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
+		return delegate.getList( name, elementType );
+	}
+
+	public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, Class<V> valueType) {
+		return delegate.getMap( name, keyType, valueType );
+	}
+
+	public <E> CollectionAttribute<X, E> getDeclaredCollection(String name, Class<E> elementType) {
+		return delegate.getDeclaredCollection( name, elementType );
+	}
+
+	public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
+		return delegate.getDeclaredSet( name, elementType );
+	}
+
+	public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
+		return delegate.getDeclaredList( name, elementType );
+	}
+
+	public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, Class<V> valueType) {
+		return delegate.getDeclaredMap( name, keyType, valueType );
+	}
+
+	public Set<PluralAttribute<? super X, ?, ?>> getCollections() {
+		return delegate.getCollections();
+	}
+
+	public Set<PluralAttribute<X, ?, ?>> getDeclaredCollections() {
+		return delegate.getDeclaredCollections();
+	}
+
+	public Attribute<? super X, ?> getAttribute(String name) {
+		return delegate.getAttribute( name );
+	}
+
+	public Attribute<X, ?> getDeclaredAttribute(String name) {
+		return delegate.getDeclaredAttribute( name );
+	}
+
+	public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
+		return delegate.getSingularAttribute( name );
+	}
+
+	public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
+		return delegate.getDeclaredSingularAttribute( name );
+	}
+
+	public CollectionAttribute<? super X, ?> getCollection(String name) {
+		return delegate.getCollection( name );
+	}
+
+	public SetAttribute<? super X, ?> getSet(String name) {
+		return delegate.getSet( name );
+	}
+
+	public ListAttribute<? super X, ?> getList(String name) {
+		return delegate.getList( name );
+	}
+
+	public MapAttribute<? super X, ?, ?> getMap(String name) {
+		return delegate.getMap( name );
+	}
+
+	public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
+		return delegate.getDeclaredCollection( name );
+	}
+
+	public SetAttribute<X, ?> getDeclaredSet(String name) {
+		return delegate.getDeclaredSet( name );
+	}
+
+	public ListAttribute<X, ?> getDeclaredList(String name) {
+		return delegate.getDeclaredList( name );
+	}
+
+	public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
+		return delegate.getDeclaredMap( name );
+	}
+
+	public PersistenceType getPersistenceType() {
+		return delegate.getPersistenceType();
+	}
+
+	public Class<X> getJavaType() {
+		return delegate.getJavaType();
+	}
+
+	public BindableType getBindableType() {
+		return delegate.getBindableType();
+	}
+
+	public Class<X> getBindableJavaType() {
+		return delegate.getBindableJavaType();
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,164 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.io.Serializable;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.IdentifiableType;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.Type;
+
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EntityTypeImpl<X> extends ManagedTypeImpl<X> implements EntityType<X>, Serializable {
+
+	private final SingularAttribute<X, ?> id;
+	private final SingularAttribute<X, ?> version;
+	private final String className;
+	private final boolean hasIdentifierProperty;
+	private final boolean isVersioned;
+	private final Set<SingularAttribute<? super X,?>> idClassAttributes;
+	private final IdentifiableType<? super X> supertype;
+
+	public EntityTypeImpl(Class<X> clazz, PersistentClass persistentClass, MetadataContext context) {
+		super(clazz, (Iterator<Property>) persistentClass.getPropertyIterator(), context );
+		this.className = persistentClass.getClassName();
+		this.hasIdentifierProperty = persistentClass.hasIdentifierProperty();
+		this.isVersioned = persistentClass.isVersioned();
+		id = buildIdAttribute( persistentClass );
+		version = buildVersionAttribute( persistentClass );
+		final Set<SingularAttribute<? super X, ?>> attributes = buildIdClassAttributes( persistentClass, context );
+		this.idClassAttributes = attributes != null ? Collections.unmodifiableSet( attributes ) : null;
+
+		PersistentClass superPersistentClass = persistentClass.getSuperclass();
+		if ( superPersistentClass == null ) {
+			supertype = null;
+		}
+		else {
+			final Class<?> superclass = superPersistentClass.getMappedClass();
+			final EntityTypeDelegator<X> entityTypeDelegator = new EntityTypeDelegator<X>();
+			context.addDelegator( entityTypeDelegator, superclass );
+			supertype = entityTypeDelegator;
+		}
+	}
+
+	private <A> SingularAttribute<X, A> buildIdAttribute(PersistentClass persistentClass) {
+		final Property identifierProperty = persistentClass.getIdentifierProperty();
+		@SuppressWarnings( "unchecked" )
+		Class<A> idClass = identifierProperty.getType().getReturnedClass();
+		final Type<A> attrType = new BasicTypeImpl<A>( idClass,
+														identifierProperty.isComposite() ?
+																PersistenceType.EMBEDDABLE :
+																PersistenceType.BASIC);
+		return SingularAttributeImpl.create(this, attrType )
+										.property(identifierProperty)
+										//.member( null ) //TODO member
+										.id()
+										.build();
+	}
+
+	private <A> SingularAttribute<X, A> buildVersionAttribute(PersistentClass persistentClass) {
+		if ( persistentClass.isVersioned() ) {
+			@SuppressWarnings( "unchecked" )
+			Class<A> versionClass = persistentClass.getVersion().getType().getReturnedClass();
+			Property property = persistentClass.getVersion();
+			final Type<A> attrType = new BasicTypeImpl<A>( versionClass, PersistenceType.BASIC);
+			return SingularAttributeImpl.create(this, attrType )
+										.property(property)
+										//.member( null ) //TODO member
+										.version()
+										.build();
+		}
+		else {
+			return null;
+		}
+	}
+
+	private Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(PersistentClass persistentClass, MetadataContext context) {
+		if ( hasSingleIdAttribute() ) {
+			return null;
+		}
+		@SuppressWarnings( "unchecked")
+		Iterator<Property> properties = persistentClass.getIdentifierMapper().getPropertyIterator();
+		Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
+		while ( properties.hasNext() ) {
+			attributes.add(
+					(SingularAttribute<? super X, ?>) MetamodelFactory.getAttribute( this, properties.next(), context )
+			);
+		}
+		return attributes;
+	}
+
+	public String getName() {
+		return className;
+	}
+
+	public <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
+		//TODO check that type and id.getJavaType() are related
+		@SuppressWarnings( "unchecked")
+		final SingularAttribute<? super X, Y> result = ( SingularAttribute<? super X, Y> ) id;
+		return result;
+	}
+
+	public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
+		//TODO check that type and version.getJavaType() are related
+		@SuppressWarnings( "unchecked")
+		final SingularAttribute<? super X, Y> result = ( SingularAttribute<? super X, Y> ) version;
+		return result;
+	}
+
+	public <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> type) {
+		//TODO check that type and id.getJavaType() are related
+		@SuppressWarnings("unchecked")
+		final SingularAttribute<X, Y> result = ( SingularAttribute<X, Y> ) id;
+		return result;
+	}
+
+	public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
+		//TODO check that type and version.getJavaType() are related
+		@SuppressWarnings("unchecked")
+		final SingularAttribute<X, Y> result = ( SingularAttribute<X, Y> ) version;
+		return result;
+	}
+
+	public IdentifiableType<? super X> getSupertype() {
+		return supertype;
+	}
+
+	public boolean hasSingleIdAttribute() {
+		return hasIdentifierProperty;
+	}
+
+	public boolean hasVersionAttribute() {
+		return isVersioned;
+	}
+
+	public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
+		if ( hasSingleIdAttribute() ) {
+			throw new IllegalArgumentException( "This class does not use @IdClass: " + getName() );
+		}
+		return idClassAttributes;
+	}
+
+	public Type<?> getIdType() {
+		return id.getType();
+	}
+
+	public BindableType getBindableType() {
+		return BindableType.ENTITY_TYPE;
+	}
+
+	public Class<X> getBindableJavaType() {
+		return getJavaType();
+	}
+
+	public PersistenceType getPersistenceType() {
+		return PersistenceType.ENTITY;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,284 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.MapAttribute;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.Bindable;
+
+import org.hibernate.mapping.Property;
+import org.hibernate.annotations.common.AssertionFailure;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class ManagedTypeImpl<X> implements ManagedType<X> {
+	private final Class<X> javaClass;
+	private final Map<String,Attribute<X, ?>> declaredAttributes;
+	private final Map<String,SingularAttribute<X, ?>> declaredSingularAttributes;
+	private final Map<String,PluralAttribute<X, ?, ?>> declaredCollections;
+
+
+	ManagedTypeImpl(Class<X> clazz, Iterator<Property> properties, MetadataContext context) {
+		this.javaClass = clazz;
+		Map<String,Attribute<X, ?>> localDeclAttr = new HashMap<String,Attribute<X, ?>>();
+		Map<String,SingularAttribute<X, ?>> localDeclSingAttr = new HashMap<String,SingularAttribute<X, ?>>();
+		Map<String,PluralAttribute<X,?,?>> localDeclPlurAttr = new HashMap<String,PluralAttribute<X,?,?>>();
+
+		while ( properties.hasNext() ) {
+			Property property = properties.next();
+			addProperty( property, context, localDeclAttr, localDeclSingAttr, localDeclPlurAttr );
+		}
+		declaredAttributes = Collections.unmodifiableMap( localDeclAttr );
+		declaredSingularAttributes = Collections.unmodifiableMap( localDeclSingAttr );
+		declaredCollections = Collections.unmodifiableMap( localDeclPlurAttr );
+	}
+
+	private <T> void addProperty(Property property,
+								 MetadataContext context,
+								 Map<String,Attribute<X, ?>> localDeclAttr,
+								 Map<String,SingularAttribute<X, ?>> localDeclSingAttr,
+								 Map<String,PluralAttribute<X,?,?>> localDeclPlurAttr) {
+		final Attribute<X, ?> attribute = MetamodelFactory.getAttribute( this, property, context );
+		localDeclAttr.put(attribute.getName(), attribute );
+		final Bindable.BindableType bindableType = ( ( Bindable<T> ) attribute ).getBindableType();
+		switch ( bindableType ) {
+			case SINGULAR_ATTRIBUTE:
+				localDeclSingAttr.put(attribute.getName(), (SingularAttribute<X, ?>) attribute );
+				break;
+			case PLURAL_ATTRIBUTE:
+				localDeclPlurAttr.put(attribute.getName(), (PluralAttribute<X,?,?>) attribute );
+				break;
+			default:
+				throw new AssertionFailure( "unknown bindable type: " + bindableType );
+		}
+
+	}
+
+	public Set<Attribute<? super X, ?>> getAttributes() {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public Set<Attribute<X, ?>> getDeclaredAttributes() {
+		return new HashSet<Attribute<X, ?>>(declaredAttributes.values());
+	}
+
+	public <Y> SingularAttribute<? super X, Y> getSingularAttribute(String name, Class<Y> type) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public <Y> SingularAttribute<X, Y> getDeclaredSingularAttribute(String name, Class<Y> type) {
+		final SingularAttribute<X, ?> attr = declaredSingularAttributes.get( name );
+		checkTypeForSingleAttribute( "SingularAttribute ", attr, name, type );
+		@SuppressWarnings( "unchecked")
+		final SingularAttribute<X, Y> result = ( SingularAttribute<X, Y> ) attr;
+		return result;
+	}
+
+	private <Y> void checkTypeForSingleAttribute(String error, SingularAttribute<?,?> attr, String name, Class<Y> type) {
+		if (attr == null || ( type != null && !attr.getBindableJavaType().equals( type ) ) ) {
+			throw new IllegalArgumentException(
+					error + " named " + name
+					+ (type != null ? " and of type " + type : "")
+					+ " is not present");
+		}
+	}
+
+	private <Y> void checkTypeForPluralAttributes(String error,
+												  PluralAttribute<?,?,?> attr,
+												  String name,
+												  Class<Y> type,
+												  PluralAttribute.CollectionType collectionType) {
+		if (attr == null
+				|| ( type != null && !attr.getBindableJavaType().equals( type ) )
+				|| attr.getCollectionType() != collectionType ) {
+			throw new IllegalArgumentException(
+					error + " named " + name
+					+ (type != null ? " and of element type " + type : "")
+					+ " is not present");
+		}
+	}
+
+	private <Y> void checkNotNull(String error, Attribute<?,?> attr, String name) {
+		if (attr == null) {
+			throw new IllegalArgumentException(
+					error + " named " + name
+					+ " is not present");
+		}
+	}
+
+	public Set<SingularAttribute<? super X, ?>> getSingularAttributes() {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public Set<SingularAttribute<X, ?>> getDeclaredSingularAttributes() {
+		return new HashSet<SingularAttribute<X, ?>>(declaredSingularAttributes.values());
+	}
+
+	public <E> CollectionAttribute<? super X, E> getCollection(String name, Class<E> elementType) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public <E> SetAttribute<? super X, E> getSet(String name, Class<E> elementType) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public <E> ListAttribute<? super X, E> getList(String name, Class<E> elementType) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public <K, V> MapAttribute<? super X, K, V> getMap(String name, Class<K> keyType, Class<V> valueType) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public <E> CollectionAttribute<X, E> getDeclaredCollection(String name, Class<E> elementType) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		checkTypeForPluralAttributes( "CollectionAttribute ", attr, name, elementType, PluralAttribute.CollectionType.COLLECTION );
+		@SuppressWarnings( "unchecked")
+		final CollectionAttribute<X, E> result = ( CollectionAttribute<X, E> ) attr;
+		return result;
+	}
+
+	public <E> SetAttribute<X, E> getDeclaredSet(String name, Class<E> elementType) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		checkTypeForPluralAttributes( "SetAttribute ", attr, name, elementType, PluralAttribute.CollectionType.SET );
+		@SuppressWarnings( "unchecked")
+		final SetAttribute<X, E> result = ( SetAttribute<X, E> ) attr;
+		return result;
+	}
+
+	public <E> ListAttribute<X, E> getDeclaredList(String name, Class<E> elementType) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		checkTypeForPluralAttributes( "ListAttribute ", attr, name, elementType, PluralAttribute.CollectionType.LIST );
+		@SuppressWarnings( "unchecked")
+		final ListAttribute<X, E> result = ( ListAttribute<X, E> ) attr;
+		return result;
+	}
+
+	public <K, V> MapAttribute<X, K, V> getDeclaredMap(String name, Class<K> keyType, Class<V> valueType) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		final String error = "MapAttribute ";
+		checkTypeForPluralAttributes( error, attr, name, valueType, PluralAttribute.CollectionType.LIST );
+		@SuppressWarnings( "unchecked")
+		final MapAttribute<X, K, V> result = ( MapAttribute<X, K, V> ) attr;
+		if ( result.getKeyJavaType() != keyType ) {
+			throw new IllegalArgumentException(
+					error + " named " + name + " does not support a key of type " + keyType
+			);
+		}
+		return result;
+	}
+
+	public Set<PluralAttribute<? super X, ?, ?>> getCollections() {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public Set<PluralAttribute<X, ?, ?>> getDeclaredCollections() {
+		return new HashSet<PluralAttribute<X,?,?>>(declaredCollections.values());
+	}
+
+	public Attribute<? super X, ?> getAttribute(String name) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public Attribute<X, ?> getDeclaredAttribute(String name) {
+		final Attribute<X, ?> attr = declaredSingularAttributes.get( name );
+		checkNotNull( "Attribute ", attr, name );
+		return attr;
+	}
+
+	public SingularAttribute<? super X, ?> getSingularAttribute(String name) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public SingularAttribute<X, ?> getDeclaredSingularAttribute(String name) {
+		final SingularAttribute<X, ?> attr = declaredSingularAttributes.get( name );
+		checkNotNull( "SingularAttribute ", attr, name );
+		return attr;
+	}
+
+	public CollectionAttribute<? super X, ?> getCollection(String name) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public SetAttribute<? super X, ?> getSet(String name) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public ListAttribute<? super X, ?> getList(String name) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public MapAttribute<? super X, ?, ?> getMap(String name) {
+		return null;  //To change body of implemented methods use File | Settings | File Templates.
+	}
+
+	public CollectionAttribute<X, ?> getDeclaredCollection(String name) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		final String error = "CollectionAttribute ";
+		checkNotNull( error, attr, name );
+		if ( ! CollectionAttribute.class.isAssignableFrom( attr.getClass() ) ) {
+			throw new IllegalArgumentException( name
+					+ " is not a " + error + ": " + attr.getClass() );
+		}
+		@SuppressWarnings( "unchecked")
+		final CollectionAttribute<X, ?> result = ( CollectionAttribute<X, ?> ) attr;
+		return result;
+	}
+
+	public SetAttribute<X, ?> getDeclaredSet(String name) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		final String error = "SetAttribute ";
+		checkNotNull( error, attr, name );
+		if ( ! CollectionAttribute.class.isAssignableFrom( attr.getClass() ) ) {
+			throw new IllegalArgumentException( name
+					+ " is not a " + error + ": " + attr.getClass() );
+		}
+		@SuppressWarnings( "unchecked")
+		final SetAttribute<X, ?> result = ( SetAttribute<X, ?> ) attr;
+		return result;
+	}
+
+	public ListAttribute<X, ?> getDeclaredList(String name) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		final String error = "ListAttribute ";
+		checkNotNull( error, attr, name );
+		if ( ! CollectionAttribute.class.isAssignableFrom( attr.getClass() ) ) {
+			throw new IllegalArgumentException( name
+					+ " is not a " + error + ": " + attr.getClass() );
+		}
+		@SuppressWarnings( "unchecked")
+		final ListAttribute<X, ?> result = ( ListAttribute<X, ?> ) attr;
+		return result;
+	}
+
+	public MapAttribute<X, ?, ?> getDeclaredMap(String name) {
+		final PluralAttribute<X,?,?> attr = declaredCollections.get( name );
+		final String error = "MapAttribute ";
+		checkNotNull( error, attr, name );
+		if ( ! MapAttribute.class.isAssignableFrom( attr.getClass() ) ) {
+			throw new IllegalArgumentException( name
+					+ " is not a " + error + ": " + attr.getClass() );
+		}
+		@SuppressWarnings( "unchecked")
+		final MapAttribute<X,?,?> result = ( MapAttribute<X,?,?> ) attr;
+		return result;
+	}
+
+	public abstract PersistenceType getPersistenceType();
+
+	public Class<X> getJavaType() {
+		return javaClass;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,42 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.EmbeddableType;
+
+/**
+ * Keep contextual information related tot he metedata building process.
+ * In particular keeps data than theens to be processed in a second phase.
+ * @author Emmanuel Bernard
+ */
+class MetadataContext {
+	private Map<EntityTypeDelegator<?>, Class<?>> delegators = new HashMap<EntityTypeDelegator<?>, Class<?>>();
+	private Map<Class<?>, EmbeddableType<?>> embeddables = new HashMap<Class<?>, EmbeddableType<?>>();
+
+	void addDelegator(EntityTypeDelegator<?> type, Class<?> clazz) {
+		delegators.put(type, clazz);
+	}
+
+	void postProcess(Metamodel model) {
+		for ( Map.Entry<EntityTypeDelegator<?>, Class<?>> entry : delegators.entrySet() ) {
+			setDelegate( model, entry );
+		}
+	}
+
+	private <X> void setDelegate(Metamodel model, Map.Entry<EntityTypeDelegator<?>, Class<?>> entry) {
+		@SuppressWarnings( "unchecked" )
+		final Class<X> entityClass = (Class<X>) entry.getValue();
+		@SuppressWarnings( "unchecked" )
+		final EntityTypeDelegator<X> delegator = (EntityTypeDelegator<X>) entry.getKey();
+		delegator.setDelegate( model.entity( entityClass ) );
+	}
+
+	<X> void addEmbeddableType(Class<X> clazz, EmbeddableType<X> embeddableType) {
+		embeddables.put( clazz, embeddableType );
+	}
+
+	Map<Class<?>, EmbeddableType<?>> getEmbeddableTypes() {
+		return embeddables;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,323 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.Iterator;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Type;
+import javax.persistence.metamodel.EmbeddableType;
+
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Map;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Value;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class MetamodelFactory {
+
+	static<X, Y, V, K> Attribute<X, Y> getAttribute(ManagedType<X> ownerType, Property property, MetadataContext metadataContext) {
+		AttributeContext attrContext = getAttributeContext( property );
+		final Attribute<X, Y> attribute;
+		if ( attrContext.isCollection() ) {
+			final Type<V> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue(), metadataContext );
+			@SuppressWarnings( "unchecked" )
+			final Class<Y> collectionClass = (Class<Y>) attrContext.getCollectionClass();
+			if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) {
+				final Type<K> keyType = getType( attrContext.getKeyTypeStatus(), attrContext.getKeyValue(), metadataContext );
+				attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, keyType )
+						// .member(  ); //TODO member
+						.property( property )
+						.persistentAttributeType( attrContext.getElementAttributeType() )
+						.build();
+			}
+			else {
+				attribute =  PluralAttributeImpl.create( ownerType, attrType, collectionClass, null )
+						// .member(  ); //TODO member
+						.property( property )
+						.persistentAttributeType( attrContext.getElementAttributeType() )
+						.build();
+			}
+		}
+		else {
+			final Type<Y> attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue(), metadataContext );
+			attribute = SingularAttributeImpl.create( ownerType, attrType )
+					// .member(  ); //TODO member
+					.property( property )
+					.persistentAttributeType( attrContext.getElementAttributeType() )
+					.build();
+		}
+		return attribute;
+	}
+
+	private static <X> Type<X> getType(AttributeContext.TypeStatus elementTypeStatus, Value value, MetadataContext metadataContext) {
+		final org.hibernate.type.Type type = value.getType();
+		switch ( elementTypeStatus ) {
+			case BASIC:
+				return buildBasicType( type );
+			case EMBEDDABLE:
+				return buildEmbeddableType( value, type, metadataContext );
+			case ENTITY:
+				return buildEntityType( type, metadataContext );
+			default:
+				throw new AssertionFailure( "Unknown AttributeContext.TypeStatus: " + elementTypeStatus );
+
+		}
+	}
+
+	private static class AttributeContext {
+		private final Value elementValue;
+		private final TypeStatus typeStatus;
+		private final Class<?> collectionClass;
+		private final Attribute.PersistentAttributeType attrType;
+		private final Value keyValue;
+		private final TypeStatus keyTypeStatus;
+
+		enum TypeStatus {
+			EMBEDDABLE,
+			ENTITY,
+			BASIC
+		}
+
+		AttributeContext(Value elementValue,
+						 TypeStatus elementTypeStatus,
+						 Attribute.PersistentAttributeType elementPAT,
+						 Class<?> collectionClass,
+						 Value keyValue,
+						 TypeStatus keyTypeStatus) {
+			this.elementValue = elementValue;
+			this.typeStatus = elementTypeStatus;
+			this.collectionClass = collectionClass;
+			this.attrType = elementPAT;
+			this.keyValue = keyValue;
+			this.keyTypeStatus = keyTypeStatus;
+		}
+
+		public Value getElementValue() {
+			return elementValue;
+		}
+
+		public TypeStatus getElementTypeStatus() {
+			return typeStatus;
+		}
+
+		public boolean isCollection() {
+			return collectionClass != null;
+		}
+
+		public Class<?> getCollectionClass() {
+			return collectionClass;
+		}
+
+		public Attribute.PersistentAttributeType getElementAttributeType() {
+			return attrType;
+		}
+
+		public Value getKeyValue() {
+			return keyValue;
+		}
+
+		public TypeStatus getKeyTypeStatus() {
+			return keyTypeStatus;
+		}
+	}
+
+
+	//FIXME the logical level for *To* is different from the Hibernate physical model.
+	//ie a @ManyToOne @AssocTable is a many-to-many for hibernate
+	//and a @OneToMany @AssocTable is a many-to-many for hibernate
+	//FIXME so basically Attribute.PersistentAttributeType is crap at the moment
+	private static AttributeContext getAttributeContext(Property property) {
+		final Value value = property.getValue();
+		org.hibernate.type.Type type = value.getType();
+		if ( type.isAnyType() ) {
+			throw new UnsupportedOperationException( "any not supported yet" );
+		}
+		else if ( type.isAssociationType() ) {
+			//collection or entity
+			if ( type.isCollectionType() ) {
+				//do collection
+				if ( value instanceof Collection ) {
+					final Collection collValue = (Collection) value;
+					final Value elementValue = collValue.getElement();
+					final org.hibernate.type.Type elementType = elementValue.getType();
+					final AttributeContext.TypeStatus elementTypeStatus;
+					final Attribute.PersistentAttributeType elementPAT;
+					final Class<?> collectionClass = collValue.getCollectionType().getReturnedClass();
+
+
+					final Value keyValue;
+					final org.hibernate.type.Type keyType;
+					final AttributeContext.TypeStatus keyTypeStatus;
+					if ( value instanceof Map ) {
+						keyValue = ( (Map) value).getIndex();
+						keyType = keyValue.getType();
+						if ( keyValue instanceof Component ) {
+							keyTypeStatus = AttributeContext.TypeStatus.EMBEDDABLE;
+						}
+						else if ( keyType.isAnyType() ) {
+							throw new UnsupportedOperationException( "collection of any not supported yet" );
+						}
+						else if ( keyType.isAssociationType() ) {
+							keyTypeStatus = AttributeContext.TypeStatus.ENTITY;
+						}
+						else {
+							keyTypeStatus = AttributeContext.TypeStatus.BASIC;
+						}
+					}
+					else {
+						keyValue = null;
+						keyTypeStatus = null;
+					}
+
+					if ( elementValue instanceof Component ) {
+						//collection of components
+						elementTypeStatus = AttributeContext.TypeStatus.EMBEDDABLE;
+						elementPAT = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
+					}
+					else if ( elementType.isAnyType() ) {
+						throw new UnsupportedOperationException( "collection of any not supported yet" );
+					}
+					else if ( elementType.isAssociationType() ) {
+						//collection of entity
+						elementTypeStatus = AttributeContext.TypeStatus.ENTITY;
+						elementPAT = Attribute.PersistentAttributeType.MANY_TO_MANY;
+					}
+					else {
+						//collection of basic type
+						elementTypeStatus = AttributeContext.TypeStatus.BASIC;
+						elementPAT = Attribute.PersistentAttributeType.ELEMENT_COLLECTION;
+					}
+					return new AttributeContext(
+								elementValue,
+								elementTypeStatus,
+								elementPAT,
+								collectionClass,
+								keyValue,
+								keyTypeStatus
+						);
+				}
+				else if ( value instanceof OneToMany ) {
+					//one to many with FK => entity
+					return new AttributeContext(
+							value,
+							AttributeContext.TypeStatus.ENTITY,
+							Attribute.PersistentAttributeType.ONE_TO_MANY,
+							null, null, null );
+				}
+
+			}
+			else {
+				//ToOne association
+				return new AttributeContext(
+						value,
+						AttributeContext.TypeStatus.ENTITY,
+						Attribute.PersistentAttributeType.MANY_TO_MANY, //FIXME how to differentiate the logical many to one from the one to one (not physical level)
+						null, null, null);
+			}
+		}
+		else if ( property.isComposite() ) {
+			//embeddable
+			return new AttributeContext(
+					value,
+					AttributeContext.TypeStatus.EMBEDDABLE,
+					Attribute.PersistentAttributeType.EMBEDDED,
+					null, null, null);
+
+		}
+		else {
+			//basic type
+			return new AttributeContext(
+					value,
+					AttributeContext.TypeStatus.BASIC,
+					Attribute.PersistentAttributeType.BASIC,
+					null, null, null);
+		}
+		throw new UnsupportedOperationException("oops, we are missing something: " + property.toString() );
+	}
+
+
+
+	static <X> Type<X> getType(Property property, MetadataContext context) {
+		final Value value = property.getValue();
+		org.hibernate.type.Type type = value.getType();
+		if ( type.isAnyType() ) {
+			throw new UnsupportedOperationException( "any not supported yet" );
+		}
+		else if ( type.isAssociationType() ) {
+			//collection or entity
+			if ( type.isCollectionType() ) {
+				//do collection
+				if ( value instanceof Collection ) {
+					Collection collValue = (Collection) value;
+					collValue.getCollectionType();
+					Value elementValue = collValue.getElement();
+					final org.hibernate.type.Type elementType = elementValue.getType();
+					if ( elementValue instanceof Component ) {
+						//colelction of components
+						return buildEmbeddableType( elementValue, elementType, context );
+					}
+					else if ( elementType.isAnyType() ) {
+						throw new UnsupportedOperationException( "collection of any not supported yet" );
+					}
+					else if ( elementType.isAssociationType() ) {
+						//collection of entity
+						return buildEntityType( elementType, context);
+					}
+					else {
+						//collection of basic type
+						buildBasicType( elementType );
+					}
+				}
+				else if ( value instanceof OneToMany ) {
+					//one to many with FK => entity
+					return buildEntityType( value.getType(), context );
+				}
+				
+			}
+			else {
+				//ToOne association
+				return buildEntityType( type, context );
+			}
+		}
+		else if ( property.isComposite() ) {
+			//embeddable
+			return buildEmbeddableType( value, type, context );
+
+		}
+		else {
+			//basic type
+			return buildBasicType( type );
+		}
+		throw new UnsupportedOperationException("oops, we are missing something: " + property.toString() );
+	}
+
+	private static <X> Type<X> buildBasicType(org.hibernate.type.Type type) {
+		@SuppressWarnings( "unchecked" )
+		final Class<X> clazz = type.getReturnedClass();
+		return new BasicTypeImpl<X>( clazz, Type.PersistenceType.BASIC );
+	}
+
+	private static <X> Type<X> buildEntityType(org.hibernate.type.Type type, MetadataContext context) {
+		@SuppressWarnings( "unchecked" )
+		final Class<X> clazz = type.getReturnedClass();
+		final EntityTypeDelegator<X> entityTypeDelegator = new EntityTypeDelegator<X>();
+		context.addDelegator( entityTypeDelegator, clazz );
+		return entityTypeDelegator;
+	}
+
+	private static <X> Type<X> buildEmbeddableType(Value value, org.hibernate.type.Type type, MetadataContext context) {
+		//build embedable type
+		@SuppressWarnings( "unchecked" )
+		final Class<X> clazz = type.getReturnedClass();
+		Component component = (Component) value;
+		@SuppressWarnings( "unchecked")
+		final Iterator<Property> subProperties = component.getPropertyIterator();
+		final EmbeddableType<X> embeddableType = new EmbeddableTypeImpl<X>( clazz, subProperties, context );
+		context.addEmbeddableType( clazz, embeddableType );
+		return embeddableType;
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,81 @@
+package org.hibernate.ejb.metamodel;
+
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.HashSet;
+import java.io.Serializable;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.EmbeddableType;
+
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class MetamodelImpl implements Metamodel, Serializable {
+
+	private final Map<Class<?>,EntityType<?>> entities;
+	private Map<Class<?>, EmbeddableType<?>> embeddables;
+
+	public MetamodelImpl(Iterator<PersistentClass> classes) {
+		Map<Class<?>,EntityType<?>> localEntities = new HashMap<Class<?>,EntityType<?>>();
+		MetadataContext context = new MetadataContext();
+		while ( classes.hasNext() ) {
+			buildEntityType( classes, localEntities, context );
+		}
+		this.entities = Collections.unmodifiableMap( localEntities );
+		this.embeddables = Collections.unmodifiableMap( context.getEmbeddableTypes() );
+		context.postProcess( this );
+	}
+
+	private <X> void buildEntityType(Iterator<PersistentClass> classes, Map<Class<?>, EntityType<?>> localEntities, MetadataContext context) {
+		PersistentClass persistentClass = classes.next();
+		@SuppressWarnings( "unchecked" )
+		final Class<X> clazz = persistentClass.getMappedClass();
+		if ( clazz != null ) {
+			localEntities.put( clazz, new EntityTypeImpl<X>(clazz, persistentClass, context) );
+		}
+	}
+
+	public <X> EntityType<X> entity(Class<X> cls) {
+		final EntityType<?> entityType = entities.get( cls );
+		if ( entityType == null ) throw new IllegalArgumentException( "Not an entity: " + cls );
+		//unsafe casting is our map inserts guarantee them
+		return (EntityType<X>) entityType;
+	}
+
+	public <X> ManagedType<X> type(Class<X> cls) {
+		ManagedType<?> type = null;
+		type = entities.get( cls );
+		if ( type == null ) throw new IllegalArgumentException( "Not an managed type: " + cls );
+		//unsafe casting is our map inserts guarantee them
+		return (ManagedType<X>) type;
+	}
+
+	public <X> EmbeddableType<X> embeddable(Class<X> cls) {
+		final EmbeddableType<?> embeddableType = embeddables.get( cls );
+		if ( embeddableType == null ) throw new IllegalArgumentException( "Not an entity: " + cls );
+		//unsafe casting is our map inserts guarantee them
+		return (EmbeddableType<X>) embeddableType;
+	}
+
+	public Set<ManagedType<?>> getManagedTypes() {
+		final Set<ManagedType<?>> managedTypes = new HashSet<ManagedType<?>>( entities.size() + embeddables.size() );
+		managedTypes.addAll( entities.values() );
+		managedTypes.addAll( embeddables.values() );
+		return managedTypes;
+	}
+
+	public Set<EntityType<?>> getEntities() {
+		return new HashSet<EntityType<?>>(entities.values());
+	}
+
+	public Set<EmbeddableType<?>> getEmbeddables() {
+		return new HashSet<EmbeddableType<?>>(embeddables.values());
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,214 @@
+package org.hibernate.ejb.metamodel;
+
+import java.lang.reflect.Member;
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import java.util.Collection;
+import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Type;
+import javax.persistence.metamodel.SetAttribute;
+import javax.persistence.metamodel.CollectionAttribute;
+import javax.persistence.metamodel.ListAttribute;
+import javax.persistence.metamodel.MapAttribute;
+
+import org.hibernate.mapping.Property;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class PluralAttributeImpl<X, C, E> implements PluralAttribute<X, C, E> {
+
+	private final ManagedType<X> ownerType;
+	private final Type<E> elementType;
+	//FIXME member is not serializable
+	private final Member member;
+	private final String name;
+	private final PersistentAttributeType persistentAttributeType;
+	private final Class<C> collectionClass;
+
+	private PluralAttributeImpl(Builder<X,C,E,?> builder) {
+		this.ownerType = builder.type;
+		this.elementType = builder.attributeType;
+		this.collectionClass = builder.collectionClass;
+		this.member = builder.member;
+		this.name = builder.property.getName();
+		this.persistentAttributeType = builder.persistentAttributeType;
+	}
+
+	public static class Builder<X, C, E, K> {
+		private final Type<E> attributeType;
+		private final ManagedType<X> type;
+		private Member member;
+		private PersistentAttributeType persistentAttributeType;
+		private Property property;
+		private Class<C> collectionClass;
+		private Type<K> keyType;
+
+
+		private Builder(ManagedType<X> ownerType, Type<E> attrType, Class<C> collectionClass, Type<K> keyType) {
+			this.type = ownerType;
+			this.attributeType = attrType;
+			this.collectionClass = collectionClass;
+			this.keyType = keyType;
+		}
+
+		public Builder<X,C,E,K> member(Member member) {
+			this.member = member;
+			return this;
+		}
+
+		public Builder<X,C,E,K> property(Property property) {
+			this.property = property;
+			return this;
+		}
+
+		public Builder<X,C,E,K> persistentAttributeType(PersistentAttributeType attrType) {
+			this.persistentAttributeType = attrType;
+			return this;
+		}
+
+		public <K> PluralAttributeImpl<X,C,E> build() {
+			if ( Map.class.isAssignableFrom( collectionClass ) ) {
+				@SuppressWarnings( "unchecked" )
+				final Builder<X,Map<K,E>,E,K> builder = (Builder<X,Map<K,E>,E,K>) this;
+				@SuppressWarnings( "unchecked" )
+				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new MapAttributeImpl<X,K,E>(
+						builder
+				);
+				return result;
+			}
+			else if ( Set.class.isAssignableFrom( collectionClass ) ) {
+				@SuppressWarnings( "unchecked" )
+				final Builder<X,Set<E>, E,?> builder = (Builder<X, Set<E>, E,?>) this;
+				@SuppressWarnings( "unchecked" )
+				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new SetAttributeImpl<X,E>(
+						builder
+				);
+				return result;
+			}
+			else if ( List.class.isAssignableFrom( collectionClass ) ) {
+				@SuppressWarnings( "unchecked" )
+				final Builder<X, List<E>, E,?> builder = (Builder<X, List<E>, E,?>) this;
+				@SuppressWarnings( "unchecked" )
+				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new ListAttributeImpl<X,E>(
+						builder
+				);
+				return result;
+			}
+			else if ( Collection.class.isAssignableFrom( collectionClass ) ) {
+				@SuppressWarnings( "unchecked" )
+				final Builder<X, Collection<E>,E,?> builder = (Builder<X, Collection<E>, E,?>) this;
+				@SuppressWarnings( "unchecked" )
+				final PluralAttributeImpl<X, C, E> result = ( PluralAttributeImpl<X, C, E> ) new CollectionAttributeImpl<X, E>(
+						builder
+				);
+				return result;
+			}
+			throw new UnsupportedOperationException( "Unkown collection: " + collectionClass );
+		}
+	}
+
+	public static <X,C,E,K> Builder<X,C,E,K> create(
+			ManagedType<X> ownerType,
+			Type<E> attrType,
+			Class<C> collectionClass,
+			Type<K> keyType) {
+		return new Builder<X,C,E,K>(ownerType, attrType, collectionClass, keyType);
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public PersistentAttributeType getPersistentAttributeType() {
+		return persistentAttributeType;
+	}
+
+	public ManagedType<X> getDeclaringType() {
+		return ownerType;
+	}
+
+	public Class<C> getJavaType() {
+		return collectionClass;
+	}
+
+	public abstract CollectionType getCollectionType();
+
+	public Type<E> getElementType() {
+		return elementType;
+	}
+
+
+	public Member getJavaMember() {
+		return member;
+	}
+
+	public boolean isAssociation() {
+		return true;
+	}
+
+	public boolean isCollection() {
+		return true;
+	}
+
+	public BindableType getBindableType() {
+		return BindableType.PLURAL_ATTRIBUTE;
+	}
+
+	public Class<E> getBindableJavaType() {
+		return elementType.getJavaType();
+	}
+
+	static class SetAttributeImpl<X,E> extends PluralAttributeImpl<X,Set<E>,E> implements SetAttribute<X,E> {
+		SetAttributeImpl(Builder<X,Set<E>,E,?> xceBuilder) {
+			super( xceBuilder );
+		}
+
+		public CollectionType getCollectionType() {
+			return CollectionType.SET;
+		}
+	}
+
+	static class CollectionAttributeImpl<X,E> extends PluralAttributeImpl<X,Collection<E>,E> implements CollectionAttribute<X,E> {
+		CollectionAttributeImpl(Builder<X, Collection<E>,E,?> xceBuilder) {
+			super( xceBuilder );
+		}
+
+		public CollectionType getCollectionType() {
+			return CollectionType.COLLECTION;
+		}
+	}
+
+	static class ListAttributeImpl<X,E> extends PluralAttributeImpl<X,List<E>,E> implements ListAttribute<X,E> {
+		ListAttributeImpl(Builder<X,List<E>,E,?> xceBuilder) {
+			super( xceBuilder );
+		}
+
+		public CollectionType getCollectionType() {
+			return CollectionType.LIST;
+		}
+	}
+
+	static class MapAttributeImpl<X,K,V> extends PluralAttributeImpl<X,Map<K,V>,V> implements MapAttribute<X,K,V> {
+		private final Type<K> keyType;
+
+		MapAttributeImpl(Builder<X,Map<K,V>,V,K> xceBuilder) {
+			super( xceBuilder );
+			this.keyType = xceBuilder.keyType;
+		}
+
+		public CollectionType getCollectionType() {
+			return CollectionType.MAP;
+		}
+
+		public Class<K> getKeyJavaType() {
+			return keyType.getJavaType();
+		}
+
+		public Type<K> getKeyType() {
+			return keyType;
+		}
+	}
+}

Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java	                        (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java	2009-08-09 18:04:35 UTC (rev 17254)
@@ -0,0 +1,146 @@
+package org.hibernate.ejb.metamodel;
+
+import java.lang.reflect.Member;
+import java.io.Serializable;
+import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.Type;
+
+import org.hibernate.mapping.Property;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SingularAttributeImpl<X, Y> implements SingularAttribute<X, Y>, Serializable {
+	private final boolean isId;
+	private final boolean isVersion;
+	private final boolean isOptional;
+	private final ManagedType<X> ownerType;
+	private final Type<Y> attrType;
+	//FIXME member is not serializable
+	private final Member member;
+	private final String name;
+	private final PersistentAttributeType persistentAttributeType;
+
+	private SingularAttributeImpl(Builder<X,Y> builder) {
+		this.ownerType = builder.type;
+		this.attrType = builder.attributeType;
+		this.isId = builder.isId;
+		this.isVersion = builder.isVersion;
+		final Property property = builder.property;
+		this.isOptional = property.isOptional();
+		this.member = builder.member;
+		this.name = property.getName();
+		if ( builder.persistentAttributeType != null) {
+			this.persistentAttributeType = builder.persistentAttributeType;
+		}
+		else {
+			this.persistentAttributeType = property.isComposite() ?
+														PersistentAttributeType.EMBEDDED :
+														PersistentAttributeType.BASIC;
+		}
+	}
+
+	public static class Builder<X,Y> {
+		private boolean isId;
+		private boolean isVersion;
+		//private boolean isOptional = true;
+		private final Type<Y> attributeType;
+		private final ManagedType<X> type;
+		private Member member;
+		//private String name;
+		private PersistentAttributeType persistentAttributeType;
+		private Property property;
+
+
+		private Builder(ManagedType<X> ownerType, Type<Y> attrType) {
+			this.type = ownerType;
+			this.attributeType = attrType;
+		}
+
+		public Builder<X,Y> member(Member member) {
+			this.member = member;
+			return this;
+		}
+
+		public Builder<X, Y> property(Property property) {
+			this.property = property;
+			return this;
+		}
+
+		public Builder<X,Y> id() {
+			isId = true;
+			return this;
+		}
+
+		public Builder<X,Y> version() {
+			isVersion = true;
+			return this;
+		}
+
+		public SingularAttribute<X, Y> build() {
+			return new SingularAttributeImpl<X,Y>(this);
+		}
+
+		public Builder<X, Y> persistentAttributeType(PersistentAttributeType attrType) {
+			this.persistentAttributeType = attrType;
+			return this;
+		}
+	}
+
+	public static <X,Y> Builder<X,Y> create(ManagedType<X> ownerType, Type<Y> attrType) {
+		return new Builder<X,Y>(ownerType, attrType);
+	}
+
+	public boolean isId() {
+		return isId;
+	}
+
+	public boolean isVersion() {
+		return isVersion;
+	}
+
+	public boolean isOptional() {
+		return isOptional;
+	}
+
+	public Type<Y> getType() {
+		return attrType;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public PersistentAttributeType getPersistentAttributeType() {
+		return persistentAttributeType;
+	}
+
+	public ManagedType<X> getDeclaringType() {
+		return ownerType;
+	}
+
+	public Class<Y> getJavaType() {
+		return attrType.getJavaType();
+	}
+
+	public Member getJavaMember() {
+		return member;
+	}
+
+	public boolean isAssociation() {
+		return false;
+	}
+
+	public boolean isCollection() {
+		return false;
+	}
+
+	public BindableType getBindableType() {
+		return BindableType.SINGULAR_ATTRIBUTE;
+	}
+
+	public Class<Y> getBindableJavaType() {
+		return attrType.getJavaType();
+	}
+}



More information about the hibernate-commits mailing list