Hibernate SVN: r16207 - in search/trunk: src/java/org/hibernate/search/annotations and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-03-22 22:11:36 -0400 (Sun, 22 Mar 2009)
New Revision: 16207
Added:
search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java
search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java
search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java
search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java
search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java
search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java
search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java
search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java
search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java
search/trunk/src/test/org/hibernate/search/test/configuration/Address.java
search/trunk/src/test/org/hibernate/search/test/configuration/Country.java
search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
search/trunk/src/test/org/hibernate/search/test/configuration/User.java
Modified:
search/trunk/pom.xml
search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java
search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java
search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
Log:
HSEARCH-352 inital commit for the programmatic mapping API
Modified: search/trunk/pom.xml
===================================================================
--- search/trunk/pom.xml 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/pom.xml 2009-03-23 02:11:36 UTC (rev 16207)
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
- <version>3.1.0.GA</version>
+ <version>3.2.0-SNAPSHOT</version>
<name>Hibernate Search</name>
<description>Hibernate Search</description>
<url>http://search.hibernate.org</url>
@@ -32,12 +32,12 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
- <version>3.3.1.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
- <version>3.1.0.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
@@ -198,13 +198,13 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
- <version>3.4.0.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
- <version>3.4.0.GA</version>
+ <version>3.5.0-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependency>
Modified: search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/annotations/Analyzer.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -23,8 +23,7 @@
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE, ElementType.FIELD, ElementType.METHOD} )
@Documented
-
public @interface Analyzer {
- Class impl() default void.class;
+ Class<?> impl() default void.class;
String definition() default "";
}
Added: search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/AnalyzerDefMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,55 @@
+package org.hibernate.search.cfg;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenizerFactory;
+import org.apache.solr.analysis.TokenFilterFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class AnalyzerDefMapping {
+ private SearchMapping mapping;
+ private Map<String, Object> analyzerDef;
+ private Map<String, Object> tokenizer;
+
+ AnalyzerDefMapping(String name, Class<? extends TokenizerFactory> tokenizerFactory, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.analyzerDef = new HashMap<String, Object>();
+ mapping.addAnalyzerDef(analyzerDef);
+ analyzerDef.put( "name", name );
+ tokenizer = new HashMap<String, Object>();
+ tokenizer.put( "factory", tokenizerFactory );
+ analyzerDef.put( "tokenizer", tokenizer );
+ }
+
+ /**
+ * @TokenizerDef(, ... params={@Parameter(name="name", value="value"), ...})
+ */
+ public AnalyzerDefMapping tokenizerParam(String name, String value) {
+ Map<String, Object> param = SearchMapping.addElementToAnnotationArray(tokenizer, "params");
+ param.put("name", name);
+ param.put("value", value);
+ return this;
+ }
+
+ /**
+ * @TokenFilterDef(factory=factory)
+ */
+ public TokenFilterDefMapping filter(Class<? extends TokenFilterFactory> factory) {
+ return new TokenFilterDefMapping(factory, analyzerDef, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/EntityDescriptor.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,79 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EntityDescriptor {
+ private Class<?> entityType;
+ private Map<String, Object> indexed;
+ private Map<PropertyKey, PropertyDescriptor> properties = new HashMap<PropertyKey, PropertyDescriptor>();
+
+ public Map<String, Object> getIndexed() {
+ return indexed;
+ }
+
+ public EntityDescriptor(Class<?> entityType) {
+ this.entityType = entityType;
+ }
+
+ public void setIndexed(Map<String, Object> indexed) {
+ this.indexed = indexed;
+ }
+
+ PropertyDescriptor getProperty(String name, ElementType type) {
+ PropertyKey propertyKey = new PropertyKey( name, type );
+ PropertyDescriptor descriptor = properties.get( propertyKey );
+ if (descriptor == null) {
+ descriptor = new PropertyDescriptor(name, type);
+ properties.put(propertyKey, descriptor);
+ }
+ return descriptor;
+ }
+
+ public PropertyDescriptor getPropertyDescriptor(String name, ElementType type) {
+ return properties.get( new PropertyKey( name, type ) );
+ }
+
+
+ private static class PropertyKey {
+ private String name;
+ private ElementType type;
+
+ PropertyKey(String name, ElementType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+
+ PropertyKey property = ( PropertyKey ) o;
+
+ if ( name != null ? !name.equals( property.name ) : property.name != null ) {
+ return false;
+ }
+ if ( type != property.type ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + ( type != null ? type.hashCode() : 0 );
+ return result;
+ }
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/EntityMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,41 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenizerFactory;
+
+import org.hibernate.search.annotations.Indexed;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class EntityMapping {
+ private SearchMapping mapping;
+ private EntityDescriptor entity;
+
+ public EntityMapping(Class<?> entityType, String name, SearchMapping mapping) {
+ this.mapping = mapping;
+ entity = mapping.getEntity(entityType);
+ Map<String, Object> indexed = new HashMap<String, Object>();
+ if (name != null) indexed.put( "index", name );
+ entity.setIndexed(indexed);
+ }
+
+ public PropertyMapping property(String name, ElementType type) {
+ return new PropertyMapping(name, type, entity, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/FieldMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,78 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenizerFactory;
+
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Store;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class FieldMapping {
+ private SearchMapping mapping;
+ private EntityDescriptor entity;
+ private PropertyDescriptor property;
+ private Map<String, Object> field = new HashMap<String, Object>();
+
+ public FieldMapping(PropertyDescriptor property, EntityDescriptor entity, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.entity = entity;
+ this.mapping = mapping;
+ this.property = property;
+ property.addField(field);
+ }
+
+ public FieldMapping name(String fieldName) {
+ field.put( "name", fieldName );
+ return this;
+ }
+
+ public FieldMapping store(Store store) {
+ field.put( "store", store );
+ return this;
+ }
+
+ public FieldMapping index(Index index) {
+ field.put( "index", index );
+ return this;
+ }
+
+ public FieldMapping analyzer(Class<?> analyzerClass) {
+ final Map<String, Object> analyzer = new HashMap<String, Object>();
+ analyzer.put( "impl", analyzerClass );
+ field.put( "analyzer", analyzer );
+ return this;
+ }
+
+ public FieldMapping analyzer(String analyzerDef) {
+ final Map<String, Object> analyzer = new HashMap<String, Object>();
+ analyzer.put( "definition", analyzerDef );
+ field.put( "analyzer", analyzer );
+ return this;
+ }
+
+ public FieldMapping field() {
+ return new FieldMapping(property, entity, mapping);
+ }
+
+ public PropertyMapping property(String name, ElementType type) {
+ return new PropertyMapping(name, type, entity, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/PropertyDescriptor.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,28 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PropertyDescriptor {
+ private ElementType type;
+ private String name;
+ private Set<Map<String, Object>> fields = new HashSet<Map<String, Object>>();
+
+ public PropertyDescriptor(String name, ElementType type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public void addField(Map<String, Object> field) {
+ fields.add( field );
+ }
+
+ public Set<Map<String, Object>> getFields() {
+ return fields;
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/PropertyMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,40 @@
+package org.hibernate.search.cfg;
+
+import java.lang.annotation.ElementType;
+
+import org.apache.solr.analysis.TokenizerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PropertyMapping {
+ private SearchMapping mapping;
+ private EntityDescriptor entity;
+ private PropertyDescriptor property;
+
+ public PropertyMapping(String name, ElementType type, EntityDescriptor entity, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.entity = entity;
+ property = entity.getProperty(name, type);
+ }
+
+ public FieldMapping field() {
+ return new FieldMapping(property, entity, mapping);
+ }
+
+ public PropertyMapping property(String name, ElementType type) {
+ return new PropertyMapping(name, type, entity, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+}
Modified: search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/cfg/SearchConfiguration.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -52,5 +52,9 @@
*/
ReflectionManager getReflectionManager();
-
+ /**
+ * returns the programmatic configuration or null
+ * //TODO remove hard dep with solr classes
+ */
+ SearchMapping getProgrammaticMapping();
}
Modified: search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -2,8 +2,8 @@
package org.hibernate.search.cfg;
import java.util.Iterator;
+import java.util.NoSuchElementException;
import java.util.Properties;
-import java.util.NoSuchElementException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
@@ -56,6 +56,10 @@
return reflectionManager;
}
+ public SearchMapping getProgrammaticMapping() {
+ return ( SearchMapping ) getProperties().get( "hibernate.search.mapping_model" );
+ }
+
private static class ClassIterator implements Iterator<Class<?>> {
private Iterator hibernatePersistentClassIterator;
private Class<?> future;
Added: search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/SearchMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,67 @@
+package org.hibernate.search.cfg;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.solr.analysis.TokenizerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SearchMapping {
+ private Set<Map<String, Object>> analyzerDefs = new HashSet<Map<String, Object>>();
+ private Map<Class<?>, EntityDescriptor> entities = new HashMap<Class<?>, EntityDescriptor>();
+
+ public Set<Map<String, Object>> getAnalyzerDefs() {
+ return analyzerDefs;
+ }
+
+ public EntityDescriptor getEntityDescriptor(Class<?> entityType) {
+ return entities.get( entityType );
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, this);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, this);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, this);
+ }
+
+ /**
+ * eg @Containing(things={@Thing(...), @Thing(...)}
+ * Map<String, Object> addedThing = addElementToAnnotationArray(containing, "things");
+ */
+ static Map<String, Object> addElementToAnnotationArray(Map<String, Object> containingAnnotation,
+ String attributeName) {
+ List<Map<String, Object>> array = (List<Map<String, Object>>) containingAnnotation.get( attributeName );
+ if ( array == null) {
+ array = new ArrayList<Map<String, Object>>();
+ containingAnnotation.put( attributeName, array );
+ }
+ Map<String, Object> param = new HashMap<String, Object>();
+ array.add( param );
+ return param;
+ }
+
+ void addAnalyzerDef(Map<String, Object> analyzerDef) {
+ analyzerDefs.add( analyzerDef );
+ }
+
+ EntityDescriptor getEntity(Class<?> entityType) {
+ EntityDescriptor entity = entities.get( entityType );
+ if (entity == null) {
+ entity = new EntityDescriptor(entityType);
+ entities.put( entityType, entity );
+ }
+ return entity;
+ }
+}
Added: search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/cfg/TokenFilterDefMapping.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,52 @@
+package org.hibernate.search.cfg;
+
+import java.util.Map;
+
+import org.apache.solr.analysis.TokenFilterFactory;
+import org.apache.solr.analysis.TokenizerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class TokenFilterDefMapping {
+ private Map<String, Object> filter;
+ private Map<String, Object> analyzerDef;
+ private SearchMapping mapping;
+
+ TokenFilterDefMapping(Class<? extends TokenFilterFactory> factory, Map<String, Object> analyzerDef, SearchMapping mapping) {
+ this.mapping = mapping;
+ this.analyzerDef = analyzerDef;
+ this.filter = SearchMapping.addElementToAnnotationArray( analyzerDef, "filters" );
+ filter.put( "factory", factory );
+ }
+
+ /**
+ * @TokenFilterDef(, ... params={@Parameter(name="name", value="value"), ...})
+ */
+ public TokenFilterDefMapping param(String name, String value) {
+ Map<String, Object> param = SearchMapping.addElementToAnnotationArray(filter, "params");
+ param.put("name", name);
+ param.put("value", value);
+ return this;
+ }
+
+ /**
+ * @TokenFilterDef(factory=factory)
+ */
+ public TokenFilterDefMapping filter(Class<? extends TokenFilterFactory> factory) {
+ return new TokenFilterDefMapping(factory, analyzerDef, mapping );
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType) {
+ return new EntityMapping(entityType, null, mapping);
+ }
+
+ public EntityMapping indexedClass(Class<?> entityType, String indexName) {
+ return new EntityMapping(entityType, indexName, mapping);
+ }
+
+ public AnalyzerDefMapping analyzerDef(String name, Class<? extends TokenizerFactory> tokenizerFactory) {
+ return new AnalyzerDefMapping(name, tokenizerFactory, mapping);
+ }
+
+}
Modified: search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/impl/FullTextSessionImpl.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -25,6 +25,7 @@
import org.hibernate.ScrollableResults;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
+import org.hibernate.UnknownProfileException;
import org.hibernate.classic.Session;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.EntityKey;
@@ -32,6 +33,7 @@
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.LoadQueryInfluencers;
import org.hibernate.engine.query.ParameterMetadata;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.event.EventListeners;
@@ -571,6 +573,10 @@
return sessionImplementor.isClosed();
}
+ public LoadQueryInfluencers getLoadQueryInfluencers() {
+ return sessionImplementor.getLoadQueryInfluencers();
+ }
+
public org.hibernate.Session getSession(EntityMode entityMode) {
return session.getSession( entityMode );
}
@@ -706,4 +712,16 @@
public void update(Object object) throws HibernateException {
session.update( object );
}
+
+ public boolean isFetchProfileEnabled(String name) throws UnknownProfileException {
+ return session.isFetchProfileEnabled( name );
+ }
+
+ public void enableFetchProfile(String name) throws UnknownProfileException {
+ session.enableFetchProfile( name );
+ }
+
+ public void disableFetchProfile(String name) throws UnknownProfileException {
+ session.disableFetchProfile( name );
+ }
}
Added: search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/impl/MappingModelMetadataProvider.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,220 @@
+package org.hibernate.search.impl;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.beans.Introspector;
+
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.ReflectionUtil;
+import org.hibernate.annotations.common.reflection.Filter;
+import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
+import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.cfg.EntityDescriptor;
+import org.hibernate.search.cfg.PropertyDescriptor;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Analyzer;
+import org.hibernate.search.annotations.Fields;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class MappingModelMetadataProvider implements MetadataProvider {
+
+ private static final Filter FILTER = new Filter() {
+ public boolean returnStatic() {
+ return false;
+ }
+
+ public boolean returnTransient() {
+ return true;
+ }
+ };
+
+ private final MetadataProvider delegate;
+ private final SearchMapping mapping;
+ private final Map<AnnotatedElement, AnnotationReader> cache = new HashMap<AnnotatedElement, AnnotationReader>(100);
+
+ public MappingModelMetadataProvider(MetadataProvider delegate, SearchMapping mapping) {
+ this.delegate = delegate;
+ this.mapping = mapping;
+ }
+ public Map<Object, Object> getDefaults() {
+ return delegate.getDefaults();
+ }
+
+ public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
+ AnnotationReader reader = cache.get(annotatedElement);
+ if (reader == null) {
+ reader = new MappingModelAnnotationReader( mapping, delegate, annotatedElement);
+ cache.put( annotatedElement, reader );
+ }
+ return reader;
+ }
+
+ private static class MappingModelAnnotationReader implements AnnotationReader {
+ private AnnotationReader delegate;
+ private SearchMapping mapping;
+ private transient Annotation[] annotationsArray;
+ private transient Map<Class<? extends Annotation>, Annotation> annotations;
+ private Class<?> entityType;
+ private ElementType elementType;
+ private String propertyName;
+
+ public MappingModelAnnotationReader(SearchMapping mapping, MetadataProvider delegate, AnnotatedElement el) {
+ this.delegate = delegate.getAnnotationReader( el );
+ this.mapping = mapping;
+ if ( el instanceof Class ) {
+ entityType = (Class) el;
+ }
+ else if ( el instanceof Field ) {
+ Field field = (Field) el;
+ entityType = field.getDeclaringClass();
+ propertyName = field.getName();
+ elementType = ElementType.FIELD;
+ }
+ else if ( el instanceof Method ) {
+ Method method = (Method) el;
+ entityType = method.getDeclaringClass();
+ propertyName = method.getName();
+ if ( ReflectionUtil.isProperty(
+ method,
+ null, //this is yukky!! we'd rather get the TypeEnvironment()
+ FILTER
+ ) ) {
+ if ( propertyName.startsWith( "get" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring( "get".length() ) );
+ }
+ else if ( propertyName.startsWith( "is" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring( "is".length() ) );
+ }
+ else {
+ throw new RuntimeException( "Method " + propertyName + " is not a property getter" );
+ }
+ elementType = ElementType.METHOD;
+ }
+ else {
+ throw new SearchException( "Error in programmatic mapping. Method " + propertyName + " is not a property getter" );
+ }
+ }
+ else {
+ entityType = null;
+ propertyName = null;
+ }
+ }
+
+ /**
+ * Consider the class to be free of Hibernate Search annotations. Does nto attempt to merge
+ * data.
+ * TODO do merge data? or safe-guard against errors
+ */
+ private void initAnnotations() {
+ if ( annotationsArray == null ) {
+ annotations = new HashMap<Class<? extends Annotation>, Annotation>();
+ delegatesAnnotationReading();
+ if (entityType != null) {
+ final EntityDescriptor entity = mapping.getEntityDescriptor( entityType );
+ if (entity != null) {
+ if (propertyName == null) {
+ //entityType overriding
+ createIndexed( entity );
+ }
+ else {
+ final PropertyDescriptor property = entity.getPropertyDescriptor( propertyName, elementType );
+ if (property != null) {
+ // property name overriding
+ createFields( property );
+ }
+ }
+ }
+ }
+ else {
+ delegatesAnnotationReading();
+ }
+
+ populateAnnotationArray();
+ }
+ }
+
+ private void createFields(PropertyDescriptor property) {
+ final Set<Map<String,Object>> fields = property.getFields();
+ List<org.hibernate.search.annotations.Field> fieldAnnotations =
+ new ArrayList<org.hibernate.search.annotations.Field>( fields.size() );
+ for(Map<String, Object> field : fields) {
+ AnnotationDescriptor fieldAnnotation = new AnnotationDescriptor( org.hibernate.search.annotations.Field.class );
+ for ( Map.Entry<String, Object> entry : field.entrySet() ) {
+ if ( entry.getKey().equals( "analyzer" ) ) {
+ AnnotationDescriptor analyzerAnnotation = new AnnotationDescriptor( Analyzer.class );
+ @SuppressWarnings( "unchecked" )
+ Map<String, Object> analyzer = (Map<String, Object>) entry.getValue();
+ for( Map.Entry<String, Object> analyzerEntry : analyzer.entrySet() ) {
+ analyzerAnnotation.setValue( analyzerEntry.getKey(), analyzerEntry.getValue() );
+ }
+ fieldAnnotation.setValue( "analyzer", AnnotationFactory.create( analyzerAnnotation ) );
+ }
+ else {
+ fieldAnnotation.setValue( entry.getKey(), entry.getValue() );
+ }
+ }
+ fieldAnnotations.add( (org.hibernate.search.annotations.Field) AnnotationFactory.create( fieldAnnotation ) );
+ }
+ AnnotationDescriptor fieldsAnnotation = new AnnotationDescriptor( Fields.class );
+
+ final org.hibernate.search.annotations.Field[] fieldArray =
+ new org.hibernate.search.annotations.Field[fieldAnnotations.size()];
+ fieldsAnnotation.setValue( "value", fieldAnnotations.toArray( fieldArray ));
+ annotations.put( Fields.class, AnnotationFactory.create( fieldsAnnotation ) );
+ }
+
+ private void createIndexed(EntityDescriptor entity) {
+ Class<? extends Annotation> annotationType = Indexed.class;
+ AnnotationDescriptor annotation = new AnnotationDescriptor( annotationType );
+ for ( Map.Entry<String, Object> entry : entity.getIndexed().entrySet() ) {
+ annotation.setValue( entry.getKey(), entry.getValue() );
+ }
+ annotations.put( annotationType, AnnotationFactory.create( annotation ) );
+ }
+
+ private void populateAnnotationArray() {
+ annotationsArray = new Annotation[ annotations.size() ];
+ int index = 0;
+ for( Annotation ann: annotations.values() ) {
+ annotationsArray[index] = ann;
+ index++;
+ }
+ }
+
+ private void delegatesAnnotationReading() {
+ for ( Annotation a : delegate.getAnnotations() ) {
+ annotations.put( a.annotationType(), a );
+ }
+ }
+
+ @SuppressWarnings( "unchecked" )
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotations.get( annotationType );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotations.get( annotationType ) != null;
+ }
+
+ public Annotation[] getAnnotations() {
+ initAnnotations();
+ return new Annotation[0]; //To change body of implemented methods use File | Settings | File Templates.
+ }
+ }
+}
Modified: search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2009-03-23 01:53:05 UTC (rev 16206)
+++ search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -21,6 +21,8 @@
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
import org.hibernate.annotations.common.util.StringHelper;
import org.hibernate.search.Environment;
@@ -39,6 +41,7 @@
import org.hibernate.search.backend.WorkerFactory;
import org.hibernate.search.backend.configuration.ConfigurationParseHelper;
import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.cfg.SearchMapping;
import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
import org.hibernate.search.engine.FilterDef;
import org.hibernate.search.engine.SearchFactoryImplementor;
@@ -111,10 +114,8 @@
}
public SearchFactoryImpl(SearchConfiguration cfg) {
- ReflectionManager reflectionManager = cfg.getReflectionManager();
- if ( reflectionManager == null ) {
- reflectionManager = new JavaReflectionManager();
- }
+ ReflectionManager reflectionManager = getReflectionManager(cfg);
+
this.indexingStrategy = defineIndexingStrategy( cfg ); //need to be done before the document builds
initDocumentBuilders( cfg, reflectionManager );
@@ -135,6 +136,25 @@
this.barrier = 1; //write barrier
}
+ private ReflectionManager getReflectionManager(SearchConfiguration cfg) {
+ ReflectionManager reflectionManager = cfg.getReflectionManager();
+ if ( reflectionManager == null ) {
+ reflectionManager = new JavaReflectionManager();
+ }
+ final SearchMapping mapping = cfg.getProgrammaticMapping();
+ if ( mapping != null) {
+ if ( ! ( reflectionManager instanceof MetadataProviderInjector)) {
+ throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
+ + MetadataProviderInjector.class.getName() );
+ }
+ MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
+ MetadataProvider original = injector.getMetadataProvider();
+ injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
+
+ }
+ return reflectionManager;
+ }
+
private static String defineIndexingStrategy(SearchConfiguration cfg) {
String indexingStrategy = cfg.getProperties().getProperty( Environment.INDEXING_STRATEGY, "event" );
if ( !( "event".equals( indexingStrategy ) || "manual".equals( indexingStrategy ) ) ) {
Added: search/trunk/src/test/org/hibernate/search/test/configuration/Address.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/Address.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/Address.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,44 @@
+package org.hibernate.search.test.configuration;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Address {
+ @Id
+ @GeneratedValue
+ private Long id;
+ private String street1;
+ private String street2;
+ @ManyToOne
+ private Country country;
+
+ public String getStreet1() {
+ return street1;
+ }
+
+ public void setStreet1(String street1) {
+ this.street1 = street1;
+ }
+
+ public Country getCountry() {
+ return country;
+ }
+
+ public void setCountry(Country country) {
+ this.country = country;
+ }
+
+ public String getStreet2() {
+ return street2;
+ }
+
+ public void setStreet2(String street2) {
+ this.street2 = street2;
+ }
+}
Added: search/trunk/src/test/org/hibernate/search/test/configuration/Country.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/Country.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/Country.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,24 @@
+package org.hibernate.search.test.configuration;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Country {
+ @Id
+ @GeneratedValue
+ private Long id;
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,107 @@
+package org.hibernate.search.test.configuration;
+
+import java.lang.annotation.ElementType;
+
+import org.apache.solr.analysis.StandardTokenizerFactory;
+import org.apache.solr.analysis.SnowballPorterFilterFactory;
+import org.apache.solr.analysis.LowerCaseFilterFactory;
+import org.apache.solr.analysis.NGramFilterFactory;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.annotations.Store;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.test.analyzer.inheritance.ISOLatin1Analyzer;
+import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.FullTextQuery;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.Transaction;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ProgrammaticMappingTest extends SearchTestCase {
+
+ public void testMapping() throws Exception{
+ Address address = new Address();
+ address.setStreet1( "3340 Peachtree Rd NE" );
+ address.setStreet2( "JBoss" );
+
+ FullTextSession s = Search.getFullTextSession( openSession() );
+ Transaction tx = s.beginTransaction();
+ s.persist( address );
+ tx.commit();
+
+ s.clear();
+
+ tx = s.beginTransaction();
+
+ QueryParser parser = new QueryParser( "id", new StandardAnalyzer() );
+ org.apache.lucene.search.Query luceneQuery = parser.parse( "street1:peachtree" );
+ FullTextQuery query = s.createFullTextQuery( luceneQuery ).setProjection( "idx_street2", FullTextQuery.THIS );
+ assertEquals( "Not properly indexed", 1, query.getResultSize() );
+ Object[] firstResult = (Object[]) query.list().get( 0 );
+ assertEquals( "@Field.store not respected", "JBoss", firstResult[0] );
+
+ s.delete( firstResult[1] );
+ tx.commit();
+ s.close();
+
+ }
+
+ @Override
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ SearchMapping mapping = new SearchMapping();
+ mapping.indexedClass( Address.class )
+ .property( "street1", ElementType.FIELD )
+ .field()
+ .property( "street2", ElementType.METHOD )
+ .field().name( "idx_street2" )
+ .store( Store.YES );
+ cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
+ }
+
+ public void NotUseddefineMapping() {
+ SearchMapping mapping = new SearchMapping();
+ mapping.analyzerDef( "stem", StandardTokenizerFactory.class )
+ .tokenizerParam( "name", "value" )
+ .tokenizerParam( "name2", "value2" )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( SnowballPorterFilterFactory.class)
+ .param("language", "English")
+ .analyzerDef( "ngram", StandardTokenizerFactory.class )
+ .tokenizerParam( "name", "value" )
+ .tokenizerParam( "name2", "value2" )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( NGramFilterFactory.class)
+ .param("minGramSize", "3")
+ .param("maxGramSize", "3")
+ .indexedClass(Address.class, "Address_Index")
+ .property("street1", ElementType.FIELD)
+ .field()
+ .field()
+ .name("street1_iso")
+ .store( Store.YES )
+ .index( Index.TOKENIZED )
+ .analyzer( ISOLatin1Analyzer.class)
+ .field()
+ .name("street1_ngram")
+ .analyzer("ngram")
+ .indexedClass(User.class)
+ .property("name", ElementType.METHOD)
+ .field()
+ .analyzerDef( "minimal", StandardTokenizerFactory.class );
+
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ Address.class,
+ Country.class
+ };
+ }
+}
\ No newline at end of file
Added: search/trunk/src/test/org/hibernate/search/test/configuration/User.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/configuration/User.java (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/configuration/User.java 2009-03-23 02:11:36 UTC (rev 16207)
@@ -0,0 +1,16 @@
+package org.hibernate.search.test.configuration;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class User {
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
15 years, 9 months
Hibernate SVN: r16206 - in core/trunk: annotations/src/main/java/org/hibernate/cfg/annotations and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-03-22 21:53:05 -0400 (Sun, 22 Mar 2009)
New Revision: 16206
Added:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/JPAOverridenAnnotationReaderTest.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java
Removed:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3OverridenAnnotationReader.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3ReflectionManager.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/EJB3OverridenAnnotationReaderTest.java
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/Version.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Version.java
Log:
HCANN-5 Introdice the MetadataProvider and MetadataProviderInjector facility
ANN-810 Use the new MetadataProvider facility to implement EJB3 overriding
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -41,46 +41,49 @@
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;
-
+import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
-import javax.persistence.Embeddable;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
import org.hibernate.AnnotationException;
+import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
-import org.hibernate.DuplicateMappingException;
-import org.hibernate.engine.NamedQueryDefinition;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.annotations.AnyMetaDef;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
import org.hibernate.cfg.annotations.Version;
-import org.hibernate.cfg.annotations.reflection.EJB3ReflectionManager;
+import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.event.EventListeners;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.mapping.Column;
+import org.hibernate.mapping.IdGenerator;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
-import org.hibernate.mapping.IdGenerator;
import org.hibernate.util.JoinedIterator;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
/**
* Similar to the {@link Configuration} object but handles EJB3 and Hibernate
@@ -250,7 +253,9 @@
namingStrategy = EJB3NamingStrategy.INSTANCE;
setEntityResolver( new EJB3DTDEntityResolver() );
anyMetaDefs = new HashMap<String, AnyMetaDef>();
- reflectionManager = new EJB3ReflectionManager();
+ reflectionManager = new JavaReflectionManager();
+ ((MetadataProviderInjector) reflectionManager).setMetadataProvider( new JPAMetadataProvider() );
+
}
@Override
@@ -688,7 +693,9 @@
hbmDocuments.add( doc );
}
else {
- List<String> classnames = ( (EJB3ReflectionManager) reflectionManager ).getXMLContext().addDocument( doc );
+ final MetadataProvider metadataProvider = ( ( MetadataProviderInjector ) reflectionManager ).getMetadataProvider();
+ JPAMetadataProvider jpaMetadataProvider = (JPAMetadataProvider) metadataProvider;
+ List<String> classnames = jpaMetadataProvider.getXMLContext().addDocument( doc );
for (String classname : classnames) {
try {
annotatedClasses.add( reflectionManager.classForName( classname, this.getClass() ) );
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -30,7 +30,7 @@
* @author Emmanuel Bernard
*/
public class Version {
- public static final String VERSION = "3.4.0.GA";
+ public static final String VERSION = "3.5.0-SNAPSHOT";
private static Logger log = LoggerFactory.getLogger( Version.class );
static {
Deleted: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3OverridenAnnotationReader.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3OverridenAnnotationReader.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3OverridenAnnotationReader.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -1,2104 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.cfg.annotations.reflection;
-
-import java.beans.Introspector;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.persistence.AssociationOverride;
-import javax.persistence.AssociationOverrides;
-import javax.persistence.AttributeOverride;
-import javax.persistence.AttributeOverrides;
-import javax.persistence.Basic;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.ColumnResult;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Embeddable;
-import javax.persistence.Embedded;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.EntityListeners;
-import javax.persistence.EntityResult;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.ExcludeDefaultListeners;
-import javax.persistence.ExcludeSuperclassListeners;
-import javax.persistence.FetchType;
-import javax.persistence.FieldResult;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinColumns;
-import javax.persistence.JoinTable;
-import javax.persistence.Lob;
-import javax.persistence.ManyToMany;
-import javax.persistence.ManyToOne;
-import javax.persistence.MapKey;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.NamedNativeQueries;
-import javax.persistence.NamedNativeQuery;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.OrderBy;
-import javax.persistence.PostLoad;
-import javax.persistence.PostPersist;
-import javax.persistence.PostRemove;
-import javax.persistence.PostUpdate;
-import javax.persistence.PrePersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PreUpdate;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.PrimaryKeyJoinColumns;
-import javax.persistence.QueryHint;
-import javax.persistence.SecondaryTable;
-import javax.persistence.SecondaryTables;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.SqlResultSetMappings;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import javax.persistence.Transient;
-import javax.persistence.UniqueConstraint;
-import javax.persistence.Version;
-
-import org.dom4j.Attribute;
-import org.dom4j.Element;
-import org.hibernate.AnnotationException;
-import org.hibernate.annotations.AccessType;
-import org.hibernate.annotations.CollectionOfElements;
-import org.hibernate.annotations.Columns;
-import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
-import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
-import org.hibernate.annotations.common.reflection.AnnotationReader;
-import org.hibernate.annotations.common.reflection.Filter;
-import org.hibernate.annotations.common.reflection.ReflectionUtil;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Encapsulates the overriding of Java annotations from an EJB 3.0 descriptor.
- *
- * @author Paolo Perrotta
- * @author Davide Marchignoli
- * @author Emmanuel Bernard
- */
-@SuppressWarnings("unchecked")
-public class EJB3OverridenAnnotationReader implements AnnotationReader {
- private Logger log = LoggerFactory.getLogger( EJB3OverridenAnnotationReader.class );
- private static final Map<Class, String> annotationToXml;
- private static final String SCHEMA_VALIDATION = "Activate schema validation for more informations";
- private static final Filter FILTER = new Filter() {
- public boolean returnStatic() {
- return false;
- }
-
- public boolean returnTransient() {
- return false;
- }
- };
-
- static {
- annotationToXml = new HashMap<Class, String>();
- annotationToXml.put( Entity.class, "entity" );
- annotationToXml.put( MappedSuperclass.class, "mapped-superclass" );
- annotationToXml.put( Embeddable.class, "embeddable" );
- annotationToXml.put( Table.class, "table" );
- annotationToXml.put( SecondaryTable.class, "secondary-table" );
- annotationToXml.put( SecondaryTables.class, "secondary-table" );
- annotationToXml.put( PrimaryKeyJoinColumn.class, "primary-key-join-column" );
- annotationToXml.put( PrimaryKeyJoinColumns.class, "primary-key-join-column" );
- annotationToXml.put( IdClass.class, "id-class" );
- annotationToXml.put( Inheritance.class, "inheritance" );
- annotationToXml.put( DiscriminatorValue.class, "discriminator-value" );
- annotationToXml.put( DiscriminatorColumn.class, "discriminator-column" );
- annotationToXml.put( SequenceGenerator.class, "sequence-generator" );
- annotationToXml.put( TableGenerator.class, "table-generator" );
- annotationToXml.put( NamedQuery.class, "named-query" );
- annotationToXml.put( NamedQueries.class, "named-query" );
- annotationToXml.put( NamedNativeQuery.class, "named-native-query" );
- annotationToXml.put( NamedNativeQueries.class, "named-native-query" );
- annotationToXml.put( SqlResultSetMapping.class, "sql-result-set-mapping" );
- annotationToXml.put( SqlResultSetMappings.class, "sql-result-set-mapping" );
- annotationToXml.put( ExcludeDefaultListeners.class, "exclude-default-listeners" );
- annotationToXml.put( ExcludeSuperclassListeners.class, "exclude-superclass-listeners" );
- annotationToXml.put( AccessType.class, "access" );
- annotationToXml.put( AttributeOverride.class, "attribute-override" );
- annotationToXml.put( AttributeOverrides.class, "attribute-override" );
- annotationToXml.put( AttributeOverride.class, "association-override" );
- annotationToXml.put( AttributeOverrides.class, "association-override" );
- annotationToXml.put( Id.class, "id" );
- annotationToXml.put( EmbeddedId.class, "embedded-id" );
- annotationToXml.put( GeneratedValue.class, "generated-value" );
- annotationToXml.put( Column.class, "column" );
- annotationToXml.put( Columns.class, "column" );
- annotationToXml.put( Temporal.class, "temporal" );
- annotationToXml.put( Lob.class, "lob" );
- annotationToXml.put( Enumerated.class, "enumerated" );
- annotationToXml.put( Version.class, "version" );
- annotationToXml.put( Transient.class, "transient" );
- annotationToXml.put( Basic.class, "basic" );
- annotationToXml.put( Embedded.class, "embedded" );
- annotationToXml.put( ManyToOne.class, "many-to-one" );
- annotationToXml.put( OneToOne.class, "one-to-one" );
- annotationToXml.put( OneToMany.class, "one-to-many" );
- annotationToXml.put( ManyToMany.class, "many-to-many" );
- annotationToXml.put( JoinTable.class, "join-table" );
- annotationToXml.put( JoinColumn.class, "join-column" );
- annotationToXml.put( JoinColumns.class, "join-column" );
- annotationToXml.put( MapKey.class, "map-key" );
- annotationToXml.put( OrderBy.class, "order-by" );
- annotationToXml.put( EntityListeners.class, "entity-listeners" );
- annotationToXml.put( PrePersist.class, "pre-persist" );
- annotationToXml.put( PreRemove.class, "pre-remove" );
- annotationToXml.put( PreUpdate.class, "pre-update" );
- annotationToXml.put( PostPersist.class, "post-persist" );
- annotationToXml.put( PostRemove.class, "post-remove" );
- annotationToXml.put( PostUpdate.class, "post-update" );
- annotationToXml.put( PostLoad.class, "post-load" );
- }
-
- private XMLContext xmlContext;
- private String className;
- private String propertyName;
- private PropertyType propertyType;
- private transient Annotation[] annotations;
- private transient Map<Class, Annotation> annotationsMap;
- private static final String WORD_SEPARATOR = "-";
- private transient List<Element> elementsForProperty;
- private AccessibleObject mirroredAttribute;
- private final AnnotatedElement element;
-
- private enum PropertyType {
- PROPERTY,
- FIELD,
- METHOD
- }
-
- public EJB3OverridenAnnotationReader(AnnotatedElement el, XMLContext xmlContext) {
- this.element = el;
- this.xmlContext = xmlContext;
- if ( el instanceof Class ) {
- Class clazz = (Class) el;
- className = clazz.getName();
- }
- else if ( el instanceof Field ) {
- Field field = (Field) el;
- className = field.getDeclaringClass().getName();
- propertyName = field.getName();
- propertyType = PropertyType.FIELD;
- String expectedGetter = "get" + Character.toUpperCase( propertyName.charAt( 0 ) ) + propertyName.substring(
- 1
- );
- try {
- mirroredAttribute = field.getDeclaringClass().getDeclaredMethod( expectedGetter );
- }
- catch (NoSuchMethodException e) {
- //no method
- }
- }
- else if ( el instanceof Method ) {
- Method method = (Method) el;
- className = method.getDeclaringClass().getName();
- propertyName = method.getName();
- if ( ReflectionUtil.isProperty(
- method,
- null, //this is yukky!! we'd rather get the TypeEnvironment()
- FILTER
- ) ) {
- if ( propertyName.startsWith( "get" ) ) {
- propertyName = Introspector.decapitalize( propertyName.substring( "get".length() ) );
- }
- else if ( propertyName.startsWith( "is" ) ) {
- propertyName = Introspector.decapitalize( propertyName.substring( "is".length() ) );
- }
- else {
- throw new RuntimeException( "Method " + propertyName + " is not a property getter" );
- }
- propertyType = PropertyType.PROPERTY;
- try {
- mirroredAttribute = method.getDeclaringClass().getDeclaredField( propertyName );
- }
- catch (NoSuchFieldException e) {
- //no method
- }
- }
- else {
- propertyType = PropertyType.METHOD;
- }
- }
- else {
- className = null;
- propertyName = null;
- }
- }
-
- public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
- initAnnotations();
- return (T) annotationsMap.get( annotationType );
- }
-
- public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) {
- initAnnotations();
- return (T) annotationsMap.get( annotationType ) != null;
- }
-
- public Annotation[] getAnnotations() {
- initAnnotations();
- return annotations;
- }
-
- private void initAnnotations() {
- if ( annotations == null ) {
- XMLContext.Default defaults = xmlContext.getDefault( className );
- if ( className != null && propertyName == null ) {
- //is a class
- Element tree = xmlContext.getXMLTree( className, null );
- Annotation[] annotations = getJavaAnnotations();
- List<Annotation> annotationList = new ArrayList<Annotation>( annotations.length + 5 );
- annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
- for (Annotation annotation : annotations) {
- if ( !annotationToXml.containsKey( annotation.annotationType() ) ) {
- //unknown annotations are left over
- annotationList.add( annotation );
- }
- }
- addIfNotNull( annotationList, getEntity( tree, defaults ) );
- addIfNotNull( annotationList, getMappedSuperclass( tree, defaults ) );
- addIfNotNull( annotationList, getEmbeddable( tree, defaults ) );
- addIfNotNull( annotationList, getTable( tree, defaults ) );
- addIfNotNull( annotationList, getSecondaryTables( tree, defaults ) );
- addIfNotNull( annotationList, getPrimaryKeyJoinColumns( tree, defaults ) );
- addIfNotNull( annotationList, getIdClass( tree, defaults ) );
- addIfNotNull( annotationList, getInheritance( tree, defaults ) );
- addIfNotNull( annotationList, getDiscriminatorValue( tree, defaults ) );
- addIfNotNull( annotationList, getDiscriminatorColumn( tree, defaults ) );
- addIfNotNull( annotationList, getSequenceGenerator( tree, defaults ) );
- addIfNotNull( annotationList, getTableGenerator( tree, defaults ) );
- addIfNotNull( annotationList, getNamedQueries( tree, defaults ) );
- addIfNotNull( annotationList, getNamedNativeQueries( tree, defaults ) );
- addIfNotNull( annotationList, getSqlResultSetMappings( tree, defaults ) );
- addIfNotNull( annotationList, getExcludeDefaultListeners( tree, defaults ) );
- addIfNotNull( annotationList, getExcludeSuperclassListeners( tree, defaults ) );
- addIfNotNull( annotationList, getAccessType( tree, defaults ) );
- addIfNotNull( annotationList, getAttributeOverrides( tree, defaults ) );
- addIfNotNull( annotationList, getAssociationOverrides( tree, defaults ) );
- addIfNotNull( annotationList, getEntityListeners( tree, defaults ) );
- //FIXME use annotationsMap rather than annotationList this will be faster since the annotation type is usually known at put() time
- this.annotations = annotationList.toArray( new Annotation[annotationList.size()] );
- for (Annotation ann : this.annotations) {
- annotationsMap.put( ann.annotationType(), ann );
- }
- checkForOrphanProperties( tree );
- }
- else if ( className != null ) { //&& propertyName != null ) { //always true but less confusing
- Element tree = xmlContext.getXMLTree( className, propertyName );
- Annotation[] annotations = getJavaAnnotations();
- List<Annotation> annotationList = new ArrayList<Annotation>( annotations.length + 5 );
- annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
- for (Annotation annotation : annotations) {
- if ( !annotationToXml.containsKey( annotation.annotationType() ) ) {
- //unknown annotations are left over
- annotationList.add( annotation );
- }
- }
- preCalculateElementsForProperty( tree );
- Transient transientAnn = getTransient( defaults );
- if ( transientAnn != null ) {
- annotationList.add( transientAnn );
- }
- else {
- if ( defaults.canUseJavaAnnotations() ) {
- Annotation annotation = getJavaAnnotation( AccessType.class );
- addIfNotNull( annotationList, annotation );
- }
- getId( annotationList, defaults );
- getEmbeddedId( annotationList, defaults );
- getEmbedded( annotationList, defaults );
- getBasic( annotationList, defaults );
- getVersion( annotationList, defaults );
- getAssociation( ManyToOne.class, annotationList, defaults );
- getAssociation( OneToOne.class, annotationList, defaults );
- getAssociation( OneToMany.class, annotationList, defaults );
- getAssociation( ManyToMany.class, annotationList, defaults );
- addIfNotNull( annotationList, getSequenceGenerator( elementsForProperty, defaults ) );
- addIfNotNull( annotationList, getTableGenerator( elementsForProperty, defaults ) );
- addIfNotNull( annotationList, getAttributeOverrides( elementsForProperty, defaults ) );
-
- }
- processEventAnnotations( annotationList, defaults );
- //FIXME use annotationsMap rather than annotationList this will be faster since the annotation type is usually known at put() time
- this.annotations = annotationList.toArray( new Annotation[annotationList.size()] );
- for (Annotation ann : this.annotations) {
- annotationsMap.put( ann.annotationType(), ann );
- }
- }
- else {
- this.annotations = getJavaAnnotations();
- annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
- for (Annotation ann : this.annotations) {
- annotationsMap.put( ann.annotationType(), ann );
- }
- }
- }
- }
-
- private void checkForOrphanProperties(Element tree) {
- Class clazz;
- try {
- clazz = ReflectHelper.classForName( className, this.getClass() );
- }
- catch (ClassNotFoundException e) {
- return; //a primitive type most likely
- }
- Element element = tree != null ? tree.element( "attributes" ) : null;
- //put entity.attributes elements
- if ( element != null ) {
- //precompute the list of properties
- //TODO is it really useful...
- Set<String> properties = new HashSet<String>();
- for (Field field : clazz.getFields()) {
- properties.add( field.getName() );
- }
- for (Method method : clazz.getMethods()) {
- String name = method.getName();
- if ( name.startsWith( "get" ) ) {
- properties.add( Introspector.decapitalize( name.substring( "get".length() ) ) );
- }
- else if ( name.startsWith( "is" ) ) {
- properties.add( Introspector.decapitalize( name.substring( "is".length() ) ) );
- }
- }
- for (Element subelement : (List<Element>) element.elements()) {
- String propertyName = subelement.attributeValue( "name" );
- if ( !properties.contains( propertyName ) ) {
- log.warn( "Property {} not found in class"
- + " but described in <mapping-file/> (possible typo error)",
- StringHelper.qualify( className, propertyName ) );
- }
- }
- }
- }
-
- /**
- * Addes the Annotation to the list (only if it's not null) and then returns it.
- */
- private Annotation addIfNotNull(List<Annotation> annotationList, Annotation element) {
- if ( element != null ) {
- annotationList.add( element );
- }
- return element;
- }
-
- //TODO mutualize the next 2 methods
- private Annotation getTableGenerator(List<Element> elementsForProperty, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- Element subelement = element != null ? element.element( annotationToXml.get( TableGenerator.class ) ) : null;
- if ( subelement != null ) {
- return buildTableGeneratorAnnotation( subelement, defaults );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( TableGenerator.class );
- }
- else {
- return null;
- }
- }
-
-
- private Annotation getSequenceGenerator(List<Element> elementsForProperty, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- Element subelement = element != null ? element.element( annotationToXml.get( SequenceGenerator.class ) ) : null;
- if ( subelement != null ) {
- return buildSequenceGeneratorAnnotation( subelement );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( SequenceGenerator.class );
- }
- else {
- return null;
- }
- }
-
- private void processEventAnnotations(List<Annotation> annotationList, XMLContext.Default defaults) {
- boolean eventElement = false;
- for (Element element : elementsForProperty) {
- String elementName = element.getName();
- if ( "pre-persist".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PrePersist.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- else if ( "pre-remove".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PreRemove.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- else if ( "pre-update".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PreUpdate.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- else if ( "post-persist".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PostPersist.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- else if ( "post-remove".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PostRemove.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- else if ( "post-update".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PostUpdate.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- else if ( "post-load".equals( elementName ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PostLoad.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- eventElement = true;
- }
- }
- if ( !eventElement && defaults.canUseJavaAnnotations() ) {
- Annotation ann = getJavaAnnotation( PrePersist.class );
- addIfNotNull( annotationList, ann );
- ann = getJavaAnnotation( PreRemove.class );
- addIfNotNull( annotationList, ann );
- ann = getJavaAnnotation( PreUpdate.class );
- addIfNotNull( annotationList, ann );
- ann = getJavaAnnotation( PostPersist.class );
- addIfNotNull( annotationList, ann );
- ann = getJavaAnnotation( PostRemove.class );
- addIfNotNull( annotationList, ann );
- ann = getJavaAnnotation( PostUpdate.class );
- addIfNotNull( annotationList, ann );
- ann = getJavaAnnotation( PostLoad.class );
- addIfNotNull( annotationList, ann );
- }
- }
-
- private EntityListeners getEntityListeners(Element tree, XMLContext.Default defaults) {
- Element element = tree != null ? tree.element( "entity-listeners" ) : null;
- if ( element != null ) {
- List<Class> entityListenerClasses = new ArrayList<Class>();
- for (Element subelement : (List<Element>) element.elements( "entity-listener" )) {
- String className = subelement.attributeValue( "class" );
- try {
- entityListenerClasses.add(
- ReflectHelper.classForName(
- XMLContext.buildSafeClassName( className, defaults ),
- this.getClass()
- )
- );
- }
- catch (ClassNotFoundException e) {
- throw new AnnotationException(
- "Unable to find " + element.getPath() + ".class: " + className, e
- );
- }
- }
- AnnotationDescriptor ad = new AnnotationDescriptor( EntityListeners.class );
- ad.setValue( "value", entityListenerClasses.toArray( new Class[entityListenerClasses.size()] ) );
- return AnnotationFactory.create( ad );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( EntityListeners.class );
- }
- else {
- return null;
- }
- }
-
- private JoinTable overridesDefaultsInJoinTable(Annotation annotation, XMLContext.Default defaults) {
- //no element but might have some default or some annotation
- boolean defaultToJoinTable = !( isJavaAnnotationPresent( JoinColumn.class )
- || isJavaAnnotationPresent( JoinColumns.class ) );
- final Class<? extends Annotation> annotationClass = annotation.annotationType();
- defaultToJoinTable = defaultToJoinTable &&
- ( ( annotationClass == ManyToMany.class && StringHelper.isEmpty( ( (ManyToMany) annotation ).mappedBy() ) )
- || ( annotationClass == OneToMany.class && StringHelper.isEmpty( ( (OneToMany) annotation ).mappedBy() ) )
- || ( annotationClass == CollectionOfElements.class )
- );
- final Class<JoinTable> annotationType = JoinTable.class;
- if ( defaultToJoinTable
- && ( StringHelper.isNotEmpty( defaults.getCatalog() )
- || StringHelper.isNotEmpty( defaults.getSchema() ) ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
- if ( defaults.canUseJavaAnnotations() ) {
- JoinTable table = getJavaAnnotation( annotationType );
- if ( table != null ) {
- ad.setValue( "name", table.name() );
- ad.setValue( "schema", table.schema() );
- ad.setValue( "catalog", table.catalog() );
- ad.setValue( "uniqueConstraints", table.uniqueConstraints() );
- ad.setValue( "joinColumns", table.joinColumns() );
- ad.setValue( "inverseJoinColumns", table.inverseJoinColumns() );
- }
- }
- if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) )
- && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- ad.setValue( "schema", defaults.getSchema() );
- }
- if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) )
- && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
- ad.setValue( "catalog", defaults.getCatalog() );
- }
- return AnnotationFactory.create( ad );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( annotationType );
- }
- else {
- return null;
- }
- }
-
- /*
- * no partial overriding possible
- */
- private void getJoinTable(List<Annotation> annotationList, Element tree, XMLContext.Default defaults) {
- Element subelement = tree == null ? null : tree.element( "join-table" );
- final Class<JoinTable> annotationType = JoinTable.class;
- if ( subelement != null ) {
- //ignore java annotation, an element is defined
- AnnotationDescriptor annotation = new AnnotationDescriptor( annotationType );
- copyStringAttribute( annotation, subelement, "name", false );
- copyStringAttribute( annotation, subelement, "catalog", false );
- if ( StringHelper.isNotEmpty( defaults.getCatalog() )
- && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
- annotation.setValue( "catalog", defaults.getCatalog() );
- }
- copyStringAttribute( annotation, subelement, "schema", false );
- if ( StringHelper.isNotEmpty( defaults.getSchema() )
- && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
- annotation.setValue( "schema", defaults.getSchema() );
- }
- buildUniqueConstraints( annotation, subelement );
- annotation.setValue( "joinColumns", getJoinColumns( subelement, false ) );
- annotation.setValue( "inverseJoinColumns", getJoinColumns( subelement, true ) );
- annotationList.add( AnnotationFactory.create( annotation ) );
- }
- }
-
- private void getAssociation(
- Class<? extends Annotation> annotationType, List<Annotation> annotationList, XMLContext.Default defaults
- ) {
- String xmlName = annotationToXml.get( annotationType );
- for (Element element : elementsForProperty) {
- if ( xmlName.equals( element.getName() ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
- String className = element.attributeValue( "target-entity" );
- if ( className != null ) {
- Class clazz;
- try {
- clazz = ReflectHelper.classForName(
- XMLContext.buildSafeClassName( className, defaults ),
- this.getClass()
- );
- }
- catch (ClassNotFoundException e) {
- throw new AnnotationException(
- "Unable to find " + element.getPath() + "target-entity: " + className, e
- );
- }
- ad.setValue( "targetEntity", clazz );
- }
- getFetchType( ad, element );
- getCascades( ad, element, defaults );
- getJoinTable( annotationList, element, defaults );
- buildJoinColumns( annotationList, element, defaults );
- Annotation annotation = getPrimaryKeyJoinColumns( element, defaults );
- addIfNotNull( annotationList, annotation );
- copyBooleanAttribute( ad, element, "optional" );
- copyStringAttribute( ad, element, "mapped-by", false );
- getOrderBy( annotationList, element, defaults );
- getMapKey( annotationList, element, defaults );
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- Annotation annotation = getJavaAnnotation( annotationType );
- if ( annotation != null ) {
- annotationList.add( annotation );
- annotation = overridesDefaultsInJoinTable( annotation, defaults );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( JoinColumn.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( JoinColumns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( MapKey.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( OrderBy.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Lob.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Enumerated.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Temporal.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Column.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Columns.class );
- addIfNotNull( annotationList, annotation );
- }
- else if ( isJavaAnnotationPresent( CollectionOfElements.class ) ) {
- annotation = overridesDefaultsInJoinTable( getJavaAnnotation( CollectionOfElements.class ), defaults );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( JoinColumn.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( JoinColumns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( MapKey.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( OrderBy.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Lob.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Enumerated.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Temporal.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Column.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Columns.class );
- addIfNotNull( annotationList, annotation );
- }
- }
- }
-
- private void getOrderBy(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
- Element subelement = element != null ? element.element( "order-by" ) : null;
- if ( subelement != null ) {
- String orderByString = subelement.getTextTrim();
- AnnotationDescriptor ad = new AnnotationDescriptor( OrderBy.class );
- if ( StringHelper.isNotEmpty( orderByString ) ) ad.setValue( "value", orderByString );
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
-
- private void getMapKey(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
- Element subelement = element != null ? element.element( "map-key" ) : null;
- if ( subelement != null ) {
- String mapKeyString = subelement.attributeValue( "name" );
- AnnotationDescriptor ad = new AnnotationDescriptor( MapKey.class );
- if ( StringHelper.isNotEmpty( mapKeyString ) ) ad.setValue( "name", mapKeyString );
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
-
- private void buildJoinColumns(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
- JoinColumn[] joinColumns = getJoinColumns( element, false );
- if ( joinColumns.length > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( JoinColumns.class );
- ad.setValue( "value", joinColumns );
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
-
- private void getCascades(AnnotationDescriptor ad, Element element, XMLContext.Default defaults) {
- List<Element> elements = element != null ? element.elements( "cascade" ) : new ArrayList<Element>( 0 );
- List<CascadeType> cascades = new ArrayList<CascadeType>();
- for (Element subelement : elements) {
- if ( subelement.element( "cascade-all" ) != null ) cascades.add( CascadeType.ALL );
- if ( subelement.element( "cascade-persist" ) != null ) cascades.add( CascadeType.PERSIST );
- if ( subelement.element( "cascade-merge" ) != null ) cascades.add( CascadeType.MERGE );
- if ( subelement.element( "cascade-remove" ) != null ) cascades.add( CascadeType.REMOVE );
- if ( subelement.element( "cascade-refresh" ) != null ) cascades.add( CascadeType.REFRESH );
- }
- if ( Boolean.TRUE.equals( defaults.getCascadePersist() )
- && !cascades.contains( CascadeType.ALL ) && !cascades.contains( CascadeType.PERSIST ) ) {
- cascades.add( CascadeType.PERSIST );
- }
- if ( cascades.size() > 0 ) {
- ad.setValue( "cascade", cascades.toArray( new CascadeType[cascades.size()] ) );
- }
- }
-
- private void getEmbedded(List<Annotation> annotationList, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- if ( "embedded".equals( element.getName() ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( Embedded.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- Annotation annotation = getJavaAnnotation( Embedded.class );
- if ( annotation != null ) {
- annotationList.add( annotation );
- annotation = getJavaAnnotation( AttributeOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverrides.class );
- addIfNotNull( annotationList, annotation );
- }
- }
- }
-
- private Transient getTransient(XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- if ( "transient".equals( element.getName() ) ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( Transient.class );
- return AnnotationFactory.create( ad );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( Transient.class );
- }
- else {
- return null;
- }
- }
-
- private void getVersion(List<Annotation> annotationList, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- if ( "version".equals( element.getName() ) ) {
- Annotation annotation = buildColumns( element );
- addIfNotNull( annotationList, annotation );
- getTemporal( annotationList, element );
- AnnotationDescriptor basic = new AnnotationDescriptor( Version.class );
- annotationList.add( AnnotationFactory.create( basic ) );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- //we have nothing, so Java annotations might occurs
- Annotation annotation = getJavaAnnotation( Version.class );
- if ( annotation != null ) {
- annotationList.add( annotation );
- annotation = getJavaAnnotation( Column.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Columns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Temporal.class );
- addIfNotNull( annotationList, annotation );
- }
- }
- }
-
- private void getBasic(List<Annotation> annotationList, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- if ( "basic".equals( element.getName() ) ) {
- Annotation annotation = buildColumns( element );
- addIfNotNull( annotationList, annotation );
- getTemporal( annotationList, element );
- getLob( annotationList, element );
- getEnumerated( annotationList, element );
- AnnotationDescriptor basic = new AnnotationDescriptor( Basic.class );
- getFetchType( basic, element );
- copyBooleanAttribute( basic, element, "optional" );
- annotationList.add( AnnotationFactory.create( basic ) );
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- //no annotation presence constraint, basic is the default
- Annotation annotation = getJavaAnnotation( Basic.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Lob.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Enumerated.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Temporal.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Column.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Columns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverrides.class );
- addIfNotNull( annotationList, annotation );
- }
- }
-
- private void getEnumerated(List<Annotation> annotationList, Element element) {
- Element subElement = element != null ? element.element( "enumerated" ) : null;
- if ( subElement != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( Enumerated.class );
- String enumerated = subElement.getTextTrim();
- if ( "ORDINAL".equalsIgnoreCase( enumerated ) ) {
- ad.setValue( "value", EnumType.ORDINAL );
- }
- else if ( "STRING".equalsIgnoreCase( enumerated ) ) {
- ad.setValue( "value", EnumType.STRING );
- }
- else if ( StringHelper.isNotEmpty( enumerated ) ) {
- throw new AnnotationException( "Unknown EnumType: " + enumerated + ". " + SCHEMA_VALIDATION );
- }
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
-
- private void getLob(List<Annotation> annotationList, Element element) {
- Element subElement = element != null ? element.element( "lob" ) : null;
- if ( subElement != null ) {
- annotationList.add( AnnotationFactory.create( new AnnotationDescriptor( Lob.class ) ) );
- }
- }
-
- private void getFetchType(AnnotationDescriptor descriptor, Element element) {
- String fetchString = element != null ? element.attributeValue( "fetch" ) : null;
- if ( fetchString != null ) {
- if ( "eager".equalsIgnoreCase( fetchString ) ) {
- descriptor.setValue( "fetch", FetchType.EAGER );
- }
- else if ( "lazy".equalsIgnoreCase( fetchString ) ) {
- descriptor.setValue( "fetch", FetchType.LAZY );
- }
- }
- }
-
- private void getEmbeddedId(List<Annotation> annotationList, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- if ( "embedded-id".equals( element.getName() ) ) {
- if ( isProcessingId( defaults ) ) {
- Annotation annotation = getAttributeOverrides( element, defaults );
- addIfNotNull( annotationList, annotation );
- annotation = getAssociationOverrides( element, defaults );
- addIfNotNull( annotationList, annotation );
- AnnotationDescriptor ad = new AnnotationDescriptor( EmbeddedId.class );
- annotationList.add( AnnotationFactory.create( ad ) );
- }
-// else {
-// if ( defaults.canUseJavaAnnotations() ) {
-// if ( ! properOverridingOnMetadataNonComplete ) {
-// //check that id exists on the other attribute
-// //TODO Id too?
-// if ( mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent(
-// EmbeddedId.class
-// ) ) {
-// throw new AnnotationException(
-// "Cannot override an property with <embedded-id> not having an @EmbeddedId already"
-// );
-// }
-// }
-// }
-// }
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- Annotation annotation = getJavaAnnotation( EmbeddedId.class );
- if ( annotation != null ) {
- annotationList.add( annotation );
- annotation = getJavaAnnotation( Column.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Columns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( GeneratedValue.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Temporal.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( TableGenerator.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( SequenceGenerator.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverrides.class );
- addIfNotNull( annotationList, annotation );
- }
- }
- }
-
- private void preCalculateElementsForProperty(Element tree) {
- elementsForProperty = new ArrayList<Element>();
- Element element = tree != null ? tree.element( "attributes" ) : null;
- //put entity.attributes elements
- if ( element != null ) {
- for (Element subelement : (List<Element>) element.elements()) {
- if ( propertyName.equals( subelement.attributeValue( "name" ) ) ) {
- elementsForProperty.add( subelement );
- }
- }
- }
- //add pre-* etc from entity and pure entity listener classes
- if ( tree != null ) {
- for (Element subelement : (List<Element>) tree.elements()) {
- if ( propertyName.equals( subelement.attributeValue( "method-name" ) ) ) {
- elementsForProperty.add( subelement );
- }
- }
- }
- }
-
- private void getId(List<Annotation> annotationList, XMLContext.Default defaults) {
- for (Element element : elementsForProperty) {
- if ( "id".equals( element.getName() ) ) {
- boolean processId = isProcessingId( defaults );
- if ( processId ) {
- Annotation annotation = buildColumns( element );
- addIfNotNull( annotationList, annotation );
- annotation = buildGeneratedValue( element );
- addIfNotNull( annotationList, annotation );
- getTemporal( annotationList, element );
- //FIXME: fix the priority of xml over java for generator names
- annotation = getTableGenerator( element, defaults );
- addIfNotNull( annotationList, annotation );
- annotation = getSequenceGenerator( element, defaults );
- addIfNotNull( annotationList, annotation );
- AnnotationDescriptor id = new AnnotationDescriptor( Id.class );
- annotationList.add( AnnotationFactory.create( id ) );
- }
-// else {
-// if ( defaults.canUseJavaAnnotations() ) {
-// if ( ! properOverridingOnMetadataNonComplete ) {
-// //check that id exists on the other attribute
-// //TODO EmbeddedId too?
-// if ( mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent( Id.class ) ) {
-// throw new AnnotationException(
-// "Cannot override a property with <id> it does not have an @Id already"
-// );
-// }
-// }
-// }
-// }
- }
- }
- if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
- Annotation annotation = getJavaAnnotation( Id.class );
- if ( annotation != null ) {
- annotationList.add( annotation );
- annotation = getJavaAnnotation( Column.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Columns.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( GeneratedValue.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( Temporal.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( TableGenerator.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( SequenceGenerator.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AttributeOverrides.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverride.class );
- addIfNotNull( annotationList, annotation );
- annotation = getJavaAnnotation( AssociationOverrides.class );
- addIfNotNull( annotationList, annotation );
- }
- }
- }
-
- private boolean isProcessingId(XMLContext.Default defaults) {
- boolean isExplicit = defaults.getAccess() != null;
- boolean correctAccess =
- ( PropertyType.PROPERTY.equals( propertyType ) && "property".equals( defaults.getAccess() ) )
- || ( PropertyType.FIELD.equals( propertyType ) && "field".equals( defaults.getAccess() ) );
- boolean hasId = defaults.canUseJavaAnnotations()
- && ( isJavaAnnotationPresent( Id.class ) || isJavaAnnotationPresent( EmbeddedId.class ) );
- //if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) {
- boolean mirrorAttributeIsId = defaults.canUseJavaAnnotations() &&
- ( mirroredAttribute != null &&
- ( mirroredAttribute.isAnnotationPresent( Id.class )
- || mirroredAttribute.isAnnotationPresent( EmbeddedId.class ) ) );
- boolean propertyIsDefault = PropertyType.PROPERTY.equals( propertyType )
- && !mirrorAttributeIsId;
- return correctAccess || ( !isExplicit && hasId ) || ( !isExplicit && propertyIsDefault );
- }
-
- private Columns buildColumns(Element element) {
- List<Element> subelements = element.elements( "column" );
- List<Column> columns = new ArrayList<Column>( subelements.size() );
- for (Element subelement : subelements) {
- columns.add( getColumn( subelement, false, element ) );
- }
- if ( columns.size() > 0 ) {
- AnnotationDescriptor columnsDescr = new AnnotationDescriptor( Columns.class );
- columnsDescr.setValue( "columns", columns.toArray( new Column[columns.size()] ) );
- return AnnotationFactory.create( columnsDescr );
- }
- else {
- return null;
- }
- }
-
- private GeneratedValue buildGeneratedValue(Element element) {
- Element subElement = element != null ? element.element( "generated-value" ) : null;
- if ( subElement != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( GeneratedValue.class );
- String strategy = subElement.attributeValue( "strategy" );
- if ( "TABLE".equalsIgnoreCase( strategy ) ) {
- ad.setValue( "strategy", GenerationType.TABLE );
- }
- else if ( "SEQUENCE".equalsIgnoreCase( strategy ) ) {
- ad.setValue( "strategy", GenerationType.SEQUENCE );
- }
- else if ( "IDENTITY".equalsIgnoreCase( strategy ) ) {
- ad.setValue( "strategy", GenerationType.IDENTITY );
- }
- else if ( "AUTO".equalsIgnoreCase( strategy ) ) {
- ad.setValue( "strategy", GenerationType.AUTO );
- }
- else if ( StringHelper.isNotEmpty( strategy ) ) {
- throw new AnnotationException( "Unknown GenerationType: " + strategy + ". " + SCHEMA_VALIDATION );
- }
- copyStringAttribute( ad, subElement, "generator", false );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private void getTemporal(List<Annotation> annotationList, Element element) {
- Element subElement = element != null ? element.element( "temporal" ) : null;
- if ( subElement != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( Temporal.class );
- String temporal = subElement.getTextTrim();
- if ( "DATE".equalsIgnoreCase( temporal ) ) {
- ad.setValue( "value", TemporalType.DATE );
- }
- else if ( "TIME".equalsIgnoreCase( temporal ) ) {
- ad.setValue( "value", TemporalType.TIME );
- }
- else if ( "TIMESTAMP".equalsIgnoreCase( temporal ) ) {
- ad.setValue( "value", TemporalType.TIMESTAMP );
- }
- else if ( StringHelper.isNotEmpty( temporal ) ) {
- throw new AnnotationException( "Unknown TemporalType: " + temporal + ". " + SCHEMA_VALIDATION );
- }
- annotationList.add( AnnotationFactory.create( ad ) );
- }
- }
-
- private AssociationOverrides getAssociationOverrides(Element tree, XMLContext.Default defaults) {
- List<AssociationOverride> attributes = (List<AssociationOverride>) buildAssociationOverrides( tree );
- if ( defaults.canUseJavaAnnotations() ) {
- AssociationOverride annotation = getJavaAnnotation( AssociationOverride.class );
- addAssociationOverrideIfNeeded( annotation, attributes );
- AssociationOverrides annotations = getJavaAnnotation( AssociationOverrides.class );
- if ( annotations != null ) {
- for (AssociationOverride current : annotations.value()) {
- addAssociationOverrideIfNeeded( current, attributes );
- }
- }
- }
- if ( attributes.size() > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( AssociationOverrides.class );
- ad.setValue( "value", attributes.toArray( new AssociationOverride[attributes.size()] ) );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private List<AssociationOverride> buildAssociationOverrides(Element element) {
- List<Element> subelements = element == null ? null : element.elements( "association-override" );
- List<AssociationOverride> overrides = new ArrayList<AssociationOverride>();
- if ( subelements != null && subelements.size() > 0 ) {
- for (Element current : subelements) {
- AnnotationDescriptor override = new AnnotationDescriptor( AssociationOverride.class );
- copyStringAttribute( override, current, "name", true );
- override.setValue( "joinColumns", getJoinColumns( current, false ) );
- overrides.add( (AssociationOverride) AnnotationFactory.create( override ) );
- }
- }
- return overrides;
- }
-
- private JoinColumn[] getJoinColumns(Element element, boolean isInverse) {
- List<Element> subelements = element != null ?
- element.elements( isInverse ? "inverse-join-column" : "join-column" ) :
- null;
- List<JoinColumn> joinColumns = new ArrayList<JoinColumn>();
- if ( subelements != null ) {
- for (Element subelement : subelements) {
- AnnotationDescriptor column = new AnnotationDescriptor( JoinColumn.class );
- copyStringAttribute( column, subelement, "name", false );
- copyStringAttribute( column, subelement, "referenced-column-name", false );
- copyBooleanAttribute( column, subelement, "unique" );
- copyBooleanAttribute( column, subelement, "nullable" );
- copyBooleanAttribute( column, subelement, "insertable" );
- copyBooleanAttribute( column, subelement, "updatable" );
- copyStringAttribute( column, subelement, "column-definition", false );
- copyStringAttribute( column, subelement, "table", false );
- joinColumns.add( (JoinColumn) AnnotationFactory.create( column ) );
- }
- }
- return joinColumns.toArray( new JoinColumn[joinColumns.size()] );
- }
-
- private void addAssociationOverrideIfNeeded(AssociationOverride annotation, List<AssociationOverride> overrides) {
- if ( annotation != null ) {
- String overrideName = annotation.name();
- boolean present = false;
- for (AssociationOverride current : overrides) {
- if ( current.name().equals( overrideName ) ) {
- present = true;
- break;
- }
- }
- if ( !present ) overrides.add( annotation );
- }
- }
-
- private AttributeOverrides getAttributeOverrides(Element tree, XMLContext.Default defaults) {
- List<AttributeOverride> attributes = buildAttributeOverrides( tree );
- return mergeAttributeOverrides( defaults, attributes );
- }
-
- private AttributeOverrides getAttributeOverrides(List<Element> elements, XMLContext.Default defaults) {
- List<AttributeOverride> attributes = new ArrayList<AttributeOverride>();
- for (Element element : elements) {
- attributes.addAll( buildAttributeOverrides( element ) );
- }
- return mergeAttributeOverrides( defaults, attributes );
- }
-
- private AttributeOverrides mergeAttributeOverrides(XMLContext.Default defaults,
- List<AttributeOverride> attributes) {
- if ( defaults.canUseJavaAnnotations() ) {
- AttributeOverride annotation = getJavaAnnotation( AttributeOverride.class );
- addAttributeOverrideIfNeeded( annotation, attributes );
- AttributeOverrides annotations = getJavaAnnotation( AttributeOverrides.class );
- if ( annotations != null ) {
- for (AttributeOverride current : annotations.value()) {
- addAttributeOverrideIfNeeded( current, attributes );
- }
- }
- }
- if ( attributes.size() > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( AttributeOverrides.class );
- ad.setValue( "value", attributes.toArray( new AttributeOverride[attributes.size()] ) );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private List<AttributeOverride> buildAttributeOverrides(Element element) {
- List<Element> subelements = element == null ? null : element.elements( "attribute-override" );
- return buildAttributeOverrides( subelements );
- }
-
- private List<AttributeOverride> buildAttributeOverrides(List<Element> subelements) {
- List<AttributeOverride> overrides = new ArrayList<AttributeOverride>();
- if ( subelements != null && subelements.size() > 0 ) {
- for (Element current : subelements) {
- if ( !current.getName().equals( "attribute-override" ) ) continue;
- AnnotationDescriptor override = new AnnotationDescriptor( AttributeOverride.class );
- copyStringAttribute( override, current, "name", true );
- Element column = current != null ? current.element( "column" ) : null;
- override.setValue( "column", getColumn( column, true, current ) );
- overrides.add( (AttributeOverride) AnnotationFactory.create( override ) );
- }
- }
- return overrides;
- }
-
- private Column getColumn(Element element, boolean isMandatory, Element current) {
- //Element subelement = element != null ? element.element( "column" ) : null;
- if ( element != null ) {
- AnnotationDescriptor column = new AnnotationDescriptor( Column.class );
- copyStringAttribute( column, element, "name", false );
- copyBooleanAttribute( column, element, "unique" );
- copyBooleanAttribute( column, element, "nullable" );
- copyBooleanAttribute( column, element, "insertable" );
- copyBooleanAttribute( column, element, "updatable" );
- copyStringAttribute( column, element, "column-definition", false );
- copyStringAttribute( column, element, "table", false );
- copyIntegerAttribute( column, element, "length" );
- copyIntegerAttribute( column, element, "precision" );
- copyIntegerAttribute( column, element, "scale" );
- return (Column) AnnotationFactory.create( column );
- }
- else {
- if ( isMandatory ) {
- throw new AnnotationException( current.getPath() + ".column is mandatory. " + SCHEMA_VALIDATION );
- }
- return null;
- }
- }
-
- private void addAttributeOverrideIfNeeded(AttributeOverride annotation, List<AttributeOverride> overrides) {
- if ( annotation != null ) {
- String overrideName = annotation.name();
- boolean present = false;
- for (AttributeOverride current : overrides) {
- if ( current.name().equals( overrideName ) ) {
- present = true;
- break;
- }
- }
- if ( !present ) overrides.add( annotation );
- }
- }
-
- private AccessType getAccessType(Element tree, XMLContext.Default defaults) {
- String access = tree == null ? null : tree.attributeValue( "access" );
- if ( "FIELD".equals( access ) || "PROPERTY".equals( access ) ) {
- access = access.toLowerCase();
- }
- if ( access != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( AccessType.class );
- ad.setValue( "value", access );
- return AnnotationFactory.create( ad );
- }
- else if ( defaults.canUseJavaAnnotations() && isJavaAnnotationPresent( AccessType.class ) ) {
- AccessType annotation = getJavaAnnotation( AccessType.class );
- return annotation;
- }
- else if ( defaults.getAccess() != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( AccessType.class );
- ad.setValue( "value", defaults.getAccess() );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private ExcludeSuperclassListeners getExcludeSuperclassListeners(Element tree, XMLContext.Default defaults) {
- return (ExcludeSuperclassListeners) getMarkerAnnotation( ExcludeSuperclassListeners.class, tree, defaults );
- }
-
- private ExcludeDefaultListeners getExcludeDefaultListeners(Element tree, XMLContext.Default defaults) {
- return (ExcludeDefaultListeners) getMarkerAnnotation( ExcludeDefaultListeners.class, tree, defaults );
- }
-
- private Annotation getMarkerAnnotation(
- Class<? extends Annotation> clazz, Element element, XMLContext.Default defaults
- ) {
- Element subelement = element == null ? null : element.element( annotationToXml.get( clazz ) );
- if ( subelement != null ) {
- return AnnotationFactory.create( new AnnotationDescriptor( clazz ) );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- //TODO wonder whether it should be excluded so that user can undone it
- return getJavaAnnotation( clazz );
- }
- else {
- return null;
- }
- }
-
- private SqlResultSetMappings getSqlResultSetMappings(Element tree, XMLContext.Default defaults) {
- List<SqlResultSetMapping> results = (List<SqlResultSetMapping>) buildSqlResultsetMappings( tree, defaults );
- if ( defaults.canUseJavaAnnotations() ) {
- SqlResultSetMapping annotation = getJavaAnnotation( SqlResultSetMapping.class );
- addSqlResultsetMappingIfNeeded( annotation, results );
- SqlResultSetMappings annotations = getJavaAnnotation( SqlResultSetMappings.class );
- if ( annotations != null ) {
- for (SqlResultSetMapping current : annotations.value()) {
- addSqlResultsetMappingIfNeeded( current, results );
- }
- }
- }
- if ( results.size() > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( SqlResultSetMappings.class );
- ad.setValue( "value", results.toArray( new SqlResultSetMapping[results.size()] ) );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults) {
- if ( element == null ) return new ArrayList<SqlResultSetMapping>();
- List resultsetElementList = element.elements( "sql-result-set-mapping" );
- List<SqlResultSetMapping> resultsets = new ArrayList<SqlResultSetMapping>();
- Iterator it = resultsetElementList.listIterator();
- while ( it.hasNext() ) {
- Element subelement = (Element) it.next();
- AnnotationDescriptor ann = new AnnotationDescriptor( SqlResultSetMapping.class );
- copyStringAttribute( ann, subelement, "name", true );
- List<Element> elements = subelement.elements( "entity-result" );
- List<EntityResult> entityResults = new ArrayList<EntityResult>( elements.size() );
- for (Element entityResult : elements) {
- AnnotationDescriptor entityResultDescriptor = new AnnotationDescriptor( EntityResult.class );
- String clazzName = entityResult.attributeValue( "entity-class" );
- if ( clazzName == null ) {
- throw new AnnotationException( "<entity-result> without entity-class. " + SCHEMA_VALIDATION );
- }
- Class clazz = null;
- try {
- clazz = ReflectHelper.classForName(
- XMLContext.buildSafeClassName( clazzName, defaults ),
- EJB3OverridenAnnotationReader.class
- );
- }
- catch (ClassNotFoundException e) {
- throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
- }
- entityResultDescriptor.setValue( "entityClass", clazz );
- copyStringAttribute( entityResultDescriptor, entityResult, "discriminator-column", false );
- List<FieldResult> fieldResults = new ArrayList<FieldResult>();
- for (Element fieldResult : (List<Element>) entityResult.elements( "field-result" )) {
- AnnotationDescriptor fieldResultDescriptor = new AnnotationDescriptor( FieldResult.class );
- copyStringAttribute( fieldResultDescriptor, fieldResult, "name", true );
- copyStringAttribute( fieldResultDescriptor, fieldResult, "column", true );
- fieldResults.add( (FieldResult) AnnotationFactory.create( fieldResultDescriptor ) );
- }
- entityResultDescriptor.setValue(
- "fields", fieldResults.toArray( new FieldResult[fieldResults.size()] )
- );
- entityResults.add( (EntityResult) AnnotationFactory.create( entityResultDescriptor ) );
- }
- ann.setValue( "entities", entityResults.toArray( new EntityResult[entityResults.size()] ) );
-
- elements = subelement.elements( "column-result" );
- List<ColumnResult> columnResults = new ArrayList<ColumnResult>( elements.size() );
- for (Element columnResult : elements) {
- AnnotationDescriptor columnResultDescriptor = new AnnotationDescriptor( ColumnResult.class );
- copyStringAttribute( columnResultDescriptor, columnResult, "name", true );
- columnResults.add( (ColumnResult) AnnotationFactory.create( columnResultDescriptor ) );
- }
- ann.setValue( "columns", columnResults.toArray( new ColumnResult[columnResults.size()] ) );
- //FIXME there is never such a result-class, get rid of it?
- String clazzName = subelement.attributeValue( "result-class" );
- if ( StringHelper.isNotEmpty( clazzName ) ) {
- Class clazz = null;
- try {
- clazz = ReflectHelper.classForName(
- XMLContext.buildSafeClassName( clazzName, defaults ),
- EJB3OverridenAnnotationReader.class
- );
- }
- catch (ClassNotFoundException e) {
- throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
- }
- ann.setValue( "resultClass", clazz );
- }
- copyStringAttribute( ann, subelement, "result-set-mapping", false );
- resultsets.add( (SqlResultSetMapping) AnnotationFactory.create( ann ) );
- }
- return resultsets;
- }
-
- private void addSqlResultsetMappingIfNeeded(SqlResultSetMapping annotation, List<SqlResultSetMapping> resultsets) {
- if ( annotation != null ) {
- String resultsetName = annotation.name();
- boolean present = false;
- for (SqlResultSetMapping current : resultsets) {
- if ( current.name().equals( resultsetName ) ) {
- present = true;
- break;
- }
- }
- if ( !present ) resultsets.add( annotation );
- }
- }
-
- private NamedQueries getNamedQueries(Element tree, XMLContext.Default defaults) {
- //TODO avoid the Proxy Creation (@NamedQueries) when possible
- List<NamedQuery> queries = (List<NamedQuery>) buildNamedQueries( tree, false, defaults );
- if ( defaults.canUseJavaAnnotations() ) {
- NamedQuery annotation = getJavaAnnotation( NamedQuery.class );
- addNamedQueryIfNeeded( annotation, queries );
- NamedQueries annotations = getJavaAnnotation( NamedQueries.class );
- if ( annotations != null ) {
- for (NamedQuery current : annotations.value()) {
- addNamedQueryIfNeeded( current, queries );
- }
- }
- }
- if ( queries.size() > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( NamedQueries.class );
- ad.setValue( "value", queries.toArray( new NamedQuery[queries.size()] ) );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private void addNamedQueryIfNeeded(NamedQuery annotation, List<NamedQuery> queries) {
- if ( annotation != null ) {
- String queryName = annotation.name();
- boolean present = false;
- for (NamedQuery current : queries) {
- if ( current.name().equals( queryName ) ) {
- present = true;
- break;
- }
- }
- if ( !present ) queries.add( annotation );
- }
- }
-
- private NamedNativeQueries getNamedNativeQueries(Element tree, XMLContext.Default defaults) {
- List<NamedNativeQuery> queries = (List<NamedNativeQuery>) buildNamedQueries( tree, true, defaults );
- if ( defaults.canUseJavaAnnotations() ) {
- NamedNativeQuery annotation = getJavaAnnotation( NamedNativeQuery.class );
- addNamedNativeQueryIfNeeded( annotation, queries );
- NamedNativeQueries annotations = getJavaAnnotation( NamedNativeQueries.class );
- if ( annotations != null ) {
- for (NamedNativeQuery current : annotations.value()) {
- addNamedNativeQueryIfNeeded( current, queries );
- }
- }
- }
- if ( queries.size() > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( NamedNativeQueries.class );
- ad.setValue( "value", queries.toArray( new NamedNativeQuery[queries.size()] ) );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private void addNamedNativeQueryIfNeeded(NamedNativeQuery annotation, List<NamedNativeQuery> queries) {
- if ( annotation != null ) {
- String queryName = annotation.name();
- boolean present = false;
- for (NamedNativeQuery current : queries) {
- if ( current.name().equals( queryName ) ) {
- present = true;
- break;
- }
- }
- if ( !present ) queries.add( annotation );
- }
- }
-
- public static List buildNamedQueries(Element element, boolean isNative, XMLContext.Default defaults) {
- if ( element == null ) return new ArrayList();
- List namedQueryElementList = isNative ?
- element.elements( "named-native-query" ) :
- element.elements( "named-query" );
- List namedQueries = new ArrayList();
- Iterator it = namedQueryElementList.listIterator();
- while ( it.hasNext() ) {
- Element subelement = (Element) it.next();
- AnnotationDescriptor ann = new AnnotationDescriptor(
- isNative ? NamedNativeQuery.class : NamedQuery.class
- );
- copyStringAttribute( ann, subelement, "name", false );
- Element queryElt = subelement.element( "query" );
- if ( queryElt == null ) throw new AnnotationException( "No <query> element found." + SCHEMA_VALIDATION );
- ann.setValue( "query", queryElt.getTextTrim() );
- List<Element> elements = subelement.elements( "hint" );
- List<QueryHint> queryHints = new ArrayList<QueryHint>( elements.size() );
- for (Element hint : elements) {
- AnnotationDescriptor hintDescriptor = new AnnotationDescriptor( QueryHint.class );
- String value = hint.attributeValue( "name" );
- if ( value == null ) throw new AnnotationException( "<hint> without name. " + SCHEMA_VALIDATION );
- hintDescriptor.setValue( "name", value );
- value = hint.attributeValue( "value" );
- if ( value == null ) throw new AnnotationException( "<hint> without value. " + SCHEMA_VALIDATION );
- hintDescriptor.setValue( "value", value );
- queryHints.add( (QueryHint) AnnotationFactory.create( hintDescriptor ) );
- }
- ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
- String clazzName = subelement.attributeValue( "result-class" );
- if ( StringHelper.isNotEmpty( clazzName ) ) {
- Class clazz = null;
- try {
- clazz = ReflectHelper.classForName(
- XMLContext.buildSafeClassName( clazzName, defaults ),
- EJB3OverridenAnnotationReader.class
- );
- }
- catch (ClassNotFoundException e) {
- throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
- }
- ann.setValue( "resultClass", clazz );
- }
- copyStringAttribute( ann, subelement, "result-set-mapping", false );
- namedQueries.add( AnnotationFactory.create( ann ) );
- }
- return namedQueries;
- }
-
- private TableGenerator getTableGenerator(Element tree, XMLContext.Default defaults) {
- Element element = tree != null ? tree.element( annotationToXml.get( TableGenerator.class ) ) : null;
- if ( element != null ) {
- return buildTableGeneratorAnnotation( element, defaults );
- }
- else if ( defaults.canUseJavaAnnotations() && isJavaAnnotationPresent( TableGenerator.class ) ) {
- TableGenerator tableAnn = getJavaAnnotation( TableGenerator.class );
- if ( StringHelper.isNotEmpty( defaults.getSchema() )
- || StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
- AnnotationDescriptor annotation = new AnnotationDescriptor( TableGenerator.class );
- annotation.setValue( "name", tableAnn.name() );
- annotation.setValue( "table", tableAnn.table() );
- annotation.setValue( "catalog", tableAnn.table() );
- if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
- && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
- annotation.setValue( "catalog", defaults.getCatalog() );
- }
- annotation.setValue( "schema", tableAnn.table() );
- if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
- && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- annotation.setValue( "catalog", defaults.getSchema() );
- }
- annotation.setValue( "pkColumnName", tableAnn.pkColumnName() );
- annotation.setValue( "valueColumnName", tableAnn.valueColumnName() );
- annotation.setValue( "pkColumnValue", tableAnn.pkColumnValue() );
- annotation.setValue( "initialValue", tableAnn.initialValue() );
- annotation.setValue( "allocationSize", tableAnn.allocationSize() );
- annotation.setValue( "uniqueConstraints", tableAnn.uniqueConstraints() );
- return AnnotationFactory.create( annotation );
- }
- else {
- return tableAnn;
- }
- }
- else {
- return null;
- }
- }
-
- public static TableGenerator buildTableGeneratorAnnotation(Element element, XMLContext.Default defaults) {
- AnnotationDescriptor ad = new AnnotationDescriptor( TableGenerator.class );
- copyStringAttribute( ad, element, "name", false );
- copyStringAttribute( ad, element, "table", false );
- copyStringAttribute( ad, element, "catalog", false );
- copyStringAttribute( ad, element, "schema", false );
- copyStringAttribute( ad, element, "pk-column-name", false );
- copyStringAttribute( ad, element, "value-column-name", false );
- copyStringAttribute( ad, element, "pk-column-value", false );
- copyIntegerAttribute( ad, element, "initial-value" );
- copyIntegerAttribute( ad, element, "allocation-size" );
- buildUniqueConstraints( ad, element );
- if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) )
- && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- ad.setValue( "schema", defaults.getSchema() );
- }
- if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) )
- && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
- ad.setValue( "catalog", defaults.getCatalog() );
- }
- return AnnotationFactory.create( ad );
- }
-
- private SequenceGenerator getSequenceGenerator(Element tree, XMLContext.Default defaults) {
- Element element = tree != null ? tree.element( annotationToXml.get( SequenceGenerator.class ) ) : null;
- if ( element != null ) {
- return buildSequenceGeneratorAnnotation( element );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( SequenceGenerator.class );
- }
- else {
- return null;
- }
- }
-
- public static SequenceGenerator buildSequenceGeneratorAnnotation(Element element) {
- if ( element != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( SequenceGenerator.class );
- copyStringAttribute( ad, element, "name", false );
- copyStringAttribute( ad, element, "sequence-name", false );
- copyIntegerAttribute( ad, element, "initial-value" );
- copyIntegerAttribute( ad, element, "allocation-size" );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private DiscriminatorColumn getDiscriminatorColumn(Element tree, XMLContext.Default defaults) {
- Element element = tree != null ? tree.element( "discriminator-column" ) : null;
- if ( element != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( DiscriminatorColumn.class );
- copyStringAttribute( ad, element, "name", false );
- copyStringAttribute( ad, element, "column-definition", false );
- String value = element.attributeValue( "discriminator-type" );
- DiscriminatorType type = DiscriminatorType.STRING;
- if ( value != null ) {
- if ( "STRING".equals( value ) ) {
- type = DiscriminatorType.STRING;
- }
- else if ( "CHAR".equals( value ) ) {
- type = DiscriminatorType.CHAR;
- }
- else if ( "INTEGER".equals( value ) ) {
- type = DiscriminatorType.INTEGER;
- }
- else {
- throw new AnnotationException(
- "Unknown DiscrimiatorType in XML: " + value + " (" + SCHEMA_VALIDATION + ")"
- );
- }
- }
- ad.setValue( "discriminatorType", type );
- copyIntegerAttribute( ad, element, "length" );
- return AnnotationFactory.create( ad );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( DiscriminatorColumn.class );
- }
- else {
- return null;
- }
- }
-
- private DiscriminatorValue getDiscriminatorValue(Element tree, XMLContext.Default defaults) {
- Element element = tree != null ? tree.element( "discriminator-value" ) : null;
- if ( element != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( DiscriminatorValue.class );
- copyStringElement( element, ad, "value" );
- return AnnotationFactory.create( ad );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( DiscriminatorValue.class );
- }
- else {
- return null;
- }
- }
-
- private Inheritance getInheritance(Element tree, XMLContext.Default defaults) {
- Element element = tree != null ? tree.element( "inheritance" ) : null;
- if ( element != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( Inheritance.class );
- Attribute attr = element.attribute( "strategy" );
- InheritanceType strategy = InheritanceType.SINGLE_TABLE;
- if ( attr != null ) {
- String value = attr.getValue();
- if ( "SINGLE_TABLE".equals( value ) ) {
- strategy = InheritanceType.SINGLE_TABLE;
- }
- else if ( "JOINED".equals( value ) ) {
- strategy = InheritanceType.JOINED;
- }
- else if ( "TABLE_PER_CLASS".equals( value ) ) {
- strategy = InheritanceType.TABLE_PER_CLASS;
- }
- else {
- throw new AnnotationException(
- "Unknown InheritanceType in XML: " + value + " (" + SCHEMA_VALIDATION + ")"
- );
- }
- }
- ad.setValue( "strategy", strategy );
- return AnnotationFactory.create( ad );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( Inheritance.class );
- }
- else {
- return null;
- }
- }
-
- private IdClass getIdClass(Element tree, XMLContext.Default defaults) {
- Element element = tree == null ? null : tree.element( "id-class" );
- if ( element != null ) {
- Attribute attr = element.attribute( "class" );
- if ( attr != null ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( IdClass.class );
- Class clazz = null;
- try {
- clazz = ReflectHelper.classForName(
- XMLContext.buildSafeClassName( attr.getValue(), defaults ),
- this.getClass()
- );
- }
- catch (ClassNotFoundException e) {
- throw new AnnotationException( "Unable to find id-class: " + attr.getValue(), e );
- }
- ad.setValue( "value", clazz );
- return AnnotationFactory.create( ad );
- }
- else {
- throw new AnnotationException( "id-class without class. " + SCHEMA_VALIDATION );
- }
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( IdClass.class );
- }
- else {
- return null;
- }
- }
-
- private PrimaryKeyJoinColumns getPrimaryKeyJoinColumns(Element element, XMLContext.Default defaults) {
- PrimaryKeyJoinColumn[] columns = buildPrimaryKeyJoinColumns( element );
- if ( columns.length == 0 && defaults.canUseJavaAnnotations() ) {
- PrimaryKeyJoinColumn annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
- if ( annotation != null ) {
- columns = new PrimaryKeyJoinColumn[] { annotation };
- }
- else {
- PrimaryKeyJoinColumns annotations = getJavaAnnotation( PrimaryKeyJoinColumns.class );
- columns = annotations != null ? annotations.value() : columns;
- }
- }
- if ( columns.length > 0 ) {
- AnnotationDescriptor ad = new AnnotationDescriptor( PrimaryKeyJoinColumns.class );
- ad.setValue( "value", columns );
- return AnnotationFactory.create( ad );
- }
- else {
- return null;
- }
- }
-
- private Entity getEntity(Element tree, XMLContext.Default defaults) {
- if ( tree == null ) {
- return defaults.canUseJavaAnnotations() ? getJavaAnnotation( Entity.class ) : null;
- }
- else {
- if ( "entity".equals( tree.getName() ) ) {
- AnnotationDescriptor entity = new AnnotationDescriptor( Entity.class );
- copyStringAttribute( entity, tree, "name", false );
- if ( defaults.canUseJavaAnnotations()
- && StringHelper.isEmpty( (String) entity.valueOf( "name" ) ) ) {
- Entity javaAnn = getJavaAnnotation( Entity.class );
- if ( javaAnn != null ) entity.setValue( "name", javaAnn.name() );
- }
- return AnnotationFactory.create( entity );
- }
- else {
- return null; //this is not an entity
- }
- }
- }
-
- private MappedSuperclass getMappedSuperclass(Element tree, XMLContext.Default defaults) {
- if ( tree == null ) {
- return defaults.canUseJavaAnnotations() ? getJavaAnnotation( MappedSuperclass.class ) : null;
- }
- else {
- if ( "mapped-superclass".equals( tree.getName() ) ) {
- AnnotationDescriptor entity = new AnnotationDescriptor( MappedSuperclass.class );
- return AnnotationFactory.create( entity );
- }
- else {
- return null; //this is not an entity
- }
- }
- }
-
- private Embeddable getEmbeddable(Element tree, XMLContext.Default defaults) {
- if ( tree == null ) {
- return defaults.canUseJavaAnnotations() ? getJavaAnnotation( Embeddable.class ) : null;
- }
- else {
- if ( "embeddable".equals( tree.getName() ) ) {
- AnnotationDescriptor entity = new AnnotationDescriptor( Embeddable.class );
- return AnnotationFactory.create( entity );
- }
- else {
- return null; //this is not an entity
- }
- }
- }
-
- private Table getTable(Element tree, XMLContext.Default defaults) {
- Element subelement = tree == null ? null : tree.element( "table" );
- if ( subelement == null ) {
- //no element but might have some default or some annotation
- if ( StringHelper.isNotEmpty( defaults.getCatalog() )
- || StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- AnnotationDescriptor annotation = new AnnotationDescriptor( Table.class );
- if ( defaults.canUseJavaAnnotations() ) {
- Table table = getJavaAnnotation( Table.class );
- if ( table != null ) {
- annotation.setValue( "name", table.name() );
- annotation.setValue( "schema", table.schema() );
- annotation.setValue( "catalog", table.catalog() );
- annotation.setValue( "uniqueConstraints", table.uniqueConstraints() );
- }
- }
- if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
- && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- annotation.setValue( "schema", defaults.getSchema() );
- }
- if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
- && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
- annotation.setValue( "catalog", defaults.getCatalog() );
- }
- return AnnotationFactory.create( annotation );
- }
- else if ( defaults.canUseJavaAnnotations() ) {
- return getJavaAnnotation( Table.class );
- }
- else {
- return null;
- }
- }
- else {
- //ignore java annotation, an element is defined
- AnnotationDescriptor annotation = new AnnotationDescriptor( Table.class );
- copyStringAttribute( annotation, subelement, "name", false );
- copyStringAttribute( annotation, subelement, "catalog", false );
- if ( StringHelper.isNotEmpty( defaults.getCatalog() )
- && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
- annotation.setValue( "catalog", defaults.getCatalog() );
- }
- copyStringAttribute( annotation, subelement, "schema", false );
- if ( StringHelper.isNotEmpty( defaults.getSchema() )
- && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
- annotation.setValue( "schema", defaults.getSchema() );
- }
- buildUniqueConstraints( annotation, subelement );
- return AnnotationFactory.create( annotation );
- }
- }
-
- private SecondaryTables getSecondaryTables(Element tree, XMLContext.Default defaults) {
- List<Element> elements = tree == null ?
- new ArrayList<Element>() :
- (List<Element>) tree.elements( "secondary-table" );
- List<SecondaryTable> secondaryTables = new ArrayList<SecondaryTable>( 3 );
- for (Element element : elements) {
- AnnotationDescriptor annotation = new AnnotationDescriptor( SecondaryTable.class );
- copyStringAttribute( annotation, element, "name", false );
- copyStringAttribute( annotation, element, "catalog", false );
- if ( StringHelper.isNotEmpty( defaults.getCatalog() )
- && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
- annotation.setValue( "catalog", defaults.getCatalog() );
- }
- copyStringAttribute( annotation, element, "schema", false );
- if ( StringHelper.isNotEmpty( defaults.getSchema() )
- && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
- annotation.setValue( "schema", defaults.getSchema() );
- }
- buildUniqueConstraints( annotation, element );
- annotation.setValue( "pkJoinColumns", buildPrimaryKeyJoinColumns( element ) );
- secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
- }
- /*
- * You can't have both secondary table in XML and Java,
- * since there would be no way to "remove" a secondary table
- */
- if ( secondaryTables.size() == 0 && defaults.canUseJavaAnnotations() ) {
- SecondaryTable secTableAnn = getJavaAnnotation( SecondaryTable.class );
- overridesDefaultInSecondaryTable( secTableAnn, defaults, secondaryTables );
- SecondaryTables secTablesAnn = getJavaAnnotation( SecondaryTables.class );
- if ( secTablesAnn != null ) {
- for (SecondaryTable table : secTablesAnn.value()) {
- overridesDefaultInSecondaryTable( table, defaults, secondaryTables );
- }
- }
- }
- if ( secondaryTables.size() > 0 ) {
- AnnotationDescriptor descriptor = new AnnotationDescriptor( SecondaryTables.class );
- descriptor.setValue( "value", secondaryTables.toArray( new SecondaryTable[secondaryTables.size()] ) );
- return AnnotationFactory.create( descriptor );
- }
- else {
- return null;
- }
- }
-
- private void overridesDefaultInSecondaryTable(
- SecondaryTable secTableAnn, XMLContext.Default defaults, List<SecondaryTable> secondaryTables
- ) {
- if ( secTableAnn != null ) {
- //handle default values
- if ( StringHelper.isNotEmpty( defaults.getCatalog() )
- || StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- AnnotationDescriptor annotation = new AnnotationDescriptor( SecondaryTable.class );
- annotation.setValue( "name", secTableAnn.name() );
- annotation.setValue( "schema", secTableAnn.schema() );
- annotation.setValue( "catalog", secTableAnn.catalog() );
- annotation.setValue( "uniqueConstraints", secTableAnn.uniqueConstraints() );
- annotation.setValue( "pkJoinColumns", secTableAnn.pkJoinColumns() );
- if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
- && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
- annotation.setValue( "schema", defaults.getSchema() );
- }
- if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
- && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
- annotation.setValue( "catalog", defaults.getCatalog() );
- }
- secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
- }
- else {
- secondaryTables.add( secTableAnn );
- }
- }
- }
-
- private static void buildUniqueConstraints(AnnotationDescriptor annotation, Element element) {
- List uniqueConstraintElementList = element.elements( "unique-constraint" );
- UniqueConstraint[] uniqueConstraints = new UniqueConstraint[uniqueConstraintElementList.size()];
- int ucIndex = 0;
- Iterator ucIt = uniqueConstraintElementList.listIterator();
- while ( ucIt.hasNext() ) {
- Element subelement = (Element) ucIt.next();
- List<Element> columnNamesElements = subelement.elements( "column-name" );
- String[] columnNames = new String[columnNamesElements.size()];
- int columnNameIndex = 0;
- Iterator it = columnNamesElements.listIterator();
- while ( it.hasNext() ) {
- Element columnNameElt = (Element) it.next();
- columnNames[columnNameIndex++] = columnNameElt.getTextTrim();
- }
- AnnotationDescriptor ucAnn = new AnnotationDescriptor( UniqueConstraint.class );
- ucAnn.setValue( "columnNames", columnNames );
- uniqueConstraints[ucIndex++] = AnnotationFactory.create( ucAnn );
- }
- annotation.setValue( "uniqueConstraints", uniqueConstraints );
- }
-
- private PrimaryKeyJoinColumn[] buildPrimaryKeyJoinColumns(Element element) {
- if ( element == null ) return new PrimaryKeyJoinColumn[] { };
- List pkJoinColumnElementList = element.elements( "primary-key-join-column" );
- PrimaryKeyJoinColumn[] pkJoinColumns = new PrimaryKeyJoinColumn[pkJoinColumnElementList.size()];
- int index = 0;
- Iterator pkIt = pkJoinColumnElementList.listIterator();
- while ( pkIt.hasNext() ) {
- Element subelement = (Element) pkIt.next();
- AnnotationDescriptor pkAnn = new AnnotationDescriptor( PrimaryKeyJoinColumn.class );
- copyStringAttribute( pkAnn, subelement, "name", false );
- copyStringAttribute( pkAnn, subelement, "referenced-column-name", false );
- copyStringAttribute( pkAnn, subelement, "column-definition", false );
- pkJoinColumns[index++] = AnnotationFactory.create( pkAnn );
- }
- return pkJoinColumns;
- }
-
- private static void copyStringAttribute(
- AnnotationDescriptor annotation, Element element, String attributeName, boolean mandatory
- ) {
- String attribute = element.attributeValue( attributeName );
- if ( attribute != null ) {
- String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
- annotation.setValue( annotationAttributeName, attribute );
- }
- else {
- if ( mandatory ) {
- throw new AnnotationException(
- element.getName() + "." + attributeName + " is mandatory in XML overring. " + SCHEMA_VALIDATION
- );
- }
- }
- }
-
- private static void copyIntegerAttribute(AnnotationDescriptor annotation, Element element, String attributeName) {
- String attribute = element.attributeValue( attributeName );
- if ( attribute != null ) {
- String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
- annotation.setValue( annotationAttributeName, attribute );
- try {
- int length = Integer.parseInt( attribute );
- annotation.setValue( annotationAttributeName, length );
- }
- catch (NumberFormatException e) {
- throw new AnnotationException(
- element.getPath() + attributeName + " not parseable: " + attribute + " (" + SCHEMA_VALIDATION + ")"
- );
- }
- }
- }
-
- private static String getJavaAttributeNameFromXMLOne(String attributeName) {
- StringBuilder annotationAttributeName = new StringBuilder( attributeName );
- int index = annotationAttributeName.indexOf( WORD_SEPARATOR );
- while ( index != -1 ) {
- annotationAttributeName.deleteCharAt( index );
- annotationAttributeName.setCharAt(
- index, Character.toUpperCase( annotationAttributeName.charAt( index ) )
- );
- index = annotationAttributeName.indexOf( WORD_SEPARATOR );
- }
- return annotationAttributeName.toString();
- }
-
- private static void copyStringElement(Element element, AnnotationDescriptor ad, String annotationAttribute) {
- String discr = element.getTextTrim();
- ad.setValue( annotationAttribute, discr );
- }
-
- private static void copyBooleanAttribute(AnnotationDescriptor descriptor, Element element, String attribute) {
- String attributeValue = element.attributeValue( attribute );
- if ( StringHelper.isNotEmpty( attributeValue ) ) {
- String javaAttribute = getJavaAttributeNameFromXMLOne( attribute );
- descriptor.setValue( javaAttribute, Boolean.parseBoolean( attributeValue ) );
- }
- }
-
- private <T extends Annotation> T getJavaAnnotation(Class<T> annotationType) {
- return element.getAnnotation( annotationType );
- }
-
- private <T extends Annotation> boolean isJavaAnnotationPresent(Class<T> annotationType) {
- return element.isAnnotationPresent( annotationType );
- }
-
- private Annotation[] getJavaAnnotations() {
- return element.getAnnotations();
- }
-}
Deleted: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3ReflectionManager.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3ReflectionManager.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3ReflectionManager.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -1,124 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.cfg.annotations.reflection;
-
-import java.lang.reflect.AnnotatedElement;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.persistence.EntityListeners;
-import javax.persistence.NamedNativeQuery;
-import javax.persistence.NamedQuery;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.SqlResultSetMapping;
-import javax.persistence.TableGenerator;
-
-import org.dom4j.Element;
-import org.hibernate.annotations.common.reflection.AnnotationReader;
-import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
-import org.hibernate.util.ReflectHelper;
-
-public class EJB3ReflectionManager extends JavaReflectionManager {
-
- private XMLContext xmlContext = new XMLContext();
- private HashMap defaults = null;
-
- public AnnotationReader buildAnnotationReader(AnnotatedElement annotatedElement) {
- if ( xmlContext.hasContext() ) {
- return new EJB3OverridenAnnotationReader( annotatedElement, xmlContext );
- }
- else {
- return super.buildAnnotationReader( annotatedElement );
- }
- }
-
- public Map getDefaults() {
- if ( defaults == null ) {
- defaults = new HashMap();
- XMLContext.Default xmlDefaults = xmlContext.getDefault( null );
- List<Class> entityListeners = new ArrayList<Class>();
- for (String className : xmlContext.getDefaultEntityListeners()) {
- try {
- entityListeners.add( ReflectHelper.classForName( className, this.getClass() ) );
- }
- catch (ClassNotFoundException e) {
- throw new IllegalStateException( "Default entity listener class not found: " + className );
- }
- }
- defaults.put( EntityListeners.class, entityListeners );
- for (Element element : xmlContext.getAllDocuments()) {
-
- List<Element> elements = element.elements( "sequence-generator" );
- List<SequenceGenerator> sequenceGenerators = (List<SequenceGenerator>) defaults.get( SequenceGenerator.class );
- if ( sequenceGenerators == null ) {
- sequenceGenerators = new ArrayList<SequenceGenerator>();
- defaults.put( SequenceGenerator.class, sequenceGenerators );
- }
- for (Element subelement : elements) {
- sequenceGenerators.add( EJB3OverridenAnnotationReader.buildSequenceGeneratorAnnotation( subelement ) );
- }
-
- elements = element.elements( "table-generator" );
- List<TableGenerator> tableGenerators = (List<TableGenerator>) defaults.get( TableGenerator.class );
- if ( tableGenerators == null ) {
- tableGenerators = new ArrayList<TableGenerator>();
- defaults.put( TableGenerator.class, tableGenerators );
- }
- for (Element subelement : elements) {
- tableGenerators.add( EJB3OverridenAnnotationReader.buildTableGeneratorAnnotation( subelement, xmlDefaults ) );
- }
-
- List<NamedQuery> namedQueries = (List<NamedQuery>) defaults.get( NamedQuery.class );
- if ( namedQueries == null ) {
- namedQueries = new ArrayList<NamedQuery>();
- defaults.put( NamedQuery.class, namedQueries );
- }
- List<NamedQuery> currentNamedQueries = EJB3OverridenAnnotationReader.buildNamedQueries( element, false, xmlDefaults );
- namedQueries.addAll( currentNamedQueries );
-
- List<NamedNativeQuery> namedNativeQueries = (List<NamedNativeQuery>) defaults.get( NamedNativeQuery.class );
- if ( namedNativeQueries == null ) {
- namedNativeQueries = new ArrayList<NamedNativeQuery>();
- defaults.put( NamedNativeQuery.class, namedNativeQueries );
- }
- List<NamedNativeQuery> currentNamedNativeQueries = EJB3OverridenAnnotationReader.buildNamedQueries( element, true, xmlDefaults );
- namedNativeQueries.addAll( currentNamedNativeQueries );
-
- List<SqlResultSetMapping> sqlResultSetMappings = (List<SqlResultSetMapping>) defaults.get( SqlResultSetMapping.class );
- if ( sqlResultSetMappings == null ) {
- sqlResultSetMappings = new ArrayList<SqlResultSetMapping>();
- defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
- }
- List<SqlResultSetMapping> currentSqlResultSetMappings = EJB3OverridenAnnotationReader.buildSqlResultsetMappings( element, xmlDefaults );
- sqlResultSetMappings.addAll( currentSqlResultSetMappings );
- }
- }
- return defaults;
- }
-
- public XMLContext getXMLContext() {
- return xmlContext;
- }
-}
Added: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java (rev 0)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -0,0 +1,126 @@
+package org.hibernate.cfg.annotations.reflection;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityListeners;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQuery;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.TableGenerator;
+
+import org.dom4j.Element;
+
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.java.JavaMetadataProvider;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * MetadataProvider aware of the JPA Deployment descriptor
+ *
+ * @author Emmanuel Bernard
+ */
+public class JPAMetadataProvider implements MetadataProvider {
+ private MetadataProvider delegate = new JavaMetadataProvider();
+ private XMLContext xmlContext = new XMLContext();
+ private Map<Object, Object> defaults;
+ private Map<AnnotatedElement, AnnotationReader> cache = new HashMap<AnnotatedElement, AnnotationReader>(100);
+
+ public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
+ AnnotationReader reader = cache.get( annotatedElement );
+ if (reader == null) {
+ if ( xmlContext.hasContext() ) {
+ reader = new JPAOverridenAnnotationReader( annotatedElement, xmlContext );
+ }
+ else {
+ reader = delegate.getAnnotationReader( annotatedElement );
+ }
+ cache.put(annotatedElement, reader);
+ }
+ return reader;
+ }
+
+ public Map<Object, Object> getDefaults() {
+ if ( defaults == null ) {
+ defaults = new HashMap<Object, Object>();
+ XMLContext.Default xmlDefaults = xmlContext.getDefault( null );
+ List<Class> entityListeners = new ArrayList<Class>();
+ for ( String className : xmlContext.getDefaultEntityListeners() ) {
+ try {
+ entityListeners.add( ReflectHelper.classForName( className, this.getClass() ) );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new IllegalStateException( "Default entity listener class not found: " + className );
+ }
+ }
+ defaults.put( EntityListeners.class, entityListeners );
+ for ( Element element : xmlContext.getAllDocuments() ) {
+
+ List<Element> elements = element.elements( "sequence-generator" );
+ List<SequenceGenerator> sequenceGenerators = ( List<SequenceGenerator> ) defaults.get( SequenceGenerator.class );
+ if ( sequenceGenerators == null ) {
+ sequenceGenerators = new ArrayList<SequenceGenerator>();
+ defaults.put( SequenceGenerator.class, sequenceGenerators );
+ }
+ for ( Element subelement : elements ) {
+ sequenceGenerators.add( JPAOverridenAnnotationReader.buildSequenceGeneratorAnnotation( subelement ) );
+ }
+
+ elements = element.elements( "table-generator" );
+ List<TableGenerator> tableGenerators = ( List<TableGenerator> ) defaults.get( TableGenerator.class );
+ if ( tableGenerators == null ) {
+ tableGenerators = new ArrayList<TableGenerator>();
+ defaults.put( TableGenerator.class, tableGenerators );
+ }
+ for ( Element subelement : elements ) {
+ tableGenerators.add(
+ JPAOverridenAnnotationReader.buildTableGeneratorAnnotation(
+ subelement, xmlDefaults
+ )
+ );
+ }
+
+ List<NamedQuery> namedQueries = ( List<NamedQuery> ) defaults.get( NamedQuery.class );
+ if ( namedQueries == null ) {
+ namedQueries = new ArrayList<NamedQuery>();
+ defaults.put( NamedQuery.class, namedQueries );
+ }
+ List<NamedQuery> currentNamedQueries = JPAOverridenAnnotationReader.buildNamedQueries(
+ element, false, xmlDefaults
+ );
+ namedQueries.addAll( currentNamedQueries );
+
+ List<NamedNativeQuery> namedNativeQueries = ( List<NamedNativeQuery> ) defaults.get( NamedNativeQuery.class );
+ if ( namedNativeQueries == null ) {
+ namedNativeQueries = new ArrayList<NamedNativeQuery>();
+ defaults.put( NamedNativeQuery.class, namedNativeQueries );
+ }
+ List<NamedNativeQuery> currentNamedNativeQueries = JPAOverridenAnnotationReader.buildNamedQueries(
+ element, true, xmlDefaults
+ );
+ namedNativeQueries.addAll( currentNamedNativeQueries );
+
+ List<SqlResultSetMapping> sqlResultSetMappings = ( List<SqlResultSetMapping> ) defaults.get(
+ SqlResultSetMapping.class
+ );
+ if ( sqlResultSetMappings == null ) {
+ sqlResultSetMappings = new ArrayList<SqlResultSetMapping>();
+ defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
+ }
+ List<SqlResultSetMapping> currentSqlResultSetMappings = JPAOverridenAnnotationReader.buildSqlResultsetMappings(
+ element, xmlDefaults
+ );
+ sqlResultSetMappings.addAll( currentSqlResultSetMappings );
+ }
+ }
+ return defaults;
+ }
+
+ public XMLContext getXMLContext() {
+ return xmlContext;
+ }
+}
Copied: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java (from rev 16204, core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/EJB3OverridenAnnotationReader.java)
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java (rev 0)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -0,0 +1,2104 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.cfg.annotations.reflection;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.AssociationOverride;
+import javax.persistence.AssociationOverrides;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.ColumnResult;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.EntityResult;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.ExcludeDefaultListeners;
+import javax.persistence.ExcludeSuperclassListeners;
+import javax.persistence.FetchType;
+import javax.persistence.FieldResult;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.JoinTable;
+import javax.persistence.Lob;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.MapKey;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderBy;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.PrimaryKeyJoinColumns;
+import javax.persistence.QueryHint;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.SqlResultSetMappings;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+import javax.persistence.Version;
+
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.AccessType;
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.Columns;
+import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
+import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.Filter;
+import org.hibernate.annotations.common.reflection.ReflectionUtil;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encapsulates the overriding of Java annotations from an EJB 3.0 descriptor.
+ *
+ * @author Paolo Perrotta
+ * @author Davide Marchignoli
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings("unchecked")
+public class JPAOverridenAnnotationReader implements AnnotationReader {
+ private Logger log = LoggerFactory.getLogger( JPAOverridenAnnotationReader.class );
+ private static final Map<Class, String> annotationToXml;
+ private static final String SCHEMA_VALIDATION = "Activate schema validation for more informations";
+ private static final Filter FILTER = new Filter() {
+ public boolean returnStatic() {
+ return false;
+ }
+
+ public boolean returnTransient() {
+ return false;
+ }
+ };
+
+ static {
+ annotationToXml = new HashMap<Class, String>();
+ annotationToXml.put( Entity.class, "entity" );
+ annotationToXml.put( MappedSuperclass.class, "mapped-superclass" );
+ annotationToXml.put( Embeddable.class, "embeddable" );
+ annotationToXml.put( Table.class, "table" );
+ annotationToXml.put( SecondaryTable.class, "secondary-table" );
+ annotationToXml.put( SecondaryTables.class, "secondary-table" );
+ annotationToXml.put( PrimaryKeyJoinColumn.class, "primary-key-join-column" );
+ annotationToXml.put( PrimaryKeyJoinColumns.class, "primary-key-join-column" );
+ annotationToXml.put( IdClass.class, "id-class" );
+ annotationToXml.put( Inheritance.class, "inheritance" );
+ annotationToXml.put( DiscriminatorValue.class, "discriminator-value" );
+ annotationToXml.put( DiscriminatorColumn.class, "discriminator-column" );
+ annotationToXml.put( SequenceGenerator.class, "sequence-generator" );
+ annotationToXml.put( TableGenerator.class, "table-generator" );
+ annotationToXml.put( NamedQuery.class, "named-query" );
+ annotationToXml.put( NamedQueries.class, "named-query" );
+ annotationToXml.put( NamedNativeQuery.class, "named-native-query" );
+ annotationToXml.put( NamedNativeQueries.class, "named-native-query" );
+ annotationToXml.put( SqlResultSetMapping.class, "sql-result-set-mapping" );
+ annotationToXml.put( SqlResultSetMappings.class, "sql-result-set-mapping" );
+ annotationToXml.put( ExcludeDefaultListeners.class, "exclude-default-listeners" );
+ annotationToXml.put( ExcludeSuperclassListeners.class, "exclude-superclass-listeners" );
+ annotationToXml.put( AccessType.class, "access" );
+ annotationToXml.put( AttributeOverride.class, "attribute-override" );
+ annotationToXml.put( AttributeOverrides.class, "attribute-override" );
+ annotationToXml.put( AttributeOverride.class, "association-override" );
+ annotationToXml.put( AttributeOverrides.class, "association-override" );
+ annotationToXml.put( Id.class, "id" );
+ annotationToXml.put( EmbeddedId.class, "embedded-id" );
+ annotationToXml.put( GeneratedValue.class, "generated-value" );
+ annotationToXml.put( Column.class, "column" );
+ annotationToXml.put( Columns.class, "column" );
+ annotationToXml.put( Temporal.class, "temporal" );
+ annotationToXml.put( Lob.class, "lob" );
+ annotationToXml.put( Enumerated.class, "enumerated" );
+ annotationToXml.put( Version.class, "version" );
+ annotationToXml.put( Transient.class, "transient" );
+ annotationToXml.put( Basic.class, "basic" );
+ annotationToXml.put( Embedded.class, "embedded" );
+ annotationToXml.put( ManyToOne.class, "many-to-one" );
+ annotationToXml.put( OneToOne.class, "one-to-one" );
+ annotationToXml.put( OneToMany.class, "one-to-many" );
+ annotationToXml.put( ManyToMany.class, "many-to-many" );
+ annotationToXml.put( JoinTable.class, "join-table" );
+ annotationToXml.put( JoinColumn.class, "join-column" );
+ annotationToXml.put( JoinColumns.class, "join-column" );
+ annotationToXml.put( MapKey.class, "map-key" );
+ annotationToXml.put( OrderBy.class, "order-by" );
+ annotationToXml.put( EntityListeners.class, "entity-listeners" );
+ annotationToXml.put( PrePersist.class, "pre-persist" );
+ annotationToXml.put( PreRemove.class, "pre-remove" );
+ annotationToXml.put( PreUpdate.class, "pre-update" );
+ annotationToXml.put( PostPersist.class, "post-persist" );
+ annotationToXml.put( PostRemove.class, "post-remove" );
+ annotationToXml.put( PostUpdate.class, "post-update" );
+ annotationToXml.put( PostLoad.class, "post-load" );
+ }
+
+ private XMLContext xmlContext;
+ private String className;
+ private String propertyName;
+ private PropertyType propertyType;
+ private transient Annotation[] annotations;
+ private transient Map<Class, Annotation> annotationsMap;
+ private static final String WORD_SEPARATOR = "-";
+ private transient List<Element> elementsForProperty;
+ private AccessibleObject mirroredAttribute;
+ private final AnnotatedElement element;
+
+ private enum PropertyType {
+ PROPERTY,
+ FIELD,
+ METHOD
+ }
+
+ public JPAOverridenAnnotationReader(AnnotatedElement el, XMLContext xmlContext) {
+ this.element = el;
+ this.xmlContext = xmlContext;
+ if ( el instanceof Class ) {
+ Class clazz = (Class) el;
+ className = clazz.getName();
+ }
+ else if ( el instanceof Field ) {
+ Field field = (Field) el;
+ className = field.getDeclaringClass().getName();
+ propertyName = field.getName();
+ propertyType = PropertyType.FIELD;
+ String expectedGetter = "get" + Character.toUpperCase( propertyName.charAt( 0 ) ) + propertyName.substring(
+ 1
+ );
+ try {
+ mirroredAttribute = field.getDeclaringClass().getDeclaredMethod( expectedGetter );
+ }
+ catch (NoSuchMethodException e) {
+ //no method
+ }
+ }
+ else if ( el instanceof Method ) {
+ Method method = (Method) el;
+ className = method.getDeclaringClass().getName();
+ propertyName = method.getName();
+ if ( ReflectionUtil.isProperty(
+ method,
+ null, //this is yukky!! we'd rather get the TypeEnvironment()
+ FILTER
+ ) ) {
+ if ( propertyName.startsWith( "get" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring( "get".length() ) );
+ }
+ else if ( propertyName.startsWith( "is" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring( "is".length() ) );
+ }
+ else {
+ throw new RuntimeException( "Method " + propertyName + " is not a property getter" );
+ }
+ propertyType = PropertyType.PROPERTY;
+ try {
+ mirroredAttribute = method.getDeclaringClass().getDeclaredField( propertyName );
+ }
+ catch (NoSuchFieldException e) {
+ //no method
+ }
+ }
+ else {
+ propertyType = PropertyType.METHOD;
+ }
+ }
+ else {
+ className = null;
+ propertyName = null;
+ }
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotationsMap.get( annotationType );
+ }
+
+ public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotationsMap.get( annotationType ) != null;
+ }
+
+ public Annotation[] getAnnotations() {
+ initAnnotations();
+ return annotations;
+ }
+
+ private void initAnnotations() {
+ if ( annotations == null ) {
+ XMLContext.Default defaults = xmlContext.getDefault( className );
+ if ( className != null && propertyName == null ) {
+ //is a class
+ Element tree = xmlContext.getXMLTree( className, null );
+ Annotation[] annotations = getJavaAnnotations();
+ List<Annotation> annotationList = new ArrayList<Annotation>( annotations.length + 5 );
+ annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
+ for (Annotation annotation : annotations) {
+ if ( !annotationToXml.containsKey( annotation.annotationType() ) ) {
+ //unknown annotations are left over
+ annotationList.add( annotation );
+ }
+ }
+ addIfNotNull( annotationList, getEntity( tree, defaults ) );
+ addIfNotNull( annotationList, getMappedSuperclass( tree, defaults ) );
+ addIfNotNull( annotationList, getEmbeddable( tree, defaults ) );
+ addIfNotNull( annotationList, getTable( tree, defaults ) );
+ addIfNotNull( annotationList, getSecondaryTables( tree, defaults ) );
+ addIfNotNull( annotationList, getPrimaryKeyJoinColumns( tree, defaults ) );
+ addIfNotNull( annotationList, getIdClass( tree, defaults ) );
+ addIfNotNull( annotationList, getInheritance( tree, defaults ) );
+ addIfNotNull( annotationList, getDiscriminatorValue( tree, defaults ) );
+ addIfNotNull( annotationList, getDiscriminatorColumn( tree, defaults ) );
+ addIfNotNull( annotationList, getSequenceGenerator( tree, defaults ) );
+ addIfNotNull( annotationList, getTableGenerator( tree, defaults ) );
+ addIfNotNull( annotationList, getNamedQueries( tree, defaults ) );
+ addIfNotNull( annotationList, getNamedNativeQueries( tree, defaults ) );
+ addIfNotNull( annotationList, getSqlResultSetMappings( tree, defaults ) );
+ addIfNotNull( annotationList, getExcludeDefaultListeners( tree, defaults ) );
+ addIfNotNull( annotationList, getExcludeSuperclassListeners( tree, defaults ) );
+ addIfNotNull( annotationList, getAccessType( tree, defaults ) );
+ addIfNotNull( annotationList, getAttributeOverrides( tree, defaults ) );
+ addIfNotNull( annotationList, getAssociationOverrides( tree, defaults ) );
+ addIfNotNull( annotationList, getEntityListeners( tree, defaults ) );
+ //FIXME use annotationsMap rather than annotationList this will be faster since the annotation type is usually known at put() time
+ this.annotations = annotationList.toArray( new Annotation[annotationList.size()] );
+ for (Annotation ann : this.annotations) {
+ annotationsMap.put( ann.annotationType(), ann );
+ }
+ checkForOrphanProperties( tree );
+ }
+ else if ( className != null ) { //&& propertyName != null ) { //always true but less confusing
+ Element tree = xmlContext.getXMLTree( className, propertyName );
+ Annotation[] annotations = getJavaAnnotations();
+ List<Annotation> annotationList = new ArrayList<Annotation>( annotations.length + 5 );
+ annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
+ for (Annotation annotation : annotations) {
+ if ( !annotationToXml.containsKey( annotation.annotationType() ) ) {
+ //unknown annotations are left over
+ annotationList.add( annotation );
+ }
+ }
+ preCalculateElementsForProperty( tree );
+ Transient transientAnn = getTransient( defaults );
+ if ( transientAnn != null ) {
+ annotationList.add( transientAnn );
+ }
+ else {
+ if ( defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( AccessType.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ getId( annotationList, defaults );
+ getEmbeddedId( annotationList, defaults );
+ getEmbedded( annotationList, defaults );
+ getBasic( annotationList, defaults );
+ getVersion( annotationList, defaults );
+ getAssociation( ManyToOne.class, annotationList, defaults );
+ getAssociation( OneToOne.class, annotationList, defaults );
+ getAssociation( OneToMany.class, annotationList, defaults );
+ getAssociation( ManyToMany.class, annotationList, defaults );
+ addIfNotNull( annotationList, getSequenceGenerator( elementsForProperty, defaults ) );
+ addIfNotNull( annotationList, getTableGenerator( elementsForProperty, defaults ) );
+ addIfNotNull( annotationList, getAttributeOverrides( elementsForProperty, defaults ) );
+
+ }
+ processEventAnnotations( annotationList, defaults );
+ //FIXME use annotationsMap rather than annotationList this will be faster since the annotation type is usually known at put() time
+ this.annotations = annotationList.toArray( new Annotation[annotationList.size()] );
+ for (Annotation ann : this.annotations) {
+ annotationsMap.put( ann.annotationType(), ann );
+ }
+ }
+ else {
+ this.annotations = getJavaAnnotations();
+ annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
+ for (Annotation ann : this.annotations) {
+ annotationsMap.put( ann.annotationType(), ann );
+ }
+ }
+ }
+ }
+
+ private void checkForOrphanProperties(Element tree) {
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName( className, this.getClass() );
+ }
+ catch (ClassNotFoundException e) {
+ return; //a primitive type most likely
+ }
+ Element element = tree != null ? tree.element( "attributes" ) : null;
+ //put entity.attributes elements
+ if ( element != null ) {
+ //precompute the list of properties
+ //TODO is it really useful...
+ Set<String> properties = new HashSet<String>();
+ for (Field field : clazz.getFields()) {
+ properties.add( field.getName() );
+ }
+ for (Method method : clazz.getMethods()) {
+ String name = method.getName();
+ if ( name.startsWith( "get" ) ) {
+ properties.add( Introspector.decapitalize( name.substring( "get".length() ) ) );
+ }
+ else if ( name.startsWith( "is" ) ) {
+ properties.add( Introspector.decapitalize( name.substring( "is".length() ) ) );
+ }
+ }
+ for (Element subelement : (List<Element>) element.elements()) {
+ String propertyName = subelement.attributeValue( "name" );
+ if ( !properties.contains( propertyName ) ) {
+ log.warn( "Property {} not found in class"
+ + " but described in <mapping-file/> (possible typo error)",
+ StringHelper.qualify( className, propertyName ) );
+ }
+ }
+ }
+ }
+
+ /**
+ * Addes the Annotation to the list (only if it's not null) and then returns it.
+ */
+ private Annotation addIfNotNull(List<Annotation> annotationList, Annotation element) {
+ if ( element != null ) {
+ annotationList.add( element );
+ }
+ return element;
+ }
+
+ //TODO mutualize the next 2 methods
+ private Annotation getTableGenerator(List<Element> elementsForProperty, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ Element subelement = element != null ? element.element( annotationToXml.get( TableGenerator.class ) ) : null;
+ if ( subelement != null ) {
+ return buildTableGeneratorAnnotation( subelement, defaults );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( TableGenerator.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+
+ private Annotation getSequenceGenerator(List<Element> elementsForProperty, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ Element subelement = element != null ? element.element( annotationToXml.get( SequenceGenerator.class ) ) : null;
+ if ( subelement != null ) {
+ return buildSequenceGeneratorAnnotation( subelement );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( SequenceGenerator.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void processEventAnnotations(List<Annotation> annotationList, XMLContext.Default defaults) {
+ boolean eventElement = false;
+ for (Element element : elementsForProperty) {
+ String elementName = element.getName();
+ if ( "pre-persist".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PrePersist.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "pre-remove".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PreRemove.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "pre-update".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PreUpdate.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-persist".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostPersist.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-remove".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostRemove.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-update".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostUpdate.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-load".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostLoad.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ }
+ if ( !eventElement && defaults.canUseJavaAnnotations() ) {
+ Annotation ann = getJavaAnnotation( PrePersist.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PreRemove.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PreUpdate.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostPersist.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostRemove.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostUpdate.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostLoad.class );
+ addIfNotNull( annotationList, ann );
+ }
+ }
+
+ private EntityListeners getEntityListeners(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( "entity-listeners" ) : null;
+ if ( element != null ) {
+ List<Class> entityListenerClasses = new ArrayList<Class>();
+ for (Element subelement : (List<Element>) element.elements( "entity-listener" )) {
+ String className = subelement.attributeValue( "class" );
+ try {
+ entityListenerClasses.add(
+ ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( className, defaults ),
+ this.getClass()
+ )
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException(
+ "Unable to find " + element.getPath() + ".class: " + className, e
+ );
+ }
+ }
+ AnnotationDescriptor ad = new AnnotationDescriptor( EntityListeners.class );
+ ad.setValue( "value", entityListenerClasses.toArray( new Class[entityListenerClasses.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( EntityListeners.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private JoinTable overridesDefaultsInJoinTable(Annotation annotation, XMLContext.Default defaults) {
+ //no element but might have some default or some annotation
+ boolean defaultToJoinTable = !( isJavaAnnotationPresent( JoinColumn.class )
+ || isJavaAnnotationPresent( JoinColumns.class ) );
+ final Class<? extends Annotation> annotationClass = annotation.annotationType();
+ defaultToJoinTable = defaultToJoinTable &&
+ ( ( annotationClass == ManyToMany.class && StringHelper.isEmpty( ( (ManyToMany) annotation ).mappedBy() ) )
+ || ( annotationClass == OneToMany.class && StringHelper.isEmpty( ( (OneToMany) annotation ).mappedBy() ) )
+ || ( annotationClass == CollectionOfElements.class )
+ );
+ final Class<JoinTable> annotationType = JoinTable.class;
+ if ( defaultToJoinTable
+ && ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ || StringHelper.isNotEmpty( defaults.getSchema() ) ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
+ if ( defaults.canUseJavaAnnotations() ) {
+ JoinTable table = getJavaAnnotation( annotationType );
+ if ( table != null ) {
+ ad.setValue( "name", table.name() );
+ ad.setValue( "schema", table.schema() );
+ ad.setValue( "catalog", table.catalog() );
+ ad.setValue( "uniqueConstraints", table.uniqueConstraints() );
+ ad.setValue( "joinColumns", table.joinColumns() );
+ ad.setValue( "inverseJoinColumns", table.inverseJoinColumns() );
+ }
+ }
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ ad.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ ad.setValue( "catalog", defaults.getCatalog() );
+ }
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( annotationType );
+ }
+ else {
+ return null;
+ }
+ }
+
+ /*
+ * no partial overriding possible
+ */
+ private void getJoinTable(List<Annotation> annotationList, Element tree, XMLContext.Default defaults) {
+ Element subelement = tree == null ? null : tree.element( "join-table" );
+ final Class<JoinTable> annotationType = JoinTable.class;
+ if ( subelement != null ) {
+ //ignore java annotation, an element is defined
+ AnnotationDescriptor annotation = new AnnotationDescriptor( annotationType );
+ copyStringAttribute( annotation, subelement, "name", false );
+ copyStringAttribute( annotation, subelement, "catalog", false );
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ copyStringAttribute( annotation, subelement, "schema", false );
+ if ( StringHelper.isNotEmpty( defaults.getSchema() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ buildUniqueConstraints( annotation, subelement );
+ annotation.setValue( "joinColumns", getJoinColumns( subelement, false ) );
+ annotation.setValue( "inverseJoinColumns", getJoinColumns( subelement, true ) );
+ annotationList.add( AnnotationFactory.create( annotation ) );
+ }
+ }
+
+ private void getAssociation(
+ Class<? extends Annotation> annotationType, List<Annotation> annotationList, XMLContext.Default defaults
+ ) {
+ String xmlName = annotationToXml.get( annotationType );
+ for (Element element : elementsForProperty) {
+ if ( xmlName.equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
+ String className = element.attributeValue( "target-entity" );
+ if ( className != null ) {
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( className, defaults ),
+ this.getClass()
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException(
+ "Unable to find " + element.getPath() + "target-entity: " + className, e
+ );
+ }
+ ad.setValue( "targetEntity", clazz );
+ }
+ getFetchType( ad, element );
+ getCascades( ad, element, defaults );
+ getJoinTable( annotationList, element, defaults );
+ buildJoinColumns( annotationList, element, defaults );
+ Annotation annotation = getPrimaryKeyJoinColumns( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ copyBooleanAttribute( ad, element, "optional" );
+ copyStringAttribute( ad, element, "mapped-by", false );
+ getOrderBy( annotationList, element, defaults );
+ getMapKey( annotationList, element, defaults );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( annotationType );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = overridesDefaultsInJoinTable( annotation, defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( MapKey.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( OrderBy.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Enumerated.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ else if ( isJavaAnnotationPresent( CollectionOfElements.class ) ) {
+ annotation = overridesDefaultsInJoinTable( getJavaAnnotation( CollectionOfElements.class ), defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( MapKey.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( OrderBy.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Enumerated.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private void getOrderBy(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
+ Element subelement = element != null ? element.element( "order-by" ) : null;
+ if ( subelement != null ) {
+ String orderByString = subelement.getTextTrim();
+ AnnotationDescriptor ad = new AnnotationDescriptor( OrderBy.class );
+ if ( StringHelper.isNotEmpty( orderByString ) ) ad.setValue( "value", orderByString );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getMapKey(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
+ Element subelement = element != null ? element.element( "map-key" ) : null;
+ if ( subelement != null ) {
+ String mapKeyString = subelement.attributeValue( "name" );
+ AnnotationDescriptor ad = new AnnotationDescriptor( MapKey.class );
+ if ( StringHelper.isNotEmpty( mapKeyString ) ) ad.setValue( "name", mapKeyString );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void buildJoinColumns(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
+ JoinColumn[] joinColumns = getJoinColumns( element, false );
+ if ( joinColumns.length > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( JoinColumns.class );
+ ad.setValue( "value", joinColumns );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getCascades(AnnotationDescriptor ad, Element element, XMLContext.Default defaults) {
+ List<Element> elements = element != null ? element.elements( "cascade" ) : new ArrayList<Element>( 0 );
+ List<CascadeType> cascades = new ArrayList<CascadeType>();
+ for (Element subelement : elements) {
+ if ( subelement.element( "cascade-all" ) != null ) cascades.add( CascadeType.ALL );
+ if ( subelement.element( "cascade-persist" ) != null ) cascades.add( CascadeType.PERSIST );
+ if ( subelement.element( "cascade-merge" ) != null ) cascades.add( CascadeType.MERGE );
+ if ( subelement.element( "cascade-remove" ) != null ) cascades.add( CascadeType.REMOVE );
+ if ( subelement.element( "cascade-refresh" ) != null ) cascades.add( CascadeType.REFRESH );
+ }
+ if ( Boolean.TRUE.equals( defaults.getCascadePersist() )
+ && !cascades.contains( CascadeType.ALL ) && !cascades.contains( CascadeType.PERSIST ) ) {
+ cascades.add( CascadeType.PERSIST );
+ }
+ if ( cascades.size() > 0 ) {
+ ad.setValue( "cascade", cascades.toArray( new CascadeType[cascades.size()] ) );
+ }
+ }
+
+ private void getEmbedded(List<Annotation> annotationList, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "embedded".equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Embedded.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( Embedded.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private Transient getTransient(XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "transient".equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Transient.class );
+ return AnnotationFactory.create( ad );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( Transient.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void getVersion(List<Annotation> annotationList, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "version".equals( element.getName() ) ) {
+ Annotation annotation = buildColumns( element );
+ addIfNotNull( annotationList, annotation );
+ getTemporal( annotationList, element );
+ AnnotationDescriptor basic = new AnnotationDescriptor( Version.class );
+ annotationList.add( AnnotationFactory.create( basic ) );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ //we have nothing, so Java annotations might occurs
+ Annotation annotation = getJavaAnnotation( Version.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private void getBasic(List<Annotation> annotationList, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "basic".equals( element.getName() ) ) {
+ Annotation annotation = buildColumns( element );
+ addIfNotNull( annotationList, annotation );
+ getTemporal( annotationList, element );
+ getLob( annotationList, element );
+ getEnumerated( annotationList, element );
+ AnnotationDescriptor basic = new AnnotationDescriptor( Basic.class );
+ getFetchType( basic, element );
+ copyBooleanAttribute( basic, element, "optional" );
+ annotationList.add( AnnotationFactory.create( basic ) );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ //no annotation presence constraint, basic is the default
+ Annotation annotation = getJavaAnnotation( Basic.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Enumerated.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+
+ private void getEnumerated(List<Annotation> annotationList, Element element) {
+ Element subElement = element != null ? element.element( "enumerated" ) : null;
+ if ( subElement != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Enumerated.class );
+ String enumerated = subElement.getTextTrim();
+ if ( "ORDINAL".equalsIgnoreCase( enumerated ) ) {
+ ad.setValue( "value", EnumType.ORDINAL );
+ }
+ else if ( "STRING".equalsIgnoreCase( enumerated ) ) {
+ ad.setValue( "value", EnumType.STRING );
+ }
+ else if ( StringHelper.isNotEmpty( enumerated ) ) {
+ throw new AnnotationException( "Unknown EnumType: " + enumerated + ". " + SCHEMA_VALIDATION );
+ }
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getLob(List<Annotation> annotationList, Element element) {
+ Element subElement = element != null ? element.element( "lob" ) : null;
+ if ( subElement != null ) {
+ annotationList.add( AnnotationFactory.create( new AnnotationDescriptor( Lob.class ) ) );
+ }
+ }
+
+ private void getFetchType(AnnotationDescriptor descriptor, Element element) {
+ String fetchString = element != null ? element.attributeValue( "fetch" ) : null;
+ if ( fetchString != null ) {
+ if ( "eager".equalsIgnoreCase( fetchString ) ) {
+ descriptor.setValue( "fetch", FetchType.EAGER );
+ }
+ else if ( "lazy".equalsIgnoreCase( fetchString ) ) {
+ descriptor.setValue( "fetch", FetchType.LAZY );
+ }
+ }
+ }
+
+ private void getEmbeddedId(List<Annotation> annotationList, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "embedded-id".equals( element.getName() ) ) {
+ if ( isProcessingId( defaults ) ) {
+ Annotation annotation = getAttributeOverrides( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getAssociationOverrides( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ AnnotationDescriptor ad = new AnnotationDescriptor( EmbeddedId.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+// else {
+// if ( defaults.canUseJavaAnnotations() ) {
+// if ( ! properOverridingOnMetadataNonComplete ) {
+// //check that id exists on the other attribute
+// //TODO Id too?
+// if ( mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent(
+// EmbeddedId.class
+// ) ) {
+// throw new AnnotationException(
+// "Cannot override an property with <embedded-id> not having an @EmbeddedId already"
+// );
+// }
+// }
+// }
+// }
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( EmbeddedId.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( GeneratedValue.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( TableGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( SequenceGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private void preCalculateElementsForProperty(Element tree) {
+ elementsForProperty = new ArrayList<Element>();
+ Element element = tree != null ? tree.element( "attributes" ) : null;
+ //put entity.attributes elements
+ if ( element != null ) {
+ for (Element subelement : (List<Element>) element.elements()) {
+ if ( propertyName.equals( subelement.attributeValue( "name" ) ) ) {
+ elementsForProperty.add( subelement );
+ }
+ }
+ }
+ //add pre-* etc from entity and pure entity listener classes
+ if ( tree != null ) {
+ for (Element subelement : (List<Element>) tree.elements()) {
+ if ( propertyName.equals( subelement.attributeValue( "method-name" ) ) ) {
+ elementsForProperty.add( subelement );
+ }
+ }
+ }
+ }
+
+ private void getId(List<Annotation> annotationList, XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "id".equals( element.getName() ) ) {
+ boolean processId = isProcessingId( defaults );
+ if ( processId ) {
+ Annotation annotation = buildColumns( element );
+ addIfNotNull( annotationList, annotation );
+ annotation = buildGeneratedValue( element );
+ addIfNotNull( annotationList, annotation );
+ getTemporal( annotationList, element );
+ //FIXME: fix the priority of xml over java for generator names
+ annotation = getTableGenerator( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getSequenceGenerator( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ AnnotationDescriptor id = new AnnotationDescriptor( Id.class );
+ annotationList.add( AnnotationFactory.create( id ) );
+ }
+// else {
+// if ( defaults.canUseJavaAnnotations() ) {
+// if ( ! properOverridingOnMetadataNonComplete ) {
+// //check that id exists on the other attribute
+// //TODO EmbeddedId too?
+// if ( mirroredAttribute == null || ! mirroredAttribute.isAnnotationPresent( Id.class ) ) {
+// throw new AnnotationException(
+// "Cannot override a property with <id> it does not have an @Id already"
+// );
+// }
+// }
+// }
+// }
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( Id.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( GeneratedValue.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( TableGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( SequenceGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private boolean isProcessingId(XMLContext.Default defaults) {
+ boolean isExplicit = defaults.getAccess() != null;
+ boolean correctAccess =
+ ( PropertyType.PROPERTY.equals( propertyType ) && "property".equals( defaults.getAccess() ) )
+ || ( PropertyType.FIELD.equals( propertyType ) && "field".equals( defaults.getAccess() ) );
+ boolean hasId = defaults.canUseJavaAnnotations()
+ && ( isJavaAnnotationPresent( Id.class ) || isJavaAnnotationPresent( EmbeddedId.class ) );
+ //if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) {
+ boolean mirrorAttributeIsId = defaults.canUseJavaAnnotations() &&
+ ( mirroredAttribute != null &&
+ ( mirroredAttribute.isAnnotationPresent( Id.class )
+ || mirroredAttribute.isAnnotationPresent( EmbeddedId.class ) ) );
+ boolean propertyIsDefault = PropertyType.PROPERTY.equals( propertyType )
+ && !mirrorAttributeIsId;
+ return correctAccess || ( !isExplicit && hasId ) || ( !isExplicit && propertyIsDefault );
+ }
+
+ private Columns buildColumns(Element element) {
+ List<Element> subelements = element.elements( "column" );
+ List<Column> columns = new ArrayList<Column>( subelements.size() );
+ for (Element subelement : subelements) {
+ columns.add( getColumn( subelement, false, element ) );
+ }
+ if ( columns.size() > 0 ) {
+ AnnotationDescriptor columnsDescr = new AnnotationDescriptor( Columns.class );
+ columnsDescr.setValue( "columns", columns.toArray( new Column[columns.size()] ) );
+ return AnnotationFactory.create( columnsDescr );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private GeneratedValue buildGeneratedValue(Element element) {
+ Element subElement = element != null ? element.element( "generated-value" ) : null;
+ if ( subElement != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( GeneratedValue.class );
+ String strategy = subElement.attributeValue( "strategy" );
+ if ( "TABLE".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.TABLE );
+ }
+ else if ( "SEQUENCE".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.SEQUENCE );
+ }
+ else if ( "IDENTITY".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.IDENTITY );
+ }
+ else if ( "AUTO".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.AUTO );
+ }
+ else if ( StringHelper.isNotEmpty( strategy ) ) {
+ throw new AnnotationException( "Unknown GenerationType: " + strategy + ". " + SCHEMA_VALIDATION );
+ }
+ copyStringAttribute( ad, subElement, "generator", false );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void getTemporal(List<Annotation> annotationList, Element element) {
+ Element subElement = element != null ? element.element( "temporal" ) : null;
+ if ( subElement != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Temporal.class );
+ String temporal = subElement.getTextTrim();
+ if ( "DATE".equalsIgnoreCase( temporal ) ) {
+ ad.setValue( "value", TemporalType.DATE );
+ }
+ else if ( "TIME".equalsIgnoreCase( temporal ) ) {
+ ad.setValue( "value", TemporalType.TIME );
+ }
+ else if ( "TIMESTAMP".equalsIgnoreCase( temporal ) ) {
+ ad.setValue( "value", TemporalType.TIMESTAMP );
+ }
+ else if ( StringHelper.isNotEmpty( temporal ) ) {
+ throw new AnnotationException( "Unknown TemporalType: " + temporal + ". " + SCHEMA_VALIDATION );
+ }
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private AssociationOverrides getAssociationOverrides(Element tree, XMLContext.Default defaults) {
+ List<AssociationOverride> attributes = (List<AssociationOverride>) buildAssociationOverrides( tree );
+ if ( defaults.canUseJavaAnnotations() ) {
+ AssociationOverride annotation = getJavaAnnotation( AssociationOverride.class );
+ addAssociationOverrideIfNeeded( annotation, attributes );
+ AssociationOverrides annotations = getJavaAnnotation( AssociationOverrides.class );
+ if ( annotations != null ) {
+ for (AssociationOverride current : annotations.value()) {
+ addAssociationOverrideIfNeeded( current, attributes );
+ }
+ }
+ }
+ if ( attributes.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( AssociationOverrides.class );
+ ad.setValue( "value", attributes.toArray( new AssociationOverride[attributes.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private List<AssociationOverride> buildAssociationOverrides(Element element) {
+ List<Element> subelements = element == null ? null : element.elements( "association-override" );
+ List<AssociationOverride> overrides = new ArrayList<AssociationOverride>();
+ if ( subelements != null && subelements.size() > 0 ) {
+ for (Element current : subelements) {
+ AnnotationDescriptor override = new AnnotationDescriptor( AssociationOverride.class );
+ copyStringAttribute( override, current, "name", true );
+ override.setValue( "joinColumns", getJoinColumns( current, false ) );
+ overrides.add( (AssociationOverride) AnnotationFactory.create( override ) );
+ }
+ }
+ return overrides;
+ }
+
+ private JoinColumn[] getJoinColumns(Element element, boolean isInverse) {
+ List<Element> subelements = element != null ?
+ element.elements( isInverse ? "inverse-join-column" : "join-column" ) :
+ null;
+ List<JoinColumn> joinColumns = new ArrayList<JoinColumn>();
+ if ( subelements != null ) {
+ for (Element subelement : subelements) {
+ AnnotationDescriptor column = new AnnotationDescriptor( JoinColumn.class );
+ copyStringAttribute( column, subelement, "name", false );
+ copyStringAttribute( column, subelement, "referenced-column-name", false );
+ copyBooleanAttribute( column, subelement, "unique" );
+ copyBooleanAttribute( column, subelement, "nullable" );
+ copyBooleanAttribute( column, subelement, "insertable" );
+ copyBooleanAttribute( column, subelement, "updatable" );
+ copyStringAttribute( column, subelement, "column-definition", false );
+ copyStringAttribute( column, subelement, "table", false );
+ joinColumns.add( (JoinColumn) AnnotationFactory.create( column ) );
+ }
+ }
+ return joinColumns.toArray( new JoinColumn[joinColumns.size()] );
+ }
+
+ private void addAssociationOverrideIfNeeded(AssociationOverride annotation, List<AssociationOverride> overrides) {
+ if ( annotation != null ) {
+ String overrideName = annotation.name();
+ boolean present = false;
+ for (AssociationOverride current : overrides) {
+ if ( current.name().equals( overrideName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) overrides.add( annotation );
+ }
+ }
+
+ private AttributeOverrides getAttributeOverrides(Element tree, XMLContext.Default defaults) {
+ List<AttributeOverride> attributes = buildAttributeOverrides( tree );
+ return mergeAttributeOverrides( defaults, attributes );
+ }
+
+ private AttributeOverrides getAttributeOverrides(List<Element> elements, XMLContext.Default defaults) {
+ List<AttributeOverride> attributes = new ArrayList<AttributeOverride>();
+ for (Element element : elements) {
+ attributes.addAll( buildAttributeOverrides( element ) );
+ }
+ return mergeAttributeOverrides( defaults, attributes );
+ }
+
+ private AttributeOverrides mergeAttributeOverrides(XMLContext.Default defaults,
+ List<AttributeOverride> attributes) {
+ if ( defaults.canUseJavaAnnotations() ) {
+ AttributeOverride annotation = getJavaAnnotation( AttributeOverride.class );
+ addAttributeOverrideIfNeeded( annotation, attributes );
+ AttributeOverrides annotations = getJavaAnnotation( AttributeOverrides.class );
+ if ( annotations != null ) {
+ for (AttributeOverride current : annotations.value()) {
+ addAttributeOverrideIfNeeded( current, attributes );
+ }
+ }
+ }
+ if ( attributes.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( AttributeOverrides.class );
+ ad.setValue( "value", attributes.toArray( new AttributeOverride[attributes.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private List<AttributeOverride> buildAttributeOverrides(Element element) {
+ List<Element> subelements = element == null ? null : element.elements( "attribute-override" );
+ return buildAttributeOverrides( subelements );
+ }
+
+ private List<AttributeOverride> buildAttributeOverrides(List<Element> subelements) {
+ List<AttributeOverride> overrides = new ArrayList<AttributeOverride>();
+ if ( subelements != null && subelements.size() > 0 ) {
+ for (Element current : subelements) {
+ if ( !current.getName().equals( "attribute-override" ) ) continue;
+ AnnotationDescriptor override = new AnnotationDescriptor( AttributeOverride.class );
+ copyStringAttribute( override, current, "name", true );
+ Element column = current != null ? current.element( "column" ) : null;
+ override.setValue( "column", getColumn( column, true, current ) );
+ overrides.add( (AttributeOverride) AnnotationFactory.create( override ) );
+ }
+ }
+ return overrides;
+ }
+
+ private Column getColumn(Element element, boolean isMandatory, Element current) {
+ //Element subelement = element != null ? element.element( "column" ) : null;
+ if ( element != null ) {
+ AnnotationDescriptor column = new AnnotationDescriptor( Column.class );
+ copyStringAttribute( column, element, "name", false );
+ copyBooleanAttribute( column, element, "unique" );
+ copyBooleanAttribute( column, element, "nullable" );
+ copyBooleanAttribute( column, element, "insertable" );
+ copyBooleanAttribute( column, element, "updatable" );
+ copyStringAttribute( column, element, "column-definition", false );
+ copyStringAttribute( column, element, "table", false );
+ copyIntegerAttribute( column, element, "length" );
+ copyIntegerAttribute( column, element, "precision" );
+ copyIntegerAttribute( column, element, "scale" );
+ return (Column) AnnotationFactory.create( column );
+ }
+ else {
+ if ( isMandatory ) {
+ throw new AnnotationException( current.getPath() + ".column is mandatory. " + SCHEMA_VALIDATION );
+ }
+ return null;
+ }
+ }
+
+ private void addAttributeOverrideIfNeeded(AttributeOverride annotation, List<AttributeOverride> overrides) {
+ if ( annotation != null ) {
+ String overrideName = annotation.name();
+ boolean present = false;
+ for (AttributeOverride current : overrides) {
+ if ( current.name().equals( overrideName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) overrides.add( annotation );
+ }
+ }
+
+ private AccessType getAccessType(Element tree, XMLContext.Default defaults) {
+ String access = tree == null ? null : tree.attributeValue( "access" );
+ if ( "FIELD".equals( access ) || "PROPERTY".equals( access ) ) {
+ access = access.toLowerCase();
+ }
+ if ( access != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( AccessType.class );
+ ad.setValue( "value", access );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() && isJavaAnnotationPresent( AccessType.class ) ) {
+ AccessType annotation = getJavaAnnotation( AccessType.class );
+ return annotation;
+ }
+ else if ( defaults.getAccess() != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( AccessType.class );
+ ad.setValue( "value", defaults.getAccess() );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private ExcludeSuperclassListeners getExcludeSuperclassListeners(Element tree, XMLContext.Default defaults) {
+ return (ExcludeSuperclassListeners) getMarkerAnnotation( ExcludeSuperclassListeners.class, tree, defaults );
+ }
+
+ private ExcludeDefaultListeners getExcludeDefaultListeners(Element tree, XMLContext.Default defaults) {
+ return (ExcludeDefaultListeners) getMarkerAnnotation( ExcludeDefaultListeners.class, tree, defaults );
+ }
+
+ private Annotation getMarkerAnnotation(
+ Class<? extends Annotation> clazz, Element element, XMLContext.Default defaults
+ ) {
+ Element subelement = element == null ? null : element.element( annotationToXml.get( clazz ) );
+ if ( subelement != null ) {
+ return AnnotationFactory.create( new AnnotationDescriptor( clazz ) );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ //TODO wonder whether it should be excluded so that user can undone it
+ return getJavaAnnotation( clazz );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private SqlResultSetMappings getSqlResultSetMappings(Element tree, XMLContext.Default defaults) {
+ List<SqlResultSetMapping> results = (List<SqlResultSetMapping>) buildSqlResultsetMappings( tree, defaults );
+ if ( defaults.canUseJavaAnnotations() ) {
+ SqlResultSetMapping annotation = getJavaAnnotation( SqlResultSetMapping.class );
+ addSqlResultsetMappingIfNeeded( annotation, results );
+ SqlResultSetMappings annotations = getJavaAnnotation( SqlResultSetMappings.class );
+ if ( annotations != null ) {
+ for (SqlResultSetMapping current : annotations.value()) {
+ addSqlResultsetMappingIfNeeded( current, results );
+ }
+ }
+ }
+ if ( results.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( SqlResultSetMappings.class );
+ ad.setValue( "value", results.toArray( new SqlResultSetMapping[results.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults) {
+ if ( element == null ) return new ArrayList<SqlResultSetMapping>();
+ List resultsetElementList = element.elements( "sql-result-set-mapping" );
+ List<SqlResultSetMapping> resultsets = new ArrayList<SqlResultSetMapping>();
+ Iterator it = resultsetElementList.listIterator();
+ while ( it.hasNext() ) {
+ Element subelement = (Element) it.next();
+ AnnotationDescriptor ann = new AnnotationDescriptor( SqlResultSetMapping.class );
+ copyStringAttribute( ann, subelement, "name", true );
+ List<Element> elements = subelement.elements( "entity-result" );
+ List<EntityResult> entityResults = new ArrayList<EntityResult>( elements.size() );
+ for (Element entityResult : elements) {
+ AnnotationDescriptor entityResultDescriptor = new AnnotationDescriptor( EntityResult.class );
+ String clazzName = entityResult.attributeValue( "entity-class" );
+ if ( clazzName == null ) {
+ throw new AnnotationException( "<entity-result> without entity-class. " + SCHEMA_VALIDATION );
+ }
+ Class clazz = null;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( clazzName, defaults ),
+ JPAOverridenAnnotationReader.class
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
+ }
+ entityResultDescriptor.setValue( "entityClass", clazz );
+ copyStringAttribute( entityResultDescriptor, entityResult, "discriminator-column", false );
+ List<FieldResult> fieldResults = new ArrayList<FieldResult>();
+ for (Element fieldResult : (List<Element>) entityResult.elements( "field-result" )) {
+ AnnotationDescriptor fieldResultDescriptor = new AnnotationDescriptor( FieldResult.class );
+ copyStringAttribute( fieldResultDescriptor, fieldResult, "name", true );
+ copyStringAttribute( fieldResultDescriptor, fieldResult, "column", true );
+ fieldResults.add( (FieldResult) AnnotationFactory.create( fieldResultDescriptor ) );
+ }
+ entityResultDescriptor.setValue(
+ "fields", fieldResults.toArray( new FieldResult[fieldResults.size()] )
+ );
+ entityResults.add( (EntityResult) AnnotationFactory.create( entityResultDescriptor ) );
+ }
+ ann.setValue( "entities", entityResults.toArray( new EntityResult[entityResults.size()] ) );
+
+ elements = subelement.elements( "column-result" );
+ List<ColumnResult> columnResults = new ArrayList<ColumnResult>( elements.size() );
+ for (Element columnResult : elements) {
+ AnnotationDescriptor columnResultDescriptor = new AnnotationDescriptor( ColumnResult.class );
+ copyStringAttribute( columnResultDescriptor, columnResult, "name", true );
+ columnResults.add( (ColumnResult) AnnotationFactory.create( columnResultDescriptor ) );
+ }
+ ann.setValue( "columns", columnResults.toArray( new ColumnResult[columnResults.size()] ) );
+ //FIXME there is never such a result-class, get rid of it?
+ String clazzName = subelement.attributeValue( "result-class" );
+ if ( StringHelper.isNotEmpty( clazzName ) ) {
+ Class clazz = null;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( clazzName, defaults ),
+ JPAOverridenAnnotationReader.class
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
+ }
+ ann.setValue( "resultClass", clazz );
+ }
+ copyStringAttribute( ann, subelement, "result-set-mapping", false );
+ resultsets.add( (SqlResultSetMapping) AnnotationFactory.create( ann ) );
+ }
+ return resultsets;
+ }
+
+ private void addSqlResultsetMappingIfNeeded(SqlResultSetMapping annotation, List<SqlResultSetMapping> resultsets) {
+ if ( annotation != null ) {
+ String resultsetName = annotation.name();
+ boolean present = false;
+ for (SqlResultSetMapping current : resultsets) {
+ if ( current.name().equals( resultsetName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) resultsets.add( annotation );
+ }
+ }
+
+ private NamedQueries getNamedQueries(Element tree, XMLContext.Default defaults) {
+ //TODO avoid the Proxy Creation (@NamedQueries) when possible
+ List<NamedQuery> queries = (List<NamedQuery>) buildNamedQueries( tree, false, defaults );
+ if ( defaults.canUseJavaAnnotations() ) {
+ NamedQuery annotation = getJavaAnnotation( NamedQuery.class );
+ addNamedQueryIfNeeded( annotation, queries );
+ NamedQueries annotations = getJavaAnnotation( NamedQueries.class );
+ if ( annotations != null ) {
+ for (NamedQuery current : annotations.value()) {
+ addNamedQueryIfNeeded( current, queries );
+ }
+ }
+ }
+ if ( queries.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( NamedQueries.class );
+ ad.setValue( "value", queries.toArray( new NamedQuery[queries.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void addNamedQueryIfNeeded(NamedQuery annotation, List<NamedQuery> queries) {
+ if ( annotation != null ) {
+ String queryName = annotation.name();
+ boolean present = false;
+ for (NamedQuery current : queries) {
+ if ( current.name().equals( queryName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) queries.add( annotation );
+ }
+ }
+
+ private NamedNativeQueries getNamedNativeQueries(Element tree, XMLContext.Default defaults) {
+ List<NamedNativeQuery> queries = (List<NamedNativeQuery>) buildNamedQueries( tree, true, defaults );
+ if ( defaults.canUseJavaAnnotations() ) {
+ NamedNativeQuery annotation = getJavaAnnotation( NamedNativeQuery.class );
+ addNamedNativeQueryIfNeeded( annotation, queries );
+ NamedNativeQueries annotations = getJavaAnnotation( NamedNativeQueries.class );
+ if ( annotations != null ) {
+ for (NamedNativeQuery current : annotations.value()) {
+ addNamedNativeQueryIfNeeded( current, queries );
+ }
+ }
+ }
+ if ( queries.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( NamedNativeQueries.class );
+ ad.setValue( "value", queries.toArray( new NamedNativeQuery[queries.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void addNamedNativeQueryIfNeeded(NamedNativeQuery annotation, List<NamedNativeQuery> queries) {
+ if ( annotation != null ) {
+ String queryName = annotation.name();
+ boolean present = false;
+ for (NamedNativeQuery current : queries) {
+ if ( current.name().equals( queryName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) queries.add( annotation );
+ }
+ }
+
+ public static List buildNamedQueries(Element element, boolean isNative, XMLContext.Default defaults) {
+ if ( element == null ) return new ArrayList();
+ List namedQueryElementList = isNative ?
+ element.elements( "named-native-query" ) :
+ element.elements( "named-query" );
+ List namedQueries = new ArrayList();
+ Iterator it = namedQueryElementList.listIterator();
+ while ( it.hasNext() ) {
+ Element subelement = (Element) it.next();
+ AnnotationDescriptor ann = new AnnotationDescriptor(
+ isNative ? NamedNativeQuery.class : NamedQuery.class
+ );
+ copyStringAttribute( ann, subelement, "name", false );
+ Element queryElt = subelement.element( "query" );
+ if ( queryElt == null ) throw new AnnotationException( "No <query> element found." + SCHEMA_VALIDATION );
+ ann.setValue( "query", queryElt.getTextTrim() );
+ List<Element> elements = subelement.elements( "hint" );
+ List<QueryHint> queryHints = new ArrayList<QueryHint>( elements.size() );
+ for (Element hint : elements) {
+ AnnotationDescriptor hintDescriptor = new AnnotationDescriptor( QueryHint.class );
+ String value = hint.attributeValue( "name" );
+ if ( value == null ) throw new AnnotationException( "<hint> without name. " + SCHEMA_VALIDATION );
+ hintDescriptor.setValue( "name", value );
+ value = hint.attributeValue( "value" );
+ if ( value == null ) throw new AnnotationException( "<hint> without value. " + SCHEMA_VALIDATION );
+ hintDescriptor.setValue( "value", value );
+ queryHints.add( (QueryHint) AnnotationFactory.create( hintDescriptor ) );
+ }
+ ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
+ String clazzName = subelement.attributeValue( "result-class" );
+ if ( StringHelper.isNotEmpty( clazzName ) ) {
+ Class clazz = null;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( clazzName, defaults ),
+ JPAOverridenAnnotationReader.class
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
+ }
+ ann.setValue( "resultClass", clazz );
+ }
+ copyStringAttribute( ann, subelement, "result-set-mapping", false );
+ namedQueries.add( AnnotationFactory.create( ann ) );
+ }
+ return namedQueries;
+ }
+
+ private TableGenerator getTableGenerator(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( annotationToXml.get( TableGenerator.class ) ) : null;
+ if ( element != null ) {
+ return buildTableGeneratorAnnotation( element, defaults );
+ }
+ else if ( defaults.canUseJavaAnnotations() && isJavaAnnotationPresent( TableGenerator.class ) ) {
+ TableGenerator tableAnn = getJavaAnnotation( TableGenerator.class );
+ if ( StringHelper.isNotEmpty( defaults.getSchema() )
+ || StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( TableGenerator.class );
+ annotation.setValue( "name", tableAnn.name() );
+ annotation.setValue( "table", tableAnn.table() );
+ annotation.setValue( "catalog", tableAnn.table() );
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ annotation.setValue( "schema", tableAnn.table() );
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ annotation.setValue( "catalog", defaults.getSchema() );
+ }
+ annotation.setValue( "pkColumnName", tableAnn.pkColumnName() );
+ annotation.setValue( "valueColumnName", tableAnn.valueColumnName() );
+ annotation.setValue( "pkColumnValue", tableAnn.pkColumnValue() );
+ annotation.setValue( "initialValue", tableAnn.initialValue() );
+ annotation.setValue( "allocationSize", tableAnn.allocationSize() );
+ annotation.setValue( "uniqueConstraints", tableAnn.uniqueConstraints() );
+ return AnnotationFactory.create( annotation );
+ }
+ else {
+ return tableAnn;
+ }
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static TableGenerator buildTableGeneratorAnnotation(Element element, XMLContext.Default defaults) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( TableGenerator.class );
+ copyStringAttribute( ad, element, "name", false );
+ copyStringAttribute( ad, element, "table", false );
+ copyStringAttribute( ad, element, "catalog", false );
+ copyStringAttribute( ad, element, "schema", false );
+ copyStringAttribute( ad, element, "pk-column-name", false );
+ copyStringAttribute( ad, element, "value-column-name", false );
+ copyStringAttribute( ad, element, "pk-column-value", false );
+ copyIntegerAttribute( ad, element, "initial-value" );
+ copyIntegerAttribute( ad, element, "allocation-size" );
+ buildUniqueConstraints( ad, element );
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ ad.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ ad.setValue( "catalog", defaults.getCatalog() );
+ }
+ return AnnotationFactory.create( ad );
+ }
+
+ private SequenceGenerator getSequenceGenerator(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( annotationToXml.get( SequenceGenerator.class ) ) : null;
+ if ( element != null ) {
+ return buildSequenceGeneratorAnnotation( element );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( SequenceGenerator.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static SequenceGenerator buildSequenceGeneratorAnnotation(Element element) {
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( SequenceGenerator.class );
+ copyStringAttribute( ad, element, "name", false );
+ copyStringAttribute( ad, element, "sequence-name", false );
+ copyIntegerAttribute( ad, element, "initial-value" );
+ copyIntegerAttribute( ad, element, "allocation-size" );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private DiscriminatorColumn getDiscriminatorColumn(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( "discriminator-column" ) : null;
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( DiscriminatorColumn.class );
+ copyStringAttribute( ad, element, "name", false );
+ copyStringAttribute( ad, element, "column-definition", false );
+ String value = element.attributeValue( "discriminator-type" );
+ DiscriminatorType type = DiscriminatorType.STRING;
+ if ( value != null ) {
+ if ( "STRING".equals( value ) ) {
+ type = DiscriminatorType.STRING;
+ }
+ else if ( "CHAR".equals( value ) ) {
+ type = DiscriminatorType.CHAR;
+ }
+ else if ( "INTEGER".equals( value ) ) {
+ type = DiscriminatorType.INTEGER;
+ }
+ else {
+ throw new AnnotationException(
+ "Unknown DiscrimiatorType in XML: " + value + " (" + SCHEMA_VALIDATION + ")"
+ );
+ }
+ }
+ ad.setValue( "discriminatorType", type );
+ copyIntegerAttribute( ad, element, "length" );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( DiscriminatorColumn.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private DiscriminatorValue getDiscriminatorValue(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( "discriminator-value" ) : null;
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( DiscriminatorValue.class );
+ copyStringElement( element, ad, "value" );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( DiscriminatorValue.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private Inheritance getInheritance(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( "inheritance" ) : null;
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Inheritance.class );
+ Attribute attr = element.attribute( "strategy" );
+ InheritanceType strategy = InheritanceType.SINGLE_TABLE;
+ if ( attr != null ) {
+ String value = attr.getValue();
+ if ( "SINGLE_TABLE".equals( value ) ) {
+ strategy = InheritanceType.SINGLE_TABLE;
+ }
+ else if ( "JOINED".equals( value ) ) {
+ strategy = InheritanceType.JOINED;
+ }
+ else if ( "TABLE_PER_CLASS".equals( value ) ) {
+ strategy = InheritanceType.TABLE_PER_CLASS;
+ }
+ else {
+ throw new AnnotationException(
+ "Unknown InheritanceType in XML: " + value + " (" + SCHEMA_VALIDATION + ")"
+ );
+ }
+ }
+ ad.setValue( "strategy", strategy );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( Inheritance.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private IdClass getIdClass(Element tree, XMLContext.Default defaults) {
+ Element element = tree == null ? null : tree.element( "id-class" );
+ if ( element != null ) {
+ Attribute attr = element.attribute( "class" );
+ if ( attr != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( IdClass.class );
+ Class clazz = null;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( attr.getValue(), defaults ),
+ this.getClass()
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find id-class: " + attr.getValue(), e );
+ }
+ ad.setValue( "value", clazz );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ throw new AnnotationException( "id-class without class. " + SCHEMA_VALIDATION );
+ }
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( IdClass.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private PrimaryKeyJoinColumns getPrimaryKeyJoinColumns(Element element, XMLContext.Default defaults) {
+ PrimaryKeyJoinColumn[] columns = buildPrimaryKeyJoinColumns( element );
+ if ( columns.length == 0 && defaults.canUseJavaAnnotations() ) {
+ PrimaryKeyJoinColumn annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ if ( annotation != null ) {
+ columns = new PrimaryKeyJoinColumn[] { annotation };
+ }
+ else {
+ PrimaryKeyJoinColumns annotations = getJavaAnnotation( PrimaryKeyJoinColumns.class );
+ columns = annotations != null ? annotations.value() : columns;
+ }
+ }
+ if ( columns.length > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PrimaryKeyJoinColumns.class );
+ ad.setValue( "value", columns );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private Entity getEntity(Element tree, XMLContext.Default defaults) {
+ if ( tree == null ) {
+ return defaults.canUseJavaAnnotations() ? getJavaAnnotation( Entity.class ) : null;
+ }
+ else {
+ if ( "entity".equals( tree.getName() ) ) {
+ AnnotationDescriptor entity = new AnnotationDescriptor( Entity.class );
+ copyStringAttribute( entity, tree, "name", false );
+ if ( defaults.canUseJavaAnnotations()
+ && StringHelper.isEmpty( (String) entity.valueOf( "name" ) ) ) {
+ Entity javaAnn = getJavaAnnotation( Entity.class );
+ if ( javaAnn != null ) entity.setValue( "name", javaAnn.name() );
+ }
+ return AnnotationFactory.create( entity );
+ }
+ else {
+ return null; //this is not an entity
+ }
+ }
+ }
+
+ private MappedSuperclass getMappedSuperclass(Element tree, XMLContext.Default defaults) {
+ if ( tree == null ) {
+ return defaults.canUseJavaAnnotations() ? getJavaAnnotation( MappedSuperclass.class ) : null;
+ }
+ else {
+ if ( "mapped-superclass".equals( tree.getName() ) ) {
+ AnnotationDescriptor entity = new AnnotationDescriptor( MappedSuperclass.class );
+ return AnnotationFactory.create( entity );
+ }
+ else {
+ return null; //this is not an entity
+ }
+ }
+ }
+
+ private Embeddable getEmbeddable(Element tree, XMLContext.Default defaults) {
+ if ( tree == null ) {
+ return defaults.canUseJavaAnnotations() ? getJavaAnnotation( Embeddable.class ) : null;
+ }
+ else {
+ if ( "embeddable".equals( tree.getName() ) ) {
+ AnnotationDescriptor entity = new AnnotationDescriptor( Embeddable.class );
+ return AnnotationFactory.create( entity );
+ }
+ else {
+ return null; //this is not an entity
+ }
+ }
+ }
+
+ private Table getTable(Element tree, XMLContext.Default defaults) {
+ Element subelement = tree == null ? null : tree.element( "table" );
+ if ( subelement == null ) {
+ //no element but might have some default or some annotation
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ || StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( Table.class );
+ if ( defaults.canUseJavaAnnotations() ) {
+ Table table = getJavaAnnotation( Table.class );
+ if ( table != null ) {
+ annotation.setValue( "name", table.name() );
+ annotation.setValue( "schema", table.schema() );
+ annotation.setValue( "catalog", table.catalog() );
+ annotation.setValue( "uniqueConstraints", table.uniqueConstraints() );
+ }
+ }
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ return AnnotationFactory.create( annotation );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( Table.class );
+ }
+ else {
+ return null;
+ }
+ }
+ else {
+ //ignore java annotation, an element is defined
+ AnnotationDescriptor annotation = new AnnotationDescriptor( Table.class );
+ copyStringAttribute( annotation, subelement, "name", false );
+ copyStringAttribute( annotation, subelement, "catalog", false );
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ copyStringAttribute( annotation, subelement, "schema", false );
+ if ( StringHelper.isNotEmpty( defaults.getSchema() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ buildUniqueConstraints( annotation, subelement );
+ return AnnotationFactory.create( annotation );
+ }
+ }
+
+ private SecondaryTables getSecondaryTables(Element tree, XMLContext.Default defaults) {
+ List<Element> elements = tree == null ?
+ new ArrayList<Element>() :
+ (List<Element>) tree.elements( "secondary-table" );
+ List<SecondaryTable> secondaryTables = new ArrayList<SecondaryTable>( 3 );
+ for (Element element : elements) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( SecondaryTable.class );
+ copyStringAttribute( annotation, element, "name", false );
+ copyStringAttribute( annotation, element, "catalog", false );
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ copyStringAttribute( annotation, element, "schema", false );
+ if ( StringHelper.isNotEmpty( defaults.getSchema() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ buildUniqueConstraints( annotation, element );
+ annotation.setValue( "pkJoinColumns", buildPrimaryKeyJoinColumns( element ) );
+ secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
+ }
+ /*
+ * You can't have both secondary table in XML and Java,
+ * since there would be no way to "remove" a secondary table
+ */
+ if ( secondaryTables.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ SecondaryTable secTableAnn = getJavaAnnotation( SecondaryTable.class );
+ overridesDefaultInSecondaryTable( secTableAnn, defaults, secondaryTables );
+ SecondaryTables secTablesAnn = getJavaAnnotation( SecondaryTables.class );
+ if ( secTablesAnn != null ) {
+ for (SecondaryTable table : secTablesAnn.value()) {
+ overridesDefaultInSecondaryTable( table, defaults, secondaryTables );
+ }
+ }
+ }
+ if ( secondaryTables.size() > 0 ) {
+ AnnotationDescriptor descriptor = new AnnotationDescriptor( SecondaryTables.class );
+ descriptor.setValue( "value", secondaryTables.toArray( new SecondaryTable[secondaryTables.size()] ) );
+ return AnnotationFactory.create( descriptor );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void overridesDefaultInSecondaryTable(
+ SecondaryTable secTableAnn, XMLContext.Default defaults, List<SecondaryTable> secondaryTables
+ ) {
+ if ( secTableAnn != null ) {
+ //handle default values
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ || StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( SecondaryTable.class );
+ annotation.setValue( "name", secTableAnn.name() );
+ annotation.setValue( "schema", secTableAnn.schema() );
+ annotation.setValue( "catalog", secTableAnn.catalog() );
+ annotation.setValue( "uniqueConstraints", secTableAnn.uniqueConstraints() );
+ annotation.setValue( "pkJoinColumns", secTableAnn.pkJoinColumns() );
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
+ }
+ else {
+ secondaryTables.add( secTableAnn );
+ }
+ }
+ }
+
+ private static void buildUniqueConstraints(AnnotationDescriptor annotation, Element element) {
+ List uniqueConstraintElementList = element.elements( "unique-constraint" );
+ UniqueConstraint[] uniqueConstraints = new UniqueConstraint[uniqueConstraintElementList.size()];
+ int ucIndex = 0;
+ Iterator ucIt = uniqueConstraintElementList.listIterator();
+ while ( ucIt.hasNext() ) {
+ Element subelement = (Element) ucIt.next();
+ List<Element> columnNamesElements = subelement.elements( "column-name" );
+ String[] columnNames = new String[columnNamesElements.size()];
+ int columnNameIndex = 0;
+ Iterator it = columnNamesElements.listIterator();
+ while ( it.hasNext() ) {
+ Element columnNameElt = (Element) it.next();
+ columnNames[columnNameIndex++] = columnNameElt.getTextTrim();
+ }
+ AnnotationDescriptor ucAnn = new AnnotationDescriptor( UniqueConstraint.class );
+ ucAnn.setValue( "columnNames", columnNames );
+ uniqueConstraints[ucIndex++] = AnnotationFactory.create( ucAnn );
+ }
+ annotation.setValue( "uniqueConstraints", uniqueConstraints );
+ }
+
+ private PrimaryKeyJoinColumn[] buildPrimaryKeyJoinColumns(Element element) {
+ if ( element == null ) return new PrimaryKeyJoinColumn[] { };
+ List pkJoinColumnElementList = element.elements( "primary-key-join-column" );
+ PrimaryKeyJoinColumn[] pkJoinColumns = new PrimaryKeyJoinColumn[pkJoinColumnElementList.size()];
+ int index = 0;
+ Iterator pkIt = pkJoinColumnElementList.listIterator();
+ while ( pkIt.hasNext() ) {
+ Element subelement = (Element) pkIt.next();
+ AnnotationDescriptor pkAnn = new AnnotationDescriptor( PrimaryKeyJoinColumn.class );
+ copyStringAttribute( pkAnn, subelement, "name", false );
+ copyStringAttribute( pkAnn, subelement, "referenced-column-name", false );
+ copyStringAttribute( pkAnn, subelement, "column-definition", false );
+ pkJoinColumns[index++] = AnnotationFactory.create( pkAnn );
+ }
+ return pkJoinColumns;
+ }
+
+ private static void copyStringAttribute(
+ AnnotationDescriptor annotation, Element element, String attributeName, boolean mandatory
+ ) {
+ String attribute = element.attributeValue( attributeName );
+ if ( attribute != null ) {
+ String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
+ annotation.setValue( annotationAttributeName, attribute );
+ }
+ else {
+ if ( mandatory ) {
+ throw new AnnotationException(
+ element.getName() + "." + attributeName + " is mandatory in XML overring. " + SCHEMA_VALIDATION
+ );
+ }
+ }
+ }
+
+ private static void copyIntegerAttribute(AnnotationDescriptor annotation, Element element, String attributeName) {
+ String attribute = element.attributeValue( attributeName );
+ if ( attribute != null ) {
+ String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
+ annotation.setValue( annotationAttributeName, attribute );
+ try {
+ int length = Integer.parseInt( attribute );
+ annotation.setValue( annotationAttributeName, length );
+ }
+ catch (NumberFormatException e) {
+ throw new AnnotationException(
+ element.getPath() + attributeName + " not parseable: " + attribute + " (" + SCHEMA_VALIDATION + ")"
+ );
+ }
+ }
+ }
+
+ private static String getJavaAttributeNameFromXMLOne(String attributeName) {
+ StringBuilder annotationAttributeName = new StringBuilder( attributeName );
+ int index = annotationAttributeName.indexOf( WORD_SEPARATOR );
+ while ( index != -1 ) {
+ annotationAttributeName.deleteCharAt( index );
+ annotationAttributeName.setCharAt(
+ index, Character.toUpperCase( annotationAttributeName.charAt( index ) )
+ );
+ index = annotationAttributeName.indexOf( WORD_SEPARATOR );
+ }
+ return annotationAttributeName.toString();
+ }
+
+ private static void copyStringElement(Element element, AnnotationDescriptor ad, String annotationAttribute) {
+ String discr = element.getTextTrim();
+ ad.setValue( annotationAttribute, discr );
+ }
+
+ private static void copyBooleanAttribute(AnnotationDescriptor descriptor, Element element, String attribute) {
+ String attributeValue = element.attributeValue( attribute );
+ if ( StringHelper.isNotEmpty( attributeValue ) ) {
+ String javaAttribute = getJavaAttributeNameFromXMLOne( attribute );
+ descriptor.setValue( javaAttribute, Boolean.parseBoolean( attributeValue ) );
+ }
+ }
+
+ private <T extends Annotation> T getJavaAnnotation(Class<T> annotationType) {
+ return element.getAnnotation( annotationType );
+ }
+
+ private <T extends Annotation> boolean isJavaAnnotationPresent(Class<T> annotationType) {
+ return element.isAnnotationPresent( annotationType );
+ }
+
+ private Annotation[] getJavaAnnotations() {
+ return element.getAnnotations();
+ }
+}
Property changes on: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Deleted: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/EJB3OverridenAnnotationReaderTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/EJB3OverridenAnnotationReaderTest.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/EJB3OverridenAnnotationReaderTest.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -1,434 +0,0 @@
-//$Id$
-package org.hibernate.test.annotations.reflection;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.AssociationOverrides;
-import javax.persistence.AttributeOverrides;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Embedded;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.ExcludeDefaultListeners;
-import javax.persistence.ExcludeSuperclassListeners;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.IdClass;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.JoinColumns;
-import javax.persistence.JoinTable;
-import javax.persistence.Lob;
-import javax.persistence.ManyToMany;
-import javax.persistence.MapKey;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.NamedNativeQueries;
-import javax.persistence.NamedQueries;
-import javax.persistence.OneToMany;
-import javax.persistence.OneToOne;
-import javax.persistence.OrderBy;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.PrimaryKeyJoinColumns;
-import javax.persistence.SecondaryTable;
-import javax.persistence.SecondaryTables;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.SqlResultSetMappings;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import javax.persistence.Transient;
-import javax.persistence.Version;
-import javax.persistence.PrePersist;
-import javax.persistence.EntityListeners;
-import javax.persistence.PostLoad;
-import javax.persistence.PostPersist;
-
-import junit.framework.TestCase;
-import org.dom4j.DocumentException;
-import org.dom4j.io.SAXReader;
-import org.hibernate.annotations.Columns;
-import org.hibernate.cfg.EJB3DTDEntityResolver;
-import org.hibernate.cfg.annotations.reflection.EJB3OverridenAnnotationReader;
-import org.hibernate.cfg.annotations.reflection.XMLContext;
-import org.hibernate.util.XMLHelper;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotSupportedException;
-
-
-/**
- * @author Emmanuel Bernard
- */
-public class EJB3OverridenAnnotationReaderTest extends TestCase {
- public void testMappedSuperclassAnnotations() throws Exception {
- XMLContext context = buildContext(
- "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( Organization.class, context );
- assertTrue( reader.isAnnotationPresent( MappedSuperclass.class ) );
- }
-
- public void testEntityRelatedAnnotations() throws Exception {
- XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( Administration.class, context );
- assertNotNull( reader.getAnnotation( Entity.class ) );
- assertEquals(
- "Default value in xml entity should not override @Entity.name", "JavaAdministration",
- reader.getAnnotation( Entity.class ).name()
- );
- assertNotNull( reader.getAnnotation( Table.class ) );
- assertEquals( "@Table not overriden", "tbl_admin", reader.getAnnotation( Table.class ).name() );
- assertEquals( "Default schema not overriden", "myschema", reader.getAnnotation( Table.class ).schema() );
- assertEquals(
- "Proper @Table.uniqueConstraints", 2,
- reader.getAnnotation( Table.class ).uniqueConstraints()[0].columnNames().length
- );
- String columnName = reader.getAnnotation( Table.class ).uniqueConstraints()[0].columnNames()[0];
- assertTrue(
- "Proper @Table.uniqueConstraints", "firstname".equals( columnName ) || "lastname".equals( columnName )
- );
- assertNull( "Both Java and XML used", reader.getAnnotation( SecondaryTable.class ) );
- assertNotNull( "XML does not work", reader.getAnnotation( SecondaryTables.class ) );
- SecondaryTable[] tables = reader.getAnnotation( SecondaryTables.class ).value();
- assertEquals( 1, tables.length );
- assertEquals( "admin2", tables[0].name() );
- assertEquals( "unique constraints ignored", 1, tables[0].uniqueConstraints().length );
- assertEquals( "pk join column ignored", 1, tables[0].pkJoinColumns().length );
- assertEquals( "pk join column ignored", "admin_id", tables[0].pkJoinColumns()[0].name() );
- assertNotNull( "Sequence Overriding not working", reader.getAnnotation( SequenceGenerator.class ) );
- assertEquals(
- "wrong sequence name", "seqhilo", reader.getAnnotation( SequenceGenerator.class ).sequenceName()
- );
- assertEquals( "default fails", 50, reader.getAnnotation( SequenceGenerator.class ).allocationSize() );
- assertNotNull( "TableOverriding not working", reader.getAnnotation( TableGenerator.class ) );
- assertEquals( "wrong tble name", "tablehilo", reader.getAnnotation( TableGenerator.class ).table() );
- assertEquals( "no schema overriding", "myschema", reader.getAnnotation( TableGenerator.class ).schema() );
-
- reader = new EJB3OverridenAnnotationReader( Match.class, context );
- assertNotNull( reader.getAnnotation( Table.class ) );
- assertEquals(
- "Java annotation not taken into account", "matchtable", reader.getAnnotation( Table.class ).name()
- );
- assertEquals(
- "Java annotation not taken into account", "matchschema", reader.getAnnotation( Table.class ).schema()
- );
- assertEquals( "Overriding not taken into account", "mycatalog", reader.getAnnotation( Table.class ).catalog() );
- assertNotNull( "SecondaryTable swallowed", reader.getAnnotation( SecondaryTables.class ) );
- assertEquals(
- "Default schema not taken into account", "myschema",
- reader.getAnnotation( SecondaryTables.class ).value()[0].schema()
- );
- assertNotNull( reader.getAnnotation( Inheritance.class ) );
- assertEquals(
- "inheritance strategy not overriden", InheritanceType.JOINED,
- reader.getAnnotation( Inheritance.class ).strategy()
- );
- assertNotNull( "NamedQuery not overriden", reader.getAnnotation( NamedQueries.class ) );
- assertEquals( "No deduplication", 3, reader.getAnnotation( NamedQueries.class ).value().length );
- assertEquals(
- "deduplication kept the Java version", 1,
- reader.getAnnotation( NamedQueries.class ).value()[1].hints().length
- );
- assertEquals(
- "org.hibernate.timeout", reader.getAnnotation( NamedQueries.class ).value()[1].hints()[0].name()
- );
- assertNotNull( "NamedNativeQuery not overriden", reader.getAnnotation( NamedNativeQueries.class ) );
- assertEquals( "No deduplication", 3, reader.getAnnotation( NamedNativeQueries.class ).value().length );
- assertEquals(
- "deduplication kept the Java version", 1,
- reader.getAnnotation( NamedNativeQueries.class ).value()[1].hints().length
- );
- assertEquals(
- "org.hibernate.timeout", reader.getAnnotation( NamedNativeQueries.class ).value()[1].hints()[0].name()
- );
- assertNotNull( reader.getAnnotation( SqlResultSetMappings.class ) );
- assertEquals(
- "competitor1Point", reader.getAnnotation( SqlResultSetMappings.class ).value()[0].columns()[0].name()
- );
- assertEquals(
- "competitor1Point",
- reader.getAnnotation( SqlResultSetMappings.class ).value()[0].entities()[0].fields()[0].column()
- );
- assertNotNull( reader.getAnnotation( ExcludeSuperclassListeners.class ) );
- assertNotNull( reader.getAnnotation( ExcludeDefaultListeners.class ) );
-
- reader = new EJB3OverridenAnnotationReader( Competition.class, context );
- assertNotNull( reader.getAnnotation( MappedSuperclass.class ) );
-
- reader = new EJB3OverridenAnnotationReader( TennisMatch.class, context );
- assertNull( "Mutualize PKJC into PKJCs", reader.getAnnotation( PrimaryKeyJoinColumn.class ) );
- assertNotNull( reader.getAnnotation( PrimaryKeyJoinColumns.class ) );
- assertEquals(
- "PrimaryKeyJoinColumn overrden", "id",
- reader.getAnnotation( PrimaryKeyJoinColumns.class ).value()[0].name()
- );
- assertNotNull( reader.getAnnotation( AttributeOverrides.class ) );
- assertEquals( "Wrong deduplication", 3, reader.getAnnotation( AttributeOverrides.class ).value().length );
- assertEquals(
- "Wrong priority (XML vs java annotations)", "fld_net",
- reader.getAnnotation( AttributeOverrides.class ).value()[0].column().name()
- );
- assertEquals(
- "Column mapping", 2, reader.getAnnotation( AttributeOverrides.class ).value()[1].column().scale()
- );
- assertEquals(
- "Column mapping", true, reader.getAnnotation( AttributeOverrides.class ).value()[1].column().unique()
- );
- assertNotNull( reader.getAnnotation( AssociationOverrides.class ) );
- assertEquals( "no XML processing", 1, reader.getAnnotation( AssociationOverrides.class ).value().length );
- assertEquals(
- "wrong xml processing", "id",
- reader.getAnnotation( AssociationOverrides.class ).value()[0].joinColumns()[0].referencedColumnName()
- );
-
-
- reader = new EJB3OverridenAnnotationReader( SocialSecurityPhysicalAccount.class, context );
- assertNotNull( reader.getAnnotation( IdClass.class ) );
- assertEquals( "id-class not used", SocialSecurityNumber.class, reader.getAnnotation( IdClass.class ).value() );
- assertEquals(
- "discriminator-value not used", "Physical", reader.getAnnotation( DiscriminatorValue.class ).value()
- );
- assertNotNull( "discriminator-column not used", reader.getAnnotation( DiscriminatorColumn.class ) );
- assertEquals(
- "discriminator-column.name default value broken", "DTYPE",
- reader.getAnnotation( DiscriminatorColumn.class ).name()
- );
- assertEquals(
- "discriminator-column.length broken", 34, reader.getAnnotation( DiscriminatorColumn.class ).length()
- );
- }
-
- public void testEntityRelatedAnnotationsMetadataComplete() throws Exception {
- XMLContext context = buildContext(
- "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( Administration.class, context );
- assertNotNull( reader.getAnnotation( Entity.class ) );
- assertEquals(
- "Metadata complete should ignore java annotations", "", reader.getAnnotation( Entity.class ).name()
- );
- assertNotNull( reader.getAnnotation( Table.class ) );
- assertEquals( "@Table should not be used", "", reader.getAnnotation( Table.class ).name() );
- assertEquals( "Default schema not overriden", "myschema", reader.getAnnotation( Table.class ).schema() );
-
- reader = new EJB3OverridenAnnotationReader( Match.class, context );
- assertNotNull( reader.getAnnotation( Table.class ) );
- assertEquals( "@Table should not be used", "", reader.getAnnotation( Table.class ).name() );
- assertEquals( "Overriding not taken into account", "myschema", reader.getAnnotation( Table.class ).schema() );
- assertEquals( "Overriding not taken into account", "mycatalog", reader.getAnnotation( Table.class ).catalog() );
- assertNull( "Ignore Java annotation", reader.getAnnotation( SecondaryTable.class ) );
- assertNull( "Ignore Java annotation", reader.getAnnotation( SecondaryTables.class ) );
- assertNull( "Ignore Java annotation", reader.getAnnotation( Inheritance.class ) );
- assertNull( reader.getAnnotation( NamedQueries.class ) );
- assertNull( reader.getAnnotation( NamedNativeQueries.class ) );
-
- reader = new EJB3OverridenAnnotationReader( TennisMatch.class, context );
- assertNull( reader.getAnnotation( PrimaryKeyJoinColumn.class ) );
- assertNull( reader.getAnnotation( PrimaryKeyJoinColumns.class ) );
-
- reader = new EJB3OverridenAnnotationReader( Competition.class, context );
- assertNull( reader.getAnnotation( MappedSuperclass.class ) );
-
- reader = new EJB3OverridenAnnotationReader( SocialSecurityMoralAccount.class, context );
- assertNull( reader.getAnnotation( IdClass.class ) );
- assertNull( reader.getAnnotation( DiscriminatorValue.class ) );
- assertNull( reader.getAnnotation( DiscriminatorColumn.class ) );
- assertNull( reader.getAnnotation( SequenceGenerator.class ) );
- assertNull( reader.getAnnotation( TableGenerator.class ) );
- }
-
- public void testIdRelatedAnnotations() throws Exception {
- XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
- Method method = Administration.class.getDeclaredMethod( "getId" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( method, context );
- assertNull( reader.getAnnotation( Id.class ) );
- assertNull( reader.getAnnotation( Column.class ) );
- Field field = Administration.class.getDeclaredField( "id" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Id.class ) );
- assertNotNull( reader.getAnnotation( GeneratedValue.class ) );
- assertEquals( GenerationType.SEQUENCE, reader.getAnnotation( GeneratedValue.class ).strategy() );
- assertEquals( "generator", reader.getAnnotation( GeneratedValue.class ).generator() );
- assertNotNull( reader.getAnnotation( SequenceGenerator.class ) );
- assertEquals( "seq", reader.getAnnotation( SequenceGenerator.class ).sequenceName() );
- assertNotNull( reader.getAnnotation( Columns.class ) );
- assertEquals( 1, reader.getAnnotation( Columns.class ).columns().length );
- assertEquals( "fld_id", reader.getAnnotation( Columns.class ).columns()[0].name() );
- assertNotNull( reader.getAnnotation( Temporal.class ) );
- assertEquals( TemporalType.DATE, reader.getAnnotation( Temporal.class ).value() );
-
- context = buildContext(
- "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
- method = Administration.class.getDeclaredMethod( "getId" );
- reader = new EJB3OverridenAnnotationReader( method, context );
- assertNotNull(
- "Default access type when not defined in metadata complete should be property",
- reader.getAnnotation( Id.class )
- );
- field = Administration.class.getDeclaredField( "id" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNull(
- "Default access type when not defined in metadata complete should be property",
- reader.getAnnotation( Id.class )
- );
-
- method = BusTrip.class.getDeclaredMethod( "getId" );
- reader = new EJB3OverridenAnnotationReader( method, context );
- assertNull( reader.getAnnotation( EmbeddedId.class ) );
- field = BusTrip.class.getDeclaredField( "id" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( EmbeddedId.class ) );
- assertNotNull( reader.getAnnotation( AttributeOverrides.class ) );
- assertEquals( 1, reader.getAnnotation( AttributeOverrides.class ).value().length );
- }
-
- public void testBasicRelatedAnnotations() throws Exception {
- XMLContext context = buildContext(
- "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
- Field field = BusTrip.class.getDeclaredField( "status" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Enumerated.class ) );
- assertEquals( EnumType.STRING, reader.getAnnotation( Enumerated.class ).value() );
- assertEquals( false, reader.getAnnotation( Basic.class ).optional() );
- field = BusTrip.class.getDeclaredField( "serial" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Lob.class ) );
- assertEquals( "serialbytes", reader.getAnnotation( Columns.class ).columns()[0].name() );
- field = BusTrip.class.getDeclaredField( "terminusTime" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Temporal.class ) );
- assertEquals( TemporalType.TIMESTAMP, reader.getAnnotation( Temporal.class ).value() );
- assertEquals( FetchType.LAZY, reader.getAnnotation( Basic.class ).fetch() );
-
- field = BusTripPk.class.getDeclaredField( "busDriver" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.isAnnotationPresent( Basic.class ) );
- }
-
- public void testVersionRelatedAnnotations() throws Exception {
- XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
- Method method = Administration.class.getDeclaredMethod( "getVersion" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( method, context );
- assertNotNull( reader.getAnnotation( Version.class ) );
-
- Field field = Match.class.getDeclaredField( "version" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Version.class ) );
- }
-
- public void testTransientAndEmbeddedRelatedAnnotations() throws Exception {
- XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
-
- Field field = Administration.class.getDeclaredField( "transientField" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Transient.class ) );
- assertNull( reader.getAnnotation( Basic.class ) );
-
- field = Match.class.getDeclaredField( "playerASSN" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( Embedded.class ) );
- }
-
- public void testAssociationRelatedAnnotations() throws Exception {
- XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
-
- Field field = Administration.class.getDeclaredField( "defaultBusTrip" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( OneToOne.class ) );
- assertNull( reader.getAnnotation( JoinColumns.class ) );
- assertNotNull( reader.getAnnotation( PrimaryKeyJoinColumns.class ) );
- assertEquals( "pk", reader.getAnnotation( PrimaryKeyJoinColumns.class ).value()[0].name() );
- assertEquals( 5, reader.getAnnotation( OneToOne.class ).cascade().length );
- assertEquals( FetchType.LAZY, reader.getAnnotation( OneToOne.class ).fetch() );
- assertEquals( "test", reader.getAnnotation( OneToOne.class ).mappedBy() );
-
- context = buildContext(
- "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
- field = BusTrip.class.getDeclaredField( "players" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( OneToMany.class ) );
- assertNotNull( reader.getAnnotation( JoinColumns.class ) );
- assertEquals( 2, reader.getAnnotation( JoinColumns.class ).value().length );
- assertEquals( "driver", reader.getAnnotation( JoinColumns.class ).value()[0].name() );
- assertNotNull( reader.getAnnotation( MapKey.class ) );
- assertEquals( "name", reader.getAnnotation( MapKey.class ).name() );
-
- field = BusTrip.class.getDeclaredField( "roads" );
- reader = new EJB3OverridenAnnotationReader( field, context );
- assertNotNull( reader.getAnnotation( ManyToMany.class ) );
- assertNotNull( reader.getAnnotation( JoinTable.class ) );
- assertEquals( "bus_road", reader.getAnnotation( JoinTable.class ).name() );
- assertEquals( 2, reader.getAnnotation( JoinTable.class ).joinColumns().length );
- assertEquals( 1, reader.getAnnotation( JoinTable.class ).inverseJoinColumns().length );
- assertEquals( 2, reader.getAnnotation( JoinTable.class ).uniqueConstraints()[0].columnNames().length );
- assertNotNull( reader.getAnnotation( OrderBy.class ) );
- assertEquals( "maxSpeed", reader.getAnnotation( OrderBy.class ).value() );
- }
-
- public void testEntityListeners() throws Exception {
- XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
-
- Method method = Administration.class.getDeclaredMethod( "calculate" );
- EJB3OverridenAnnotationReader reader = new EJB3OverridenAnnotationReader( method, context );
- assertTrue( reader.isAnnotationPresent( PrePersist.class ) );
-
- reader = new EJB3OverridenAnnotationReader( Administration.class, context );
- assertTrue( reader.isAnnotationPresent( EntityListeners.class ) );
- assertEquals( 1, reader.getAnnotation( EntityListeners.class ).value().length );
- assertEquals( LogListener.class, reader.getAnnotation( EntityListeners.class ).value()[0] );
-
- method = LogListener.class.getDeclaredMethod( "noLog", Object.class );
- reader = new EJB3OverridenAnnotationReader( method, context );
- assertTrue( reader.isAnnotationPresent( PostLoad.class ) );
-
- method = LogListener.class.getDeclaredMethod( "log", Object.class );
- reader = new EJB3OverridenAnnotationReader( method, context );
- assertTrue( reader.isAnnotationPresent( PrePersist.class ) );
- assertFalse( reader.isAnnotationPresent( PostPersist.class ) );
-
- assertEquals( 1, context.getDefaultEntityListeners().size() );
- assertEquals( OtherLogListener.class.getName(), context.getDefaultEntityListeners().get(0) );
- }
-
- private XMLContext buildContext(String ormfile) throws SAXException, DocumentException, IOException {
- XMLHelper xmlHelper = new XMLHelper();
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- InputStream is = cl.getResourceAsStream( ormfile );
- assertNotNull( "ORM.xml not found: " + ormfile, is );
- XMLContext context = new XMLContext();
- List errors = new ArrayList();
- SAXReader saxReader = xmlHelper.createSAXReader( "XML InputStream", errors, EJB3DTDEntityResolver.INSTANCE );
- //saxReader.setValidation( false );
- try {
- saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
- }
- catch (SAXNotSupportedException e) {
- saxReader.setValidation( false );
- }
- org.dom4j.Document doc;
- try {
- doc = saxReader
- .read( new InputSource( new BufferedInputStream( is ) ) );
- }
- finally {
- is.close();
- }
- if (errors.size() > 0) {
- System.out.println( errors.get( 0 ) );
- }
- assertEquals( 0, errors.size() );
- context.addDocument( doc );
- return context;
- }
-}
Copied: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/JPAOverridenAnnotationReaderTest.java (from rev 16204, core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/EJB3OverridenAnnotationReaderTest.java)
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/JPAOverridenAnnotationReaderTest.java (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/JPAOverridenAnnotationReaderTest.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -0,0 +1,434 @@
+//$Id$
+package org.hibernate.test.annotations.reflection;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.AssociationOverrides;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.ExcludeDefaultListeners;
+import javax.persistence.ExcludeSuperclassListeners;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumns;
+import javax.persistence.JoinTable;
+import javax.persistence.Lob;
+import javax.persistence.ManyToMany;
+import javax.persistence.MapKey;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedQueries;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderBy;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.PrimaryKeyJoinColumns;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.SqlResultSetMappings;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+import javax.persistence.Version;
+import javax.persistence.PrePersist;
+import javax.persistence.EntityListeners;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+
+import junit.framework.TestCase;
+import org.dom4j.DocumentException;
+import org.dom4j.io.SAXReader;
+import org.hibernate.annotations.Columns;
+import org.hibernate.cfg.EJB3DTDEntityResolver;
+import org.hibernate.cfg.annotations.reflection.JPAOverridenAnnotationReader;
+import org.hibernate.cfg.annotations.reflection.XMLContext;
+import org.hibernate.util.XMLHelper;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotSupportedException;
+
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class JPAOverridenAnnotationReaderTest extends TestCase {
+ public void testMappedSuperclassAnnotations() throws Exception {
+ XMLContext context = buildContext(
+ "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( Organization.class, context );
+ assertTrue( reader.isAnnotationPresent( MappedSuperclass.class ) );
+ }
+
+ public void testEntityRelatedAnnotations() throws Exception {
+ XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( Administration.class, context );
+ assertNotNull( reader.getAnnotation( Entity.class ) );
+ assertEquals(
+ "Default value in xml entity should not override @Entity.name", "JavaAdministration",
+ reader.getAnnotation( Entity.class ).name()
+ );
+ assertNotNull( reader.getAnnotation( Table.class ) );
+ assertEquals( "@Table not overriden", "tbl_admin", reader.getAnnotation( Table.class ).name() );
+ assertEquals( "Default schema not overriden", "myschema", reader.getAnnotation( Table.class ).schema() );
+ assertEquals(
+ "Proper @Table.uniqueConstraints", 2,
+ reader.getAnnotation( Table.class ).uniqueConstraints()[0].columnNames().length
+ );
+ String columnName = reader.getAnnotation( Table.class ).uniqueConstraints()[0].columnNames()[0];
+ assertTrue(
+ "Proper @Table.uniqueConstraints", "firstname".equals( columnName ) || "lastname".equals( columnName )
+ );
+ assertNull( "Both Java and XML used", reader.getAnnotation( SecondaryTable.class ) );
+ assertNotNull( "XML does not work", reader.getAnnotation( SecondaryTables.class ) );
+ SecondaryTable[] tables = reader.getAnnotation( SecondaryTables.class ).value();
+ assertEquals( 1, tables.length );
+ assertEquals( "admin2", tables[0].name() );
+ assertEquals( "unique constraints ignored", 1, tables[0].uniqueConstraints().length );
+ assertEquals( "pk join column ignored", 1, tables[0].pkJoinColumns().length );
+ assertEquals( "pk join column ignored", "admin_id", tables[0].pkJoinColumns()[0].name() );
+ assertNotNull( "Sequence Overriding not working", reader.getAnnotation( SequenceGenerator.class ) );
+ assertEquals(
+ "wrong sequence name", "seqhilo", reader.getAnnotation( SequenceGenerator.class ).sequenceName()
+ );
+ assertEquals( "default fails", 50, reader.getAnnotation( SequenceGenerator.class ).allocationSize() );
+ assertNotNull( "TableOverriding not working", reader.getAnnotation( TableGenerator.class ) );
+ assertEquals( "wrong tble name", "tablehilo", reader.getAnnotation( TableGenerator.class ).table() );
+ assertEquals( "no schema overriding", "myschema", reader.getAnnotation( TableGenerator.class ).schema() );
+
+ reader = new JPAOverridenAnnotationReader( Match.class, context );
+ assertNotNull( reader.getAnnotation( Table.class ) );
+ assertEquals(
+ "Java annotation not taken into account", "matchtable", reader.getAnnotation( Table.class ).name()
+ );
+ assertEquals(
+ "Java annotation not taken into account", "matchschema", reader.getAnnotation( Table.class ).schema()
+ );
+ assertEquals( "Overriding not taken into account", "mycatalog", reader.getAnnotation( Table.class ).catalog() );
+ assertNotNull( "SecondaryTable swallowed", reader.getAnnotation( SecondaryTables.class ) );
+ assertEquals(
+ "Default schema not taken into account", "myschema",
+ reader.getAnnotation( SecondaryTables.class ).value()[0].schema()
+ );
+ assertNotNull( reader.getAnnotation( Inheritance.class ) );
+ assertEquals(
+ "inheritance strategy not overriden", InheritanceType.JOINED,
+ reader.getAnnotation( Inheritance.class ).strategy()
+ );
+ assertNotNull( "NamedQuery not overriden", reader.getAnnotation( NamedQueries.class ) );
+ assertEquals( "No deduplication", 3, reader.getAnnotation( NamedQueries.class ).value().length );
+ assertEquals(
+ "deduplication kept the Java version", 1,
+ reader.getAnnotation( NamedQueries.class ).value()[1].hints().length
+ );
+ assertEquals(
+ "org.hibernate.timeout", reader.getAnnotation( NamedQueries.class ).value()[1].hints()[0].name()
+ );
+ assertNotNull( "NamedNativeQuery not overriden", reader.getAnnotation( NamedNativeQueries.class ) );
+ assertEquals( "No deduplication", 3, reader.getAnnotation( NamedNativeQueries.class ).value().length );
+ assertEquals(
+ "deduplication kept the Java version", 1,
+ reader.getAnnotation( NamedNativeQueries.class ).value()[1].hints().length
+ );
+ assertEquals(
+ "org.hibernate.timeout", reader.getAnnotation( NamedNativeQueries.class ).value()[1].hints()[0].name()
+ );
+ assertNotNull( reader.getAnnotation( SqlResultSetMappings.class ) );
+ assertEquals(
+ "competitor1Point", reader.getAnnotation( SqlResultSetMappings.class ).value()[0].columns()[0].name()
+ );
+ assertEquals(
+ "competitor1Point",
+ reader.getAnnotation( SqlResultSetMappings.class ).value()[0].entities()[0].fields()[0].column()
+ );
+ assertNotNull( reader.getAnnotation( ExcludeSuperclassListeners.class ) );
+ assertNotNull( reader.getAnnotation( ExcludeDefaultListeners.class ) );
+
+ reader = new JPAOverridenAnnotationReader( Competition.class, context );
+ assertNotNull( reader.getAnnotation( MappedSuperclass.class ) );
+
+ reader = new JPAOverridenAnnotationReader( TennisMatch.class, context );
+ assertNull( "Mutualize PKJC into PKJCs", reader.getAnnotation( PrimaryKeyJoinColumn.class ) );
+ assertNotNull( reader.getAnnotation( PrimaryKeyJoinColumns.class ) );
+ assertEquals(
+ "PrimaryKeyJoinColumn overrden", "id",
+ reader.getAnnotation( PrimaryKeyJoinColumns.class ).value()[0].name()
+ );
+ assertNotNull( reader.getAnnotation( AttributeOverrides.class ) );
+ assertEquals( "Wrong deduplication", 3, reader.getAnnotation( AttributeOverrides.class ).value().length );
+ assertEquals(
+ "Wrong priority (XML vs java annotations)", "fld_net",
+ reader.getAnnotation( AttributeOverrides.class ).value()[0].column().name()
+ );
+ assertEquals(
+ "Column mapping", 2, reader.getAnnotation( AttributeOverrides.class ).value()[1].column().scale()
+ );
+ assertEquals(
+ "Column mapping", true, reader.getAnnotation( AttributeOverrides.class ).value()[1].column().unique()
+ );
+ assertNotNull( reader.getAnnotation( AssociationOverrides.class ) );
+ assertEquals( "no XML processing", 1, reader.getAnnotation( AssociationOverrides.class ).value().length );
+ assertEquals(
+ "wrong xml processing", "id",
+ reader.getAnnotation( AssociationOverrides.class ).value()[0].joinColumns()[0].referencedColumnName()
+ );
+
+
+ reader = new JPAOverridenAnnotationReader( SocialSecurityPhysicalAccount.class, context );
+ assertNotNull( reader.getAnnotation( IdClass.class ) );
+ assertEquals( "id-class not used", SocialSecurityNumber.class, reader.getAnnotation( IdClass.class ).value() );
+ assertEquals(
+ "discriminator-value not used", "Physical", reader.getAnnotation( DiscriminatorValue.class ).value()
+ );
+ assertNotNull( "discriminator-column not used", reader.getAnnotation( DiscriminatorColumn.class ) );
+ assertEquals(
+ "discriminator-column.name default value broken", "DTYPE",
+ reader.getAnnotation( DiscriminatorColumn.class ).name()
+ );
+ assertEquals(
+ "discriminator-column.length broken", 34, reader.getAnnotation( DiscriminatorColumn.class ).length()
+ );
+ }
+
+ public void testEntityRelatedAnnotationsMetadataComplete() throws Exception {
+ XMLContext context = buildContext(
+ "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( Administration.class, context );
+ assertNotNull( reader.getAnnotation( Entity.class ) );
+ assertEquals(
+ "Metadata complete should ignore java annotations", "", reader.getAnnotation( Entity.class ).name()
+ );
+ assertNotNull( reader.getAnnotation( Table.class ) );
+ assertEquals( "@Table should not be used", "", reader.getAnnotation( Table.class ).name() );
+ assertEquals( "Default schema not overriden", "myschema", reader.getAnnotation( Table.class ).schema() );
+
+ reader = new JPAOverridenAnnotationReader( Match.class, context );
+ assertNotNull( reader.getAnnotation( Table.class ) );
+ assertEquals( "@Table should not be used", "", reader.getAnnotation( Table.class ).name() );
+ assertEquals( "Overriding not taken into account", "myschema", reader.getAnnotation( Table.class ).schema() );
+ assertEquals( "Overriding not taken into account", "mycatalog", reader.getAnnotation( Table.class ).catalog() );
+ assertNull( "Ignore Java annotation", reader.getAnnotation( SecondaryTable.class ) );
+ assertNull( "Ignore Java annotation", reader.getAnnotation( SecondaryTables.class ) );
+ assertNull( "Ignore Java annotation", reader.getAnnotation( Inheritance.class ) );
+ assertNull( reader.getAnnotation( NamedQueries.class ) );
+ assertNull( reader.getAnnotation( NamedNativeQueries.class ) );
+
+ reader = new JPAOverridenAnnotationReader( TennisMatch.class, context );
+ assertNull( reader.getAnnotation( PrimaryKeyJoinColumn.class ) );
+ assertNull( reader.getAnnotation( PrimaryKeyJoinColumns.class ) );
+
+ reader = new JPAOverridenAnnotationReader( Competition.class, context );
+ assertNull( reader.getAnnotation( MappedSuperclass.class ) );
+
+ reader = new JPAOverridenAnnotationReader( SocialSecurityMoralAccount.class, context );
+ assertNull( reader.getAnnotation( IdClass.class ) );
+ assertNull( reader.getAnnotation( DiscriminatorValue.class ) );
+ assertNull( reader.getAnnotation( DiscriminatorColumn.class ) );
+ assertNull( reader.getAnnotation( SequenceGenerator.class ) );
+ assertNull( reader.getAnnotation( TableGenerator.class ) );
+ }
+
+ public void testIdRelatedAnnotations() throws Exception {
+ XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
+ Method method = Administration.class.getDeclaredMethod( "getId" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( method, context );
+ assertNull( reader.getAnnotation( Id.class ) );
+ assertNull( reader.getAnnotation( Column.class ) );
+ Field field = Administration.class.getDeclaredField( "id" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Id.class ) );
+ assertNotNull( reader.getAnnotation( GeneratedValue.class ) );
+ assertEquals( GenerationType.SEQUENCE, reader.getAnnotation( GeneratedValue.class ).strategy() );
+ assertEquals( "generator", reader.getAnnotation( GeneratedValue.class ).generator() );
+ assertNotNull( reader.getAnnotation( SequenceGenerator.class ) );
+ assertEquals( "seq", reader.getAnnotation( SequenceGenerator.class ).sequenceName() );
+ assertNotNull( reader.getAnnotation( Columns.class ) );
+ assertEquals( 1, reader.getAnnotation( Columns.class ).columns().length );
+ assertEquals( "fld_id", reader.getAnnotation( Columns.class ).columns()[0].name() );
+ assertNotNull( reader.getAnnotation( Temporal.class ) );
+ assertEquals( TemporalType.DATE, reader.getAnnotation( Temporal.class ).value() );
+
+ context = buildContext(
+ "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
+ method = Administration.class.getDeclaredMethod( "getId" );
+ reader = new JPAOverridenAnnotationReader( method, context );
+ assertNotNull(
+ "Default access type when not defined in metadata complete should be property",
+ reader.getAnnotation( Id.class )
+ );
+ field = Administration.class.getDeclaredField( "id" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNull(
+ "Default access type when not defined in metadata complete should be property",
+ reader.getAnnotation( Id.class )
+ );
+
+ method = BusTrip.class.getDeclaredMethod( "getId" );
+ reader = new JPAOverridenAnnotationReader( method, context );
+ assertNull( reader.getAnnotation( EmbeddedId.class ) );
+ field = BusTrip.class.getDeclaredField( "id" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( EmbeddedId.class ) );
+ assertNotNull( reader.getAnnotation( AttributeOverrides.class ) );
+ assertEquals( 1, reader.getAnnotation( AttributeOverrides.class ).value().length );
+ }
+
+ public void testBasicRelatedAnnotations() throws Exception {
+ XMLContext context = buildContext(
+ "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
+ Field field = BusTrip.class.getDeclaredField( "status" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Enumerated.class ) );
+ assertEquals( EnumType.STRING, reader.getAnnotation( Enumerated.class ).value() );
+ assertEquals( false, reader.getAnnotation( Basic.class ).optional() );
+ field = BusTrip.class.getDeclaredField( "serial" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Lob.class ) );
+ assertEquals( "serialbytes", reader.getAnnotation( Columns.class ).columns()[0].name() );
+ field = BusTrip.class.getDeclaredField( "terminusTime" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Temporal.class ) );
+ assertEquals( TemporalType.TIMESTAMP, reader.getAnnotation( Temporal.class ).value() );
+ assertEquals( FetchType.LAZY, reader.getAnnotation( Basic.class ).fetch() );
+
+ field = BusTripPk.class.getDeclaredField( "busDriver" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.isAnnotationPresent( Basic.class ) );
+ }
+
+ public void testVersionRelatedAnnotations() throws Exception {
+ XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
+ Method method = Administration.class.getDeclaredMethod( "getVersion" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( method, context );
+ assertNotNull( reader.getAnnotation( Version.class ) );
+
+ Field field = Match.class.getDeclaredField( "version" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Version.class ) );
+ }
+
+ public void testTransientAndEmbeddedRelatedAnnotations() throws Exception {
+ XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
+
+ Field field = Administration.class.getDeclaredField( "transientField" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Transient.class ) );
+ assertNull( reader.getAnnotation( Basic.class ) );
+
+ field = Match.class.getDeclaredField( "playerASSN" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( Embedded.class ) );
+ }
+
+ public void testAssociationRelatedAnnotations() throws Exception {
+ XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
+
+ Field field = Administration.class.getDeclaredField( "defaultBusTrip" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( OneToOne.class ) );
+ assertNull( reader.getAnnotation( JoinColumns.class ) );
+ assertNotNull( reader.getAnnotation( PrimaryKeyJoinColumns.class ) );
+ assertEquals( "pk", reader.getAnnotation( PrimaryKeyJoinColumns.class ).value()[0].name() );
+ assertEquals( 5, reader.getAnnotation( OneToOne.class ).cascade().length );
+ assertEquals( FetchType.LAZY, reader.getAnnotation( OneToOne.class ).fetch() );
+ assertEquals( "test", reader.getAnnotation( OneToOne.class ).mappedBy() );
+
+ context = buildContext(
+ "org/hibernate/test/annotations/reflection/metadata-complete.xml" );
+ field = BusTrip.class.getDeclaredField( "players" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( OneToMany.class ) );
+ assertNotNull( reader.getAnnotation( JoinColumns.class ) );
+ assertEquals( 2, reader.getAnnotation( JoinColumns.class ).value().length );
+ assertEquals( "driver", reader.getAnnotation( JoinColumns.class ).value()[0].name() );
+ assertNotNull( reader.getAnnotation( MapKey.class ) );
+ assertEquals( "name", reader.getAnnotation( MapKey.class ).name() );
+
+ field = BusTrip.class.getDeclaredField( "roads" );
+ reader = new JPAOverridenAnnotationReader( field, context );
+ assertNotNull( reader.getAnnotation( ManyToMany.class ) );
+ assertNotNull( reader.getAnnotation( JoinTable.class ) );
+ assertEquals( "bus_road", reader.getAnnotation( JoinTable.class ).name() );
+ assertEquals( 2, reader.getAnnotation( JoinTable.class ).joinColumns().length );
+ assertEquals( 1, reader.getAnnotation( JoinTable.class ).inverseJoinColumns().length );
+ assertEquals( 2, reader.getAnnotation( JoinTable.class ).uniqueConstraints()[0].columnNames().length );
+ assertNotNull( reader.getAnnotation( OrderBy.class ) );
+ assertEquals( "maxSpeed", reader.getAnnotation( OrderBy.class ).value() );
+ }
+
+ public void testEntityListeners() throws Exception {
+ XMLContext context = buildContext( "org/hibernate/test/annotations/reflection/orm.xml" );
+
+ Method method = Administration.class.getDeclaredMethod( "calculate" );
+ JPAOverridenAnnotationReader reader = new JPAOverridenAnnotationReader( method, context );
+ assertTrue( reader.isAnnotationPresent( PrePersist.class ) );
+
+ reader = new JPAOverridenAnnotationReader( Administration.class, context );
+ assertTrue( reader.isAnnotationPresent( EntityListeners.class ) );
+ assertEquals( 1, reader.getAnnotation( EntityListeners.class ).value().length );
+ assertEquals( LogListener.class, reader.getAnnotation( EntityListeners.class ).value()[0] );
+
+ method = LogListener.class.getDeclaredMethod( "noLog", Object.class );
+ reader = new JPAOverridenAnnotationReader( method, context );
+ assertTrue( reader.isAnnotationPresent( PostLoad.class ) );
+
+ method = LogListener.class.getDeclaredMethod( "log", Object.class );
+ reader = new JPAOverridenAnnotationReader( method, context );
+ assertTrue( reader.isAnnotationPresent( PrePersist.class ) );
+ assertFalse( reader.isAnnotationPresent( PostPersist.class ) );
+
+ assertEquals( 1, context.getDefaultEntityListeners().size() );
+ assertEquals( OtherLogListener.class.getName(), context.getDefaultEntityListeners().get(0) );
+ }
+
+ private XMLContext buildContext(String ormfile) throws SAXException, DocumentException, IOException {
+ XMLHelper xmlHelper = new XMLHelper();
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ InputStream is = cl.getResourceAsStream( ormfile );
+ assertNotNull( "ORM.xml not found: " + ormfile, is );
+ XMLContext context = new XMLContext();
+ List errors = new ArrayList();
+ SAXReader saxReader = xmlHelper.createSAXReader( "XML InputStream", errors, EJB3DTDEntityResolver.INSTANCE );
+ //saxReader.setValidation( false );
+ try {
+ saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
+ }
+ catch (SAXNotSupportedException e) {
+ saxReader.setValidation( false );
+ }
+ org.dom4j.Document doc;
+ try {
+ doc = saxReader
+ .read( new InputSource( new BufferedInputStream( is ) ) );
+ }
+ finally {
+ is.close();
+ }
+ if (errors.size() > 0) {
+ System.out.println( errors.get( 0 ) );
+ }
+ assertEquals( 0, errors.size() );
+ context.addDocument( doc );
+ return context;
+ }
+}
Property changes on: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/reflection/JPAOverridenAnnotationReaderTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/Version.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/Version.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/Version.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -30,7 +30,7 @@
* @author Emmanuel Bernard
*/
public class Version {
- public static final String VERSION = "3.1.0.GA";
+ public static final String VERSION = "3.2.0-SNAPSHOT";
private static Logger log = LoggerFactory.getLogger( Version.class );
static {
Added: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java (rev 0)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProvider.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -0,0 +1,22 @@
+package org.hibernate.annotations.common.reflection;
+
+import java.util.Map;
+import java.lang.reflect.AnnotatedElement;
+
+/**
+ * Provides metadata
+ *
+ * @author Emmanuel Bernard
+ */
+public interface MetadataProvider {
+
+ /**
+ * provide default metadata
+ */
+ Map<Object, Object> getDefaults();
+
+ /**
+ * provide metadata for a gien annotated element
+ */
+ AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement);
+}
Added: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java (rev 0)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/MetadataProviderInjector.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -0,0 +1,15 @@
+package org.hibernate.annotations.common.reflection;
+
+/**
+ * Offers access to and the ability to change the metadata provider
+ *
+ * @author Emmanuel Bernard
+ */
+public interface MetadataProviderInjector {
+ MetadataProvider getMetadataProvider();
+
+ /**
+ * Defines the metadata provider for a given Reflection Manager
+ */
+ void setMetadataProvider(MetadataProvider metadataProvider);
+}
Added: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java (rev 0)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaMetadataProvider.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -0,0 +1,22 @@
+package org.hibernate.annotations.common.reflection.java;
+
+import java.util.Map;
+import java.util.Collections;
+import java.lang.reflect.AnnotatedElement;
+
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+
+/**
+ * @author Emmanuel Bernard
+*/
+public class JavaMetadataProvider implements MetadataProvider {
+
+ public Map<Object, Object> getDefaults() {
+ return Collections.emptyMap();
+ }
+
+ public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
+ return new JavaAnnotationReader(annotatedElement);
+ }
+}
Modified: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -37,6 +37,8 @@
import org.hibernate.annotations.common.reflection.XMethod;
import org.hibernate.annotations.common.reflection.XPackage;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
import org.hibernate.annotations.common.reflection.java.generics.IdentityTypeEnvironment;
import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironment;
import org.hibernate.annotations.common.reflection.java.generics.TypeEnvironmentFactory;
@@ -52,8 +54,21 @@
* @author Davide Marchignoli
* @author Emmanuel Bernard
*/
-public class JavaReflectionManager implements ReflectionManager {
+public class JavaReflectionManager implements ReflectionManager, MetadataProviderInjector {
+ private MetadataProvider metadataProvider;
+
+ public MetadataProvider getMetadataProvider() {
+ if (metadataProvider == null) {
+ setMetadataProvider( new JavaMetadataProvider() );
+ }
+ return metadataProvider;
+ }
+
+ public void setMetadataProvider(MetadataProvider metadataProvider) {
+ this.metadataProvider = metadataProvider;
+ }
+
static {
Version.touch();
}
@@ -204,10 +219,11 @@
}
public AnnotationReader buildAnnotationReader(AnnotatedElement annotatedElement) {
- return new JavaAnnotationReader(annotatedElement);
+ return getMetadataProvider().getAnnotationReader( annotatedElement );
}
public Map getDefaults() {
- return new HashMap();
+ return getMetadataProvider().getDefaults();
}
+
}
Modified: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/reflection/java/JavaXAnnotatedElement.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -35,9 +35,6 @@
*/
abstract class JavaXAnnotatedElement implements XAnnotatedElement {
- // responsible for extracting annotations
- private AnnotationReader annotationReader;
-
private final JavaReflectionManager factory;
private final AnnotatedElement annotatedElement;
@@ -52,10 +49,7 @@
}
private AnnotationReader getAnnotationReader() {
- if (annotationReader == null) {
- annotationReader = factory.buildAnnotationReader(annotatedElement);
- }
- return annotationReader;
+ return factory.buildAnnotationReader(annotatedElement);
}
public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Version.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Version.java 2009-03-22 16:22:53 UTC (rev 16205)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Version.java 2009-03-23 01:53:05 UTC (rev 16206)
@@ -9,7 +9,7 @@
* @author Emmanuel Bernard
*/
public class Version {
- public static final String VERSION = "3.4.0.GA";
+ public static final String VERSION = "3.5.0-SNAPSHOT";
private static final Logger log = LoggerFactory.getLogger( Version.class );
static {
15 years, 9 months