HHH-6174 Adding support for o.h.a.Index

This commit is contained in:
Hardy Ferentschik 2011-05-05 15:44:05 +02:00
parent 328d72e1cd
commit 101aa09e36
4 changed files with 1605 additions and 1432 deletions

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.source.annotations;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -84,12 +83,24 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
return isVersioned;
}
public final List<AnnotationInstance> annotations(DotName annotationDotName) {
/**
* Returns the annotation with the specified name or {@code null}
*
* @param annotationDotName The annotation to retrieve/check
*
* @return Returns the annotation with the specified name or {@code null}. Note, since these are the
* annotations defined on a single attribute there can never be more than one.
*/
public final AnnotationInstance annotations(DotName annotationDotName) {
if ( annotations.containsKey( annotationDotName ) ) {
return annotations.get( annotationDotName );
List<AnnotationInstance> instanceList = annotations.get( annotationDotName );
if ( instanceList.size() > 1 ) {
throw new AssertionFailure( "There cannot be more than one @" + annotationDotName.toString() + " annotation per mapped attribute" );
}
return instanceList.get( 0 );
}
else {
return Collections.emptyList();
return null;
}
}

View File

@ -0,0 +1,138 @@
/*
* 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.global;
import java.util.Arrays;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
import org.hibernate.AnnotationException;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.ObjectName;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.Table;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
* Binds table related information. This binder is called after the entities are bound.
*
* @author Hardy Ferentschik
*/
public class TableBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, TableBinder.class.getName()
);
private TableBinder() {
}
/**
* Binds {@link org.hibernate.annotations.Tables} and {@link org.hibernate.annotations.Table}
* annotations to the specified meta data instance.
*
* @param meta the global metadata
* @param index the annotation index repository
*/
public static void bind(MetadataImpl meta, Index index) {
// check @o.h.a.Tables
List<AnnotationInstance> tablesAnnotations = index.getAnnotations( HibernateDotNames.TABLES );
for ( AnnotationInstance tableAnnotation : tablesAnnotations ) {
AnnotationInstance tables[] = tableAnnotation.value().asNestedArray();
bindTablesAnnotation( meta, Arrays.asList( tables ) );
}
// check @o.h.a.Table
List<AnnotationInstance> tableAnnotations = index.getAnnotations( HibernateDotNames.TABLE );
bindTablesAnnotation( meta, tableAnnotations );
}
private static void bindTablesAnnotation(MetadataImpl meta, List<AnnotationInstance> tableAnnotations) {
for ( AnnotationInstance tableAnnotation : tableAnnotations ) {
String tableName = tableAnnotation.value( "appliesTo" ).asString();
ObjectName objectName = new ObjectName( tableName );
Schema schema = meta.getDatabase().getSchema( objectName.getSchema(), objectName.getCatalog() );
Table table = schema.getTable( objectName.getName() );
if ( table == null ) {
continue;
}
bindHibernateTableAnnotation( table, tableAnnotation );
}
}
private static void bindHibernateTableAnnotation(Table table, AnnotationInstance tableAnnotation) {
if ( tableAnnotation.value( "indexes" ) != null ) {
AnnotationInstance[] indexAnnotations = tableAnnotation.value( "indexes" ).asNestedArray();
for ( AnnotationInstance indexAnnotation : indexAnnotations ) {
bindIndexAnnotation( table, indexAnnotation );
}
}
if ( tableAnnotation.value( "comment" ) != null ) {
table.addComment( tableAnnotation.value( "comment" ).asString().trim() );
}
}
private static void bindIndexAnnotation(Table table, AnnotationInstance indexAnnotation) {
String indexName = indexAnnotation.value( "name" ).asString();
if ( indexAnnotation.value( "columnNames" ) == null ) {
LOG.noColumnsSpecifiedForIndex( indexName, table.toLoggableString() );
return;
}
org.hibernate.metamodel.relational.Index index = table.getOrCreateIndex( indexName );
String[] columnNames = indexAnnotation.value( "columnNames" ).asStringArray();
for ( String columnName : columnNames ) {
Column column = findColumn( table, columnName );
if ( column == null ) {
throw new AnnotationException(
"@Index references a unknown column: " + columnName
);
}
index.addColumn( column );
}
}
private static Column findColumn(Table table, String columnName) {
Column column = null;
for ( SimpleValue value : table.values() ) {
if ( value instanceof Column && ( (Column) value ).getName().equals( columnName ) ) {
column = (Column) value;
break;
}
}
return column;
}
}

View File

@ -32,7 +32,6 @@ import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.relational.Size;
@ -53,13 +52,14 @@ public class AttributeColumnRelationalState implements SimpleAttributeBinding.Co
private final String checkCondition;
private final String customWriteFragment;
private final String customReadFragment;
private final Set<String> indexes;
// todo - what about these annotations !?
private String defaultString;
private String sqlType;
private String comment;
private Set<String> uniqueKeys = new HashSet<String>();
private Set<String> indexes = new HashSet<String>();
public AttributeColumnRelationalState(MappedAttribute attribute, MetadataImpl meta) {
ColumnValues columnValues = attribute.getColumnValues();
@ -68,24 +68,14 @@ public class AttributeColumnRelationalState implements SimpleAttributeBinding.Co
unique = columnValues.isUnique();
nullable = columnValues.isNullable();
size = createSize( columnValues.getLength(), columnValues.getScale(), columnValues.getPrecision() );
List<AnnotationInstance> checkAnnotations = attribute.annotations( HibernateDotNames.CHECK );
if ( checkAnnotations.size() > 1 ) {
throw new AssertionFailure( "There cannot be more than one @Check annotation per mapped attribute" );
}
if ( checkAnnotations.size() == 1 ) {
checkCondition = checkAnnotations.get( 0 ).value( "constraints" ).toString();
}
else {
checkCondition = null;
}
checkCondition = parseCheckAnnotation( attribute );
indexes = parseIndexAnnotation( attribute );
String[] readWrite;
List<AnnotationInstance> columnTransformerAnnotations = getAllColumnTransformerAnnotations( attribute );
readWrite = createCustomReadWrite( columnTransformerAnnotations );
customReadFragment = readWrite[0];
customWriteFragment = readWrite[1];
}
@Override
@ -161,35 +151,23 @@ public class AttributeColumnRelationalState implements SimpleAttributeBinding.Co
return size;
}
private List<AnnotationInstance> getAllColumnTransformerAnnotations(MappedAttribute attribute) {
List<AnnotationInstance> allColumnTransformerAnnotations = new ArrayList<AnnotationInstance>();
// not quite sure about the usefulness of @ColumnTransformers (HF)
List<AnnotationInstance> columnTransformersAnnotations = attribute.annotations( HibernateDotNames.COLUMN_TRANSFORMERS );
if ( columnTransformersAnnotations.size() > 1 ) {
throw new AssertionFailure(
"There cannot be more than one @ColumnTransformers annotation per mapped attribute"
);
}
if ( columnTransformersAnnotations.size() == 1 ) {
AnnotationInstance columnTransformersAnnotations = attribute.annotations( HibernateDotNames.COLUMN_TRANSFORMERS );
if ( columnTransformersAnnotations != null ) {
AnnotationInstance[] annotationInstances = allColumnTransformerAnnotations.get( 0 ).value().asNestedArray();
allColumnTransformerAnnotations.addAll( Arrays.asList( annotationInstances ) );
}
List<AnnotationInstance> columnTransformerAnnotations = attribute.annotations( HibernateDotNames.COLUMN_TRANSFORMER );
if ( columnTransformerAnnotations.size() > 1 ) {
throw new AssertionFailure(
"There cannot be more than one @ColumnTransformer annotation per mapped attribute"
);
}
if ( columnTransformerAnnotations.size() == 1 ) {
allColumnTransformerAnnotations.add( columnTransformerAnnotations.get( 0 ) );
AnnotationInstance columnTransformerAnnotation = attribute.annotations( HibernateDotNames.COLUMN_TRANSFORMER );
if ( columnTransformerAnnotation != null ) {
allColumnTransformerAnnotations.add( columnTransformerAnnotation );
}
return allColumnTransformerAnnotations;
}
private String[] createCustomReadWrite(List<AnnotationInstance> columnTransformerAnnotations) {
String[] readWrite = new String[2];
@ -215,6 +193,25 @@ public class AttributeColumnRelationalState implements SimpleAttributeBinding.Co
}
return readWrite;
}
private String parseCheckAnnotation(MappedAttribute attribute) {
String checkCondition = null;
AnnotationInstance checkAnnotation = attribute.annotations( HibernateDotNames.CHECK );
if ( checkAnnotation != null ) {
checkCondition = checkAnnotation.value( "constraints" ).toString();
}
return checkCondition;
}
private Set<String> parseIndexAnnotation(MappedAttribute attribute) {
Set<String> indexNames = new HashSet<String>();
AnnotationInstance indexAnnotation = attribute.annotations( HibernateDotNames.INDEX );
if ( indexAnnotation != null ) {
String indexName = indexAnnotation.value( "name" ).toString();
indexNames.add( indexName );
}
return indexNames;
}
}