HHH-6132: Created binders for several global configurations and updated metadata appropriately.

This commit is contained in:
JPAV 2011-05-09 11:26:00 -05:00
parent 3960b0d8ea
commit 7258cb98f4
16 changed files with 1207 additions and 488 deletions

View File

@ -0,0 +1,44 @@
/*
* 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.annotations;
/**
*
*/
public class QueryHints {
public static final String CACHE_MODE = "org.hibernate.cacheMode";
public static final String CACHE_REGION = "org.hibernate.cacheRegion";
public static final String CACHEABLE = "org.hibernate.cacheable";
public static final String CALLABLE = "org.hibernate.callable";
public static final String COMMENT = "org.hibernate.comment";
public static final String FETCH_SIZE = "org.hibernate.fetchSize";
public static final String FLUSH_MODE = "org.hibernate.flushMode";
public static final String READ_ONLY = "org.hibernate.readOnly";
public static final String TIMEOUT_HIBERNATE = "org.hibernate.timeout";
public static final String TIMEOUT_JPA = "javax.persistence.query.timeout";
private QueryHints() {
}
}

View File

@ -22,34 +22,34 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import java.util.LinkedHashSet;
import org.hibernate.mapping.MetadataSource;
import java.util.Collections;
import java.util.Set;
/**
* A fetch profile allows a user to dynamically modify the fetching strategy used for particular associations at
* runtime, whereas that information was historically only statically defined in the metadata.
* A fetch profile allows a user to dynamically modify the fetching strategy used for particular associations at runtime, whereas
* that information was historically only statically defined in the metadata.
* <p/>
* This class represent the data as it is defined in their metadata.
*
* @author Steve Ebersole
*
* @see org.hibernate.engine.profile.FetchProfile
*/
public class FetchProfile {
private final String name;
private final MetadataSource source;
private LinkedHashSet<Fetch> fetches = new LinkedHashSet<Fetch>();
private final Set<Fetch> fetches;
/**
* Create a fetch profile representation.
*
* @param name The name of the fetch profile.
* @param source The source of the fetch profile (where was it defined).
* @param fetches
*/
public FetchProfile(String name, MetadataSource source) {
public FetchProfile( String name,
Set<Fetch> fetches ) {
this.name = name;
this.source = source;
this.fetches = fetches;
}
/**
@ -61,22 +61,13 @@ public class FetchProfile {
return name;
}
/**
* Retrieve the fetch profile source.
*
* @return The profile source.
*/
public MetadataSource getSource() {
return source;
}
/**
* Retrieve the fetches associated with this profile
*
* @return The fetches associated with this profile.
*/
public LinkedHashSet<Fetch> getFetches() {
return fetches;
public Set<Fetch> getFetches() {
return Collections.unmodifiableSet(fetches);
}
/**
@ -86,34 +77,12 @@ public class FetchProfile {
* @param association The association to fetch
* @param style The style of fetch t apply
*/
public void addFetch(String entity, String association, String style) {
fetches.add( new Fetch( entity, association, style ) );
public void addFetch( String entity,
String association,
String style ) {
fetches.add(new Fetch(entity, association, style));
}
/**
* {@inheritDoc}
*/
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
FetchProfile that = (FetchProfile) o;
return name.equals( that.name );
}
/**
* {@inheritDoc}
*/
public int hashCode() {
return name.hashCode();
}
/**
* Defines an individual association fetch within the given profile.
*/
@ -122,7 +91,9 @@ public class FetchProfile {
private final String association;
private final String style;
public Fetch(String entity, String association, String style) {
public Fetch( String entity,
String association,
String style ) {
this.entity = entity;
this.association = association;
this.style = style;

View File

@ -22,26 +22,34 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import java.io.Serializable;
import java.util.Properties;
import java.util.Collections;
import java.util.Map;
/**
* Identifier generator container,
* Useful to keep named generator in annotations
* Identifier generator container, Useful to keep named generator in annotations
*
* @author Emmanuel Bernard
*/
public class IdGenerator implements Serializable {
private String name;
private String identifierGeneratorStrategy;
private Properties params = new Properties();
private final String name;
private final String strategy;
private final Map<String, String> parameters;
public IdGenerator( String name,
String strategy,
Map<String, String> parameters ) {
this.name = name;
this.strategy = strategy;
this.parameters = parameters;
}
/**
* @return identifier generator strategy
*/
public String getIdentifierGeneratorStrategy() {
return identifierGeneratorStrategy;
public String getStrategy() {
return strategy;
}
/**
@ -54,20 +62,7 @@ public class IdGenerator implements Serializable {
/**
* @return generator configuration parameters
*/
public Properties getParams() {
return params;
public Map<String, String> getParameters() {
return Collections.unmodifiableMap(parameters);
}
public void setIdentifierGeneratorStrategy(String string) {
identifierGeneratorStrategy = string;
}
public void setName(String string) {
name = string;
}
public void addParam(String key, String value) {
params.setProperty( key, value );
}
}

View File

@ -22,27 +22,30 @@
* Boston, MA 02110-1301 USA
*/
package org.hibernate.metamodel.binding;
import java.io.Serializable;
import java.util.Properties;
import java.util.Collections;
import java.util.Map;
/**
* Placeholder for typedef information
*/
public class TypeDef implements Serializable {
private String typeClass;
private Properties parameters;
private final String typeClass;
private final Map<String, String> parameters;
public TypeDef(String typeClass, Properties parameters) {
public TypeDef( String typeClass,
Map<String, String> parameters ) {
this.typeClass = typeClass;
this.parameters = parameters;
}
public Properties getParameters() {
return parameters;
public Map<String, String> getParameters() {
return Collections.unmodifiableMap(parameters);
}
public String getTypeClass() {
return typeClass;
}
}

View File

@ -32,6 +32,10 @@ import org.slf4j.LoggerFactory;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
import org.hibernate.metamodel.source.annotations.entity.EntityBinder;
import org.hibernate.metamodel.source.annotations.global.FilterDefBinder;
import org.hibernate.metamodel.source.annotations.global.IdGeneratorBinder;
import org.hibernate.metamodel.source.annotations.global.QueryBinder;
import org.hibernate.metamodel.source.annotations.global.TypeDefBinder;
import org.hibernate.metamodel.source.annotations.global.FetchProfileBinder;
import org.hibernate.metamodel.source.annotations.global.TableBinder;
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
@ -45,7 +49,9 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik
*/
public class AnnotationBinder {
private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
private static final Logger LOG = LoggerFactory.getLogger( AnnotationBinder.class );
private final MetadataImpl metadata;
private final Index index;
@ -64,7 +70,8 @@ public class AnnotationBinder {
* Binds global configuration data prior to entity binding. This includes generators and type definitions.
*/
private void preEntityBindings() {
FetchProfileBinder.bind( metadata, index );
TypeDefBinder.bind(metadata, index);
IdGeneratorBinder.bind(metadata, index);
}
/**
@ -79,7 +86,7 @@ public class AnnotationBinder {
// now we process each hierarchy one at the time
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
for ( ConfiguredClass configuredClass : hierarchy ) {
log.info( "Binding entity from annotated class: {}", configuredClass.getName() );
LOG.info( "Binding entity from annotated class: {}", configuredClass.getName() );
EntityBinder entityBinder = new EntityBinder( metadata, configuredClass );
entityBinder.bind();
}
@ -92,6 +99,9 @@ public class AnnotationBinder {
*/
private void postEntityBindings() {
TableBinder.bind( metadata, index );
FetchProfileBinder.bind( metadata, index );
QueryBinder.bind(metadata, index);
FilterDefBinder.bind(metadata, index);
}
}

View File

@ -23,17 +23,17 @@
*/
package org.hibernate.metamodel.source.annotations.global;
import java.util.Arrays;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.hibernate.MappingException;
import org.hibernate.annotations.FetchMode;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.annotations.FetchProfiles;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.FetchProfile.Fetch;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
@ -42,51 +42,42 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik
*/
public class FetchProfileBinder {
private FetchProfileBinder() {
}
/**
* Binds all {@link org.hibernate.annotations.FetchProfiles} and {@link org.hibernate.annotations.FetchProfile}
* annotations to the specified meta data instance.
* Binds all {@link FetchProfiles} and {@link org.hibernate.annotations.FetchProfile} annotations to the supplied metadata.
*
* @param meta the global metadata
* @param index the annotation index repository
* @param metadata the global metadata
* @param jandex the jandex index
*/
// TODO how to handle fetch profiles defined in hbm and annotations. Which overrides which?
// TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
public static void bind(MetadataImpl meta, Index index) {
// check @FetchProfiles
List<AnnotationInstance> fetchProfilesAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILES );
for ( AnnotationInstance fetchProfilesAnnotation : fetchProfilesAnnotations ) {
AnnotationInstance fetchProfiles[] = fetchProfilesAnnotation.value().asNestedArray();
bindFetchProfileAnnotations( meta, Arrays.asList( fetchProfiles ) );
public static void bind( MetadataImpl metadata,
Index jandex ) {
for (AnnotationInstance fetchProfile : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILE)) {
bind(metadata, jandex, fetchProfile);
}
for (AnnotationInstance fetchProfiles : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILES)) {
for (AnnotationInstance fetchProfile : JandexHelper.getValueAsArray(fetchProfiles, "value")) {
bind(metadata, jandex, fetchProfile);
}
}
}
// check @FetchProfile
List<AnnotationInstance> fetchProfileAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILE );
bindFetchProfileAnnotations( meta, fetchProfileAnnotations );
private static void bind( MetadataImpl metadata,
Index jandex,
AnnotationInstance fetchProfile ) {
String name = JandexHelper.getValueAsString(jandex, fetchProfile, "name");
Set<Fetch> fetches = new HashSet<Fetch>();
for (AnnotationInstance override : JandexHelper.getValueAsArray(fetchProfile, "fetchOverrides")) {
FetchMode fetchMode = JandexHelper.getValueAsEnum(jandex, override, "mode", FetchMode.class);
if (!fetchMode.equals(org.hibernate.annotations.FetchMode.JOIN)) throw new MappingException(
"Only FetchMode.JOIN is currently supported");
fetches.add(new Fetch(JandexHelper.getValueAsString(jandex, override, "entity"),
JandexHelper.getValueAsString(jandex, override, "association"),
fetchMode.toString().toLowerCase()));
}
metadata.addFetchProfile(new FetchProfile(name, fetches));
}
private static void bindFetchProfileAnnotations(MetadataImpl meta, List<AnnotationInstance> fetchProfileAnnotations) {
for ( AnnotationInstance fetchProfileAnnotation : fetchProfileAnnotations ) {
String name = fetchProfileAnnotation.value( "name" ).asString();
FetchProfile profile = meta.findOrCreateFetchProfile( name, MetadataSource.ANNOTATIONS );
AnnotationInstance overrides[] = fetchProfileAnnotation.value( "fetchOverrides" ).asNestedArray();
for ( AnnotationInstance overrideAnnotation : overrides ) {
FetchMode fetchMode = Enum.valueOf( FetchMode.class, overrideAnnotation.value( "mode" ).asEnum() );
if ( !fetchMode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
throw new MappingException( "Only FetchMode.JOIN is currently supported" );
}
String entityClassName = overrideAnnotation.value( "entity" ).asClass().name().toString();
String associationName = overrideAnnotation.value( "association" ).asString();
profile.addFetch(
entityClassName, associationName, fetchMode.toString().toLowerCase()
);
}
}
private FetchProfileBinder() {
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.HashMap;
import java.util.Map;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.FilterDefs;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.type.Type;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
/**
*
*/
public class FilterDefBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, FilterDefBinder.class.getName());
/**
* Binds all {@link FilterDefs} and {@link FilterDef} annotations to the supplied metadata.
*
* @param metadata the global metadata
* @param jandex the jandex index
*/
public static void bind( MetadataImpl metadata,
Index jandex ) {
for (AnnotationInstance filterDef : jandex.getAnnotations(HibernateDotNames.FILTER_DEF)) {
bind(metadata, jandex, filterDef);
}
for (AnnotationInstance filterDefs : jandex.getAnnotations(HibernateDotNames.FILTER_DEFS)) {
for (AnnotationInstance filterDef : JandexHelper.getValueAsArray(filterDefs, "value")) {
bind(metadata, jandex, filterDef);
}
}
}
private static void bind( MetadataImpl metadata,
Index jandex,
AnnotationInstance filterDef ) {
String name = JandexHelper.getValueAsString(jandex, filterDef, "name");
Map<String, Type> prms = new HashMap<String, Type>();
for (AnnotationInstance prm : JandexHelper.getValueAsArray(filterDef, "parameters")) {
prms.put(JandexHelper.getValueAsString(jandex, prm, "name"),
metadata.typeResolver().heuristicType(JandexHelper.getValueAsString(jandex, prm, "type")));
}
metadata.addFilterDef(new FilterDefinition(name, JandexHelper.getValueAsString(jandex, filterDef, "defaultCondition"), prms));
LOG.debugf("Binding filter definition: %s", name);
}
private FilterDefBinder() {
}
}

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.global;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.SequenceGenerator;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.GenericGenerators;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.id.MultipleHiLoPerTableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.SequenceHiLoGenerator;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
/**
*
*/
public class IdGeneratorBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, IdGeneratorBinder.class.getName());
private static void addStringParameter( Index index,
AnnotationInstance annotation,
String element,
Map<String, String> parameters,
String parameter ) {
String string = JandexHelper.getValueAsString(index, annotation, element);
if (StringHelper.isNotEmpty(string)) parameters.put(parameter, string);
}
/**
* Binds all {@link SequenceGenerator}, {@link javax.persistence.TableGenerator}, {@link GenericGenerator}, and {
* {@link GenericGenerators} annotations to the supplied metadata.
*
* @param metadata the global metadata
* @param jandex the jandex index
*/
public static void bind( MetadataImpl metadata,
Index jandex ) {
for (AnnotationInstance generator : jandex.getAnnotations(JPADotNames.SEQUENCE_GENERATOR)) {
bindSequenceGenerator(metadata, jandex, generator);
}
for (AnnotationInstance generator : jandex.getAnnotations(JPADotNames.TABLE_GENERATOR)) {
bindTableGenerator(metadata, jandex, generator);
}
for (AnnotationInstance generator : jandex.getAnnotations(HibernateDotNames.GENERIC_GENERATOR)) {
bindGenericGenerator(metadata, jandex, generator);
}
for (AnnotationInstance generators : jandex.getAnnotations(HibernateDotNames.GENERIC_GENERATORS)) {
for (AnnotationInstance generator : JandexHelper.getValueAsArray(generators, "value")) {
bindGenericGenerator(metadata, jandex, generator);
}
}
}
private static void bindGenericGenerator( MetadataImpl metadata,
Index jandex,
AnnotationInstance generator ) {
String name = JandexHelper.getValueAsString(jandex, generator, "name");
Map<String, String> prms = new HashMap<String, String>();
for (AnnotationInstance prm : JandexHelper.getValueAsArray(generator, "parameters")) {
prms.put(JandexHelper.getValueAsString(jandex, prm, "name"), JandexHelper.getValueAsString(jandex, prm, "value"));
}
metadata.addIdGenerator(new IdGenerator(name, JandexHelper.getValueAsString(jandex, generator, "strategy"), prms));
LOG.tracef("Add generic generator with name: %s", name);
}
private static void bindSequenceGenerator( MetadataImpl metadata,
Index jandex,
AnnotationInstance generator ) {
String name = JandexHelper.getValueAsString(jandex, generator, "name");
String strategy;
Map<String, String> prms = new HashMap<String, String>();
addStringParameter(jandex, generator, "sequenceName", prms, SequenceStyleGenerator.SEQUENCE_PARAM);
if (metadata.getOptions().useNewIdentifierGenerators()) {
strategy = SequenceStyleGenerator.class.getName();
addStringParameter(jandex, generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG);
addStringParameter(jandex, generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA);
prms.put(SequenceStyleGenerator.INCREMENT_PARAM,
String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize")));
prms.put(SequenceStyleGenerator.INITIAL_PARAM,
String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "initialValue")));
} else {
strategy = "seqhilo";
if (JandexHelper.getValueAsInt(jandex, generator, "initialValue") != 1) LOG.unsupportedInitialValue(AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS);
prms.put(SequenceHiLoGenerator.MAX_LO,
String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize") - 1));
}
metadata.addIdGenerator(new IdGenerator(name, strategy, prms));
LOG.tracef("Add sequence generator with name: %s", name);
}
private static void bindTableGenerator( MetadataImpl metadata,
Index jandex,
AnnotationInstance generator ) {
String name = JandexHelper.getValueAsString(jandex, generator, "name");
String strategy;
Map<String, String> prms = new HashMap<String, String>();
addStringParameter(jandex, generator, "catalog", prms, PersistentIdentifierGenerator.CATALOG);
addStringParameter(jandex, generator, "schema", prms, PersistentIdentifierGenerator.SCHEMA);
if (metadata.getOptions().useNewIdentifierGenerators()) {
strategy = TableGenerator.class.getName();
prms.put(TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, "true");
addStringParameter(jandex, generator, "table", prms, TableGenerator.TABLE_PARAM);
addStringParameter(jandex, generator, "pkColumnName", prms, TableGenerator.SEGMENT_COLUMN_PARAM);
addStringParameter(jandex, generator, "pkColumnValue", prms, TableGenerator.SEGMENT_VALUE_PARAM);
addStringParameter(jandex, generator, "valueColumnName", prms, TableGenerator.VALUE_COLUMN_PARAM);
prms.put(TableGenerator.INCREMENT_PARAM,
String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize")));
prms.put(TableGenerator.INITIAL_PARAM,
String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "initialValue") + 1));
} else {
strategy = MultipleHiLoPerTableGenerator.class.getName();
addStringParameter(jandex, generator, "table", prms, MultipleHiLoPerTableGenerator.ID_TABLE);
addStringParameter(jandex, generator, "pkColumnName", prms, MultipleHiLoPerTableGenerator.PK_COLUMN_NAME);
addStringParameter(jandex, generator, "pkColumnValue", prms, MultipleHiLoPerTableGenerator.PK_VALUE_NAME);
addStringParameter(jandex, generator, "valueColumnName", prms, MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME);
prms.put(TableHiLoGenerator.MAX_LO, String.valueOf(JandexHelper.getValueAsInt(jandex, generator, "allocationSize") - 1));
}
if (JandexHelper.getValueAsArray(generator, "uniqueConstraints").length > 0) LOG.ignoringTableGeneratorConstraints(name);
metadata.addIdGenerator(new IdGenerator(name, strategy, prms));
LOG.tracef("Add table generator with name: %s", name);
}
private IdGeneratorBinder() {
}
}

View File

@ -23,22 +23,221 @@
*/
package org.hibernate.metamodel.source.annotations.global;
import org.jboss.jandex.Index;
import java.util.HashMap;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import org.hibernate.AnnotationException;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.LockMode;
import org.hibernate.annotations.QueryHints;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
/**
* @author Hardy Ferentschik
*/
public class QueryBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, QueryBinder.class.getName());
/**
* Binds all {@link NamedQuery}, {@link NamedQueries}, {@link NamedNativeQuery}, {{@link NamedNativeQueries},
* {@link org.hibernate.annotations.NamedQuery} , {@link org.hibernate.annotations.NamedQueries},
* {@link org.hibernate.annotations.NamedNativeQuery}, and {@link org.hibernate.annotations.NamedNativeQueries} annotations to
* the supplied metadata.
*
* @param metadata the global metadata
* @param jandex the jandex index
*/
public static void bind( MetadataImpl metadata,
Index jandex ) {
for (AnnotationInstance query : jandex.getAnnotations(JPADotNames.NAMED_QUERY)) {
bindNamedQuery(metadata, jandex, query);
}
for (AnnotationInstance queries : jandex.getAnnotations(JPADotNames.NAMED_QUERIES)) {
for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
bindNamedQuery(metadata, jandex, query);
}
}
for (AnnotationInstance query : jandex.getAnnotations(JPADotNames.NAMED_NATIVE_QUERY)) {
bindNamedNativeQuery(metadata, jandex, query);
}
for (AnnotationInstance queries : jandex.getAnnotations(JPADotNames.NAMED_NATIVE_QUERIES)) {
for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
bindNamedNativeQuery(metadata, jandex, query);
}
}
for (AnnotationInstance query : jandex.getAnnotations(HibernateDotNames.NAMED_QUERY)) {
bindNamedQuery(metadata, jandex, query);
}
for (AnnotationInstance queries : jandex.getAnnotations(HibernateDotNames.NAMED_QUERIES)) {
for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
bindNamedQuery(metadata, jandex, query);
}
}
for (AnnotationInstance query : jandex.getAnnotations(HibernateDotNames.NAMED_NATIVE_QUERY)) {
bindNamedNativeQuery(metadata, jandex, query);
}
for (AnnotationInstance queries : jandex.getAnnotations(HibernateDotNames.NAMED_NATIVE_QUERIES)) {
for (AnnotationInstance query : JandexHelper.getValueAsArray(queries, "value")) {
bindNamedNativeQuery(metadata, jandex, query);
}
}
}
private static void bindNamedQuery( MetadataImpl metadata,
Index jandex,
AnnotationInstance annotation ) {
String name = JandexHelper.getValueAsString(jandex, annotation, "name");
if (StringHelper.isEmpty(name)) throw new AnnotationException(
"A named query must have a name when used in class or package level");
String query = JandexHelper.getValueAsString(jandex, annotation, "query");
AnnotationInstance[] hints = JandexHelper.getValueAsArray(annotation, "hints");
String cacheRegion = getString(jandex, hints, QueryHints.CACHE_REGION);
if (StringHelper.isEmpty(cacheRegion)) cacheRegion = null;
Integer timeout = getTimeout(jandex, hints, query);
if (timeout != null && timeout < 0) timeout = null;
Integer fetchSize = getInteger(jandex, hints, QueryHints.FETCH_SIZE, name);
if (fetchSize != null && fetchSize < 0) fetchSize = null;
String comment = getString(jandex, hints, QueryHints.COMMENT);
if (StringHelper.isEmpty(comment)) comment = null;
metadata.addNamedQuery(name,
new NamedQueryDefinition(query, getBoolean(jandex, hints, QueryHints.CACHEABLE, name), cacheRegion,
timeout, fetchSize,
getFlushMode(jandex, hints, QueryHints.FLUSH_MODE, name),
getCacheMode(jandex, hints, QueryHints.CACHE_MODE, name),
getBoolean(jandex, hints, QueryHints.READ_ONLY, name), comment, null));
LOG.debugf("Binding named query: %s => %s", name, query);
}
private static void bindNamedNativeQuery( MetadataImpl metadata,
Index jandex,
AnnotationInstance annotation ) {
String name = JandexHelper.getValueAsString(jandex, annotation, "name");
if (StringHelper.isEmpty(name)) throw new AnnotationException(
"A named native query must have a name when used in class or package level");
String query = JandexHelper.getValueAsString(jandex, annotation, "query");
String resultSetMapping = JandexHelper.getValueAsString(jandex, annotation, "resultSetMapping");
AnnotationInstance[] hints = JandexHelper.getValueAsArray(annotation, "hints");
boolean cacheable = getBoolean(jandex, hints, "org.hibernate.cacheable", name);
String cacheRegion = getString(jandex, hints, QueryHints.CACHE_REGION);
if (StringHelper.isEmpty(cacheRegion)) cacheRegion = null;
Integer timeout = getTimeout(jandex, hints, query);
if (timeout != null && timeout < 0) timeout = null;
Integer fetchSize = getInteger(jandex, hints, QueryHints.FETCH_SIZE, name);
if (fetchSize != null && fetchSize < 0) fetchSize = null;
FlushMode flushMode = getFlushMode(jandex, hints, QueryHints.FLUSH_MODE, name);
CacheMode cacheMode = getCacheMode(jandex, hints, QueryHints.CACHE_MODE, name);
boolean readOnly = getBoolean(jandex, hints, QueryHints.READ_ONLY, name);
String comment = getString(jandex, hints, QueryHints.COMMENT);
if (StringHelper.isEmpty(comment)) comment = null;
boolean callable = getBoolean(jandex, hints, QueryHints.CALLABLE, name);
NamedSQLQueryDefinition def;
if (StringHelper.isNotEmpty(resultSetMapping)) def = new NamedSQLQueryDefinition(query, resultSetMapping, null, cacheable,
cacheRegion, timeout, fetchSize,
flushMode, cacheMode, readOnly, comment,
null, callable);
else {
String resultClass = JandexHelper.getValueAsString(jandex, annotation, "resultClass");
if (void.class.equals(resultClass)) throw new NotYetImplementedException(
"Pure native scalar queries are not yet supported");
def = new NamedSQLQueryDefinition(query, new NativeSQLQueryRootReturn[] {new NativeSQLQueryRootReturn("alias1",
resultClass,
new HashMap(),
LockMode.READ)},
null, cacheable, cacheRegion, timeout, fetchSize, flushMode, cacheMode, readOnly,
comment, null, callable);
}
metadata.addNamedNativeQuery(name, def);
LOG.debugf("Binding named native query: %s => %s", name, query);
}
private static boolean getBoolean( Index jandex,
AnnotationInstance[] hints,
String element,
String query ) {
String val = getString(jandex, hints, element);
if (val == null || val.equalsIgnoreCase("false")) return false;
if (val.equalsIgnoreCase("true")) return true;
throw new AnnotationException("Not a boolean in hint: " + query + ":" + element);
}
private static CacheMode getCacheMode( Index jandex,
AnnotationInstance[] hints,
String element,
String query ) {
String val = getString(jandex, hints, element);
if (val == null) return null;
if (val.equalsIgnoreCase(CacheMode.GET.toString())) return CacheMode.GET;
if (val.equalsIgnoreCase(CacheMode.IGNORE.toString())) return CacheMode.IGNORE;
if (val.equalsIgnoreCase(CacheMode.NORMAL.toString())) return CacheMode.NORMAL;
if (val.equalsIgnoreCase(CacheMode.PUT.toString())) return CacheMode.PUT;
if (val.equalsIgnoreCase(CacheMode.REFRESH.toString())) return CacheMode.REFRESH;
throw new AnnotationException("Unknown CacheMode in hint: " + query + ":" + element);
}
private static FlushMode getFlushMode( Index jandex,
AnnotationInstance[] hints,
String element,
String query ) {
String val = getString(jandex, hints, element);
if (val == null) return null;
if (val.equalsIgnoreCase(FlushMode.ALWAYS.toString())) return FlushMode.ALWAYS;
else if (val.equalsIgnoreCase(FlushMode.AUTO.toString())) return FlushMode.AUTO;
else if (val.equalsIgnoreCase(FlushMode.COMMIT.toString())) return FlushMode.COMMIT;
else if (val.equalsIgnoreCase(FlushMode.NEVER.toString())) return FlushMode.MANUAL;
else if (val.equalsIgnoreCase(FlushMode.MANUAL.toString())) return FlushMode.MANUAL;
else throw new AnnotationException("Unknown FlushMode in hint: " + query + ":" + element);
}
private static Integer getInteger( Index jandex,
AnnotationInstance[] hints,
String element,
String query ) {
String val = getString(jandex, hints, element);
if (val == null) return null;
try {
return Integer.decode(val);
} catch (NumberFormatException nfe) {
throw new AnnotationException("Not an integer in hint: " + query + ":" + element, nfe);
}
}
private static String getString( Index jandex,
AnnotationInstance[] hints,
String element ) {
for (AnnotationInstance hint : hints) {
if (element.equals(JandexHelper.getValue(jandex, hint, "name"))) return JandexHelper.getValueAsString(jandex,
hint,
"value");
}
return null;
}
private static Integer getTimeout( Index jandex,
AnnotationInstance[] hints,
String query ) {
Integer timeout = getInteger(jandex, hints, QueryHints.TIMEOUT_JPA, query);
if (timeout == null) return getInteger(jandex, hints, QueryHints.TIMEOUT_HIBERNATE, query); // timeout is already in seconds
return new Integer((int)Math.round(timeout.doubleValue() / 1000.0)); // convert milliseconds to seconds
}
private QueryBinder() {
}
public static void bindNamedQuery(MetadataImpl meta, Index index) {
}
public static void bindNativeNamedQuery(MetadataImpl meta, Index index) {
}
}

View File

@ -23,21 +23,19 @@
*/
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.internal.util.StringHelper;
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.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
@ -46,93 +44,77 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik
*/
public class TableBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, TableBinder.class.getName()
);
private TableBinder() {
}
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TableBinder.class.getName());
/**
* Binds {@link org.hibernate.annotations.Tables} and {@link org.hibernate.annotations.Table}
* annotations to the specified meta data instance.
* Binds {@link org.hibernate.annotations.Tables} and {@link org.hibernate.annotations.Table} annotations to the supplied
* metadata.
*
* @param meta the global metadata
* @param index the annotation index repository
* @param metadata the global metadata
* @param jandex 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 ) );
public static void bind( MetadataImpl metadata,
Index jandex ) {
for (AnnotationInstance tableAnnotation : jandex.getAnnotations(HibernateDotNames.TABLE)) {
bind(metadata, jandex, tableAnnotation);
}
// check @o.h.a.Table
List<AnnotationInstance> tableAnnotations = index.getAnnotations( HibernateDotNames.TABLE );
bindTablesAnnotation( meta, tableAnnotations );
for (AnnotationInstance tables : jandex.getAnnotations(HibernateDotNames.TABLES)) {
for (AnnotationInstance table : JandexHelper.getValueAsArray(tables, "value")) {
bind(metadata, jandex, table);
}
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 );
}
private static void bind( MetadataImpl metadata,
Index jandex,
AnnotationInstance tableAnnotation ) {
String tableName = JandexHelper.getValueAsString(jandex, tableAnnotation, "appliesTo");
ObjectName objectName = new ObjectName(tableName);
Schema schema = metadata.getDatabase().getSchema(objectName.getSchema(), objectName.getCatalog());
Table table = schema.getTable(objectName.getName());
if (table != null) bindHibernateTableAnnotation(jandex, table, tableAnnotation);
}
if ( tableAnnotation.value( "comment" ) != null ) {
table.addComment( tableAnnotation.value( "comment" ).asString().trim() );
private static void bindHibernateTableAnnotation( Index jandex,
Table table,
AnnotationInstance tableAnnotation ) {
for (AnnotationInstance indexAnnotation : JandexHelper.getValueAsArray(tableAnnotation, "indexes")) {
bindIndexAnnotation(jandex, table, indexAnnotation);
}
String comment = JandexHelper.getValueAsString(jandex, tableAnnotation, "comment");
if (StringHelper.isNotEmpty(comment)) table.addComment(comment.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() );
private static void bindIndexAnnotation( Index jandex,
Table table,
AnnotationInstance indexAnnotation ) {
String indexName = JandexHelper.getValueAsString(jandex, indexAnnotation, "appliesTo");
String[] columnNames = (String[])JandexHelper.getValue(jandex, indexAnnotation, "columnNames");
if (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 );
org.hibernate.metamodel.relational.Index index = table.getOrCreateIndex(indexName);
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) {
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;
for (SimpleValue value : table.values()) {
if (value instanceof Column && ((Column)value).getName().equals(columnName)) {
column = (Column)value;
break;
}
}
return column;
}
private TableBinder() {
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.HashMap;
import java.util.Map;
import org.hibernate.AnnotationException;
import org.hibernate.annotations.TypeDefs;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
/**
*
*/
public class TypeDefBinder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TypeDefBinder.class.getName());
/**
* Binds all {@link org.hibernate.annotations.TypeDef} and {@link TypeDefs} annotations to the supplied metadata.
*
* @param metadata the global metadata
* @param jandex the jandex jandex
*/
public static void bind( MetadataImpl metadata,
Index jandex ) {
for (AnnotationInstance typeDef : jandex.getAnnotations(HibernateDotNames.TYPE_DEF)) {
bind(metadata, jandex, typeDef);
}
for (AnnotationInstance typeDefs : jandex.getAnnotations(HibernateDotNames.TYPE_DEFS)) {
for (AnnotationInstance typeDef : JandexHelper.getValueAsArray(typeDefs, "value")) {
bind(metadata, jandex, typeDef);
}
}
}
private static void bind( String name,
String typeClass,
Map<String, String> prms,
MetadataImpl metadata ) {
LOG.debugf("Binding type definition: %s", name);
metadata.addTypeDef(name, new TypeDef(typeClass, prms));
}
private static void bind( MetadataImpl metadata,
Index jandex,
AnnotationInstance typeDef ) {
String name = JandexHelper.getValueAsString(jandex, typeDef, "name");
String defaultForType = JandexHelper.getValueAsString(jandex, typeDef, "defaultForType");
String typeClass = JandexHelper.getValueAsString(jandex, typeDef, "typeClass");
boolean noName = StringHelper.isEmpty(name);
boolean noDefaultForType = defaultForType == null || defaultForType.equals(void.class.getName());
if (noName && noDefaultForType) throw new AnnotationException(
"Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass "
+ typeClass);
Map<String, String> prms = new HashMap<String, String>();
for (AnnotationInstance prm : JandexHelper.getValueAsArray(typeDef, "parameters")) {
prms.put(JandexHelper.getValueAsString(jandex, prm, "name"), JandexHelper.getValueAsString(jandex, prm, "value"));
}
if (!noName) bind(name, typeClass, prms, metadata);
if (!noDefaultForType) bind(defaultForType, typeClass, prms, metadata);
}
private TypeDefBinder() {
}
}

View File

@ -33,6 +33,7 @@ import java.util.Map;
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;
@ -40,6 +41,7 @@ import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.jboss.jandex.MethodInfo;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.service.classloading.spi.ClassLoaderService;
@ -50,7 +52,27 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Hardy Ferentschik
*/
public class JandexHelper {
private JandexHelper() {
private static final AnnotationInstance[] EMPTY_ANNOTATIONS_ARRAY = new AnnotationInstance[0];
private static final Map<String, Object> DEFAULT_VALUES_BY_ELEMENT = new HashMap<String, Object>();
private static Object getDefaultValue( Index index,
AnnotationInstance annotation,
String element ) {
String name = annotation.name().toString();
String fqElement = name + '.' + element;
Object val = DEFAULT_VALUES_BY_ELEMENT.get(fqElement);
if (val != null) return val;
try {
val = Index.class.getClassLoader().loadClass(name).getMethod(element).getDefaultValue();
DEFAULT_VALUES_BY_ELEMENT.put(fqElement, val);
return val == null ? null : val;
} catch (RuntimeException error) {
throw error;
} catch (Exception error) {
throw new AnnotationException(error);
}
}
/**
@ -126,6 +148,98 @@ public class JandexHelper {
}
}
/**
* Retrieves a jandex annotation element value. If the value is <code>null</code>, the default value specified in the
* annotation class is retrieved instead. Note, {@link #getValueAsEnum(Index, AnnotationInstance, String, Class)} must be
* called to retrieve an enumerated value, and {@link #getValueAsArray(AnnotationInstance, String)} must be called to retrieve
* an object array (other than a String array).
*
* @param index the jandex index containing the supplied annotation
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
* @return the value if not <code>null</code>, else the default value if not
* <code>null</code>, else <code>null</code>.
*/
public static Object getValue( Index index,
AnnotationInstance annotation,
String element ) {
AnnotationValue val = annotation.value(element);
if (val == null) return getDefaultValue(index, annotation, element);
return val.asNested();
}
/**
* Retrieves a jandex annotation element array. Note, {@link #getValue(Index, AnnotationInstance, String)} may be
* called to retrieve a String array (or a non-array value).
*
* @param annotation the jandex annotation containing the element with the supplied name
* @param element the name of the element array
* @return the element array if not <code>null</code>, else an empty array
*/
public static AnnotationInstance[] getValueAsArray( AnnotationInstance annotation,
String element ) {
AnnotationValue val = annotation.value(element);
return val == null ? EMPTY_ANNOTATIONS_ARRAY : val.asNestedArray();
}
/**
* Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is
* <code>null</code>, the default value specified in the annotation class is retrieved instead.
*
* @param <T> an enumerated type
* @param index the jandex index containing the supplied annotation
* @param annotation the annotation containing the enumerated element with the supplied name
* @param element the name of the enumerated element value to be retrieve
* @param type the type to which to convert the value before being returned
* @return the value converted to the supplied enumerated type if the value is not <code>null</code>, else the default value if
* not <code>null</code>, else <code>null</code>.
* @see #getValue(Index, AnnotationInstance, String)
*/
public static <T extends Enum<T>> T getValueAsEnum( Index index,
AnnotationInstance annotation,
String element,
Class<T> type ) {
AnnotationValue val = annotation.value(element);
if (val == null) return (T)getDefaultValue(index, annotation, element);
return Enum.valueOf(type, val.asEnum());
}
/**
* Retrieves a jandex annotation element value as an Integer. If the value is <code>null</code>, the default value specified in
* the annotation class is retrieved instead.
*
* @param index the jandex index containing the supplied annotation
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
* @return the value converted to an int if the value is not <code>null</code>, else the default value if not
* <code>null</code>, else <code>0</code>.
*/
public static int getValueAsInt( Index index,
AnnotationInstance annotation,
String element ) {
AnnotationValue val = annotation.value(element);
if (val == null) return (Integer)getDefaultValue(index, annotation, element);
return val.asInt();
}
/**
* Retrieves a jandex annotation element value as a String. If the value is <code>null</code>, the default value specified in
* the annotation class is retrieved instead.
*
* @param index the jandex index containing the supplied annotation
* @param annotation the annotation containing the element with the supplied name
* @param element the name of the element value to be retrieve
* @return the value converted to a String if the value is not <code>null</code>, else the default value if not
* <code>null</code>, else <code>null</code>.
*/
public static String getValueAsString( Index index,
AnnotationInstance annotation,
String element ) {
AnnotationValue val = annotation.value(element);
if (val == null) return (String)getDefaultValue(index, annotation, element);
return val.asString();
}
/**
* Creates a jandex index for the specified classes
*
@ -216,6 +330,7 @@ public class JandexHelper {
}
list.add( instance );
}
private JandexHelper() {
}
}

View File

@ -23,18 +23,19 @@
*/
package org.hibernate.metamodel.source.hbm;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Attribute;
import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.FetchProfile.Fetch;
import org.hibernate.metamodel.domain.MetaAttribute;
import org.hibernate.metamodel.source.Origin;
import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.metamodel.source.hbm.util.MappingHelper;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement.XMLFetch;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
@ -45,7 +46,7 @@ import org.hibernate.metamodel.source.hbm.xml.mapping.XMLQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement;
import org.hibernate.metamodel.source.hbm.util.MappingHelper;
import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.service.ServiceRegistry;
/**
@ -225,14 +226,15 @@ public class HibernateMappingBinder implements MappingDefaults {
protected void parseFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) {
for ( XMLFetchProfileElement fetchProfile : fetchProfiles ) {
String profileName = fetchProfile.getName();
org.hibernate.metamodel.binding.FetchProfile profile = hibernateXmlBinder.getMetadata().findOrCreateFetchProfile( profileName, MetadataSource.HBM );
Set<Fetch> fetches = new HashSet<Fetch>();
for ( XMLFetch fetch : fetchProfile.getFetch() ) {
String entityName = fetch.getEntity() == null ? containingEntityName : fetch.getEntity();
if ( entityName == null ) {
throw new MappingException( "could not determine entity for fetch-profile fetch [" + profileName + "]:[" + fetch.getAssociation() + "]" );
}
profile.addFetch( entityName, fetch.getAssociation(), fetch.getStyle() );
fetches.add(new Fetch(entityName, fetch.getAssociation(), fetch.getStyle()));
}
hibernateXmlBinder.getMetadata().addFetchProfile( new FetchProfile(profileName, fetches));
}
}

View File

@ -30,21 +30,21 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.jboss.logging.Logger;
import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.SourceProcessingOrder;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.relational.Database;
@ -56,6 +56,7 @@ import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.spi.MetadataImplementor;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.type.TypeResolver;
/**
* Container for configuration data collected during binding the metamodel.
@ -63,15 +64,15 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Steve Ebersole
* @author Hardy Ferentschik
*/
public class MetadataImpl implements Metadata, MetadataImplementor, Serializable {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, MetadataImpl.class.getName()
);
public class MetadataImpl implements MetadataImplementor, Serializable {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataImpl.class.getName());
private final BasicServiceRegistry serviceRegistry;
private final Options options;
private final Database database = new Database();
private TypeResolver typeResolver = new TypeResolver();
/**
* Maps the fully qualified class name of an entity to its entity binding
@ -79,8 +80,12 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
private Map<String, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
private Map<String, TypeDef> typeDefs = new HashMap<String, TypeDef>();
private Map<String, String> imports;
private Map<String, TypeDef> typeDefs = new HashMap<String, TypeDef>();
private Map<String, IdGenerator> idGenerators = new HashMap<String, IdGenerator>();
private Map<String, NamedQueryDefinition> namedQueryDefs = new HashMap<String, NamedQueryDefinition>();
private Map<String, NamedSQLQueryDefinition> namedNativeQueryDefs = new HashMap<String, NamedSQLQueryDefinition>();
private Map<String, FilterDefinition> filterDefs = new HashMap<String, FilterDefinition>();
public MetadataImpl(MetadataSources metadataSources, Options options) {
this.serviceRegistry = metadataSources.getServiceRegistry();
@ -99,6 +104,33 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
new EntityReferenceResolver( this ).resolve();
}
public void addFetchProfile( FetchProfile profile ) {
fetchProfiles.put(profile.getName(), profile);
}
public void addFilterDef( FilterDefinition def ) {
filterDefs.put(def.getFilterName(), def);
}
public void addIdGenerator( IdGenerator generator ) {
idGenerators.put(generator.getName(), generator);
}
public void addNamedNativeQuery( String name,
NamedSQLQueryDefinition def ) {
namedNativeQueryDefs.put(name, def);
}
public void addNamedQuery( String name,
NamedQueryDefinition def ) {
namedQueryDefs.put(name, def);
}
public void addTypeDef(String name, TypeDef typeDef) {
// TODO - should we check whether the typedef already exists? Log it? Exception? (HF)
typeDefs.put( name, typeDef );
}
private void applyHibernateMappings(MetadataSources metadataSources, List<String> processedEntityNames) {
final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
for ( JaxbRoot jaxbRoot : metadataSources.getJaxbRootList() ) {
@ -223,25 +255,15 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
}
}
public Iterable<FetchProfile> getFetchProfiles() {
return fetchProfiles.values();
}
public void addTypeDef(String name, TypeDef typeDef) {
// TODO - should we check whether the typedef already exists? Log it? Exception? (HF)
typeDefs.put( name, typeDef );
}
public TypeDef getTypeDef(String name) {
return typeDefs.get( name );
}
public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) {
FetchProfile profile = fetchProfiles.get( profileName );
if ( profile == null ) {
profile = new FetchProfile( profileName, source );
fetchProfiles.put( profileName, profile );
public Iterable<FetchProfile> getFetchProfiles() {
return fetchProfiles.values();
}
return profile;
public TypeResolver typeResolver() {
return typeResolver;
}
}

View File

@ -23,7 +23,6 @@
*/
package org.hibernate.metamodel.source.spi;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
@ -47,5 +46,5 @@ public interface MetadataImplementor extends Metadata {
public void addCollection(PluralAttributeBinding collectionBinding);
public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource hbm);
public void addFetchProfile( FetchProfile profile );
}

View File

@ -23,10 +23,17 @@
*/
package org.hibernate.metamodel.source.annotations.util;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import java.util.Map;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.LockModeType;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
@ -36,6 +43,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
@ -88,6 +96,49 @@ public class JandexHelperTest extends BaseUnitTestCase {
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" );
assertTrue( "there should be no annotations in fubar", memberAnnotations.isEmpty() );
}
@Test
public void shouldRetrieveDefaultOfUnspecifiedAnnotationElement() {
@NamedQuery(name="foo", query="bar")
@SequenceGenerator(name="fu")
class Foo {
}
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
assertThat(JandexHelper.getValueAsEnum(index, query, "lockMode", LockModeType.class), is(LockModeType.NONE));
}
for (AnnotationInstance generator : index.getAnnotations( JPADotNames.SEQUENCE_GENERATOR)) {
assertThat(JandexHelper.getValueAsInt(index, generator, "allocationSize"), is(50));
}
}
@Test
public void shouldRetrieveValueOfAnnotationElement() {
@NamedQuery(name="foo", query="bar")
class Foo {
}
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
assertThat(JandexHelper.getValueAsString(index, query, "name"), is("foo"));
}
}
@Test
public void shouldRetrieveValueOfEnumeratedAnnotationElement() {
@NamedQuery(name="foo", query="bar", lockMode=LockModeType.OPTIMISTIC)
class Foo {
}
Index index = JandexHelper.indexForClass(classLoaderService, Foo.class);
for (AnnotationInstance query : index.getAnnotations( JPADotNames.NAMED_QUERY)) {
assertThat(JandexHelper.getValueAsEnum(index, query, "lockMode", LockModeType.class), is(LockModeType.OPTIMISTIC));
}
}
}