/// <summary> Writes the mapping of all mapped classes of the specified assembly in the specified stream. </summary> /// <param name="stream">Where the xml is written.</param> /// <param name="assembly">Assembly used to extract user-defined types containing a valid attribute (can be [Class] or [xSubclass]).</param> public virtual void Serialize(System.IO.Stream stream, System.Reflection.Assembly assembly) { if (stream == null) { throw new System.ArgumentNullException("stream"); } if (assembly == null) { throw new System.ArgumentNullException("assembly"); } System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(stream, System.Text.Encoding.UTF8); writer.Formatting = System.Xml.Formatting.Indented; writer.WriteStartDocument(); if (WriteDateComment) { writer.WriteComment(string.Format("Generated from NHibernate.Mapping.Attributes on {0}.", System.DateTime.Now.ToString("u"))); } WriteHibernateMapping(writer, null); // Write imports (classes decorated with the [ImportAttribute]) foreach (System.Type type in assembly.GetTypes()) { object[] imports = type.GetCustomAttributes(typeof(ImportAttribute), false); foreach (ImportAttribute import in imports) { writer.WriteStartElement("import"); if (import.Class != null && import.Class != string.Empty) { writer.WriteAttributeString("class", import.Class); } else // Assume that it is the current type that must be imported { writer.WriteAttributeString("class", HbmWriterHelper.GetNameWithAssembly(type)); } if (import.Rename != null && import.Rename != string.Empty) { writer.WriteAttributeString("rename", import.Rename); } writer.WriteEndElement(); } } // Write classes and x-subclasses (classes must come first if inherited by "external" subclasses) int classCount = 0; System.Collections.ArrayList mappedClassesNames = new System.Collections.ArrayList(); foreach (System.Type type in assembly.GetTypes()) { if (!IsClass(type)) { continue; } HbmWriter.WriteClass(writer, type); mappedClassesNames.Add(HbmWriterHelper.GetNameWithAssembly(type)); classCount++; } System.Collections.ArrayList subclasses = new System.Collections.ArrayList(); System.Collections.Specialized.StringCollection extendedClassesNames = new System.Collections.Specialized.StringCollection(); foreach (System.Type type in assembly.GetTypes()) { if (!IsSubclass(type)) { continue; } bool map = true; System.Type t = type; while ((t = t.DeclaringType) != null) { if (IsClass(t) || AreSameSubclass(type, t)) // If a base class is also mapped... (Note: A x-subclass can only contain x-subclasses of the same family) { map = false; // This class's mapping is already included in the mapping of the base class break; } } if (map) { subclasses.Add(type); if (IsSubclass(type, typeof(SubclassAttribute))) { extendedClassesNames.Add((type.GetCustomAttributes(typeof(SubclassAttribute), false)[0] as SubclassAttribute).Extends); } else if (IsSubclass(type, typeof(JoinedSubclassAttribute))) { extendedClassesNames.Add((type.GetCustomAttributes(typeof(JoinedSubclassAttribute), false)[0] as JoinedSubclassAttribute).Extends); } else if (IsSubclass(type, typeof(UnionSubclassAttribute))) { extendedClassesNames.Add((type.GetCustomAttributes(typeof(UnionSubclassAttribute), false)[0] as UnionSubclassAttribute).Extends); } } } classCount += subclasses.Count; MapSubclasses(subclasses, extendedClassesNames, mappedClassesNames, writer); writer.WriteEndElement(); // </hibernate-mapping> writer.WriteEndDocument(); writer.Flush(); if (classCount == 0) { throw new MappingException("The following assembly contains no mapped classes: " + assembly.FullName); } if (!Validate) { return; } // Validate the generated XML stream try { writer.BaseStream.Position = 0; System.Xml.XmlTextReader tr = new System.Xml.XmlTextReader(writer.BaseStream); var reader = CreateReader(tr); _stop = false; while (reader.Read() && !_stop) // Read to validate (stop at the first error) { ; } } catch (System.Exception ex) { Error.Append(ex.ToString()).Append(System.Environment.NewLine + System.Environment.NewLine); } }
/// <summary> Writes the mapping of the specified class in the specified stream. </summary> /// <param name="stream">Where the xml is written; can be null if you send the writer.</param> /// <param name="type">User-defined type containing a valid attribute (can be [Class] or [xSubclass]).</param> /// <param name="writer">The XmlTextWriter used to write the xml; can be null if you send the stream. You can also create it yourself, but don't forget to write the StartElement ("hibernate-mapping") before.</param> /// <param name="writeEndDocument">Tells if the EndElement of "hibernate-mapping" must be written; send false to append many classes in the same stream.</param> /// <returns>The parameter writer if it was not null; else it is a new writer (created using the stream). Send it back to append many classes in this stream.</returns> public virtual System.Xml.XmlTextWriter Serialize(System.IO.Stream stream, System.Type type, System.Xml.XmlTextWriter writer, bool writeEndDocument) { if (stream == null && writer == null) { throw new System.ArgumentNullException("stream"); } if (type == null) { throw new System.ArgumentNullException("type"); } if (writer == null) { writer = new System.Xml.XmlTextWriter(stream, System.Text.Encoding.UTF8); writer.Formatting = System.Xml.Formatting.Indented; writer.WriteStartDocument(); if (WriteDateComment) { writer.WriteComment(string.Format("Generated by NHibernate.Mapping.Attributes on {0}.", System.DateTime.Now.ToString("u"))); } WriteHibernateMapping(writer, type); } if (IsClass(type)) { HbmWriter.WriteClass(writer, type); } else if (IsSubclass(type, typeof(SubclassAttribute))) { HbmWriter.WriteSubclass(writer, type); } else if (IsSubclass(type, typeof(JoinedSubclassAttribute))) { HbmWriter.WriteJoinedSubclass(writer, type); } else if (IsSubclass(type, typeof(UnionSubclassAttribute))) { HbmWriter.WriteUnionSubclass(writer, type); } else { throw new System.ArgumentException("No valid attribute; looking for [Class] or [xSubclass].", "type"); } if (writeEndDocument) { writer.WriteEndElement(); // </hibernate-mapping> writer.WriteEndDocument(); writer.Flush(); if (!Validate) { return(writer); } // Validate the generated XML stream try { writer.BaseStream.Position = 0; var tr = new System.Xml.XmlTextReader(writer.BaseStream); var reader = CreateReader(tr); _stop = false; while (reader.Read() && !_stop) // Read to validate (stop at the first error) { ; } } catch (System.Exception ex) { Error.Append(ex.ToString()).Append(System.Environment.NewLine + System.Environment.NewLine); } } else { writer.Flush(); } return(writer); }
/// <summary> Writes the mapping of the specified class in the specified stream. </summary> /// <param name="stream">Where the xml is written; can be null if you send the writer.</param> /// <param name="type">User-defined type containing a valid attribute (can be [Class] or [xSubclass]).</param> /// <param name="writer">The XmlTextWriter used to write the xml; can be null if you send the stream. You can also create it yourself, but don't forget to write the StartElement ("hibernate-mapping") before.</param> /// <param name="writeEndDocument">Tells if the EndElement of "hibernate-mapping" must be written; send false to append many classes in the same stream.</param> /// <returns>The parameter writer if it was not null; else it is a new writer (created using the stream). Send it back to append many classes in this stream.</returns> public virtual System.Xml.XmlTextWriter Serialize(System.IO.Stream stream, System.Type type, System.Xml.XmlTextWriter writer, bool writeEndDocument) { if (stream == null && writer == null) { throw new System.ArgumentNullException("stream"); } if (type == null) { throw new System.ArgumentNullException("type"); } if (writer == null) { writer = new System.Xml.XmlTextWriter(stream, System.Text.Encoding.UTF8); writer.Formatting = System.Xml.Formatting.Indented; writer.WriteStartDocument(); if (WriteDateComment) { writer.WriteComment(string.Format("Generated by NHibernate.Mapping.Attributes on {0}.", System.DateTime.Now.ToString("u"))); } WriteHibernateMapping(writer, type); } if (IsClass(type)) { HbmWriter.WriteClass(writer, type); } else if (IsSubclass(type, typeof(SubclassAttribute))) { HbmWriter.WriteSubclass(writer, type); } else if (IsSubclass(type, typeof(JoinedSubclassAttribute))) { HbmWriter.WriteJoinedSubclass(writer, type); } else if (IsSubclass(type, typeof(UnionSubclassAttribute))) { HbmWriter.WriteUnionSubclass(writer, type); } else { throw new System.ArgumentException("No valid attribute; looking for [Class] or [xSubclass].", "type"); } if (writeEndDocument) { writer.WriteEndElement(); // </hibernate-mapping> writer.WriteEndDocument(); writer.Flush(); if (!Validate) { return(writer); } // Validate the generated XML stream try { writer.BaseStream.Position = 0; System.Xml.XmlTextReader tr = new System.Xml.XmlTextReader(writer.BaseStream); System.Xml.XmlValidatingReader vr = new System.Xml.XmlValidatingReader(tr); // Open the Schema System.IO.Stream schema = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("NHibernate.Mapping.Attributes.nhibernate-mapping.xsd"); vr.Schemas.Add("urn:nhibernate-mapping-2.2", new System.Xml.XmlTextReader(schema)); vr.ValidationType = System.Xml.ValidationType.Schema; vr.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(XmlValidationHandler); _stop = false; while (vr.Read() && !_stop) // Read to validate (stop at the first error) { ; } } catch (System.Exception ex) { Error.Append(ex.ToString()).Append(System.Environment.NewLine + System.Environment.NewLine); } } else { writer.Flush(); } return(writer); }