public void AddOneToOneNotOwning(PropertyAuditingData propertyAuditingData, OneToOne value, ICompositeMapperBuilder mapper, string entityName)
        {
            var owningReferencePropertyName = referencePropertyName(value, entityName);

            var configuration = mainGenerator.EntitiesConfigurations[entityName];
            if (configuration == null)
            {
                throw new MappingException("An audited relation to a non-audited entity " + entityName + "!");
            }

            var ownedIdMapping = configuration.IdMappingData;

            if (ownedIdMapping == null)
            {
                throw new MappingException("An audited relation to a non-audited entity " + entityName + "!");
            }

            var lastPropertyPrefix = MappingTools.CreateToOneRelationPrefix(owningReferencePropertyName);
            var referencedEntityName = value.ReferencedEntityName;

            // Generating the id mapper for the relation
            var ownedIdMapper = ownedIdMapping.IdMapper.PrefixMappedProperties(lastPropertyPrefix);

            // Storing information about this relation
            mainGenerator.EntitiesConfigurations[entityName].AddToOneNotOwningRelation(
                    propertyAuditingData.Name, owningReferencePropertyName,
                    referencedEntityName, ownedIdMapper);

            // Adding mapper for the id
            var propertyData = propertyAuditingData.GetPropertyData();
            mapper.AddComposite(propertyData, new OneToOneNotOwningMapper(owningReferencePropertyName,
                    referencedEntityName, propertyData));
        }
		protected void InitOuterJoinFetchSetting(HbmOneToOne oneToOne, OneToOne model)
		{
			FetchMode fetchStyle;
			bool lazy = true;

			if (!oneToOne.fetchSpecified)
			{
				if (!oneToOne.outerjoinSpecified)
				{
					//NOTE SPECIAL CASE:
					// one-to-one constrained=falase cannot be proxied,
					// so default to join and non-lazy
					lazy = model.IsConstrained;
					fetchStyle = lazy ? FetchMode.Default : FetchMode.Join;
				}
				else
				{
					fetchStyle = GetFetchStyle(oneToOne.outerjoin);
				}
			}
			else
			{
				fetchStyle = GetFetchStyle(oneToOne.fetch);
			}

			model.FetchMode = fetchStyle;
			model.IsLazy = lazy;
		}
		protected void BindOneToOne(HbmOneToOne oneToOneMapping, OneToOne model)
		{
			model.IsConstrained = oneToOneMapping.constrained;

			model.ForeignKeyType = oneToOneMapping.constrained
			                       	? ForeignKeyDirection.ForeignKeyFromParent
			                       	: ForeignKeyDirection.ForeignKeyToParent;

			InitOuterJoinFetchSetting(oneToOneMapping, model);
			InitLaziness(oneToOneMapping.Lazy, model, true);
			BindForeignKey(oneToOneMapping.foreignkey, model);

			model.ReferencedPropertyName = oneToOneMapping.propertyref;

			model.ReferencedEntityName = GetEntityName(oneToOneMapping, mappings);
			model.PropertyName = oneToOneMapping.Name;
		}
Example #4
0
		public void Bind(IEnumerable<IEntityPropertyMapping> properties, Table table, IDictionary<string, MetaAttribute> inheritedMetas, Action<Property> modifier, Action<Property> addToModelAction)
		{
			if (table == null)
			{
				throw new ArgumentNullException("table");
			}
			if (modifier == null)
			{
				throw new ArgumentNullException("modifier");
			}
			if (addToModelAction == null)
			{
				throw new ArgumentNullException("addToModelAction");
			}

			foreach (var entityPropertyMapping in properties)
			{
				Property property = null;

				string propertyName = entityPropertyMapping.Name;

				ICollectionPropertiesMapping collectionMapping;
				HbmManyToOne manyToOneMapping;
				HbmAny anyMapping;
				HbmOneToOne oneToOneMapping;
				HbmProperty propertyMapping;
				HbmComponent componentMapping;
				HbmDynamicComponent dynamicComponentMapping;
				HbmNestedCompositeElement nestedCompositeElementMapping;
				HbmKeyProperty keyPropertyMapping;
				HbmKeyManyToOne keyManyToOneMapping;

				if ((propertyMapping = entityPropertyMapping as HbmProperty) != null)
				{
					var value = new SimpleValue(table);
					new ValuePropertyBinder(value, Mappings).BindSimpleValue(propertyMapping, propertyName, true);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
					BindValueProperty(propertyMapping, property);
				}
				else if ((collectionMapping = entityPropertyMapping as ICollectionPropertiesMapping) != null)
				{
					var collectionBinder = new CollectionBinder(Mappings, dialect);
					string propertyPath = propertyName == null ? null : StringHelper.Qualify(propertyBasePath, propertyName);

					Mapping.Collection collection = collectionBinder.Create(collectionMapping, entityName, propertyPath, persistentClass,
																												mappedClass, inheritedMetas);

					mappings.AddCollection(collection);

					property = CreateProperty(collectionMapping, className, collection, inheritedMetas);
					BindCollectionProperty(collectionMapping, property);
				}
				else if ((manyToOneMapping = entityPropertyMapping as HbmManyToOne) != null)
				{
					var value = new ManyToOne(table);
					BindManyToOne(manyToOneMapping, value, propertyName, true);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
					property.UnwrapProxy = manyToOneMapping.Lazy == HbmLaziness.NoProxy;
					BindManyToOneProperty(manyToOneMapping, property);
				}
				else if ((componentMapping = entityPropertyMapping as HbmComponent) != null)
				{
					string subpath = propertyName == null ? null : StringHelper.Qualify(propertyBasePath, propertyName);
					var value = CreateNewComponent();
					// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
					System.Type reflectedClass = mappedClass == null ? null : GetPropertyType(componentMapping.Class, mappedClass, propertyName, componentMapping.Access);
					BindComponent(componentMapping, value, reflectedClass, entityName, subpath, componetDefaultNullable, inheritedMetas);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
					BindComponentProperty(componentMapping, property);
				}
				else if ((oneToOneMapping = entityPropertyMapping as HbmOneToOne) != null)
				{
					var value = new OneToOne(table, persistentClass);
					BindOneToOne(oneToOneMapping, value);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
					BindOneToOneProperty(oneToOneMapping, property);
				}
				else if ((dynamicComponentMapping = entityPropertyMapping as HbmDynamicComponent) != null)
				{
					string subpath = propertyName == null ? null : StringHelper.Qualify(propertyBasePath, propertyName);
					var value = CreateNewComponent();
					// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
					System.Type reflectedClass = mappedClass == null ? null : GetPropertyType(dynamicComponentMapping.Class, mappedClass, propertyName, dynamicComponentMapping.Access);
					BindComponent(dynamicComponentMapping, value, reflectedClass, entityName, subpath, componetDefaultNullable, inheritedMetas);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
					BindComponentProperty(dynamicComponentMapping, property);
				}
				else if ((anyMapping = entityPropertyMapping as HbmAny) != null)
				{
					var value = new Any(table);
					BindAny(anyMapping, value, true);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
					BindAnyProperty(anyMapping, property);
				}
				else if ((nestedCompositeElementMapping = entityPropertyMapping as HbmNestedCompositeElement) != null)
				{
					if (component == null)
					{
						throw new AssertionFailure("Nested Composite Element without a owner component.");
					}
					string subpath = propertyName == null ? null : StringHelper.Qualify(propertyBasePath, propertyName);
					var value = CreateNewComponent();
					// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
					System.Type reflectedClass = mappedClass == null ? null : GetPropertyType(nestedCompositeElementMapping.Class, mappedClass, propertyName, nestedCompositeElementMapping.access);
					BindComponent(nestedCompositeElementMapping, value, reflectedClass, entityName, subpath, componetDefaultNullable, inheritedMetas);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
				}
				else if ((keyPropertyMapping = entityPropertyMapping as HbmKeyProperty) != null)
				{
					var value = new SimpleValue(table);
					new ValuePropertyBinder(value, Mappings).BindSimpleValue(keyPropertyMapping, propertyName, componetDefaultNullable);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
				}
				else if ((keyManyToOneMapping = entityPropertyMapping as HbmKeyManyToOne) != null)
				{
					var value = new ManyToOne(table);
					BindKeyManyToOne(keyManyToOneMapping, value, propertyName, componetDefaultNullable);
					property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas);
				}

				if (property != null)
				{
					modifier(property);
					property.LogMapped(log);
					addToModelAction(property);
				}
			}			
		}
		public static void BindComponent( XmlNode node, Component model, System.Type reflectedClass, string className, string path, bool isNullable, Mappings mappings )
		{
			XmlAttribute classNode = node.Attributes[ "class" ];

			if( "dynamic-component".Equals( node.Name ) )
			{
				model.IsEmbedded = false;
				model.IsDynamic = true;
			}
			else if( classNode != null )
			{
				model.ComponentClass = ClassForNameChecked(
					classNode.Value, mappings,
					"component class not found: {0}" );
				model.IsEmbedded = false;
			}
			else if( reflectedClass != null )
			{
				model.ComponentClass = reflectedClass;
				model.IsEmbedded = false;
			}
			else
			{
				// an "embedded" component (ids only)
				model.ComponentClass = model.Owner.MappedClass;
				model.IsEmbedded = true;
			}

			foreach( XmlNode subnode in node.ChildNodes )
			{
				//I am only concerned with elements that are from the nhibernate namespace
				if( subnode.NamespaceURI != Configuration.MappingSchemaXMLNS )
				{
					continue;
				}

				string name = subnode.LocalName; //.Name;
				string propertyName = GetPropertyName( subnode );
				string subpath = propertyName == null ? null : StringHelper.Qualify( path, propertyName );

				CollectionType collectType = CollectionType.CollectionTypeFromString( name );
				IValue value = null;
				if( collectType != null )
				{
					Mapping.Collection collection = collectType.Create( subnode, className, subpath, model.Owner, mappings );
					mappings.AddCollection( collection );
					value = collection;
				}
				else if( "many-to-one".Equals( name ) || "key-many-to-one".Equals( name ) )
				{
					value = new ManyToOne( model.Table );
					BindManyToOne( subnode, ( ManyToOne ) value, subpath, isNullable, mappings );
				}
				else if( "one-to-one".Equals( name ) )
				{
					value = new OneToOne( model.Table, model.Owner.Identifier );
					BindOneToOne( subnode, ( OneToOne ) value, isNullable, mappings );
				}
				else if( "any".Equals( name ) )
				{
					value = new Any( model.Table );
					BindAny( subnode, ( Any ) value, isNullable, mappings );
				}
				else if( "property".Equals( name ) || "key-property".Equals( name ) )
				{
					value = new SimpleValue( model.Table );
					BindSimpleValue( subnode, ( SimpleValue ) value, isNullable, subpath, mappings );
				}
				else if( "component".Equals( name ) || "dynamic-component".Equals( name ) || "nested-composite-element".Equals( name ) )
				{
					System.Type subreflectedClass = model.ComponentClass == null ?
						null :
						GetPropertyType( subnode, mappings, model.ComponentClass, propertyName );
					value = ( model.Owner != null ) ?
						new Component( model.Owner ) : // a class component
						new Component( model.Table ); // a composite element
					BindComponent( subnode, ( Component ) value, subreflectedClass, className, subpath, isNullable, mappings );
				}
				else if( "parent".Equals( name ) )
				{
					model.ParentProperty = propertyName;
				}

				if( value != null )
				{
					model.AddProperty( CreateProperty( value, propertyName, model.ComponentClass, subnode, mappings ) );
				}
			}

			int span = model.PropertySpan;
			string[ ] names = new string[span];
			IType[ ] types = new IType[span];
			Cascades.CascadeStyle[ ] cascade = new Cascades.CascadeStyle[span];
			OuterJoinFetchStrategy[ ] joinedFetch = new OuterJoinFetchStrategy[span];

			int i = 0;
			foreach( Mapping.Property prop in model.PropertyCollection )
			{
				if( prop.IsFormula )
				{
					throw new MappingException( "properties of components may not be formulas: " + prop.Name );
				}
				if( !prop.IsInsertable || !prop.IsUpdateable )
				{
					throw new MappingException( "insert=\"false\", update=\"false\" not supported for properties of components: " + prop.Name );
				}
				names[ i ] = prop.Name;
				types[ i ] = prop.Type;
				cascade[ i ] = prop.CascadeStyle;
				joinedFetch[ i ] = prop.Value.OuterJoinFetchSetting;
				i++;
			}

			IType componentType;
			if( model.IsDynamic )
			{
				componentType = new DynamicComponentType( names, types, joinedFetch, cascade );
			}
			else
			{
				IGetter[ ] getters = new IGetter[span];
				ISetter[ ] setters = new ISetter[span];
				bool foundCustomAccessor = false;
				i = 0;
				foreach( Mapping.Property prop in model.PropertyCollection )
				{
					setters[ i ] = prop.GetSetter( model.ComponentClass );
					getters[ i ] = prop.GetGetter( model.ComponentClass );
					if( !prop.IsBasicPropertyAccessor )
					{
						foundCustomAccessor = true;
					}
					i++;
				}

				componentType = new ComponentType(
					model.ComponentClass,
					names,
					getters,
					setters,
					foundCustomAccessor,
					types,
					joinedFetch,
					cascade,
					model.ParentProperty );
			}
			model.Type = componentType;
		}
		public static void BindOneToOne( XmlNode node, OneToOne model, bool isNullable, Mappings mappings )
		{
			//BindColumns( node, model, isNullable, false, null, mappings );
			InitOuterJoinFetchSetting( node, model );

			XmlAttribute constrNode = node.Attributes[ "constrained" ];
			bool constrained = constrNode != null && constrNode.Value.Equals( "true" );
			model.IsConstrained = constrained;

			model.ForeignKeyType = ( constrained ? ForeignKeyType.ForeignKeyFromParent : ForeignKeyType.ForeignKeyToParent );

			XmlAttribute fkNode = node.Attributes[ "foreign-key" ];
			if( fkNode != null )
			{
				model.ForeignKeyName = fkNode.Value;
			}

			XmlAttribute ukName = node.Attributes[ "property-ref" ];
			if( ukName != null )
			{
				model.ReferencedPropertyName = ukName.Value;
			}

			XmlAttribute classNode = node.Attributes[ "class" ];
			if( classNode != null )
			{
				model.Type = TypeFactory.OneToOne(
					ClassForNameChecked( classNode.Value, mappings, "could not find class: {0}" ),
					model.ForeignKeyType, model.ReferencedPropertyName );
			}
		}
		protected static void PropertiesFromXML( XmlNode node, PersistentClass model, Mappings mappings )
		{
			Table table = model.Table;

			foreach( XmlNode subnode in node.ChildNodes )
			{
				//I am only concerned with elements that are from the nhibernate namespace
				if( subnode.NamespaceURI != Configuration.MappingSchemaXMLNS )
				{
					continue;
				}

				string name = subnode.LocalName; //.Name;
				string propertyName = GetPropertyName( subnode );

				CollectionType collectType = CollectionType.CollectionTypeFromString( name );
				IValue value = null;
				if( collectType != null )
				{
					Mapping.Collection collection = collectType.Create( subnode, model.Name, propertyName, model, mappings );
					mappings.AddCollection( collection );
					value = collection;
				}
				else if( "many-to-one".Equals( name ) )
				{
					value = new ManyToOne( table );
					BindManyToOne( subnode, ( ManyToOne ) value, propertyName, true, mappings );
				}
				else if( "any".Equals( name ) )
				{
					value = new Any( table );
					BindAny( subnode, ( Any ) value, true, mappings );
				}
				else if( "one-to-one".Equals( name ) )
				{
					value = new OneToOne( table, model.Identifier );
					BindOneToOne( subnode, ( OneToOne ) value, true, mappings );
				}
				else if( "property".Equals( name ) )
				{
					value = new SimpleValue( table );
					BindSimpleValue( subnode, ( SimpleValue ) value, true, propertyName, mappings );
				}
				else if( "component".Equals( name ) || "dynamic-component".Equals( name ) )
				{
					// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
					System.Type reflectedClass = GetPropertyType( subnode, mappings, model.MappedClass, propertyName );
					value = new Component( model );
					BindComponent( subnode, ( Component ) value, reflectedClass, model.Name, propertyName, true, mappings );
				}
				else if( "subclass".Equals( name ) )
				{
					HandleSubclass( model, mappings, subnode );
				}
				else if( "joined-subclass".Equals( name ) )
				{
					HandleJoinedSubclass( model, mappings, subnode );
				}
				if( value != null )
				{
					model.AddNewProperty( CreateProperty( value, propertyName, model.MappedClass, subnode, mappings ) );
				}
			}
		}
        private string referencePropertyName(OneToOne value, string entityName)
        {
            var owningReferencePropertyName = value.ReferencedPropertyName;

            if (owningReferencePropertyName == null) //onetoone pk
            {
                foreach (var refProperty in mainGenerator.Cfg.GetClassMapping(value.ReferencedEntityName).PropertyIterator)
                {
                    if (refProperty.Value is OneToOne && refProperty.Type.Name.Equals(entityName))
                    {
                        owningReferencePropertyName = refProperty.Name;
                        break;
                    }
                }
            }
            if(owningReferencePropertyName==null)
                throw new AuditException("The onetoone mapping on entity " + entityName + ", property " + value.PropertyName + " is not supported!");
            return owningReferencePropertyName;
        }
        protected void PropertiesFromXML(XmlNode node, PersistentClass model)
        {
            Table table = model.Table;

            foreach (XmlNode subnode in node.ChildNodes)
            {
                //I am only concerned with elements that are from the nhibernate namespace
                if (subnode.NamespaceURI != Configuration.MappingSchemaXMLNS)
                    continue;

                string name = subnode.LocalName; //.Name;
                string propertyName = GetPropertyName(subnode);

                IValue value = null;
                CollectionBinder collectionBinder = new CollectionBinder(this);
                if (collectionBinder.CanCreate(name))
                {
                    Mapping.Collection collection = collectionBinder.Create(name, subnode, model.EntityName,
                        propertyName, model, model.MappedClass);

                    mappings.AddCollection(collection);
                    value = collection;
                }
                else if ("many-to-one".Equals(name))
                {
                    value = new ManyToOne(table);
                    BindManyToOne(subnode, (ManyToOne) value, propertyName, true);
                }
                else if ("any".Equals(name))
                {
                    value = new Any(table);
                    BindAny(subnode, (Any) value, true);
                }
                else if ("one-to-one".Equals(name))
                {
                    value = new OneToOne(table, model);
                    BindOneToOne(subnode, (OneToOne) value);
                }
                else if ("property".Equals(name))
                {
                    value = new SimpleValue(table);
                    BindSimpleValue(subnode, (SimpleValue) value, true, propertyName);
                }
                else if ("component".Equals(name) || "dynamic-component".Equals(name))
                {
                    // NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
                    System.Type reflectedClass = GetPropertyType(subnode, model.MappedClass, propertyName);
                    value = new Component(model);
                    BindComponent(subnode, (Component) value, reflectedClass, model.EntityName, propertyName, true);
                }
                else if ("join".Equals(name))
                {
                    Join join = new Join();
                    join.PersistentClass = model;
                    BindJoin(subnode, join);
                    model.AddJoin(join);
                }
                else if ("subclass".Equals(name))
                    new SubclassBinder(this).HandleSubclass(model, subnode);

                else if ("joined-subclass".Equals(name))
                    new JoinedSubclassBinder(this).HandleJoinedSubclass(model, subnode);

                else if ("union-subclass".Equals(name))
                    new UnionSubclassBinder(this).HandleUnionSubclass(model, subnode);

                else if ("filter".Equals(name))
                    ParseFilter(subnode, model);

                if (value != null)
                    model.AddProperty(CreateProperty(value, propertyName, model.MappedClass, subnode));
            }
        }
        protected void BindComponent(XmlNode node, Component model, System.Type reflectedClass,
			string className, string path, bool isNullable)
        {
            XmlAttribute classNode = node.Attributes["class"];

            if ("dynamic-component".Equals(node.Name))
            {
                model.IsEmbedded = false;
                model.IsDynamic = true;
            }
            else if (classNode != null)
            {
                model.ComponentClass = ClassForNameChecked(
                    classNode.Value, mappings,
                    "component class not found: {0}");
                model.ComponentClassName = FullClassName(classNode.Value, mappings);
                model.IsEmbedded = false;
            }
            else if (reflectedClass != null)
            {
                model.ComponentClass = reflectedClass;
                model.IsEmbedded = false;
            }
            else
            {
                // an "embedded" component (ids only)
                model.ComponentClass = model.Owner.MappedClass;
                model.IsEmbedded = true;
            }

            foreach (XmlNode subnode in node.ChildNodes)
            {
                //I am only concerned with elements that are from the nhibernate namespace
                if (subnode.NamespaceURI != Configuration.MappingSchemaXMLNS)
                    continue;

                string name = subnode.LocalName; //.Name;
                string propertyName = GetPropertyName(subnode);
                string subpath = propertyName == null ? null : StringHelper.Qualify(path, propertyName);

                IValue value = null;

                CollectionBinder binder = new CollectionBinder(this);

                if (binder.CanCreate(name))
                {
                    Mapping.Collection collection = binder.Create(name, subnode, className,
                        subpath, model.Owner, model.ComponentClass);

                    mappings.AddCollection(collection);
                    value = collection;
                }
                else if ("many-to-one".Equals(name) || "key-many-to-one".Equals(name))
                {
                    value = new ManyToOne(model.Table);
                    BindManyToOne(subnode, (ManyToOne) value, subpath, isNullable);
                }
                else if ("one-to-one".Equals(name))
                {
                    value = new OneToOne(model.Table, model.Owner);
                    BindOneToOne(subnode, (OneToOne) value);
                }
                else if ("any".Equals(name))
                {
                    value = new Any(model.Table);
                    BindAny(subnode, (Any) value, isNullable);
                }
                else if ("property".Equals(name) || "key-property".Equals(name))
                {
                    value = new SimpleValue(model.Table);
                    BindSimpleValue(subnode, (SimpleValue) value, isNullable, subpath);
                }
                else if ("component".Equals(name) || "dynamic-component".Equals(name) || "nested-composite-element".Equals(name))
                {
                    System.Type subreflectedClass = model.ComponentClass == null
                        ?
                            null
                        :
                            GetPropertyType(subnode, model.ComponentClass, propertyName);
                    value = new Component(model);
                    BindComponent(subnode, (Component) value, subreflectedClass, className, subpath, isNullable);
                }
                else if ("parent".Equals(name))
                    model.ParentProperty = propertyName;

                if (value != null)
                    model.AddProperty(CreateProperty(value, propertyName, model.ComponentClass, subnode));
            }
        }
        private void BindOneToOne(XmlNode node, OneToOne model)
        {
            //BindColumns( node, model, isNullable, false, null, mappings );

            XmlAttribute constrNode = node.Attributes["constrained"];
            bool constrained = constrNode != null && constrNode.Value.Equals("true");
            model.IsConstrained = constrained;

            model.ForeignKeyType = (constrained
                ? ForeignKeyDirection.ForeignKeyFromParent
                : ForeignKeyDirection.ForeignKeyToParent);

            InitOuterJoinFetchSetting(node, model);
            InitLaziness(node, model, true);

            XmlAttribute fkNode = node.Attributes["foreign-key"];
            if (fkNode != null)
                model.ForeignKeyName = fkNode.Value;

            XmlAttribute ukName = node.Attributes["property-ref"];
            if (ukName != null)
                model.ReferencedPropertyName = ukName.Value;

            model.ReferencedEntityName = GetEntityName(node, mappings);
            model.PropertyName = node.Attributes["name"].Value;
        }
Example #12
0
		protected void PropertiesFromXML(XmlNode node, PersistentClass model, IDictionary<string, MetaAttribute> inheritedMetas, UniqueKey uniqueKey, bool mutable, bool nullable, bool naturalId)
		{
			string entityName = model.EntityName;

			Table table = model.Table;

			foreach (XmlNode subnode in node.ChildNodes)
			{
				//I am only concerned with elements that are from the nhibernate namespace
				if (subnode.NamespaceURI != Configuration.MappingSchemaXMLNS)
					continue;

				string name = subnode.LocalName; //.Name;
				string propertyName = GetPropertyName(subnode);

				IValue value = null;
				CollectionBinder collectionBinder = new CollectionBinder(this);
				if (collectionBinder.CanCreate(name))
				{
					Mapping.Collection collection = collectionBinder.Create(name, subnode, entityName, propertyName, model,
					                                                        model.MappedClass, inheritedMetas);

					mappings.AddCollection(collection);
					value = collection;
				}
				else if ("many-to-one".Equals(name))
				{
					value = new ManyToOne(table);
					BindManyToOne(subnode, (ManyToOne) value, propertyName, true);
				}
				else if ("any".Equals(name))
				{
					value = new Any(table);
					BindAny(subnode, (Any) value, true);
				}
				else if ("one-to-one".Equals(name))
				{
					value = new OneToOne(table, model);
					BindOneToOne(subnode, (OneToOne) value);
				}
				else if ("property".Equals(name))
				{
					value = new SimpleValue(table);
					BindSimpleValue(subnode, (SimpleValue) value, true, propertyName);
				}
				else if ("component".Equals(name) || "dynamic-component".Equals(name))
				{
					string subpath = StringHelper.Qualify(entityName, propertyName);
					// NH: Modified from H2.1 to allow specifying the type explicitly using class attribute
					System.Type reflectedClass = GetPropertyType(subnode, model.MappedClass, propertyName);
					value = new Component(model);
					BindComponent(subnode, (Component) value, reflectedClass, entityName, propertyName, subpath, true, inheritedMetas);
				}
				else if ("join".Equals(name))
				{
					Join join = new Join();
					join.PersistentClass = model;
					BindJoin(subnode, join, inheritedMetas);
					model.AddJoin(join);
				}
				else if ("subclass".Equals(name))
					new SubclassBinder(this).HandleSubclass(model, subnode, inheritedMetas);

				else if ("joined-subclass".Equals(name))
					new JoinedSubclassBinder(this).HandleJoinedSubclass(model, subnode, inheritedMetas);

				else if ("union-subclass".Equals(name))
					new UnionSubclassBinder(this).HandleUnionSubclass(model, subnode, inheritedMetas);

				else if ("filter".Equals(name))
					ParseFilter(subnode, model);
				else if ("natural-id".Equals(name))
				{
					UniqueKey uk = new UniqueKey();
					uk.Name = "_UniqueKey";
					uk.Table = table;
					//by default, natural-ids are "immutable" (constant)

					bool mutableId = false;
					if (subnode.Attributes["mutable"] != null)
					{
						mutableId = "true".Equals(subnode.Attributes["mutable"]);						
					}

					PropertiesFromXML(subnode, model, inheritedMetas, uk, mutableId, false, true);
					table.AddUniqueKey(uk);
				}

				if (value != null)
				{
					Property property = CreateProperty(value, propertyName, model.ClassName, subnode, inheritedMetas);
					if (!mutable)
						property.IsUpdateable = false;
					if (naturalId)
						property.IsNaturalIdentifier = true;
					model.AddProperty(property);
					if (uniqueKey != null)
						uniqueKey.AddColumns(new SafetyEnumerable<Column>(property.ColumnIterator));
				}
			}
		}