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

View File

@ -22,52 +22,47 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.metamodel.binding; package org.hibernate.metamodel.binding;
import java.io.Serializable; import java.io.Serializable;
import java.util.Properties; import java.util.Collections;
import java.util.Map;
/** /**
* Identifier generator container, * Identifier generator container, Useful to keep named generator in annotations
* Useful to keep named generator in annotations
* *
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
public class IdGenerator implements Serializable { public class IdGenerator implements Serializable {
private String name; private final String name;
private String identifierGeneratorStrategy; private final String strategy;
private Properties params = new Properties(); 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 * @return identifier generator strategy
*/ */
public String getIdentifierGeneratorStrategy() { public String getStrategy() {
return identifierGeneratorStrategy; return strategy;
} }
/** /**
* @return generator name * @return generator name
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/**
* @return generator configuration parameters
*/
public Properties getParams() {
return params;
}
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 );
}
/**
* @return generator configuration parameters
*/
public Map<String, String> getParameters() {
return Collections.unmodifiableMap(parameters);
}
} }

View File

@ -22,27 +22,30 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.metamodel.binding; package org.hibernate.metamodel.binding;
import java.io.Serializable; import java.io.Serializable;
import java.util.Properties; import java.util.Collections;
import java.util.Map;
/** /**
* Placeholder for typedef information * Placeholder for typedef information
*/ */
public class TypeDef implements Serializable { public class TypeDef implements Serializable {
private String typeClass; private final String typeClass;
private Properties parameters; private final Map<String, String> parameters;
public TypeDef(String typeClass, Properties parameters) { public TypeDef( String typeClass,
this.typeClass = typeClass; Map<String, String> parameters ) {
this.parameters = parameters; this.typeClass = typeClass;
} this.parameters = parameters;
}
public Properties getParameters() { public Map<String, String> getParameters() {
return parameters; return Collections.unmodifiableMap(parameters);
} }
public String getTypeClass() {
return typeClass;
}
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.ConfiguredClass;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy; import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
import org.hibernate.metamodel.source.annotations.entity.EntityBinder; 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.FetchProfileBinder;
import org.hibernate.metamodel.source.annotations.global.TableBinder; import org.hibernate.metamodel.source.annotations.global.TableBinder;
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder; import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
@ -45,7 +49,9 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class AnnotationBinder { 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 MetadataImpl metadata;
private final Index index; 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. * Binds global configuration data prior to entity binding. This includes generators and type definitions.
*/ */
private void preEntityBindings() { 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 // now we process each hierarchy one at the time
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) { for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
for ( ConfiguredClass configuredClass : hierarchy ) { 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 entityBinder = new EntityBinder( metadata, configuredClass );
entityBinder.bind(); entityBinder.bind();
} }
@ -92,6 +99,9 @@ public class AnnotationBinder {
*/ */
private void postEntityBindings() { private void postEntityBindings() {
TableBinder.bind( metadata, index ); 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; package org.hibernate.metamodel.source.annotations.global;
import java.util.Arrays; import java.util.HashSet;
import java.util.List; import java.util.Set;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index; import org.jboss.jandex.Index;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.annotations.FetchMode; 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;
import org.hibernate.metamodel.binding.FetchProfile.Fetch;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; 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.metamodel.source.internal.MetadataImpl;
/** /**
@ -42,51 +42,42 @@ import org.hibernate.metamodel.source.internal.MetadataImpl;
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class FetchProfileBinder { public class FetchProfileBinder {
private FetchProfileBinder() {
}
/** /**
* Binds all {@link org.hibernate.annotations.FetchProfiles} and {@link org.hibernate.annotations.FetchProfile} * Binds all {@link FetchProfiles} and {@link org.hibernate.annotations.FetchProfile} annotations to the supplied metadata.
* annotations to the specified meta data instance. *
* * @param metadata the global metadata
* @param meta the global metadata * @param jandex the jandex index
* @param index the annotation index repository */
*/ // TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass
// TODO how to handle fetch profiles defined in hbm and annotations. Which overrides which? public static void bind( MetadataImpl metadata,
// TODO verify that association exists. See former VerifyFetchProfileReferenceSecondPass Index jandex ) {
public static void bind(MetadataImpl meta, Index index) { for (AnnotationInstance fetchProfile : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILE)) {
// check @FetchProfiles bind(metadata, jandex, fetchProfile);
List<AnnotationInstance> fetchProfilesAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILES ); }
for ( AnnotationInstance fetchProfilesAnnotation : fetchProfilesAnnotations ) { for (AnnotationInstance fetchProfiles : jandex.getAnnotations(HibernateDotNames.FETCH_PROFILES)) {
AnnotationInstance fetchProfiles[] = fetchProfilesAnnotation.value().asNestedArray(); for (AnnotationInstance fetchProfile : JandexHelper.getValueAsArray(fetchProfiles, "value")) {
bindFetchProfileAnnotations( meta, Arrays.asList( fetchProfiles ) ); bind(metadata, jandex, fetchProfile);
} }
}
}
// check @FetchProfile private static void bind( MetadataImpl metadata,
List<AnnotationInstance> fetchProfileAnnotations = index.getAnnotations( HibernateDotNames.FETCH_PROFILE ); Index jandex,
bindFetchProfileAnnotations( meta, fetchProfileAnnotations ); 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) { private FetchProfileBinder() {
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()
);
}
}
}
} }

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; 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.hibernate.metamodel.source.internal.MetadataImpl;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
/** /**
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class QueryBinder { public class QueryBinder {
private QueryBinder() {
}
public static void bindNamedQuery(MetadataImpl meta, Index index) { private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, QueryBinder.class.getName());
}
public static void bindNativeNamedQuery(MetadataImpl meta, Index index) { /**
} * 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() {
}
} }

View File

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

@ -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.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo; import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo; import org.jboss.jandex.FieldInfo;
@ -40,6 +41,7 @@ import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer; import org.jboss.jandex.Indexer;
import org.jboss.jandex.MethodInfo; import org.jboss.jandex.MethodInfo;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.service.classloading.spi.ClassLoaderService;
@ -50,172 +52,285 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class JandexHelper { public class JandexHelper {
private JandexHelper() {
}
/** private static final AnnotationInstance[] EMPTY_ANNOTATIONS_ARRAY = new AnnotationInstance[0];
* Expects a method or field annotation target and returns the property name for this target
*
* @param target the annotation target
*
* @return the property name of the target. For a field it is the field name and for a method name it is
* the method name stripped of 'is', 'has' or 'get'
*/
public static String getPropertyName(AnnotationTarget target) {
if ( !( target instanceof MethodInfo || target instanceof FieldInfo ) ) {
throw new AssertionFailure( "Unexpected annotation target " + target.toString() );
}
if ( target instanceof FieldInfo ) { private static final Map<String, Object> DEFAULT_VALUES_BY_ELEMENT = new HashMap<String, Object>();
return ( (FieldInfo) target ).name();
}
else {
String methodName = ( (MethodInfo) target ).name();
if ( methodName.startsWith( "is" ) ) {
methodName = Introspector.decapitalize( methodName.substring( 2 ) );
}
else if ( methodName.startsWith( "has" ) ) {
methodName = Introspector.decapitalize( methodName.substring( 3 ) );
}
else if ( methodName.startsWith( "get" ) ) {
methodName = Introspector.decapitalize( methodName.substring( 3 ) );
}
else {
throw new AssertionFailure( "Expected a method following the Java Bean notation" );
}
return methodName;
}
}
/** private static Object getDefaultValue( Index index,
* @param classInfo the class info from which to retrieve the annotation instance AnnotationInstance annotation,
* @param annotationName the annotation to retrieve from the class info String element ) {
* String name = annotation.name().toString();
* @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all String fqElement = name + '.' + element;
* Object val = DEFAULT_VALUES_BY_ELEMENT.get(fqElement);
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type. if (val != null) return val;
*/ try {
public static AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName) val = Index.class.getClassLoader().loadClass(name).getMethod(element).getDefaultValue();
throws AssertionFailure { DEFAULT_VALUES_BY_ELEMENT.put(fqElement, val);
return getSingleAnnotation( classInfo.annotations(), annotationName ); return val == null ? null : val;
} } catch (RuntimeException error) {
throw error;
} catch (Exception error) {
throw new AnnotationException(error);
}
}
/** /**
* @param annotations List of annotation instances keyed against their dot name. * Expects a method or field annotation target and returns the property name for this target
* @param annotationName the annotation to retrieve from map *
* * @param target the annotation target
* @return the single annotation of the specified dot name or {@code null} in case the annotation is not specified at all *
* * @return the property name of the target. For a field it is the field name and for a method name it is
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type. * the method name stripped of 'is', 'has' or 'get'
*/ */
public static AnnotationInstance getSingleAnnotation(Map<DotName, List<AnnotationInstance>> annotations, DotName annotationName) public static String getPropertyName(AnnotationTarget target) {
throws AssertionFailure { if ( !( target instanceof MethodInfo || target instanceof FieldInfo ) ) {
List<AnnotationInstance> annotationList = annotations.get( annotationName ); throw new AssertionFailure( "Unexpected annotation target " + target.toString() );
if ( annotationList == null ) { }
return null;
}
else if ( annotationList.size() == 1 ) {
return annotationList.get( 0 );
}
else {
throw new AssertionFailure(
"Found more than one instance of the annotation "
+ annotationList.get( 0 ).name().toString()
+ ". Expected was one."
);
}
}
/** if ( target instanceof FieldInfo ) {
* Creates a jandex index for the specified classes return ( (FieldInfo) target ).name();
* }
* @param classLoaderService class loader service else {
* @param classes the classes to index String methodName = ( (MethodInfo) target ).name();
* if ( methodName.startsWith( "is" ) ) {
* @return an annotation repository w/ all the annotation discovered in the specified classes methodName = Introspector.decapitalize( methodName.substring( 2 ) );
*/ }
public static Index indexForClass(ClassLoaderService classLoaderService, Class<?>... classes) { else if ( methodName.startsWith( "has" ) ) {
Indexer indexer = new Indexer(); methodName = Introspector.decapitalize( methodName.substring( 3 ) );
for ( Class<?> clazz : classes ) { }
InputStream stream = classLoaderService.locateResourceStream( else if ( methodName.startsWith( "get" ) ) {
clazz.getName().replace( '.', '/' ) + ".class" methodName = Introspector.decapitalize( methodName.substring( 3 ) );
); }
try { else {
indexer.index( stream ); throw new AssertionFailure( "Expected a method following the Java Bean notation" );
} }
catch ( IOException e ) { return methodName;
StringBuilder builder = new StringBuilder(); }
builder.append( "[" ); }
int count = 0;
for ( Class<?> c : classes ) {
builder.append( c.getName() );
if ( count < classes.length - 1 ) {
builder.append( "," );
}
count++;
}
builder.append( "]" );
throw new HibernateException( "Unable to create annotation index for " + builder.toString() );
}
}
return indexer.complete();
}
public static Map<DotName, List<AnnotationInstance>> getMemberAnnotations(ClassInfo classInfo, String name) { /**
if ( classInfo == null ) { * @param classInfo the class info from which to retrieve the annotation instance
throw new IllegalArgumentException( "classInfo cannot be null" ); * @param annotationName the annotation to retrieve from the class info
} *
* @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all
*
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
*/
public static AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName)
throws AssertionFailure {
return getSingleAnnotation( classInfo.annotations(), annotationName );
}
if ( name == null ) { /**
throw new IllegalArgumentException( "name cannot be null" ); * @param annotations List of annotation instances keyed against their dot name.
} * @param annotationName the annotation to retrieve from map
*
* @return the single annotation of the specified dot name or {@code null} in case the annotation is not specified at all
*
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
*/
public static AnnotationInstance getSingleAnnotation(Map<DotName, List<AnnotationInstance>> annotations, DotName annotationName)
throws AssertionFailure {
List<AnnotationInstance> annotationList = annotations.get( annotationName );
if ( annotationList == null ) {
return null;
}
else if ( annotationList.size() == 1 ) {
return annotationList.get( 0 );
}
else {
throw new AssertionFailure(
"Found more than one instance of the annotation "
+ annotationList.get( 0 ).name().toString()
+ ". Expected was one."
);
}
}
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>(); /**
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) { * Retrieves a jandex annotation element value. If the value is <code>null</code>, the default value specified in the
for ( AnnotationInstance instance : annotationList ) { * annotation class is retrieved instead. Note, {@link #getValueAsEnum(Index, AnnotationInstance, String, Class)} must be
String targetName = null; * called to retrieve an enumerated value, and {@link #getValueAsArray(AnnotationInstance, String)} must be called to retrieve
if ( instance.target() instanceof FieldInfo ) { * an object array (other than a String array).
targetName = ( (FieldInfo) instance.target() ).name(); *
} * @param index the jandex index containing the supplied annotation
else if ( instance.target() instanceof MethodInfo ) { * @param annotation the annotation containing the element with the supplied name
targetName = ( (MethodInfo) instance.target() ).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
if ( targetName != null && name.equals( targetName ) ) { * <code>null</code>, else <code>null</code>.
addAnnotationToMap( instance, annotations ); */
} public static Object getValue( Index index,
} AnnotationInstance annotation,
} String element ) {
return annotations; AnnotationValue val = annotation.value(element);
} if (val == null) return getDefaultValue(index, annotation, element);
return val.asNested();
}
public static Map<DotName, List<AnnotationInstance>> getTypeAnnotations(ClassInfo classInfo) { /**
if ( classInfo == null ) { * Retrieves a jandex annotation element array. Note, {@link #getValue(Index, AnnotationInstance, String)} may be
throw new IllegalArgumentException( "classInfo cannot be null" ); * 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();
}
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>(); /**
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) { * Retrieves a jandex annotation element value, converting it to the supplied enumerated type. If the value is
for ( AnnotationInstance instance : annotationList ) { * <code>null</code>, the default value specified in the annotation class is retrieved instead.
if ( instance.target() instanceof ClassInfo ) { *
addAnnotationToMap( instance, annotations ); * @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
return annotations; * @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());
}
private static void addAnnotationToMap(AnnotationInstance instance, Map<DotName, List<AnnotationInstance>> annotations) { /**
DotName dotName = instance.name(); * Retrieves a jandex annotation element value as an Integer. If the value is <code>null</code>, the default value specified in
List<AnnotationInstance> list; * the annotation class is retrieved instead.
if ( annotations.containsKey( dotName ) ) { *
list = annotations.get( dotName ); * @param index the jandex index containing the supplied annotation
} * @param annotation the annotation containing the element with the supplied name
else { * @param element the name of the element value to be retrieve
list = new ArrayList<AnnotationInstance>(); * @return the value converted to an int if the value is not <code>null</code>, else the default value if not
annotations.put( dotName, list ); * <code>null</code>, else <code>0</code>.
} */
list.add( instance ); 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
*
* @param classLoaderService class loader service
* @param classes the classes to index
*
* @return an annotation repository w/ all the annotation discovered in the specified classes
*/
public static Index indexForClass(ClassLoaderService classLoaderService, Class<?>... classes) {
Indexer indexer = new Indexer();
for ( Class<?> clazz : classes ) {
InputStream stream = classLoaderService.locateResourceStream(
clazz.getName().replace( '.', '/' ) + ".class"
);
try {
indexer.index( stream );
}
catch ( IOException e ) {
StringBuilder builder = new StringBuilder();
builder.append( "[" );
int count = 0;
for ( Class<?> c : classes ) {
builder.append( c.getName() );
if ( count < classes.length - 1 ) {
builder.append( "," );
}
count++;
}
builder.append( "]" );
throw new HibernateException( "Unable to create annotation index for " + builder.toString() );
}
}
return indexer.complete();
}
public static Map<DotName, List<AnnotationInstance>> getMemberAnnotations(ClassInfo classInfo, String name) {
if ( classInfo == null ) {
throw new IllegalArgumentException( "classInfo cannot be null" );
}
if ( name == null ) {
throw new IllegalArgumentException( "name cannot be null" );
}
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) {
for ( AnnotationInstance instance : annotationList ) {
String targetName = null;
if ( instance.target() instanceof FieldInfo ) {
targetName = ( (FieldInfo) instance.target() ).name();
}
else if ( instance.target() instanceof MethodInfo ) {
targetName = ( (MethodInfo) instance.target() ).name();
}
if ( targetName != null && name.equals( targetName ) ) {
addAnnotationToMap( instance, annotations );
}
}
}
return annotations;
}
public static Map<DotName, List<AnnotationInstance>> getTypeAnnotations(ClassInfo classInfo) {
if ( classInfo == null ) {
throw new IllegalArgumentException( "classInfo cannot be null" );
}
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) {
for ( AnnotationInstance instance : annotationList ) {
if ( instance.target() instanceof ClassInfo ) {
addAnnotationToMap( instance, annotations );
}
}
}
return annotations;
}
private static void addAnnotationToMap(AnnotationInstance instance, Map<DotName, List<AnnotationInstance>> annotations) {
DotName dotName = instance.name();
List<AnnotationInstance> list;
if ( annotations.containsKey( dotName ) ) {
list = annotations.get( dotName );
}
else {
list = new ArrayList<AnnotationInstance>();
annotations.put( dotName, list );
}
list.add( instance );
}
private JandexHelper() {
}
} }

View File

@ -23,18 +23,19 @@
*/ */
package org.hibernate.metamodel.source.hbm; package org.hibernate.metamodel.source.hbm;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.dom4j.Attribute; import org.dom4j.Attribute;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.cfg.NamingStrategy; import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.StringHelper; 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.domain.MetaAttribute;
import org.hibernate.metamodel.source.Origin; 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;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement.XMLFetch; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement.XMLFetch;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping; 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.XMLSqlQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement; 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; import org.hibernate.service.ServiceRegistry;
/** /**
@ -225,14 +226,15 @@ public class HibernateMappingBinder implements MappingDefaults {
protected void parseFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) { protected void parseFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName) {
for ( XMLFetchProfileElement fetchProfile : fetchProfiles ) { for ( XMLFetchProfileElement fetchProfile : fetchProfiles ) {
String profileName = fetchProfile.getName(); 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() ) { for ( XMLFetch fetch : fetchProfile.getFetch() ) {
String entityName = fetch.getEntity() == null ? containingEntityName : fetch.getEntity(); String entityName = fetch.getEntity() == null ? containingEntityName : fetch.getEntity();
if ( entityName == null ) { if ( entityName == null ) {
throw new MappingException( "could not determine entity for fetch-profile fetch [" + profileName + "]:[" + fetch.getAssociation() + "]" ); 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.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.jboss.jandex.Index; import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer; import org.jboss.jandex.Indexer;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.hibernate.DuplicateMappingException; import org.hibernate.DuplicateMappingException;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.SessionFactory; 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.internal.CoreMessageLogger;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.MetadataSources; import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.SourceProcessingOrder; import org.hibernate.metamodel.SourceProcessingOrder;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile; import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef; import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.relational.Database; 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.metamodel.source.spi.MetadataImplementor;
import org.hibernate.service.BasicServiceRegistry; import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.type.TypeResolver;
/** /**
* Container for configuration data collected during binding the metamodel. * Container for configuration data collected during binding the metamodel.
@ -63,15 +64,15 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
* @author Steve Ebersole * @author Steve Ebersole
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class MetadataImpl implements Metadata, MetadataImplementor, Serializable { public class MetadataImpl implements MetadataImplementor, Serializable {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, MetadataImpl.class.getName() private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataImpl.class.getName());
);
private final BasicServiceRegistry serviceRegistry; private final BasicServiceRegistry serviceRegistry;
private final Options options; private final Options options;
private final Database database = new Database(); private final Database database = new Database();
private TypeResolver typeResolver = new TypeResolver();
/** /**
* Maps the fully qualified class name of an entity to its entity binding * 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, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>(); private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>(); 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, 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) { public MetadataImpl(MetadataSources metadataSources, Options options) {
this.serviceRegistry = metadataSources.getServiceRegistry(); this.serviceRegistry = metadataSources.getServiceRegistry();
@ -99,6 +104,33 @@ public class MetadataImpl implements Metadata, MetadataImplementor, Serializable
new EntityReferenceResolver( this ).resolve(); 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) { private void applyHibernateMappings(MetadataSources metadataSources, List<String> processedEntityNames) {
final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this ); final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
for ( JaxbRoot jaxbRoot : metadataSources.getJaxbRootList() ) { 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) { public TypeDef getTypeDef(String name) {
return typeDefs.get( name ); return typeDefs.get( name );
} }
public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) { public Iterable<FetchProfile> getFetchProfiles() {
FetchProfile profile = fetchProfiles.get( profileName ); return fetchProfiles.values();
if ( profile == null ) { }
profile = new FetchProfile( profileName, source );
fetchProfiles.put( profileName, profile ); public TypeResolver typeResolver() {
} return typeResolver;
return profile; }
}
} }

View File

@ -23,7 +23,6 @@
*/ */
package org.hibernate.metamodel.source.spi; package org.hibernate.metamodel.source.spi;
import org.hibernate.mapping.MetadataSource;
import org.hibernate.metamodel.Metadata; import org.hibernate.metamodel.Metadata;
import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile; import org.hibernate.metamodel.binding.FetchProfile;
@ -47,5 +46,5 @@ public interface MetadataImplementor extends Metadata {
public void addCollection(PluralAttributeBinding collectionBinding); 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; 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.List;
import java.util.Map; import java.util.Map;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Column; 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.AnnotationInstance;
import org.jboss.jandex.ClassInfo; import org.jboss.jandex.ClassInfo;
@ -36,6 +43,7 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.service.ServiceRegistryBuilder; import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.BasicServiceRegistryImpl; import org.hibernate.service.internal.BasicServiceRegistryImpl;
@ -88,6 +96,49 @@ public class JandexHelperTest extends BaseUnitTestCase {
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" ); memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" );
assertTrue( "there should be no annotations in fubar", memberAnnotations.isEmpty() ); 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));
}
}
} }