From 0d14085ba68ebf086bbd3fb5915e3dc123732fc8 Mon Sep 17 00:00:00 2001 From: Emmanuel Bernard Date: Sun, 9 Aug 2009 18:04:35 +0000 Subject: [PATCH] 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 git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17254 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../org/hibernate/ejb/Ejb3Configuration.java | 3 +- .../ejb/EntityManagerFactoryImpl.java | 24 +- .../ejb/metamodel/BasicTypeImpl.java | 26 ++ .../ejb/metamodel/EmbeddableTypeImpl.java | 21 ++ .../ejb/metamodel/EntityTypeDelegator.java | 196 +++++++++++ .../ejb/metamodel/EntityTypeImpl.java | 164 +++++++++ .../ejb/metamodel/ManagedTypeImpl.java | 284 +++++++++++++++ .../ejb/metamodel/MetadataContext.java | 42 +++ .../ejb/metamodel/MetamodelFactory.java | 323 ++++++++++++++++++ .../ejb/metamodel/MetamodelImpl.java | 81 +++++ .../ejb/metamodel/PluralAttributeImpl.java | 214 ++++++++++++ .../ejb/metamodel/SingularAttributeImpl.java | 146 ++++++++ 12 files changed, 1515 insertions(+), 9 deletions(-) create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java create mode 100644 entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java diff --git a/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java index b9e1f64143..a5c0c50a45 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java @@ -712,7 +712,8 @@ public class Ejb3Configuration implements Serializable, Referenceable { cfg.buildSessionFactory(), transactionType, discardOnClose, - getSessionInterceptorClass( cfg.getProperties() ) + getSessionInterceptorClass( cfg.getProperties() ), + cfg ); } catch (HibernateException e) { diff --git a/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java index 556a6deacf..62050f78ad 100755 --- a/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java @@ -3,6 +3,7 @@ package org.hibernate.ejb; 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.criteria.QueryBuilder; 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 classes = cfg.getClassMappings(); + this.metamodel = new MetamodelImpl( classes ); this.criteriaQueryBuilder = new QueryBuilderImpl( this ); } @@ -54,8 +63,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory { } 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() { diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java new file mode 100644 index 0000000000..1f702025c8 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/BasicTypeImpl.java @@ -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 implements BasicType, Serializable { + private final Class clazz; + private PersistenceType persistenceType; + + public PersistenceType getPersistenceType() { + return persistenceType; + } + + public Class getJavaType() { + return clazz; + } + + public BasicTypeImpl(Class clazz, PersistenceType persistenceType) { + this.clazz = clazz; + this.persistenceType = persistenceType; + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java new file mode 100644 index 0000000000..a80a0a1b7b --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java @@ -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 extends ManagedTypeImpl implements EmbeddableType, Serializable { + EmbeddableTypeImpl(Class clazz, Iterator properties, MetadataContext context) { + super(clazz, properties, context); + } + + public PersistenceType getPersistenceType() { + return PersistenceType.EMBEDDABLE; + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java new file mode 100644 index 0000000000..1505ce6140 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeDelegator.java @@ -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 + * Helps break infinite loops when creating entity metamodel related to each other + * + * @author Emmanuel Bernard + */ +public class EntityTypeDelegator implements EntityType, Serializable { + private volatile EntityType delegate; + + void setDelegate(EntityType delegate) { + this.delegate = delegate; + } + + public String getName() { + return delegate.getName(); + } + + public SingularAttribute getId(Class type) { + return delegate.getId( type ); + } + + public SingularAttribute getVersion(Class type) { + return delegate.getVersion( type ); + } + + public SingularAttribute getDeclaredId(Class type) { + return delegate.getDeclaredId( type ); + } + + public SingularAttribute getDeclaredVersion(Class type) { + return delegate.getDeclaredVersion( type ); + } + + public IdentifiableType getSupertype() { + return delegate.getSupertype(); + } + + public boolean hasSingleIdAttribute() { + return delegate.hasSingleIdAttribute(); + } + + public boolean hasVersionAttribute() { + return delegate.hasVersionAttribute(); + } + + public Set> getIdClassAttributes() { + return delegate.getIdClassAttributes(); + } + + public Type getIdType() { + return delegate.getIdType(); + } + + public Set> getAttributes() { + return delegate.getAttributes(); + } + + public Set> getDeclaredAttributes() { + return delegate.getDeclaredAttributes(); + } + + public SingularAttribute getSingularAttribute(String name, Class type) { + return delegate.getSingularAttribute( name, type ); + } + + public SingularAttribute getDeclaredSingularAttribute(String name, Class type) { + return delegate.getDeclaredSingularAttribute( name, type ); + } + + public Set> getSingularAttributes() { + return delegate.getSingularAttributes(); + } + + public Set> getDeclaredSingularAttributes() { + return delegate.getDeclaredSingularAttributes(); + } + + public CollectionAttribute getCollection(String name, Class elementType) { + return delegate.getCollection( name, elementType ); + } + + public SetAttribute getSet(String name, Class elementType) { + return delegate.getSet( name, elementType ); + } + + public ListAttribute getList(String name, Class elementType) { + return delegate.getList( name, elementType ); + } + + public MapAttribute getMap(String name, Class keyType, Class valueType) { + return delegate.getMap( name, keyType, valueType ); + } + + public CollectionAttribute getDeclaredCollection(String name, Class elementType) { + return delegate.getDeclaredCollection( name, elementType ); + } + + public SetAttribute getDeclaredSet(String name, Class elementType) { + return delegate.getDeclaredSet( name, elementType ); + } + + public ListAttribute getDeclaredList(String name, Class elementType) { + return delegate.getDeclaredList( name, elementType ); + } + + public MapAttribute getDeclaredMap(String name, Class keyType, Class valueType) { + return delegate.getDeclaredMap( name, keyType, valueType ); + } + + public Set> getCollections() { + return delegate.getCollections(); + } + + public Set> getDeclaredCollections() { + return delegate.getDeclaredCollections(); + } + + public Attribute getAttribute(String name) { + return delegate.getAttribute( name ); + } + + public Attribute getDeclaredAttribute(String name) { + return delegate.getDeclaredAttribute( name ); + } + + public SingularAttribute getSingularAttribute(String name) { + return delegate.getSingularAttribute( name ); + } + + public SingularAttribute getDeclaredSingularAttribute(String name) { + return delegate.getDeclaredSingularAttribute( name ); + } + + public CollectionAttribute getCollection(String name) { + return delegate.getCollection( name ); + } + + public SetAttribute getSet(String name) { + return delegate.getSet( name ); + } + + public ListAttribute getList(String name) { + return delegate.getList( name ); + } + + public MapAttribute getMap(String name) { + return delegate.getMap( name ); + } + + public CollectionAttribute getDeclaredCollection(String name) { + return delegate.getDeclaredCollection( name ); + } + + public SetAttribute getDeclaredSet(String name) { + return delegate.getDeclaredSet( name ); + } + + public ListAttribute getDeclaredList(String name) { + return delegate.getDeclaredList( name ); + } + + public MapAttribute getDeclaredMap(String name) { + return delegate.getDeclaredMap( name ); + } + + public PersistenceType getPersistenceType() { + return delegate.getPersistenceType(); + } + + public Class getJavaType() { + return delegate.getJavaType(); + } + + public BindableType getBindableType() { + return delegate.getBindableType(); + } + + public Class getBindableJavaType() { + return delegate.getBindableJavaType(); + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java new file mode 100644 index 0000000000..c29b0eb878 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EntityTypeImpl.java @@ -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 extends ManagedTypeImpl implements EntityType, Serializable { + + private final SingularAttribute id; + private final SingularAttribute version; + private final String className; + private final boolean hasIdentifierProperty; + private final boolean isVersioned; + private final Set> idClassAttributes; + private final IdentifiableType supertype; + + public EntityTypeImpl(Class clazz, PersistentClass persistentClass, MetadataContext context) { + super(clazz, (Iterator) persistentClass.getPropertyIterator(), context ); + this.className = persistentClass.getClassName(); + this.hasIdentifierProperty = persistentClass.hasIdentifierProperty(); + this.isVersioned = persistentClass.isVersioned(); + id = buildIdAttribute( persistentClass ); + version = buildVersionAttribute( persistentClass ); + final Set> 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 entityTypeDelegator = new EntityTypeDelegator(); + context.addDelegator( entityTypeDelegator, superclass ); + supertype = entityTypeDelegator; + } + } + + private SingularAttribute buildIdAttribute(PersistentClass persistentClass) { + final Property identifierProperty = persistentClass.getIdentifierProperty(); + @SuppressWarnings( "unchecked" ) + Class idClass = identifierProperty.getType().getReturnedClass(); + final Type attrType = new BasicTypeImpl( idClass, + identifierProperty.isComposite() ? + PersistenceType.EMBEDDABLE : + PersistenceType.BASIC); + return SingularAttributeImpl.create(this, attrType ) + .property(identifierProperty) + //.member( null ) //TODO member + .id() + .build(); + } + + private SingularAttribute buildVersionAttribute(PersistentClass persistentClass) { + if ( persistentClass.isVersioned() ) { + @SuppressWarnings( "unchecked" ) + Class versionClass = persistentClass.getVersion().getType().getReturnedClass(); + Property property = persistentClass.getVersion(); + final Type attrType = new BasicTypeImpl( versionClass, PersistenceType.BASIC); + return SingularAttributeImpl.create(this, attrType ) + .property(property) + //.member( null ) //TODO member + .version() + .build(); + } + else { + return null; + } + } + + private Set> buildIdClassAttributes(PersistentClass persistentClass, MetadataContext context) { + if ( hasSingleIdAttribute() ) { + return null; + } + @SuppressWarnings( "unchecked") + Iterator properties = persistentClass.getIdentifierMapper().getPropertyIterator(); + Set> attributes = new HashSet>(); + while ( properties.hasNext() ) { + attributes.add( + (SingularAttribute) MetamodelFactory.getAttribute( this, properties.next(), context ) + ); + } + return attributes; + } + + public String getName() { + return className; + } + + public SingularAttribute getId(Class type) { + //TODO check that type and id.getJavaType() are related + @SuppressWarnings( "unchecked") + final SingularAttribute result = ( SingularAttribute ) id; + return result; + } + + public SingularAttribute getVersion(Class type) { + //TODO check that type and version.getJavaType() are related + @SuppressWarnings( "unchecked") + final SingularAttribute result = ( SingularAttribute ) version; + return result; + } + + public SingularAttribute getDeclaredId(Class type) { + //TODO check that type and id.getJavaType() are related + @SuppressWarnings("unchecked") + final SingularAttribute result = ( SingularAttribute ) id; + return result; + } + + public SingularAttribute getDeclaredVersion(Class type) { + //TODO check that type and version.getJavaType() are related + @SuppressWarnings("unchecked") + final SingularAttribute result = ( SingularAttribute ) version; + return result; + } + + public IdentifiableType getSupertype() { + return supertype; + } + + public boolean hasSingleIdAttribute() { + return hasIdentifierProperty; + } + + public boolean hasVersionAttribute() { + return isVersioned; + } + + public Set> 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 getBindableJavaType() { + return getJavaType(); + } + + public PersistenceType getPersistenceType() { + return PersistenceType.ENTITY; + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java new file mode 100644 index 0000000000..2fa1bc009d --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/ManagedTypeImpl.java @@ -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 implements ManagedType { + private final Class javaClass; + private final Map> declaredAttributes; + private final Map> declaredSingularAttributes; + private final Map> declaredCollections; + + + ManagedTypeImpl(Class clazz, Iterator properties, MetadataContext context) { + this.javaClass = clazz; + Map> localDeclAttr = new HashMap>(); + Map> localDeclSingAttr = new HashMap>(); + Map> localDeclPlurAttr = new HashMap>(); + + 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 void addProperty(Property property, + MetadataContext context, + Map> localDeclAttr, + Map> localDeclSingAttr, + Map> localDeclPlurAttr) { + final Attribute attribute = MetamodelFactory.getAttribute( this, property, context ); + localDeclAttr.put(attribute.getName(), attribute ); + final Bindable.BindableType bindableType = ( ( Bindable ) attribute ).getBindableType(); + switch ( bindableType ) { + case SINGULAR_ATTRIBUTE: + localDeclSingAttr.put(attribute.getName(), (SingularAttribute) attribute ); + break; + case PLURAL_ATTRIBUTE: + localDeclPlurAttr.put(attribute.getName(), (PluralAttribute) attribute ); + break; + default: + throw new AssertionFailure( "unknown bindable type: " + bindableType ); + } + + } + + public Set> getAttributes() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public Set> getDeclaredAttributes() { + return new HashSet>(declaredAttributes.values()); + } + + public SingularAttribute getSingularAttribute(String name, Class type) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public SingularAttribute getDeclaredSingularAttribute(String name, Class type) { + final SingularAttribute attr = declaredSingularAttributes.get( name ); + checkTypeForSingleAttribute( "SingularAttribute ", attr, name, type ); + @SuppressWarnings( "unchecked") + final SingularAttribute result = ( SingularAttribute ) attr; + return result; + } + + private void checkTypeForSingleAttribute(String error, SingularAttribute attr, String name, Class 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 void checkTypeForPluralAttributes(String error, + PluralAttribute attr, + String name, + Class 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 void checkNotNull(String error, Attribute attr, String name) { + if (attr == null) { + throw new IllegalArgumentException( + error + " named " + name + + " is not present"); + } + } + + public Set> getSingularAttributes() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public Set> getDeclaredSingularAttributes() { + return new HashSet>(declaredSingularAttributes.values()); + } + + public CollectionAttribute getCollection(String name, Class elementType) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public SetAttribute getSet(String name, Class elementType) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public ListAttribute getList(String name, Class elementType) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public MapAttribute getMap(String name, Class keyType, Class valueType) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public CollectionAttribute getDeclaredCollection(String name, Class elementType) { + final PluralAttribute attr = declaredCollections.get( name ); + checkTypeForPluralAttributes( "CollectionAttribute ", attr, name, elementType, PluralAttribute.CollectionType.COLLECTION ); + @SuppressWarnings( "unchecked") + final CollectionAttribute result = ( CollectionAttribute ) attr; + return result; + } + + public SetAttribute getDeclaredSet(String name, Class elementType) { + final PluralAttribute attr = declaredCollections.get( name ); + checkTypeForPluralAttributes( "SetAttribute ", attr, name, elementType, PluralAttribute.CollectionType.SET ); + @SuppressWarnings( "unchecked") + final SetAttribute result = ( SetAttribute ) attr; + return result; + } + + public ListAttribute getDeclaredList(String name, Class elementType) { + final PluralAttribute attr = declaredCollections.get( name ); + checkTypeForPluralAttributes( "ListAttribute ", attr, name, elementType, PluralAttribute.CollectionType.LIST ); + @SuppressWarnings( "unchecked") + final ListAttribute result = ( ListAttribute ) attr; + return result; + } + + public MapAttribute getDeclaredMap(String name, Class keyType, Class valueType) { + final PluralAttribute attr = declaredCollections.get( name ); + final String error = "MapAttribute "; + checkTypeForPluralAttributes( error, attr, name, valueType, PluralAttribute.CollectionType.LIST ); + @SuppressWarnings( "unchecked") + final MapAttribute result = ( MapAttribute ) attr; + if ( result.getKeyJavaType() != keyType ) { + throw new IllegalArgumentException( + error + " named " + name + " does not support a key of type " + keyType + ); + } + return result; + } + + public Set> getCollections() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public Set> getDeclaredCollections() { + return new HashSet>(declaredCollections.values()); + } + + public Attribute getAttribute(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public Attribute getDeclaredAttribute(String name) { + final Attribute attr = declaredSingularAttributes.get( name ); + checkNotNull( "Attribute ", attr, name ); + return attr; + } + + public SingularAttribute getSingularAttribute(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public SingularAttribute getDeclaredSingularAttribute(String name) { + final SingularAttribute attr = declaredSingularAttributes.get( name ); + checkNotNull( "SingularAttribute ", attr, name ); + return attr; + } + + public CollectionAttribute getCollection(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public SetAttribute getSet(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public ListAttribute getList(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public MapAttribute getMap(String name) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public CollectionAttribute getDeclaredCollection(String name) { + final PluralAttribute 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 result = ( CollectionAttribute ) attr; + return result; + } + + public SetAttribute getDeclaredSet(String name) { + final PluralAttribute 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 result = ( SetAttribute ) attr; + return result; + } + + public ListAttribute getDeclaredList(String name) { + final PluralAttribute 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 result = ( ListAttribute ) attr; + return result; + } + + public MapAttribute getDeclaredMap(String name) { + final PluralAttribute 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 result = ( MapAttribute ) attr; + return result; + } + + public abstract PersistenceType getPersistenceType(); + + public Class getJavaType() { + return javaClass; + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java new file mode 100644 index 0000000000..82d63e8b51 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java @@ -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, Class> delegators = new HashMap, Class>(); + private Map, EmbeddableType> embeddables = new HashMap, EmbeddableType>(); + + void addDelegator(EntityTypeDelegator type, Class clazz) { + delegators.put(type, clazz); + } + + void postProcess(Metamodel model) { + for ( Map.Entry, Class> entry : delegators.entrySet() ) { + setDelegate( model, entry ); + } + } + + private void setDelegate(Metamodel model, Map.Entry, Class> entry) { + @SuppressWarnings( "unchecked" ) + final Class entityClass = (Class) entry.getValue(); + @SuppressWarnings( "unchecked" ) + final EntityTypeDelegator delegator = (EntityTypeDelegator) entry.getKey(); + delegator.setDelegate( model.entity( entityClass ) ); + } + + void addEmbeddableType(Class clazz, EmbeddableType embeddableType) { + embeddables.put( clazz, embeddableType ); + } + + Map, EmbeddableType> getEmbeddableTypes() { + return embeddables; + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java new file mode 100644 index 0000000000..d6dd913189 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelFactory.java @@ -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 Attribute getAttribute(ManagedType ownerType, Property property, MetadataContext metadataContext) { + AttributeContext attrContext = getAttributeContext( property ); + final Attribute attribute; + if ( attrContext.isCollection() ) { + final Type attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue(), metadataContext ); + @SuppressWarnings( "unchecked" ) + final Class collectionClass = (Class) attrContext.getCollectionClass(); + if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) { + final Type 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 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 Type 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 Type 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 Type buildBasicType(org.hibernate.type.Type type) { + @SuppressWarnings( "unchecked" ) + final Class clazz = type.getReturnedClass(); + return new BasicTypeImpl( clazz, Type.PersistenceType.BASIC ); + } + + private static Type buildEntityType(org.hibernate.type.Type type, MetadataContext context) { + @SuppressWarnings( "unchecked" ) + final Class clazz = type.getReturnedClass(); + final EntityTypeDelegator entityTypeDelegator = new EntityTypeDelegator(); + context.addDelegator( entityTypeDelegator, clazz ); + return entityTypeDelegator; + } + + private static Type buildEmbeddableType(Value value, org.hibernate.type.Type type, MetadataContext context) { + //build embedable type + @SuppressWarnings( "unchecked" ) + final Class clazz = type.getReturnedClass(); + Component component = (Component) value; + @SuppressWarnings( "unchecked") + final Iterator subProperties = component.getPropertyIterator(); + final EmbeddableType embeddableType = new EmbeddableTypeImpl( clazz, subProperties, context ); + context.addEmbeddableType( clazz, embeddableType ); + return embeddableType; + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java new file mode 100644 index 0000000000..38d1c73926 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java @@ -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,EntityType> entities; + private Map, EmbeddableType> embeddables; + + public MetamodelImpl(Iterator classes) { + Map,EntityType> localEntities = new HashMap,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 void buildEntityType(Iterator classes, Map, EntityType> localEntities, MetadataContext context) { + PersistentClass persistentClass = classes.next(); + @SuppressWarnings( "unchecked" ) + final Class clazz = persistentClass.getMappedClass(); + if ( clazz != null ) { + localEntities.put( clazz, new EntityTypeImpl(clazz, persistentClass, context) ); + } + } + + public EntityType entity(Class 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) entityType; + } + + public ManagedType type(Class 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) type; + } + + public EmbeddableType embeddable(Class 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) embeddableType; + } + + public Set> getManagedTypes() { + final Set> managedTypes = new HashSet>( entities.size() + embeddables.size() ); + managedTypes.addAll( entities.values() ); + managedTypes.addAll( embeddables.values() ); + return managedTypes; + } + + public Set> getEntities() { + return new HashSet>(entities.values()); + } + + public Set> getEmbeddables() { + return new HashSet>(embeddables.values()); + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java new file mode 100644 index 0000000000..e2f1bc57b3 --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/PluralAttributeImpl.java @@ -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 implements PluralAttribute { + + private final ManagedType ownerType; + private final Type elementType; + //FIXME member is not serializable + private final Member member; + private final String name; + private final PersistentAttributeType persistentAttributeType; + private final Class collectionClass; + + private PluralAttributeImpl(Builder 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 { + private final Type attributeType; + private final ManagedType type; + private Member member; + private PersistentAttributeType persistentAttributeType; + private Property property; + private Class collectionClass; + private Type keyType; + + + private Builder(ManagedType ownerType, Type attrType, Class collectionClass, Type keyType) { + this.type = ownerType; + this.attributeType = attrType; + this.collectionClass = collectionClass; + this.keyType = keyType; + } + + public Builder member(Member member) { + this.member = member; + return this; + } + + public Builder property(Property property) { + this.property = property; + return this; + } + + public Builder persistentAttributeType(PersistentAttributeType attrType) { + this.persistentAttributeType = attrType; + return this; + } + + public PluralAttributeImpl build() { + if ( Map.class.isAssignableFrom( collectionClass ) ) { + @SuppressWarnings( "unchecked" ) + final Builder,E,K> builder = (Builder,E,K>) this; + @SuppressWarnings( "unchecked" ) + final PluralAttributeImpl result = ( PluralAttributeImpl ) new MapAttributeImpl( + builder + ); + return result; + } + else if ( Set.class.isAssignableFrom( collectionClass ) ) { + @SuppressWarnings( "unchecked" ) + final Builder, E,?> builder = (Builder, E,?>) this; + @SuppressWarnings( "unchecked" ) + final PluralAttributeImpl result = ( PluralAttributeImpl ) new SetAttributeImpl( + builder + ); + return result; + } + else if ( List.class.isAssignableFrom( collectionClass ) ) { + @SuppressWarnings( "unchecked" ) + final Builder, E,?> builder = (Builder, E,?>) this; + @SuppressWarnings( "unchecked" ) + final PluralAttributeImpl result = ( PluralAttributeImpl ) new ListAttributeImpl( + builder + ); + return result; + } + else if ( Collection.class.isAssignableFrom( collectionClass ) ) { + @SuppressWarnings( "unchecked" ) + final Builder,E,?> builder = (Builder, E,?>) this; + @SuppressWarnings( "unchecked" ) + final PluralAttributeImpl result = ( PluralAttributeImpl ) new CollectionAttributeImpl( + builder + ); + return result; + } + throw new UnsupportedOperationException( "Unkown collection: " + collectionClass ); + } + } + + public static Builder create( + ManagedType ownerType, + Type attrType, + Class collectionClass, + Type keyType) { + return new Builder(ownerType, attrType, collectionClass, keyType); + } + + public String getName() { + return name; + } + + public PersistentAttributeType getPersistentAttributeType() { + return persistentAttributeType; + } + + public ManagedType getDeclaringType() { + return ownerType; + } + + public Class getJavaType() { + return collectionClass; + } + + public abstract CollectionType getCollectionType(); + + public Type 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 getBindableJavaType() { + return elementType.getJavaType(); + } + + static class SetAttributeImpl extends PluralAttributeImpl,E> implements SetAttribute { + SetAttributeImpl(Builder,E,?> xceBuilder) { + super( xceBuilder ); + } + + public CollectionType getCollectionType() { + return CollectionType.SET; + } + } + + static class CollectionAttributeImpl extends PluralAttributeImpl,E> implements CollectionAttribute { + CollectionAttributeImpl(Builder,E,?> xceBuilder) { + super( xceBuilder ); + } + + public CollectionType getCollectionType() { + return CollectionType.COLLECTION; + } + } + + static class ListAttributeImpl extends PluralAttributeImpl,E> implements ListAttribute { + ListAttributeImpl(Builder,E,?> xceBuilder) { + super( xceBuilder ); + } + + public CollectionType getCollectionType() { + return CollectionType.LIST; + } + } + + static class MapAttributeImpl extends PluralAttributeImpl,V> implements MapAttribute { + private final Type keyType; + + MapAttributeImpl(Builder,V,K> xceBuilder) { + super( xceBuilder ); + this.keyType = xceBuilder.keyType; + } + + public CollectionType getCollectionType() { + return CollectionType.MAP; + } + + public Class getKeyJavaType() { + return keyType.getJavaType(); + } + + public Type getKeyType() { + return keyType; + } + } +} diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java new file mode 100644 index 0000000000..a5f2ab983d --- /dev/null +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/SingularAttributeImpl.java @@ -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 implements SingularAttribute, Serializable { + private final boolean isId; + private final boolean isVersion; + private final boolean isOptional; + private final ManagedType ownerType; + private final Type attrType; + //FIXME member is not serializable + private final Member member; + private final String name; + private final PersistentAttributeType persistentAttributeType; + + private SingularAttributeImpl(Builder 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 { + private boolean isId; + private boolean isVersion; + //private boolean isOptional = true; + private final Type attributeType; + private final ManagedType type; + private Member member; + //private String name; + private PersistentAttributeType persistentAttributeType; + private Property property; + + + private Builder(ManagedType ownerType, Type attrType) { + this.type = ownerType; + this.attributeType = attrType; + } + + public Builder member(Member member) { + this.member = member; + return this; + } + + public Builder property(Property property) { + this.property = property; + return this; + } + + public Builder id() { + isId = true; + return this; + } + + public Builder version() { + isVersion = true; + return this; + } + + public SingularAttribute build() { + return new SingularAttributeImpl(this); + } + + public Builder persistentAttributeType(PersistentAttributeType attrType) { + this.persistentAttributeType = attrType; + return this; + } + } + + public static Builder create(ManagedType ownerType, Type attrType) { + return new Builder(ownerType, attrType); + } + + public boolean isId() { + return isId; + } + + public boolean isVersion() { + return isVersion; + } + + public boolean isOptional() { + return isOptional; + } + + public Type getType() { + return attrType; + } + + public String getName() { + return name; + } + + public PersistentAttributeType getPersistentAttributeType() { + return persistentAttributeType; + } + + public ManagedType getDeclaringType() { + return ownerType; + } + + public Class 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 getBindableJavaType() { + return attrType.getJavaType(); + } +}