Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hibernate.cfg.Configuration Maven / Gradle / Ivy
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.cfg;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.io.StringReader;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import org.dom4j.Attribute;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.hibernate.EmptyInterceptor;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.InvalidMappingException;
import org.hibernate.MappingException;
import org.hibernate.MappingNotFoundException;
import org.hibernate.SessionFactory;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.DuplicateMappingException;
import org.hibernate.id.IdentifierGeneratorAggregator;
import org.hibernate.tuple.entity.EntityTuplizerFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.event.AutoFlushEventListener;
import org.hibernate.event.DeleteEventListener;
import org.hibernate.event.DirtyCheckEventListener;
import org.hibernate.event.EventListeners;
import org.hibernate.event.EvictEventListener;
import org.hibernate.event.FlushEntityEventListener;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.InitializeCollectionEventListener;
import org.hibernate.event.LoadEventListener;
import org.hibernate.event.LockEventListener;
import org.hibernate.event.MergeEventListener;
import org.hibernate.event.PersistEventListener;
import org.hibernate.event.PostCollectionRecreateEventListener;
import org.hibernate.event.PostCollectionRemoveEventListener;
import org.hibernate.event.PostCollectionUpdateEventListener;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PostLoadEventListener;
import org.hibernate.event.PostUpdateEventListener;
import org.hibernate.event.PreCollectionRecreateEventListener;
import org.hibernate.event.PreCollectionRemoveEventListener;
import org.hibernate.event.PreCollectionUpdateEventListener;
import org.hibernate.event.PreDeleteEventListener;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreLoadEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.hibernate.event.RefreshEventListener;
import org.hibernate.event.ReplicateEventListener;
import org.hibernate.event.SaveOrUpdateEventListener;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
import org.hibernate.impl.SessionFactoryImpl;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.IdentifierCollection;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table;
import org.hibernate.mapping.UniqueKey;
import org.hibernate.mapping.FetchProfile;
import org.hibernate.mapping.DenormalizedTable;
import org.hibernate.mapping.TypeDef;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.secure.JACCConfiguration;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;
import org.hibernate.tool.hbm2ddl.IndexMetadata;
import org.hibernate.type.SerializationException;
import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.ConfigHelper;
import org.hibernate.util.PropertiesHelper;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.SerializationHelper;
import org.hibernate.util.StringHelper;
import org.hibernate.util.XMLHelper;
/**
* An instance of Configuration allows the application
* to specify properties and mapping documents to be used when
* creating a SessionFactory . Usually an application will create
* a single Configuration , build a single instance of
* SessionFactory and then instantiate Session s in
* threads servicing client requests. The Configuration is meant
* only as an initialization-time object. SessionFactory s are
* immutable and do not retain any association back to the
* Configuration .
*
* A new Configuration will use the properties specified in
* hibernate.properties by default.
*
* @author Gavin King
* @see org.hibernate.SessionFactory
*/
public class Configuration implements Serializable {
private static Logger log = LoggerFactory.getLogger( Configuration.class );
protected Map classes;
protected Map imports;
protected Map collections;
protected Map tables;
protected List auxiliaryDatabaseObjects;
protected Map namedQueries;
protected Map namedSqlQueries;
protected Map/**/ sqlResultSetMappings;
protected Map typeDefs;
protected Map filterDefinitions;
protected Map fetchProfiles;
protected Map tableNameBinding;
protected Map columnNameBindingPerTable;
protected List secondPasses;
protected List propertyReferences;
// protected List extendsQueue;
protected Map extendsQueue;
protected Map sqlFunctions;
private EntityTuplizerFactory entityTuplizerFactory;
// private ComponentTuplizerFactory componentTuplizerFactory; todo : HHH-3517 and HHH-1907
private Interceptor interceptor;
private Properties properties;
private EntityResolver entityResolver;
private EntityNotFoundDelegate entityNotFoundDelegate;
protected transient XMLHelper xmlHelper;
protected NamingStrategy namingStrategy;
private SessionFactoryObserver sessionFactoryObserver;
private EventListeners eventListeners;
protected final SettingsFactory settingsFactory;
private transient Mapping mapping = buildMapping();
private DefaultIdentifierGeneratorFactory identifierGeneratorFactory;
//Map, org.hibernate.mapping.MappedSuperclass>
private Map mappedSuperclasses;
protected Configuration(SettingsFactory settingsFactory) {
this.settingsFactory = settingsFactory;
reset();
}
public Configuration() {
this( new SettingsFactory() );
}
protected void reset() {
classes = new HashMap();
imports = new HashMap();
collections = new HashMap();
tables = new TreeMap();
namedQueries = new HashMap();
namedSqlQueries = new HashMap();
sqlResultSetMappings = new HashMap();
typeDefs = new HashMap();
filterDefinitions = new HashMap();
fetchProfiles = new HashMap();
auxiliaryDatabaseObjects = new ArrayList();
tableNameBinding = new HashMap();
columnNameBindingPerTable = new HashMap();
propertyReferences = new ArrayList();
secondPasses = new ArrayList();
// extendsQueue = new ArrayList();
extendsQueue = new HashMap();
namingStrategy = DefaultNamingStrategy.INSTANCE;
xmlHelper = new XMLHelper();
interceptor = EmptyInterceptor.INSTANCE;
properties = Environment.getProperties();
entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER;
eventListeners = new EventListeners();
sqlFunctions = new HashMap();
entityTuplizerFactory = new EntityTuplizerFactory();
// componentTuplizerFactory = new ComponentTuplizerFactory();
identifierGeneratorFactory = new DefaultIdentifierGeneratorFactory();
mappedSuperclasses = new HashMap();
}
public EntityTuplizerFactory getEntityTuplizerFactory() {
return entityTuplizerFactory;
}
// public ComponentTuplizerFactory getComponentTuplizerFactory() {
// return componentTuplizerFactory;
// }
/**
* Iterate the entity mappings
*
* @return Iterator of the entity mappings currently contained in the configuration.
*/
public Iterator getClassMappings() {
return classes.values().iterator();
}
/**
* Iterate the collection mappings
*
* @return Iterator of the collection mappings currently contained in the configuration.
*/
public Iterator getCollectionMappings() {
return collections.values().iterator();
}
/**
* Iterate the table mappings
*
* @return Iterator of the table mappings currently contained in the configuration.
*/
public Iterator getTableMappings() {
return tables.values().iterator();
}
/**
* Iterate the mapped superclasses mappings
* EXPERIMENTAL Consider this API as PRIVATE
*
* @return Iterator over the MappedSuperclass mapping currently contained in the configuration.
*/
public Iterator getMappedSuperclassMappings() {
return mappedSuperclasses.values().iterator();
}
/**
* Get the mapping for a particular entity
*
* @param entityName An entity name.
* @return the entity mapping information
*/
public PersistentClass getClassMapping(String entityName) {
return (PersistentClass) classes.get( entityName );
}
/**
* Get the mapping for a particular collection role
*
* @param role a collection role
* @return The collection mapping information
*/
public Collection getCollectionMapping(String role) {
return (Collection) collections.get( role );
}
/**
* Set a custom entity resolver. This entity resolver must be
* set before addXXX(misc) call.
* Default value is {@link org.hibernate.util.DTDEntityResolver}
*
* @param entityResolver entity resolver to use
*/
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
public EntityResolver getEntityResolver() {
return entityResolver;
}
/**
* Retrieve the user-supplied delegate to handle non-existent entity
* scenarios. May be null.
*
* @return The user-supplied delegate
*/
public EntityNotFoundDelegate getEntityNotFoundDelegate() {
return entityNotFoundDelegate;
}
/**
* Specify a user-supplied delegate to be used to handle scenarios where an entity could not be
* located by specified id. This is mainly intended for EJB3 implementations to be able to
* control how proxy initialization errors should be handled...
*
* @param entityNotFoundDelegate The delegate to use
*/
public void setEntityNotFoundDelegate(EntityNotFoundDelegate entityNotFoundDelegate) {
this.entityNotFoundDelegate = entityNotFoundDelegate;
}
/**
* Read mappings from a particular XML file
*
* @param xmlFile a path to a file
* @return this (for method chaining purposes)
* @throws org.hibernate.MappingException Indicates inability to locate or parse
* the specified mapping file.
* @see #addFile(java.io.File)
*/
public Configuration addFile(String xmlFile) throws MappingException {
return addFile( new File( xmlFile ) );
}
/**
* Read mappings from a particular XML file
*
* @param xmlFile a path to a file
* @return this (for method chaining purposes)
* @throws org.hibernate.MappingException Indicates inability to locate or parse
* the specified mapping file.
*/
public Configuration addFile(File xmlFile) throws MappingException {
log.info( "Reading mappings from file: " + xmlFile.getPath() );
if ( !xmlFile.exists() ) {
throw new MappingNotFoundException( "file", xmlFile.toString() );
}
try {
List errors = new ArrayList();
org.dom4j.Document doc = xmlHelper.createSAXReader( xmlFile.toString(), errors, entityResolver ).read( xmlFile );
if ( errors.size() != 0 ) {
throw new InvalidMappingException( "file", xmlFile.toString(), ( Throwable ) errors.get( 0 ) );
}
add( doc );
return this;
}
catch ( InvalidMappingException e ) {
throw e;
}
catch ( MappingNotFoundException e ) {
throw e;
}
catch ( Exception e ) {
throw new InvalidMappingException( "file", xmlFile.toString(), e );
}
}
/**
* Add a cached mapping file. A cached file is a serialized representation
* of the DOM structure of a particular mapping. It is saved from a previous
* call as a file with the name xmlFile + ".bin" where xmlFile is
* the name of the original mapping file.
*
* If a cached xmlFile + ".bin" exists and is newer than
* xmlFile the ".bin" file will be read directly. Otherwise
* xmlFile is read and then serialized to xmlFile + ".bin" for use
* the next time.
*
* @param xmlFile The cacheable mapping file to be added.
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the cached file or processing
* the non-cached file.
*/
public Configuration addCacheableFile(File xmlFile) throws MappingException {
File cachedFile = determineCachedDomFile( xmlFile );
try {
return addCacheableFileStrictly( xmlFile );
}
catch ( SerializationException e ) {
log.warn( "Could not deserialize cache file: " + cachedFile.getPath() + " : " + e );
}
catch ( FileNotFoundException e ) {
log.warn( "I/O reported cached file could not be found : " + cachedFile.getPath() + " : " + e );
}
if ( !xmlFile.exists() ) {
throw new MappingNotFoundException( "file", xmlFile.toString() );
}
log.info( "Reading mappings from file: " + xmlFile );
List errors = new ArrayList();
try {
org.dom4j.Document doc = xmlHelper.createSAXReader( xmlFile.getAbsolutePath(), errors, entityResolver ).read( xmlFile );
if ( errors.size() != 0 ) {
throw new InvalidMappingException( "file", xmlFile.toString(), (Throwable) errors.get(0) );
}
try {
log.debug( "Writing cache file for: " + xmlFile + " to: " + cachedFile );
SerializationHelper.serialize( ( Serializable ) doc, new FileOutputStream( cachedFile ) );
}
catch ( SerializationException e ) {
log.warn( "Could not write cached file: " + cachedFile, e );
}
catch ( FileNotFoundException e ) {
log.warn( "I/O reported error writing cached file : " + cachedFile.getPath(), e );
}
add( doc );
}
catch (DocumentException e) {
throw new InvalidMappingException( "file", xmlFile.toString(), e );
}
return this;
}
private File determineCachedDomFile(File xmlFile) {
return new File( xmlFile.getAbsolutePath() + ".bin" );
}
/**
* INTENDED FOR TESTSUITE USE ONLY!
*
* Much like {@link #addCacheableFile(File)} except that here we will fail immediately if
* the cache version cannot be found or used for whatever reason
*
* @param xmlFile The xml file, not the bin!
*
* @return The dom "deserialized" from the cached file.
*
* @throws MappingException Indicates a problem in the underlyiong call to {@link #add(org.dom4j.Document)}
* @throws SerializationException Indicates a problem deserializing the cached dom tree
* @throws FileNotFoundException Indicates that the cached file was not found or was not usable.
*/
public Configuration addCacheableFileStrictly(File xmlFile)
throws MappingException, SerializationException, FileNotFoundException {
final File cachedFile = determineCachedDomFile( xmlFile );
final boolean useCachedFile = xmlFile.exists()
&& cachedFile.exists()
&& xmlFile.lastModified() < cachedFile.lastModified();
if ( ! useCachedFile ) {
throw new FileNotFoundException( "Cached file could not be found or could not be used" );
}
log.info( "Reading mappings from cache file: " + cachedFile );
org.dom4j.Document document =
( org.dom4j.Document ) SerializationHelper.deserialize( new FileInputStream( cachedFile ) );
add( document );
return this;
}
/**
* Add a cacheable mapping file.
*
* @param xmlFile The name of the file to be added. This must be in a form
* useable to simply construct a {@link java.io.File} instance.
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the cached file or processing
* the non-cached file.
* @see #addCacheableFile(java.io.File)
*/
public Configuration addCacheableFile(String xmlFile) throws MappingException {
return addCacheableFile( new File( xmlFile ) );
}
/**
* Read mappings from a String
*
* @param xml an XML string
* @return this (for method chaining purposes)
* @throws org.hibernate.MappingException Indicates problems parsing the
* given XML string
*/
public Configuration addXML(String xml) throws MappingException {
if ( log.isDebugEnabled() ) {
log.debug( "Mapping XML:\n" + xml );
}
try {
List errors = new ArrayList();
org.dom4j.Document doc = xmlHelper.createSAXReader( "XML String", errors, entityResolver )
.read( new StringReader( xml ) );
if ( errors.size() != 0 ) {
throw new MappingException( "invalid mapping", (Throwable) errors.get( 0 ) );
}
add( doc );
}
catch (DocumentException e) {
throw new MappingException( "Could not parse mapping document in XML string", e );
}
return this;
}
/**
* Read mappings from a URL
*
* @param url The url for the mapping document to be read.
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the URL or processing
* the mapping document.
*/
public Configuration addURL(URL url) throws MappingException {
if ( log.isDebugEnabled() ) {
log.debug( "Reading mapping document from URL:" + url.toExternalForm() );
}
try {
addInputStream( url.openStream() );
}
catch ( InvalidMappingException e ) {
throw new InvalidMappingException( "URL", url.toExternalForm(), e.getCause() );
}
catch (Exception e) {
throw new InvalidMappingException( "URL", url.toExternalForm(), e );
}
return this;
}
/**
* Read mappings from a DOM Document
*
* @param doc The DOM document
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the DOM or processing
* the mapping document.
*/
public Configuration addDocument(Document doc) throws MappingException {
if ( log.isDebugEnabled() ) {
log.debug( "Mapping document:\n" + doc );
}
add( xmlHelper.createDOMReader().read( doc ) );
return this;
}
/**
* Read mappings from an {@link java.io.InputStream}.
*
* @param xmlInputStream The input stream containing a DOM.
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the stream, or
* processing the contained mapping document.
*/
public Configuration addInputStream(InputStream xmlInputStream) throws MappingException {
try {
List errors = new ArrayList();
org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver )
.read( new InputSource( xmlInputStream ) );
if ( errors.size() != 0 ) {
throw new InvalidMappingException( "invalid mapping", null, (Throwable) errors.get( 0 ) );
}
add( doc );
return this;
}
catch (DocumentException e) {
throw new InvalidMappingException( "input stream", null, e );
}
finally {
try {
xmlInputStream.close();
}
catch (IOException ioe) {
log.warn( "Could not close input stream", ioe );
}
}
}
/**
* Read mappings as a application resource (i.e. classpath lookup).
*
* @param resourceName The resource name
* @param classLoader The class loader to use.
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems locating the resource or
* processing the contained mapping document.
*/
public Configuration addResource(String resourceName, ClassLoader classLoader) throws MappingException {
log.info( "Reading mappings from resource: " + resourceName );
InputStream rsrc = classLoader.getResourceAsStream( resourceName );
if ( rsrc == null ) {
throw new MappingNotFoundException( "resource", resourceName );
}
try {
return addInputStream( rsrc );
}
catch (MappingException me) {
throw new InvalidMappingException( "resource", resourceName, me );
}
}
/**
* Read mappings as a application resourceName (i.e. classpath lookup)
* trying different classloaders.
*
* @param resourceName The resource name
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems locating the resource or
* processing the contained mapping document.
*/
public Configuration addResource(String resourceName) throws MappingException {
log.info( "Reading mappings from resource : " + resourceName );
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
InputStream rsrc = null;
if (contextClassLoader!=null) {
rsrc = contextClassLoader.getResourceAsStream( resourceName );
}
if ( rsrc == null ) {
rsrc = Environment.class.getClassLoader().getResourceAsStream( resourceName );
}
if ( rsrc == null ) {
throw new MappingNotFoundException( "resource", resourceName );
}
try {
return addInputStream( rsrc );
}
catch (MappingException me) {
throw new InvalidMappingException( "resource", resourceName, me );
}
}
/**
* Read a mapping as an application resouurce using the convention that a class
* named foo.bar.Foo is mapped by a file foo/bar/Foo.hbm.xml
* which can be resolved as a classpath resource.
*
* @param persistentClass The mapped class
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems locating the resource or
* processing the contained mapping document.
*/
public Configuration addClass(Class persistentClass) throws MappingException {
String mappingResourceName = persistentClass.getName().replace( '.', '/' ) + ".hbm.xml";
log.info( "Reading mappings from resource: " + mappingResourceName );
return addResource( mappingResourceName, persistentClass.getClassLoader() );
}
/**
* Read all mappings from a jar file
*
* Assumes that any file named *.hbm.xml is a mapping document.
*
* @param jar a jar file
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the jar file or
* processing the contained mapping documents.
*/
public Configuration addJar(File jar) throws MappingException {
log.info( "Searching for mapping documents in jar: " + jar.getName() );
JarFile jarFile = null;
try {
try {
jarFile = new JarFile( jar );
}
catch (IOException ioe) {
throw new InvalidMappingException(
"Could not read mapping documents from jar: " + jar.getName(), "jar", jar.getName(),
ioe
);
}
Enumeration jarEntries = jarFile.entries();
while ( jarEntries.hasMoreElements() ) {
ZipEntry ze = (ZipEntry) jarEntries.nextElement();
if ( ze.getName().endsWith( ".hbm.xml" ) ) {
log.info( "Found mapping document in jar: " + ze.getName() );
try {
addInputStream( jarFile.getInputStream( ze ) );
}
catch (Exception e) {
throw new InvalidMappingException(
"Could not read mapping documents from jar: " + jar.getName(),
"jar",
jar.getName(),
e
);
}
}
}
}
finally {
try {
if ( jarFile != null ) {
jarFile.close();
}
}
catch (IOException ioe) {
log.error("could not close jar", ioe);
}
}
return this;
}
/**
* Read all mapping documents from a directory tree.
*
* Assumes that any file named *.hbm.xml is a mapping document.
*
* @param dir The directory
* @return this (for method chaining purposes)
* @throws MappingException Indicates problems reading the jar file or
* processing the contained mapping documents.
*/
public Configuration addDirectory(File dir) throws MappingException {
File[] files = dir.listFiles();
for ( int i = 0; i < files.length ; i++ ) {
if ( files[i].isDirectory() ) {
addDirectory( files[i] );
}
else if ( files[i].getName().endsWith( ".hbm.xml" ) ) {
addFile( files[i] );
}
}
return this;
}
protected void add(org.dom4j.Document doc) throws MappingException {
HbmBinder.bindRoot( doc, createMappings(), CollectionHelper.EMPTY_MAP );
}
/**
* Create a new Mappings to add class and collection
* mappings to.
*/
public Mappings createMappings() {
return new MappingsImpl();
}
private Iterator iterateGenerators(Dialect dialect) throws MappingException {
TreeMap generators = new TreeMap();
String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
Iterator iter = classes.values().iterator();
while ( iter.hasNext() ) {
PersistentClass pc = ( PersistentClass ) iter.next();
if ( !pc.isInherited() ) {
IdentifierGenerator ig = pc.getIdentifier().createIdentifierGenerator(
getIdentifierGeneratorFactory(),
dialect,
defaultCatalog,
defaultSchema,
(RootClass) pc
);
if ( ig instanceof PersistentIdentifierGenerator ) {
generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
}
else if ( ig instanceof IdentifierGeneratorAggregator ) {
( (IdentifierGeneratorAggregator) ig ).registerPersistentGenerators( generators );
}
}
}
iter = collections.values().iterator();
while ( iter.hasNext() ) {
Collection collection = ( Collection ) iter.next();
if ( collection.isIdentified() ) {
IdentifierGenerator ig = ( ( IdentifierCollection ) collection ).getIdentifier().createIdentifierGenerator(
getIdentifierGeneratorFactory(),
dialect,
defaultCatalog,
defaultSchema,
null
);
if ( ig instanceof PersistentIdentifierGenerator ) {
generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
}
}
}
return generators.values().iterator();
}
/**
* Generate DDL for dropping tables
*
* @see org.hibernate.tool.hbm2ddl.SchemaExport
*/
public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
secondPassCompile();
String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
ArrayList script = new ArrayList( 50 );
// drop them in reverse order in case db needs it done that way...
ListIterator itr = auxiliaryDatabaseObjects.listIterator( auxiliaryDatabaseObjects.size() );
while ( itr.hasPrevious() ) {
AuxiliaryDatabaseObject object = (AuxiliaryDatabaseObject) itr.previous();
if ( object.appliesToDialect( dialect ) ) {
script.add( object.sqlDropString( dialect, defaultCatalog, defaultSchema ) );
}
}
if ( dialect.dropConstraints() ) {
Iterator iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
Iterator subIter = table.getForeignKeyIterator();
while ( subIter.hasNext() ) {
ForeignKey fk = (ForeignKey) subIter.next();
if ( fk.isPhysicalConstraint() ) {
script.add(
fk.sqlDropString(
dialect,
defaultCatalog,
defaultSchema
)
);
}
}
}
}
}
Iterator iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
/*Iterator subIter = table.getIndexIterator();
while ( subIter.hasNext() ) {
Index index = (Index) subIter.next();
if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
script.add( index.sqlDropString(dialect) );
}
}*/
script.add(
table.sqlDropString(
dialect,
defaultCatalog,
defaultSchema
)
);
}
}
iter = iterateGenerators( dialect );
while ( iter.hasNext() ) {
String[] lines = ( (PersistentIdentifierGenerator) iter.next() ).sqlDropStrings( dialect );
for ( int i = 0; i < lines.length ; i++ ) {
script.add( lines[i] );
}
}
return ArrayHelper.toStringArray( script );
}
/**
* Generate DDL for creating tables
*
* @see org.hibernate.tool.hbm2ddl.SchemaExport
*/
public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
secondPassCompile();
ArrayList script = new ArrayList( 50 );
String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
Iterator iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
script.add(
table.sqlCreateString(
dialect,
mapping,
defaultCatalog,
defaultSchema
)
);
Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema );
while ( comments.hasNext() ) {
script.add( comments.next() );
}
}
}
iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) {
Iterator subIter = table.getUniqueKeyIterator();
while ( subIter.hasNext() ) {
UniqueKey uk = (UniqueKey) subIter.next();
String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema );
if (constraintString != null) script.add( constraintString );
}
}
Iterator subIter = table.getIndexIterator();
while ( subIter.hasNext() ) {
Index index = (Index) subIter.next();
script.add(
index.sqlCreateString(
dialect,
mapping,
defaultCatalog,
defaultSchema
)
);
}
if ( dialect.hasAlterTable() ) {
subIter = table.getForeignKeyIterator();
while ( subIter.hasNext() ) {
ForeignKey fk = (ForeignKey) subIter.next();
if ( fk.isPhysicalConstraint() ) {
script.add(
fk.sqlCreateString(
dialect, mapping,
defaultCatalog,
defaultSchema
)
);
}
}
}
}
}
iter = iterateGenerators( dialect );
while ( iter.hasNext() ) {
String[] lines = ( (PersistentIdentifierGenerator) iter.next() ).sqlCreateStrings( dialect );
for ( int i = 0; i < lines.length ; i++ ) {
script.add( lines[i] );
}
}
Iterator itr = auxiliaryDatabaseObjects.iterator();
while ( itr.hasNext() ) {
AuxiliaryDatabaseObject object = (AuxiliaryDatabaseObject) itr.next();
if ( object.appliesToDialect( dialect ) ) {
script.add( object.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ) );
}
}
return ArrayHelper.toStringArray( script );
}
/**
* Generate DDL for altering tables
*
* @see org.hibernate.tool.hbm2ddl.SchemaUpdate
*/
public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
throws HibernateException {
secondPassCompile();
String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
ArrayList script = new ArrayList( 50 );
Iterator iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
TableMetadata tableInfo = databaseMetadata.getTableMetadata(
table.getName(),
( table.getSchema() == null ) ? defaultSchema : table.getSchema(),
( table.getCatalog() == null ) ? defaultCatalog : table.getCatalog(),
table.isQuoted()
);
if ( tableInfo == null ) {
script.add(
table.sqlCreateString(
dialect,
mapping,
defaultCatalog,
defaultSchema
)
);
}
else {
Iterator subiter = table.sqlAlterStrings(
dialect,
mapping,
tableInfo,
defaultCatalog,
defaultSchema
);
while ( subiter.hasNext() ) {
script.add( subiter.next() );
}
}
Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema );
while ( comments.hasNext() ) {
script.add( comments.next() );
}
}
}
iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
TableMetadata tableInfo = databaseMetadata.getTableMetadata(
table.getName(),
table.getSchema(),
table.getCatalog(),
table.isQuoted()
);
if ( dialect.hasAlterTable() ) {
Iterator subIter = table.getForeignKeyIterator();
while ( subIter.hasNext() ) {
ForeignKey fk = (ForeignKey) subIter.next();
if ( fk.isPhysicalConstraint() ) {
boolean create = tableInfo == null || (
tableInfo.getForeignKeyMetadata( fk ) == null && (
//Icky workaround for MySQL bug:
!( dialect instanceof MySQLDialect ) ||
tableInfo.getIndexMetadata( fk.getName() ) == null
)
);
if ( create ) {
script.add(
fk.sqlCreateString(
dialect,
mapping,
defaultCatalog,
defaultSchema
)
);
}
}
}
}
Iterator subIter = table.getIndexIterator();
while ( subIter.hasNext() ) {
final Index index = (Index) subIter.next();
// Skip if index already exists
if ( tableInfo != null && StringHelper.isNotEmpty( index.getName() ) ) {
final IndexMetadata meta = tableInfo.getIndexMetadata( index.getName() );
if ( meta != null ) {
continue;
}
}
script.add(
index.sqlCreateString(
dialect,
mapping,
defaultCatalog,
defaultSchema
)
);
}
//broken, 'cos we don't generate these with names in SchemaExport
// subIter = table.getUniqueKeyIterator();
// while ( subIter.hasNext() ) {
// UniqueKey uk = (UniqueKey) subIter.next();
// if ( tableInfo==null || tableInfo.getIndexMetadata( uk.getFilterName() ) == null ) {
// script.add( uk.sqlCreateString(dialect, mapping) );
// }
// }
}
}
iter = iterateGenerators( dialect );
while ( iter.hasNext() ) {
PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
Object key = generator.generatorKey();
if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
String[] lines = generator.sqlCreateStrings( dialect );
for ( int i = 0; i < lines.length ; i++ ) {
script.add( lines[i] );
}
}
}
return ArrayHelper.toStringArray( script );
}
public void validateSchema(Dialect dialect, DatabaseMetadata databaseMetadata)
throws HibernateException {
secondPassCompile();
String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
Iterator iter = getTableMappings();
while ( iter.hasNext() ) {
Table table = (Table) iter.next();
if ( table.isPhysicalTable() ) {
TableMetadata tableInfo = databaseMetadata.getTableMetadata(
table.getName(),
( table.getSchema() == null ) ? defaultSchema : table.getSchema(),
( table.getCatalog() == null ) ? defaultCatalog : table.getCatalog(),
table.isQuoted());
if ( tableInfo == null ) {
throw new HibernateException( "Missing table: " + table.getName() );
}
else {
table.validateColumns( dialect, mapping, tableInfo );
}
}
}
iter = iterateGenerators( dialect );
while ( iter.hasNext() ) {
PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
Object key = generator.generatorKey();
if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
throw new HibernateException( "Missing sequence or table: " + key );
}
}
}
private void validate() throws MappingException {
Iterator iter = classes.values().iterator();
while ( iter.hasNext() ) {
( (PersistentClass) iter.next() ).validate( mapping );
}
iter = collections.values().iterator();
while ( iter.hasNext() ) {
( (Collection) iter.next() ).validate( mapping );
}
}
/**
* Call this to ensure the mappings are fully compiled/built. Usefull to ensure getting
* access to all information in the metamodel when calling e.g. getClassMappings().
*/
public void buildMappings() {
secondPassCompile();
}
// This method may be called many times!!
protected void secondPassCompile() throws MappingException {
log.debug( "processing extends queue" );
processExtendsQueue();
log.debug( "processing collection mappings" );
Iterator iter = secondPasses.iterator();
while ( iter.hasNext() ) {
SecondPass sp = (SecondPass) iter.next();
if ( ! (sp instanceof QuerySecondPass) ) {
sp.doSecondPass( classes );
iter.remove();
}
}
log.debug( "processing native query and ResultSetMapping mappings" );
iter = secondPasses.iterator();
while ( iter.hasNext() ) {
SecondPass sp = (SecondPass) iter.next();
sp.doSecondPass( classes );
iter.remove();
}
log.debug( "processing association property references" );
iter = propertyReferences.iterator();
while ( iter.hasNext() ) {
Mappings.PropertyReference upr = (Mappings.PropertyReference) iter.next();
PersistentClass clazz = getClassMapping( upr.referencedClass );
if ( clazz == null ) {
throw new MappingException(
"property-ref to unmapped class: " +
upr.referencedClass
);
}
Property prop = clazz.getReferencedProperty( upr.propertyName );
if ( upr.unique ) {
( (SimpleValue) prop.getValue() ).setAlternateUniqueKey( true );
}
}
//TODO: Somehow add the newly created foreign keys to the internal collection
log.debug( "processing foreign key constraints" );
iter = getTableMappings();
Set done = new HashSet();
while ( iter.hasNext() ) {
secondPassCompileForeignKeys( (Table) iter.next(), done );
}
}
/**
* Try to empty the extends queue.
*/
private void processExtendsQueue() {
// todo : would love to have this work on a notification basis
// where the successful binding of an entity/subclass would
// emit a notification which the extendsQueue entries could
// react to...
org.dom4j.Document document = findPossibleExtends();
while ( document != null ) {
add( document );
document = findPossibleExtends();
}
if ( extendsQueue.size() > 0 ) {
// Iterator iterator = extendsQueue.iterator();
Iterator iterator = extendsQueue.keySet().iterator();
StringBuffer buf = new StringBuffer( "Following superclasses referenced in extends not found: " );
while ( iterator.hasNext() ) {
final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iterator.next();
buf.append( entry.getExplicitName() );
if ( entry.getMappingPackage() != null ) {
buf.append( "[" ).append( entry.getMappingPackage() ).append( "]" );
}
if ( iterator.hasNext() ) {
buf.append( "," );
}
}
throw new MappingException( buf.toString() );
}
}
/**
* Find the first possible element in the queue of extends.
*/
protected org.dom4j.Document findPossibleExtends() {
// Iterator iter = extendsQueue.iterator();
Iterator iter = extendsQueue.keySet().iterator();
while ( iter.hasNext() ) {
final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iter.next();
if ( getClassMapping( entry.getExplicitName() ) != null ) {
// found
iter.remove();
return entry.getDocument();
}
else if ( getClassMapping( HbmBinder.getClassName( entry.getExplicitName(), entry.getMappingPackage() ) ) != null ) {
// found
iter.remove();
return entry.getDocument();
}
}
return null;
}
protected void secondPassCompileForeignKeys(Table table, Set done) throws MappingException {
table.createForeignKeys();
Iterator iter = table.getForeignKeyIterator();
while ( iter.hasNext() ) {
ForeignKey fk = (ForeignKey) iter.next();
if ( !done.contains( fk ) ) {
done.add( fk );
final String referencedEntityName = fk.getReferencedEntityName();
if ( referencedEntityName == null ) {
throw new MappingException(
"An association from the table " +
fk.getTable().getName() +
" does not specify the referenced entity"
);
}
if ( log.isDebugEnabled() ) {
log.debug( "resolving reference to class: " + referencedEntityName );
}
PersistentClass referencedClass = (PersistentClass) classes.get( referencedEntityName );
if ( referencedClass == null ) {
throw new MappingException(
"An association from the table " +
fk.getTable().getName() +
" refers to an unmapped class: " +
referencedEntityName
);
}
if ( referencedClass.isJoinedSubclass() ) {
secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done );
}
fk.setReferencedTable( referencedClass.getTable() );
fk.alignColumns();
}
}
}
/**
* Get the named queries
*/
public Map getNamedQueries() {
return namedQueries;
}
/**
* Instantiate a new SessionFactory , using the properties and
* mappings in this configuration. The SessionFactory will be
* immutable, so changes made to the Configuration after
* building the SessionFactory will not affect it.
*
* @return a new factory for Session s
* @see org.hibernate.SessionFactory
*/
public SessionFactory buildSessionFactory() throws HibernateException {
log.debug( "Preparing to build session factory with filters : " + filterDefinitions );
secondPassCompile();
validate();
Environment.verifyProperties( properties );
Properties copy = new Properties();
copy.putAll( properties );
PropertiesHelper.resolvePlaceHolders( copy );
Settings settings = buildSettings( copy );
return new SessionFactoryImpl(
this,
mapping,
settings,
getInitializedEventListeners(),
sessionFactoryObserver
);
}
private EventListeners getInitializedEventListeners() {
EventListeners result = (EventListeners) eventListeners.shallowCopy();
result.initializeListeners( this );
return result;
}
/**
* Return the configured Interceptor
*/
public Interceptor getInterceptor() {
return interceptor;
}
/**
* Get all properties
*/
public Properties getProperties() {
return properties;
}
/**
* Configure an Interceptor
*/
public Configuration setInterceptor(Interceptor interceptor) {
this.interceptor = interceptor;
return this;
}
/**
* Specify a completely new set of properties
*/
public Configuration setProperties(Properties properties) {
this.properties = properties;
return this;
}
/**
* Set the given properties
*/
public Configuration addProperties(Properties extraProperties) {
this.properties.putAll( extraProperties );
return this;
}
/**
* Adds the incoming properties to the internap properties structure,
* as long as the internal structure does not already contain an
* entry for the given key.
*
* @param properties
* @return this
*/
public Configuration mergeProperties(Properties properties) {
Iterator itr = properties.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
if ( this.properties.containsKey( entry.getKey() ) ) {
continue;
}
this.properties.setProperty( ( String ) entry.getKey(), ( String ) entry.getValue() );
}
return this;
}
/**
* Set a property
*/
public Configuration setProperty(String propertyName, String value) {
properties.setProperty( propertyName, value );
return this;
}
/**
* Get a property
*/
public String getProperty(String propertyName) {
return properties.getProperty( propertyName );
}
private void addProperties(Element parent) {
Iterator iter = parent.elementIterator( "property" );
while ( iter.hasNext() ) {
Element node = (Element) iter.next();
String name = node.attributeValue( "name" );
String value = node.getText().trim();
log.debug( name + "=" + value );
properties.setProperty( name, value );
if ( !name.startsWith( "hibernate" ) ) {
properties.setProperty( "hibernate." + name, value );
}
}
Environment.verifyProperties( properties );
}
/**
* Get the configuration file as an InputStream . Might be overridden
* by subclasses to allow the configuration to be located by some arbitrary
* mechanism.
*/
protected InputStream getConfigurationInputStream(String resource) throws HibernateException {
log.info( "Configuration resource: " + resource );
return ConfigHelper.getResourceAsStream( resource );
}
/**
* Use the mappings and properties specified in an application
* resource named hibernate.cfg.xml .
*/
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
}
/**
* Use the mappings and properties specified in the given application
* resource. The format of the resource is defined in
* hibernate-configuration-3.0.dtd .
*
* The resource is found via getConfigurationInputStream(resource) .
*/
public Configuration configure(String resource) throws HibernateException {
log.info( "configuring from resource: " + resource );
InputStream stream = getConfigurationInputStream( resource );
return doConfigure( stream, resource );
}
/**
* Use the mappings and properties specified in the given document.
* The format of the document is defined in
* hibernate-configuration-3.0.dtd .
*
* @param url URL from which you wish to load the configuration
* @return A configuration configured via the file
* @throws HibernateException
*/
public Configuration configure(URL url) throws HibernateException {
log.info( "configuring from url: " + url.toString() );
try {
return doConfigure( url.openStream(), url.toString() );
}
catch (IOException ioe) {
throw new HibernateException( "could not configure from URL: " + url, ioe );
}
}
/**
* Use the mappings and properties specified in the given application
* file. The format of the file is defined in
* hibernate-configuration-3.0.dtd .
*
* @param configFile File from which you wish to load the configuration
* @return A configuration configured via the file
* @throws HibernateException
*/
public Configuration configure(File configFile) throws HibernateException {
log.info( "configuring from file: " + configFile.getName() );
try {
return doConfigure( new FileInputStream( configFile ), configFile.toString() );
}
catch (FileNotFoundException fnfe) {
throw new HibernateException( "could not find file: " + configFile, fnfe );
}
}
/**
* Use the mappings and properties specified in the given application
* resource. The format of the resource is defined in
* hibernate-configuration-3.0.dtd .
*
* @param stream Inputstream to be read from
* @param resourceName The name to use in warning/error messages
* @return A configuration configured via the stream
* @throws HibernateException
*/
protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
org.dom4j.Document doc;
try {
List errors = new ArrayList();
doc = xmlHelper.createSAXReader( resourceName, errors, entityResolver )
.read( new InputSource( stream ) );
if ( errors.size() != 0 ) {
throw new MappingException(
"invalid configuration",
(Throwable) errors.get( 0 )
);
}
}
catch (DocumentException e) {
throw new HibernateException(
"Could not parse configuration: " + resourceName,
e
);
}
finally {
try {
stream.close();
}
catch (IOException ioe) {
log.warn( "could not close input stream for: " + resourceName, ioe );
}
}
return doConfigure( doc );
}
/**
* Use the mappings and properties specified in the given XML document.
* The format of the file is defined in
* hibernate-configuration-3.0.dtd .
*
* @param document an XML document from which you wish to load the configuration
* @return A configuration configured via the Document
* @throws HibernateException if there is problem in accessing the file.
*/
public Configuration configure(Document document) throws HibernateException {
log.info( "configuring from XML document" );
return doConfigure( xmlHelper.createDOMReader().read( document ) );
}
protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException {
Element sfNode = doc.getRootElement().element( "session-factory" );
String name = sfNode.attributeValue( "name" );
if ( name != null ) {
properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
}
addProperties( sfNode );
parseSessionFactory( sfNode, name );
Element secNode = doc.getRootElement().element( "security" );
if ( secNode != null ) {
parseSecurity( secNode );
}
log.info( "Configured SessionFactory: " + name );
log.debug( "properties: " + properties );
return this;
}
private void parseSessionFactory(Element sfNode, String name) {
Iterator elements = sfNode.elementIterator();
while ( elements.hasNext() ) {
Element subelement = (Element) elements.next();
String subelementName = subelement.getName();
if ( "mapping".equals( subelementName ) ) {
parseMappingElement( subelement, name );
}
else if ( "class-cache".equals( subelementName ) ) {
String className = subelement.attributeValue( "class" );
Attribute regionNode = subelement.attribute( "region" );
final String region = ( regionNode == null ) ? className : regionNode.getValue();
boolean includeLazy = !"non-lazy".equals( subelement.attributeValue( "include" ) );
setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region, includeLazy );
}
else if ( "collection-cache".equals( subelementName ) ) {
String role = subelement.attributeValue( "collection" );
Attribute regionNode = subelement.attribute( "region" );
final String region = ( regionNode == null ) ? role : regionNode.getValue();
setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
}
else if ( "listener".equals( subelementName ) ) {
parseListener( subelement );
}
else if ( "event".equals( subelementName ) ) {
parseEvent( subelement );
}
}
}
protected void parseMappingElement(Element subelement, String name) {
Attribute rsrc = subelement.attribute( "resource" );
Attribute file = subelement.attribute( "file" );
Attribute jar = subelement.attribute( "jar" );
Attribute pkg = subelement.attribute( "package" );
Attribute clazz = subelement.attribute( "class" );
if ( rsrc != null ) {
log.debug( name + "<-" + rsrc );
addResource( rsrc.getValue() );
}
else if ( jar != null ) {
log.debug( name + "<-" + jar );
addJar( new File( jar.getValue() ) );
}
else if ( pkg != null ) {
throw new MappingException(
"An AnnotationConfiguration instance is required to use "
);
}
else if ( clazz != null ) {
throw new MappingException(
"An AnnotationConfiguration instance is required to use "
);
}
else {
if ( file == null ) {
throw new MappingException(
" element in configuration specifies no attributes"
);
}
log.debug( name + "<-" + file );
addFile( file.getValue() );
}
}
private void parseSecurity(Element secNode) {
String contextId = secNode.attributeValue( "context" );
setProperty(Environment.JACC_CONTEXTID, contextId);
log.info( "JACC contextID: " + contextId );
JACCConfiguration jcfg = new JACCConfiguration( contextId );
Iterator grantElements = secNode.elementIterator();
while ( grantElements.hasNext() ) {
Element grantElement = (Element) grantElements.next();
String elementName = grantElement.getName();
if ( "grant".equals( elementName ) ) {
jcfg.addPermission(
grantElement.attributeValue( "role" ),
grantElement.attributeValue( "entity-name" ),
grantElement.attributeValue( "actions" )
);
}
}
}
private void parseEvent(Element element) {
String type = element.attributeValue( "type" );
List listeners = element.elements();
String[] listenerClasses = new String[ listeners.size() ];
for ( int i = 0; i < listeners.size() ; i++ ) {
listenerClasses[i] = ( (Element) listeners.get( i ) ).attributeValue( "class" );
}
log.debug( "Event listeners: " + type + "=" + StringHelper.toString( listenerClasses ) );
setListeners( type, listenerClasses );
}
private void parseListener(Element element) {
String type = element.attributeValue( "type" );
if ( type == null ) {
throw new MappingException( "No type specified for listener" );
}
String impl = element.attributeValue( "class" );
log.debug( "Event listener: " + type + "=" + impl );
setListeners( type, new String[]{impl} );
}
public void setListener(String type, String listener) {
String[] listeners = null;
if ( listener != null ) {
listeners = (String[]) Array.newInstance( String.class, 1 );
listeners[0] = listener;
}
setListeners( type, listeners );
}
public void setListeners(String type, String[] listenerClasses) {
Object[] listeners = null;
if ( listenerClasses != null ) {
listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), listenerClasses.length );
for ( int i = 0; i < listeners.length ; i++ ) {
try {
listeners[i] = ReflectHelper.classForName( listenerClasses[i] ).newInstance();
}
catch (Exception e) {
throw new MappingException(
"Unable to instantiate specified event (" + type + ") listener class: " + listenerClasses[i],
e
);
}
}
}
setListeners( type, listeners );
}
public void setListener(String type, Object listener) {
Object[] listeners = null;
if ( listener != null ) {
listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), 1 );
listeners[0] = listener;
}
setListeners( type, listeners );
}
public void setListeners(String type, Object[] listeners) {
if ( "auto-flush".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setAutoFlushEventListeners( new AutoFlushEventListener[]{} );
}
else {
eventListeners.setAutoFlushEventListeners( (AutoFlushEventListener[]) listeners );
}
}
else if ( "merge".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setMergeEventListeners( new MergeEventListener[]{} );
}
else {
eventListeners.setMergeEventListeners( (MergeEventListener[]) listeners );
}
}
else if ( "create".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPersistEventListeners( new PersistEventListener[]{} );
}
else {
eventListeners.setPersistEventListeners( (PersistEventListener[]) listeners );
}
}
else if ( "create-onflush".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPersistOnFlushEventListeners( new PersistEventListener[]{} );
}
else {
eventListeners.setPersistOnFlushEventListeners( (PersistEventListener[]) listeners );
}
}
else if ( "delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setDeleteEventListeners( new DeleteEventListener[]{} );
}
else {
eventListeners.setDeleteEventListeners( (DeleteEventListener[]) listeners );
}
}
else if ( "dirty-check".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setDirtyCheckEventListeners( new DirtyCheckEventListener[]{} );
}
else {
eventListeners.setDirtyCheckEventListeners( (DirtyCheckEventListener[]) listeners );
}
}
else if ( "evict".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setEvictEventListeners( new EvictEventListener[]{} );
}
else {
eventListeners.setEvictEventListeners( (EvictEventListener[]) listeners );
}
}
else if ( "flush".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setFlushEventListeners( new FlushEventListener[]{} );
}
else {
eventListeners.setFlushEventListeners( (FlushEventListener[]) listeners );
}
}
else if ( "flush-entity".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setFlushEntityEventListeners( new FlushEntityEventListener[]{} );
}
else {
eventListeners.setFlushEntityEventListeners( (FlushEntityEventListener[]) listeners );
}
}
else if ( "load".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setLoadEventListeners( new LoadEventListener[]{} );
}
else {
eventListeners.setLoadEventListeners( (LoadEventListener[]) listeners );
}
}
else if ( "load-collection".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setInitializeCollectionEventListeners(
new InitializeCollectionEventListener[]{}
);
}
else {
eventListeners.setInitializeCollectionEventListeners(
(InitializeCollectionEventListener[]) listeners
);
}
}
else if ( "lock".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setLockEventListeners( new LockEventListener[]{} );
}
else {
eventListeners.setLockEventListeners( (LockEventListener[]) listeners );
}
}
else if ( "refresh".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setRefreshEventListeners( new RefreshEventListener[]{} );
}
else {
eventListeners.setRefreshEventListeners( (RefreshEventListener[]) listeners );
}
}
else if ( "replicate".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setReplicateEventListeners( new ReplicateEventListener[]{} );
}
else {
eventListeners.setReplicateEventListeners( (ReplicateEventListener[]) listeners );
}
}
else if ( "save-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setSaveOrUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
}
else {
eventListeners.setSaveOrUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
}
}
else if ( "save".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setSaveEventListeners( new SaveOrUpdateEventListener[]{} );
}
else {
eventListeners.setSaveEventListeners( (SaveOrUpdateEventListener[]) listeners );
}
}
else if ( "update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
}
else {
eventListeners.setUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
}
}
else if ( "pre-load".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreLoadEventListeners( new PreLoadEventListener[]{} );
}
else {
eventListeners.setPreLoadEventListeners( (PreLoadEventListener[]) listeners );
}
}
else if ( "pre-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreUpdateEventListeners( new PreUpdateEventListener[]{} );
}
else {
eventListeners.setPreUpdateEventListeners( (PreUpdateEventListener[]) listeners );
}
}
else if ( "pre-delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreDeleteEventListeners( new PreDeleteEventListener[]{} );
}
else {
eventListeners.setPreDeleteEventListeners( (PreDeleteEventListener[]) listeners );
}
}
else if ( "pre-insert".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreInsertEventListeners( new PreInsertEventListener[]{} );
}
else {
eventListeners.setPreInsertEventListeners( (PreInsertEventListener[]) listeners );
}
}
else if ( "pre-collection-recreate".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreCollectionRecreateEventListeners( new PreCollectionRecreateEventListener[]{} );
}
else {
eventListeners.setPreCollectionRecreateEventListeners( (PreCollectionRecreateEventListener[]) listeners );
}
}
else if ( "pre-collection-remove".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreCollectionRemoveEventListeners( new PreCollectionRemoveEventListener[]{} );
}
else {
eventListeners.setPreCollectionRemoveEventListeners( ( PreCollectionRemoveEventListener[]) listeners );
}
}
else if ( "pre-collection-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPreCollectionUpdateEventListeners( new PreCollectionUpdateEventListener[]{} );
}
else {
eventListeners.setPreCollectionUpdateEventListeners( ( PreCollectionUpdateEventListener[]) listeners );
}
}
else if ( "post-load".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostLoadEventListeners( new PostLoadEventListener[]{} );
}
else {
eventListeners.setPostLoadEventListeners( (PostLoadEventListener[]) listeners );
}
}
else if ( "post-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostUpdateEventListeners( new PostUpdateEventListener[]{} );
}
else {
eventListeners.setPostUpdateEventListeners( (PostUpdateEventListener[]) listeners );
}
}
else if ( "post-delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostDeleteEventListeners( new PostDeleteEventListener[]{} );
}
else {
eventListeners.setPostDeleteEventListeners( (PostDeleteEventListener[]) listeners );
}
}
else if ( "post-insert".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostInsertEventListeners( new PostInsertEventListener[]{} );
}
else {
eventListeners.setPostInsertEventListeners( (PostInsertEventListener[]) listeners );
}
}
else if ( "post-commit-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCommitUpdateEventListeners(
new PostUpdateEventListener[]{}
);
}
else {
eventListeners.setPostCommitUpdateEventListeners( (PostUpdateEventListener[]) listeners );
}
}
else if ( "post-commit-delete".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCommitDeleteEventListeners(
new PostDeleteEventListener[]{}
);
}
else {
eventListeners.setPostCommitDeleteEventListeners( (PostDeleteEventListener[]) listeners );
}
}
else if ( "post-commit-insert".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCommitInsertEventListeners(
new PostInsertEventListener[]{}
);
}
else {
eventListeners.setPostCommitInsertEventListeners( (PostInsertEventListener[]) listeners );
}
}
else if ( "post-collection-recreate".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCollectionRecreateEventListeners( new PostCollectionRecreateEventListener[]{} );
}
else {
eventListeners.setPostCollectionRecreateEventListeners( (PostCollectionRecreateEventListener[]) listeners );
}
}
else if ( "post-collection-remove".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCollectionRemoveEventListeners( new PostCollectionRemoveEventListener[]{} );
}
else {
eventListeners.setPostCollectionRemoveEventListeners( ( PostCollectionRemoveEventListener[]) listeners );
}
}
else if ( "post-collection-update".equals( type ) ) {
if ( listeners == null ) {
eventListeners.setPostCollectionUpdateEventListeners( new PostCollectionUpdateEventListener[]{} );
}
else {
eventListeners.setPostCollectionUpdateEventListeners( ( PostCollectionUpdateEventListener[]) listeners );
}
}
else {
throw new MappingException("Unrecognized listener type [" + type + "]");
}
}
public EventListeners getEventListeners() {
return eventListeners;
}
RootClass getRootClassMapping(String clazz) throws MappingException {
try {
return (RootClass) getClassMapping( clazz );
}
catch (ClassCastException cce) {
throw new MappingException( "You may only specify a cache for root mappings" );
}
}
/**
* Set up a cache for an entity class
*
* @param clazz
* @param concurrencyStrategy
* @return Configuration
* @throws MappingException
*/
public Configuration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy)
throws MappingException {
setCacheConcurrencyStrategy( clazz, concurrencyStrategy, clazz );
return this;
}
public void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region)
throws MappingException {
setCacheConcurrencyStrategy( clazz, concurrencyStrategy, region, true );
}
void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region, boolean includeLazy)
throws MappingException {
RootClass rootClass = getRootClassMapping( clazz );
if ( rootClass == null ) {
throw new MappingException( "Cannot cache an unknown entity: " + clazz );
}
rootClass.setCacheConcurrencyStrategy( concurrencyStrategy );
rootClass.setCacheRegionName( region );
rootClass.setLazyPropertiesCacheable( includeLazy );
}
/**
* Set up a cache for a collection role
*
* @param collectionRole
* @param concurrencyStrategy
* @return Configuration
* @throws MappingException
*/
public Configuration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy)
throws MappingException {
setCollectionCacheConcurrencyStrategy( collectionRole, concurrencyStrategy, collectionRole );
return this;
}
public void setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy, String region)
throws MappingException {
Collection collection = getCollectionMapping( collectionRole );
if ( collection == null ) {
throw new MappingException( "Cannot cache an unknown collection: " + collectionRole );
}
collection.setCacheConcurrencyStrategy( concurrencyStrategy );
collection.setCacheRegionName( region );
}
/**
* Get the query language imports
*
* @return a mapping from "import" names to fully qualified class names
*/
public Map getImports() {
return imports;
}
/**
* Create an object-oriented view of the configuration properties
*/
public Settings buildSettings() throws HibernateException {
Properties clone = ( Properties ) properties.clone();
PropertiesHelper.resolvePlaceHolders( clone );
return buildSettingsInternal( clone );
}
public Settings buildSettings(Properties props) throws HibernateException {
return buildSettingsInternal( props );
}
private Settings buildSettingsInternal(Properties props) {
final Settings settings = settingsFactory.buildSettings( props );
settings.setEntityTuplizerFactory( this.getEntityTuplizerFactory() );
// settings.setComponentTuplizerFactory( this.getComponentTuplizerFactory() );
return settings;
}
public Map getNamedSQLQueries() {
return namedSqlQueries;
}
public Map getSqlResultSetMappings() {
return sqlResultSetMappings;
}
/**
* @return the NamingStrategy.
*/
public NamingStrategy getNamingStrategy() {
return namingStrategy;
}
/**
* Set a custom naming strategy
*
* @param namingStrategy the NamingStrategy to set
*/
public Configuration setNamingStrategy(NamingStrategy namingStrategy) {
this.namingStrategy = namingStrategy;
return this;
}
/**
* Retrieve the IdentifierGeneratorFactory in effect for this configuration.
*
* @return This configuration's IdentifierGeneratorFactory.
*/
public DefaultIdentifierGeneratorFactory getIdentifierGeneratorFactory() {
return identifierGeneratorFactory;
}
public Mapping buildMapping() {
return new Mapping() {
public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
return identifierGeneratorFactory;
}
/**
* Returns the identifier type of a mapped class
*/
public Type getIdentifierType(String persistentClass) throws MappingException {
PersistentClass pc = ( (PersistentClass) classes.get( persistentClass ) );
if ( pc == null ) {
throw new MappingException( "persistent class not known: " + persistentClass );
}
return pc.getIdentifier().getType();
}
public String getIdentifierPropertyName(String persistentClass) throws MappingException {
final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
if ( pc == null ) {
throw new MappingException( "persistent class not known: " + persistentClass );
}
if ( !pc.hasIdentifierProperty() ) {
return null;
}
return pc.getIdentifierProperty().getName();
}
public Type getReferencedPropertyType(String persistentClass, String propertyName) throws MappingException {
final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
if ( pc == null ) {
throw new MappingException( "persistent class not known: " + persistentClass );
}
Property prop = pc.getReferencedProperty( propertyName );
if ( prop == null ) {
throw new MappingException(
"property not known: " +
persistentClass + '.' + propertyName
);
}
return prop.getType();
}
};
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
this.mapping = buildMapping();
xmlHelper = new XMLHelper();
}
public Map getFilterDefinitions() {
return filterDefinitions;
}
public void addFilterDefinition(FilterDefinition definition) {
filterDefinitions.put( definition.getFilterName(), definition );
}
public Iterator iterateFetchProfiles() {
return fetchProfiles.values().iterator();
}
public void addFetchProfile(FetchProfile fetchProfile) {
fetchProfiles.put( fetchProfile.getName(), fetchProfile );
}
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject object) {
auxiliaryDatabaseObjects.add( object );
}
public Map getSqlFunctions() {
return sqlFunctions;
}
public void addSqlFunction(String functionName, SQLFunction function) {
sqlFunctions.put( functionName, function );
}
public SessionFactoryObserver getSessionFactoryObserver() {
return sessionFactoryObserver;
}
public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) {
this.sessionFactoryObserver = sessionFactoryObserver;
}
// Mappings impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Internal implementation of the Mappings interface giving access to the Configuration's internal
* metadata repository state ({@link Configuration#classes}, {@link Configuration#tables}, etc).
*/
protected class MappingsImpl implements Mappings, Serializable {
private String schemaName;
public String getSchemaName() {
return schemaName;
}
public void setSchemaName(String schemaName) {
this.schemaName = schemaName;
}
private String catalogName;
public String getCatalogName() {
return catalogName;
}
public void setCatalogName(String catalogName) {
this.catalogName = catalogName;
}
private String defaultPackage;
public String getDefaultPackage() {
return defaultPackage;
}
public void setDefaultPackage(String defaultPackage) {
this.defaultPackage = defaultPackage;
}
private boolean autoImport;
public boolean isAutoImport() {
return autoImport;
}
public void setAutoImport(boolean autoImport) {
this.autoImport = autoImport;
}
private boolean defaultLazy;
public boolean isDefaultLazy() {
return defaultLazy;
}
public void setDefaultLazy(boolean defaultLazy) {
this.defaultLazy = defaultLazy;
}
private String defaultCascade;
public String getDefaultCascade() {
return defaultCascade;
}
public void setDefaultCascade(String defaultCascade) {
this.defaultCascade = defaultCascade;
}
private String defaultAccess;
public String getDefaultAccess() {
return defaultAccess;
}
public void setDefaultAccess(String defaultAccess) {
this.defaultAccess = defaultAccess;
}
public NamingStrategy getNamingStrategy() {
return namingStrategy;
}
public void setNamingStrategy(NamingStrategy namingStrategy) {
Configuration.this.namingStrategy = namingStrategy;
}
public Iterator iterateClasses() {
return classes.values().iterator();
}
public PersistentClass getClass(String entityName) {
return ( PersistentClass ) classes.get( entityName );
}
public PersistentClass locatePersistentClassByEntityName(String entityName) {
PersistentClass persistentClass = ( PersistentClass ) classes.get( entityName );
if ( persistentClass == null ) {
String actualEntityName = ( String ) imports.get( entityName );
if ( StringHelper.isNotEmpty( actualEntityName ) ) {
persistentClass = ( PersistentClass ) classes.get( actualEntityName );
}
}
return persistentClass;
}
public void addClass(PersistentClass persistentClass) throws DuplicateMappingException {
Object old = classes.put( persistentClass.getEntityName(), persistentClass );
if ( old != null ) {
throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() );
}
}
public void addImport(String entityName, String rename) throws DuplicateMappingException {
String existing = ( String ) imports.put( rename, entityName );
if ( existing != null ) {
if ( existing.equals( entityName ) ) {
log.info( "duplicate import: {} -> {}", entityName, rename );
}
else {
throw new DuplicateMappingException(
"duplicate import: " + rename + " refers to both " + entityName +
" and " + existing + " (try using auto-import=\"false\")",
"import",
rename
);
}
}
}
public Collection getCollection(String role) {
return ( Collection ) collections.get( role );
}
public Iterator iterateCollections() {
return collections.values().iterator();
}
public void addCollection(Collection collection) throws DuplicateMappingException {
Object old = collections.put( collection.getRole(), collection );
if ( old != null ) {
throw new DuplicateMappingException( "collection role", collection.getRole() );
}
}
public Table getTable(String schema, String catalog, String name) {
String key = Table.qualify(catalog, schema, name);
return (Table) tables.get(key);
}
public Iterator iterateTables() {
return tables.values().iterator();
}
public Table addTable(
String schema,
String catalog,
String name,
String subselect,
boolean isAbstract) {
name = getObjectNameNormalizer().normalizeIdentifierQuoting( name );
schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
String key = subselect == null ? Table.qualify( catalog, schema, name ) : subselect;
Table table = ( Table ) tables.get( key );
if ( table == null ) {
table = new Table();
table.setAbstract( isAbstract );
table.setName( name );
table.setSchema( schema );
table.setCatalog( catalog );
table.setSubselect( subselect );
tables.put( key, table );
}
else {
if ( !isAbstract ) {
table.setAbstract( false );
}
}
return table;
}
public Table addDenormalizedTable(
String schema,
String catalog,
String name,
boolean isAbstract,
String subselect,
Table includedTable) throws DuplicateMappingException {
name = getObjectNameNormalizer().normalizeIdentifierQuoting( name );
schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
String key = subselect == null ? Table.qualify(catalog, schema, name) : subselect;
if ( tables.containsKey( key ) ) {
throw new DuplicateMappingException( "table", name );
}
Table table = new DenormalizedTable( includedTable );
table.setAbstract( isAbstract );
table.setName( name );
table.setSchema( schema );
table.setCatalog( catalog );
table.setSubselect( subselect );
tables.put( key, table );
return table;
}
public NamedQueryDefinition getQuery(String name) {
return ( NamedQueryDefinition ) namedQueries.get( name );
}
public void addQuery(String name, NamedQueryDefinition query) throws DuplicateMappingException {
checkQueryName( name );
namedQueries.put( name.intern(), query );
}
private void checkQueryName(String name) throws DuplicateMappingException {
if ( namedQueries.containsKey( name ) || namedSqlQueries.containsKey( name ) ) {
throw new DuplicateMappingException( "query", name );
}
}
public NamedSQLQueryDefinition getSQLQuery(String name) {
return ( NamedSQLQueryDefinition ) namedSqlQueries.get( name );
}
public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException {
checkQueryName( name );
namedSqlQueries.put( name.intern(), query );
}
public ResultSetMappingDefinition getResultSetMapping(String name) {
return (ResultSetMappingDefinition) sqlResultSetMappings.get(name);
}
public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) throws DuplicateMappingException {
Object old = sqlResultSetMappings.put( sqlResultSetMapping.getName(), sqlResultSetMapping );
if ( old != null ) {
throw new DuplicateMappingException( "resultSet", sqlResultSetMapping.getName() );
}
}
protected void removeResultSetMapping(String name) {
sqlResultSetMappings.remove( name );
}
public TypeDef getTypeDef(String typeName) {
return ( TypeDef ) typeDefs.get( typeName );
}
public void addTypeDef(String typeName, String typeClass, Properties paramMap) {
TypeDef def = new TypeDef( typeClass, paramMap );
typeDefs.put( typeName, def );
log.debug( "Added " + typeName + " with class " + typeClass );
}
public Map getFilterDefinitions() {
return filterDefinitions;
}
public FilterDefinition getFilterDefinition(String name) {
return ( FilterDefinition ) filterDefinitions.get( name );
}
public void addFilterDefinition(FilterDefinition definition) {
filterDefinitions.put( definition.getFilterName(), definition );
}
public FetchProfile findOrCreateFetchProfile(String name) {
FetchProfile profile = ( FetchProfile ) fetchProfiles.get( name );
if ( profile == null ) {
profile = new FetchProfile( name );
fetchProfiles.put( name, profile );
}
return profile;
}
public Iterator iterateAuxliaryDatabaseObjects() {
return auxiliaryDatabaseObjects.iterator();
}
public ListIterator iterateAuxliaryDatabaseObjectsInReverse() {
return auxiliaryDatabaseObjects.listIterator( auxiliaryDatabaseObjects.size() );
}
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
}
/**
* Internal struct used to help track physical table names to logical table names.
*/
private class TableDescription implements Serializable {
final String logicalName;
final Table denormalizedSupertable;
TableDescription(String logicalName, Table denormalizedSupertable) {
this.logicalName = logicalName;
this.denormalizedSupertable = denormalizedSupertable;
}
}
public String getLogicalTableName(Table table) throws MappingException {
return getLogicalTableName( table.getQuotedSchema(), table.getCatalog(), table.getQuotedName() );
}
private String getLogicalTableName(String schema, String catalog, String physicalName) throws MappingException {
String key = buildTableNameKey( schema, catalog, physicalName );
TableDescription descriptor = (TableDescription) tableNameBinding.get( key );
if (descriptor == null) {
throw new MappingException( "Unable to find physical table: " + physicalName);
}
return descriptor.logicalName;
}
public void addTableBinding(
String schema,
String catalog,
String logicalName,
String physicalName,
Table denormalizedSuperTable) throws DuplicateMappingException {
String key = buildTableNameKey( schema, catalog, physicalName );
TableDescription tableDescription = new TableDescription( logicalName, denormalizedSuperTable );
TableDescription oldDescriptor = ( TableDescription ) tableNameBinding.put( key, tableDescription );
if ( oldDescriptor != null && ! oldDescriptor.logicalName.equals( logicalName ) ) {
//TODO possibly relax that
throw new DuplicateMappingException(
"Same physical table name [" + physicalName + "] references several logical table names: [" +
oldDescriptor.logicalName + "], [" + logicalName + ']',
"table",
physicalName
);
}
}
private String buildTableNameKey(String schema, String catalog, String finalName) {
StringBuffer keyBuilder = new StringBuffer();
if (schema != null) keyBuilder.append( schema );
keyBuilder.append( ".");
if (catalog != null) keyBuilder.append( catalog );
keyBuilder.append( ".");
keyBuilder.append( finalName );
return keyBuilder.toString();
}
/**
* Internal struct used to maintain xref between physical and logical column
* names for a table. Mainly this is used to ensure that the defined
* {@link NamingStrategy} is not creating duplicate column names.
*/
private class TableColumnNameBinding implements Serializable {
private final String tableName;
private Map/**/ logicalToPhysical = new HashMap();
private Map/**/ physicalToLogical = new HashMap();
private TableColumnNameBinding(String tableName) {
this.tableName = tableName;
}
public void addBinding(String logicalName, Column physicalColumn) {
bindLogicalToPhysical( logicalName, physicalColumn );
bindPhysicalToLogical( logicalName, physicalColumn );
}
private void bindLogicalToPhysical(String logicalName, Column physicalColumn) throws DuplicateMappingException {
final String logicalKey = logicalName.toLowerCase();
final String physicalName = physicalColumn.getQuotedName();
final String existingPhysicalName = ( String ) logicalToPhysical.put( logicalKey, physicalName );
if ( existingPhysicalName != null ) {
boolean areSamePhysicalColumn = physicalColumn.isQuoted()
? existingPhysicalName.equals( physicalName )
: existingPhysicalName.equalsIgnoreCase( physicalName );
if ( ! areSamePhysicalColumn ) {
throw new DuplicateMappingException(
" Table [" + tableName + "] contains logical column name [" + logicalName
+ "] referenced by multiple physical column names: [" + existingPhysicalName
+ "], [" + physicalName + "]",
"column-binding",
tableName + "." + logicalName
);
}
}
}
private void bindPhysicalToLogical(String logicalName, Column physicalColumn) throws DuplicateMappingException {
final String physicalName = physicalColumn.getQuotedName();
final String existingLogicalName = ( String ) physicalToLogical.put( physicalName, logicalName );
if ( existingLogicalName != null && ! existingLogicalName.equals( logicalName ) ) {
throw new DuplicateMappingException(
" Table [" + tableName + "] contains phyical column name [" + physicalName
+ "] represented by different logical column names: [" + existingLogicalName
+ "], [" + logicalName + "]",
"column-binding",
tableName + "." + physicalName
);
}
}
}
public void addColumnBinding(String logicalName, Column physicalColumn, Table table) throws DuplicateMappingException {
TableColumnNameBinding binding = ( TableColumnNameBinding ) columnNameBindingPerTable.get( table );
if ( binding == null ) {
binding = new TableColumnNameBinding( table.getName() );
columnNameBindingPerTable.put( table, binding );
}
binding.addBinding( logicalName, physicalColumn );
}
public String getPhysicalColumnName(String logicalName, Table table) throws MappingException {
logicalName = logicalName.toLowerCase();
String finalName = null;
Table currentTable = table;
do {
TableColumnNameBinding binding = ( TableColumnNameBinding ) columnNameBindingPerTable.get( currentTable );
if ( binding != null ) {
finalName = ( String ) binding.logicalToPhysical.get( logicalName );
}
String key = buildTableNameKey(
currentTable.getQuotedSchema(), currentTable.getCatalog(), currentTable.getQuotedName()
);
TableDescription description = ( TableDescription ) tableNameBinding.get( key );
if ( description != null ) {
currentTable = description.denormalizedSupertable;
}
else {
currentTable = null;
}
} while ( finalName == null && currentTable != null );
if ( finalName == null ) {
throw new MappingException(
"Unable to find column with logical name " + logicalName + " in table " + table.getName()
);
}
return finalName;
}
public String getLogicalColumnName(String physicalName, Table table) throws MappingException {
String logical = null;
Table currentTable = table;
TableDescription description = null;
do {
TableColumnNameBinding binding = ( TableColumnNameBinding ) columnNameBindingPerTable.get( currentTable );
if ( binding != null ) {
logical = ( String ) binding.physicalToLogical.get( physicalName );
}
String key = buildTableNameKey(
currentTable.getQuotedSchema(), currentTable.getCatalog(), currentTable.getQuotedName()
);
description = ( TableDescription ) tableNameBinding.get( key );
if ( description != null ) {
currentTable = description.denormalizedSupertable;
}
else {
currentTable = null;
}
}
while ( logical == null && currentTable != null && description != null );
if ( logical == null ) {
throw new MappingException(
"Unable to find logical column name from physical name "
+ physicalName + " in table " + table.getName()
);
}
return logical;
}
public void addSecondPass(SecondPass sp) {
addSecondPass( sp, false );
}
public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue) {
if ( onTopOfTheQueue ) {
secondPasses.add( 0, sp );
}
else {
secondPasses.add( sp );
}
}
public void addPropertyReference(String referencedClass, String propertyName) {
propertyReferences.add( new PropertyReference( referencedClass, propertyName, false ) );
}
public void addUniquePropertyReference(String referencedClass, String propertyName) {
propertyReferences.add( new PropertyReference( referencedClass, propertyName, true ) );
}
public void addToExtendsQueue(ExtendsQueueEntry entry) {
extendsQueue.put( entry, null );
}
public DefaultIdentifierGeneratorFactory getIdentifierGeneratorFactory() {
return identifierGeneratorFactory;
}
public void addMappedSuperclass(Class type, MappedSuperclass mappedSuperclass) {
mappedSuperclasses.put( type, mappedSuperclass );
}
public MappedSuperclass getMappedSuperclass(Class type) {
return (MappedSuperclass) mappedSuperclasses.get( type );
}
public ObjectNameNormalizer getObjectNameNormalizer() {
return normalizer;
}
public Properties getConfigurationProperties() {
return properties;
}
}
final ObjectNameNormalizer normalizer = new ObjectNameNormalizerImpl();
final class ObjectNameNormalizerImpl extends ObjectNameNormalizer implements Serializable {
public boolean isUseQuotedIdentifiersGlobally() {
//Do not cache this value as we lazily set it in Hibernate Annotation (AnnotationConfiguration)
//TODO use a dedicated protected useQuotedIdentifier flag in Configuration (overriden by AnnotationConfiguration)
String setting = (String) properties.get( Environment.GLOBALLY_QUOTED_IDENTIFIERS );
return setting != null && Boolean.valueOf( setting ).booleanValue();
}
public NamingStrategy getNamingStrategy() {
return namingStrategy;
}
}
}