[hibernate-commits] Hibernate SVN: r15210 - in core/trunk/core/src/main/java/org/hibernate: impl and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Sep 17 12:44:23 EDT 2008


Author: steve.ebersole at jboss.com
Date: 2008-09-17 12:44:23 -0400 (Wed, 17 Sep 2008)
New Revision: 15210

Modified:
   core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
   core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java
   core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
Log:
HHH-3439 : Mappings

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java	2008-09-17 15:58:58 UTC (rev 15209)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java	2008-09-17 16:44:23 UTC (rev 15210)
@@ -66,11 +66,15 @@
 import org.hibernate.MappingNotFoundException;
 import org.hibernate.SessionFactory;
 import org.hibernate.SessionFactoryObserver;
+import org.hibernate.DuplicateMappingException;
 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;
@@ -115,6 +119,9 @@
 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.proxy.EntityNotFoundDelegate;
 import org.hibernate.secure.JACCConfiguration;
 import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
@@ -156,68 +163,73 @@
 	protected Map collections;
 	protected Map tables;
 	protected List auxiliaryDatabaseObjects;
-	protected Map sqlFunctions;
+
 	protected Map namedQueries;
 	protected Map namedSqlQueries;
-	/**
-	 * Map<String, SqlResultSetMapping> result set name, result set description
-	 */
-	protected Map sqlResultSetMappings;
+	protected Map/*<String, SqlResultSetMapping>*/ 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 tableNameBinding;
-	protected Map columnNameBindingPerTable;
+
+	protected Map sqlFunctions;
+
 	private Interceptor interceptor;
 	private Properties properties;
 	private EntityResolver entityResolver;
 	private EntityNotFoundDelegate entityNotFoundDelegate;
 
 	protected transient XMLHelper xmlHelper;
-	protected transient Map typeDefs;
-
 	protected NamingStrategy namingStrategy;
+	private SessionFactoryObserver sessionFactoryObserver;
 
 	private EventListeners eventListeners;
 
 	protected final SettingsFactory settingsFactory;
 
-	private SessionFactoryObserver sessionFactoryObserver;
+	private transient Mapping mapping = buildMapping();
 
 	protected void reset() {
 		classes = new HashMap();
 		imports = new HashMap();
 		collections = new HashMap();
 		tables = new TreeMap();
+
 		namedQueries = new HashMap();
 		namedSqlQueries = new HashMap();
 		sqlResultSetMappings = new HashMap();
-		xmlHelper = new XMLHelper();
+
 		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();
-		filterDefinitions = new HashMap();
-		fetchProfiles = new HashMap();
-//		extendsQueue = new ArrayList();
-		extendsQueue = new HashMap();
-		auxiliaryDatabaseObjects = new ArrayList();
-		tableNameBinding = new HashMap();
-		columnNameBindingPerTable = new HashMap();
-		namingStrategy = DefaultNamingStrategy.INSTANCE;
+
 		sqlFunctions = new HashMap();
 	}
 
-	private transient Mapping mapping = buildMapping();
-
-
-
 	protected Configuration(SettingsFactory settingsFactory) {
 		this.settingsFactory = settingsFactory;
 		reset();
@@ -710,25 +722,7 @@
 	 * mappings to.
 	 */
 	public Mappings createMappings() {
-		return new Mappings(
-				classes,
-				collections,
-				tables,
-				namedQueries,
-				namedSqlQueries,
-				sqlResultSetMappings,
-				imports,
-				secondPasses,
-				propertyReferences,
-				namingStrategy,
-				typeDefs,
-				filterDefinitions,
-				fetchProfiles,
-				extendsQueue,
-				auxiliaryDatabaseObjects,
-				tableNameBinding,
-				columnNameBindingPerTable
-			);
+		return new MappingsImpl();
 	}
 
 
@@ -2185,8 +2179,8 @@
 		filterDefinitions.put( definition.getFilterName(), definition );
 	}
 
-	public Map getFetchProfiles() {
-		return fetchProfiles;
+	public Iterator iterateFetchProfiles() {
+		return fetchProfiles.values().iterator();
 	}
 
 	public void addFetchProfile(FetchProfile fetchProfile) {
@@ -2212,4 +2206,494 @@
 	public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) {
 		this.sessionFactoryObserver = sessionFactoryObserver;
 	}
+
+
+	// Mappings impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Internal implementation of the Mappings interface giving access to the Configuration's internal
+	 * <tt>metadata repository</tt> 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) {
+			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 {
+			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() );
+			}
+
+		}
+
+		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/*<String, String>*/ logicalToPhysical = new HashMap();
+			private Map/*<String, String>*/ 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.getSchema(), currentTable.getCatalog(), currentTable.getName()
+				);
+				TableDescription description = ( TableDescription ) tableNameBinding.get( key );
+				if ( description != null ) {
+					currentTable = description.denormalizedSupertable;
+				}
+			} 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.getSchema(), currentTable.getCatalog(), currentTable.getName()
+				);
+				description = ( TableDescription ) tableNameBinding.get( key );
+				if ( description != null ) {
+					currentTable = description.denormalizedSupertable;
+				}
+			}
+			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 );
+		}
+
+	}
 }

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java	2008-09-17 15:58:58 UTC (rev 15209)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java	2008-09-17 16:44:23 UTC (rev 15210)
@@ -26,13 +26,10 @@
 
 import java.io.Serializable;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 import java.util.Properties;
-import java.util.HashMap;
+import java.util.Map;
+import java.util.ListIterator;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.hibernate.DuplicateMappingException;
 import org.hibernate.MappingException;
 import org.hibernate.engine.FilterDefinition;
@@ -40,542 +37,485 @@
 import org.hibernate.engine.NamedSQLQueryDefinition;
 import org.hibernate.engine.ResultSetMappingDefinition;
 import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.DenormalizedTable;
 import org.hibernate.mapping.PersistentClass;
 import org.hibernate.mapping.Table;
 import org.hibernate.mapping.TypeDef;
 import org.hibernate.mapping.AuxiliaryDatabaseObject;
 import org.hibernate.mapping.Column;
 import org.hibernate.mapping.FetchProfile;
-import org.hibernate.util.StringHelper;
 
 /**
- * A collection of mappings from classes and collections to
- * relational database tables. (Represents a single
- * <tt>&lt;hibernate-mapping&gt;</tt> element.)
+ * A collection of mappings from classes and collections to relational database tables.  Represents a single
+ * <tt>&lt;hibernate-mapping&gt;</tt> element.
+ * <p/>
+ * todo : the statement about this representing a single mapping element is simply not true if it was ever the case.
+ * this contract actually represents 3 scopes of information: <ol>
+ * <li><i>bounded</i> state : this is information which is indeed scoped by a single mapping</li>
+ * <li><i>unbounded</i> state : this is information which is Configuration wide (think of metadata repository)</li>
+ * <li><i>transient</i> state : state which changed at its own pace (naming strategy)</li>
+ * </ol>
+ *
  * @author Gavin King
+ * @author Steve Ebersole
  */
-public class Mappings implements Serializable {
+public interface Mappings {
 
-	private static final Logger log = LoggerFactory.getLogger(Mappings.class);
+	/**
+	 * Get the current naming strategy.
+	 *
+	 * @return The current naming strategy.
+	 */
+	public NamingStrategy getNamingStrategy();
 
-	protected final Map classes;
-	protected final Map collections;
-	protected final Map tables;
-	protected final Map queries;
-	protected final Map sqlqueries;
-	protected final Map resultSetMappings;
-	protected final Map typeDefs;
-	protected final List secondPasses;
-	protected final Map imports;
-	protected String schemaName;
-    protected String catalogName;
-	protected String defaultCascade;
-	protected String defaultPackage;
-	protected String defaultAccess;
-	protected boolean autoImport;
-	protected boolean defaultLazy;
-	protected final List propertyReferences;
-	protected final NamingStrategy namingStrategy;
-	protected final Map filterDefinitions;
-	protected final Map fetchProfiles;
-	protected final List auxiliaryDatabaseObjects;
+	/**
+	 * Set the current naming strategy.
+	 *
+	 * @param namingStrategy The naming strategy to use.
+	 */
+	public void setNamingStrategy(NamingStrategy namingStrategy);
 
-	protected final Map extendsQueue;
-//	private final List extendsQueue;
+	/**
+	 * Returns the currently bound default schema name.
+	 *
+	 * @return The currently bound schema name
+	 */
+	public String getSchemaName();
 
 	/**
-	 * binding table between the logical column name and the name out of the naming strategy
-	 * for each table.
-	 * According that when the column name is not set, the property name is considered as such
-	 * This means that while theorically possible through the naming strategy contract, it is
-	 * forbidden to have 2 real columns having the same logical name
-	 * <Table, ColumnNames >
+	 * Sets the currently bound default schema name.
+	 *
+	 * @param schemaName The schema name to bind as the current default.
 	 */
-	protected final Map columnNameBindingPerTable;
+	public void setSchemaName(String schemaName);
+
 	/**
-	 * binding between logical table name and physical one (ie after the naming strategy has been applied)
-	 * <String, TableDescription>
+	 * Returns the currently bound default catalog name.
+	 *
+	 * @return The currently bound catalog name, or null if none.
 	 */
-	protected final Map tableNameBinding;
+	public String getCatalogName();
 
+    /**
+     * Sets the currently bound default catalog name.
+	 *
+     * @param catalogName The catalog name to use as the current default.
+     */
+    public void setCatalogName(String catalogName);
 
-	Mappings(
-			final Map classes,
-			final Map collections,
-			final Map tables,
-			final Map queries,
-			final Map sqlqueries,
-			final Map sqlResultSetMappings,
-			final Map imports,
-			final List secondPasses,
-			final List propertyReferences,
-			final NamingStrategy namingStrategy,
-			final Map typeDefs,
-			final Map filterDefinitions,
-			final Map fetchProfiles,
-//			final List extendsQueue,
-			final Map extendsQueue,
-			final List auxiliaryDatabaseObjects,
-			final Map tableNamebinding,
-			final Map columnNameBindingPerTable) {
-		this.classes = classes;
-		this.collections = collections;
-		this.queries = queries;
-		this.sqlqueries = sqlqueries;
-		this.resultSetMappings = sqlResultSetMappings;
-		this.tables = tables;
-		this.imports = imports;
-		this.secondPasses = secondPasses;
-		this.propertyReferences = propertyReferences;
-		this.namingStrategy = namingStrategy;
-		this.typeDefs = typeDefs;
-		this.filterDefinitions = filterDefinitions;
-		this.fetchProfiles = fetchProfiles;
-		this.extendsQueue = extendsQueue;
-		this.auxiliaryDatabaseObjects = auxiliaryDatabaseObjects;
-		this.tableNameBinding = tableNamebinding;
-		this.columnNameBindingPerTable = columnNameBindingPerTable;
-	}
+	/**
+	 * Get the currently bound default package name.
+	 *
+	 * @return The currently bound default package name
+	 */
+	public String getDefaultPackage();
 
-	public void addClass(PersistentClass persistentClass) throws MappingException {
-		Object old = classes.put( persistentClass.getEntityName(), persistentClass );
-		if ( old!=null ) {
-			throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() );
-		}
-	}
-	public void addCollection(Collection collection) throws MappingException {
-		Object old = collections.put( collection.getRole(), collection );
-		if ( old!=null ) {
-			throw new DuplicateMappingException( "collection role", collection.getRole() );
-		}
-	}
-	public PersistentClass getClass(String className) {
-		return (PersistentClass) classes.get(className);
-	}
-	public Collection getCollection(String role) {
-		return (Collection) collections.get(role);
-	}
+	/**
+	 * Set the current default package name.
+	 *
+	 * @param defaultPackage The package name to set as the current default.
+	 */
+	public void setDefaultPackage(String defaultPackage);
 
-	public void addImport(String className, String rename) throws MappingException {
-		String existing = (String) imports.put(rename, className);
-		if ( existing!=null ) {
-			if ( existing.equals(className) ) {
-				log.info( "duplicate import: " + className + "->" + rename );
-			}
-			else {
-				throw new DuplicateMappingException(
-						"duplicate import: " + rename + 
-						" refers to both " + className + 
-						" and " + existing + 
-						" (try using auto-import=\"false\")",
-						"import",
-						rename
-					);
-			}
-		}
-	}
+	/**
+	 * Determine whether auto importing of entity names is currently enabled.
+	 *
+	 * @return True if currently enabled; false otherwise.
+	 */
+	public boolean isAutoImport();
 
-	public Table addTable(String schema, 
-			String catalog, 
-			String name,
-			String subselect,
-			boolean isAbstract
-	) {
-        String key = subselect==null ?
-			Table.qualify(catalog, schema, name) :
-			subselect;
-		Table table = (Table) tables.get(key);
+	/**
+	 * Set whether to enable auto importing of entity names.
+	 *
+	 * @param autoImport True to enable; false to diasable.
+	 * @see #addImport
+	 */
+	public void setAutoImport(boolean autoImport);
 
-		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);
-		}
+	/**
+	 * Determine whether default laziness is currently enabled.
+	 *
+	 * @return True if enabled, false otherwise.
+	 */
+	public boolean isDefaultLazy();
 
-		return table;
-	}
+	/**
+	 * Set whether to enable default laziness.
+	 *
+	 * @param defaultLazy True to enable, false to disable.
+	 */
+	public void setDefaultLazy(boolean defaultLazy);
 
-	public Table addDenormalizedTable(
-			String schema, 
-			String catalog, 
-			String name,
-			boolean isAbstract, 
-			String subselect,
-			Table includedTable)
-	throws MappingException {
-        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;
-	}
+	/**
+	 * Get the current default cascade style.
+	 *
+	 * @return The current default cascade style.
+	 */
+	public String getDefaultCascade();
 
-	public Table getTable(String schema, String catalog, String name) {
-        String key = Table.qualify(catalog, schema, name);
-		return (Table) tables.get(key);
-	}
+	/**
+	 * Sets the current default cascade style.
+	 * .
+	 * @param defaultCascade The cascade style to set as the current default.
+	 */
+	public void setDefaultCascade(String defaultCascade);
 
-	public String getSchemaName() {
-		return schemaName;
-	}
+	/**
+	 * Get the current default property access style.
+	 *
+	 * @return The current default property access style.
+	 */
+	public String getDefaultAccess();
 
-    public String getCatalogName() {
-        return catalogName;
-    }
+	/**
+	 * Sets the current default property access style.
+	 *
+	 * @param defaultAccess The access style to use as the current default.
+	 */
+	public void setDefaultAccess(String defaultAccess);
 
-	public String getDefaultCascade() {
-		return defaultCascade;
-	}
 
 	/**
-	 * Sets the schemaName.
-	 * @param schemaName The schemaName to set
+	 * Retrieves an iterator over the entity metadata present in this repository.
+	 *
+	 * @return Iterator over class metadata.
 	 */
-	public void setSchemaName(String schemaName) {
-		this.schemaName = schemaName;
-	}
+	public Iterator iterateClasses();
 
-    /**
-     * Sets the catalogName.
-     * @param catalogName The catalogName to set
-     */
-    public void setCatalogName(String catalogName) {
-        this.catalogName = catalogName;
-    }
+	/**
+	 * Retrieves the entity mapping metadata for the given entity name.
+	 *
+	 * @param entityName The entity name for which to retrieve the metadata.
+	 * @return The entity mapping metadata, or null if none found matching given entity name.
+	 */
+	public PersistentClass getClass(String entityName);
 
 	/**
-	 * Sets the defaultCascade.
-	 * @param defaultCascade The defaultCascade to set
+	 * Retrieves the entity mapping metadata for the given entity name, potentially accounting
+	 * for imports.
+	 *
+	 * @param entityName The entity name for which to retrieve the metadata.
+	 * @return The entity mapping metadata, or null if none found matching given entity name.
 	 */
-	public void setDefaultCascade(String defaultCascade) {
-		this.defaultCascade = defaultCascade;
-	}
+	public PersistentClass locatePersistentClassByEntityName(String entityName);
 
 	/**
-	 * sets the default access strategy
-	 * @param defaultAccess the default access strategy.
+	 * Add entity mapping metadata.
+	 *
+	 * @param persistentClass The entity metadata
+	 * @throws DuplicateMappingException Indicates there4 was already an extry
+	 * corresponding to the given entity name.
 	 */
-	public void setDefaultAccess(String defaultAccess) {
-		this.defaultAccess = defaultAccess;
-	}
+	public void addClass(PersistentClass persistentClass) throws DuplicateMappingException;
 
-	public String getDefaultAccess() {
-		return defaultAccess;
-	}
+	/**
+	 * Adds an import (HQL entity rename) to the repository.
+	 *
+	 * @param entityName The entity name being renamed.
+	 * @param rename The rename
+	 * @throws DuplicateMappingException If rename already is mapped to another
+	 * entity name in this repository.
+	 */
+	public void addImport(String entityName, String rename) throws DuplicateMappingException;
 
-	public void addQuery(String name, NamedQueryDefinition query) throws MappingException {
-		checkQueryExist(name);
-		queries.put( name.intern(), query );
-	}
+	/**
+	 * Retrieves the collection mapping metadata for the given collection role.
+	 *
+	 * @param role The collection role for which to retrieve the metadata.
+	 * @return The collection mapping metadata, or null if no matching collection role found.
+	 */
+	public Collection getCollection(String role);
 
-	public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws MappingException {
-		checkQueryExist(name);
-		sqlqueries.put( name.intern(), query );
-	}
+	/**
+	 * Returns an iterator over collection metadata.
+	 *
+	 * @return Iterator over collection metadata.
+	 */
+	public Iterator iterateCollections();
 
-	private void checkQueryExist(String name) throws MappingException {
-		if ( sqlqueries.containsKey(name) || queries.containsKey(name) ) {
-			throw new DuplicateMappingException("query", name);
-		}
-	}
+	/**
+	 * Add collection mapping metadata to this repository.
+	 *
+	 * @param collection The collection metadata
+	 * @throws DuplicateMappingException Indicates there was already an entry
+	 * corresponding to the given collection role
+	 */
+	public void addCollection(Collection collection) throws DuplicateMappingException;
 
-	public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) {
-		final String name = sqlResultSetMapping.getName();
-		if ( resultSetMappings.containsKey(name) ) {
-			throw new DuplicateMappingException("resultSet",  name);
-		}
-		resultSetMappings.put(name, sqlResultSetMapping);
-	}
+	/**
+	 * Returns the named table metadata.
+	 *
+	 * @param schema The named schema in which the table belongs (or null).
+	 * @param catalog The named catalog in which the table belongs (or null).
+	 * @param name The table name
+	 * @return The table metadata, or null.
+	 */
+	public Table getTable(String schema, String catalog, String name);
 
-	public ResultSetMappingDefinition getResultSetMapping(String name) {
-		return (ResultSetMappingDefinition) resultSetMappings.get(name);
-	}
+	/**
+	 * Returns an iterator over table metadata.
+	 *
+	 * @return Iterator over table metadata.
+	 */
+	public Iterator iterateTables();
 
+	/**
+	 * Adds table metedata to this repository returning the created
+	 * metadata instance.
+	 *
+	 * @param schema The named schema in which the table belongs (or null).
+	 * @param catalog The named catalog in which the table belongs (or null).
+	 * @param name The table name
+	 * @param subselect A select statement wwich defines a logical table, much
+	 * like a DB view.
+	 * @param isAbstract Is the table abstract (i.e. not really existing in the DB)?
+	 * @return The created table metadata, or the existing reference.
+	 */
+	public Table addTable(String schema, String catalog, String name, String subselect, boolean isAbstract);
 
-	public NamedQueryDefinition getQuery(String name) {
-		return (NamedQueryDefinition) queries.get(name);
-	}
+	/**
+	 * Adds a 'denormalized table' to this repository.
+	 *
+	 * @param schema The named schema in which the table belongs (or null).
+	 * @param catalog The named catalog in which the table belongs (or null).
+	 * @param name The table name
+	 * @param isAbstract Is the table abstract (i.e. not really existing in the DB)?
+	 * @param subselect A select statement wwich defines a logical table, much
+	 * like a DB view.
+	 * @param includedTable ???
+	 * @return The created table metadata.
+	 * @throws DuplicateMappingException If such a table mapping already exists.
+	 */
+	public Table addDenormalizedTable(String schema, String catalog, String name, boolean isAbstract, String subselect, Table includedTable)
+			throws DuplicateMappingException;
 
-	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);
-		}
-	}
+	/**
+	 * Get named query metadata by name.
+	 *
+	 * @param name The named query name
+	 * @return The query metadata, or null.
+	 */
+	public NamedQueryDefinition getQuery(String name);
 
 	/**
-	 * Returns the autoImport.
-	 * @return boolean
+	 * Adds metadata for a named query to this repository.
+	 *
+	 * @param name The name
+	 * @param query The metadata
+	 * @throws DuplicateMappingException If a query already exists with that name.
 	 */
-	public boolean isAutoImport() {
-		return autoImport;
-	}
+	public void addQuery(String name, NamedQueryDefinition query) throws DuplicateMappingException;
 
 	/**
-	 * Sets the autoImport.
-	 * @param autoImport The autoImport to set
+	 * Get named SQL query metadata.
+	 *
+	 * @param name The named SQL query name.
+	 * @return The meatdata, or null if none found.
 	 */
-	public void setAutoImport(boolean autoImport) {
-		this.autoImport = autoImport;
-	}
+	public NamedSQLQueryDefinition getSQLQuery(String name);
 
-	void addUniquePropertyReference(String referencedClass, String propertyName) {
-		PropertyReference upr = new PropertyReference();
-		upr.referencedClass = referencedClass;
-		upr.propertyName = propertyName;
-		upr.unique = true;
-		propertyReferences.add(upr);
-	}
+	/**
+	 * Adds metadata for a named SQL query to this repository.
+	 *
+	 * @param name The name
+	 * @param query The metadata
+	 * @throws DuplicateMappingException If a query already exists with that name.
+	 */
+	public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws DuplicateMappingException;
 
-	void addPropertyReference(String referencedClass, String propertyName) {
-		PropertyReference upr = new PropertyReference();
-		upr.referencedClass = referencedClass;
-		upr.propertyName = propertyName;
-		propertyReferences.add(upr);
-	}
+	/**
+	 * Get the metadata for a named SQL result set mapping.
+	 *
+	 * @param name The mapping name.
+	 * @return The SQL result set mapping metadat, or null if none found.
+	 */
+	public ResultSetMappingDefinition getResultSetMapping(String name);
 
-	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();
-	}
+	/**
+	 * Adds the metadata for a named SQL result set mapping to this repository.
+	 *
+	 * @param sqlResultSetMapping The metadata
+	 * @throws DuplicateMappingException If metadata for another SQL result mapping was
+	 * already found under the given name.
+	 */
+	public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) throws DuplicateMappingException;
 
-	static final class PropertyReference implements Serializable {
-		String referencedClass;
-		String propertyName;
-		boolean unique;
-	}
+	/**
+	 * Retrieve a type definition by name.
+	 *
+	 * @param typeName The name of the type definition to retrieve.
+	 * @return The type definition, or null if none found.
+	 */
+	public TypeDef getTypeDef(String typeName);
 
 	/**
-	 * @return Returns the defaultPackage.
+	 * Adds a type definition to this metadata repository.
+	 *
+	 * @param typeName The type name.
+	 * @param typeClass The class implementing the {@link org.hibernate.type.Type} contract.
+	 * @param paramMap Map of parameters to be used to configure the type after instantiation.
 	 */
-	public String getDefaultPackage() {
-		return defaultPackage;
-	}
+	public void addTypeDef(String typeName, String typeClass, Properties paramMap);
 
 	/**
-	 * @param defaultPackage The defaultPackage to set.
+	 * Retrieves the copmplete map of filter definitions.
+	 *
+	 * @return The filter definition map.
 	 */
-	public void setDefaultPackage(String defaultPackage) {
-		this.defaultPackage = defaultPackage;
-	}
+	public Map getFilterDefinitions();
 
-	public NamingStrategy getNamingStrategy() {
-		return namingStrategy;
-	}
+	/**
+	 * Retrieves a filter definition by name.
+	 *
+	 * @param name The name of the filter defintion to retrieve.
+	 * @return The filter definition, or null.
+	 */
+	public FilterDefinition getFilterDefinition(String name);
 
-	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);
-	}
+	/**
+	 * Adds a filter definition to this repository.
+	 *
+	 * @param definition The filter definition to add.
+	 */
+	public void addFilterDefinition(FilterDefinition definition);
 
-	public TypeDef getTypeDef(String typeName) {
-		return (TypeDef) typeDefs.get(typeName);
-	}
+	/**
+	 * Retrieves a fetch profile by either finding one currently in this repository matching the given name
+	 * or by creating one (and adding it).
+	 *
+	 * @param name The name of the profile.
+	 * @return The fetch profile metadata.
+	 */
+	public FetchProfile findOrCreateFetchProfile(String name);
 
-    public Iterator iterateCollections() {
-        return collections.values().iterator();
-    }
-    
-    public Iterator iterateTables() {
-    	return tables.values().iterator();
-    }
+	/**
+	 * Retrieves an iterator over the metadata pertaining to all auxilary database objects int this repository.
+	 *
+	 * @return Iterator over the auxilary database object metadata.
+	 */
+	public Iterator iterateAuxliaryDatabaseObjects();
 
-	public Map getFilterDefinitions() {
-		return filterDefinitions;
-	}
+	/**
+	 * Same as {@link #iterateAuxliaryDatabaseObjects()} except that here the iterator is reversed.
+	 *
+	 * @return The reversed iterator.
+	 */
+	public ListIterator iterateAuxliaryDatabaseObjectsInReverse();
 
-	public void addFilterDefinition(FilterDefinition definition) {
-		filterDefinitions.put( definition.getFilterName(), definition );
-	}
-	
-	public FilterDefinition getFilterDefinition(String name) {
-		return (FilterDefinition) filterDefinitions.get(name);
-	}
+	/**
+	 * Add metadata pertaining to an auxilary database object to this repository.
+	 *
+	 * @param auxiliaryDatabaseObject The metadata.
+	 */
+	public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject);
 
-	public Map getFetchProfiles() {
-		return fetchProfiles;
-	}
+	/**
+	 * Get the logical table name mapped for the given physical table.
+	 *
+	 * @param table The table for which to determine the logical name.
+	 * @return The logical name.
+	 * @throws MappingException Indicates that no logical name was bound for the given physical table.
+	 */
+	public String getLogicalTableName(Table table) throws MappingException;
 
-	public FetchProfile findOrCreateFetchProfile(String name) {
-		FetchProfile profile = ( FetchProfile ) fetchProfiles.get( name );
-		if ( profile == null ) {
-			profile = new FetchProfile( name );
-			fetchProfiles.put( name, profile );
-		}
-		return profile;
-	}
+	/**
+	 * Adds a table binding to this repository.
+	 *
+	 * @param schema The schema in which the table belongs (may be null).
+	 * @param catalog The catalog in which the table belongs (may be null).
+	 * @param logicalName The logical table name.
+	 * @param physicalName The physical table name.
+	 * @param denormalizedSuperTable ???
+	 * @throws DuplicateMappingException Indicates physical table was already bound to another logical name.
+	 */
+	public void addTableBinding(
+			String schema,
+			String catalog,
+			String logicalName,
+			String physicalName,
+			Table denormalizedSuperTable) throws DuplicateMappingException;
 
-	public boolean isDefaultLazy() {
-		return defaultLazy;
-	}
-	public void setDefaultLazy(boolean defaultLazy) {
-		this.defaultLazy = defaultLazy;
-	}
+	/**
+	 * Binds the given 'physicalColumn' to the give 'logicalName' within the given 'table'.
+	 *
+	 * @param logicalName The logical column name binding.
+	 * @param physicalColumn The physical column metadata.
+	 * @param table The table metadata.
+	 * @throws DuplicateMappingException Indicates a duplicate binding for either the physical column name
+	 * or the logical column name.
+	 */
+	public void addColumnBinding(String logicalName, Column physicalColumn, Table table) throws DuplicateMappingException;
 
-    public void addToExtendsQueue(ExtendsQueueEntry entry) {
-	    extendsQueue.put( entry, null );
-    }
+	/**
+	 * Find the physical column name for the given logical column name within the given table.
+	 *
+	 * @param logicalName The logical name binding.
+	 * @param table The table metatdata.
+	 * @return The physical column name.
+	 * @throws MappingException Indicates that no such binding was found.
+	 */
+	public String getPhysicalColumnName(String logicalName, Table table) throws MappingException;
 
-	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;
-	}
+	/**
+	 * Find the logical column name against whcih the given physical column name was bound within the given table.
+	 *
+	 * @param physicalName The physical column name
+	 * @param table The table metadata.
+	 * @return The logical column name.
+	 * @throws MappingException Indicates that no such binding was found.
+	 */
+	public String getLogicalColumnName(String physicalName, Table table) throws MappingException;
 
-	public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
-		auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
-	}
+	/**
+	 * Adds a second-pass to the end of the current queue.
+	 *
+	 * @param sp The second pass to add.
+	 */
+	public void addSecondPass(SecondPass sp);
 
-	public void addTableBinding(
-			String schema, String catalog, String logicalName, String physicalName, Table denormalizedSuperTable
-	) {
-		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 MappingException("Same physical table name reference several logical table names: "
-					+ physicalName + " => " + "'" + oldDescriptor.logicalName + "' and '" + logicalName + "'");
-		}
-	}
+	/**
+	 * Adds a second pass.
+	 * @param sp The second pass to add.
+	 * @param onTopOfTheQueue True to add to the beginning of the queue; false to add to the end.
+	 */
+	public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue);
 
-	public void addColumnBinding(String logicalName, Column finalColumn, Table table) {
-		ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(table);
-		if (binding == null) {
-			binding = new ColumnNames();
-			columnNameBindingPerTable.put(table, binding);
-		}
-		String oldFinalName = (String) binding.logicalToPhysical.put(
-				logicalName.toLowerCase(),
-				finalColumn.getQuotedName()
-		);
-		if ( oldFinalName != null &&
-				! ( finalColumn.isQuoted() ?
-						oldFinalName.equals( finalColumn.getQuotedName() ) :
-						oldFinalName.equalsIgnoreCase( finalColumn.getQuotedName() ) ) ) {
-			//TODO possibly relax that
-			throw new MappingException("Same logical column name referenced by different physical ones: "
-					+ table.getName() + "." + logicalName + " => '" + oldFinalName + "' and '" + finalColumn.getQuotedName() + "'" );
-		}
-		String oldLogicalName = (String) binding.physicalToLogical.put(
-				finalColumn.getQuotedName(),
-				logicalName
-		);
-		if ( oldLogicalName != null && ! oldLogicalName.equals( logicalName ) ) {
-			//TODO possibly relax that
-			throw new MappingException("Same physical column represented by different logical column names: "
-					+ table.getName() + "." + finalColumn.getQuotedName() + " => '" + oldLogicalName + "' and '" + logicalName + "'");
-		}
-	}
+	/**
+	 * Represents a property-ref mapping.
+	 * <p/>
+	 * TODO : currently needs to be exposed because Configuration needs access to it for second-pass processing
+	 */
+	public static final class PropertyReference implements Serializable {
+		public final String referencedClass;
+		public final String propertyName;
+		public final boolean unique;
 
-	private String getLogicalTableName(String schema, String catalog, String physicalName) {
-		String key = buildTableNameKey( schema, catalog, physicalName );
-		TableDescription descriptor = (TableDescription) tableNameBinding.get( key );
-		if (descriptor == null) {
-			throw new MappingException( "Unable to find physical table: " + physicalName);
+		public PropertyReference(String referencedClass, String propertyName, boolean unique) {
+			this.referencedClass = referencedClass;
+			this.propertyName = propertyName;
+			this.unique = unique;
 		}
-		return descriptor.logicalName;
 	}
 
-	public String getPhysicalColumnName(String logicalName, Table table) {
-		logicalName = logicalName.toLowerCase();
-		String finalName = null;
-		Table currentTable = table;
-		do {
-			ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable);
-			if (binding != null) {
-				finalName = (String) binding.logicalToPhysical.get( logicalName );
-			}
-			String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() );
-			TableDescription description = (TableDescription) tableNameBinding.get(key);
-			if (description != null) currentTable = description.denormalizedSupertable;
-		}
-		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;
-	}
+	/**
+	 * Adds a property reference binding to this repository.
+	 *
+	 * @param referencedClass The referenced entity name.
+	 * @param propertyName The referenced property name.
+	 */
+	public void addPropertyReference(String referencedClass, String propertyName);
 
-	public String getLogicalColumnName(String physicalName, Table table) {
-		String logical = null;
-		Table currentTable = table;
-		TableDescription description = null;
-		do {
-			ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable);
-			if (binding != null) {
-				logical = (String) binding.physicalToLogical.get( physicalName );
-			}
-			String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() );
-			description = (TableDescription) tableNameBinding.get(key);
-			if (description != null) currentTable = description.denormalizedSupertable;
-		}
-		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;
-	}
+	/**
+	 * Adds a property reference binding to this repository where said proeprty reference is marked as unique.
+	 *
+	 * @param referencedClass The referenced entity name.
+	 * @param propertyName The referenced property name.
+	 */
+	public void addUniquePropertyReference(String referencedClass, String propertyName);
 
-	public String getLogicalTableName(Table table) {
-		return getLogicalTableName( table.getQuotedSchema(), table.getCatalog(), table.getQuotedName() );
-	}
-
-	static public class ColumnNames implements Serializable {
-		//<String, String>
-		public Map logicalToPhysical = new HashMap();
-		//<String, String>
-		public Map physicalToLogical = new HashMap();
-		public ColumnNames() {
-		}
-	}
-
-	static public class TableDescription implements Serializable {
-		public TableDescription(String logicalName, Table denormalizedSupertable) {
-			this.logicalName = logicalName;
-			this.denormalizedSupertable = denormalizedSupertable;
-		}
-
-		public String logicalName;
-		public Table denormalizedSupertable;
-	}
+	/**
+	 * Adds an entry to the extends queue queue.
+	 *
+	 * @param entry The entry to add.
+	 */
+	public void addToExtendsQueue(ExtendsQueueEntry entry);
 }
\ No newline at end of file

Modified: core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java	2008-09-17 15:58:58 UTC (rev 15209)
+++ core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java	2008-09-17 16:44:23 UTC (rev 15210)
@@ -420,7 +420,7 @@
 
 		// this needs to happen after persisters are all ready to go...
 		this.fetchProfiles = new HashMap();
-		itr = cfg.getFetchProfiles().values().iterator();
+		itr = cfg.iterateFetchProfiles();
 		while ( itr.hasNext() ) {
 			final org.hibernate.mapping.FetchProfile mappingProfile =
 					( org.hibernate.mapping.FetchProfile ) itr.next();




More information about the hibernate-commits mailing list