/// <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; }
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)); } }
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 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); }
/// <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; } }
/// <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 ) ); } } }
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; }
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); }