/// <summary>
		/// Called for Maps
		/// </summary>
		private void BindMapSecondPass(HbmMap mapMapping, Map model,
			IDictionary<string, PersistentClass> persistentClasses, IDictionary<string, MetaAttribute> inheritedMetas)
		{
			BindCollectionSecondPass(mapMapping, model, persistentClasses, inheritedMetas);

			HbmIndex indexMapping;
			HbmMapKey mapKeyMapping;

			HbmIndexManyToMany indexManyToManyMapping;
			HbmMapKeyManyToMany mapKeyManyToManyMapping;

			HbmCompositeIndex compositeIndexMapping;
			HbmCompositeMapKey compositeMapKeyMapping;

			HbmIndexManyToAny indexManyToAnyMapping;

			if ((indexMapping = mapMapping.Item as HbmIndex) != null)
			{
				var value = new SimpleValue(model.CollectionTable);
				new ValuePropertyBinder(value, Mappings).BindSimpleValue(indexMapping, IndexedCollection.DefaultIndexColumnName,
																		 model.IsOneToMany);
				model.Index = value;
				if (string.IsNullOrEmpty(model.Index.TypeName))
					throw new MappingException("map index element must specify a type: " + model.Role);
			}
			else if ((mapKeyMapping = mapMapping.Item as HbmMapKey) != null)
			{
				var value = new SimpleValue(model.CollectionTable);
				new ValuePropertyBinder(value, Mappings).BindSimpleValue(mapKeyMapping, IndexedCollection.DefaultIndexColumnName,
																																 model.IsOneToMany);
				model.Index = value;
				if (string.IsNullOrEmpty(model.Index.TypeName))
					throw new MappingException("map index element must specify a type: " + model.Role);
			}
			else if ((indexManyToManyMapping = mapMapping.Item as HbmIndexManyToMany) != null)
			{
				var manyToOne = new ManyToOne(model.CollectionTable);
				BindIndexManyToMany(indexManyToManyMapping, manyToOne, IndexedCollection.DefaultIndexColumnName, model.IsOneToMany);
				model.Index = manyToOne;
			}
			else if ((mapKeyManyToManyMapping = mapMapping.Item as HbmMapKeyManyToMany) != null)
			{
				var manyToOne = new ManyToOne(model.CollectionTable);
				BindMapKeyManyToMany(mapKeyManyToManyMapping, manyToOne, IndexedCollection.DefaultIndexColumnName, model.IsOneToMany);
				model.Index = manyToOne;
			}
			else if ((compositeIndexMapping = mapMapping.Item as HbmCompositeIndex) != null)
			{
				var component = new Component(model);
				BindComponent(compositeIndexMapping, component, null, null, model.Role + ".index", model.IsOneToMany, inheritedMetas);
				model.Index = component;
			}
			else if ((compositeMapKeyMapping = mapMapping.Item as HbmCompositeMapKey) != null)
			{
				var component = new Component(model);
				BindComponent(compositeMapKeyMapping, component, null, null, model.Role + ".index", model.IsOneToMany, inheritedMetas);
				model.Index = component;
			}
			else if ((indexManyToAnyMapping = mapMapping.Item as HbmIndexManyToAny) != null)
			{
				var any = new Any(model.CollectionTable);
				BindIndexManyToAny(indexManyToAnyMapping, any, model.IsOneToMany);
				model.Index = any;				
			}

			bool indexIsFormula = model.Index.ColumnIterator.Any(x=> x.IsFormula);
			if (NeedBackref(model) && !indexIsFormula)
			{
				string entityName = ((OneToMany)model.Element).ReferencedEntityName;
				PersistentClass referenced = mappings.GetClass(entityName);
				var ib = new IndexBackref();
				ib.Name = '_' + model.OwnerEntityName + "." + mapMapping.Name + "IndexBackref";
				ib.IsUpdateable = false;
				ib.IsSelectable = false;
				ib.CollectionRole = model.Role;
				ib.EntityName = model.Owner.EntityName;
				ib.Value = model.Index;
				referenced.AddProperty(ib);
			}
		}
		private void BindIndexManyToAny(HbmIndexManyToAny indexManyToAnyMapping, Any any, bool isNullable)
		{
			any.IdentifierTypeName = indexManyToAnyMapping.idtype;
			new TypeBinder(any, Mappings).Bind(indexManyToAnyMapping.idtype);
			BindAnyMeta(indexManyToAnyMapping, any);
			new ColumnsBinder(any, Mappings).Bind(indexManyToAnyMapping.Columns, isNullable,
																						() =>
																						new HbmColumn
																						{
																							name = mappings.NamingStrategy.PropertyToColumnName(indexManyToAnyMapping.column1)
																						});
		}
		public static void BindAny( XmlNode node, Any model, bool isNullable, Mappings mappings )
		{
			model.IdentifierType = GetTypeFromXML( node );

			XmlAttribute metaAttribute = node.Attributes[ "meta-type" ];
			if( metaAttribute != null )
			{
				IType metaType = TypeFactory.HeuristicType( metaAttribute.Value );
				if( metaType == null )
				{
					throw new MappingException( "could not interpret meta-type" );
				}
				model.MetaType = metaType;

				Hashtable values = new Hashtable();
				foreach( XmlNode metaValue in node.SelectNodes( nsMetaValue, nsmgr ) )
				{
					try
					{
						object value = ((IDiscriminatorType) model.MetaType).FromString( metaValue.Attributes["value"].Value );
						System.Type clazz = ReflectHelper.ClassForName( FullClassName( metaValue.Attributes["class"].Value, mappings ) );
						values[ value ] = clazz;
					}
					catch( InvalidCastException )
					{
						throw new MappingException( "meta-type was not an IDiscriminatorType: " + metaType.Name );
					}
					catch( HibernateException he )
					{
						throw new MappingException( "could not interpret meta-value", he );
					}
					catch( TypeLoadException cnfe )
					{
						throw new MappingException( "meta-value class not found", cnfe );
					}
				}

				if( values.Count > 0 )
				{
					model.MetaType = new MetaType( values, model.MetaType );
				}
			}

			BindColumns( node, model, isNullable, false, null, mappings );
		}
		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;
		}
示例#5
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));
				}
			}
		}
		/// <remarks>
		/// Called for all collections
		/// </remarks>
		public static void BindCollectionSecondPass( XmlNode node, Mapping.Collection model, IDictionary persistentClasses, Mappings mappings )
		{
			if( model.IsOneToMany )
			{
				OneToMany oneToMany = ( OneToMany ) model.Element;
				System.Type assocClass = oneToMany.EntityType.AssociatedClass;
				PersistentClass persistentClass = ( PersistentClass ) persistentClasses[ assocClass ];
				if( persistentClass == null )
				{
					throw new MappingException( "Association references unmapped class: " + assocClass.Name );
				}
				oneToMany.AssociatedClass = persistentClass;
				model.CollectionTable = persistentClass.Table;

				if( log.IsInfoEnabled )
				{
					log.Info( "mapping collection: " + model.Role + " -> " + model.CollectionTable.Name );
				}
			}

			//CHECK
			XmlAttribute chNode = node.Attributes[ "check" ];
			if( chNode != null )
			{
				model.CollectionTable.AddCheckConstraint( chNode.Value );
			}

			//contained elements:
			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;

				if( "key".Equals( name ) || "generated-key".Equals( name ) )
				{
					SimpleValue key = new SimpleValue( model.CollectionTable );
					BindSimpleValue( subnode, key, model.IsOneToMany, Mapping.Collection.DefaultKeyColumnName, mappings );
					key.Type = model.Owner.Identifier.Type;
					if( key.Type.ReturnedClass.IsArray )
					{
						throw new MappingException( "illegal use of an array as an identifier (arrays don't reimplement Equals)" );
					}
					model.Key = key;
				}
				else if( "element".Equals( name ) )
				{
					SimpleValue elt = new SimpleValue( model.CollectionTable );
					model.Element = elt;
					BindSimpleValue( subnode, elt, true, Mapping.Collection.DefaultElementColumnName, mappings );
				}
				else if( "many-to-many".Equals( name ) )
				{
					ManyToOne element = new ManyToOne( model.CollectionTable );
					model.Element = element;
					BindManyToOne( subnode, element, Mapping.Collection.DefaultElementColumnName, false, mappings );
				}
				else if( "composite-element".Equals( name ) )
				{
					Component element = new Component( model.CollectionTable );
					model.Element = element;
					BindComponent( subnode, element, null, model.Role, "element", true, mappings );
				}
				else if( "many-to-any".Equals( name ) )
				{
					Any element = new Any( model.CollectionTable );
					model.Element = element;
					BindAny( subnode, element, true, mappings );
				}
				else if( "jcs-cache".Equals( name ) || "cache".Equals( name ) )
				{
					ICacheConcurrencyStrategy cache = CacheFactory.CreateCache( subnode, model.Role, model.Owner.IsMutable );
					mappings.AddCache( model.Role, cache );
					model.Cache = cache;
				}
			}

			// Code below is not present in H2.1, why was it added?
			if( !model.IsInverse )
			{
				if( !model.IsOneToMany ) // no foreign key for a one-to-many
				{
					model.Element.CreateForeignKey();
				}

				model.Key.CreateForeignKeyOfClass( model.Owner.MappedClass );
			}
		}
        private void BindJoin(XmlNode node, Join join)
        {
            PersistentClass persistentClass = join.PersistentClass;
            String path = persistentClass.EntityName;

            // TABLENAME

            XmlAttribute schemaNode = node.Attributes["schema"];
            string schema = schemaNode == null ? mappings.SchemaName : schemaNode.Value;
            XmlAttribute catalogNode = node.Attributes["catalog"];
            string catalog = catalogNode == null ? mappings.CatalogName : catalogNode.Value;

            Table table = mappings.AddTable(schema, catalog, GetClassTableName(persistentClass, node), null, false);
            join.Table = table;

            XmlAttribute fetchNode = node.Attributes["fetch"];
            if (fetchNode != null)
                join.IsSequentialSelect = "select".Equals(fetchNode.Value);

            XmlAttribute invNode = node.Attributes["inverse"];
            if (invNode != null)
                join.IsInverse = "true".Equals(invNode.Value);

            XmlAttribute nullNode = node.Attributes["optional"];
            if (nullNode != null)
                join.IsOptional = "true".Equals(nullNode.Value);

            log.InfoFormat("Mapping class join: {0} -> {1}", persistentClass.EntityName, join.Table.Name);

            // KEY
            XmlNode keyNode = node.SelectSingleNode(HbmConstants.nsKey, namespaceManager);
            SimpleValue key = new DependantValue(table, persistentClass.Identifier);
            join.Key = key;
            if (keyNode.Attributes["on-delete"] != null)
                key.IsCascadeDeleteEnabled = "cascade".Equals(keyNode.Attributes["on-delete"].Value);
            BindSimpleValue(keyNode, key, false, persistentClass.EntityName);

            join.CreatePrimaryKey(dialect);
            join.CreateForeignKey();

            // PROPERTIES
            //PropertiesFromXML(node, persistentClass, mappings);
            foreach (XmlNode subnode in node.ChildNodes)
            {
                string name = subnode.Name;
                XmlAttribute nameAttribute = subnode.Attributes["name"];
                string propertyName = nameAttribute == null ? null : nameAttribute.Value;

                IValue value = null;
                switch (name)
                {
                    case "many-to-one":
                        value = new ManyToOne(table);
                        BindManyToOne(subnode, (ManyToOne) value, propertyName, true);
                        break;
                    case "any":
                        value = new Any(table);
                        BindAny(subnode, (Any) value, true);
                        break;
                    case "property":
                        value = new SimpleValue(table);
                        BindSimpleValue(subnode, (SimpleValue) value, true, propertyName);
                        break;
                    case "component":
                    case "dynamic-component":
                        string subpath = StringHelper.Qualify(path, propertyName);
                        value = new Component(join);
                        BindComponent(
                            subnode,
                            (Component) value,
                            join.PersistentClass.MappedClass,
                            propertyName,
                            subpath,
                            true);
                        break;
                }

                if (value != null)
                {
                    Mapping.Property prop = CreateProperty(value, propertyName, persistentClass.MappedClass, subnode);
                    prop.IsOptional = join.IsOptional;
                    join.AddProperty(prop);
                }
            }

            // CUSTOM SQL
            HandleCustomSQL(node, join);
        }
		protected void BindAny(HbmAny node, Any model, bool isNullable)
		{
			model.IdentifierTypeName = node.idtype;
			new TypeBinder(model, Mappings).Bind(node.idtype);

			BindAnyMeta(node, model);

			new ColumnsBinder(model, Mappings).Bind(node.Columns, isNullable, null);
		}
        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));
            }
        }
示例#10
0
        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));
            }
        }
示例#11
0
        protected void BindAny(XmlNode node, Any model, bool isNullable)
        {
            IType idt = GetTypeFromXML(node);
            if (idt != null)
                model.IdentifierTypeName = idt.Name;

            XmlAttribute metaAttribute = node.Attributes["meta-type"];
            if (metaAttribute != null)
            {
                model.MetaType = metaAttribute.Value;
                XmlNodeList metaValues = node.SelectNodes(HbmConstants.nsMetaValue, namespaceManager);
                if (metaValues != null && metaValues.Count > 0)
                {
                    IDictionary<object, string> values = new Dictionary<object, string>();
                    IType metaType = TypeFactory.HeuristicType(model.MetaType);
                    foreach (XmlNode metaValue in metaValues)
                        try
                        {
                            object value = ((IDiscriminatorType) metaType).StringToObject(metaValue.Attributes["value"].Value);
                            string entityName = GetClassName(metaValue.Attributes["class"].Value, mappings);
                            values[value] = entityName;
                        }
                        catch (InvalidCastException)
                        {
                            throw new MappingException("meta-type was not an IDiscriminatorType: " + metaType.Name);
                        }
                        catch (HibernateException he)
                        {
                            throw new MappingException("could not interpret meta-value", he);
                        }
                        catch (TypeLoadException cnfe)
                        {
                            throw new MappingException("meta-value class not found", cnfe);
                        }
                    model.MetaValues = values.Count > 0 ? values : null;
                }
            }

            BindColumns(node, model, isNullable, false, null);
        }
示例#12
0
		/// <summary>
		/// Called for Maps
		/// </summary>
		private void BindMapSecondPass(HbmMap mapMapping, Map model,
			IDictionary<string, PersistentClass> persistentClasses, IDictionary<string, MetaAttribute> inheritedMetas)
		{
			BindCollectionSecondPass(mapMapping, model, persistentClasses, inheritedMetas);

			HbmIndex indexMapping;
			HbmMapKey mapKeyMapping;

			HbmIndexManyToMany indexManyToManyMapping;
			HbmMapKeyManyToMany mapKeyManyToManyMapping;

			HbmCompositeIndex compositeIndexMapping;
			HbmCompositeMapKey compositeMapKeyMapping;

			HbmIndexManyToAny indexManyToAnyMapping;

			if ((indexMapping = mapMapping.Item as HbmIndex) != null)
			{
				var value = new SimpleValue(model.CollectionTable);
				new ValuePropertyBinder(value, Mappings).BindSimpleValue(indexMapping, IndexedCollection.DefaultIndexColumnName,
				                                                         model.IsOneToMany);
				model.Index = value;
				if (string.IsNullOrEmpty(model.Index.TypeName))
					throw new MappingException("map index element must specify a type: " + model.Role);
			}
			else if ((mapKeyMapping = mapMapping.Item as HbmMapKey) != null)
			{
				var value = new SimpleValue(model.CollectionTable);
				new ValuePropertyBinder(value, Mappings).BindSimpleValue(mapKeyMapping, IndexedCollection.DefaultIndexColumnName,
																																 model.IsOneToMany);
				model.Index = value;
				if (string.IsNullOrEmpty(model.Index.TypeName))
					throw new MappingException("map index element must specify a type: " + model.Role);
			}
			else if ((indexManyToManyMapping = mapMapping.Item as HbmIndexManyToMany) != null)
			{
				var manyToOne = new ManyToOne(model.CollectionTable);
				BindIndexManyToMany(indexManyToManyMapping, manyToOne, IndexedCollection.DefaultIndexColumnName, model.IsOneToMany);
				model.Index = manyToOne;
			}
			else if ((mapKeyManyToManyMapping = mapMapping.Item as HbmMapKeyManyToMany) != null)
			{
				var manyToOne = new ManyToOne(model.CollectionTable);
				BindMapKeyManyToMany(mapKeyManyToManyMapping, manyToOne, IndexedCollection.DefaultIndexColumnName, model.IsOneToMany);
				model.Index = manyToOne;
			}
			else if ((compositeIndexMapping = mapMapping.Item as HbmCompositeIndex) != null)
			{
				var component = new Component(model);
				BindComponent(compositeIndexMapping, component, null, null, model.Role + ".index", model.IsOneToMany, inheritedMetas);
				model.Index = component;
			}
			else if ((compositeMapKeyMapping = mapMapping.Item as HbmCompositeMapKey) != null)
			{
				var component = new Component(model);
				BindComponent(compositeMapKeyMapping, component, null, null, model.Role + ".index", model.IsOneToMany, inheritedMetas);
				model.Index = component;
			}
			else if ((indexManyToAnyMapping = mapMapping.Item as HbmIndexManyToAny) != null)
			{
				var any = new Any(model.CollectionTable);
				BindIndexManyToAny(indexManyToAnyMapping, any, model.IsOneToMany);
				model.Index = any;				
			}
		}
示例#13
0
		/// <remarks>
		/// Called for all collections
		/// </remarks>
		private void BindCollectionSecondPass(XmlNode node, Mapping.Collection model,
			IDictionary<string, PersistentClass> persistentClasses)
		{
			if (model.IsOneToMany)
			{
				OneToMany oneToMany = (OneToMany)model.Element;
				string associatedEntityName = oneToMany.ReferencedEntityName;
				PersistentClass persistentClass;
				if (persistentClasses.TryGetValue(associatedEntityName, out persistentClass) == false)
					throw new MappingException("Association references unmapped class: " + associatedEntityName);
				oneToMany.AssociatedClass = persistentClass;
				model.CollectionTable = persistentClass.Table;

				if (log.IsInfoEnabled)
					log.Info("mapping collection: " + model.Role + " -> " + model.CollectionTable.Name);
			}

			//CHECK
			XmlAttribute chNode = node.Attributes["check"];
			if (chNode != null)
				model.CollectionTable.AddCheckConstraint(chNode.Value);

			//contained elements:
			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;

				if ("key".Equals(name) || "generated-key".Equals(name))
				{
					string propRef = model.ReferencedPropertyName;
					IKeyValue keyValue;
					if (propRef == null)
					{
						keyValue = model.Owner.Identifier;
					}
					else
					{
						keyValue = (IKeyValue)model.Owner.GetProperty(propRef).Value;
					}
					DependantValue key = new DependantValue(model.CollectionTable, keyValue);
					if (subnode.Attributes["on-delete"] != null)
						key.IsCascadeDeleteEnabled = "cascade".Equals(subnode.Attributes["on-delete"].Value);
					BindSimpleValue(subnode, key, model.IsOneToMany, Mapping.Collection.DefaultKeyColumnName);
					if (key.Type.ReturnedClass.IsArray)
						throw new MappingException("illegal use of an array as an identifier (arrays don't reimplement Equals)");
					model.Key = key;


					XmlAttribute notNull = subnode.Attributes["not-null"];
					key.SetNullable(notNull == null || IsFalse(notNull.Value));
					XmlAttribute updateable = subnode.Attributes["update"];
					key.SetUpdateable(updateable == null || IsTrue(updateable.Value));
				}
				else if ("element".Equals(name))
				{
					SimpleValue elt = new SimpleValue(model.CollectionTable);
					model.Element = elt;
					BindSimpleValue(subnode, elt, true, Mapping.Collection.DefaultElementColumnName);
				}
				else if ("many-to-many".Equals(name))
				{
					ManyToOne element = new ManyToOne(model.CollectionTable);
					model.Element = element;
					BindManyToOne(subnode, element, Mapping.Collection.DefaultElementColumnName, false);
					BindManyToManySubelements(model, subnode);
				}
				else if ("composite-element".Equals(name))
				{
					Component element = new Component(model);
					model.Element = element;
					BindComponent(subnode, element, null, model.Role, "element", true);
				}
				else if ("many-to-any".Equals(name))
				{
					Any element = new Any(model.CollectionTable);
					model.Element = element;
					BindAny(subnode, element, true);
				}
				else if ("jcs-cache".Equals(name) || "cache".Equals(name))
				{
					XmlAttribute usageNode = subnode.Attributes["usage"];
					model.CacheConcurrencyStrategy = (usageNode != null) ? usageNode.Value : null;
					XmlAttribute regionNode = subnode.Attributes["region"];
					model.CacheRegionName = (regionNode != null) ? regionNode.Value : null;
				}
			}
		}
		private void BindManyToAny(HbmManyToAny manyToAnyMapping, Mapping.Collection model)
		{
			var any = new Any(model.CollectionTable);
			model.Element = any;
			any.IdentifierTypeName = manyToAnyMapping.idtype;
			new TypeBinder(any, Mappings).Bind(manyToAnyMapping.idtype);
			BindAnyMeta(manyToAnyMapping, any);
			new ColumnsBinder(any, Mappings).Bind(manyToAnyMapping.Columns, true,
												  () =>
												  new HbmColumn
													{
														name = mappings.NamingStrategy.PropertyToColumnName(manyToAnyMapping.column1)
													});
		}
		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 ) );
				}
			}
		}
示例#16
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);
				}
			}			
		}
		/// <summary>
		/// Called for Maps
		/// </summary>
		/// <param name="node"></param>
		/// <param name="model"></param>
		/// <param name="classes"></param>
		/// <param name="mappings"></param>
		public static void BindMapSecondPass( XmlNode node, Map model, IDictionary classes, Mappings mappings )
		{
			BindCollectionSecondPass( node, model, classes, mappings );

			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;

				if( "index".Equals( name ) )
				{
					SimpleValue value = new SimpleValue( model.CollectionTable );
					BindSimpleValue( subnode, value, model.IsOneToMany, IndexedCollection.DefaultIndexColumnName, mappings );
					model.Index = value;
					if( model.Index.Type == null )
					{
						throw new MappingException( "map index element must specify a type: " + model.Role );
					}
				}
				else if( "index-many-to-many".Equals( name ) )
				{
					ManyToOne mto = new ManyToOne( model.CollectionTable );
					BindManyToOne( subnode, mto, IndexedCollection.DefaultIndexColumnName, model.IsOneToMany, mappings );
					model.Index = mto;
				}
				else if( "composite-index".Equals( name ) )
				{
					Component component = new Component( model.CollectionTable );
					BindComponent( subnode, component, null, model.Role, "index", model.IsOneToMany, mappings );
					model.Index = component;
				}
				else if( "index-many-to-any".Equals( name ) )
				{
					Any any = new Any( model.CollectionTable );
					BindAny( subnode, any, model.IsOneToMany, mappings );
					model.Index = any;
				}
			}
		}
		protected void BindAnyMeta(IAnyMapping anyMapping, Any model)
		{
			if(string.IsNullOrEmpty(anyMapping.MetaType))
			{
				return;
			}
				model.MetaType = anyMapping.MetaType;
			var metaValues = anyMapping.MetaValues;
			if (metaValues.Count == 0)
			{
				return;
			}
			IDictionary<object, string> values = new Dictionary<object, string>();
			IType metaType = TypeFactory.HeuristicType(model.MetaType);

			foreach (var metaValue in metaValues)
			{
				try
				{
					object value = ((IDiscriminatorType)metaType).StringToObject(metaValue.value);
					string entityName = GetClassName(metaValue.@class, mappings);
					values[value] = entityName;
				}
				catch (InvalidCastException)
				{
					throw new MappingException("meta-type was not an IDiscriminatorType: " + metaType.Name);
				}
				catch (HibernateException he)
				{
					throw new MappingException("could not interpret meta-value", he);
				}
				catch (TypeLoadException cnfe)
				{
					throw new MappingException("meta-value class not found", cnfe);
				}
			}
			model.MetaValues = values.Count > 0 ? values : null;
		}
示例#19
0
		private void BindJoin(XmlNode node, Join join, IDictionary<string, MetaAttribute> inheritedMetas)
		{
			PersistentClass persistentClass = join.PersistentClass;
			String path = persistentClass.EntityName;

			// TABLENAME

			XmlAttribute schemaNode = node.Attributes["schema"];
			string schema = schemaNode == null ? mappings.SchemaName : schemaNode.Value;
			XmlAttribute catalogNode = node.Attributes["catalog"];
			string catalog = catalogNode == null ? mappings.CatalogName : catalogNode.Value;

			XmlAttribute actionNode = node.Attributes["schema-action"];
			string action = actionNode == null ? "all" : actionNode.Value;

			Table table = mappings.AddTable(schema, catalog, GetClassTableName(persistentClass, node), null, false, action);
			join.Table = table;

			XmlAttribute fetchNode = node.Attributes["fetch"];
			if (fetchNode != null)
				join.IsSequentialSelect = "select".Equals(fetchNode.Value);

			XmlAttribute invNode = node.Attributes["inverse"];
			if (invNode != null)
				join.IsInverse = "true".Equals(invNode.Value);

			XmlAttribute nullNode = node.Attributes["optional"];
			if (nullNode != null)
				join.IsOptional = "true".Equals(nullNode.Value);

			log.InfoFormat("Mapping class join: {0} -> {1}", persistentClass.EntityName, join.Table.Name);

			// KEY
			XmlNode keyNode = node.SelectSingleNode(HbmConstants.nsKey, namespaceManager);
			SimpleValue key = new DependantValue(table, persistentClass.Identifier);
			join.Key = key;
			if (keyNode.Attributes["on-delete"] != null)
				key.IsCascadeDeleteEnabled = "cascade".Equals(keyNode.Attributes["on-delete"].Value);
			BindSimpleValue(keyNode, key, false, persistentClass.EntityName);

			join.CreatePrimaryKey(dialect);
			join.CreateForeignKey();

			// PROPERTIES
			//PropertiesFromXML(node, persistentClass, mappings);
			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.Name;
				XmlAttribute nameAttribute = subnode.Attributes["name"];
				string propertyName = nameAttribute == null ? null : nameAttribute.Value;
				IValue value = null;
				var collectionBinder = new CollectionBinder(this);
				if (collectionBinder.CanCreate(name))
				{
					Mapping.Collection collection = collectionBinder.Create(name, subnode, persistentClass.EntityName, propertyName,
					                                                        persistentClass, persistentClass.MappedClass,
					                                                        inheritedMetas);

					mappings.AddCollection(collection);
					value = collection;
				}
				else
				{
					switch (name)
					{
						case "many-to-one":
							value = new ManyToOne(table);
							BindManyToOne(subnode, (ManyToOne) value, propertyName, true);
							break;
						case "any":
							value = new Any(table);
							BindAny(subnode, (Any) value, true);
							break;
						case "property":
							value = new SimpleValue(table);
							BindSimpleValue(subnode, (SimpleValue) value, true, propertyName);
							break;
						case "component":
						case "dynamic-component":
							string subpath = StringHelper.Qualify(path, propertyName);
							value = new Component(join);
							BindComponent(subnode, (Component) value, join.PersistentClass.MappedClass, join.PersistentClass.ClassName,
							              propertyName, subpath, true, inheritedMetas);
							break;
					}
				}
				if (value != null)
				{
					var prop = CreateProperty(value, propertyName, persistentClass.MappedClass.AssemblyQualifiedName, subnode,
					                          inheritedMetas);
					prop.IsOptional = join.IsOptional;
					join.AddProperty(prop);
				}
			}

			// CUSTOM SQL
			HandleCustomSQL(node, join);
		}