/// <summary> Fill the ClassDeclaration with Attributes of the XmlSchemaElement. </summary> public static void GenerateAttribute(System.Xml.Schema.XmlSchemaElement attElt, Refly.CodeDom.ClassDeclaration cd, System.Xml.Schema.XmlSchemaComplexType refSchemaType) { cd.Doc.Summary.AddText(AnnotationToString(attElt.Annotation)); // Create the <summary /> cd.Parent = new Refly.CodeDom.StringTypeDeclaration("BaseAttribute"); // Add [AttributeUsage(AttributeTargets, AllowMultiple] and [Serializable] // Note: There is a problem with the order of the arguments, that's why they are together bool targetsAll = Utils.TargetsAll(Utils.Capitalize(attElt.Name)); string attributeTargets = "System.AttributeTargets."; if (Utils.IsRoot(Utils.Capitalize(attElt.Name)) || targetsAll) { attributeTargets += "Class | System.AttributeTargets.Struct | System.AttributeTargets.Interface"; } if (targetsAll) { attributeTargets += " | System.AttributeTargets."; } if (!Utils.IsRoot(Utils.Capitalize(attElt.Name)) || targetsAll) { attributeTargets += "Property | System.AttributeTargets.Field"; } Refly.CodeDom.AttributeDeclaration attribUsage = cd.CustomAttributes.Add("System.AttributeUsage"); attribUsage.Arguments.Add("", new Refly.CodeDom.Expressions.SnippetExpression( attributeTargets + ", AllowMultiple=" + Utils.AllowMultipleValue(attElt.Name))); cd.CustomAttributes.Add("System.Serializable"); // Add the constructors Refly.CodeDom.ConstructorDeclaration defCtor = cd.AddConstructor(); defCtor.Doc.Summary.AddText(" Default constructor (position=0) "); // Create the <summary /> defCtor.BaseContructorArgs.Add(new Refly.CodeDom.Expressions.SnippetExpression("0")); Refly.CodeDom.ConstructorDeclaration posCtor = cd.AddConstructor(); posCtor.Doc.Summary.AddText(" Constructor taking the position of the attribute. "); // Create the <summary /> posCtor.Signature.Parameters.Add(typeof(int), "position"); posCtor.BaseContructorArgs.Add(new Refly.CodeDom.Expressions.SnippetExpression("position")); System.Xml.Schema.XmlSchemaComplexType type = attElt.SchemaType as System.Xml.Schema.XmlSchemaComplexType; if (type == null && !attElt.SchemaTypeName.IsEmpty) // eg: <xs:element name="cache" type="cacheType" /> { type = refSchemaType; } if (type != null) { // Add the attribute members System.Collections.ArrayList attribMembers = Utils.GetAttributes(type.Attributes); log.Debug("Add Attribute members: Count=" + attribMembers.Count); foreach (System.Xml.Schema.XmlSchemaAttribute attribMember in attribMembers) { string memberType = Utils.GetAttributeTypeName(attElt, attribMember); if (attribMember.SchemaTypeName.Name == string.Empty) // Create the dynamically generated enumeration { log.Debug("Generate Enumeration for SimpleType: " + memberType); GenerateEnumeration(attribMember.SchemaType, cd.Namespace.AddEnum(memberType, false)); } // Add the field with its default value Refly.CodeDom.FieldDeclaration fd = cd.AddField( memberType, attribMember.Name.Replace("-", "").ToLower()); // Set the unspecified value (to know if specified by the user) fd.InitExpression = new Refly.CodeDom.Expressions.SnippetExpression(Utils.GetUnspecifiedValue(attElt, attribMember)); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pd = cd.AddProperty(fd, true, true, false); pd.Doc.Summary.AddText(AnnotationToString(attribMember.Annotation)); // Create the <summary /> if (memberType == "System.Boolean") { // Add the field+property to know if this field has been specified Refly.CodeDom.FieldDeclaration boolIsSpec = cd.AddField( "System.Boolean", fd.Name + "specified"); cd.AddProperty(boolIsSpec, true, false, false).Doc.Summary.AddText(" Tells if " + pd.Name + " has been specified. "); // Create the <summary /> pd.Set.Add(new Refly.CodeDom.Expressions.SnippetExpression( boolIsSpec.Name + " = true")); } // Add the System.Type property (to allow setting this attribute with a type) if (Utils.IsSystemType(attElt.Name, attribMember, memberType)) { log.Debug(" Create System.Type for <" + attElt.Name + "> <" + attribMember.Name + ">"); Refly.CodeDom.PropertyDeclaration pdType = cd.AddProperty(typeof(System.Type), pd.Name + "Type"); pdType.Doc.Summary.AddText(AnnotationToString(attribMember.Annotation)); // Create the <summary /> pdType.Get.Add(new Refly.CodeDom.Expressions.SnippetExpression( "return System.Type.GetType( this." + pd.Name + " )")); pdType.Set.Add(new Refly.CodeDom.Expressions.SnippetExpression(string.Format( @"if(value.Assembly == typeof(int).Assembly) this.{0} = value.FullName.Substring(7); else this.{0} = value.FullName + "", "" + value.Assembly.GetName().Name" , pd.Name))); } // Add the object property (to allow setting this attribute with any object) if (Utils.IsSystemObject(attElt.Name, attribMember, memberType)) { bool IsSystemEnum = Utils.IsSystemEnum(attElt.Name, attribMember, memberType); log.Debug(" Create object version " + (IsSystemEnum?"+ EnumFormat ":"") + "for <" + attElt.Name + "> <" + attribMember.Name + ">"); Refly.CodeDom.PropertyDeclaration pdType = cd.AddProperty(typeof(object), pd.Name + "Object"); pdType.Doc.Summary.AddText(AnnotationToString(attribMember.Annotation)); // Create the <summary /> pdType.Get.Add(new Refly.CodeDom.Expressions.SnippetExpression( "return this." + pd.Name)); // handle conversion of enum values if (IsSystemEnum) { pdType.Set.Add(new Refly.CodeDom.Expressions.SnippetExpression(string.Format( @"if(value is System.Enum) this.{0} = System.Enum.Format(value.GetType(), value, this.{0}EnumFormat); else this.{0} = value==null ? ""null"" : value.ToString()" , pd.Name))); } else { pdType.Set.Add(new Refly.CodeDom.Expressions.SnippetExpression(string.Format( @"this.{0} = value==null ? ""null"" : value.ToString()", pd.Name))); } // Add the field xxxEnumFormat to set the string to use when formatting an Enum if (IsSystemEnum) { Refly.CodeDom.FieldDeclaration fdEnumFormat = cd.AddField( typeof(string), (fd.Name + "EnumFormat").ToLower()); // Set the default value fdEnumFormat.InitExpression = new Refly.CodeDom.Expressions.SnippetExpression("\"g\""); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pdEnumFormat = cd.AddProperty(fdEnumFormat, true, true, false); pdEnumFormat.Doc.Summary.AddText("'format' used by System.Enum.Format() in " + pdType.Name); // Create the <summary /> } } } if (type.IsMixed) // used by elements like <param> { // Add the field with its default value Refly.CodeDom.FieldDeclaration fd = cd.AddField("System.String", "Content"); // Add the unspecified value (to know if specified by the user) fd.InitExpression = new Refly.CodeDom.Expressions.SnippetExpression("null"); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pd = cd.AddProperty(fd, true, true, false); pd.Doc.Summary.AddText(" Gets or sets the content of this element "); // Create the <summary /> } } else { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append("Unknow Element: ").Append(attElt.Name); if (attElt.SchemaType != null) { sb.Append(", SchemaType = ").Append(attElt.SchemaType).Append(" - ").Append(attElt.SchemaType.Name); } if (!attElt.SchemaTypeName.IsEmpty) { sb.Append(", SchemaTypeName = ").Append(attElt.SchemaTypeName.Name); } if (attElt.ElementType != null) { sb.Append(", ElementType = ").Append(attElt.ElementType); } log.Warn(sb.ToString()); } }
static void Main() { try { log.Info("Generation of NHibernate.Mapping.Attributes"); // Open the Schema (in /NHMA/ directory) System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader("../../../../NHibernate.Mapping.Attributes/nhibernate-mapping.xsd"); schema = System.Xml.Schema.XmlSchema.Read(reader, null); Refly.CodeDom.NamespaceDeclaration nd = new Refly.CodeDom.NamespaceDeclaration("NHibernate.Mapping.Attributes", conformer); nd.Imports.Clear(); // remove "using System;" conformer.Capitalize = true; Refly.CodeDom.ClassDeclaration hbmWriter = nd.AddClass("HbmWriter"); hbmWriter.Attributes = System.Reflection.TypeAttributes.Public; hbmWriter.Doc.Summary.AddText(" Write a XmlSchemaElement from attributes in a System.Type. "); // Create the <summary /> Refly.CodeDom.FieldDeclaration fdDefaultHelper = hbmWriter.AddField("HbmWriterHelper", "DefaultHelper"); fdDefaultHelper.InitExpression = new Refly.CodeDom.Expressions.SnippetExpression("new HbmWriterHelperEx()"); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pdDefaultHelper = hbmWriter.AddProperty(fdDefaultHelper, true, true, false); pdDefaultHelper.Doc.Summary.AddText(" Gets or sets the HbmWriterHelper used by HbmWriter "); // Create the <summary /> Refly.CodeDom.FieldDeclaration fdStartQuote = hbmWriter.AddField(typeof(string), "StartQuote"); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pdStartQuote = hbmWriter.AddProperty(fdStartQuote, false, true, false); pdStartQuote.Get.Add(new Refly.CodeDom.Expressions.SnippetExpression(@"if(_startQuote==null || _startQuote.Length==0) _startQuote = ""{{""; return _startQuote" )); pdStartQuote.Doc.Summary.AddText(" Gets or sets the beginning string used when declaring an identifier for an AttributeIdenfierAttribute "); // Create the <summary /> Refly.CodeDom.FieldDeclaration fdEndQuote = hbmWriter.AddField(typeof(string), "EndQuote"); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pdEndQuote = hbmWriter.AddProperty(fdEndQuote, false, true, false); pdEndQuote.Get.Add(new Refly.CodeDom.Expressions.SnippetExpression(@"if(_endQuote==null || _endQuote.Length==0) _endQuote = ""}}""; return _endQuote" )); pdEndQuote.Doc.Summary.AddText(" Gets or sets the ending string used when declaring an identifier for an AttributeIdenfierAttribute "); // Create the <summary /> Refly.CodeDom.FieldDeclaration fdPatterns = hbmWriter.AddField(typeof(System.Collections.Hashtable), "Patterns"); // Add its public property with a comment Refly.CodeDom.PropertyDeclaration pdPatterns = hbmWriter.AddProperty(fdPatterns, false, true, false); pdPatterns.Get.Add(new Refly.CodeDom.Expressions.SnippetExpression(@"if(_patterns==null) { _patterns = new System.Collections.Hashtable(); _patterns.Add(@""Nullables.Nullable(\w+), Nullables"", ""Nullables.NHibernate.Nullable$1Type, Nullables.NHibernate""); _patterns.Add(@""System.Data.SqlTypes.Sql(\w+), System.Data"", ""NHibernate.UserTypes.SqlTypes.Sql$1Type, NHibernate.UserTypes.SqlTypes""); } return _patterns" )); pdPatterns.Doc.Summary.AddText(" Gets or sets the Patterns to convert properties types (the key is the pattern string and the value is the replacement string) "); // Create the <summary /> HbmWriterGenerator.FillFindAttributedMembers(hbmWriter.AddMethod("FindAttributedMembers")); HbmWriterGenerator.FillGetSortedAttributes(hbmWriter.AddMethod("GetSortedAttributes")); HbmWriterGenerator.FillIsNextElement(hbmWriter.AddMethod("IsNextElement"), schema.Items); HbmWriterGenerator.FillGetXmlEnumValue(hbmWriter.AddMethod("GetXmlEnumValue")); HbmWriterGenerator.FillGetAttributeValue(hbmWriter.AddMethod("GetAttributeValue")); HbmWriterGenerator.FillWriteUserDefinedContent(hbmWriter.AddMethod("WriteUserDefinedContent"), hbmWriter.AddMethod("WriteUserDefinedContent")); log.Info("Browse Schema.Items (Count=" + schema.Items.Count + ")"); foreach (System.Xml.Schema.XmlSchemaObject obj in schema.Items) { if (obj is System.Xml.Schema.XmlSchemaAttributeGroup) { // Ignore (used by Elements: <xs:attributeGroup ref="..." />) log.Debug("Ignore AttributeGroup: " + (obj as System.Xml.Schema.XmlSchemaAttributeGroup).Name + string.Format(", nh-mapping.xsd({0})", obj.LineNumber)); } else if (obj is System.Xml.Schema.XmlSchemaGroup) { // Ignore (used by Elements: <xs:group ref="..." />) log.Debug("Ignore Group: " + (obj as System.Xml.Schema.XmlSchemaGroup).Name + string.Format(", nh-mapping.xsd({0})", obj.LineNumber)); } else if (obj is System.Xml.Schema.XmlSchemaSimpleType) { System.Xml.Schema.XmlSchemaSimpleType elt = obj as System.Xml.Schema.XmlSchemaSimpleType; log.Debug("Generate Enumeration for SimpleType: " + elt.Name + string.Format(", nh-mapping.xsd({0})", elt.LineNumber)); AttributeAndEnumGenerator.GenerateEnumeration(elt, nd.AddEnum(Utils.Capitalize(elt.Name), false)); } else if (obj is System.Xml.Schema.XmlSchemaElement) { System.Xml.Schema.XmlSchemaElement elt = obj as System.Xml.Schema.XmlSchemaElement; System.Xml.Schema.XmlSchemaComplexType type = null; if (!elt.SchemaTypeName.IsEmpty) // eg: <xs:element name="cache" type="cacheType" /> { foreach (System.Xml.Schema.XmlSchemaObject o in schema.Items) { System.Xml.Schema.XmlSchemaComplexType t = o as System.Xml.Schema.XmlSchemaComplexType; if (t != null && t.Name == elt.SchemaTypeName.Name) { type = t; break; } } } string eltName = Utils.Capitalize(elt.Name); log.Debug("Generate Attrib and EltWriter for Elt: " + elt.Name + string.Format(", nh-mapping.xsd({0})", elt.LineNumber)); AttributeAndEnumGenerator.GenerateAttribute(elt, nd.AddClass(eltName + "Attribute"), type); HbmWriterGenerator.GenerateElementWriter(elt, eltName, hbmWriter.AddMethod("Write" + eltName), type, schema.Items); if (Utils.IsRoot(eltName)) { HbmWriterGenerator.FillWriteNestedTypes(eltName, hbmWriter.AddMethod("WriteNested" + eltName + "Types")); } } else if (obj is System.Xml.Schema.XmlSchemaComplexType) { // Ignore (Note: Make sure that it is used by Elements only like this: <xs:element name="XXX" type="YYY" />) System.Xml.Schema.XmlSchemaComplexType elt = obj as System.Xml.Schema.XmlSchemaComplexType; log.Debug("Don't generate ComplexType: " + elt.Name + string.Format(", nh-mapping.xsd({0})", elt.LineNumber)); // like <query> and <sql-query> } else { log.Warn("Unknown Object: " + obj.ToString() + string.Format(", nh-mapping.xsd({0})", obj.LineNumber)); } } // Generate the source code // Note: NameConformer.WordSplit() has been replaced in Refly. Refly.CodeDom.CodeGenerator gen = new Refly.CodeDom.CodeGenerator(); gen.Options.IndentString = " "; // Tab gen.CreateFolders = false; #region Copyright gen.Copyright = string.Format(@" NHibernate.Mapping.Attributes This product is under the terms of the GNU Lesser General Public License. ------------------------------------------------------------------------------ <autogenerated> This code was generated by a tool. Runtime Version: {0}.{1}.{2}.x Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. </autogenerated> ------------------------------------------------------------------------------ This source code was auto-generated by Refly, Version={3} (modified). ", System.Environment.Version.Major, System.Environment.Version.Minor, System.Environment.Version.Build, gen.GetType().Assembly.GetName(false).Version); #endregion log.Info("CodeGenerator.GenerateCode()... Classes=" + nd.Classes.Count + ", Enums=" + nd.Enums.Count); gen.GenerateCode(@"../../../../NHibernate.Mapping.Attributes", nd); log.Info("Done !"); } catch (System.Exception ex) { log.Error("Unexpected Exception", ex); } }