HHH-6133 Enhance annotation based Jandex index with configuration extracted from orm.xml

This commit is contained in:
Strong Liu 2011-05-11 17:40:10 +08:00 committed by Hardy Ferentschik
parent de1e1717c5
commit fcf439d4d1
59 changed files with 6312 additions and 6 deletions

View File

@ -50,7 +50,7 @@ libraries = [
// Annotations // Annotations
commons_annotations: commons_annotations:
'org.hibernate:hibernate-commons-annotations:3.2.0.Final', 'org.hibernate:hibernate-commons-annotations:3.2.0.Final',
jandex: 'org.jboss:jandex:1.0.0.Beta6', jandex: 'org.jboss:jandex:1.0.0.Beta7',
classmate: 'com.fasterxml:classmate:0.5.2', classmate: 'com.fasterxml:classmate:0.5.2',
// Jakarta commons-collections todo : get rid of commons-collections dependency // Jakarta commons-collections todo : get rid of commons-collections dependency

View File

@ -120,7 +120,7 @@ public interface Session extends SharedSessionContract {
/** /**
* Force this session to flush. Must be called at the end of a * Force this session to flush. Must be called at the end of a
* unit of work, before committing the transaction and closing the * unit of work, before committing the transaction and closing the
* session (depending on {@link #setFlushMode flush-mode}, * session (depending on {@link #setFlushMode(FlushMode)},
* {@link Transaction#commit()} calls this method). * {@link Transaction#commit()} calls this method).
* <p/> * <p/>
* <i>Flushing</i> is the process of synchronizing the underlying persistent * <i>Flushing</i> is the process of synchronizing the underlying persistent

View File

@ -190,7 +190,7 @@ class PropertyContainer {
*/ */
private TreeMap<String, XProperty> initProperties(AccessType access) { private TreeMap<String, XProperty> initProperties(AccessType access) {
if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) { if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) {
throw new IllegalArgumentException( "Acces type has to be AccessType.FIELD or AccessType.Property" ); throw new IllegalArgumentException( "Access type has to be AccessType.FIELD or AccessType.Property" );
} }
//order so that property are used in the same order when binding native query //order so that property are used in the same order when binding native query

View File

@ -24,16 +24,19 @@
package org.hibernate.metamodel.source.annotations; package org.hibernate.metamodel.source.annotations;
import javax.persistence.Access; import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.AssociationOverride; import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides; import javax.persistence.AssociationOverrides;
import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides; import javax.persistence.AttributeOverrides;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Cacheable; import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable; import javax.persistence.CollectionTable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.ColumnResult; import javax.persistence.ColumnResult;
import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue; import javax.persistence.DiscriminatorValue;
import javax.persistence.ElementCollection; import javax.persistence.ElementCollection;
import javax.persistence.Embeddable; import javax.persistence.Embeddable;
@ -42,18 +45,23 @@ import javax.persistence.EmbeddedId;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EntityListeners; import javax.persistence.EntityListeners;
import javax.persistence.EntityResult; import javax.persistence.EntityResult;
import javax.persistence.EnumType;
import javax.persistence.Enumerated; import javax.persistence.Enumerated;
import javax.persistence.ExcludeDefaultListeners; import javax.persistence.ExcludeDefaultListeners;
import javax.persistence.ExcludeSuperclassListeners; import javax.persistence.ExcludeSuperclassListeners;
import javax.persistence.FetchType;
import javax.persistence.FieldResult; import javax.persistence.FieldResult;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.IdClass; import javax.persistence.IdClass;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns; import javax.persistence.JoinColumns;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.Lob; import javax.persistence.Lob;
import javax.persistence.LockModeType;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.MapKey; import javax.persistence.MapKey;
@ -96,6 +104,7 @@ import javax.persistence.SqlResultSetMappings;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.TableGenerator; import javax.persistence.TableGenerator;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient; import javax.persistence.Transient;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.persistence.Version; import javax.persistence.Version;
@ -109,16 +118,19 @@ import org.jboss.jandex.DotName;
*/ */
public interface JPADotNames { public interface JPADotNames {
public static final DotName ACCESS = DotName.createSimple( Access.class.getName() ); public static final DotName ACCESS = DotName.createSimple( Access.class.getName() );
public static final DotName ACCESS_TYPE = DotName.createSimple( AccessType.class.getName() );
public static final DotName ASSOCIATION_OVERRIDE = DotName.createSimple( AssociationOverride.class.getName() ); public static final DotName ASSOCIATION_OVERRIDE = DotName.createSimple( AssociationOverride.class.getName() );
public static final DotName ASSOCIATION_OVERRIDES = DotName.createSimple( AssociationOverrides.class.getName() ); public static final DotName ASSOCIATION_OVERRIDES = DotName.createSimple( AssociationOverrides.class.getName() );
public static final DotName ATTRIBUTE_OVERRIDE = DotName.createSimple( AttributeOverride.class.getName() ); public static final DotName ATTRIBUTE_OVERRIDE = DotName.createSimple( AttributeOverride.class.getName() );
public static final DotName ATTRIBUTE_OVERRIDES = DotName.createSimple( AttributeOverrides.class.getName() ); public static final DotName ATTRIBUTE_OVERRIDES = DotName.createSimple( AttributeOverrides.class.getName() );
public static final DotName BASIC = DotName.createSimple( Basic.class.getName() ); public static final DotName BASIC = DotName.createSimple( Basic.class.getName() );
public static final DotName CACHEABLE = DotName.createSimple( Cacheable.class.getName() ); public static final DotName CACHEABLE = DotName.createSimple( Cacheable.class.getName() );
public static final DotName CASCADE_TYPE = DotName.createSimple( CascadeType.class.getName() );
public static final DotName COLLECTION_TABLE = DotName.createSimple( CollectionTable.class.getName() ); public static final DotName COLLECTION_TABLE = DotName.createSimple( CollectionTable.class.getName() );
public static final DotName COLUMN = DotName.createSimple( Column.class.getName() ); public static final DotName COLUMN = DotName.createSimple( Column.class.getName() );
public static final DotName COLUMN_RESULT = DotName.createSimple( ColumnResult.class.getName() ); public static final DotName COLUMN_RESULT = DotName.createSimple( ColumnResult.class.getName() );
public static final DotName DISCRIMINATOR_COLUMN = DotName.createSimple( DiscriminatorColumn.class.getName() ); public static final DotName DISCRIMINATOR_COLUMN = DotName.createSimple( DiscriminatorColumn.class.getName() );
public static final DotName DISCRIMINATOR_TYPE = DotName.createSimple( DiscriminatorType.class.getName() );
public static final DotName DISCRIMINATOR_VALUE = DotName.createSimple( DiscriminatorValue.class.getName() ); public static final DotName DISCRIMINATOR_VALUE = DotName.createSimple( DiscriminatorValue.class.getName() );
public static final DotName ELEMENT_COLLECTION = DotName.createSimple( ElementCollection.class.getName() ); public static final DotName ELEMENT_COLLECTION = DotName.createSimple( ElementCollection.class.getName() );
public static final DotName EMBEDDABLE = DotName.createSimple( Embeddable.class.getName() ); public static final DotName EMBEDDABLE = DotName.createSimple( Embeddable.class.getName() );
@ -128,17 +140,22 @@ public interface JPADotNames {
public static final DotName ENTITY_LISTENERS = DotName.createSimple( EntityListeners.class.getName() ); public static final DotName ENTITY_LISTENERS = DotName.createSimple( EntityListeners.class.getName() );
public static final DotName ENTITY_RESULT = DotName.createSimple( EntityResult.class.getName() ); public static final DotName ENTITY_RESULT = DotName.createSimple( EntityResult.class.getName() );
public static final DotName ENUMERATED = DotName.createSimple( Enumerated.class.getName() ); public static final DotName ENUMERATED = DotName.createSimple( Enumerated.class.getName() );
public static final DotName ENUM_TYPE = DotName.createSimple( EnumType.class.getName() );
public static final DotName EXCLUDE_DEFAULT_LISTENERS = DotName.createSimple( ExcludeDefaultListeners.class.getName() ); public static final DotName EXCLUDE_DEFAULT_LISTENERS = DotName.createSimple( ExcludeDefaultListeners.class.getName() );
public static final DotName EXCLUDE_SUPERCLASS_LISTENERS = DotName.createSimple( ExcludeSuperclassListeners.class.getName() ); public static final DotName EXCLUDE_SUPERCLASS_LISTENERS = DotName.createSimple( ExcludeSuperclassListeners.class.getName() );
public static final DotName FETCH_TYPE = DotName.createSimple( FetchType.class.getName() );
public static final DotName FIELD_RESULT = DotName.createSimple( FieldResult.class.getName() ); public static final DotName FIELD_RESULT = DotName.createSimple( FieldResult.class.getName() );
public static final DotName GENERATION_TYPE = DotName.createSimple( GenerationType.class.getName() );
public static final DotName GENERATED_VALUE = DotName.createSimple( GeneratedValue.class.getName() ); public static final DotName GENERATED_VALUE = DotName.createSimple( GeneratedValue.class.getName() );
public static final DotName ID = DotName.createSimple( Id.class.getName() ); public static final DotName ID = DotName.createSimple( Id.class.getName() );
public static final DotName ID_CLASS = DotName.createSimple( IdClass.class.getName() ); public static final DotName ID_CLASS = DotName.createSimple( IdClass.class.getName() );
public static final DotName INHERITANCE_TYPE = DotName.createSimple( InheritanceType.class.getName() );
public static final DotName JOIN_COLUMN = DotName.createSimple( JoinColumn.class.getName() ); public static final DotName JOIN_COLUMN = DotName.createSimple( JoinColumn.class.getName() );
public static final DotName INHERITANCE = DotName.createSimple( Inheritance.class.getName() ); public static final DotName INHERITANCE = DotName.createSimple( Inheritance.class.getName() );
public static final DotName JOIN_COLUMNS = DotName.createSimple( JoinColumns.class.getName() ); public static final DotName JOIN_COLUMNS = DotName.createSimple( JoinColumns.class.getName() );
public static final DotName JOIN_TABLE = DotName.createSimple( JoinTable.class.getName() ); public static final DotName JOIN_TABLE = DotName.createSimple( JoinTable.class.getName() );
public static final DotName LOB = DotName.createSimple( Lob.class.getName() ); public static final DotName LOB = DotName.createSimple( Lob.class.getName() );
public static final DotName LOCK_MODE_TYPE = DotName.createSimple( LockModeType.class.getName() );
public static final DotName MANY_TO_MANY = DotName.createSimple( ManyToMany.class.getName() ); public static final DotName MANY_TO_MANY = DotName.createSimple( ManyToMany.class.getName() );
public static final DotName MANY_TO_ONE = DotName.createSimple( ManyToOne.class.getName() ); public static final DotName MANY_TO_ONE = DotName.createSimple( ManyToOne.class.getName() );
public static final DotName MAP_KEY = DotName.createSimple( MapKey.class.getName() ); public static final DotName MAP_KEY = DotName.createSimple( MapKey.class.getName() );
@ -181,6 +198,7 @@ public interface JPADotNames {
public static final DotName TABLE = DotName.createSimple( Table.class.getName() ); public static final DotName TABLE = DotName.createSimple( Table.class.getName() );
public static final DotName TABLE_GENERATOR = DotName.createSimple( TableGenerator.class.getName() ); public static final DotName TABLE_GENERATOR = DotName.createSimple( TableGenerator.class.getName() );
public static final DotName TEMPORAL = DotName.createSimple( Temporal.class.getName() ); public static final DotName TEMPORAL = DotName.createSimple( Temporal.class.getName() );
public static final DotName TEMPORAL_TYPE = DotName.createSimple( TemporalType.class.getName() );
public static final DotName TRANSIENT = DotName.createSimple( Transient.class.getName() ); public static final DotName TRANSIENT = DotName.createSimple( Transient.class.getName() );
public static final DotName UNIQUE_CONSTRAINT = DotName.createSimple( UniqueConstraint.class.getName() ); public static final DotName UNIQUE_CONSTRAINT = DotName.createSimple( UniqueConstraint.class.getName() );
public static final DotName VERSION = DotName.createSimple( Version.class.getName() ); public static final DotName VERSION = DotName.createSimple( Version.class.getName() );

View File

@ -1,13 +1,17 @@
package org.hibernate.metamodel.source.annotations.xml; package org.hibernate.metamodel.source.annotations.xml;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jboss.jandex.Index; import org.jboss.jandex.Index;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings; import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
import org.hibernate.metamodel.source.annotations.xml.mocker.EntityMappingsMocker;
import org.hibernate.metamodel.source.internal.JaxbRoot; import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.metamodel.source.internal.MetadataImpl; import org.hibernate.metamodel.source.internal.MetadataImpl;
//import org.hibernate.metamodel.source.util.xml.XmlHelper;
/** /**
* @author Hardy Ferentschik * @author Hardy Ferentschik
* @todo Need some create some XMLContext as well which can be populated w/ information which can not be expressed via annotations * @todo Need some create some XMLContext as well which can be populated w/ information which can not be expressed via annotations
@ -28,11 +32,17 @@ public class OrmXmlParser {
* @return a new updated annotation index, enhancing and modifying the existing ones according to the jpa xml rules * @return a new updated annotation index, enhancing and modifying the existing ones according to the jpa xml rules
*/ */
public Index parseAndUpdateIndex(List<JaxbRoot<XMLEntityMappings>> mappings, Index annotationIndex) { public Index parseAndUpdateIndex(List<JaxbRoot<XMLEntityMappings>> mappings, Index annotationIndex) {
for ( JaxbRoot<XMLEntityMappings> root : mappings ) { List<XMLEntityMappings> list = new ArrayList<XMLEntityMappings>( mappings.size() );
root.getRoot().toString(); for ( JaxbRoot<XMLEntityMappings> jaxbRoot : mappings ) {
list.add( jaxbRoot.getRoot() );
} }
return annotationIndex; return new EntityMappingsMocker(
list, annotationIndex, meta.getServiceRegistry()
).mockNewIndex();
} }
} }

View File

@ -0,0 +1,81 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.filter;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotations.xml.mocker.IndexBuilder;
/**
* @author Strong Liu
*/
abstract class AbstractAnnotationFilter implements IndexedAnnotationFilter {
protected static final DotName[] EMPTY_DOTNAME_ARRAY = new DotName[0];
private Set<DotName> candidates;
private boolean match(DotName annName) {
if ( candidates == null ) {
candidates = new HashSet<DotName>();
for ( DotName name : targetAnnotation() ) {
candidates.add( name );
}
}
return candidates.contains( annName );
}
@Override
public void beforePush(IndexBuilder indexBuilder, DotName classDotName, AnnotationInstance annotationInstance) {
DotName annName = annotationInstance.name();
if ( !match( annName ) ) {
return;
}
Map<DotName, List<AnnotationInstance>> map = indexBuilder.getIndexedAnnotations( classDotName );
overrideIndexedAnnotationMap( annName, annotationInstance, map );
}
protected void overrideIndexedAnnotationMap(DotName annName, AnnotationInstance annotationInstance, Map<DotName, List<AnnotationInstance>> map) {
if ( !map.containsKey( annName ) ) {
return;
}
List<AnnotationInstance> indexedAnnotationInstanceList = map.get( annName );
if ( indexedAnnotationInstanceList.isEmpty() ) {
return;
}
process( annName, annotationInstance, indexedAnnotationInstanceList );
}
protected void process(DotName annName, AnnotationInstance annotationInstance, List<AnnotationInstance> indexedAnnotationInstanceList) {
}
protected DotName[] targetAnnotation() {
return EMPTY_DOTNAME_ARRAY;
}
}

View File

@ -0,0 +1,181 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.filter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotations.xml.mocker.MockHelper;
/**
* @author Strong Liu
*/
class ExclusiveAnnotationFilter extends AbstractAnnotationFilter {
public static ExclusiveAnnotationFilter INSTANCE = new ExclusiveAnnotationFilter();
private DotName[] targetNames;
private List<ExclusiveGroup> exclusiveGroupList;
private ExclusiveAnnotationFilter() {
this.exclusiveGroupList = getExclusiveGroupList();
Set<DotName> names = new HashSet<DotName>();
for ( ExclusiveGroup group : exclusiveGroupList ) {
names.addAll( group.getNames() );
}
targetNames = names.toArray( new DotName[names.size()] );
}
private List<ExclusiveGroup> getExclusiveGroupList() {
if ( exclusiveGroupList == null ) {
exclusiveGroupList = new ArrayList<ExclusiveGroup>();
ExclusiveGroup group = new ExclusiveGroup();
group.add( ENTITY );
group.add( MAPPED_SUPERCLASS );
group.add( EMBEDDABLE );
group.scope = Scope.TYPE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( SECONDARY_TABLES );
group.add( SECONDARY_TABLE );
group.scope = Scope.TYPE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( PRIMARY_KEY_JOIN_COLUMNS );
group.add( PRIMARY_KEY_JOIN_COLUMN );
group.scope = Scope.ATTRIBUTE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( SQL_RESULT_SET_MAPPING );
group.add( SQL_RESULT_SET_MAPPINGS );
group.scope = Scope.TYPE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( NAMED_NATIVE_QUERY );
group.add( NAMED_NATIVE_QUERIES );
group.scope = Scope.TYPE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( NAMED_QUERY );
group.add( NAMED_QUERIES );
group.scope = Scope.TYPE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( ATTRIBUTE_OVERRIDES );
group.add( ATTRIBUTE_OVERRIDE );
group.scope = Scope.ATTRIBUTE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( ASSOCIATION_OVERRIDE );
group.add( ASSOCIATION_OVERRIDES );
group.scope = Scope.ATTRIBUTE;
exclusiveGroupList.add( group );
group = new ExclusiveGroup();
group.add( MAP_KEY_JOIN_COLUMN );
group.add( MAP_KEY_JOIN_COLUMNS );
group.scope = Scope.ATTRIBUTE;
exclusiveGroupList.add( group );
}
return exclusiveGroupList;
}
@Override
protected void overrideIndexedAnnotationMap(DotName annName, AnnotationInstance annotationInstance, Map<DotName, List<AnnotationInstance>> map) {
ExclusiveGroup group = getExclusiveGroup( annName );
if ( group == null ) {
return;
}
AnnotationTarget target = annotationInstance.target();
for ( DotName entityAnnName : group ) {
if ( !map.containsKey( entityAnnName ) ) {
continue;
}
switch ( group.scope ) {
case TYPE:
map.put( entityAnnName, Collections.<AnnotationInstance>emptyList() );
break;
case ATTRIBUTE:
List<AnnotationInstance> indexedAnnotationInstanceList = map.get( entityAnnName );
Iterator<AnnotationInstance> iter = indexedAnnotationInstanceList.iterator();
while ( iter.hasNext() ) {
AnnotationInstance ann = iter.next();
if ( MockHelper.targetEquals( target, ann.target(), true ) ) {
iter.remove();
}
}
break;
}
}
}
@Override
protected DotName[] targetAnnotation() {
return targetNames;
}
private ExclusiveGroup getExclusiveGroup(DotName annName) {
for ( ExclusiveGroup group : exclusiveGroupList ) {
if ( group.contains( annName ) ) {
return group;
}
}
return null;
}
enum Scope {TYPE, ATTRIBUTE}
private class ExclusiveGroup implements Iterable<DotName> {
public Set<DotName> getNames() {
return names;
}
private Set<DotName> names = new HashSet<DotName>();
Scope scope = Scope.ATTRIBUTE;
@Override
public Iterator iterator() {
return names.iterator();
}
boolean contains(DotName name) {
return names.contains( name );
}
void add(DotName name) {
names.add( name );
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.filter;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.xml.mocker.IndexBuilder;
/**
* @author Strong Liu
*/
public interface IndexedAnnotationFilter extends JPADotNames {
DotName[] GLOBAL_ANNOTATIONS = new DotName[] {
SEQUENCE_GENERATOR,
TABLE_GENERATOR,
NAMED_QUERIES,
NAMED_QUERY,
NAMED_NATIVE_QUERIES,
NAMED_NATIVE_QUERY,
SQL_RESULT_SET_MAPPING,
SQL_RESULT_SET_MAPPINGS
};
DotName[] SCHEMAAWARE_ANNOTATIONS = new DotName[] {
TABLE, JOIN_TABLE, COLLECTION_TABLE, SECONDARY_TABLE, SECONDARY_TABLES
, TABLE_GENERATOR, SEQUENCE_GENERATOR
};
DotName[] ASSOCIATION_ANNOTATIONS = new DotName[] {
ONE_TO_MANY, ONE_TO_ONE, MANY_TO_ONE, MANY_TO_MANY
};
IndexedAnnotationFilter[] filters = new IndexedAnnotationFilter[] {
ExclusiveAnnotationFilter.INSTANCE,
NameAnnotationFilter.INSTANCE, NameTargetAnnotationFilter.INSTANCE
};
void beforePush(IndexBuilder indexBuilder, DotName classDotName, AnnotationInstance annotationInstance);
}

View File

@ -0,0 +1,34 @@
package org.hibernate.metamodel.source.annotations.xml.filter;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
/**
* @author Strong Liu
*/
class NameAnnotationFilter extends AbstractAnnotationFilter {
@Override
protected void process(DotName annName, AnnotationInstance annotationInstance, List<AnnotationInstance> indexedAnnotationInstanceList) {
indexedAnnotationInstanceList.clear();
}
public static NameTargetAnnotationFilter INSTANCE = new NameTargetAnnotationFilter();
@Override
protected DotName[] targetAnnotation() {
return new DotName[] {
CACHEABLE,
TABLE,
EXCLUDE_DEFAULT_LISTENERS,
EXCLUDE_SUPERCLASS_LISTENERS,
ID_CLASS,
INHERITANCE,
DISCRIMINATOR_VALUE,
DISCRIMINATOR_COLUMN,
ENTITY_LISTENERS
};
}
}

View File

@ -0,0 +1,97 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.filter;
import java.util.Iterator;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotations.xml.mocker.MockHelper;
/**
* @author Strong Liu
*/
class NameTargetAnnotationFilter extends AbstractAnnotationFilter {
@Override
protected void process(DotName annName, AnnotationInstance annotationInstance, List<AnnotationInstance> indexedAnnotationInstanceList) {
AnnotationTarget target = annotationInstance.target();
for ( Iterator<AnnotationInstance> iter = indexedAnnotationInstanceList.iterator(); iter.hasNext(); ) {
AnnotationInstance ann = iter.next();
if ( MockHelper.targetEquals( target, ann.target(), false ) ) {
iter.remove();
}
}
}
public static NameTargetAnnotationFilter INSTANCE = new NameTargetAnnotationFilter();
@Override
protected DotName[] targetAnnotation() {
return new DotName[] {
LOB,
ID,
BASIC,
GENERATED_VALUE,
VERSION,
TRANSIENT,
ACCESS,
POST_LOAD,
POST_PERSIST,
POST_REMOVE,
POST_UPDATE,
PRE_PERSIST,
PRE_REMOVE,
PRE_UPDATE,
EMBEDDED_ID,
EMBEDDED,
MANY_TO_ONE,
MANY_TO_MANY,
ONE_TO_ONE,
ONE_TO_MANY,
ELEMENT_COLLECTION,
COLLECTION_TABLE,
COLUMN,
ENUMERATED,
JOIN_TABLE,
TEMPORAL,
ORDER_BY,
ORDER_COLUMN,
JOIN_COLUMN,
JOIN_COLUMNS,
MAPS_ID,
MAP_KEY_TEMPORAL,
MAP_KEY,
MAP_KEY_CLASS,
MAP_KEY_COLUMN,
MAP_KEY_ENUMERATED
};
}
}

View File

@ -0,0 +1,127 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.List;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLBasic;
import org.hibernate.metamodel.source.annotation.xml.XMLElementCollection;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbedded;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddedId;
import org.hibernate.metamodel.source.annotation.xml.XMLId;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToMany;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToOne;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToMany;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToOne;
import org.hibernate.metamodel.source.annotation.xml.XMLTransient;
import org.hibernate.metamodel.source.annotation.xml.XMLVersion;
/**
* Abstract Parser to handle {@link org.hibernate.metamodel.source.annotation.xml.XMLAttributes XMLAttributes}
* and {@link org.hibernate.metamodel.source.annotation.xml.XMLEmbeddableAttributes XMLEmbeddableAttributes}.
*
* It would be really helpful if these two classes can implement an interface with those abstract methods in this class.
*
* @author Strong Liu
*/
abstract class AbstractAttributesBuilder {
private ClassInfo classInfo;
private EntityMappingsMocker.Default defaults;
private IndexBuilder indexBuilder;
AbstractAttributesBuilder(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults) {
this.indexBuilder = indexBuilder;
this.classInfo = classInfo;
this.defaults = defaults;
}
final void parser() {
for ( XMLId id : getId() ) {
new IdMocker( indexBuilder, classInfo, defaults, id ).process();
}
for ( XMLTransient transientObj : getTransient() ) {
new TransientMocker( indexBuilder, classInfo, defaults, transientObj ).process();
}
for ( XMLVersion version : getVersion() ) {
new VersionMocker( indexBuilder, classInfo, defaults, version ).process();
}
for ( XMLBasic basic : getBasic() ) {
new BasicMocker( indexBuilder, classInfo, defaults, basic ).process();
}
for ( XMLElementCollection elementCollection : getElementCollection() ) {
new ElementCollectionMocker(
indexBuilder, classInfo, defaults, elementCollection
).process();
}
for ( XMLEmbedded embedded : getEmbedded() ) {
new EmbeddedMocker( indexBuilder, classInfo, defaults, embedded ).process();
}
for ( XMLManyToMany manyToMany : getManyToMany() ) {
new ManyToManyMocker( indexBuilder, classInfo, defaults, manyToMany ).process();
}
for ( XMLManyToOne manyToOne : getManyToOne() ) {
new ManyToOneMocker( indexBuilder, classInfo, defaults, manyToOne ).process();
}
for ( XMLOneToMany oneToMany : getOneToMany() ) {
new OneToManyMocker(
indexBuilder, classInfo, defaults, oneToMany
).process();
}
for ( XMLOneToOne oneToOne : getOneToOne() ) {
new OneToOneMocker( indexBuilder, classInfo, defaults, oneToOne ).process();
}
if ( getEmbeddedId() != null ) {
new EmbeddedIdMocker(
indexBuilder, classInfo, defaults, getEmbeddedId()
).process();
}
}
abstract List<XMLId> getId();
abstract List<XMLTransient> getTransient();
abstract List<XMLVersion> getVersion();
abstract List<XMLBasic> getBasic();
abstract List<XMLElementCollection> getElementCollection();
abstract List<XMLEmbedded> getEmbedded();
abstract List<XMLManyToMany> getManyToMany();
abstract List<XMLManyToOne> getManyToOne();
abstract List<XMLOneToMany> getOneToMany();
abstract List<XMLOneToOne> getOneToOne();
abstract XMLEmbeddedId getEmbeddedId();
}

View File

@ -0,0 +1,165 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLIdClass;
import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad;
import org.hibernate.metamodel.source.annotation.xml.XMLPostPersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPostRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPostUpdate;
import org.hibernate.metamodel.source.annotation.xml.XMLPrePersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPreRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate;
/**
* @author Strong Liu
*/
abstract class AbstractEntityObjectMocker extends AnnotationMocker {
private ListenerMocker listenerParser;
protected AbstractAttributesBuilder attributesBuilder;
protected ClassInfo classInfo;
AbstractEntityObjectMocker(IndexBuilder indexBuilder, EntityMappingsMocker.Default defaults) {
super( indexBuilder, defaults );
}
final void process() {
applyDefaults();
classInfo = indexBuilder.createClassInfo( getClassName() );
DotName classDotName = classInfo.name();
indexBuilder.metadataComplete( classDotName, isMetadataComplete() );
processExtra();
if ( isExcludeDefaultListeners() ) {
create( EXCLUDE_DEFAULT_LISTENERS );
}
if ( isExcludeSuperclassListeners() ) {
create( EXCLUDE_SUPERCLASS_LISTENERS );
}
parserIdClass( getIdClass() );
parserAccessType( getAccessType(), getTarget() );
if ( getAttributes() != null ) {
getAttributesBuilder().parser();
}
if ( getEntityListeners() != null ) {
getListenerParser().parser( getEntityListeners() );
}
getListenerParser().parser( getPrePersist() );
getListenerParser().parser( getPreRemove() );
getListenerParser().parser( getPreUpdate() );
getListenerParser().parser( getPostPersist() );
getListenerParser().parser( getPostUpdate() );
getListenerParser().parser( getPostRemove() );
getListenerParser().parser( getPostLoad() );
indexBuilder.finishEntityObject( getTargetName(), getDefaults() );
}
abstract protected void processExtra();
/**
* give a chance to the sub-classes to override defaults configuration
*/
abstract protected void applyDefaults();
abstract protected boolean isMetadataComplete();
abstract protected boolean isExcludeDefaultListeners();
abstract protected boolean isExcludeSuperclassListeners();
abstract protected XMLIdClass getIdClass();
abstract protected XMLEntityListeners getEntityListeners();
abstract protected XMLAccessType getAccessType();
abstract protected String getClassName();
abstract protected XMLPrePersist getPrePersist();
abstract protected XMLPreRemove getPreRemove();
abstract protected XMLPreUpdate getPreUpdate();
abstract protected XMLPostPersist getPostPersist();
abstract protected XMLPostUpdate getPostUpdate();
abstract protected XMLPostRemove getPostRemove();
abstract protected XMLPostLoad getPostLoad();
abstract protected XMLAttributes getAttributes();
protected ListenerMocker getListenerParser() {
if ( listenerParser == null ) {
listenerParser = new ListenerMocker( indexBuilder, classInfo );
}
return listenerParser;
}
protected AbstractAttributesBuilder getAttributesBuilder() {
if ( attributesBuilder == null ) {
attributesBuilder = new AttributesBuilder(
indexBuilder, classInfo, getAccessType(), getDefaults(), getAttributes()
);
}
return attributesBuilder;
}
protected AnnotationInstance parserIdClass(XMLIdClass idClass) {
if ( idClass == null ) {
return null;
}
String className = MockHelper.buildSafeClassName( idClass.getClazz(), getDefaults().getPackageName() );
return create(
ID_CLASS, MockHelper.classValueArray(
"value", className, indexBuilder.getServiceRegistry()
)
);
}
@Override
protected DotName getTargetName() {
return classInfo.name();
}
@Override
protected AnnotationTarget getTarget() {
return classInfo;
}
}

View File

@ -0,0 +1,568 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLAssociationOverride;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributeOverride;
import org.hibernate.metamodel.source.annotation.xml.XMLCollectionTable;
import org.hibernate.metamodel.source.annotation.xml.XMLColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLEnumType;
import org.hibernate.metamodel.source.annotation.xml.XMLJoinColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLJoinTable;
import org.hibernate.metamodel.source.annotation.xml.XMLLob;
import org.hibernate.metamodel.source.annotation.xml.XMLOrderColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLPrimaryKeyJoinColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLTemporalType;
import org.hibernate.metamodel.source.annotation.xml.XMLUniqueConstraint;
import org.hibernate.metamodel.source.annotations.JPADotNames;
/**
* @author Strong Liu
*/
abstract class AbstractMocker implements JPADotNames {
protected IndexBuilder indexBuilder;
AbstractMocker(IndexBuilder indexBuilder) {
this.indexBuilder = indexBuilder;
}
abstract protected EntityMappingsMocker.Default getDefaults();
/**
* @return DotName as the key for the ClassInfo object this mocker created that being push to.
*/
abstract protected DotName getTargetName();
/**
* @return Default Annotation Target for #{create} and #{mocker} methods.
*/
abstract protected AnnotationTarget getTarget();
protected AnnotationInstance push(AnnotationInstance annotationInstance) {
if ( annotationInstance != null ) {
indexBuilder.addAnnotationInstance( getTargetName(), annotationInstance );
}
return annotationInstance;
}
/**
* Create simple AnnotationInstance with empty annotation value.
* AnnotationInstance's target is get from #{getTarget}
*
* @param name annotation name
*
* @return annotationInstance which name is , target is from #{getTarget}, and has no annotation values.
*/
protected AnnotationInstance create(DotName name) {
return create( name, MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY );
}
protected AnnotationInstance create(DotName name, AnnotationValue[] annotationValues) {
return create( name, getTarget(), annotationValues );
}
protected AnnotationInstance create(DotName name, List<AnnotationValue> annotationValueList) {
return create( name, getTarget(), annotationValueList );
}
protected AnnotationInstance create(DotName name, AnnotationTarget target) {
return create( name, target, MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY );
}
protected AnnotationInstance create(DotName name, AnnotationTarget target, List<AnnotationValue> annotationValueList) {
return create( name, target, MockHelper.toArray( annotationValueList ) );
}
protected AnnotationInstance create(DotName name, AnnotationTarget target, AnnotationValue[] annotationValues) {
AnnotationInstance annotationInstance = MockHelper.create( name, target, annotationValues );
if ( target != null ) {
push( annotationInstance );
}
return annotationInstance;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//@Column
protected AnnotationInstance parserColumn(XMLColumn column, AnnotationTarget target) {
if ( column == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", column.getName(), annotationValueList );
MockHelper.stringValue( "columnDefinition", column.getColumnDefinition(), annotationValueList );
MockHelper.stringValue( "table", column.getTable(), annotationValueList );
MockHelper.booleanValue( "unique", column.isUnique(), annotationValueList );
MockHelper.booleanValue( "nullable", column.isNullable(), annotationValueList );
MockHelper.booleanValue( "insertable", column.isInsertable(), annotationValueList );
MockHelper.booleanValue( "updatable", column.isUpdatable(), annotationValueList );
MockHelper.integerValue( "length", column.getLength(), annotationValueList );
MockHelper.integerValue( "precision", column.getPrecision(), annotationValueList );
MockHelper.integerValue( "scale", column.getScale(), annotationValueList );
return create( COLUMN, target, annotationValueList );
}
protected AnnotationInstance parserTemporalType(XMLTemporalType temporalType, AnnotationTarget target) {
if ( temporalType == null ) {
return null;
}
return create( TEMPORAL, target, MockHelper.enumValueArray( "value", TEMPORAL_TYPE, temporalType ) );
}
protected AnnotationInstance parserEnumType(XMLEnumType enumerated, AnnotationTarget target) {
if ( enumerated == null ) {
return null;
}
return create( ENUMERATED, target, MockHelper.enumValueArray( "value", ENUM_TYPE, enumerated ) );
}
//@AttributeOverride
private AnnotationInstance parserAttributeOverride(XMLAttributeOverride attributeOverride, AnnotationTarget target) {
if ( attributeOverride == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", attributeOverride.getName(), annotationValueList );
if ( attributeOverride instanceof XMLAttributeOverrideProxy ) {
XMLAttributeOverrideProxy proxy = (XMLAttributeOverrideProxy) attributeOverride;
MockHelper.addToCollectionIfNotNull( annotationValueList, proxy.getColumnAnnotationValue() );
}
else {
MockHelper.nestedAnnotationValue(
"column", parserColumn( attributeOverride.getColumn(), null ), annotationValueList
);
}
return
create(
ATTRIBUTE_OVERRIDE, target, annotationValueList
);
}
protected AnnotationInstance parserPrimaryKeyJoinColumn(XMLPrimaryKeyJoinColumn primaryKeyJoinColumn, AnnotationTarget target) {
if ( primaryKeyJoinColumn == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", primaryKeyJoinColumn.getName(), annotationValueList );
MockHelper.stringValue(
"referencedColumnName", primaryKeyJoinColumn.getReferencedColumnName(), annotationValueList
);
MockHelper.stringValue(
"columnDefinition", primaryKeyJoinColumn.getColumnDefinition(), annotationValueList
);
return
create(
PRIMARY_KEY_JOIN_COLUMN, target, annotationValueList
);
}
protected AnnotationInstance parserPrimaryKeyJoinColumnList(List<XMLPrimaryKeyJoinColumn> primaryKeyJoinColumnList, AnnotationTarget target) {
if ( MockHelper.isNotEmpty( primaryKeyJoinColumnList ) ) {
if ( primaryKeyJoinColumnList.size() == 1 ) {
return parserPrimaryKeyJoinColumn( primaryKeyJoinColumnList.get( 0 ), target );
}
else {
return create(
PRIMARY_KEY_JOIN_COLUMNS,
target,
nestedPrimaryKeyJoinColumnList( "value", primaryKeyJoinColumnList, null )
);
}
}
return null;
}
protected AnnotationValue[] nestedPrimaryKeyJoinColumnList(String name, List<XMLPrimaryKeyJoinColumn> constraints, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( constraints ) ) {
AnnotationValue[] values = new AnnotationValue[constraints.size()];
for ( int i = 0; i < constraints.size(); i++ ) {
AnnotationInstance annotationInstance = parserPrimaryKeyJoinColumn( constraints.get( i ), null );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull(
annotationValueList, AnnotationValue.createArrayValue( name, values )
);
return values;
}
return MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY;
}
protected void getAnnotationInstanceByTarget(DotName annName, AnnotationTarget target, Operation operation) {
Map<DotName, List<AnnotationInstance>> annotatedMap = indexBuilder.getIndexedAnnotations( getTargetName() );
if ( !annotatedMap.containsKey( annName ) ) {
return;
}
List<AnnotationInstance> annotationInstanceList = annotatedMap.get( annName );
if ( MockHelper.isNotEmpty( annotationInstanceList ) ) {
for ( AnnotationInstance annotationInstance : annotationInstanceList ) {
AnnotationTarget annotationTarget = annotationInstance.target();
if ( MockHelper.targetEquals( target, annotationTarget, false ) ) {
if ( operation.process( annotationInstance ) ) {
return;
}
}
}
}
}
protected interface Operation {
boolean process(AnnotationInstance annotationInstance);
}
class ContainerOperation implements Operation {
private Operation child;
ContainerOperation(Operation child) {
this.child = child;
}
@Override
public boolean process(AnnotationInstance annotationInstance) {
AnnotationValue value = annotationInstance.value();
AnnotationInstance[] indexedAttributeOverridesValues = value.asNestedArray();
for ( AnnotationInstance ai : indexedAttributeOverridesValues ) {
child.process( ai );
}
return true;
}
}
class AttributeOverrideOperation implements Operation {
private Set<String> names;
private List<XMLAttributeOverride> attributeOverrides;
AttributeOverrideOperation(Set<String> names, List<XMLAttributeOverride> attributeOverrides) {
this.names = names;
this.attributeOverrides = attributeOverrides;
}
@Override
public boolean process(AnnotationInstance annotationInstance) {
String name = annotationInstance.value( "name" ).asString();
if ( !names.contains( name ) ) {
XMLAttributeOverrideProxy attributeOverride = new XMLAttributeOverrideProxy();
attributeOverride.setName( name );
attributeOverride.setColumnAnnotationValue( annotationInstance.value( "column" ) );
attributeOverrides.add( attributeOverride );
}
return false;
}
}
protected AnnotationInstance parserAttributeOverrides(List<XMLAttributeOverride> attributeOverrides, AnnotationTarget target) {
if ( target == null ) {
throw new AssertionFailure( "target can not be null" );
}
if ( attributeOverrides == null || attributeOverrides.isEmpty() ) {
return null;
}
Set<String> names = new HashSet<String>();
for ( XMLAttributeOverride attributeOverride : attributeOverrides ) {
names.add( attributeOverride.getName() );
}
Operation operation = new AttributeOverrideOperation( names, attributeOverrides );
getAnnotationInstanceByTarget(
ATTRIBUTE_OVERRIDES, target, new ContainerOperation( operation )
);
getAnnotationInstanceByTarget(
ATTRIBUTE_OVERRIDE, target, operation
);
if ( attributeOverrides.size() == 1 ) {
return parserAttributeOverride( attributeOverrides.get( 0 ), target );
}
else {
AnnotationValue[] values = new AnnotationValue[attributeOverrides.size()];
for ( int i = 0; i < values.length; i++ ) {
values[i] = MockHelper.nestedAnnotationValue(
"", parserAttributeOverride( attributeOverrides.get( i ), null )
);
}
return create(
ATTRIBUTE_OVERRIDES,
target,
new AnnotationValue[] { AnnotationValue.createArrayValue( "value", values ) }
);
}
}
class AssociationOverrideOperation implements Operation {
private Set<String> names;
private List<XMLAssociationOverride> associationOverrides;
AssociationOverrideOperation(Set<String> names, List<XMLAssociationOverride> associationOverrides) {
this.names = names;
this.associationOverrides = associationOverrides;
}
@Override
public boolean process(AnnotationInstance annotationInstance) {
String name = annotationInstance.value( "name" ).asString();
if ( !names.contains( name ) ) {
XMLAssociationOverrideProxy associationOverride = new XMLAssociationOverrideProxy();
associationOverride.setName( name );
associationOverride.setJoinColumnsAnnotationValue( annotationInstance.value( "joinColumns" ) );
associationOverride.setJoinTableAnnotationValue( annotationInstance.value( "joinTable" ) );
associationOverrides.add( associationOverride );
}
return false;
}
}
protected AnnotationInstance parserAssociationOverrides(List<XMLAssociationOverride> associationOverrides, AnnotationTarget target) {
if ( target == null ) {
throw new AssertionFailure( "target can not be null" );
}
if ( associationOverrides == null || associationOverrides.isEmpty() ) {
return null;
}
Set<String> names = new HashSet<String>();
for ( XMLAssociationOverride associationOverride : associationOverrides ) {
names.add( associationOverride.getName() );
}
Operation operation = new AssociationOverrideOperation( names, associationOverrides );
getAnnotationInstanceByTarget(
ASSOCIATION_OVERRIDES, target, new ContainerOperation( operation )
);
getAnnotationInstanceByTarget(
ASSOCIATION_OVERRIDE, target, operation
);
if ( associationOverrides.size() == 1 ) {
return parserAssociationOverride( associationOverrides.get( 0 ), target );
}
else {
AnnotationValue[] values = new AnnotationValue[associationOverrides.size()];
for ( int i = 0; i < values.length; i++ ) {
values[i] = MockHelper.nestedAnnotationValue(
"", parserAssociationOverride( associationOverrides.get( i ), null )
);
}
return create(
ASSOCIATION_OVERRIDES,
target,
new AnnotationValue[] { AnnotationValue.createArrayValue( "value", values ) }
);
}
}
//@AssociationOverride
private AnnotationInstance parserAssociationOverride(XMLAssociationOverride associationOverride, AnnotationTarget target) {
if ( associationOverride == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", associationOverride.getName(), annotationValueList );
if ( associationOverride instanceof XMLAssociationOverrideProxy ) {
XMLAssociationOverrideProxy proxy = (XMLAssociationOverrideProxy) associationOverride;
MockHelper.addToCollectionIfNotNull( annotationValueList, proxy.getJoinColumnsAnnotationValue() );
MockHelper.addToCollectionIfNotNull( annotationValueList, proxy.getJoinTableAnnotationValue() );
}
else {
nestedJoinColumnList(
"joinColumns", associationOverride.getJoinColumn(), annotationValueList
);
MockHelper.nestedAnnotationValue(
"joinTable", parserJoinTable( associationOverride.getJoinTable(), null ), annotationValueList
);
}
return create( ASSOCIATION_OVERRIDE, target, annotationValueList );
}
//@JoinTable
protected AnnotationInstance parserJoinTable(XMLJoinTable joinTable, AnnotationTarget target) {
if ( joinTable == null ) {
return null;
}
MockHelper.updateSchema( new SchemaAware.JoinTableSchemaAware( joinTable ), getDefaults() );
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", joinTable.getName(), annotationValueList );
MockHelper.stringValue( "catalog", joinTable.getCatalog(), annotationValueList );
MockHelper.stringValue( "schema", joinTable.getSchema(), annotationValueList );
nestedJoinColumnList( "joinColumns", joinTable.getJoinColumn(), annotationValueList );
nestedJoinColumnList(
"inverseJoinColumns", joinTable.getInverseJoinColumn(), annotationValueList
);
nestedUniqueConstraintList(
"uniqueConstraints", joinTable.getUniqueConstraint(), annotationValueList
);
return create( JOIN_TABLE, target, annotationValueList );
}
protected void nestedUniqueConstraintList(String name, List<XMLUniqueConstraint> constraints, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( constraints ) ) {
AnnotationValue[] values = new AnnotationValue[constraints.size()];
for ( int i = 0; i < constraints.size(); i++ ) {
AnnotationInstance annotationInstance = parserUniqueConstraint( constraints.get( i ) );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull(
annotationValueList, AnnotationValue.createArrayValue( name, values )
);
}
}
//@UniqueConstraint
protected AnnotationInstance parserUniqueConstraint(XMLUniqueConstraint uniqueConstraint) {
if ( uniqueConstraint == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", uniqueConstraint.getName(), annotationValueList );
MockHelper.stringArrayValue( "columnNames", uniqueConstraint.getColumnName(), annotationValueList );
return
create(
UNIQUE_CONSTRAINT,
annotationValueList
);
}
protected AnnotationInstance parserAccessType(XMLAccessType accessType, AnnotationTarget target) {
if ( accessType == null ) {
return null;
}
return create( ACCESS, target, MockHelper.enumValueArray( "value", ACCESS_TYPE, accessType ) );
}
protected AnnotationInstance parserCollectionTable(XMLCollectionTable collectionTable, AnnotationTarget target) {
if ( collectionTable == null ) {
return null;
}
MockHelper.updateSchema( new SchemaAware.CollectionTableSchemaAware( collectionTable ), getDefaults() );
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", collectionTable.getName(), annotationValueList );
MockHelper.stringValue( "catalog", collectionTable.getCatalog(), annotationValueList );
MockHelper.stringValue( "schema", collectionTable.getSchema(), annotationValueList );
nestedJoinColumnList( "joinColumns", collectionTable.getJoinColumn(), annotationValueList );
nestedUniqueConstraintList( "uniqueConstraints", collectionTable.getUniqueConstraint(), annotationValueList );
return create( COLLECTION_TABLE, target, annotationValueList );
}
private AnnotationValue[] nestedJoinColumnList(String name, List<XMLJoinColumn> columns, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( columns ) ) {
AnnotationValue[] values = new AnnotationValue[columns.size()];
for ( int i = 0; i < columns.size(); i++ ) {
AnnotationInstance annotationInstance = parserJoinColumn( columns.get( i ), null );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull(
annotationValueList, AnnotationValue.createArrayValue( name, values )
);
return values;
}
return MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY;
}
protected AnnotationInstance parserJoinColumnList(List<XMLJoinColumn> joinColumnList, AnnotationTarget target) {
if ( MockHelper.isNotEmpty( joinColumnList ) ) {
if ( joinColumnList.size() == 1 ) {
return parserJoinColumn( joinColumnList.get( 0 ), target );
}
else {
AnnotationValue[] values = nestedJoinColumnList( "value", joinColumnList, null );
return create(
JOIN_COLUMNS,
target,
values
);
}
}
return null;
}
protected AnnotationInstance parserOrderColumn(XMLOrderColumn orderColumn, AnnotationTarget target) {
if ( orderColumn == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", orderColumn.getName(), annotationValueList );
MockHelper.stringValue( "columnDefinition", orderColumn.getColumnDefinition(), annotationValueList );
MockHelper.booleanValue( "nullable", orderColumn.isNullable(), annotationValueList );
MockHelper.booleanValue( "insertable", orderColumn.isInsertable(), annotationValueList );
MockHelper.booleanValue( "updatable", orderColumn.isUpdatable(), annotationValueList );
return create( ORDER_COLUMN, target, annotationValueList );
}
//@JoinColumn
protected AnnotationInstance parserJoinColumn(XMLJoinColumn column, AnnotationTarget target) {
if ( column == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", column.getName(), annotationValueList );
MockHelper.stringValue( "columnDefinition", column.getColumnDefinition(), annotationValueList );
MockHelper.stringValue( "table", column.getTable(), annotationValueList );
MockHelper.stringValue(
"referencedColumnName", column.getReferencedColumnName(), annotationValueList
);
MockHelper.booleanValue( "unique", column.isUnique(), annotationValueList );
MockHelper.booleanValue( "nullable", column.isNullable(), annotationValueList );
MockHelper.booleanValue( "insertable", column.isInsertable(), annotationValueList );
MockHelper.booleanValue( "updatable", column.isUpdatable(), annotationValueList );
return create( JOIN_COLUMN, target, annotationValueList );
}
protected AnnotationInstance parserLob(XMLLob lob, AnnotationTarget target) {
if ( lob == null ) {
return null;
}
return create( LOB, target );
}
}

View File

@ -0,0 +1,49 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
/**
* @author Strong Liu
*/
abstract class AnnotationMocker extends AbstractMocker {
private EntityMappingsMocker.Default defaults;
AnnotationMocker(IndexBuilder indexBuilder, EntityMappingsMocker.Default defaults) {
super( indexBuilder );
this.defaults = defaults;
}
abstract void process();
@Override
protected EntityMappingsMocker.Default getDefaults() {
return defaults;
}
protected boolean isDefaultCascadePersist() {
return defaults.getCascadePersist() != null && defaults.getCascadePersist();
}
}

View File

@ -0,0 +1,111 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.List;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLBasic;
import org.hibernate.metamodel.source.annotation.xml.XMLElementCollection;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbedded;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddedId;
import org.hibernate.metamodel.source.annotation.xml.XMLId;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToMany;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToOne;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToMany;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToOne;
import org.hibernate.metamodel.source.annotation.xml.XMLTransient;
import org.hibernate.metamodel.source.annotation.xml.XMLVersion;
/**
* @author Strong Liu
*/
class AttributesBuilder extends AbstractAttributesBuilder {
private XMLAttributes attributes;
AttributesBuilder(IndexBuilder indexBuilder, ClassInfo classInfo, XMLAccessType accessType, EntityMappingsMocker.Default defaults, XMLAttributes attributes) {
super( indexBuilder, classInfo, defaults );
this.attributes = attributes;
}
@Override
List<XMLBasic> getBasic() {
return attributes.getBasic();
}
@Override
List<XMLId> getId() {
return attributes.getId();
}
@Override
List<XMLTransient> getTransient() {
return attributes.getTransient();
}
@Override
List<XMLVersion> getVersion() {
return attributes.getVersion();
}
@Override
List<XMLElementCollection> getElementCollection() {
return attributes.getElementCollection();
}
@Override
List<XMLEmbedded> getEmbedded() {
return attributes.getEmbedded();
}
@Override
List<XMLManyToMany> getManyToMany() {
return attributes.getManyToMany();
}
@Override
List<XMLManyToOne> getManyToOne() {
return attributes.getManyToOne();
}
@Override
List<XMLOneToMany> getOneToMany() {
return attributes.getOneToMany();
}
@Override
List<XMLOneToOne> getOneToOne() {
return attributes.getOneToOne();
}
@Override
XMLEmbeddedId getEmbeddedId() {
return attributes.getEmbeddedId();
}
}

View File

@ -0,0 +1,70 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLBasic;
/**
* @author Strong Liu
*/
class BasicMocker extends PropertyMocker {
private XMLBasic basic;
BasicMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLBasic basic) {
super( indexBuilder, classInfo, defaults );
this.basic = basic;
}
@Override
protected String getFieldName() {
return basic.getName();
}
@Override
protected void processExtra() {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.booleanValue( "optional", basic.isOptional(), annotationValueList );
MockHelper.enumValue( "fetch", FETCH_TYPE, basic.getFetch(), annotationValueList );
create( BASIC, annotationValueList );
parserColumn( basic.getColumn(), getTarget() );
parserEnumType( basic.getEnumerated(), getTarget() );
parserLob( basic.getLob(), getTarget() );
parserTemporalType( basic.getTemporal(), getTarget() );
}
@Override
protected XMLAccessType getAccessType() {
return basic.getAccess();
}
}

View File

@ -0,0 +1,199 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.xml.filter.IndexedAnnotationFilter;
/**
* @author Strong Liu
*/
class DefaultConfigurationHelper {
static DefaultConfigurationHelper INSTANCE = new DefaultConfigurationHelper();
private DefaultConfigurationHelper() {
}
void apply(Map<DotName, List<AnnotationInstance>> annotationsMap, EntityMappingsMocker.Default defaults) {
if ( annotationsMap == null || annotationsMap.isEmpty() || defaults == null ) {
return;
}
if ( MockHelper.hasSchemaOrCatalogDefined( defaults ) ) {
for ( DotName annName : IndexedAnnotationFilter.SCHEMAAWARE_ANNOTATIONS ) {
if ( annName.equals( JPADotNames.TABLE ) && !annotationsMap.containsKey( JPADotNames.TABLE ) && annotationsMap
.containsKey( JPADotNames.ENTITY ) ) {
//if an entity doesn't have a @Table, we create one here
AnnotationInstance entity = annotationsMap.get( JPADotNames.ENTITY ).get( 0 );
AnnotationInstance table = AnnotationInstance.create(
JPADotNames.TABLE, entity.target(), MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY
);
List<AnnotationInstance> tableList = new ArrayList<AnnotationInstance>( 1 );
tableList.add( table );
annotationsMap.put( JPADotNames.TABLE, tableList );
}
if ( annotationsMap.containsKey( annName ) ) {
overrideScheamCatalogByDefault( annName, annotationsMap, defaults );
}
}
}
if ( defaults.getCascadePersist() != null && defaults.getCascadePersist() ) {
for ( DotName annName : IndexedAnnotationFilter.ASSOCIATION_ANNOTATIONS ) {
if ( annotationsMap.containsKey( annName ) ) {
addCascadePersistIfNotExist( annName, annotationsMap );
}
}
}
}
private void addCascadePersistIfNotExist(DotName annName, Map<DotName, List<AnnotationInstance>> indexedAnnotationMap) {
List<AnnotationInstance> annotationInstanceList = indexedAnnotationMap.get( annName );
if ( annotationInstanceList == null || annotationInstanceList.isEmpty() ) {
return;
}
List<AnnotationInstance> newAnnotationInstanceList = new ArrayList<AnnotationInstance>( annotationInstanceList.size() );
for ( AnnotationInstance annotationInstance : annotationInstanceList ) {
AnnotationValue cascadeValue = annotationInstance.value( "cascade" );
List<AnnotationValue> newAnnotationValueList = new ArrayList<AnnotationValue>();
newAnnotationValueList.addAll( annotationInstance.values() );
if ( cascadeValue == null ) {
AnnotationValue temp = AnnotationValue.createEnumValue( "", JPADotNames.CASCADE_TYPE, "PERSIST" );
cascadeValue = AnnotationValue.createArrayValue( "cascade", new AnnotationValue[] { temp } );
}
else {
newAnnotationValueList.remove( cascadeValue );
String[] cascadeTypes = cascadeValue.asEnumArray();
boolean hasPersistDefined = false;
for ( String type : cascadeTypes ) {
if ( "PERSIST".equals( type ) ) {
hasPersistDefined = true;
break;
}
}
if ( hasPersistDefined ) {
break;
}
String[] newCascadeTypes = new String[cascadeTypes.length + 1];
newCascadeTypes[0] = "PERSIST";
System.arraycopy( cascadeTypes, 0, newCascadeTypes, 1, cascadeTypes.length );
AnnotationValue[] cascades = new AnnotationValue[newCascadeTypes.length];
for ( int i = 0; i < newCascadeTypes.length; i++ ) {
cascades[i] = AnnotationValue.createEnumValue( "", JPADotNames.CASCADE_TYPE, newCascadeTypes[i] );
}
cascadeValue = AnnotationValue.createArrayValue( "cascade", cascades );
}
newAnnotationValueList.add( cascadeValue );
AnnotationInstance newAnnotationInstance = AnnotationInstance.create(
annotationInstance.name(),
annotationInstance.target(),
MockHelper.toArray( newAnnotationValueList )
);
newAnnotationInstanceList.add( newAnnotationInstance );
}
indexedAnnotationMap.put( annName, newAnnotationInstanceList );
}
//@Table, @CollectionTable, @JoinTable, @SecondaryTable
private void overrideScheamCatalogByDefault(DotName annName, Map<DotName, List<AnnotationInstance>> indexedAnnotationMap, EntityMappingsMocker.Default defaults) {
List<AnnotationInstance> annotationInstanceList = indexedAnnotationMap.get( annName );
if ( annotationInstanceList == null || annotationInstanceList.isEmpty() ) {
return;
}
List<AnnotationInstance> newAnnotationInstanceList = new ArrayList<AnnotationInstance>( annotationInstanceList.size() );
for ( AnnotationInstance annotationInstance : annotationInstanceList ) {
if ( annName.equals( IndexedAnnotationFilter.SECONDARY_TABLES ) ) {
AnnotationInstance[] secondaryTableAnnotationInstanceArray = annotationInstance.value().asNestedArray();
AnnotationValue[] newAnnotationValueArray = new AnnotationValue[secondaryTableAnnotationInstanceArray.length];
for ( int i = 0; i < secondaryTableAnnotationInstanceArray.length; i++ ) {
newAnnotationValueArray[i] = AnnotationValue.createNestedAnnotationValue(
"", overrideScheamCatalogByDefault(
secondaryTableAnnotationInstanceArray[i],
defaults
)
);
}
AnnotationInstance secondaryTablesAnnotationInstance = AnnotationInstance.create(
annName,
annotationInstance.target(),
new AnnotationValue[] {
AnnotationValue.createArrayValue( "value", newAnnotationValueArray )
}
);
newAnnotationInstanceList.add( secondaryTablesAnnotationInstance );
}
else {
newAnnotationInstanceList.add( overrideScheamCatalogByDefault( annotationInstance, defaults ) );
}
}
indexedAnnotationMap.put( annName, newAnnotationInstanceList );
}
private AnnotationInstance overrideScheamCatalogByDefault(AnnotationInstance annotationInstance, EntityMappingsMocker.Default defaults) {
List<AnnotationValue> newAnnotationValueList = new ArrayList<AnnotationValue>();
newAnnotationValueList.addAll( annotationInstance.values() );
boolean schemaDefined = false;
boolean catalogDefined = false;
if ( annotationInstance.value( "schema" ) != null ) {
schemaDefined = true;
}
if ( annotationInstance.value( "catalog" ) != null ) {
catalogDefined = true;
}
if ( schemaDefined && catalogDefined ) {
return annotationInstance;
}
if ( !catalogDefined && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
newAnnotationValueList.add(
AnnotationValue.createStringValue(
"catalog", defaults.getCatalog()
)
);
}
if ( !schemaDefined && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
newAnnotationValueList.add(
AnnotationValue.createStringValue(
"schema", defaults.getSchema()
)
);
}
return AnnotationInstance.create(
annotationInstance.name(),
annotationInstance.target(),
MockHelper.toArray( newAnnotationValueList )
);
}
}

View File

@ -0,0 +1,87 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLElementCollection;
/**
* @author Strong Liu
*/
class ElementCollectionMocker extends PropertyMocker {
private XMLElementCollection elementCollection;
ElementCollectionMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLElementCollection elementCollection) {
super( indexBuilder, classInfo, defaults );
this.elementCollection = elementCollection;
}
@Override
protected void processExtra() {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.classValue(
"targetClass",
elementCollection.getTargetClass(),
annotationValueList,
indexBuilder.getServiceRegistry()
);
MockHelper.enumValue( "fetch", FETCH_TYPE, elementCollection.getFetch(), annotationValueList );
create( ELEMENT_COLLECTION, annotationValueList );
parserLob( elementCollection.getLob(), getTarget() );
parserEnumType( elementCollection.getEnumerated(), getTarget() );
parserColumn( elementCollection.getColumn(), getTarget() );
parserTemporalType( elementCollection.getTemporal(), getTarget() );
parserCollectionTable( elementCollection.getCollectionTable(), getTarget() );
parserAssociationOverrides( elementCollection.getAssociationOverride(), getTarget() );
parserAttributeOverrides( elementCollection.getAttributeOverride(), getTarget() );
if ( elementCollection.getOrderBy() != null ) {
create( ORDER_BY, MockHelper.stringValueArray( "value", elementCollection.getOrderBy() ) );
}
parserAttributeOverrides( elementCollection.getMapKeyAttributeOverride(), getTarget() );
parserMapKeyJoinColumnList( elementCollection.getMapKeyJoinColumn(), getTarget() );
parserMapKey( elementCollection.getMapKey(), getTarget() );
parserMapKeyColumn( elementCollection.getMapKeyColumn(), getTarget() );
parserMapKeyClass( elementCollection.getMapKeyClass(), getTarget() );
parserMapKeyEnumerated( elementCollection.getMapKeyEnumerated(), getTarget() );
parserMapKeyTemporal( elementCollection.getMapKeyTemporal(), getTarget() );
}
@Override
protected String getFieldName() {
return elementCollection.getName();
}
@Override
protected XMLAccessType getAccessType() {
return elementCollection.getAccess();
}
}

View File

@ -0,0 +1,112 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.Collections;
import java.util.List;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLBasic;
import org.hibernate.metamodel.source.annotation.xml.XMLElementCollection;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddableAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbedded;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddedId;
import org.hibernate.metamodel.source.annotation.xml.XMLId;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToMany;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToOne;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToMany;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToOne;
import org.hibernate.metamodel.source.annotation.xml.XMLTransient;
import org.hibernate.metamodel.source.annotation.xml.XMLVersion;
/**
* @author Strong Liu
*/
class EmbeddableAttributesBuilder extends AbstractAttributesBuilder {
private XMLEmbeddableAttributes attributes;
EmbeddableAttributesBuilder(IndexBuilder indexBuilder, ClassInfo classInfo, XMLAccessType accessType, EntityMappingsMocker.Default defaults, XMLEmbeddableAttributes embeddableAttributes) {
super( indexBuilder, classInfo, defaults );
this.attributes = embeddableAttributes;
}
@Override
List<XMLBasic> getBasic() {
return attributes.getBasic();
}
@Override
List<XMLId> getId() {
return Collections.emptyList();
}
@Override
List<XMLTransient> getTransient() {
return attributes.getTransient();
}
@Override
List<XMLVersion> getVersion() {
return Collections.emptyList();
}
@Override
List<XMLElementCollection> getElementCollection() {
return attributes.getElementCollection();
}
@Override
List<XMLEmbedded> getEmbedded() {
return attributes.getEmbedded();
}
@Override
List<XMLManyToMany> getManyToMany() {
return attributes.getManyToMany();
}
@Override
List<XMLManyToOne> getManyToOne() {
return attributes.getManyToOne();
}
@Override
List<XMLOneToMany> getOneToMany() {
return attributes.getOneToMany();
}
@Override
List<XMLOneToOne> getOneToOne() {
return attributes.getOneToOne();
}
@Override
XMLEmbeddedId getEmbeddedId() {
return null;
}
}

View File

@ -0,0 +1,161 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddable;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLIdClass;
import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad;
import org.hibernate.metamodel.source.annotation.xml.XMLPostPersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPostRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPostUpdate;
import org.hibernate.metamodel.source.annotation.xml.XMLPrePersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPreRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate;
/**
* Mock <embeddable> to {@link javax.persistence.Embeddable @Embeddable}
* @author Strong Liu
*/
class EmbeddableMocker extends AbstractEntityObjectMocker {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
EmbeddableMocker.class.getName()
);
private XMLEmbeddable embeddable;
EmbeddableMocker(IndexBuilder indexBuilder, XMLEmbeddable embeddable, EntityMappingsMocker.Default defaults) {
super( indexBuilder, defaults );
this.embeddable = embeddable;
}
@Override
protected AbstractAttributesBuilder getAttributesBuilder() {
if ( attributesBuilder == null ) {
attributesBuilder = new EmbeddableAttributesBuilder(
indexBuilder, classInfo, getAccessType(), getDefaults(), embeddable.getAttributes()
);
}
return attributesBuilder;
}
@Override
protected void processExtra() {
create( EMBEDDABLE );
}
@Override
protected void applyDefaults() {
String className = MockHelper.buildSafeClassName( embeddable.getClazz(), getDefaults().getPackageName() );
embeddable.setClazz( className );
if ( embeddable.isMetadataComplete() == null ) {
embeddable.setMetadataComplete( getDefaults().getMetadataComplete() );
}
if ( embeddable.getAccess() == null ) {
embeddable.setAccess( getDefaults().getAccess() );
}
LOG.debugf( "Adding XML overriding information for %s", className );
}
@Override
protected boolean isMetadataComplete() {
return embeddable.isMetadataComplete() != null && embeddable.isMetadataComplete();
}
@Override
protected boolean isExcludeDefaultListeners() {
return false;
}
@Override
protected boolean isExcludeSuperclassListeners() {
return false;
}
@Override
protected XMLIdClass getIdClass() {
return null;
}
@Override
protected XMLEntityListeners getEntityListeners() {
return null;
}
@Override
protected XMLAccessType getAccessType() {
return embeddable.getAccess();
}
@Override
protected String getClassName() {
return embeddable.getClazz();
}
@Override
protected XMLPrePersist getPrePersist() {
return null;
}
@Override
protected XMLPreRemove getPreRemove() {
return null;
}
@Override
protected XMLPreUpdate getPreUpdate() {
return null;
}
@Override
protected XMLPostPersist getPostPersist() {
return null;
}
@Override
protected XMLPostUpdate getPostUpdate() {
return null;
}
@Override
protected XMLPostRemove getPostRemove() {
return null;
}
@Override
protected XMLPostLoad getPostLoad() {
return null;
}
@Override
protected XMLAttributes getAttributes() {
return null;
}
}

View File

@ -0,0 +1,56 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddedId;
/**
* @author Strong Liu
*/
class EmbeddedIdMocker extends PropertyMocker {
private XMLEmbeddedId embeddedId;
EmbeddedIdMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLEmbeddedId embeddedId) {
super( indexBuilder, classInfo, defaults );
this.embeddedId = embeddedId;
}
@Override
protected String getFieldName() {
return embeddedId.getName();
}
@Override
protected void processExtra() {
create( EMBEDDED_ID );
}
@Override
protected XMLAccessType getAccessType() {
return embeddedId.getAccess();
}
}

View File

@ -0,0 +1,59 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbedded;
/**
* @author Strong Liu
*/
class EmbeddedMocker extends PropertyMocker {
private XMLEmbedded embedded;
EmbeddedMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLEmbedded embedded) {
super( indexBuilder, classInfo, defaults );
this.embedded = embedded;
}
@Override
protected void processExtra() {
create( EMBEDDED );
parserAttributeOverrides( embedded.getAttributeOverride(), getTarget() );
parserAssociationOverrides( embedded.getAssociationOverride(), getTarget() );
}
@Override
protected String getFieldName() {
return embedded.getName();
}
@Override
protected XMLAccessType getAccessType() {
return embedded.getAccess();
}
}

View File

@ -0,0 +1,245 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.io.Serializable;
import java.util.List;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLEmbeddable;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
import org.hibernate.metamodel.source.annotation.xml.XMLMappedSuperclass;
import org.hibernate.metamodel.source.annotation.xml.XMLPersistenceUnitDefaults;
import org.hibernate.metamodel.source.annotation.xml.XMLPersistenceUnitMetadata;
import org.hibernate.service.ServiceRegistry;
/**
* Parse all {@link XMLEntityMappings} generated from orm.xml.
*
* @author Strong Liu
*/
public class EntityMappingsMocker {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
EntityMappingsMocker.class.getName()
);
private List<XMLEntityMappings> entityMappingsList;
//todo delimited-identifier
private Default globalDefaults;
final private IndexBuilder indexBuilder;
//todo
private XMLEntityListeners defaultEntityListeners;
final private GlobalAnnotations globalAnnotations;
public EntityMappingsMocker(List<XMLEntityMappings> entityMappingsList, Index index, ServiceRegistry serviceRegistry) {
this.entityMappingsList = entityMappingsList;
this.indexBuilder = new IndexBuilder( index, serviceRegistry );
this.globalAnnotations = new GlobalAnnotations();
}
/**
* Create new {@link Index} with mocking JPA annotations from {@link XMLEntityMappings} and merge them with existing {@link Index}
*
* @return new {@link Index}
*/
public Index mockNewIndex() {
processPersistenceUnitMetadata( entityMappingsList );
processEntityMappings( entityMappingsList );
processGlobalConfiguration();
return indexBuilder.build( globalDefaults );
}
/**
* processing PersistenceUnitMetadata, there should be only one PersistenceUnitMetadata in all mapping xml files.
*/
private void processPersistenceUnitMetadata(List<XMLEntityMappings> entityMappingsList) {
for ( XMLEntityMappings entityMappings : entityMappingsList ) {
//we have to iterate entityMappingsList first to find persistence-unit-metadata
XMLPersistenceUnitMetadata pum = entityMappings.getPersistenceUnitMetadata();
if ( pum == null ) {
continue;
}
if ( globalDefaults == null ) {
globalDefaults = new Default();
globalDefaults.setMetadataComplete( pum.getXmlMappingMetadataComplete() != null );
indexBuilder.mappingMetadataComplete( globalDefaults );
XMLPersistenceUnitDefaults pud = pum.getPersistenceUnitDefaults();
if ( pud == null ) {
return;
}
globalDefaults.setSchema( pud.getSchema() );
globalDefaults.setCatalog( pud.getCatalog() );
globalDefaults.setAccess( pud.getAccess() );
globalDefaults.setCascadePersist( pud.getCascadePersist() != null );
globalDefaults.setDelimitedIdentifiers( pud.getDelimitedIdentifiers() != null );
defaultEntityListeners = pud.getEntityListeners();
}
else {
LOG.duplicateMetadata();
}
}
}
private void processEntityMappings(List<XMLEntityMappings> entityMappingsList) {
for ( XMLEntityMappings entityMappings : entityMappingsList ) {
final Default defaults = getEntityMappingsDefaults( entityMappings );
globalAnnotations.collectGlobalMappings( entityMappings, defaults );
for ( XMLMappedSuperclass mappedSuperclass : entityMappings.getMappedSuperclass() ) {
new MappedSuperclassMocker( indexBuilder, mappedSuperclass, defaults ).process();
}
for ( XMLEmbeddable embeddable : entityMappings.getEmbeddable() ) {
new EmbeddableMocker( indexBuilder, embeddable, defaults ).process();
}
for ( XMLEntity entity : entityMappings.getEntity() ) {
globalAnnotations.collectGlobalMappings( entity, defaults );
new EntityMocker( indexBuilder, entity, defaults ).process();
}
}
}
private void processGlobalConfiguration() {
if ( globalAnnotations.hasGlobalConfiguration() ) {
indexBuilder.collectGlobalConfigurationFromIndex( globalAnnotations );
new GlobalConfigurationMocker(
indexBuilder, globalAnnotations
).parser();
}
}
private Default getEntityMappingsDefaults(XMLEntityMappings entityMappings) {
Default entityMappingDefault = new Default();
entityMappingDefault.setPackageName( entityMappings.getPackage() );
entityMappingDefault.setSchema( entityMappings.getSchema() );
entityMappingDefault.setCatalog( entityMappings.getCatalog() );
entityMappingDefault.setAccess( entityMappings.getAccess() );
final Default defaults = new Default();
defaults.override( globalDefaults );
defaults.override( entityMappingDefault );
return defaults;
}
public static class Default implements Serializable {
private XMLAccessType access;
private String packageName;
private String schema;
private String catalog;
private Boolean metadataComplete;
private Boolean cascadePersist;
private Boolean delimitedIdentifier;
public XMLAccessType getAccess() {
return access;
}
void setAccess(XMLAccessType access) {
this.access = access;
}
public String getCatalog() {
return catalog;
}
void setCatalog(String catalog) {
this.catalog = catalog;
}
public String getPackageName() {
return packageName;
}
void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getSchema() {
return schema;
}
void setSchema(String schema) {
this.schema = schema;
}
public Boolean getMetadataComplete() {
return metadataComplete;
}
void setMetadataComplete(Boolean metadataComplete) {
this.metadataComplete = metadataComplete;
}
public Boolean getCascadePersist() {
return cascadePersist;
}
void setCascadePersist(Boolean cascadePersist) {
this.cascadePersist = cascadePersist;
}
void setDelimitedIdentifiers(Boolean delimitedIdentifier) {
this.delimitedIdentifier = delimitedIdentifier;
}
public Boolean getDelimitedIdentifier() {
return delimitedIdentifier;
}
void override(Default globalDefault) {
if ( globalDefault != null ) {
if ( globalDefault.getAccess() != null ) {
access = globalDefault.getAccess();
}
if ( globalDefault.getPackageName() != null ) {
packageName = globalDefault.getPackageName();
}
if ( globalDefault.getSchema() != null ) {
schema = globalDefault.getSchema();
}
if ( globalDefault.getCatalog() != null ) {
catalog = globalDefault.getCatalog();
}
if ( globalDefault.getDelimitedIdentifier() != null ) {
delimitedIdentifier = globalDefault.getDelimitedIdentifier();
}
if ( globalDefault.getMetadataComplete() != null ) {
metadataComplete = globalDefault.getMetadataComplete();
}
if ( globalDefault.getCascadePersist() != null ) {
cascadePersist = globalDefault.getCascadePersist();
}
}
}
}
}

View File

@ -0,0 +1,289 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLDiscriminatorColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLIdClass;
import org.hibernate.metamodel.source.annotation.xml.XMLInheritance;
import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad;
import org.hibernate.metamodel.source.annotation.xml.XMLPostPersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPostRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPostUpdate;
import org.hibernate.metamodel.source.annotation.xml.XMLPrePersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPreRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate;
import org.hibernate.metamodel.source.annotation.xml.XMLSecondaryTable;
import org.hibernate.metamodel.source.annotation.xml.XMLTable;
/**
* Mock <entity> to {@link javax.persistence.Entity @Entity}
*
* @author Strong Liu
*/
class EntityMocker extends AbstractEntityObjectMocker {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
EntityMocker.class.getName()
);
private XMLEntity entity;
EntityMocker(IndexBuilder indexBuilder, XMLEntity entity, EntityMappingsMocker.Default defaults) {
super( indexBuilder, defaults );
this.entity = entity;
}
@Override
protected String getClassName() {
return entity.getClazz();
}
@Override
protected void processExtra() {
//@Entity
create( ENTITY, MockHelper.stringValueArray( "name", entity.getName() ) );
if ( entity.isCacheable() != null ) {
//@Cacheable
create(
CACHEABLE,
MockHelper.booleanValueArray( "value", entity.isCacheable() )
);
}
if ( StringHelper.isNotEmpty( entity.getDiscriminatorValue() ) ) {
//@DiscriminatorValue
create(
DISCRIMINATOR_VALUE,
MockHelper.stringValueArray( "value", entity.getDiscriminatorValue() )
);
}
//@Table
parserTable( entity.getTable() );
parserInheritance( entity.getInheritance() );
parserDiscriminatorColumn( entity.getDiscriminatorColumn() );
parserAttributeOverrides( entity.getAttributeOverride(), getTarget() );
parserAssociationOverrides( entity.getAssociationOverride(), getTarget() );
parserPrimaryKeyJoinColumnList( entity.getPrimaryKeyJoinColumn(), getTarget() );
parserSecondaryTableList( entity.getSecondaryTable(), getTarget() );
}
//@Table (entity only)
private AnnotationInstance parserTable(XMLTable table) {
if ( table == null ) {
return null;
}
MockHelper.updateSchema( new SchemaAware.TableSchemaAware( table ), getDefaults() );
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", table.getName(), annotationValueList );
MockHelper.stringValue( "catalog", table.getCatalog(), annotationValueList );
MockHelper.stringValue( "schema", table.getSchema(), annotationValueList );
nestedUniqueConstraintList( "uniqueConstraints", table.getUniqueConstraint(), annotationValueList );
return create( TABLE, annotationValueList );
}
@Override
protected void applyDefaults() {
if ( getDefaults() == null ) {
return;
}
if ( MockHelper.hasSchemaOrCatalogDefined( getDefaults() ) ) {
XMLTable table = entity.getTable();
if ( table == null ) {
table = new XMLTable();
entity.setTable( table );
}
MockHelper.updateSchema( new SchemaAware.TableSchemaAware( table ), getDefaults() );
}
String className = MockHelper.buildSafeClassName( entity.getClazz(), getDefaults().getPackageName() );
entity.setClazz( className );
if ( entity.isMetadataComplete() == null ) {
entity.setMetadataComplete( getDefaults().getMetadataComplete() );
}
if ( entity.getAccess() != null ) {
entity.setAccess( getDefaults().getAccess() );
}
LOG.debugf( "Adding XML overriding information for %s", className );
}
@Override
protected XMLPrePersist getPrePersist() {
return entity.getPrePersist();
}
@Override
protected XMLPreRemove getPreRemove() {
return entity.getPreRemove();
}
@Override
protected XMLPreUpdate getPreUpdate() {
return entity.getPreUpdate();
}
@Override
protected XMLPostPersist getPostPersist() {
return entity.getPostPersist();
}
@Override
protected XMLPostUpdate getPostUpdate() {
return entity.getPostUpdate();
}
@Override
protected XMLPostRemove getPostRemove() {
return entity.getPostRemove();
}
@Override
protected XMLPostLoad getPostLoad() {
return entity.getPostLoad();
}
@Override
protected XMLAttributes getAttributes() {
return entity.getAttributes();
}
@Override
protected boolean isMetadataComplete() {
return entity.isMetadataComplete() != null && entity.isMetadataComplete();
}
@Override
protected boolean isExcludeDefaultListeners() {
return entity.getExcludeDefaultListeners() != null;
}
@Override
protected boolean isExcludeSuperclassListeners() {
return entity.getExcludeSuperclassListeners() != null;
}
@Override
protected XMLIdClass getIdClass() {
return entity.getIdClass();
}
@Override
protected XMLEntityListeners getEntityListeners() {
return entity.getEntityListeners();
}
@Override
protected XMLAccessType getAccessType() {
return entity.getAccess();
}
//@Inheritance
protected AnnotationInstance parserInheritance(XMLInheritance inheritance) {
if ( inheritance == null ) {
return null;
}
return
create(
INHERITANCE,
MockHelper.enumValueArray( "strategy", INHERITANCE_TYPE, inheritance.getStrategy() )
);
}
//@DiscriminatorColumn
protected AnnotationInstance parserDiscriminatorColumn(XMLDiscriminatorColumn discriminatorColumn) {
if ( discriminatorColumn == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", discriminatorColumn.getName(), annotationValueList );
MockHelper.stringValue(
"columnDefinition", discriminatorColumn.getColumnDefinition(), annotationValueList
);
MockHelper.integerValue( "length", discriminatorColumn.getLength(), annotationValueList );
MockHelper.enumValue(
"discriminatorType", DISCRIMINATOR_TYPE, discriminatorColumn.getDiscriminatorType(), annotationValueList
);
return
create(
DISCRIMINATOR_COLUMN, annotationValueList
);
}
//@SecondaryTable
protected AnnotationInstance parserSecondaryTable(XMLSecondaryTable secondaryTable, AnnotationTarget target) {
if ( secondaryTable == null ) {
return null;
}
MockHelper.updateSchema( new SchemaAware.SecondaryTableSchemaAware( secondaryTable ), getDefaults() );
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", secondaryTable.getName(), annotationValueList );
MockHelper.stringValue( "catalog", secondaryTable.getCatalog(), annotationValueList );
MockHelper.stringValue( "schema", secondaryTable.getSchema(), annotationValueList );
nestedPrimaryKeyJoinColumnList(
"pkJoinColumns", secondaryTable.getPrimaryKeyJoinColumn(), annotationValueList
);
nestedUniqueConstraintList(
"uniqueConstraints", secondaryTable.getUniqueConstraint(), annotationValueList
);
return
create(
SECONDARY_TABLE, target, annotationValueList
);
}
protected AnnotationInstance parserSecondaryTableList(List<XMLSecondaryTable> primaryKeyJoinColumnList, AnnotationTarget target) {
if ( MockHelper.isNotEmpty( primaryKeyJoinColumnList ) ) {
if ( primaryKeyJoinColumnList.size() == 1 ) {
return parserSecondaryTable( primaryKeyJoinColumnList.get( 0 ), target );
}
else {
return create(
SECONDARY_TABLES,
target,
nestedSecondaryTableList( "value", primaryKeyJoinColumnList, null )
);
}
}
return null;
}
protected AnnotationValue[] nestedSecondaryTableList(String name, List<XMLSecondaryTable> secondaryTableList, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( secondaryTableList ) ) {
AnnotationValue[] values = new AnnotationValue[secondaryTableList.size()];
for ( int i = 0; i < secondaryTableList.size(); i++ ) {
AnnotationInstance annotationInstance = parserSecondaryTable( secondaryTableList.get( i ), null );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull(
annotationValueList, AnnotationValue.createArrayValue( name, values )
);
return values;
}
return MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY;
}
}

View File

@ -0,0 +1,230 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
import org.hibernate.metamodel.source.annotation.xml.XMLId;
import org.hibernate.metamodel.source.annotation.xml.XMLNamedNativeQuery;
import org.hibernate.metamodel.source.annotation.xml.XMLNamedQuery;
import org.hibernate.metamodel.source.annotation.xml.XMLSequenceGenerator;
import org.hibernate.metamodel.source.annotation.xml.XMLSqlResultSetMapping;
import org.hibernate.metamodel.source.annotation.xml.XMLTableGenerator;
import org.hibernate.metamodel.source.annotations.JPADotNames;
/**
* @author Strong Liu
*/
class GlobalAnnotations implements JPADotNames {
private Map<String, XMLSequenceGenerator> sequenceGeneratorMap = new HashMap<String, XMLSequenceGenerator>();
private Map<String, XMLTableGenerator> tableGeneratorMap = new HashMap<String, XMLTableGenerator>();
private Map<String, XMLNamedQuery> namedQueryMap = new HashMap<String, XMLNamedQuery>();
private Map<String, XMLNamedNativeQuery> namedNativeQueryMap = new HashMap<String, XMLNamedNativeQuery>();
private Map<String, XMLSqlResultSetMapping> sqlResultSetMappingMap = new HashMap<String, XMLSqlResultSetMapping>();
private Map<DotName, List<AnnotationInstance>> annotationInstanceMap = new HashMap<DotName, List<AnnotationInstance>>();
private List<AnnotationInstance> indexedAnnotationInstanceList = new ArrayList<AnnotationInstance>();
Map<DotName, List<AnnotationInstance>> getAnnotationInstanceMap() {
return annotationInstanceMap;
}
AnnotationInstance push(DotName name, AnnotationInstance annotationInstance) {
if ( name == null || annotationInstance == null ) {
return null;
}
List<AnnotationInstance> list = annotationInstanceMap.get( name );
if ( list == null ) {
list = new ArrayList<AnnotationInstance>();
}
list.add( annotationInstance );
return annotationInstance;
}
void addIndexedAnnotationInstance(List<AnnotationInstance> annotationInstanceList) {
if ( MockHelper.isNotEmpty( annotationInstanceList ) ) {
indexedAnnotationInstanceList.addAll( annotationInstanceList );
}
}
/**
* do the orm xmls define global configurations?
*/
boolean hasGlobalConfiguration() {
return !( namedQueryMap.isEmpty() && namedNativeQueryMap.isEmpty() && sequenceGeneratorMap.isEmpty() && tableGeneratorMap
.isEmpty() && sqlResultSetMappingMap.isEmpty() );
}
Map<String, XMLNamedNativeQuery> getNamedNativeQueryMap() {
return namedNativeQueryMap;
}
Map<String, XMLNamedQuery> getNamedQueryMap() {
return namedQueryMap;
}
Map<String, XMLSequenceGenerator> getSequenceGeneratorMap() {
return sequenceGeneratorMap;
}
Map<String, XMLSqlResultSetMapping> getSqlResultSetMappingMap() {
return sqlResultSetMappingMap;
}
Map<String, XMLTableGenerator> getTableGeneratorMap() {
return tableGeneratorMap;
}
void put(String name, XMLNamedNativeQuery value) {
if ( value != null ) {
namedNativeQueryMap.put( name, value );
}
}
void put(String name, XMLNamedQuery value) {
if ( value != null ) {
namedQueryMap.put( name, value );
}
}
void put(String name, XMLSequenceGenerator value) {
if ( value != null ) {
sequenceGeneratorMap.put( name, value );
}
}
void put(String name, XMLTableGenerator value) {
if ( value != null ) {
tableGeneratorMap.put( name, value );
}
}
void put(String name, XMLSqlResultSetMapping value) {
if ( value != null ) {
sqlResultSetMappingMap.put( name, value );
}
}
public void filterIndexedAnnotations() {
for ( AnnotationInstance annotationInstance : indexedAnnotationInstanceList ) {
pushIfNotExist( annotationInstance );
}
}
private void pushIfNotExist(AnnotationInstance annotationInstance) {
DotName annName = annotationInstance.name();
boolean isNotExist = false;
if ( annName.equals( SQL_RESULT_SET_MAPPINGS ) ) {
AnnotationInstance[] annotationInstances = annotationInstance.value().asNestedArray();
for ( AnnotationInstance ai : annotationInstances ) {
pushIfNotExist( ai );
}
}
else {
AnnotationValue value = annotationInstance.value( "name" );
String name = value.asString();
isNotExist = ( annName.equals( TABLE_GENERATOR ) && !tableGeneratorMap.containsKey( name ) ) ||
( annName.equals( SEQUENCE_GENERATOR ) && !sequenceGeneratorMap.containsKey( name ) ) ||
( annName.equals( NAMED_QUERY ) && !namedQueryMap.containsKey( name ) ) ||
( annName.equals( NAMED_NATIVE_QUERY ) && !namedNativeQueryMap.containsKey( name ) ) ||
( annName.equals( SQL_RESULT_SET_MAPPING ) && !sqlResultSetMappingMap.containsKey( name ) );
}
if ( isNotExist ) {
push( annName, annotationInstance );
}
}
void collectGlobalMappings(XMLEntityMappings entityMappings, EntityMappingsMocker.Default defaults) {
for ( XMLSequenceGenerator generator : entityMappings.getSequenceGenerator() ) {
put( generator.getName(), overrideGenerator( generator, defaults ) );
}
for ( XMLTableGenerator generator : entityMappings.getTableGenerator() ) {
put( generator.getName(), overrideGenerator( generator, defaults ) );
}
for ( XMLNamedQuery namedQuery : entityMappings.getNamedQuery() ) {
put( namedQuery.getName(), namedQuery );
}
for ( XMLNamedNativeQuery namedNativeQuery : entityMappings.getNamedNativeQuery() ) {
put( namedNativeQuery.getName(), namedNativeQuery );
}
for ( XMLSqlResultSetMapping sqlResultSetMapping : entityMappings.getSqlResultSetMapping() ) {
put( sqlResultSetMapping.getName(), sqlResultSetMapping );
}
}
void collectGlobalMappings(XMLEntity entity, EntityMappingsMocker.Default defaults) {
for ( XMLNamedQuery namedQuery : entity.getNamedQuery() ) {
put( namedQuery.getName(), namedQuery );
}
for ( XMLNamedNativeQuery namedNativeQuery : entity.getNamedNativeQuery() ) {
put( namedNativeQuery.getName(), namedNativeQuery );
}
for ( XMLSqlResultSetMapping sqlResultSetMapping : entity.getSqlResultSetMapping() ) {
put( sqlResultSetMapping.getName(), sqlResultSetMapping );
}
XMLSequenceGenerator sequenceGenerator = entity.getSequenceGenerator();
if ( sequenceGenerator != null ) {
put( sequenceGenerator.getName(), overrideGenerator( sequenceGenerator, defaults ) );
}
XMLTableGenerator tableGenerator = entity.getTableGenerator();
if ( tableGenerator != null ) {
put( tableGenerator.getName(), overrideGenerator( tableGenerator, defaults ) );
}
XMLAttributes attributes = entity.getAttributes();
if ( attributes != null ) {
for ( XMLId id : attributes.getId() ) {
sequenceGenerator = id.getSequenceGenerator();
if ( sequenceGenerator != null ) {
put(
sequenceGenerator.getName(), overrideGenerator(
sequenceGenerator, defaults
)
);
}
tableGenerator = id.getTableGenerator();
if ( tableGenerator != null ) {
put( tableGenerator.getName(), overrideGenerator( tableGenerator, defaults ) );
}
}
}
}
/**
* Override SequenceGenerator using info definded in EntityMappings/Persistence-Metadata-Unit
*/
private static XMLSequenceGenerator overrideGenerator(XMLSequenceGenerator generator, EntityMappingsMocker.Default defaults) {
if ( StringHelper.isEmpty( generator.getSchema() ) ) {
generator.setSchema( defaults.getSchema() );
}
if ( StringHelper.isEmpty( generator.getCatalog() ) ) {
generator.setCatalog( defaults.getCatalog() );
}
return generator;
}
/**
* Override TableGenerator using info definded in EntityMappings/Persistence-Metadata-Unit
*/
private static XMLTableGenerator overrideGenerator(XMLTableGenerator generator, EntityMappingsMocker.Default defaults) {
if ( StringHelper.isEmpty( generator.getSchema() ) ) {
generator.setSchema( defaults.getSchema() );
}
if ( StringHelper.isEmpty( generator.getCatalog() ) ) {
generator.setCatalog( defaults.getCatalog() );
}
return generator;
}
}

View File

@ -0,0 +1,344 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotation.xml.XMLColumnResult;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityResult;
import org.hibernate.metamodel.source.annotation.xml.XMLFieldResult;
import org.hibernate.metamodel.source.annotation.xml.XMLNamedNativeQuery;
import org.hibernate.metamodel.source.annotation.xml.XMLNamedQuery;
import org.hibernate.metamodel.source.annotation.xml.XMLQueryHint;
import org.hibernate.metamodel.source.annotation.xml.XMLSequenceGenerator;
import org.hibernate.metamodel.source.annotation.xml.XMLSqlResultSetMapping;
import org.hibernate.metamodel.source.annotation.xml.XMLTableGenerator;
/**
* note: Global Configurations {@link org.hibernate.metamodel.source.annotations.xml.filter.IndexedAnnotationFilter.GLOBAL_ANNOTATIONS}
* in the new build Index has no target
* @author Strong Liu
*/
class GlobalConfigurationMocker extends AbstractMocker {
private GlobalAnnotations globalAnnotations;
GlobalConfigurationMocker(IndexBuilder indexBuilder, GlobalAnnotations globalAnnotations) {
super( indexBuilder );
this.globalAnnotations = globalAnnotations;
}
@Override
protected EntityMappingsMocker.Default getDefaults() {
return null;
}
@Override
protected DotName getTargetName() {
return null;
}
@Override
protected AnnotationTarget getTarget() {
return null;
}
void parser() {
if ( !globalAnnotations.getTableGeneratorMap().isEmpty() ) {
for ( XMLTableGenerator generator : globalAnnotations.getTableGeneratorMap().values() ) {
parserTableGenerator( generator );
}
}
if ( !globalAnnotations.getSequenceGeneratorMap().isEmpty() ) {
for ( XMLSequenceGenerator generator : globalAnnotations.getSequenceGeneratorMap().values() ) {
parserSequenceGenerator( generator );
}
}
if ( !globalAnnotations.getNamedQueryMap().isEmpty() ) {
Collection<XMLNamedQuery> namedQueries = globalAnnotations.getNamedQueryMap().values();
if ( namedQueries.size() > 1 ) {
parserNamedQueries( namedQueries );
}
else {
parserNamedQuery( namedQueries.iterator().next() );
}
}
if ( !globalAnnotations.getNamedNativeQueryMap().isEmpty() ) {
Collection<XMLNamedNativeQuery> namedQueries = globalAnnotations.getNamedNativeQueryMap().values();
if ( namedQueries.size() > 1 ) {
parserNamedNativeQueries( namedQueries );
}
else {
parserNamedNativeQuery( namedQueries.iterator().next() );
}
}
if ( !globalAnnotations.getSqlResultSetMappingMap().isEmpty() ) {
parserSqlResultSetMappings( globalAnnotations.getSqlResultSetMappingMap().values() );
}
indexBuilder.finishGlobalConfigurationMocking( globalAnnotations );
}
private AnnotationInstance parserSqlResultSetMappings(Collection<XMLSqlResultSetMapping> namedQueries) {
AnnotationValue[] values = new AnnotationValue[namedQueries.size()];
int i = 0;
for ( Iterator<XMLSqlResultSetMapping> iterator = namedQueries.iterator(); iterator.hasNext(); ) {
AnnotationInstance annotationInstance = parserSqlResultSetMapping( iterator.next() );
values[i++] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
return create(
SQL_RESULT_SET_MAPPINGS,
new AnnotationValue[] { AnnotationValue.createArrayValue( "values", values ) }
);
}
//@SqlResultSetMapping
private AnnotationInstance parserSqlResultSetMapping(XMLSqlResultSetMapping mapping) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", mapping.getName(), annotationValueList );
nestedEntityResultList( "entities", mapping.getEntityResult(), annotationValueList );
nestedColumnResultList( "columns", mapping.getColumnResult(), annotationValueList );
return
create(
SQL_RESULT_SET_MAPPING, annotationValueList
);
}
//@EntityResult
private AnnotationInstance parserEntityResult(XMLEntityResult result) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue(
"discriminatorColumn", result.getDiscriminatorColumn(), annotationValueList
);
nestedFieldResultList( "fields", result.getFieldResult(), annotationValueList );
MockHelper.classValue(
"entityClass", result.getEntityClass(), annotationValueList, indexBuilder.getServiceRegistry()
);
return
create(
ENTITY_RESULT, null, annotationValueList
);
}
private void nestedEntityResultList(String name, List<XMLEntityResult> entityResults, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( entityResults ) ) {
AnnotationValue[] values = new AnnotationValue[entityResults.size()];
for ( int i = 0; i < entityResults.size(); i++ ) {
AnnotationInstance annotationInstance = parserEntityResult( entityResults.get( i ) );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull( annotationValueList, AnnotationValue.createArrayValue( name, values ) );
}
}
//@ColumnResult
private AnnotationInstance parserColumnResult(XMLColumnResult result) {
return create( COLUMN_RESULT, null, MockHelper.stringValueArray( "name", result.getName() ) );
}
private void nestedColumnResultList(String name, List<XMLColumnResult> columnResults, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( columnResults ) ) {
AnnotationValue[] values = new AnnotationValue[columnResults.size()];
for ( int i = 0; i < columnResults.size(); i++ ) {
AnnotationInstance annotationInstance = parserColumnResult( columnResults.get( i ) );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull( annotationValueList, AnnotationValue.createArrayValue( name, values ) );
}
}
//@FieldResult
private AnnotationInstance parserFieldResult(XMLFieldResult result) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", result.getName(), annotationValueList );
MockHelper.stringValue( "column", result.getColumn(), annotationValueList );
return create( FIELD_RESULT, null, annotationValueList );
}
private void nestedFieldResultList(String name, List<XMLFieldResult> fieldResultList, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( fieldResultList ) ) {
AnnotationValue[] values = new AnnotationValue[fieldResultList.size()];
for ( int i = 0; i < fieldResultList.size(); i++ ) {
AnnotationInstance annotationInstance = parserFieldResult( fieldResultList.get( i ) );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull( annotationValueList, AnnotationValue.createArrayValue( name, values ) );
}
}
private AnnotationInstance parserNamedNativeQueries(Collection<XMLNamedNativeQuery> namedQueries) {
AnnotationValue[] values = new AnnotationValue[namedQueries.size()];
int i = 0;
for ( Iterator<XMLNamedNativeQuery> iterator = namedQueries.iterator(); iterator.hasNext(); ) {
AnnotationInstance annotationInstance = parserNamedNativeQuery( iterator.next() );
values[i++] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
return create(
NAMED_NATIVE_QUERIES,
new AnnotationValue[] { AnnotationValue.createArrayValue( "values", values ) }
);
}
//@NamedNativeQuery
private AnnotationInstance parserNamedNativeQuery(XMLNamedNativeQuery namedNativeQuery) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", namedNativeQuery.getName(), annotationValueList );
MockHelper.stringValue( "query", namedNativeQuery.getQuery(), annotationValueList );
MockHelper.stringValue(
"resultSetMapping", namedNativeQuery.getResultSetMapping(), annotationValueList
);
MockHelper.classValue(
"resultClass", namedNativeQuery.getResultClass(), annotationValueList, indexBuilder.getServiceRegistry()
);
nestedQueryHintList( "hints", namedNativeQuery.getHint(), annotationValueList );
return
create(
NAMED_NATIVE_QUERY, annotationValueList
);
}
private AnnotationInstance parserNamedQueries(Collection<XMLNamedQuery> namedQueries) {
AnnotationValue[] values = new AnnotationValue[namedQueries.size()];
int i = 0;
for ( Iterator<XMLNamedQuery> iterator = namedQueries.iterator(); iterator.hasNext(); ) {
AnnotationInstance annotationInstance = parserNamedQuery( iterator.next() );
values[i++] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
return create(
NAMED_QUERIES,
new AnnotationValue[] { AnnotationValue.createArrayValue( "values", values ) }
);
}
//@NamedQuery
private AnnotationInstance parserNamedQuery(XMLNamedQuery namedQuery) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", namedQuery.getName(), annotationValueList );
MockHelper.stringValue( "query", namedQuery.getQuery(), annotationValueList );
MockHelper.enumValue( "lockMode", LOCK_MODE_TYPE, namedQuery.getLockMode(), annotationValueList );
nestedQueryHintList( "hints", namedQuery.getHint(), annotationValueList );
return create( NAMED_QUERY, annotationValueList );
}
//@QueryHint
private AnnotationInstance parserQueryHint(XMLQueryHint queryHint) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", queryHint.getName(), annotationValueList );
MockHelper.stringValue( "value", queryHint.getValue(), annotationValueList );
return create( QUERY_HINT, null, annotationValueList );
}
private void nestedQueryHintList(String name, List<XMLQueryHint> constraints, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( constraints ) ) {
AnnotationValue[] values = new AnnotationValue[constraints.size()];
for ( int i = 0; i < constraints.size(); i++ ) {
AnnotationInstance annotationInstance = parserQueryHint( constraints.get( i ) );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull( annotationValueList, AnnotationValue.createArrayValue( name, values ) );
}
}
//@SequenceGenerator
private AnnotationInstance parserSequenceGenerator(XMLSequenceGenerator generator) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", generator.getName(), annotationValueList );
MockHelper.stringValue( "catalog", generator.getCatalog(), annotationValueList );
MockHelper.stringValue( "schema", generator.getSchema(), annotationValueList );
MockHelper.stringValue( "sequenceName", generator.getSequenceName(), annotationValueList );
MockHelper.integerValue( "initialValue", generator.getInitialValue(), annotationValueList );
MockHelper.integerValue( "allocationSize", generator.getAllocationSize(), annotationValueList );
return
create(
SEQUENCE_GENERATOR, annotationValueList
);
}
//@TableGenerator
private AnnotationInstance parserTableGenerator(XMLTableGenerator generator) {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", generator.getName(), annotationValueList );
MockHelper.stringValue( "catalog", generator.getCatalog(), annotationValueList );
MockHelper.stringValue( "schema", generator.getSchema(), annotationValueList );
MockHelper.stringValue( "table", generator.getTable(), annotationValueList );
MockHelper.stringValue( "pkColumnName", generator.getPkColumnName(), annotationValueList );
MockHelper.stringValue( "valueColumnName", generator.getValueColumnName(), annotationValueList );
MockHelper.stringValue( "pkColumnValue", generator.getPkColumnValue(), annotationValueList );
MockHelper.integerValue( "initialValue", generator.getInitialValue(), annotationValueList );
MockHelper.integerValue( "allocationSize", generator.getAllocationSize(), annotationValueList );
nestedUniqueConstraintList( "uniqueConstraints", generator.getUniqueConstraint(), annotationValueList );
return
create(
TABLE_GENERATOR, annotationValueList
);
}
@Override
protected AnnotationInstance push(AnnotationInstance annotationInstance) {
return globalAnnotations.push( annotationInstance.name(), annotationInstance );
}
@Override
protected AnnotationInstance create(DotName name, AnnotationTarget target, AnnotationValue[] annotationValues) {
AnnotationInstance annotationInstance = MockHelper.create( name, target, annotationValues );
return push( annotationInstance );
}
}

View File

@ -0,0 +1,81 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLGeneratedValue;
import org.hibernate.metamodel.source.annotation.xml.XMLId;
/**
* @author Strong Liu
*/
class IdMocker extends PropertyMocker {
private XMLId id;
IdMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLId id) {
super( indexBuilder, classInfo, defaults );
this.id = id;
}
@Override
protected void processExtra() {
create( ID );
parserColumn( id.getColumn(), getTarget() );
parserGeneratedValue( id.getGeneratedValue(), getTarget() );
parserTemporalType( id.getTemporal(), getTarget() );
}
private AnnotationInstance parserGeneratedValue(XMLGeneratedValue generatedValue, AnnotationTarget target) {
if ( generatedValue == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "generator", generatedValue.getGenerator(), annotationValueList );
MockHelper.enumValue(
"strategy", GENERATION_TYPE, generatedValue.getStrategy(), annotationValueList
);
return create( GENERATED_VALUE, target, annotationValueList );
}
@Override
protected String getFieldName() {
return id.getName();
}
@Override
protected XMLAccessType getAccessType() {
return id.getAccess();
}
}

View File

@ -0,0 +1,298 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotations.xml.filter.IndexedAnnotationFilter;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
* @author Strong Liu
*/
public class IndexBuilder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
IndexBuilder.class.getName()
);
private Map<DotName, List<AnnotationInstance>> annotations;
private Map<DotName, List<ClassInfo>> subclasses;
private Map<DotName, List<ClassInfo>> implementors;
private Map<DotName, ClassInfo> classes;
private Index index;
private Map<DotName, Map<DotName, List<AnnotationInstance>>> classInfoAnnotationsMap;
private Map<DotName, Map<DotName, List<AnnotationInstance>>> indexedClassInfoAnnotationsMap;
private ServiceRegistry serviceRegistry;
IndexBuilder(Index index, ServiceRegistry serviceRegistry) {
this.index = index;
this.serviceRegistry = serviceRegistry;
this.annotations = new HashMap<DotName, List<AnnotationInstance>>();
this.subclasses = new HashMap<DotName, List<ClassInfo>>();
this.implementors = new HashMap<DotName, List<ClassInfo>>();
this.classes = new HashMap<DotName, ClassInfo>();
this.classInfoAnnotationsMap = new HashMap<DotName, Map<DotName, List<AnnotationInstance>>>();
this.indexedClassInfoAnnotationsMap = new HashMap<DotName, Map<DotName, List<AnnotationInstance>>>();
}
Index build(EntityMappingsMocker.Default globalDefaults) {
if ( !classInfoAnnotationsMap.isEmpty() ) {
throw new AssertionFailure( "IndexBuilder.finishEntityObject must be called after processing each entity." );
}
//merge annotations that not overrided by xml into the new Index
for ( ClassInfo ci : index.getKnownClasses() ) {
DotName name = ci.name();
// annotations classes NOT overrided by xml
if ( !indexedClassInfoAnnotationsMap.containsKey( name ) ) {
if ( ci.annotations() != null && !ci.annotations().isEmpty() ) {
Map<DotName, List<AnnotationInstance>> tmp = new HashMap<DotName, List<AnnotationInstance>>( ci.annotations() );
DefaultConfigurationHelper.INSTANCE.apply( tmp, globalDefaults );
mergeAnnotationMap( tmp, annotations );
tmp.clear();
classes.put( name, ci );
if ( ci.superName() != null ) {
addSubClasses( ci.superName(), ci );
}
if ( ci.interfaces() != null && ci.interfaces().length > 0 ) {
addImplementors( ci.interfaces(), ci );
}
}
}
}
Index newIndex = Index.create(
annotations, subclasses, implementors, classes
);
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Annotations from new build Index:" );
newIndex.printAnnotations();
}
return newIndex;
}
void mappingMetadataComplete(EntityMappingsMocker.Default globalDefaults) {
if ( globalDefaults != null && globalDefaults.getMetadataComplete() != null && globalDefaults.getMetadataComplete() ) {
LOG.debug(
"xml-mapping-metadata-complete is specified in persistence-unit-metadata, ignore JPA annotations."
);
index = Index.create(
new HashMap<DotName, List<AnnotationInstance>>(),
new HashMap<DotName, List<ClassInfo>>(),
new HashMap<DotName, List<ClassInfo>>(),
new HashMap<DotName, ClassInfo>()
);
}
}
/**
* @param name Entity Object dot name which is being process.
* @param metadataComplete True Entity Object defined in orm.xml is supposed to override annotations.
*/
void metadataComplete(DotName name, boolean metadataComplete) {
if ( metadataComplete ) {
getIndexedAnnotations( name ).clear();
}
}
public Map<DotName, List<AnnotationInstance>> getIndexedAnnotations(DotName name) {
Map<DotName, List<AnnotationInstance>> map = indexedClassInfoAnnotationsMap.get( name );
if ( map == null ) {
ClassInfo ci = index.getClassByName( name );
if ( ci == null || ci.annotations() == null ) {
map = Collections.emptyMap();
}
else {
map = new HashMap<DotName, List<AnnotationInstance>>( ci.annotations() );
//here we ignore global annotations
for ( DotName globalAnnotationName : IndexedAnnotationFilter.GLOBAL_ANNOTATIONS ) {
if ( map.containsKey( globalAnnotationName ) ) {
map.put( globalAnnotationName, Collections.<AnnotationInstance>emptyList() );
}
}
}
indexedClassInfoAnnotationsMap.put( name, map );
}
return map;
}
void collectGlobalConfigurationFromIndex(GlobalAnnotations globalAnnotations) {
for ( DotName annName : IndexedAnnotationFilter.GLOBAL_ANNOTATIONS ) {
List<AnnotationInstance> annotationInstanceList = index.getAnnotations( annName );
if ( MockHelper.isNotEmpty( annotationInstanceList ) ) {
globalAnnotations.addIndexedAnnotationInstance( annotationInstanceList );
}
}
globalAnnotations.filterIndexedAnnotations();
}
void finishGlobalConfigurationMocking(GlobalAnnotations globalAnnotations) {
annotations.putAll( globalAnnotations.getAnnotationInstanceMap() );
}
void finishEntityObject(final DotName name, final EntityMappingsMocker.Default defaults) {
// annotations classes overrided by xml
if ( indexedClassInfoAnnotationsMap.containsKey( name ) ) {
Map<DotName, List<AnnotationInstance>> tmp = getIndexedAnnotations( name );
DefaultConfigurationHelper.INSTANCE.apply( tmp, defaults );
mergeAnnotationMap( tmp, classInfoAnnotationsMap.get( name ) );
tmp.clear();
}
Map<DotName, List<AnnotationInstance>> map = classInfoAnnotationsMap.remove( name );
if ( map == null ) {
throw new AssertionFailure( "Calling finish entity object " + name.toString() + " before create it." );
}
mergeAnnotationMap( map, annotations );
}
void addAnnotationInstance(DotName targetClassName, AnnotationInstance annotationInstance) {
if ( annotationInstance == null ) {
return;
}
for ( IndexedAnnotationFilter indexedAnnotationFilter : IndexedAnnotationFilter.filters ) {
indexedAnnotationFilter.beforePush( this, targetClassName, annotationInstance );
}
Map<DotName, List<AnnotationInstance>> map = classInfoAnnotationsMap.get( targetClassName );
if ( map == null ) {
throw new AssertionFailure( "Can't find " + targetClassName + " in internal cache, should call createClassInfo first" );
}
List<AnnotationInstance> annotationInstanceList = map.get( annotationInstance.name() );
if ( annotationInstanceList == null ) {
annotationInstanceList = new ArrayList<AnnotationInstance>();
map.put( annotationInstance.name(), annotationInstanceList );
}
annotationInstanceList.add( annotationInstance );
}
ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
ClassInfo createClassInfo(String className) {
if ( StringHelper.isEmpty( className ) ) {
throw new AssertionFailure( "Class Name used to create ClassInfo is empty." );
}
DotName classDotName = DotName.createSimple( className );
if ( classes.containsKey( classDotName ) ) {
LOG.warnf(
"Class %s has already been processed by IndexBuilder, ignoring this call and return previous created ClassInfo object"
);
return classes.get( classDotName );
}
Class clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( className );
DotName superName = null;
DotName[] interfaces = null;
short access_flag;
ClassInfo annClassInfo = index.getClassByName( classDotName );
if ( annClassInfo != null ) {
superName = annClassInfo.superName();
interfaces = annClassInfo.interfaces();
access_flag = annClassInfo.flags();
}
else {
Class superClass = clazz.getSuperclass();
if ( superClass != null ) {
superName = DotName.createSimple( superClass.getName() );
}
Class[] classInterfaces = clazz.getInterfaces();
if ( classInterfaces != null && classInterfaces.length > 0 ) {
interfaces = new DotName[classInterfaces.length];
for ( int i = 0; i < classInterfaces.length; i++ ) {
interfaces[i] = DotName.createSimple( classInterfaces[i].getName() );
}
}
//todo how to get access_flag from a Class?
access_flag = 0x0001;
}
Map<DotName, List<AnnotationInstance>> map = new HashMap<DotName, List<AnnotationInstance>>();
classInfoAnnotationsMap.put( classDotName, map );
ClassInfo classInfo = ClassInfo.create(
classDotName, superName, access_flag, interfaces, map
);
classes.put( classDotName, classInfo );
addSubClasses( superName, classInfo );
addImplementors( interfaces, classInfo );
return classInfo;
}
private void addSubClasses(DotName superClassDotName, ClassInfo classInfo) {
if ( superClassDotName != null ) {
List<ClassInfo> classInfoList = subclasses.get( superClassDotName );
if ( classInfoList == null ) {
classInfoList = new ArrayList<ClassInfo>();
subclasses.put( superClassDotName, classInfoList );
}
classInfoList.add( classInfo );
}
}
private void addImplementors(DotName[] dotNames, ClassInfo classInfo) {
if ( dotNames != null && dotNames.length > 0 ) {
for ( DotName dotName : dotNames ) {
List<ClassInfo> classInfoList = implementors.get( dotName );
if ( classInfoList == null ) {
classInfoList = new ArrayList<ClassInfo>();
implementors.put( dotName, classInfoList );
}
classInfoList.add( classInfo );
}
}
}
//merge source into target
private void mergeAnnotationMap(Map<DotName, List<AnnotationInstance>> source, Map<DotName, List<AnnotationInstance>> target) {
if ( source != null && !source.isEmpty() ) {
for ( DotName annotationName : source.keySet() ) {
if ( source.get( annotationName ).isEmpty() ) {
continue;
}
List<AnnotationInstance> annotationInstanceList = target.get( annotationName );
if ( annotationInstanceList == null ) {
annotationInstanceList = new ArrayList<AnnotationInstance>();
target.put( annotationName, annotationInstanceList );
}
annotationInstanceList.addAll( source.get( annotationName ) );
}
}
}
}

View File

@ -0,0 +1,163 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListener;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad;
import org.hibernate.metamodel.source.annotation.xml.XMLPostPersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPostRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPostUpdate;
import org.hibernate.metamodel.source.annotation.xml.XMLPrePersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPreRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate;
/**
* @author Strong Liu
*/
class ListenerMocker extends AbstractMocker {
private ClassInfo classInfo;
ListenerMocker(IndexBuilder indexBuilder, ClassInfo classInfo) {
super( indexBuilder );
this.classInfo = classInfo;
}
//@EntityListeners
AnnotationInstance parser(XMLEntityListeners entityListeners) {
if ( entityListeners == null ) {
return null;
}
//class array value
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
List<String> clazzNameList = new ArrayList<String>();
for ( XMLEntityListener listener : entityListeners.getEntityListener() ) {
MockHelper.addToCollectionIfNotNull( clazzNameList, listener.getClazz() );
parser( listener );
}
MockHelper.classArrayValue( "value", clazzNameList, annotationValueList,indexBuilder.getServiceRegistry() );
return create( ENTITY_LISTENERS, annotationValueList );
}
private void parser(XMLEntityListener listener) {
String clazz = listener.getClazz();
ClassInfo tempClassInfo = indexBuilder.createClassInfo( clazz );
ListenerMocker builder = new ListenerMocker( indexBuilder, tempClassInfo );
builder.parser( listener.getPostLoad() );
builder.parser( listener.getPostPersist() );
builder.parser( listener.getPostRemove() );
builder.parser( listener.getPostUpdate() );
builder.parser( listener.getPrePersist() );
builder.parser( listener.getPreRemove() );
builder.parser( listener.getPreUpdate() );
indexBuilder.finishEntityObject( tempClassInfo.name(),null );
}
//@PrePersist
AnnotationInstance parser(XMLPrePersist callback) {
if ( callback == null ) {
return null;
}
return create( PRE_PERSIST, getTarget( callback.getMethodName() ) );
}
//@PreRemove
AnnotationInstance parser(XMLPreRemove callback) {
if ( callback == null ) {
return null;
}
return create( PRE_REMOVE, getTarget( callback.getMethodName() ) );
}
//@PreUpdate
AnnotationInstance parser(XMLPreUpdate callback) {
if ( callback == null ) {
return null;
}
return create( PRE_UPDATE, getTarget( callback.getMethodName() ) );
}
//@PostPersist
AnnotationInstance parser(XMLPostPersist callback) {
if ( callback == null ) {
return null;
}
return create( POST_PERSIST, getTarget( callback.getMethodName() ) );
}
//@PostUpdate
AnnotationInstance parser(XMLPostUpdate callback) {
if ( callback == null ) {
return null;
}
return create( POST_UPDATE, getTarget( callback.getMethodName() ) );
}
//@PostRemove
AnnotationInstance parser(XMLPostRemove callback) {
if ( callback == null ) {
return null;
}
return create( POST_REMOVE, getTarget( callback.getMethodName() ) );
}
//@PostLoad
AnnotationInstance parser(XMLPostLoad callback) {
if ( callback == null ) {
return null;
}
return create( POST_LOAD, getTarget( callback.getMethodName() ) );
}
private AnnotationTarget getTarget(String methodName) {
return MockHelper.getTarget(
indexBuilder.getServiceRegistry(), classInfo, methodName, MockHelper.TargetType.METHOD
);
}
@Override
protected EntityMappingsMocker.Default getDefaults() {
return null;
}
@Override
protected DotName getTargetName() {
return classInfo.name();
}
@Override
protected AnnotationTarget getTarget() {
return classInfo;
}
}

View File

@ -0,0 +1,79 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToMany;
/**
* @author Strong Liu
*/
class ManyToManyMocker extends PropertyMocker {
private XMLManyToMany manyToMany;
ManyToManyMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLManyToMany manyToMany) {
super( indexBuilder, classInfo, defaults );
this.manyToMany = manyToMany;
}
@Override
protected String getFieldName() {
return manyToMany.getName();
}
@Override
protected void processExtra() {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.classValue(
"targetEntity", manyToMany.getTargetEntity(), annotationValueList, indexBuilder.getServiceRegistry()
);
MockHelper.enumValue( "fetch", FETCH_TYPE, manyToMany.getFetch(), annotationValueList );
MockHelper.stringValue( "mappedBy", manyToMany.getMappedBy(), annotationValueList );
MockHelper.cascadeValue( "cascade", manyToMany.getCascade(), isDefaultCascadePersist(), annotationValueList );
create( MANY_TO_MANY, annotationValueList );
parserMapKeyClass( manyToMany.getMapKeyClass(), getTarget() );
parserMapKeyTemporal( manyToMany.getMapKeyTemporal(), getTarget() );
parserMapKeyEnumerated( manyToMany.getMapKeyEnumerated(), getTarget() );
parserMapKey( manyToMany.getMapKey(), getTarget() );
parserAttributeOverrides( manyToMany.getMapKeyAttributeOverride(),getTarget() );
parserMapKeyJoinColumnList( manyToMany.getMapKeyJoinColumn(),getTarget() );
parserOrderColumn( manyToMany.getOrderColumn(), getTarget() );
parserJoinTable( manyToMany.getJoinTable(), getTarget() );
if ( manyToMany.getOrderBy() != null ) {
create( ORDER_BY, MockHelper.stringValueArray( "value", manyToMany.getOrderBy() ) );
}
}
@Override
protected XMLAccessType getAccessType() {
return manyToMany.getAccess();
}
}

View File

@ -0,0 +1,76 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLManyToOne;
/**
* @author Strong Liu
*/
class ManyToOneMocker extends PropertyMocker {
private XMLManyToOne manyToOne;
ManyToOneMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLManyToOne manyToOne) {
super( indexBuilder, classInfo, defaults );
this.manyToOne = manyToOne;
}
@Override
protected String getFieldName() {
return manyToOne.getName();
}
@Override
protected void processExtra() {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.classValue(
"targetEntity", manyToOne.getTargetEntity(), annotationValueList, indexBuilder.getServiceRegistry()
);
MockHelper.enumValue( "fetch", FETCH_TYPE, manyToOne.getFetch(), annotationValueList );
MockHelper.booleanValue( "optional", manyToOne.isOptional(), annotationValueList );
MockHelper.cascadeValue( "cascade", manyToOne.getCascade(), isDefaultCascadePersist(), annotationValueList );
create( MANY_TO_ONE, annotationValueList );
parserJoinColumnList( manyToOne.getJoinColumn(), getTarget() );
parserJoinTable( manyToOne.getJoinTable(), getTarget() );
if ( manyToOne.getMapsId() != null ) {
create( MAPS_ID, MockHelper.stringValueArray( "value", manyToOne.getMapsId() ) );
}
if ( manyToOne.isId() != null && manyToOne.isId() ) {
create( ID );
}
}
@Override
protected XMLAccessType getAccessType() {
return manyToOne.getAccess();
}
}

View File

@ -0,0 +1,150 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.logging.Logger;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityListeners;
import org.hibernate.metamodel.source.annotation.xml.XMLIdClass;
import org.hibernate.metamodel.source.annotation.xml.XMLMappedSuperclass;
import org.hibernate.metamodel.source.annotation.xml.XMLPostLoad;
import org.hibernate.metamodel.source.annotation.xml.XMLPostPersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPostRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPostUpdate;
import org.hibernate.metamodel.source.annotation.xml.XMLPrePersist;
import org.hibernate.metamodel.source.annotation.xml.XMLPreRemove;
import org.hibernate.metamodel.source.annotation.xml.XMLPreUpdate;
/**
* Mock <mapped-superclass> to {@link javax.persistence.MappedSuperclass @MappedSuperClass}
* @author Strong Liu
*/
class MappedSuperclassMocker extends AbstractEntityObjectMocker {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
MappedSuperclassMocker.class.getName()
);
private XMLMappedSuperclass mappedSuperclass;
MappedSuperclassMocker(IndexBuilder indexBuilder, XMLMappedSuperclass mappedSuperclass, EntityMappingsMocker.Default defaults) {
super( indexBuilder, defaults );
this.mappedSuperclass = mappedSuperclass;
}
@Override
protected void applyDefaults() {
String className = MockHelper.buildSafeClassName( mappedSuperclass.getClazz(), getDefaults().getPackageName() );
mappedSuperclass.setClazz( className );
if ( mappedSuperclass.isMetadataComplete() == null ) {
mappedSuperclass.setMetadataComplete( getDefaults().getMetadataComplete() );
}
if ( mappedSuperclass.getAccess() == null ) {
mappedSuperclass.setAccess( getDefaults().getAccess() );
}
LOG.debugf( "Adding XML overriding information for %s", className );
}
@Override
protected void processExtra() {
create( MAPPED_SUPERCLASS );
}
@Override
protected XMLAttributes getAttributes() {
return mappedSuperclass.getAttributes();
}
@Override
protected XMLAccessType getAccessType() {
return mappedSuperclass.getAccess();
}
@Override
protected boolean isMetadataComplete() {
return mappedSuperclass.isMetadataComplete() != null && mappedSuperclass.isMetadataComplete();
}
@Override
protected boolean isExcludeDefaultListeners() {
return mappedSuperclass.getExcludeDefaultListeners() != null;
}
@Override
protected boolean isExcludeSuperclassListeners() {
return mappedSuperclass.getExcludeSuperclassListeners() != null;
}
@Override
protected XMLIdClass getIdClass() {
return mappedSuperclass.getIdClass();
}
@Override
protected XMLEntityListeners getEntityListeners() {
return mappedSuperclass.getEntityListeners();
}
protected String getClassName() {
return mappedSuperclass.getClazz();
}
@Override
protected XMLPrePersist getPrePersist() {
return mappedSuperclass.getPrePersist();
}
@Override
protected XMLPreRemove getPreRemove() {
return mappedSuperclass.getPreRemove();
}
@Override
protected XMLPreUpdate getPreUpdate() {
return mappedSuperclass.getPreUpdate();
}
@Override
protected XMLPostPersist getPostPersist() {
return mappedSuperclass.getPostPersist();
}
@Override
protected XMLPostUpdate getPostUpdate() {
return mappedSuperclass.getPostUpdate();
}
@Override
protected XMLPostRemove getPostRemove() {
return mappedSuperclass.getPostRemove();
}
@Override
protected XMLPostLoad getPostLoad() {
return mappedSuperclass.getPostLoad();
}
}

View File

@ -0,0 +1,492 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.hibernate.HibernateException;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotation.xml.XMLCascadeType;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
* @author Strong Liu
*/
public class MockHelper {
static final AnnotationValue[] EMPTY_ANNOTATION_VALUE_ARRAY = new AnnotationValue[0];
static final Type[] EMPTY_TYPE_ARRAY = new Type[0];
/**
* util method for String Array attribute Annotation
*
* @param name
* @param values
* @param annotationValueList
*/
static void stringArrayValue(String name, List<String> values, List<AnnotationValue> annotationValueList) {
if ( isNotEmpty( values ) ) {
AnnotationValue[] annotationValues = new AnnotationValue[values.size()];
for ( int j = 0; j < values.size(); j++ ) {
annotationValues[j] = stringValue( "", values.get( j ) );
}
annotationValueList.add(
AnnotationValue.createArrayValue(
name, annotationValues
)
);
}
}
/**
* util method for single string attribute Annotation only
*/
static AnnotationValue[] stringValueArray(String name, String value) {
return nullSafe( stringValue( name, value ) );
}
private static AnnotationValue stringValue(String name, String value) {
if ( StringHelper.isNotEmpty( value ) ) {
return AnnotationValue.createStringValue( name, value );
}
return null;
}
static void stringValue(String name, String value, List<AnnotationValue> annotationValueList) {
addToCollectionIfNotNull( annotationValueList, stringValue( name, value ) );
}
private static AnnotationValue integerValue(String name, Integer value) {
if ( value == null ) {
return null;
}
return AnnotationValue.createIntegerValue( name, value );
}
static void integerValue(String name, Integer value, List<AnnotationValue> annotationValueList) {
addToCollectionIfNotNull( annotationValueList, integerValue( name, value ) );
}
static AnnotationValue[] booleanValueArray(String name, Boolean value) {
return nullSafe( booleanValue( name, value ) );
}
static void booleanValue(String name, Boolean value, List<AnnotationValue> annotationValueList) {
addToCollectionIfNotNull( annotationValueList, booleanValue( name, value ) );
}
private static AnnotationValue booleanValue(String name, Boolean value) {
if ( value == null ) {
return null;
}
return AnnotationValue.createBooleanValue( name, value );
}
private static AnnotationValue classValue(String name, String className, ServiceRegistry serviceRegistry) {
if ( StringHelper.isNotEmpty( className ) ) {
return AnnotationValue.createClassValue( name, getType( className, serviceRegistry ) );
}
return null;
}
static void classValue(String name, String className, List<AnnotationValue> list, ServiceRegistry serviceRegistry) {
addToCollectionIfNotNull( list, classValue( name, className, serviceRegistry ) );
}
static AnnotationValue[] classValueArray(String name, String className, ServiceRegistry serviceRegistry) {
return nullSafe( classValue( name, className, serviceRegistry ) );
}
static AnnotationValue nestedAnnotationValue(String name, AnnotationInstance value) {
if ( value == null ) {
return null;
}
return AnnotationValue.createNestedAnnotationValue(
name, value
);
}
static void nestedAnnotationValue(String name, AnnotationInstance value, List<AnnotationValue> list) {
addToCollectionIfNotNull( list, nestedAnnotationValue( name, value ) );
}
private static AnnotationValue[] nullSafe(AnnotationValue value) {
return value == null ? EMPTY_ANNOTATION_VALUE_ARRAY : new AnnotationValue[] {
value
};
}
static void classArrayValue(String name, List<String> classNameList, List<AnnotationValue> list, ServiceRegistry serviceRegistry) {
if ( isNotEmpty( classNameList ) ) {
List<AnnotationValue> clazzValueList = new ArrayList<AnnotationValue>( classNameList.size() );
for ( String clazz : classNameList ) {
addToCollectionIfNotNull( clazzValueList, classValue( "", clazz, serviceRegistry ) );
}
list.add(
AnnotationValue.createArrayValue(
name, toArray( clazzValueList )
)
);
}
}
public static AnnotationValue[] toArray(List<AnnotationValue> list) {
AnnotationValue[] values = EMPTY_ANNOTATION_VALUE_ARRAY;
if ( isNotEmpty( list ) ) {
values = list.toArray( new AnnotationValue[list.size()] );
}
return values;
}
private static AnnotationValue enumValue(String name, DotName typeName, Enum value) {
if ( value != null && StringHelper.isNotEmpty( value.toString() ) ) {
return AnnotationValue.createEnumValue( name, typeName, value.toString() );
}
return null;
}
static void cascadeValue(String name, XMLCascadeType cascadeType, boolean isCascadePersistDefault, List<AnnotationValue> annotationValueList) {
List<Enum> enumList = new ArrayList<Enum>();
if ( isCascadePersistDefault ) {
enumList.add( javax.persistence.CascadeType.PERSIST );
}
if ( cascadeType != null ) {
if ( cascadeType.getCascadeAll() != null ) {
enumList.add( javax.persistence.CascadeType.ALL );
}
if ( cascadeType.getCascadePersist() != null && !isCascadePersistDefault ) {
enumList.add( javax.persistence.CascadeType.PERSIST );
}
if ( cascadeType.getCascadeMerge() != null ) {
enumList.add( javax.persistence.CascadeType.MERGE );
}
if ( cascadeType.getCascadeRemove() != null ) {
enumList.add( javax.persistence.CascadeType.REMOVE );
}
if ( cascadeType.getCascadeRefresh() != null ) {
enumList.add( javax.persistence.CascadeType.REFRESH );
}
if ( cascadeType.getCascadeDetach() != null ) {
enumList.add( javax.persistence.CascadeType.DETACH );
}
}
if ( !enumList.isEmpty() ) {
MockHelper.enumArrayValue( name, JPADotNames.CASCADE_TYPE, enumList, annotationValueList );
}
}
static void enumArrayValue(String name, DotName typeName, List<Enum> valueList, List<AnnotationValue> list) {
if ( isNotEmpty( valueList ) ) {
List<AnnotationValue> enumValueList = new ArrayList<AnnotationValue>( valueList.size() );
for ( Enum e : valueList ) {
addToCollectionIfNotNull( enumValueList, enumValue( "", typeName, e ) );
}
list.add(
AnnotationValue.createArrayValue(
name, toArray( enumValueList )
)
);
}
}
static void enumValue(String name, DotName typeName, Enum value, List<AnnotationValue> list) {
addToCollectionIfNotNull( list, enumValue( name, typeName, value ) );
}
static AnnotationValue[] enumValueArray(String name, DotName typeName, Enum value) {
return nullSafe( enumValue( name, typeName, value ) );
}
public static void addToCollectionIfNotNull(Collection collection, Object value) {
if ( value != null && collection != null ) {
collection.add( value );
}
}
public static boolean hasSchemaOrCatalogDefined(EntityMappingsMocker.Default defaults) {
if ( defaults == null ) {
return false;
}
return StringHelper.isNotEmpty( defaults.getSchema() ) || StringHelper.isNotEmpty( defaults.getCatalog() );
}
public static void updateSchema(SchemaAware schemaAware, EntityMappingsMocker.Default defaults) {
if ( hasSchemaOrCatalogDefined( defaults ) ) {
if ( StringHelper.isEmpty( schemaAware.getSchema() ) ) {
schemaAware.setSchema( defaults.getSchema() );
}
if ( StringHelper.isEmpty( schemaAware.getCatalog() ) ) {
schemaAware.setCatalog( defaults.getCatalog() );
}
}
}
/**
* @param t1 can't be null
* @param t2 can't be null
* @param ignoreAccess true t1 and t2 can't be ClassInfo
*/
public static boolean targetEquals(AnnotationTarget t1, AnnotationTarget t2, boolean ignoreAccess) {
if ( t1 == t2 ) {
return true;
}
if ( t1.getClass() == t2.getClass() ) {
if ( t1.getClass() == ClassInfo.class ) {
return ( (ClassInfo) t1 ).name().equals( ( (ClassInfo) t2 ).name() );
}
else if ( t1.getClass() == MethodInfo.class ) {
return ( (MethodInfo) t1 ).name().equals( ( (MethodInfo) t2 ).name() );
}
else {
return ( (FieldInfo) t1 ).name().equals( ( (FieldInfo) t2 ).name() );
}
}
if ( ignoreAccess && t1.getClass() != ClassInfo.class && t2.getClass() != ClassInfo.class ) {
if ( t1.getClass() == FieldInfo.class ) {
String fieldName = JandexHelper.getPropertyName( t2 );
return ( (FieldInfo) t1 ).name().equals( fieldName );
}
else {
String fieldName = JandexHelper.getPropertyName( t1 );
return ( (FieldInfo) t2 ).name().equals( fieldName );
}
}
return false;
}
public static boolean isNotEmpty(Collection collection) {
return collection != null && !collection.isEmpty();
}
static AnnotationInstance create(DotName name, AnnotationTarget target, List<AnnotationValue> annotationValueList) {
return create(
name, target, toArray( annotationValueList )
);
}
static String buildSafeClassName(String className, String defaultPackageName) {
if ( className.indexOf( '.' ) < 0 && StringHelper.isNotEmpty( defaultPackageName ) ) {
className = StringHelper.qualify( defaultPackageName, className );
}
return className;
}
static AnnotationInstance create(DotName name, AnnotationTarget target, AnnotationValue[] values) {
if ( values == null || values.length == 0 ) {
values = EMPTY_ANNOTATION_VALUE_ARRAY;
}
return AnnotationInstance.create( name, target, values );
}
private static MethodInfo getMethodInfo(ClassInfo classInfo, Method method) {
Class returnTypeClass = method.getReturnType();
short access_flags = (short) method.getModifiers();
return MethodInfo.create(
classInfo,
method.getName(),
getTypes( method.getParameterTypes() ),
getType( returnTypeClass ),
access_flags
);
}
enum TargetType {METHOD, FIELD, PROPERTY}
static AnnotationTarget getTarget(ServiceRegistry serviceRegistry, ClassInfo classInfo, String name, TargetType type) {
Class clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( classInfo.toString() );
switch ( type ) {
case FIELD:
Field field = getField( clazz, name );
if ( field == null ) {
throw new HibernateException(
"Unable to load field "
+ name
+ " of class " + clazz.getName()
);
}
return FieldInfo.create(
classInfo, name, getType( field.getType() ), (short) ( field.getModifiers() )
);
case METHOD:
Method method = getMethod( clazz, name );
if ( method == null ) {
throw new HibernateException(
"Unable to load method "
+ name
+ " of class " + clazz.getName()
);
}
return getMethodInfo( classInfo, method );
case PROPERTY:
method = getterMethod( clazz, name );
if ( method == null ) {
throw new HibernateException(
"Unable to load method "
+ name
+ " of class " + clazz.getName()
);
}
return getMethodInfo( classInfo, method );
}
throw new HibernateException( "" );
}
//copied from org.hibernate.internal.util.ReflectHelper
private static Method getterMethod(Class theClass, String propertyName) {
Method[] methods = theClass.getDeclaredMethods();
Method.setAccessible( methods, true );
for ( Method method : methods ) {
// if the method has parameters, skip it
if ( method.getParameterTypes().length != 0 ) {
continue;
}
// if the method is a "bridge", skip it
if ( method.isBridge() ) {
continue;
}
final String methodName = method.getName();
// try "get"
if ( methodName.startsWith( "get" ) || methodName.startsWith( "has" ) ) {
String testStdMethod = Introspector.decapitalize( methodName.substring( 3 ) );
String testOldMethod = methodName.substring( 3 );
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
return method;
}
}
// if not "get", then try "is"
if ( methodName.startsWith( "is" ) ) {
String testStdMethod = Introspector.decapitalize( methodName.substring( 2 ) );
String testOldMethod = methodName.substring( 2 );
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
return method;
}
}
}
return null;
}
private static Method getMethod(Class theClass, String propertyName) {
Method[] methods = theClass.getDeclaredMethods();
Method.setAccessible( methods, true );
for ( Method method : methods ) {
// if the method has parameters, skip it
if ( method.getParameterTypes().length != 0 ) {
continue;
}
// if the method is a "bridge", skip it
if ( method.isBridge() ) {
continue;
}
final String methodName = method.getName();
if ( methodName.equals( propertyName ) ) {
return method;
}
}
return null;
}
private static Field getField(Class clazz, String name) {
Field[] fields = clazz.getDeclaredFields();
Field.setAccessible( fields, true );
for ( Field field : fields ) {
if ( field.getName().equals( name ) ) {
return field;
}
}
return null;
}
private static Type[] getTypes(Class[] classes) {
if ( classes == null || classes.length == 0 ) {
return EMPTY_TYPE_ARRAY;
}
Type[] types = new Type[classes.length];
for ( int i = 0; i < types.length; i++ ) {
types[i] = getType( classes[i] );
}
return types;
}
private static Type getType(String className, ServiceRegistry serviceRegistry) {
return getType( serviceRegistry.getService( ClassLoaderService.class ).classForName( className ) );
}
private static Type getType(Class clazz) {
return Type.create( DotName.createSimple( clazz.getName() ), getTypeKind( clazz ) );
}
private static Type.Kind getTypeKind(Class clazz) {
Type.Kind kind;
if ( clazz == Void.TYPE ) {
kind = Type.Kind.VOID;
}
else if ( clazz.isPrimitive() ) {
kind = Type.Kind.PRIMITIVE;
}
else if ( clazz.isArray() ) {
kind = Type.Kind.ARRAY;
}
else {
kind = Type.Kind.CLASS;
}
return kind;
}
}

View File

@ -0,0 +1,81 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToMany;
/**
* @author Strong Liu
*/
class OneToManyMocker extends PropertyMocker {
private XMLOneToMany oneToMany;
OneToManyMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLOneToMany oneToMany) {
super( indexBuilder, classInfo, defaults );
this.oneToMany = oneToMany;
}
@Override
protected String getFieldName() {
return oneToMany.getName();
}
@Override
protected void processExtra() {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.classValue(
"targetEntity", oneToMany.getTargetEntity(), annotationValueList, indexBuilder.getServiceRegistry()
);
MockHelper.enumValue( "fetch", FETCH_TYPE, oneToMany.getFetch(), annotationValueList );
MockHelper.stringValue( "mappedBy", oneToMany.getMappedBy(), annotationValueList );
MockHelper.booleanValue( "orphanRemoval", oneToMany.isOrphanRemoval(), annotationValueList );
MockHelper.cascadeValue( "cascade", oneToMany.getCascade(), isDefaultCascadePersist(), annotationValueList );
create( ONE_TO_MANY, getTarget(), annotationValueList );
parserAttributeOverrides( oneToMany.getMapKeyAttributeOverride(), getTarget() );
parserMapKeyJoinColumnList( oneToMany.getMapKeyJoinColumn(),getTarget() );
parserMapKey( oneToMany.getMapKey(), getTarget() );
parserMapKeyColumn( oneToMany.getMapKeyColumn(), getTarget() );
parserMapKeyClass( oneToMany.getMapKeyClass(), getTarget() );
parserMapKeyTemporal( oneToMany.getMapKeyTemporal(), getTarget() );
parserMapKeyEnumerated( oneToMany.getMapKeyEnumerated(), getTarget() );
parserJoinColumnList( oneToMany.getJoinColumn(), getTarget() );
parserOrderColumn( oneToMany.getOrderColumn(), getTarget() );
parserJoinTable( oneToMany.getJoinTable(), getTarget() );
if ( oneToMany.getOrderBy() != null ) {
create( ORDER_BY, getTarget(), MockHelper.stringValueArray( "value", oneToMany.getOrderBy() ) );
}
}
@Override
protected XMLAccessType getAccessType() {
return oneToMany.getAccess();
}
}

View File

@ -0,0 +1,79 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLOneToOne;
/**
* @author Strong Liu
*/
class OneToOneMocker extends PropertyMocker {
private XMLOneToOne oneToOne;
OneToOneMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLOneToOne oneToOne) {
super( indexBuilder, classInfo, defaults );
this.oneToOne = oneToOne;
}
@Override
protected String getFieldName() {
return oneToOne.getName();
}
@Override
protected void processExtra() {
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.classValue(
"targetEntity", oneToOne.getTargetEntity(), annotationValueList, indexBuilder.getServiceRegistry()
);
MockHelper.enumValue( "fetch", FETCH_TYPE, oneToOne.getFetch(), annotationValueList );
MockHelper.booleanValue( "optional", oneToOne.isOptional(), annotationValueList );
MockHelper.booleanValue( "orphanRemoval", oneToOne.isOrphanRemoval(), annotationValueList );
MockHelper.stringValue( "mappedBy", oneToOne.getMappedBy(), annotationValueList );
MockHelper.cascadeValue( "cascade", oneToOne.getCascade(), isDefaultCascadePersist(), annotationValueList );
create( ONE_TO_ONE, annotationValueList );
parserPrimaryKeyJoinColumnList( oneToOne.getPrimaryKeyJoinColumn(), getTarget() );
parserJoinColumnList( oneToOne.getJoinColumn(), getTarget() );
parserJoinTable( oneToOne.getJoinTable(), getTarget() );
if ( oneToOne.getMapsId() != null ) {
create( MAPS_ID, MockHelper.stringValueArray( "value", oneToOne.getMapsId() ) );
}
if ( oneToOne.isId() != null && oneToOne.isId() ) {
create( ID );
}
}
@Override
protected XMLAccessType getAccessType() {
return oneToOne.getAccess();
}
}

View File

@ -0,0 +1,205 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLEnumType;
import org.hibernate.metamodel.source.annotation.xml.XMLMapKey;
import org.hibernate.metamodel.source.annotation.xml.XMLMapKeyClass;
import org.hibernate.metamodel.source.annotation.xml.XMLMapKeyColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLMapKeyJoinColumn;
import org.hibernate.metamodel.source.annotation.xml.XMLTemporalType;
/**
* @author Strong Liu
*/
abstract class PropertyMocker extends AnnotationMocker {
protected ClassInfo classInfo;
protected XMLAccessType accessType;
private void setTarget(AnnotationTarget target) {
this.target = target;
}
private AnnotationTarget target;
PropertyMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults) {
super( indexBuilder, defaults );
this.classInfo = classInfo;
}
protected abstract void processExtra();
@Override
protected AnnotationTarget getTarget() {
return target;
}
protected abstract String getFieldName();
protected abstract XMLAccessType getAccessType();
@Override
protected DotName getTargetName() {
return classInfo.name();
}
@Override
final void process() {
setTarget(
MockHelper.getTarget(
indexBuilder.getServiceRegistry(), classInfo, getFieldName(), MockHelper.TargetType.FIELD
)
);
parserAccessType( getAccessType(), getTarget() );
processExtra();
setTarget(
MockHelper.getTarget(
indexBuilder.getServiceRegistry(), classInfo, getFieldName(), MockHelper.TargetType.PROPERTY
)
);
processExtra();
parserAccessType( getAccessType(), getTarget() );
}
protected AnnotationInstance parserMapKeyColumn(XMLMapKeyColumn mapKeyColumn, AnnotationTarget target) {
if ( mapKeyColumn == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", mapKeyColumn.getName(), annotationValueList );
MockHelper.stringValue( "columnDefinition", mapKeyColumn.getColumnDefinition(), annotationValueList );
MockHelper.stringValue( "table", mapKeyColumn.getTable(), annotationValueList );
MockHelper.booleanValue( "nullable", mapKeyColumn.isNullable(), annotationValueList );
MockHelper.booleanValue( "insertable", mapKeyColumn.isInsertable(), annotationValueList );
MockHelper.booleanValue( "updatable", mapKeyColumn.isUpdatable(), annotationValueList );
MockHelper.booleanValue( "unique", mapKeyColumn.isUnique(), annotationValueList );
MockHelper.integerValue( "length", mapKeyColumn.getLength(), annotationValueList );
MockHelper.integerValue( "precision", mapKeyColumn.getPrecision(), annotationValueList );
MockHelper.integerValue( "scale", mapKeyColumn.getScale(), annotationValueList );
return create( MAP_KEY_COLUMN, target, annotationValueList );
}
protected AnnotationInstance parserMapKeyClass(XMLMapKeyClass mapKeyClass, AnnotationTarget target) {
if ( mapKeyClass == null ) {
return null;
}
return create(
MAP_KEY_CLASS, target, MockHelper.classValueArray(
"value", mapKeyClass.getClazz(), indexBuilder.getServiceRegistry()
)
);
}
protected AnnotationInstance parserMapKeyTemporal(XMLTemporalType temporalType, AnnotationTarget target) {
if ( temporalType == null ) {
return null;
}
return create(
MAP_KEY_TEMPORAL, target,
MockHelper.enumValueArray( "value", TEMPORAL_TYPE, temporalType )
);
}
protected AnnotationInstance parserMapKeyEnumerated(XMLEnumType enumType, AnnotationTarget target) {
if ( enumType == null ) {
return null;
}
return create(
MAP_KEY_ENUMERATED, target,
MockHelper.enumValueArray( "value", ENUM_TYPE, enumType )
);
}
protected AnnotationInstance parserMapKey(XMLMapKey mapKey, AnnotationTarget target) {
if ( mapKey == null ) {
return null;
}
return create( MAP_KEY, target, MockHelper.stringValueArray( "name", mapKey.getName() ) );
}
private AnnotationValue[] nestedMapKeyJoinColumnList(String name, List<XMLMapKeyJoinColumn> columns, List<AnnotationValue> annotationValueList) {
if ( MockHelper.isNotEmpty( columns ) ) {
AnnotationValue[] values = new AnnotationValue[columns.size()];
for ( int i = 0; i < columns.size(); i++ ) {
AnnotationInstance annotationInstance = parserMapKeyJoinColumn( columns.get( i ), null );
values[i] = MockHelper.nestedAnnotationValue(
"", annotationInstance
);
}
MockHelper.addToCollectionIfNotNull( annotationValueList, AnnotationValue.createArrayValue( name, values ) );
return values;
}
return MockHelper.EMPTY_ANNOTATION_VALUE_ARRAY;
}
protected AnnotationInstance parserMapKeyJoinColumnList(List<XMLMapKeyJoinColumn> joinColumnList, AnnotationTarget target) {
if ( MockHelper.isNotEmpty( joinColumnList ) ) {
if ( joinColumnList.size() == 1 ) {
return parserMapKeyJoinColumn( joinColumnList.get( 0 ), target );
}
else {
AnnotationValue[] values = nestedMapKeyJoinColumnList( "value", joinColumnList, null );
return create(
MAP_KEY_JOIN_COLUMNS,
target,
values
);
}
}
return null;
}
//@MapKeyJoinColumn
private AnnotationInstance parserMapKeyJoinColumn(XMLMapKeyJoinColumn column, AnnotationTarget target) {
if ( column == null ) {
return null;
}
List<AnnotationValue> annotationValueList = new ArrayList<AnnotationValue>();
MockHelper.stringValue( "name", column.getName(), annotationValueList );
MockHelper.stringValue( "columnDefinition", column.getColumnDefinition(), annotationValueList );
MockHelper.stringValue( "table", column.getTable(), annotationValueList );
MockHelper.stringValue(
"referencedColumnName", column.getReferencedColumnName(), annotationValueList
);
MockHelper.booleanValue( "unique", column.isUnique(), annotationValueList );
MockHelper.booleanValue( "nullable", column.isNullable(), annotationValueList );
MockHelper.booleanValue( "insertable", column.isInsertable(), annotationValueList );
MockHelper.booleanValue( "updatable", column.isUpdatable(), annotationValueList );
return create( MAP_KEY_JOIN_COLUMN, target, annotationValueList );
}
}

View File

@ -0,0 +1,154 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.hibernate.metamodel.source.annotation.xml.XMLCollectionTable;
import org.hibernate.metamodel.source.annotation.xml.XMLJoinTable;
import org.hibernate.metamodel.source.annotation.xml.XMLSecondaryTable;
import org.hibernate.metamodel.source.annotation.xml.XMLTable;
/**
* @author Strong Liu
*/
interface SchemaAware {
String getSchema();
void setSchema(String schema);
String getCatalog();
void setCatalog(String catalog);
static class SecondaryTableSchemaAware implements SchemaAware {
private XMLSecondaryTable table;
SecondaryTableSchemaAware(XMLSecondaryTable table) {
this.table = table;
}
@Override
public String getCatalog() {
return table.getCatalog();
}
@Override
public String getSchema() {
return table.getSchema();
}
@Override
public void setSchema(String schema) {
table.setSchema( schema );
}
@Override
public void setCatalog(String catalog) {
table.setCatalog( catalog );
}
}
static class TableSchemaAware implements SchemaAware {
private XMLTable table;
public TableSchemaAware(XMLTable table) {
this.table = table;
}
@Override
public String getCatalog() {
return table.getCatalog();
}
@Override
public String getSchema() {
return table.getSchema();
}
@Override
public void setSchema(String schema) {
table.setSchema( schema );
}
@Override
public void setCatalog(String catalog) {
table.setCatalog( catalog );
}
}
static class JoinTableSchemaAware implements SchemaAware {
private XMLJoinTable table;
public JoinTableSchemaAware(XMLJoinTable table) {
this.table = table;
}
@Override
public String getCatalog() {
return table.getCatalog();
}
@Override
public String getSchema() {
return table.getSchema();
}
@Override
public void setSchema(String schema) {
table.setSchema( schema );
}
@Override
public void setCatalog(String catalog) {
table.setCatalog( catalog );
}
}
static class CollectionTableSchemaAware implements SchemaAware {
private XMLCollectionTable table;
public CollectionTableSchemaAware(XMLCollectionTable table) {
this.table = table;
}
@Override
public String getCatalog() {
return table.getCatalog();
}
@Override
public String getSchema() {
return table.getSchema();
}
@Override
public void setSchema(String schema) {
table.setSchema( schema );
}
@Override
public void setCatalog(String catalog) {
table.setCatalog( catalog );
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLTransient;
/**
* @author Strong Liu
*/
class TransientMocker extends PropertyMocker {
private XMLTransient transientObj;
TransientMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLTransient transientObj) {
super( indexBuilder, classInfo, defaults );
this.transientObj = transientObj;
}
@Override
protected void processExtra() {
create( TRANSIENT );
}
@Override
protected String getFieldName() {
return transientObj.getName();
}
@Override
protected XMLAccessType getAccessType() {
return null;
}
}

View File

@ -0,0 +1,60 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.ClassInfo;
import org.hibernate.metamodel.source.annotation.xml.XMLAccessType;
import org.hibernate.metamodel.source.annotation.xml.XMLVersion;
/**
* @author Strong Liu
*/
class VersionMocker extends PropertyMocker {
private XMLVersion version;
VersionMocker(IndexBuilder indexBuilder, ClassInfo classInfo, EntityMappingsMocker.Default defaults, XMLVersion version) {
super( indexBuilder, classInfo, defaults );
this.version = version;
}
@Override
protected String getFieldName() {
return version.getName();
}
@Override
protected void processExtra() {
create( VERSION );
parserColumn( version.getColumn(), getTarget() );
parserTemporalType( version.getTemporal(), getTarget() );
}
@Override
protected XMLAccessType getAccessType() {
return version.getAccess();
}
}

View File

@ -0,0 +1,54 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.AnnotationValue;
import org.hibernate.metamodel.source.annotation.xml.XMLAssociationOverride;
/**
* @author Strong Liu
*/
class XMLAssociationOverrideProxy extends XMLAssociationOverride {
private AnnotationValue joinTableAnnotationValue;
private AnnotationValue joinColumnsAnnotationValue;
AnnotationValue getJoinColumnsAnnotationValue() {
return joinColumnsAnnotationValue;
}
void setJoinColumnsAnnotationValue(AnnotationValue joinColumnsAnnotationValue) {
this.joinColumnsAnnotationValue = joinColumnsAnnotationValue;
}
AnnotationValue getJoinTableAnnotationValue() {
return joinTableAnnotationValue;
}
void setJoinTableAnnotationValue(AnnotationValue joinTableAnnotationValue) {
this.joinTableAnnotationValue = joinTableAnnotationValue;
}
}

View File

@ -0,0 +1,43 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc..
*
* 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.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.AnnotationValue;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributeOverride;
/**
* @author Strong Liu
*/
class XMLAttributeOverrideProxy extends XMLAttributeOverride {
private AnnotationValue columnAnnotationValue;
AnnotationValue getColumnAnnotationValue() {
return columnAnnotationValue;
}
void setColumnAnnotationValue(AnnotationValue columnAnnotationValue) {
this.columnAnnotationValue = columnAnnotationValue;
}
}

View File

@ -40,6 +40,7 @@ public class OrmXmlParserTests extends BaseUnitTestCase {
MetadataSources sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() ); MetadataSources sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
sources.addResource( "org/hibernate/metamodel/source/annotations/xml/orm.xml" ); sources.addResource( "org/hibernate/metamodel/source/annotations/xml/orm.xml" );
MetadataImpl metadata = (MetadataImpl) sources.buildMetadata(); MetadataImpl metadata = (MetadataImpl) sources.buildMetadata();
// Todo assertions // Todo assertions
} }

View File

@ -0,0 +1,178 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBException;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.hibernate.AnnotationException;
import org.hibernate.HibernateException;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.testing.ServiceRegistryBuilder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* @author Strong Liu
*/
public abstract class AbstractMockerTest {
private static final String ORM1_MAPPING_XSD = "org/hibernate/ejb/orm_1_0.xsd";
private static final String ORM2_MAPPING_XSD = "org/hibernate/ejb/orm_2_0.xsd";
private IndexBuilder indexBuilder;
private Index index;
private ServiceRegistry serviceRegistry;
protected String packagePrefix = "org/hibernate/metamodel/source/annotations/xml/mocker/";
protected IndexBuilder getIndexBuilder() {
if ( indexBuilder == null ) {
indexBuilder = new IndexBuilder( getIndex(), getServiceRegistry() );
}
return indexBuilder;
}
protected EntityMappingsMocker getEntityMappingsMocker(String... mappingFiles) {
ClassLoaderService classLoaderService = getServiceRegistry().getService( ClassLoaderService.class );
List<XMLEntityMappings> xmlEntityMappingsList = new ArrayList<XMLEntityMappings>();
for ( String fileName : mappingFiles ) {
XMLEntityMappings entityMappings;
try {
entityMappings = XmlHelper.unmarshallXml(
packagePrefix + fileName, ORM2_MAPPING_XSD, XMLEntityMappings.class, classLoaderService
).getRoot();
}
catch ( JAXBException orm2Exception ) {
// if we cannot parse against orm_2_0.xsd we try orm_1_0.xsd for backwards compatibility
try {
entityMappings = XmlHelper.unmarshallXml(
packagePrefix + fileName, ORM1_MAPPING_XSD, XMLEntityMappings.class, classLoaderService
).getRoot();
}
catch ( JAXBException orm1Exception ) {
throw new AnnotationException( "Unable to parse xml configuration.", orm1Exception );
}
}
xmlEntityMappingsList.add( entityMappings );
}
return new EntityMappingsMocker( xmlEntityMappingsList, getIndex(), getServiceRegistry() );
}
protected Index getIndex() {
if ( index == null ) {
Indexer indexer = new Indexer();
for ( Class<?> clazz : getAnnotatedClasses() ) {
indexClass( indexer, clazz.getName().replace( '.', '/' ) + ".class" );
}
// add package-info from the configured packages
for ( String packageName : getAnnotatedPackages() ) {
indexClass( indexer, packageName.replace( '.', '/' ) + "/package-info.class" );
}
index = indexer.complete();
}
return index;
}
protected Index getMockedIndex(String ormFileName){
EntityMappingsMocker mocker = getEntityMappingsMocker( ormFileName );
return mocker.mockNewIndex();
}
private void indexClass(Indexer indexer, String className) {
ClassLoaderService classLoaderService = getServiceRegistry().getService( ClassLoaderService.class );
InputStream stream = classLoaderService.locateResourceStream( className );
try {
indexer.index( stream );
}
catch ( IOException e ) {
throw new HibernateException( "Unable to open input stream for class " + className, e );
}
}
protected Class[] getAnnotatedClasses() {
return new Class[0];
}
protected String[] getAnnotatedPackages() {
return new String[0];
}
protected ServiceRegistry getServiceRegistry() {
if ( serviceRegistry == null ) {
serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry();
}
return serviceRegistry;
}
protected void assertHasAnnotation(Index index, DotName className, DotName annName) {
assertHasAnnotation( index, className, annName, 1 );
}
protected void assertHasNoAnnotation(Index index, DotName className, DotName annName) {
ClassInfo classInfo = index.getClassByName( className );
if ( classInfo == null ) {
fail( "Can't find " + className + " from Index" );
}
if ( classInfo.annotations() != null ) {
List<AnnotationInstance> annotationInstanceList = classInfo.annotations().get( annName );
if ( annotationInstanceList != null ) {
if(!annotationInstanceList.isEmpty()){
fail( className+" has Annotation "+annName );
}
}
}
}
protected void assertHasAnnotation(Index index, DotName className, DotName annName, int size) {
ClassInfo classInfo = index.getClassByName( className );
if ( classInfo == null ) {
fail( "Can't find " + className + " from Index" );
}
if ( classInfo.annotations() == null ) {
fail( classInfo + " doesn't have any annotations defined" );
}
List<AnnotationInstance> annotationInstanceList = classInfo.annotations().get( annName );
if ( annotationInstanceList == null || annotationInstanceList.isEmpty() ) {
fail( classInfo + " doesn't have annotation " + annName );
}
assertEquals(
"Expected annotation " + annName + " size is " + size + ", but it actually is " + annotationInstanceList
.size(), size, annotationInstanceList.size()
);
}
protected void assertStringAnnotationValue(String expected, AnnotationValue annotationValue) {
if ( annotationValue == null ) {
fail( "Annotation Value is null." );
}
assertEquals( expected, annotationValue.asString() );
}
protected void assertAnnotationValue(Index index, DotName className, DotName annName, AnnotationValueChecker checker) {
assertAnnotationValue( index, className, annName, 1, checker );
}
protected void assertAnnotationValue(Index index, DotName className, DotName annName, int size, AnnotationValueChecker checker) {
assertHasAnnotation( index, className, annName, size );
ClassInfo classInfo = index.getClassByName( className );
List<AnnotationInstance> annotationInstanceList = classInfo.annotations().get( annName );
for ( AnnotationInstance annotationInstance : annotationInstanceList ) {
checker.check( annotationInstance );
}
}
static interface AnnotationValueChecker {
void check(AnnotationInstance annotationInstance);
}
}

View File

@ -0,0 +1,50 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
/**
* @author Strong Liu
*/
@Entity
public class Author {
private Long id;
private String name;
private List<Book> books = new ArrayList<Book>();
@Id
@GeneratedValue(generator = "SEQ_GEN")
@SequenceGenerator(name = "SEQ_GEN", initialValue = 123)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(mappedBy = "author",cascade = CascadeType.MERGE)
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}

View File

@ -0,0 +1,84 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.junit.Test;
import org.hibernate.metamodel.source.annotation.xml.XMLAttributes;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotation.xml.XMLGeneratedValue;
import org.hibernate.metamodel.source.annotation.xml.XMLId;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import static org.junit.Assert.assertEquals;
/**
* @author Strong Liu
*/
public class BasicMockerTest extends AbstractMockerTest {
@Test
public void testEntity() {
XMLEntity entity = createEntity();
IndexBuilder indexBuilder = getIndexBuilder();
EntityMocker entityMocker = new EntityMocker( indexBuilder, entity, new EntityMappingsMocker.Default() );
entityMocker.process();
Index index = indexBuilder.build( new EntityMappingsMocker.Default() );
assertEquals( 1, index.getKnownClasses().size() );
DotName itemName = DotName.createSimple( Item.class.getName() );
assertHasAnnotation( index, itemName, JPADotNames.ENTITY );
assertHasAnnotation( index, itemName, JPADotNames.TABLE );
assertHasAnnotation( index, itemName, JPADotNames.ID, 2 );
assertHasAnnotation( index, itemName, JPADotNames.GENERATED_VALUE, 2 );
}
@Test
public void testEntityWithEntityMappingsConfiguration() {
XMLEntity entity = new XMLEntity();
entity.setName( "Item" );
entity.setClazz( "Item" );
IndexBuilder indexBuilder = getIndexBuilder();
EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default();
defaults.setPackageName( "org.hibernate.metamodel.source.annotations.xml.mocker" );
defaults.setSchema( "HIBERNATE_SCHEMA" );
defaults.setCatalog( "HIBERNATE_CATALOG" );
EntityMocker entityMocker = new EntityMocker( indexBuilder, entity, defaults );
entityMocker.process();
Index index = indexBuilder.build( new EntityMappingsMocker.Default() );
assertEquals( 1, index.getKnownClasses().size() );
DotName itemName = DotName.createSimple( Item.class.getName() );
assertHasAnnotation( index, itemName, JPADotNames.ENTITY );
assertHasAnnotation( index, itemName, JPADotNames.TABLE );
assertAnnotationValue(
index, itemName, JPADotNames.TABLE, new AnnotationValueChecker() {
@Override
public void check(AnnotationInstance annotationInstance) {
AnnotationValue schemaValue = annotationInstance.value( "schema" );
AnnotationValue catalogValue = annotationInstance.value( "catalog" );
assertStringAnnotationValue( "HIBERNATE_SCHEMA", schemaValue );
assertStringAnnotationValue( "HIBERNATE_CATALOG", catalogValue );
}
}
);
}
private XMLEntity createEntity() {
XMLEntity entity = new XMLEntity();
entity.setName( "Item" );
entity.setClazz( Item.class.getName() );
XMLAttributes attributes = new XMLAttributes();
XMLId id = new XMLId();
id.setName( "id" );
id.setGeneratedValue( new XMLGeneratedValue() );
attributes.getId().add( id );
entity.setAttributes( attributes );
return entity;
}
}

View File

@ -0,0 +1,78 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.TableGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
/**
* @author Strong Liu
*/
@Entity
@TableGenerator(name = "TABLE_GEN", catalog = "ANNOTATION_CATALOG", schema = "ANNOTATION_SCHEMA")
public class Book {
@Id
@GeneratedValue(generator = "TABLE_GEN")
private Long id;
@Temporal(TemporalType.TIMESTAMP)
private Date publishDate;
@ManyToOne(cascade = CascadeType.DETACH)
private Author author;
@ElementCollection
@AttributeOverride(name = "title", column = @Column(name = "TOC_TITLE"))
private List<Topic> topics = new ArrayList<Topic>();
public List<Topic> getTopics() {
return topics;
}
public void setTopics(List<Topic> topics) {
this.topics = topics;
}
@Version
private Long version;
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getPublishDate() {
return publishDate;
}
public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}

View File

@ -0,0 +1,26 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.junit.Test;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import static org.junit.Assert.assertEquals;
/**
* @author Strong Liu
*/
public class EntityListenerTest extends AbstractMockerTest {
@Test
public void basicEntityListenerMockTest() {
Index index = getMockedIndex( "listener.xml" );
index.printAnnotations();
DotName itemName = DotName.createSimple( Item.class.getName() );
ClassInfo itemClassInfo = index.getClassByName( itemName );
assertEquals( 2, itemClassInfo.annotations().size() );
assertHasAnnotation( index,itemName, JPADotNames.ENTITY );
assertHasAnnotation( index,itemName,JPADotNames.ENTITY_LISTENERS );
}
}

View File

@ -0,0 +1,16 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
/**
* @author Strong Liu
*/
public class Item {
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@ -0,0 +1,9 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
/**
* @author Strong Liu
*/
public class ItemListener {
public void prePersist(){}
public void postPersist(){}
}

View File

@ -0,0 +1,228 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.junit.Test;
import org.hibernate.metamodel.source.annotation.xml.XMLEntity;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
/**
* @author Strong Liu
*/
public class OverrideTest extends AbstractMockerTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
Author.class,
Book.class,
Topic.class
};
}
@Test
public void testPersistenceUnitMetadataMetadataComplete() {
XMLEntity author = new XMLEntity();
author.setClazz( Author.class.getName() );
IndexBuilder indexBuilder = getIndexBuilder();
EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default();
defaults.setMetadataComplete( true );
EntityMocker entityMocker = new EntityMocker( indexBuilder, author, defaults );
entityMocker.process();
Index index = indexBuilder.build( new EntityMappingsMocker.Default() );
DotName className = DotName.createSimple( Author.class.getName() );
ClassInfo classInfo = index.getClassByName( className );
assertEquals( 1, classInfo.annotations().size() );
assertHasAnnotation( index, className, JPADotNames.ENTITY );
}
@Test
public void testEntityMetadataComplete() {
Index index =getMockedIndex( "entity-metadata-complete.xml" );
DotName authorName = DotName.createSimple( Author.class.getName() );
ClassInfo authorClassInfo= index.getClassByName( authorName );
assertHasAnnotation( index,authorName,JPADotNames.ENTITY );
assertHasAnnotation( index, authorName, JPADotNames.ID_CLASS );
assertEquals( 2, authorClassInfo.annotations().size() );
DotName bookName = DotName.createSimple( Book.class.getName() );
assertHasAnnotation( index,bookName,JPADotNames.ENTITY );
}
@Test
public void testOverrideToMappedSuperClass(){
Index index =getMockedIndex( "override-to-mappedsuperclass.xml" );
index.printAnnotations();
DotName authorName = DotName.createSimple( Author.class.getName() );
assertHasAnnotation( index,authorName,JPADotNames.ENTITY );
assertHasNoAnnotation( index, authorName, JPADotNames.TABLE );
DotName bookName = DotName.createSimple( Book.class.getName() );
assertHasAnnotation( index,bookName,JPADotNames.MAPPED_SUPERCLASS );
assertHasNoAnnotation( index, bookName, JPADotNames.TABLE );
}
@Test
public void testPersistenceUnitDefaultsCascadePersistInAnnotation() {
XMLEntity author = new XMLEntity();
author.setClazz( Author.class.getName() );
IndexBuilder indexBuilder = getIndexBuilder();
EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default();
defaults.setCascadePersist( true );
EntityMocker entityMocker = new EntityMocker( indexBuilder, author, defaults );
entityMocker.process();
Index index = indexBuilder.build( new EntityMappingsMocker.Default() );
DotName className = DotName.createSimple( Author.class.getName() );
assertAnnotationValue(
index, className, JPADotNames.ONE_TO_MANY, new CascadeAnnotationValueChecker( "PERSIST", "MERGE" )
);
}
@Test
public void testPersistenceUnitDefaultsCascadePersistInXML() {
Index index =getMockedIndex( "AttributeOverride.xml" );
DotName className = DotName.createSimple( Author.class.getName() );
assertAnnotationValue(
index,
className,
JPADotNames.ONE_TO_MANY,
2,
new CascadeAnnotationValueChecker( new String[] { "PERSIST", "ALL" } )
);
}
protected class CascadeAnnotationValueChecker implements AnnotationValueChecker {
private String[] expected = new String[0];
public CascadeAnnotationValueChecker(String... expected) {
this.expected = expected;
}
@Override
public void check(AnnotationInstance annotationInstance) {
AnnotationValue cascadeValue = annotationInstance.value( "cascade" );
assertNotNull(
"Cascade is null in @OneToMany, but should be added a Cascade persist", cascadeValue
);
String[] enumArray = cascadeValue.asEnumArray();
assertEquals( expected.length, enumArray.length );
assertArrayEquals( expected, enumArray );
}
}
/**
* Entity has a @AttributeOverride on property topic
* and this property also has a <attribute-override> in orm.xml but with different name
* by jpa override rules, this two attribute-override should be merged into one @AttributeOverrides
*/
@Test
public void testAttributeOverride() {
Index index =getMockedIndex( "AttributeOverride.xml" );
DotName className = DotName.createSimple( Book.class.getName() );
index.printAnnotations();
assertHasNoAnnotation(
index,
className,
JPADotNames.ATTRIBUTE_OVERRIDE
);
assertAnnotationValue(
index,
className,
JPADotNames.ATTRIBUTE_OVERRIDES, 2, new AnnotationValueChecker() {
@Override
public void check(AnnotationInstance annotationInstance) {
AnnotationValue value = annotationInstance.value();
assertNotNull( value );
AnnotationInstance[] annotationInstances = value.asNestedArray();
assertEquals( 2, annotationInstances.length );
AnnotationInstance ai = annotationInstances[0];
String name = ai.value( "name" ).asString();
AnnotationValue columnValue = ai.value( "column" ).asNested().value( "name" );
if ( name.equals( "title" ) ) {
assertEquals( "TOC_TITLE", columnValue.asString() );
}
else if ( name.equals( "summary" ) ) {
assertEquals( "TOPIC_SUMMARY", columnValue.asString() );
}
else {
fail( "AttributeOverride's name is " + name + ", should be either 'title' or 'summary'" );
}
}
}
);
}
@Test
public void testSchemaInPersistenceMetadata() {
Index index =getMockedIndex( "default-schema.xml" );
//Global Configuration should be accessed like this, not from ClassInfo
List<AnnotationInstance> annotationInstanceList = index.getAnnotations( JPADotNames.TABLE_GENERATOR );
assertNotNull( annotationInstanceList );
assertEquals( 1, annotationInstanceList.size() );
AnnotationInstance generator = annotationInstanceList.get( 0 );
assertEquals( "TABLE_GEN", generator.value( "name" ).asString() );
assertEquals( "ANNOTATION_CATALOG", generator.value( "catalog" ).asString() );
assertEquals( "ANNOTATION_SCHEMA", generator.value( "schema" ).asString() );
annotationInstanceList = index.getAnnotations( JPADotNames.SEQUENCE_GENERATOR );
assertNotNull( annotationInstanceList );
assertEquals( 1, annotationInstanceList.size() );
generator = annotationInstanceList.get( 0 );
assertEquals( "SEQ_GEN", generator.value( "name" ).asString() );
assertEquals( "XML_CATALOG", generator.value( "catalog" ).asString() );
assertEquals( "XML_SCHEMA", generator.value( "schema" ).asString() );
assertEquals( 123, generator.value( "initialValue" ).asInt() );
//Book and Author and Topic are all not defined @Table
//but orm xml defines default schema and catalog in persistence-unit-metadata
//so, we have to mock @Table for entities, Book and Author but not Topic which is a Embeddable
annotationInstanceList = index.getAnnotations( JPADotNames.TABLE );
assertNotNull( annotationInstanceList );
assertEquals( 2, annotationInstanceList.size() );
for ( AnnotationInstance table : annotationInstanceList ) {
assertEquals( "XML_CATALOG", table.value( "catalog" ).asString() );
assertEquals( "XML_SCHEMA", table.value( "schema" ).asString() );
}
}
@Test
public void testSchemaInEntityMapping() {
Index index =getMockedIndex( "default-schema2.xml" );
//Global Configuration should be accessed like this, not from ClassInfo
List<AnnotationInstance> annotationInstanceList = index.getAnnotations( JPADotNames.TABLE_GENERATOR );
assertNotNull( annotationInstanceList );
assertEquals( 1, annotationInstanceList.size() );
AnnotationInstance generator = annotationInstanceList.get( 0 );
assertEquals( "TABLE_GEN", generator.value( "name" ).asString() );
assertEquals( "ANNOTATION_CATALOG", generator.value( "catalog" ).asString() );
assertEquals( "ANNOTATION_SCHEMA", generator.value( "schema" ).asString() );
annotationInstanceList = index.getAnnotations( JPADotNames.SEQUENCE_GENERATOR );
assertNotNull( annotationInstanceList );
assertEquals( 1, annotationInstanceList.size() );
generator = annotationInstanceList.get( 0 );
assertEquals( "SEQ_GEN", generator.value( "name" ).asString() );
assertNull( generator.value( "catalog" ) );
assertNull( generator.value( "schema" ) );
assertEquals( 123, generator.value( "initialValue" ).asInt() );
annotationInstanceList = index.getAnnotations( JPADotNames.TABLE );
assertNotNull( annotationInstanceList );
assertEquals( 0, annotationInstanceList.size() );
}
}

View File

@ -0,0 +1,37 @@
package org.hibernate.metamodel.source.annotations.xml.mocker;
import javax.persistence.Embeddable;
/**
* @author Strong Liu
*/
@Embeddable
public class Topic {
private String title;
private String summary;
private int position;
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

View File

@ -0,0 +1,79 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. 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 Inc.
*
* 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.metamodel.source.annotations.xml.mocker;
import java.io.InputStream;
import java.net.URL;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import org.hibernate.metamodel.source.Origin;
import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
* @author Hardy Ferentschik
*/
public class XmlHelper {
private static final Logger log = LoggerFactory.getLogger( XmlHelper.class );
private XmlHelper() {
}
public static <T> JaxbRoot<T> unmarshallXml(String fileName, String schemaName, Class<T> clazz, ClassLoaderService classLoaderService)
throws JAXBException {
Schema schema = getMappingSchema( schemaName, classLoaderService );
InputStream in = classLoaderService.locateResourceStream( fileName );
JAXBContext jc = JAXBContext.newInstance( clazz );
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema( schema );
StreamSource stream = new StreamSource( in );
JAXBElement<T> elem = unmarshaller.unmarshal( stream, clazz );
Origin origin = new Origin( null, fileName );
return new JaxbRoot<T>( elem.getValue(), origin );
}
private static Schema getMappingSchema(String schemaVersion, ClassLoaderService classLoaderService) {
URL schemaUrl = classLoaderService.locateResource( schemaVersion );
SchemaFactory sf = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
Schema schema = null;
try {
schema = sf.newSchema( schemaUrl );
}
catch ( SAXException e ) {
log.debug( "Unable to create schema for {}: {}", schemaVersion, e.getMessage() );
}
return schema;
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<cascade-persist/>
</persistence-unit-defaults>
</persistence-unit-metadata>
<package>org.hibernate.metamodel.source.annotations.xml.mocker</package>
<entity class="Book">
<attributes>
<element-collection name="topics">
<attribute-override name="summary">
<column name="TOPIC_SUMMARY"/>
</attribute-override>
</element-collection>
</attributes>
</entity>
<entity class="Author">
<attributes>
<one-to-many name="books">
<cascade>
<cascade-all/>
</cascade>
</one-to-many>
</attributes>
</entity>
</entity-mappings>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>XML_SCHEMA</schema>
<catalog>XML_CATALOG</catalog>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<package>org.hibernate.metamodel.source.annotations.xml.mocker</package>
<schema>XML_SCHEMA</schema>
<catalog>XML_CATALOG</catalog>
</entity-mappings>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<package>org.hibernate.metamodel.source.annotations.xml.mocker</package>
<entity class="Author" metadata-complete="true">
<id-class class="Topic"/>
</entity>
</entity-mappings>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<package>org.hibernate.metamodel.source.annotations.xml.mocker</package>
<entity class="Item">
<entity-listeners>
<entity-listener class="org.hibernate.metamodel.source.annotations.xml.mocker.ItemListener">
<pre-persist method-name="prePersist"/>
<post-persist method-name="postPersist"/>
</entity-listener>
</entity-listeners>
</entity>
</entity-mappings>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<package>org.hibernate.metamodel.source.annotations.xml.mocker</package>
<mapped-superclass class="Book">
<attributes>
<element-collection name="topics">
<attribute-override name="summary">
<column name="TOPIC_SUMMARY"/>
</attribute-override>
</element-collection>
</attributes>
</mapped-superclass>
</entity-mappings>

View File

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0"> version="2.0">
<package>org.hibernate.test.annotations.onetoone</package> <package>org.hibernate.test.annotations.onetoone</package>
<entity class="Father"> <entity class="Father">
<attributes> <attributes>
<id name="id"> <id name="id">