/*
*
* Welcome to the Object Model Generator v0.4
* This source file has been released on April 9th, 2004.
* Copyright 2003-2004, All Rights Reserved. http://weblogs.asp.net/OKloeten/
*
* Please feel free to use this utility however you wish. I'd appreciate any and all
* feedback regarding your use and/or source modifications.
*
* Sorry this file is not properly commented since it was written under
* the pressures of time and mind clutter.
*
* Omer van Kloeten
*
*/
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
namespace Omer.Utilities.ObjectModelGenerator
{
public class ObjectModelGenerator
{
static string tabulator = string.Empty;
static MethodInfo miFromTypeName = typeof(XmlSchemaDatatype).GetMethod("FromTypeName", BindingFlags.Static | BindingFlags.NonPublic);
#region CreateDOM
public static CodeCompileUnit CreateDOM(string nameSpace, System.Xml.Schema.XmlSchema schema)
{
CodeNamespace ns = new CodeNamespace(nameSpace);
ns.Comments.Add(new CodeCommentStatement("The following code was generated automatically by use of the Object Model Generator."));
ns.Comments.Add(new CodeCommentStatement("If you feel this tool has helped you in any way or there are bugs to notify me of,"));
ns.Comments.Add(new CodeCommentStatement("please let me know at ovanklot@gmx.net or http://weblogs.asp.net/OKloeten/."));
ns.Comments.Add(new CodeCommentStatement(string.Empty));
ns.Comments.Add(new CodeCommentStatement("Omer van Kloeten"));
foreach (XmlSchemaElement element in schema.Items)
{
if (element.SchemaType is XmlSchemaComplexType)
{
Console.WriteLine("[ " + (schema.Items.IndexOf(element) + 1) + " / " + schema.Items.Count + " ] " + element.Name);
CodeTypeMember[] temp = new CodeTypeMember[0];
ns.Types.Add(CreateComplexElement(ns, element, out temp));
// public class ElementDocument : System.Xml.XmlDocument
// {
// private static System.Xml.Schema.XmlSchema m_Schema =
// System.Xml.Schema.XmlSchema.Read(new System.IO.StringReader(...), null);
//
// public static ElementDocument FromDOM(Element element)
// {
// ElementDocument document = new ElementDocument();
//
// document.AppendChild(document.CreateXmlDeclaration("1.0", "utf-8", "true"));
// document.AppendChild(((IXmlElement)(element)).GetXml(document));
//
// System.Xml.XmlAttribute xmlns = document.CreateAttribute("xmlns");
// xmlns.Value = m_Schema.TargetNamespace;
// document["ValidationDictionary"].Attributes.Append(xmlns);
//
// return document;
// }
//
// public Element CreateDOM()
// {
// return new Element(this["Element"]);
// }
//
// public override void Load(System.Xml.XmlReader reader)
// {
// System.Xml.XmlValidatingReader valReader;
//
// if (reader is System.Xml.XmlValidatingReader)
// {
// valReader = reader as System.Xml.XmlValidatingReader;
// }
// else
// {
// valReader = new System.Xml.XmlValidatingReader(reader);
// }
//
// valReader.Schemas.Add(m_Schema);
// valReader.ValidationType = System.Xml.ValidationType.Schema;
//
// base.Load (reader);
// }
// }
string pcName = ToPascalCasing(element.Name);
CodeTypeDeclaration documentDecl = new CodeTypeDeclaration(pcName + "Document");
documentDecl.Attributes &= ~MemberAttributes.AccessMask;
documentDecl.Attributes |= MemberAttributes.Public;
documentDecl.BaseTypes.Add(typeof(System.Xml.XmlDocument));
documentDecl.Comments.Add(new CodeCommentStatement("This class is used to load and store files that contain the " + element.Name + " hierarchy.", true));
CodeMemberField schemaField = new CodeMemberField(typeof(System.Xml.Schema.XmlSchema), "m_Schema");
System.Text.StringBuilder sBuilder = new System.Text.StringBuilder();
schema.Write(new StringWriter(sBuilder));
schemaField.InitExpression = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(System.Xml.Schema.XmlSchema)), "Read", new CodeObjectCreateExpression(typeof(System.IO.StringReader), new CodePrimitiveExpression(sBuilder.ToString())), new CodePrimitiveExpression(null));
schemaField.Attributes &= ~MemberAttributes.ScopeMask;
schemaField.Attributes |= MemberAttributes.Static;
schemaField.Comments.Add(new CodeCommentStatement("This field is used to store the schema for validation.", true));
documentDecl.Members.Add(schemaField);
CodeMemberMethod fromDOMMethod = new CodeMemberMethod();
fromDOMMethod.Name = "FromDOM";
fromDOMMethod.Attributes &= ~(MemberAttributes.AccessMask | MemberAttributes.ScopeMask);
fromDOMMethod.Attributes |= MemberAttributes.Public | MemberAttributes.Static;
fromDOMMethod.Parameters.Add(new CodeParameterDeclarationExpression(pcName + "Element", "element"));
fromDOMMethod.ReturnType = new CodeTypeReference(pcName + "Document");
fromDOMMethod.Comments.Add(new CodeCommentStatement("This method is used for loading the " + pcName + "Document with data from the DOM.", true));
fromDOMMethod.Statements.Add(new CodeVariableDeclarationStatement(pcName + "Document", "document", new CodeObjectCreateExpression(pcName + "Document")));
fromDOMMethod.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "AppendChild", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "CreateXmlDeclaration", new CodePrimitiveExpression("1.0"), new CodePrimitiveExpression("utf-8"), new CodePrimitiveExpression("yes")))));
fromDOMMethod.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "AppendChild", new CodeMethodInvokeExpression(new CodeCastExpression("IXmlElement", new CodeVariableReferenceExpression("element")), "GetXml", new CodeVariableReferenceExpression("document")))));
fromDOMMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Xml.XmlAttribute), "xmlns", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "CreateAttribute", new CodePrimitiveExpression("xmlns"))));
fromDOMMethod.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("xmlns"), "Value"), new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(null, "m_Schema"), "TargetNamespace")));
fromDOMMethod.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodeVariableReferenceExpression("document"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(ToPascalCasing(element.Name) + "Element"), "ElementName")), "Attributes"), "Append", new CodeVariableReferenceExpression("xmlns")));
fromDOMMethod.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("document")));
documentDecl.Members.Add(fromDOMMethod);
CodeMemberMethod createDOMMethod = new CodeMemberMethod();
createDOMMethod.Name = "CreateDOM";
createDOMMethod.Attributes &= ~MemberAttributes.AccessMask;
createDOMMethod.Attributes |= MemberAttributes.Public;
createDOMMethod.ReturnType = new CodeTypeReference(pcName + "Element");
createDOMMethod.Comments.Add(new CodeCommentStatement("This method is used for loading the DOM into this " + pcName + "Document.", true));
createDOMMethod.Statements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(pcName + "Element", new CodeIndexerExpression(new CodeThisReferenceExpression(), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(ToPascalCasing(element.Name) + "Element"), "ElementName")))));
documentDecl.Members.Add(createDOMMethod);
CodeMemberMethod loadMethod = new CodeMemberMethod();
loadMethod.Name = "Load";
loadMethod.Attributes &= ~(MemberAttributes.AccessMask | MemberAttributes.ScopeMask);
loadMethod.Attributes |= MemberAttributes.Public | MemberAttributes.Override | MemberAttributes.Overloaded;
loadMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlReader), "reader"));
loadMethod.Comments.Add(new CodeCommentStatement("Loads the XML document from the specified and validates it against the schema.", true));
loadMethod.Comments.Add(new CodeCommentStatement("Note that if the namespace does not point to the schema, the document will not be validated.", true));
loadMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Xml.XmlValidatingReader), "valReader"));
loadMethod.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("reader"), "GetType"), CodeBinaryOperatorType.IdentityEquality, new CodeTypeOfExpression(typeof(System.Xml.XmlValidatingReader))),
new CodeStatement[] {new CodeAssignStatement(new CodeVariableReferenceExpression("valReader"), new CodeCastExpression(typeof(System.Xml.XmlValidatingReader), new CodeVariableReferenceExpression("reader")))},
new CodeStatement[] {new CodeAssignStatement(new CodeVariableReferenceExpression("valReader"), new CodeObjectCreateExpression(typeof(System.Xml.XmlValidatingReader), new CodeVariableReferenceExpression("reader")))}));
loadMethod.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("valReader"), "Schemas"), "Add", new CodeFieldReferenceExpression(null, "m_Schema")));
loadMethod.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("valReader"), "ValidationType"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(System.Xml.ValidationType)), "Schema")));
loadMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Load", new CodeVariableReferenceExpression("reader")));
documentDecl.Members.Add(loadMethod);
ns.Types.Add(documentDecl);
}
}
// public interface IXmlElementCollection
// {
// System.Xml.XmlElement[] GetXml(System.Xml.XmlDocument document);
// }
//
// public interface IXmlElement
// {
// System.Xml.XmlElement GetXml(System.Xml.XmlDocument document);
// }
CodeTypeDeclaration iXmlElementCollection = new CodeTypeDeclaration("IXmlElementCollection");
iXmlElementCollection.IsInterface = true;
iXmlElementCollection.Attributes &= ~MemberAttributes.AccessMask;
iXmlElementCollection.Attributes |= MemberAttributes.Public;
iXmlElementCollection.Comments.Add(new CodeCommentStatement("This interface is used for serializing the DOM, for an element collection.", true));
CodeMemberMethod getXmlElements = new CodeMemberMethod();
getXmlElements.Name = "GetXml";
getXmlElements.ReturnType = new CodeTypeReference(new CodeTypeReference(typeof(System.Xml.XmlElement)), 1);
getXmlElements.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlDocument), "document"));
getXmlElements.Comments.Add(new CodeCommentStatement("This method is used to serialize an element collection to XML DOM.", true));
iXmlElementCollection.Members.Add(getXmlElements);
ns.Types.Add(iXmlElementCollection);
CodeTypeDeclaration iXmlElement = new CodeTypeDeclaration("IXmlElement");
iXmlElement.IsInterface = true;
iXmlElement.Attributes &= ~MemberAttributes.AccessMask;
iXmlElement.Attributes |= MemberAttributes.Public;
iXmlElement.Comments.Add(new CodeCommentStatement("This interface is used for serializing the DOM, for a specific element.", true));
CodeMemberMethod getXml = new CodeMemberMethod();
getXml.Name = "GetXml";
getXml.ReturnType = new CodeTypeReference(typeof(System.Xml.XmlElement));
getXml.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlDocument), "document"));
getXml.Comments.Add(new CodeCommentStatement("This method is used to serialize an element to XML DOM.", true));
iXmlElement.Members.Add(getXml);
ns.Types.Add(iXmlElement);
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(ns);
return ccu;
}
#endregion
#region CreateComplexElement
static CodeTypeDeclaration CreateComplexElement(CodeObject parentObject,
System.Xml.Schema.XmlSchemaElement element,
out CodeTypeMember[] indexers)
{
string pcName = ToPascalCasing(element.Name);
System.Collections.ArrayList list = new System.Collections.ArrayList();
CodeTypeDeclaration decl = new CodeTypeDeclaration(pcName + "Element");
decl.BaseTypes.Add(typeof(object));
decl.BaseTypes.Add("IXmlElement");
decl.BaseTypes.Add(typeof(System.ICloneable));
decl.Comments.Add(new CodeCommentStatement("TODO: Complete Summary tag documentation."));
decl.Comments.Add(new CodeCommentStatement("Represents the " + element.Name + " element.", true));
// System.Xml.XmlElement IXmlElement.GetXml(System.Xml.XmlDocument document)
CodeMemberMethod getXml = new CodeMemberMethod();
getXml.Comments.Add(new CodeCommentStatement("This method is used to serialize the element to XML DOM.", true));
getXml.Name = "GetXml";
getXml.PrivateImplementationType = new CodeTypeReference("IXmlElement");
getXml.ReturnType = new CodeTypeReference(typeof(System.Xml.XmlElement));
getXml.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlDocument), "document"));
getXml.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Xml.XmlElement), "element", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "CreateElement", new CodeFieldReferenceExpression(null, "ElementName"))));
// internal Element(System.Xml.XmlElement element)
CodeConstructor fromXml = new CodeConstructor();
fromXml.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlElement), "element"));
fromXml.Attributes &= ~MemberAttributes.AccessMask;
fromXml.Attributes |= MemberAttributes.FamilyOrAssembly;
fromXml.Comments.Add(new CodeCommentStatement("This constructor is used to deserialize the element from XML DOM.", true));
CodeMemberMethod clone = new CodeMemberMethod();
clone.Name = "Clone";
clone.Attributes &= ~MemberAttributes.AccessMask;
clone.Attributes |= MemberAttributes.Public;
clone.ReturnType = new CodeTypeReference(typeof(object));
clone.Comments.Add(new CodeCommentStatement("This method is used to to clone the element.", true));
clone.Statements.Add(new CodeVariableDeclarationStatement(pcName + "Element", "clone", new CodeObjectCreateExpression(pcName + "Element")));
// if (element.Name != "Element")
// {
// throw new ApplicationException("Invalid element initialization.");
// }
fromXml.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Name"), CodeBinaryOperatorType.IdentityInequality, new CodeFieldReferenceExpression(null, "ElementName")),
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ApplicationException), new CodePrimitiveExpression("Invalid element initialization.")))));
CodeConstructor defaultCtor = new CodeConstructor();
defaultCtor.Attributes &= ~MemberAttributes.AccessMask;
defaultCtor.Attributes |= MemberAttributes.Public;
defaultCtor.Comments.Add(new CodeCommentStatement("This is the default constructor.", true));
decl.Members.Add(defaultCtor);
// public override bool Equals(object obj)
// {
// return (obj != null && obj.GetType() == typeof(Element) && ...);
// }
CodeMemberMethod equalsOverride = new CodeMemberMethod();
equalsOverride.Name = "Equals";
equalsOverride.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj"));
equalsOverride.ReturnType = new CodeTypeReference(typeof(bool));
equalsOverride.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
equalsOverride.Attributes |= MemberAttributes.Public | MemberAttributes.Override;
equalsOverride.Comments.Add(new CodeCommentStatement("Compares two instances of an element of type .", true));
equalsOverride.Comments.Add(new CodeCommentStatement("This does not support checking for equality for untyped attributes.", true));
CodeBinaryOperatorExpression equalsExpression = new CodeBinaryOperatorExpression(
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("obj"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
CodeBinaryOperatorType.BooleanAnd,
new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("obj"), "GetType"), CodeBinaryOperatorType.ValueEquality, new CodeTypeOfExpression(pcName + "Element")));
XmlSchemaComplexType complex = element.SchemaType as XmlSchemaComplexType;
CodeTypeMember[] complexTempIndexers = new CodeTypeMember[0];
if (complex.Particle is XmlSchemaChoice)
{
equalsExpression = new CodeBinaryOperatorExpression(equalsExpression, CodeBinaryOperatorType.BooleanAnd, CreateChoice(decl, complex.Particle as XmlSchemaChoice, getXml, fromXml, clone, out complexTempIndexers, defaultCtor));
}
else if (complex.Particle is XmlSchemaAny)
{
CreateAny(complex.Particle as XmlSchemaAny);
}
else if (complex.Particle is XmlSchemaAll)
{
CreateAll(complex.Particle as XmlSchemaAll);
}
else if (complex.Particle is XmlSchemaSequence)
{
equalsExpression = new CodeBinaryOperatorExpression(equalsExpression, CodeBinaryOperatorType.BooleanAnd, CreateSequence(decl, complex.Particle as XmlSchemaSequence, getXml, fromXml, clone, out complexTempIndexers, defaultCtor));
}
else if (complex.Particle is XmlSchemaGroupRef)
{
CreateGroupRef(complex.Particle as XmlSchemaGroupRef);
}
if (equalsExpression.Right == null)
{
equalsExpression = equalsExpression.Left as CodeBinaryOperatorExpression;
}
list.AddRange(complexTempIndexers);
foreach (System.Xml.Schema.XmlSchemaAttribute attribute in complex.Attributes)
{
CodeTypeMember[] attTempIndexers;
CodeBinaryOperatorExpression expr;
Type t = CreateProperty(decl,
attribute.Name,
attribute.SchemaTypeName.Name,
out attTempIndexers,
clone,
out expr);
equalsExpression = new CodeBinaryOperatorExpression(equalsExpression, CodeBinaryOperatorType.BooleanAnd, expr);
CreateAttributeGetXml(decl, attribute, getXml, t);
CreateAttributeFromXml(decl, attribute, fromXml, t);
list.AddRange(attTempIndexers);
}
if (complex.AnyAttribute != null)
{
#region AnyAttribute
#region m_CustomAttributes
// private System.Collections.Specialized.NameValueCollection m_CustomAttributes = new System.Collections.Specialized.NameValueCollection();
CodeMemberField mCustomAttributes = new CodeMemberField(typeof(System.Collections.Specialized.NameValueCollection), "m_CustomAttributes");
mCustomAttributes.InitExpression = new CodeObjectCreateExpression(typeof(System.Collections.Specialized.NameValueCollection));
mCustomAttributes.Comments.Add(new CodeCommentStatement("Represents any attribute from the original xml file that was not typed from the schema.", true));
decl.Members.Add(mCustomAttributes);
#endregion
#region CustomAttributes
// public System.Collections.Specialized.NameValueCollection CustomAttributes
// {
// get
// {
// return m_CustomAttributes;
// }
// }
CodeMemberProperty customAttributes = new CodeMemberProperty();
customAttributes.Name = "CustomAttributes";
customAttributes.Attributes &= ~MemberAttributes.AccessMask;
customAttributes.Attributes |= MemberAttributes.Public;
customAttributes.Type = new CodeTypeReference(typeof(System.Collections.Specialized.NameValueCollection));
customAttributes.Comments.Add(new CodeCommentStatement("Gets any attribute from the original xml file that was not typed from the schema.", true));
customAttributes.HasSet = false;
customAttributes.HasGet = true;
customAttributes.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes")));
decl.Members.Add(customAttributes);
#endregion
#region FromXml
// for (int index = 0; index < element.Attributes.Count; index++)
// {
// if (element.Attributes[index].Name != "Attribute")
// {
// m_CustomAttributes.Add(element.Attributes[index].Name, element.Attributes[index].Value);
// }
// }
CodeIterationStatement iterator = new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))));
System.Collections.ArrayList conditionsList = new System.Collections.ArrayList();
foreach (System.Xml.Schema.XmlSchemaAttribute attribute in complex.Attributes)
{
conditionsList.Add(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeVariableReferenceExpression("index")), "Name"), CodeBinaryOperatorType.IdentityInequality, new CodeFieldReferenceExpression(null, ToPascalCasing(attribute.Name) + "Name")));
}
if (conditionsList.Count == 0)
{
iterator.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes"), "Add", new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeVariableReferenceExpression("index")), "Name"), new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeVariableReferenceExpression("index")), "Value"))));
}
else
{
while (conditionsList.Count > 1)
{
CodeBinaryOperatorExpression bin1 = ((CodeBinaryOperatorExpression)(conditionsList[0]));
CodeBinaryOperatorExpression bin2 = ((CodeBinaryOperatorExpression)(conditionsList[1]));
conditionsList.RemoveAt(0);
conditionsList.RemoveAt(0);
conditionsList.Add(new CodeBinaryOperatorExpression(bin1, CodeBinaryOperatorType.BooleanAnd, bin2));
}
iterator.Statements.Add(new CodeConditionStatement(((CodeBinaryOperatorExpression)(conditionsList[0])), new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes"), "Add", new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeVariableReferenceExpression("index")), "Name"), new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeVariableReferenceExpression("index")), "Value")))));
conditionsList.Clear();
}
fromXml.Statements.Add(iterator);
#endregion
#region GetXml
// for (int index = 0; index < m_CustomAttributes.Count; index++)
// {
// element.SetAttribute(m_CustomAttributes.Keys[index], m_CustomAttributes[index]);
// }
getXml.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("m_CustomAttributes"), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "SetAttribute",
new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes"), "Keys"), new CodeVariableReferenceExpression("index")),
new CodeIndexerExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes"), new CodeVariableReferenceExpression("index"))))));
#endregion
#region Clone
// for (int index = 0; index < m_CustomAttributes.Count; index++)
// {
// clone.m_CustomAttributes.Add(m_CustomAttributes.Keys[index], m_CustomAttributes[index].Clone() as string);
// }
clone.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("m_CustomAttributes"), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("clone"), "m_CustomAttributes"), "Add",
new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes"), "Keys"), new CodeVariableReferenceExpression("index")),
new CodeCastExpression(typeof(string), new CodeIndexerExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_CustomAttributes"), new CodeVariableReferenceExpression("index")))))));
#endregion
#endregion
}
#region public static bool operator ==(Element left, Element right)
// public static bool operator ==(Element left, Element right)
// {
// return ((((object)(left)) == null && ((object)(right)) == null) || (((object)(left)) != null && left.Equals(right)));
// }
CodeMemberMethod equalOperator = new CodeMemberMethod();
equalOperator.Comments.Add(new CodeCommentStatement("Equality operator override.", true));
equalOperator.Comments.Add(new CodeCommentStatement("This does not support checking for equality for untyped attributes.", true));
equalOperator.Name = "operator ==";
equalOperator.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
equalOperator.Attributes |= MemberAttributes.Public | MemberAttributes.Static;
equalOperator.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "left"));
equalOperator.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "right"));
equalOperator.ReturnType = new CodeTypeReference(typeof(bool));
CodeBinaryOperatorExpression leftIsNull = new CodeBinaryOperatorExpression(new CodeCastExpression(typeof(object), new CodeVariableReferenceExpression("left")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(null));
CodeBinaryOperatorExpression rightIsNull = new CodeBinaryOperatorExpression(new CodeCastExpression(typeof(object), new CodeVariableReferenceExpression("right")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(null));
CodeBinaryOperatorExpression leftNotNull = new CodeBinaryOperatorExpression(new CodeCastExpression(typeof(object), new CodeVariableReferenceExpression("left")), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
CodeBinaryOperatorExpression leftEquals = new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("left"), "Equals", new CodeVariableReferenceExpression("right")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(true));
equalOperator.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(leftIsNull, CodeBinaryOperatorType.BooleanAnd, rightIsNull), CodeBinaryOperatorType.BooleanOr, new CodeBinaryOperatorExpression(leftNotNull, CodeBinaryOperatorType.BooleanAnd, leftEquals))));
decl.Members.Add(equalOperator);
#endregion
#region public static bool operator !=(Element left, Element right)
// public static bool operator !=(Element left, Element right)
// {
// return ((left == right) == false);
// }
CodeMemberMethod inequalOperator = new CodeMemberMethod();
inequalOperator.Comments.Add(new CodeCommentStatement("Equality operator override.", true));
inequalOperator.Comments.Add(new CodeCommentStatement("This does not support checking for equality for untyped attributes.", true));
inequalOperator.Name = "operator !=";
inequalOperator.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
inequalOperator.Attributes |= MemberAttributes.Public | MemberAttributes.Static;
inequalOperator.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "left"));
inequalOperator.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "right"));
inequalOperator.ReturnType = new CodeTypeReference(typeof(bool));
inequalOperator.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("left"), CodeBinaryOperatorType.ValueEquality, new CodeVariableReferenceExpression("right")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false))));
decl.Members.Add(inequalOperator);
#endregion
#region public override int GetHashCode()
CodeMemberMethod getHashCode = new CodeMemberMethod();
getHashCode.Name = "GetHashCode";
getHashCode.ReturnType = new CodeTypeReference(typeof(int));
getHashCode.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
getHashCode.Attributes |= MemberAttributes.Public | MemberAttributes.Override;
getHashCode.Comments.Add(new CodeCommentStatement("Serves as a hash function for the type, suitable for use in hashing algorithms and data structures like a hash table.", true));
getHashCode.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "GetHashCode")));
#endregion
#region Text
CodeMemberField elementTextNameConst = new CodeMemberField(typeof(string), "ElementTextName");
elementTextNameConst.InitExpression = new CodePrimitiveExpression("#text");
elementTextNameConst.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
elementTextNameConst.Attributes |= MemberAttributes.Public | MemberAttributes.Const;
elementTextNameConst.Comments.Add(new CodeCommentStatement("Represents the referencing name for the inner text of the element.", true));
decl.Members.Add(elementTextNameConst);
CodeMemberField textField = new CodeMemberField(typeof(string), "m_Text");
textField.Comments.Add(new CodeCommentStatement("Represents the inner text of the element.", true));
decl.Members.Add(textField);
CodeMemberProperty textProperty = new CodeMemberProperty();
textProperty.Name = "Text";
textProperty.Attributes &= ~MemberAttributes.AccessMask;
textProperty.Attributes |= MemberAttributes.Public;
textProperty.Type = new CodeTypeReference(typeof(string));
textProperty.Comments.Add(new CodeCommentStatement("TODO: Complete Summary tag documentation."));
textProperty.Comments.Add(new CodeCommentStatement("Represents the inner text of the element.", true));
textProperty.HasSet = true;
textProperty.SetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"), CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
new CodeStatement[] {
new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"), new CodePropertySetValueReferenceExpression()),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnTextChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")))
}));
textProperty.HasGet = true;
textProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text")));
decl.Members.Add(textProperty);
CodeMemberEvent textChangeEvent = new CodeMemberEvent();
textChangeEvent.Name = "TextChanged";
textChangeEvent.Attributes &= ~MemberAttributes.AccessMask;
textChangeEvent.Attributes |= MemberAttributes.Public;
textChangeEvent.Type = new CodeTypeReference(typeof(EventHandler));
textChangeEvent.Comments.Add(new CodeCommentStatement("Raised when the element's inner text is changed.", true));
decl.Members.Add(textChangeEvent);
CodeMemberMethod textChangeInvoker = new CodeMemberMethod();
textChangeInvoker.Name = "OnTextChanged";
textChangeInvoker.Attributes &= ~MemberAttributes.AccessMask;
textChangeInvoker.Attributes |= MemberAttributes.Family;
textChangeInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.EventArgs), "e"));
textChangeInvoker.Comments.Add(new CodeCommentStatement("Raises the event.", true));
textChangeInvoker.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "TextChanged"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeExpressionStatement(new CodeDelegateInvokeExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "TextChanged"), new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("e")))));
decl.Members.Add(textChangeInvoker);
getXml.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"), CodeBinaryOperatorType.IdentityInequality, new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty"))),
new CodeStatement[] {
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "AppendChild", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "CreateTextNode", new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"))))
}));
fromXml.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeFieldReferenceExpression(null, "ElementTextName")), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"), new CodePropertyReferenceExpression(new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeFieldReferenceExpression(null, "ElementTextName")), "Value"))));
equalsExpression = new CodeBinaryOperatorExpression(equalsExpression, CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Text"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(new CodeCastExpression(decl.Name, new CodeVariableReferenceExpression("obj")), "m_Text")));
#endregion
equalsOverride.Statements.Add(new CodeMethodReturnStatement(equalsExpression));
getXml.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("element")));
clone.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("clone")));
decl.Members.Add(getHashCode);
decl.Members.Add(equalsOverride);
decl.Members.Add(fromXml);
decl.Members.Add(getXml);
decl.Members.Add(clone);
CodeMemberField elementNameConst = new CodeMemberField(typeof(string), "ElementName");
elementNameConst.InitExpression = new CodePrimitiveExpression(element.Name);
elementNameConst.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
elementNameConst.Attributes |= MemberAttributes.Public | MemberAttributes.Const;
elementNameConst.Comments.Add(new CodeCommentStatement("Represents the referencing name for the element.", true));
decl.Members.Add(elementNameConst);
// Member and Property to parent
if (parentObject is CodeTypeDeclaration)
{
CodeTypeDeclaration parentDecl = ((CodeTypeDeclaration)(parentObject));
CodeMemberField parentField = new CodeMemberField(parentDecl.Name, "m_Parent" + parentDecl.Name);
parentField.Comments.Add(new CodeCommentStatement("Represents the parent for this element.", true));
CodeMemberProperty parentProperty = new CodeMemberProperty();
parentProperty.Comments.Add(new CodeCommentStatement("Gets the parent for this element.", true));
parentProperty.Name = "Parent" + parentDecl.Name;
parentProperty.Type = new CodeTypeReference(parentDecl.Name);
parentProperty.Attributes &= ~MemberAttributes.AccessMask;
parentProperty.Attributes |= MemberAttributes.Public;
parentProperty.HasGet = true;
parentProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent" + parentDecl.Name)));
parentProperty.HasSet = false;
CodeMemberMethod parentSet = new CodeMemberMethod();
parentSet.Comments.Add(new CodeCommentStatement("Sets a value for the parent for this element.", true));
parentSet.Name = "SetParent" + parentDecl.Name;
parentSet.Attributes &= ~MemberAttributes.AccessMask;
parentSet.Attributes |= MemberAttributes.FamilyOrAssembly;
parentSet.Parameters.Add(new CodeParameterDeclarationExpression(parentDecl.Name, "value"));
parentSet.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent" + parentDecl.Name), new CodeVariableReferenceExpression("value")));
decl.Members.Add(parentField);
decl.Members.Add(parentProperty);
decl.Members.Add(parentSet);
}
indexers = ((CodeTypeMember[])(list.ToArray(typeof(CodeTypeMember))));
return decl;
}
#endregion
#region CreateMemberRef
static CodeBinaryOperatorExpression CreateMemberRef(CodeTypeDeclaration decl,
System.Xml.Schema.XmlSchemaElement element,
decimal maxOccurs,
decimal minOccurs,
CodeMemberMethod getXml,
CodeConstructor fromXml,
CodeTypeMember[] indexers,
CodeMemberMethod clone,
CodeConstructor defaultCtor)
{
string pcName = ToPascalCasing(element.Name);
if (minOccurs == 0)
{
minOccurs = decimal.MaxValue;
}
if (maxOccurs > 1)
{
//public class ElementCollection : System.Collections.CollectionBase, System.Runtime.Serialization.ISerializable, IXmlElementCollection
CodeTypeDeclaration collectionDecl = new CodeTypeDeclaration(pcName + "Collection");
collectionDecl.BaseTypes.Add(typeof(System.Collections.CollectionBase));
collectionDecl.BaseTypes.Add("IXmlElementCollection");
collectionDecl.BaseTypes.Add(typeof(ICloneable));
collectionDecl.Comments.Add(new CodeCommentStatement("This is a typed collection for the " + element.Name + "Collection () element.", true));
CodeFieldReferenceExpression innerListRef = new CodeFieldReferenceExpression(new CodeBaseReferenceExpression(), "InnerList");
CodeStatementCollection MaxAmountReached = new CodeStatementCollection();
CodeStatementCollection MinAmountReached = new CodeStatementCollection();
if (maxOccurs != decimal.MaxValue)
{
CodeMemberField MaxAmountConst = new CodeMemberField(typeof(int), "MaxAmount");
MaxAmountConst.InitExpression = new CodePrimitiveExpression((int)maxOccurs);
MaxAmountConst.Attributes &= ~MemberAttributes.ScopeMask;
MaxAmountConst.Attributes |= MemberAttributes.Const;
collectionDecl.Members.Add(MaxAmountConst);
MaxAmountReached.Add(new CodeCommentStatement(" Check to see if we have reached the maximum amount."));
MaxAmountReached.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(innerListRef, "Count"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(null, "MaxAmount")),
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ApplicationException), new CodePrimitiveExpression("Maximum amount of items reached.")))));
}
if (minOccurs != decimal.MaxValue)
{
CodeMemberField MinAmountConst = new CodeMemberField(typeof(int), "MinAmount");
MinAmountConst.InitExpression = new CodePrimitiveExpression((int)minOccurs);
MinAmountConst.Attributes &= ~MemberAttributes.ScopeMask;
MinAmountConst.Attributes |= MemberAttributes.Const;
collectionDecl.Members.Add(MinAmountConst);
MinAmountReached.Add(new CodeCommentStatement(" Check to see if we have reached the minimum amount."));
MinAmountReached.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(innerListRef, "Count"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(null, "MinAmount")),
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ApplicationException), new CodePrimitiveExpression("Minimum amount of items reached.")))));
}
CodeMemberField parentField = new CodeMemberField(decl.Name, "m_Parent");
parentField.Comments.Add(new CodeCommentStatement("The parent element for this collection.", true));
collectionDecl.Members.Add(parentField);
#region public int Add(Element value)
// public int Add(Element value)
// {
// if (base.InnerList.Count == MaxAmount)
// {
// throw new ApplicationException("Maximum amount of items reached.");
// }
//
// value.SetParent(this.m_Parent);
//
// int location = base.InnerList.Add(value);
//
// this.OnCollectionChanged(EventArgs.Empty);
//
// return location;
// }
CodeMemberMethod addMethod = new CodeMemberMethod();
addMethod.Name = "Add";
addMethod.ReturnType = new CodeTypeReference(typeof(int));
addMethod.Attributes &= ~MemberAttributes.AccessMask;
addMethod.Attributes |= MemberAttributes.Public;
addMethod.Parameters.Add(new CodeParameterDeclarationExpression(pcName + "Element", "value"));
addMethod.Comments.Add(new CodeCommentStatement("Adds a to the end of the collection.", true));
addMethod.Statements.AddRange(MaxAmountReached);
addMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("value"), "SetParent" + decl.Name, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent")));
addMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(int), "location", new CodeMethodInvokeExpression(innerListRef, "Add", new CodeVariableReferenceExpression("value"))));
addMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
addMethod.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("location")));
collectionDecl.Members.Add(addMethod);
#endregion
#region public bool Contains(Element value)
// public bool Contains(Element value)
// {
// return base.InnerList.Contains(value);
// }
CodeMemberMethod containsMethod = new CodeMemberMethod();
containsMethod.Name = "Contains";
containsMethod.ReturnType = new CodeTypeReference(typeof(bool));
containsMethod.Attributes &= ~MemberAttributes.AccessMask;
containsMethod.Attributes |= MemberAttributes.Public;
containsMethod.Parameters.Add(new CodeParameterDeclarationExpression(pcName + "Element", "value"));
containsMethod.Comments.Add(new CodeCommentStatement("Determines whether the object is in the collection.", true));
containsMethod.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(innerListRef, "Contains", new CodeVariableReferenceExpression("value"))));
collectionDecl.Members.Add(containsMethod);
#endregion
#region public int IndexOf(Element value)
// public int IndexOf(Element value)
// {
// return base.InnerList.IndexOf(value);
// }
CodeMemberMethod indexOfMethod = new CodeMemberMethod();
indexOfMethod.Name = "IndexOf";
indexOfMethod.ReturnType = new CodeTypeReference(typeof(int));
indexOfMethod.Attributes &= ~MemberAttributes.AccessMask;
indexOfMethod.Attributes |= MemberAttributes.Public;
indexOfMethod.Parameters.Add(new CodeParameterDeclarationExpression(pcName + "Element", "value"));
indexOfMethod.Comments.Add(new CodeCommentStatement("Returns the zero-based index of the first occurrence of the object in the collection.", true));
indexOfMethod.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(innerListRef, "IndexOf", new CodeVariableReferenceExpression("value"))));
collectionDecl.Members.Add(indexOfMethod);
#endregion
#region public void Insert(int index, Element value)
// public void Insert(int index, Element value)
// {
// if (base.InnerList.Count == MaxAmount)
// {
// throw new ApplicationException("Maximum amount of items reached.");
// }
//
// value.SetParent(this.m_Parent);
//
// base.InnerList.Insert(index, value);
//
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod insertMethod = new CodeMemberMethod();
insertMethod.Name = "Insert";
insertMethod.ReturnType = new CodeTypeReference(typeof(void));
insertMethod.Attributes &= ~MemberAttributes.AccessMask;
insertMethod.Attributes |= MemberAttributes.Public;
insertMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "index"));
insertMethod.Parameters.Add(new CodeParameterDeclarationExpression(pcName + "Element", "value"));
insertMethod.Comments.Add(new CodeCommentStatement("Inserts an object of type into the collection at the specified index.", true));
insertMethod.Statements.AddRange(MaxAmountReached);
insertMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("value"), "SetParent" + decl.Name, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent")));
insertMethod.Statements.Add(new CodeMethodInvokeExpression(innerListRef, "Insert", new CodeVariableReferenceExpression("index"), new CodeVariableReferenceExpression("value")));
insertMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(insertMethod);
#endregion
#region public void Remove(Element value)
// public void Remove(Element value)
// {
// if (base.InnerList.Count == MinAmount)
// {
// throw new ApplicationException("Minimum amount of items reached.");
// }
//
// value.SetParent(null);
//
// base.InnerList.Remove(value);
//
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod removeMethod = new CodeMemberMethod();
removeMethod.Name = "Remove";
removeMethod.ReturnType = new CodeTypeReference(typeof(void));
removeMethod.Attributes &= ~MemberAttributes.AccessMask;
removeMethod.Attributes |= MemberAttributes.Public;
removeMethod.Parameters.Add(new CodeParameterDeclarationExpression(pcName + "Element", "value"));
removeMethod.Comments.Add(new CodeCommentStatement("Removes the first occurrence of a specific object from the collection.", true));
removeMethod.Statements.AddRange(MinAmountReached);
removeMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("value"), "SetParent" + decl.Name, new CodePrimitiveExpression(null)));
removeMethod.Statements.Add(new CodeMethodInvokeExpression(innerListRef, "Remove", new CodeVariableReferenceExpression("value")));
removeMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(removeMethod);
#endregion
#region public new void RemoveAt(int index)
// public new void RemoveAt(int index)
// {
// if (base.InnerList.Count == MinAmount)
// {
// throw new ApplicationException("Minimum amount of items reached.");
// }
//
// this[index].SetParent(null);
//
// base.InnerList.RemoveAt(index);
//
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod removeAtMethod = new CodeMemberMethod();
removeAtMethod.Name = "RemoveAt";
removeAtMethod.ReturnType = new CodeTypeReference(typeof(void));
removeAtMethod.Attributes &= ~MemberAttributes.AccessMask;
removeAtMethod.Attributes |= MemberAttributes.Public;
removeAtMethod.Attributes |= MemberAttributes.New;
removeAtMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "index"));
removeAtMethod.Comments.Add(new CodeCommentStatement("Removes the at the specific index from the collection.", true));
removeAtMethod.Statements.AddRange(MinAmountReached);
removeAtMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeIndexerExpression(new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("index")), "SetParent" + decl.Name, new CodePrimitiveExpression(null)));
removeAtMethod.Statements.Add(new CodeMethodInvokeExpression(innerListRef, "RemoveAt", new CodeVariableReferenceExpression("index")));
removeAtMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(removeAtMethod);
#endregion
#region public Element this[int index]
// public Element this[int index]
// {
// get
// {
// return base.InnerList[index] as Element;
// }
// set
// {
// base.InnerList[index] = value;
// }
// }
CodeMemberProperty thisProp = new CodeMemberProperty();
thisProp.Comments.Add(new CodeCommentStatement("Gets or sets the at the specific index.", true));
thisProp.Name = "Item";
thisProp.Type = new CodeTypeReference(pcName + "Element");
thisProp.Attributes &= ~MemberAttributes.AccessMask;
thisProp.Attributes |= MemberAttributes.Public;
thisProp.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "index"));
thisProp.HasGet = true;
thisProp.GetStatements.Add(new CodeMethodReturnStatement(new CodeCastExpression(pcName + "Element", new CodeIndexerExpression(innerListRef, new CodeVariableReferenceExpression("index")))));
thisProp.HasSet = true;
thisProp.SetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeIndexerExpression(new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("index")), CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
new CodeStatement[] {
new CodeAssignStatement(new CodeIndexerExpression(innerListRef, new CodeVariableReferenceExpression("index")), new CodeVariableReferenceExpression("value")),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")))
}));
collectionDecl.Members.Add(thisProp);
#endregion
#region internal ElementCollection(Parent parent)
CodeConstructor defaultConstructor = new CodeConstructor();
defaultConstructor.Attributes &= ~MemberAttributes.AccessMask;
defaultConstructor.Attributes |= MemberAttributes.FamilyOrAssembly;
defaultConstructor.Comments.Add(new CodeCommentStatement("Default internal constructor.", true));
defaultConstructor.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "parent"));
defaultConstructor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent"), new CodeVariableReferenceExpression("parent")));
collectionDecl.Members.Add(defaultConstructor);
#endregion
#region System.Xml.XmlElement[] IXmlElementCollection.GetXml()
//System.Xml.XmlElement[] IXmlElementCollection.GetXml(System.Xml.XmlDocument document)
//{
// // Check min/max bounds
// System.Xml.XmlElement[] elements = new System.Xml.XmlElement[base.InnerList.Count];
//
// for (int index = 0; index < base.InnerList.Count; index++)
// {
// elements[index] = ((IXmlElement)(base.InnerList[index])).GetXml(document);
// }
//
// return elements;
//}
CodeMemberMethod getXmlElements = new CodeMemberMethod();
getXmlElements.Name = "GetXml";
getXmlElements.PrivateImplementationType = new CodeTypeReference("IXmlElementCollection");
getXmlElements.ReturnType = new CodeTypeReference(new CodeTypeReference(typeof(System.Xml.XmlElement)), 1);
getXmlElements.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlDocument), "document"));
getXmlElements.Comments.Add(new CodeCommentStatement("This method is used to serialize the element collection to XML DOM.", true));
// if count is not 0.
CodeBinaryOperatorExpression checkZero = new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(innerListRef, "Count"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(0));
CodeBinaryOperatorExpression minExpression = null, maxExpression = null;
if (MinAmountReached.Count != 0)
{
minExpression = new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(innerListRef, "Count"), CodeBinaryOperatorType.LessThan, new CodeFieldReferenceExpression(null, "MinAmount"));
}
if (MaxAmountReached.Count != 0)
{
maxExpression = new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(innerListRef, "Count"), CodeBinaryOperatorType.GreaterThan, new CodeFieldReferenceExpression(null, "MaxAmount"));
}
CodeBinaryOperatorExpression boundsCheck = null;
if (minExpression != null)
{
if (maxExpression != null)
{
boundsCheck = new CodeBinaryOperatorExpression(minExpression, CodeBinaryOperatorType.BooleanOr, maxExpression);
}
else
{
boundsCheck = minExpression;
}
}
else if (maxExpression != null)
{
boundsCheck = maxExpression;
}
if (boundsCheck != null)
{
getXmlElements.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(checkZero, CodeBinaryOperatorType.BooleanAnd, boundsCheck), new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ApplicationException), new CodePrimitiveExpression("Can not serialize element set since it does not comply with minimum / maximum amounts")))));
}
getXmlElements.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Xml.XmlElement[]), "elements", new CodeArrayCreateExpression(typeof(System.Xml.XmlElement[]), new CodePropertyReferenceExpression(innerListRef, "Count"))));
getXmlElements.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(innerListRef, "Count")), new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression("elements"), new CodeVariableReferenceExpression("index")), new CodeMethodInvokeExpression(new CodeCastExpression("IXmlElement", new CodeIndexerExpression(innerListRef, new CodeVariableReferenceExpression("index"))), "GetXml", new CodeVariableReferenceExpression("document")))));
getXmlElements.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("elements")));
collectionDecl.Members.Add(getXmlElements);
#endregion
#region internal ElementCollection(System.Xml.XmlElement parentElement, Parent parent)
// internal ElementCollection(System.Xml.XmlElement parentElement, Parent parent)
// {
// this.m_Parent = parent;
//
// for (int index = 0; index < parentElement.ChildNodes.Count; index++)
// {
// if (parentElement.ChildNodes[index].GetType() == typeof(System.Xml.XmlElement) &&
// parentElement.ChildNodes[index].Name == "Element")
// {
// base.InnerList.Add(new Element(((System.Xml.XmlElement)(parentElement.ChildNodes[index]))));
// }
// }
// }
CodeConstructor xmlLoadCtor = new CodeConstructor();
xmlLoadCtor.Attributes &= ~MemberAttributes.AccessMask;
xmlLoadCtor.Attributes |= MemberAttributes.FamilyOrAssembly;
xmlLoadCtor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Xml.XmlElement), "parentElement"));
xmlLoadCtor.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "parent"));
xmlLoadCtor.Comments.Add(new CodeCommentStatement("This constructor is used to deserialize the element collection from XML DOM.", true));
xmlLoadCtor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent"), new CodeVariableReferenceExpression("parent")));
CodeIterationStatement elementIteration = new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("parentElement"), "ChildNodes"), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))));
CodeVariableReferenceExpression parentElement = new CodeVariableReferenceExpression("parentElement");
CodePropertyReferenceExpression parentElementChildNodes = new CodePropertyReferenceExpression(parentElement, "ChildNodes");
CodeIndexerExpression parentElementChildNodesIndex = new CodeIndexerExpression(parentElementChildNodes, new CodeVariableReferenceExpression("index"));
CodeConditionStatement checkValidElement = new CodeConditionStatement(new CodeBinaryOperatorExpression(
new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(parentElementChildNodesIndex, "GetType"), CodeBinaryOperatorType.ValueEquality, new CodeTypeOfExpression(typeof(System.Xml.XmlElement))),
CodeBinaryOperatorType.BooleanAnd,
new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(parentElementChildNodesIndex, "Name"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(ToPascalCasing(element.Name) + "Element"), "ElementName"))));
checkValidElement.TrueStatements.Add(new CodeMethodInvokeExpression(innerListRef, "Add", new CodeObjectCreateExpression(pcName + "Element", new CodeCastExpression(typeof(System.Xml.XmlElement), parentElementChildNodesIndex))));
elementIteration.Statements.Add(checkValidElement);
xmlLoadCtor.Statements.Add(elementIteration);
collectionDecl.Members.Add(xmlLoadCtor);
#endregion
#region public object Clone()
// public object Clone()
// {
// ElementCollection collection = new ElementCollection();
//
// for (int index = 0; index < this.Count; index++)
// {
// collection.Add(((Element)(((Element)(base.InnerList[index])).Clone()));
// }
//
// return collection;
// }
CodeMemberMethod collectionClone = new CodeMemberMethod();
collectionClone.Name = "Clone";
collectionClone.ReturnType = new CodeTypeReference(typeof(object));
collectionClone.Attributes &= ~MemberAttributes.AccessMask;
collectionClone.Attributes |= MemberAttributes.Public;
collectionClone.Comments.Add(new CodeCommentStatement("This method is used to clone the collection.", true));
collectionClone.Statements.Add(new CodeVariableDeclarationStatement(pcName + "Collection", "collection", new CodeObjectCreateExpression(pcName + "Collection", new CodePrimitiveExpression(null))));
collectionClone.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(innerListRef, "Count")), new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("collection"), "Add", new CodeCastExpression(pcName + "Element", new CodeMethodInvokeExpression(new CodeCastExpression(pcName + "Element", new CodeIndexerExpression(innerListRef, new CodeVariableReferenceExpression("index"))), "Clone"))))));
collectionClone.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("collection")));
collectionDecl.Members.Add(collectionClone);
#endregion
#region internal SetParent(Parent parent)
// public void SetParent(Parent parent)
// {
// for (int index = 0; index < this.Count; index++)
// {
// ((Element)(this[index])).SetParent(parent);
// }
//
// m_Parent = parent;
// }
CodeMemberMethod parentSet = new CodeMemberMethod();
parentSet.Comments.Add(new CodeCommentStatement("Sets a value for the parent for all elements in this collection.", true));
parentSet.Name = "SetParent" + decl.Name;
parentSet.Attributes &= ~MemberAttributes.AccessMask;
parentSet.Attributes |= MemberAttributes.FamilyOrAssembly;
parentSet.Parameters.Add(new CodeParameterDeclarationExpression(decl.Name, "parent"));
parentSet.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(innerListRef, "Count")), new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeCastExpression(pcName + "Element", new CodeIndexerExpression(new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("index"))), "SetParent" + decl.Name, new CodeVariableReferenceExpression("parent")))));
parentSet.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Parent"), new CodeVariableReferenceExpression("parent")));
collectionDecl.Members.Add(parentSet);
#endregion
#region public bool Equals(object obj)
// public bool Equals(object obj)
// {
// if (obj == null)
// {
// return false;
// }
//
// try
// {
// for (int index = 0; index < this.Count; index++)
// {
// if (this[index] != ((ElementCollection)(obj)[index]))
// {
// return false;
// }
// }
//
// return true;
// }
// catch (ArgumentOutOfRangeException)
// {
// return false;
// }
// catch (InvalidCastException)
// {
// return false;
// }
// }
CodeMemberMethod equals = new CodeMemberMethod();
equals.Name = "Equals";
equals.ReturnType = new CodeTypeReference(typeof(bool));
equals.Attributes &= ~MemberAttributes.AccessMask;
equals.Attributes &= ~MemberAttributes.ScopeMask;
equals.Attributes |= MemberAttributes.Public;
equals.Attributes |= MemberAttributes.Override;
equals.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj"));
equals.Comments.Add(new CodeCommentStatement("This method is used to check element collection equality.", true));
equals.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("obj"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(null)), new CodeMethodReturnStatement(new CodePrimitiveExpression(false))));
equals.Statements.Add(new CodeTryCatchFinallyStatement(
new CodeStatement[] {
new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(innerListRef, "Count")), new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeIndexerExpression(new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("index")), CodeBinaryOperatorType.IdentityInequality, new CodeIndexerExpression(new CodeCastExpression(pcName + "Collection", new CodeVariableReferenceExpression("obj")), new CodeVariableReferenceExpression("index"))), new CodeMethodReturnStatement(new CodePrimitiveExpression(false)))),
new CodeMethodReturnStatement(new CodePrimitiveExpression(true))
},
new CodeCatchClause[]
{
new CodeCatchClause(/*"lengthsArentSame"*/null, new CodeTypeReference(typeof(ArgumentOutOfRangeException)), new CodeMethodReturnStatement(new CodePrimitiveExpression(false))),
new CodeCatchClause(/*"badObject"*/null, new CodeTypeReference(typeof(InvalidCastException)), new CodeMethodReturnStatement(new CodePrimitiveExpression(false)))
}));
collectionDecl.Members.Add(equals);
#endregion
#region public static bool operator ==(ElementCollection left, ElementCollection right)
// public static bool operator ==(ElementCollection left, ElementCollection right)
// {
// return ((((object)(left)) == null && ((object)(right)) == null) || (((object)(left)) != null && left.Equals(right)));
// }
CodeMemberMethod equalOperator = new CodeMemberMethod();
equalOperator.Comments.Add(new CodeCommentStatement("Equality operator override.", true));
equalOperator.Name = "operator ==";
equalOperator.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
equalOperator.Attributes |= MemberAttributes.Public | MemberAttributes.Static;
equalOperator.Parameters.Add(new CodeParameterDeclarationExpression(collectionDecl.Name, "left"));
equalOperator.Parameters.Add(new CodeParameterDeclarationExpression(collectionDecl.Name, "right"));
equalOperator.ReturnType = new CodeTypeReference(typeof(bool));
CodeBinaryOperatorExpression leftIsNull = new CodeBinaryOperatorExpression(new CodeCastExpression(typeof(object), new CodeVariableReferenceExpression("left")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(null));
CodeBinaryOperatorExpression rightIsNull = new CodeBinaryOperatorExpression(new CodeCastExpression(typeof(object), new CodeVariableReferenceExpression("right")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(null));
CodeBinaryOperatorExpression leftNotNull = new CodeBinaryOperatorExpression(new CodeCastExpression(typeof(object), new CodeVariableReferenceExpression("left")), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
CodeBinaryOperatorExpression leftEquals = new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("left"), "Equals", new CodeVariableReferenceExpression("right")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(true));
equalOperator.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(leftIsNull, CodeBinaryOperatorType.BooleanAnd, rightIsNull), CodeBinaryOperatorType.BooleanOr, new CodeBinaryOperatorExpression(leftNotNull, CodeBinaryOperatorType.BooleanAnd, leftEquals))));
collectionDecl.Members.Add(equalOperator);
#endregion
#region public static bool operator !=(ElementCollection left, ElementCollection right)
// public static bool operator !=(ElementCollection left, ElementCollection right)
// {
// return ((left == right) == false);
// }
CodeMemberMethod inequalOperator = new CodeMemberMethod();
inequalOperator.Comments.Add(new CodeCommentStatement("Equality operator override.", true));
inequalOperator.Name = "operator !=";
inequalOperator.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
inequalOperator.Attributes |= MemberAttributes.Public | MemberAttributes.Static;
inequalOperator.Parameters.Add(new CodeParameterDeclarationExpression(collectionDecl.Name, "left"));
inequalOperator.Parameters.Add(new CodeParameterDeclarationExpression(collectionDecl.Name, "right"));
inequalOperator.ReturnType = new CodeTypeReference(typeof(bool));
inequalOperator.Statements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("left"), CodeBinaryOperatorType.ValueEquality, new CodeVariableReferenceExpression("right")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false))));
collectionDecl.Members.Add(inequalOperator);
#endregion
#region public event EventHandler CollectionChanged;
CodeMemberEvent collectionChangedEvent = new CodeMemberEvent();
collectionChangedEvent.Name = "CollectionChanged";
collectionChangedEvent.Type = new CodeTypeReference(typeof(EventHandler));
collectionChangedEvent.Attributes &= ~MemberAttributes.AccessMask;
collectionChangedEvent.Attributes |= MemberAttributes.Public;
collectionChangedEvent.Comments.Add(new CodeCommentStatement("This event is invoked whenever the collection has items added to it or removed from it.", true));
collectionDecl.Members.Add(collectionChangedEvent);
#endregion
#region public void OnCollectionChanged(EventArgs e)
// public void OnCollectionChanged(EventArgs e)
// {
// if (CollectionChanged != null)
// {
// CollectionChanged(this, e);
// }
// }
CodeMemberMethod onCollectionChanged = new CodeMemberMethod();
onCollectionChanged.Name = "OnCollectionChanged";
onCollectionChanged.ReturnType = new CodeTypeReference(typeof(void));
onCollectionChanged.Attributes &= ~MemberAttributes.AccessMask;
onCollectionChanged.Attributes |= MemberAttributes.Public;
onCollectionChanged.Parameters.Add(new CodeParameterDeclarationExpression(typeof(EventArgs), "e"));
onCollectionChanged.Comments.Add(new CodeCommentStatement("Invokes the event.", true));
onCollectionChanged.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "CollectionChanged"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeExpressionStatement(new CodeDelegateInvokeExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "CollectionChanged"), new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("e")))));
collectionDecl.Members.Add(onCollectionChanged);
#endregion
#region public override int GetHashCode()
CodeMemberMethod getHashCode = new CodeMemberMethod();
getHashCode.Name = "GetHashCode";
getHashCode.ReturnType = new CodeTypeReference(typeof(int));
getHashCode.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
getHashCode.Attributes |= MemberAttributes.Public | MemberAttributes.Override;
getHashCode.Comments.Add(new CodeCommentStatement("Serves as a hash function for the type, suitable for use in hashing algorithms and data structures like a hash table.", true));
getHashCode.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "GetHashCode")));
collectionDecl.Members.Add(getHashCode);
#endregion
#region protected override void OnInsertComplete(int index, object value)
// protected override void OnInsertComplete(int index, object value)
// {
// base.OnInsertComplete (index, value);
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod onInsertComplete = new CodeMemberMethod();
onInsertComplete.Name = "OnInsertComplete";
onInsertComplete.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
onInsertComplete.Attributes |= MemberAttributes.Family | MemberAttributes.Override;
onInsertComplete.Parameters.AddRange(
new CodeParameterDeclarationExpression[]
{
new CodeParameterDeclarationExpression(typeof(int), "index"),
new CodeParameterDeclarationExpression(typeof(object), "value")
});
onInsertComplete.ReturnType = new CodeTypeReference(typeof(void));
onInsertComplete.Comments.Add(new CodeCommentStatement("Used to catch insertions done via the interface.", true));
onInsertComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "OnInsertComplete", new CodeVariableReferenceExpression("index"), new CodeVariableReferenceExpression("value")));
onInsertComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(onInsertComplete);
#endregion
#region protected override void OnClearComplete()
// protected override void OnClearComplete()
// {
// base.OnClearComplete ();
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod onClearComplete = new CodeMemberMethod();
onClearComplete.Name = "OnClearComplete";
onClearComplete.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
onClearComplete.Attributes |= MemberAttributes.Family | MemberAttributes.Override;
onClearComplete.ReturnType = new CodeTypeReference(typeof(void));
onClearComplete.Comments.Add(new CodeCommentStatement("Used to catch clearing done via the interface.", true));
onClearComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "OnClearComplete"));
onClearComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(onClearComplete);
#endregion
#region protected override void OnRemoveComplete(int index, object value)
// protected override void OnRemoveComplete(int index, object value)
// {
// base.OnRemoveComplete (index, value);
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod onRemoveComplete = new CodeMemberMethod();
onRemoveComplete.Name = "OnRemoveComplete";
onRemoveComplete.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
onRemoveComplete.Attributes |= MemberAttributes.Family | MemberAttributes.Override;
onRemoveComplete.Parameters.AddRange(
new CodeParameterDeclarationExpression[]
{
new CodeParameterDeclarationExpression(typeof(int), "index"),
new CodeParameterDeclarationExpression(typeof(object), "value")
});
onRemoveComplete.ReturnType = new CodeTypeReference(typeof(void));
onRemoveComplete.Comments.Add(new CodeCommentStatement("Used to catch insertions done via the interface.", true));
onRemoveComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "OnRemoveComplete", new CodeVariableReferenceExpression("index"), new CodeVariableReferenceExpression("value")));
onRemoveComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(onRemoveComplete);
#endregion
#region protected override void OnSetComplete(int index, object oldValue, object newValue)
// protected override void OnSetComplete(int index, object oldValue, object newValue)
// {
// base.OnSetComplete (index, oldValue, newValue);
// this.OnCollectionChanged(EventArgs.Empty);
// }
CodeMemberMethod onSetComplete = new CodeMemberMethod();
onSetComplete.Name = "OnSetComplete";
onSetComplete.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
onSetComplete.Attributes |= MemberAttributes.Family | MemberAttributes.Override;
onSetComplete.Parameters.AddRange(
new CodeParameterDeclarationExpression[]
{
new CodeParameterDeclarationExpression(typeof(int), "index"),
new CodeParameterDeclarationExpression(typeof(object), "oldValue"),
new CodeParameterDeclarationExpression(typeof(object), "newValue")
});
onSetComplete.ReturnType = new CodeTypeReference(typeof(void));
onSetComplete.Comments.Add(new CodeCommentStatement("Used to catch insertions done via the interface.", true));
onSetComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "OnSetComplete", new CodeVariableReferenceExpression("index"), new CodeVariableReferenceExpression("oldValue"), new CodeVariableReferenceExpression("newValue")));
onSetComplete.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnCollectionChanged", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")));
collectionDecl.Members.Add(onSetComplete);
#endregion
#region protected override void OnValidate(object value)
// protected override void OnValidate(object value)
// {
// base.OnValidate (value);
//
// if (value.GetType() != typeof(NavigateToElement) &&
// !value.GetType().IsSubclassOf(typeof(NavigateToElement)))
// {
// throw new System.ArgumentException("Can not convert type " + value.GetType().FullName + " to type NavigateToElement.");
// }
// }
CodeMemberMethod onValidate = new CodeMemberMethod();
onValidate.Name = "OnValidate";
onValidate.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
onValidate.Attributes |= MemberAttributes.Family | MemberAttributes.Override;
onValidate.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "value"));
onValidate.ReturnType = new CodeTypeReference(typeof(void));
onValidate.Comments.Add(new CodeCommentStatement("Used to catch insertions done via the interface.", true));
onValidate.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "OnValidate", new CodeVariableReferenceExpression("value")));
onValidate.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("value"), "GetType"), CodeBinaryOperatorType.IdentityInequality, new CodeTypeOfExpression(pcName + "Element")), CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(new CodeMethodInvokeExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("value"), "GetType"), "IsSubclassOf", new CodeTypeOfExpression(pcName + "Element")), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false))),
new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(ArgumentException), new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(string)), "Concat", new CodePrimitiveExpression("Can not convert type "), new CodePropertyReferenceExpression(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("value"), "GetType"), "FullName"), new CodePrimitiveExpression(" to type " + pcName + "Element.")) ))));
collectionDecl.Members.Add(onValidate);
#endregion
collectionDecl.Members.AddRange(indexers);
decl.Members.Add(collectionDecl);
clone.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("clone"), "m_" + pcName + "s"), new CodeCastExpression(pcName + "Collection", new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName + "s"), "Clone"))));
clone.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("clone"), "m_" + pcName + "s"), "SetParent" + decl.Name, new CodeVariableReferenceExpression("clone")));
CodeMemberField elementsField = new CodeMemberField(new CodeTypeReference(pcName + "Collection"), "m_" + pcName + "s");
elementsField.Comments.Add(new CodeCommentStatement("This field holds the collection of objects.", true));
decl.Members.Add(elementsField);
CodeMemberProperty elementsProp = new CodeMemberProperty();
elementsProp.Name = pcName + "s";
elementsProp.Type = new CodeTypeReference(pcName + "Collection");
elementsProp.Attributes &= ~MemberAttributes.AccessMask;
elementsProp.Attributes |= MemberAttributes.Public;
elementsProp.Comments.Add(new CodeCommentStatement("Gets the collection of objects.", true));
elementsProp.HasGet = true;
elementsProp.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName + "s")));
elementsProp.HasSet = false;
decl.Members.Add(elementsProp);
defaultCtor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName + "s"), new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Create" + pcName + "Collection")));
// protected virtual ElementCollection CreateElementCollection()
// {
// return new ElementCollection(this);
// }
CodeMemberMethod collectionCreate = new CodeMemberMethod();
collectionCreate.Name = "Create" + pcName + "Collection";
collectionCreate.Attributes &= ~MemberAttributes.AccessMask;
collectionCreate.Attributes |= MemberAttributes.Family;
collectionCreate.Attributes &= ~MemberAttributes.ScopeMask;
collectionCreate.ReturnType = new CodeTypeReference(pcName + "Collection");
collectionCreate.Statements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(pcName + "Collection", new CodeThisReferenceExpression())));
decl.Members.Add(collectionCreate);
// subElements = ((IXmlElementCollection)(collection)).GetXml(document);
//
// for (int index = 0; index < subElements.Length; index++)
// {
// element.AppendChild(subElements[index]);
// }
getXml.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Xml.XmlElement[]), ToCamelCasing(pcName + "s"), new CodeMethodInvokeExpression(new CodeCastExpression("IXmlElementCollection", new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), pcName + "s")), "GetXml", new CodeVariableReferenceExpression("document"))));
getXml.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(ToCamelCasing(pcName + "s")), "Length")), new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "AppendChild", new CodeIndexerExpression(new CodeVariableReferenceExpression(ToCamelCasing(pcName + "s")), new CodeVariableReferenceExpression("index"))))));
// collection = new ElementCollection(element);
fromXml.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName + "s"), new CodeObjectCreateExpression(pcName + "Collection", new CodeVariableReferenceExpression("element"), new CodeThisReferenceExpression())));
return new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName + "s"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(new CodeCastExpression(decl.Name, new CodeVariableReferenceExpression("obj")), "m_" + pcName + "s"));
}
else
{
CodeMemberField elementField = new CodeMemberField(new CodeTypeReference(pcName + "Element"), "m_" + pcName);
elementField.Comments.Add(new CodeCommentStatement("This field holds the object in this object.", true));
decl.Members.Add(elementField);
CodeMemberProperty elementProp = new CodeMemberProperty();
elementProp.Name = pcName;
elementProp.Type = new CodeTypeReference(pcName + "Element");
elementProp.Attributes &= ~MemberAttributes.AccessMask;
elementProp.Attributes |= MemberAttributes.Public;
elementProp.HasGet = true;
elementProp.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName)));
elementProp.HasSet = true;
elementProp.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName), new CodePropertySetValueReferenceExpression()));
elementProp.Comments.Add(new CodeCommentStatement("Gets the object contained in this object.", true));
decl.Members.Add(elementProp);
// if (AnElement != null)
// {
// element.AppendChild(((IXmlElement)(AnElement)).GetXml(document));
// }
getXml.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), pcName), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "AppendChild", new CodeMethodInvokeExpression(new CodeCastExpression("IXmlElement", new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), pcName)), "GetXml", new CodeVariableReferenceExpression("document"))))));
// if (element["AnElement"] != null)
// {
// AnElement = new Element(element["AnElement"]);
// }
fromXml.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeIndexerExpression(new CodeVariableReferenceExpression("element"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(ToPascalCasing(element.Name) + "Element"), "ElementName")), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), pcName), new CodeObjectCreateExpression(pcName + "Element", new CodeIndexerExpression(new CodeVariableReferenceExpression("element"), new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(ToPascalCasing(element.Name) + "Element"), "ElementName"))))));
// if (this.m_Element != null)
// {
// clone.m_Element = ((ElementType)(this.m_Element.Clone()));
// }
clone.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), elementField.Name), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("clone"), elementField.Name), new CodeCastExpression(elementField.Type, new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), elementField.Name), "Clone")))));
return new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(new CodeCastExpression(decl.Name, new CodeVariableReferenceExpression("obj")), "m_" + pcName));
}
}
#endregion
#region CreateChoice
static CodeBinaryOperatorExpression CreateChoice(CodeTypeDeclaration decl,
System.Xml.Schema.XmlSchemaChoice choiceElement,
CodeMemberMethod getXml,
CodeConstructor fromXml,
CodeMemberMethod clone,
out CodeTypeMember[] indexers,
CodeConstructor defaultCtor)
{
return CreateSquenceAndChoice(decl, choiceElement, getXml, fromXml, clone, out indexers, defaultCtor);
}
#endregion
#region Unsupported Complex Elements
static void CreateAny(System.Xml.Schema.XmlSchemaAny anyElement)
{
throw new NotSupportedException();
}
static void CreateAll(System.Xml.Schema.XmlSchemaAll allElement)
{
throw new NotSupportedException();
}
static void CreateGroupRef(System.Xml.Schema.XmlSchemaGroupRef groupRefElement)
{
throw new NotSupportedException();
}
#endregion
#region CreateSequence
static CodeBinaryOperatorExpression CreateSequence(CodeTypeDeclaration decl,
XmlSchemaSequence sequenceElement,
CodeMemberMethod getXml,
CodeConstructor fromXml,
CodeMemberMethod clone,
out CodeTypeMember[] indexers,
CodeConstructor defaultCtor)
{
return CreateSquenceAndChoice(decl, sequenceElement, getXml, fromXml, clone, out indexers, defaultCtor);
}
#endregion
#region CreateSquenceAndChoice
static CodeBinaryOperatorExpression CreateSquenceAndChoice(CodeTypeDeclaration decl,
XmlSchemaGroupBase groupElement,
CodeMemberMethod getXml,
CodeConstructor fromXml,
CodeMemberMethod clone,
out CodeTypeMember[] indexers,
CodeConstructor defaultCtor)
{
CodeBinaryOperatorExpression equals = null;
System.Collections.ArrayList list = new System.Collections.ArrayList();
tabulator += "\t";
foreach (System.Xml.Schema.XmlSchemaElement element in groupElement.Items)
{
CodeTypeMember[] tempMembers = new CodeTypeMember[0];
if (element.SchemaType is XmlSchemaComplexType)
{
Console.WriteLine(tabulator + "[ " + (groupElement.Items.IndexOf(element) + 1) + " / " + groupElement.Items.Count + " ] " + element.Name);
decl.Members.Add(CreateComplexElement(decl, element, out tempMembers));
if (groupElement is XmlSchemaSequence)
{
CodeBinaryOperatorExpression sequenceCondition = CreateMemberRef(decl, element, element.MaxOccurs, element.MinOccurs, getXml, fromXml, tempMembers, clone, defaultCtor);
equals = (equals != null ? new CodeBinaryOperatorExpression(equals, CodeBinaryOperatorType.BooleanAnd, sequenceCondition) : sequenceCondition);
}
else
{
CodeBinaryOperatorExpression choiceCondition = CreateMemberRef(decl, element, groupElement.MaxOccurs, groupElement.MinOccurs, getXml, fromXml, tempMembers, clone, defaultCtor);
equals = (equals != null ? new CodeBinaryOperatorExpression(equals, CodeBinaryOperatorType.BooleanAnd, choiceCondition) : choiceCondition);
}
}
else
{
CodeBinaryOperatorExpression simpleCondition;
Type t = CreateProperty(decl,
element.Name,
element.SchemaTypeName.Name,
out tempMembers,
clone,
out simpleCondition);
CreateSimpleElementGetXml(decl, element, getXml, t);
CreateSimpleElementFromXml(decl, element, fromXml, t);
equals = (equals != null ? new CodeBinaryOperatorExpression(equals, CodeBinaryOperatorType.BooleanAnd, simpleCondition) : simpleCondition);
list.AddRange(tempMembers);
}
}
tabulator = tabulator.Substring(0, tabulator.Length - 1);
indexers = ((CodeTypeMember[])(list.ToArray(typeof(CodeTypeMember))));
return equals;
}
#endregion
#region CreateProperty
static Type CreateProperty(CodeTypeDeclaration type,
string name,
string dataType,
out CodeTypeMember[] indexers,
CodeMemberMethod clone,
out CodeBinaryOperatorExpression condition)
{
string pcName = ToPascalCasing(name);
System.Collections.ArrayList listOfIndexers = new System.Collections.ArrayList();
Type attType = ((XmlSchemaDatatype)(miFromTypeName.Invoke(null, new object[] {dataType}))).ValueType;
CodeTypeReference ctrType = new CodeTypeReference(attType);
string fieldName = "m_" + pcName;
CodeMemberField field = new CodeMemberField(ctrType, fieldName);
field.Comments.Add(new CodeCommentStatement("This field is used to create the " + name + " attribute/simple element.", true));
type.Members.Add(field);
CodeMemberField nameConst = new CodeMemberField(typeof(string), pcName + "Name");
nameConst.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
nameConst.Attributes |= MemberAttributes.Public | MemberAttributes.Const;
nameConst.Comments.Add(new CodeCommentStatement("Represents the referencing name for " + name + ".", true));
nameConst.InitExpression = new CodePrimitiveExpression(name);
type.Members.Add(nameConst);
CodeMemberProperty property = new CodeMemberProperty();
property.Type = ctrType;
property.Name = pcName;
property.Attributes &= ~MemberAttributes.AccessMask;
property.Attributes |= MemberAttributes.Public;
property.HasSet = true;
property.SetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
new CodeStatement[] {
new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression()),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "On" + pcName + "Changed", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EventArgs)), "Empty")))
}));
property.HasGet = true;
property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)));
property.Comments.Add(new CodeCommentStatement("TODO: Complete Summary tag documentation."));
property.Comments.Add(new CodeCommentStatement("Represents the " + name + " attribute/simple element for this element.", true));
type.Members.Add(property);
// protected virtual void OnAttributeChanged(object sender, EventArgs e)
// {
// if (AttributeChanged != null)
// {
// AttributeChanged(sender, e);
// }
// }
//
// public event EventHandler AttributeChanged;
CodeMemberMethod attributeChangeInvoker = new CodeMemberMethod();
attributeChangeInvoker.Name = "On" + pcName + "Changed";
attributeChangeInvoker.Attributes &= ~MemberAttributes.AccessMask;
attributeChangeInvoker.Attributes |= MemberAttributes.Family;
attributeChangeInvoker.Attributes &= ~MemberAttributes.ScopeMask;
attributeChangeInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.EventArgs), "e"));
attributeChangeInvoker.Comments.Add(new CodeCommentStatement("Raises the event.", true));
attributeChangeInvoker.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), pcName + "Changed"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeExpressionStatement(new CodeDelegateInvokeExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), pcName + "Changed"), new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("e")))));
type.Members.Add(attributeChangeInvoker);
CodeMemberEvent attributeChangeEvent = new CodeMemberEvent();
attributeChangeEvent.Name = pcName + "Changed";
attributeChangeEvent.Attributes &= ~MemberAttributes.AccessMask;
attributeChangeEvent.Attributes |= MemberAttributes.Public;
attributeChangeEvent.Type = new CodeTypeReference(typeof(EventHandler));
attributeChangeEvent.Comments.Add(new CodeCommentStatement("Raised when the property is changed.", true));
type.Members.Add(attributeChangeEvent);
// if (this.Attribute != null)
// {
// System.Xml.XmlAttribute attAttribute = document.CreateAttribute("Attribute");
// attAttribute.Value = this.Attribute.ToString();
// element.Attributes.Append(attAttribute);
// }
CodeIndexerExpression indexerExpression = new CodeIndexerExpression(new CodeThisReferenceExpression(), new CodeVariableReferenceExpression("index"));
if (attType.IsValueType)
{
string nullabilityFieldName = "m_Is" + pcName + "Null";
CodeMemberField nullabilityField = new CodeMemberField(new CodeTypeReference(typeof(bool)), nullabilityFieldName);
nullabilityField.Comments.Add(new CodeCommentStatement("Holds the null status for the value type of the " + name + " attribute/simple element.", true));
nullabilityField.InitExpression = new CodePrimitiveExpression(true);
type.Members.Add(nullabilityField);
CodeMemberProperty nullabilityProperty = new CodeMemberProperty();
nullabilityProperty.Type = new CodeTypeReference(typeof(bool));
nullabilityProperty.Name = "Is" + pcName + "Null";
nullabilityProperty.Attributes &= ~MemberAttributes.AccessMask;
nullabilityProperty.Attributes |= MemberAttributes.Public;
nullabilityProperty.Comments.Add(new CodeCommentStatement("Gets whether the value type of the " + name + " attribute/simple element is null.", true));
nullabilityProperty.HasSet = false;
nullabilityProperty.HasGet = true;
nullabilityProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Is" + pcName + "Null")));
type.Members.Add(nullabilityProperty);
CodeMemberMethod nullabilitySetMethod = new CodeMemberMethod();
nullabilitySetMethod.Name = "Set" + pcName + "Null";
nullabilitySetMethod.Attributes &= ~MemberAttributes.AccessMask;
nullabilitySetMethod.Attributes |= MemberAttributes.Public;
nullabilitySetMethod.Comments.Add(new CodeCommentStatement("Sets the value type of the " + name + " attribute/simple element to null.", true));
nullabilitySetMethod.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Is" + pcName + "Null"), new CodePrimitiveExpression(true)));
type.Members.Add(nullabilitySetMethod);
// Create an indexer for any collection wrapping this class.
// public [] GetBy( )
// {
// System.Collections.ArrayList list = new System.Collections.ArrayList();
//
// for (int index = 0; index < base.InnerList.Count; index++)
// {
// if (!base.InnerList[index].IsNull &&
// base.InnerList[index]. == )
// {
// list.Add(base.InnerList[index]);
// }
// }
//
// return (([])(list.ToArray(typeof())));
// }
CodeMemberMethod getByPropName = new CodeMemberMethod();
getByPropName.Name = "GetBy" + pcName;
getByPropName.Attributes &= ~MemberAttributes.AccessMask;
getByPropName.Attributes |= MemberAttributes.Public;
getByPropName.ReturnType = new CodeTypeReference(type.Name, 1);
getByPropName.Parameters.Add(new CodeParameterDeclarationExpression(ctrType, ToCamelCasing(pcName)));
getByPropName.Comments.Add(new CodeCommentStatement("Gets objects from this collection according to their property.", true));
getByPropName.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Collections.ArrayList), "list", new CodeObjectCreateExpression(typeof(System.Collections.ArrayList))));
getByPropName.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(indexerExpression, "Is" + pcName + "Null"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(false)), CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(indexerExpression, pcName), CodeBinaryOperatorType.ValueEquality, new CodeVariableReferenceExpression(ToCamelCasing(pcName)))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("list"), "Add", indexerExpression)))));
getByPropName.Statements.Add(new CodeMethodReturnStatement(new CodeCastExpression(new CodeTypeReference(type.Name, 1), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("list"), "ToArray", new CodeTypeOfExpression(type.Name)))));
listOfIndexers.Add(getByPropName);
// public Element[] GetByValueTypeAttributeNull()
// {
// System.Collections.ArrayList list = new System.Collections.ArrayList();
//
// for (int index = 0; index < base.InnerList.Count; index++)
// {
// if (base.InnerList[index].IsValueTypeAttributeNull)
// {
// list.Add(base.InnerList[index]);
// }
// }
//
// return ((Element[])(list.ToArray(typeof(Element))));
// }
CodeMemberMethod getByNullPropName = new CodeMemberMethod();
getByNullPropName.Name = "GetBy" + pcName + "Null";
getByNullPropName.Attributes &= ~MemberAttributes.AccessMask;
getByNullPropName.Attributes |= MemberAttributes.Public;
getByNullPropName.ReturnType = new CodeTypeReference(type.Name, 1);
getByNullPropName.Comments.Add(new CodeCommentStatement("Gets objects from this collection that have their properties set to null.", true));
getByNullPropName.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Collections.ArrayList), "list", new CodeObjectCreateExpression(typeof(System.Collections.ArrayList))));
getByNullPropName.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(indexerExpression, "Is" + pcName + "Null"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(true)),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("list"), "Add", indexerExpression)))));
getByNullPropName.Statements.Add(new CodeMethodReturnStatement(new CodeCastExpression(new CodeTypeReference(type.Name, 1), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("list"), "ToArray", new CodeTypeOfExpression(type.Name)))));
listOfIndexers.Add(getByNullPropName);
// Auto denullifier - used in From Xml Ctor
property.SetStatements.Add(new CodeCommentStatement(" After setting the value, it is no longer null.", false));
property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_Is" + pcName + "Null"), new CodePrimitiveExpression(false)));
clone.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Is" + pcName + "Null"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false)),
new CodeStatement[] { new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("clone"), pcName), new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), pcName)) },
new CodeStatement[] { new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("clone"), "Set" + pcName + "Null"))}));
// (this.IsFieldNull == obj.IsFieldNull && this.m_Field == obj.m_Field)
condition = new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(new CodeCastExpression(type.Name, new CodeVariableReferenceExpression("obj")), "m_" + pcName)),
CodeBinaryOperatorType.BooleanAnd,
new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Is" + pcName + "Null"), CodeBinaryOperatorType.ValueEquality, new CodePropertyReferenceExpression(new CodeCastExpression(type.Name, new CodeVariableReferenceExpression("obj")), "Is" + pcName + "Null")));
}
else
{
// public [] GetBy( )
// {
// System.Collections.ArrayList list = new System.Collections.ArrayList();
//
// for (int index = 0; index < base.InnerList.Count; index++)
// {
// if (base.InnerList[index]. == )
// {
// list.Add(base.InnerList[index]);
// }
// }
//
// return (([])(list.ToArray(typeof())));
// }
CodeMemberMethod getByObjectPropName = new CodeMemberMethod();
getByObjectPropName.Name = "GetBy" + pcName;
getByObjectPropName.Attributes &= ~MemberAttributes.AccessMask;
getByObjectPropName.Attributes |= MemberAttributes.Public;
getByObjectPropName.ReturnType = new CodeTypeReference(type.Name, 1);
getByObjectPropName.Parameters.Add(new CodeParameterDeclarationExpression(ctrType, ToCamelCasing(pcName)));
getByObjectPropName.Comments.Add(new CodeCommentStatement("Gets objects from this collection according to their property.", true));
getByObjectPropName.Statements.Add(new CodeVariableDeclarationStatement(typeof(System.Collections.ArrayList), "list", new CodeObjectCreateExpression(typeof(System.Collections.ArrayList))));
getByObjectPropName.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int), "index", new CodePrimitiveExpression(0)),
new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Count")),
new CodeAssignStatement(new CodeVariableReferenceExpression("index"), new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("index"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))),
new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(indexerExpression, pcName), CodeBinaryOperatorType.ValueEquality, new CodeVariableReferenceExpression(ToCamelCasing(pcName))),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("list"), "Add", indexerExpression)))));
getByObjectPropName.Statements.Add(new CodeMethodReturnStatement(new CodeCastExpression(new CodeTypeReference(type.Name, 1), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("list"), "ToArray", new CodeTypeOfExpression(type.Name)))));
listOfIndexers.Add(getByObjectPropName);
clone.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("clone"), "m_" + pcName), new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName)));
condition = new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "m_" + pcName), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(new CodeCastExpression(type.Name, new CodeVariableReferenceExpression("obj")), "m_" + pcName));
}
indexers = ((CodeTypeMember[])(listOfIndexers.ToArray(typeof(CodeTypeMember))));
return attType;
}
#endregion
#region CreateAttributeGetXml
static void CreateAttributeGetXml(CodeTypeDeclaration type,
XmlSchemaAttribute attribute,
CodeMemberMethod getXml,
Type attType)
{
CodeConditionStatement nullCheck;
if (!attType.IsValueType)
{
// if (this.Attribute != null)
nullCheck = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(ToPascalCasing(attribute.Name))), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));
}
else
{
// if (this.IsAttributeNull == false)
nullCheck = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Is" + ToPascalCasing(ToPascalCasing(attribute.Name)) + "Null"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false)));
}
// element.SetAttribute(...);
if (attType == typeof(bool))
{
nullCheck.TrueStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(ToPascalCasing(attribute.Name))), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(true)),
new CodeStatement[] {
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "SetAttribute",
new CodeFieldReferenceExpression(null, ToPascalCasing(attribute.Name) + "Name"),
new CodePrimitiveExpression("true")))
},
new CodeStatement[] {
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "SetAttribute",
new CodeFieldReferenceExpression(null, ToPascalCasing(attribute.Name) + "Name"),
new CodePrimitiveExpression("false")))
}));
}
else
{
nullCheck.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "SetAttribute",
new CodeFieldReferenceExpression(null, ToPascalCasing(attribute.Name) + "Name"),
new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(attribute.Name)), "ToString")));
}
getXml.Statements.Add(nullCheck);
}
#endregion
#region CreateSimpleElementGetXml
static void CreateSimpleElementGetXml(CodeTypeDeclaration type,
XmlSchemaElement element,
CodeMemberMethod getXml,
Type attType)
{
CodeConditionStatement nullCheck;
if (!attType.IsValueType)
{
// if (this.Attribute != null)
nullCheck = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(element.Name)), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)));
}
else
{
// if (this.IsAttributeNull == false)
nullCheck = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Is" + ToPascalCasing(element.Name) + "Null"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false)));
}
if (attType == typeof(bool))
{
nullCheck.TrueStatements.AddRange(new CodeStatement[] {
new CodeVariableDeclarationStatement(typeof(System.Xml.XmlElement), "elm" + ToPascalCasing(element.Name), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "CreateElement", new CodeFieldReferenceExpression(null, "ElementName"))),
new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(element.Name)), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(true)),
new CodeStatement[]
{
new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("elm" + ToPascalCasing(element.Name)), "Value"), new CodePrimitiveExpression("true"))
},
new CodeStatement[]
{
new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("elm" + ToPascalCasing(element.Name)), "Value"), new CodePrimitiveExpression("false"))
}),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "AppendChild", new CodeVariableReferenceExpression("elm" + ToPascalCasing(element.Name))))
});
}
else
{
nullCheck.TrueStatements.AddRange(new CodeStatement[] {
new CodeVariableDeclarationStatement(typeof(System.Xml.XmlElement), "elm" + ToPascalCasing(element.Name), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("document"), "CreateElement", new CodeFieldReferenceExpression(null, "ElementName"))),
new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("elm" + ToPascalCasing(element.Name)), "Value"), new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(element.Name)), "ToString")),
new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("element"), "AppendChild", new CodeVariableReferenceExpression("elm" + ToPascalCasing(element.Name))))
});
}
getXml.Statements.Add(nullCheck);
}
#endregion
#region CreateAttributeFromXml
static void CreateAttributeFromXml(CodeTypeDeclaration type,
XmlSchemaAttribute attribute,
CodeConstructor fromXml,
Type attType)
{
// // Deserialize Attribute
// if (element.Attributes["Attribute"] != null)
// {
// this.Attribute = ((int)(System.Convert.ChangeType(element.Attributes["Attribute"].Value, typeof(int))));
// }
// else
// {
// // nullify
// }
CodeIndexerExpression attRef = new CodeIndexerExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("element"), "Attributes"), new CodeFieldReferenceExpression(null, ToPascalCasing(attribute.Name) + "Name"));
CodeConditionStatement condition = new CodeConditionStatement(new CodeBinaryOperatorExpression(attRef, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(attribute.Name)), new CodeCastExpression(attType, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(System.Convert)), "ChangeType", new CodePropertyReferenceExpression(attRef, "Value"), new CodeTypeOfExpression(attType)))));
if (attType.IsValueType)
{
condition.FalseStatements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Set" + ToPascalCasing(attribute.Name) + "Null"));
}
fromXml.Statements.Add(condition);
}
#endregion
#region CreateSimpleElementFromXml
static void CreateSimpleElementFromXml(CodeTypeDeclaration type,
XmlSchemaElement element,
CodeConstructor fromXml,
Type attType)
{
// // Deserialize simple element
// if (element["Attribute"] != null)
// {
// this.Attribute = ((int)(System.Convert.ChangeType(element["Attribute"].Value, typeof(int))));
// // denullify
// }
// else
// {
// // nullify
// }
CodeIndexerExpression attRef = new CodeIndexerExpression(new CodeVariableReferenceExpression("element"), new CodeFieldReferenceExpression(null, "ElementName"));
CodeConditionStatement condition = new CodeConditionStatement(new CodeBinaryOperatorExpression(attRef, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), ToPascalCasing(element.Name)), new CodeCastExpression(attType, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(System.Convert)), "ChangeType", new CodePropertyReferenceExpression(attRef, "Value"), new CodeTypeOfExpression(attType)))));
if (attType.IsValueType)
{
condition.FalseStatements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Set" + ToPascalCasing(element.Name) + "Null"));
}
fromXml.Statements.Add(condition);
}
#endregion
#region Casing
private static string ToCamelCasing(string name)
{
string temp;
if (name.Length > 1)
{
temp = name.Substring(1, name.Length - 1);
temp = name[0].ToString().ToLower() + temp;
return temp;
}
else
{
return name.ToLower();
}
}
private static string ToPascalCasing(string name)
{
return Char.ToUpper(name[0]) + name.Substring(1);
}
#endregion
}
}