Example #1
0
        private void DoCollections(string classPackage, Element classElement, string xmlName, string interfaceClass,
		                           string implementingClass, MultiMap inheritedMeta)
        {
            string originalInterface = interfaceClass;
            string originalImplementation = implementingClass;

            for (IEnumerator collections = classElement.SelectNodes("urn:" + xmlName, CodeGenerator.nsmgr).GetEnumerator();
                 collections.MoveNext();)
            {
                Element collection = (Element) collections.Current;
                MultiMap metaForCollection = MetaAttributeHelper.LoadAndMergeMetaMap(collection, inheritedMeta);
                string propertyName = (collection.Attributes["name"] == null ? string.Empty : collection.Attributes["name"].Value);

                //TODO: map and set in .net
                //		Small hack to switch over to sortedSet/sortedMap if sort is specified. (that is sort != unsorted)
                string sortValue = (collection.Attributes["sort"] == null ? null : collection.Attributes["sort"].Value);
                if ((object) sortValue != null && !"unsorted".Equals(sortValue) && !"".Equals(sortValue.Trim()))
                {
                    if ("map".Equals(xmlName))
                    {
                        interfaceClass = typeof(IDictionary<,>).FullName;
                        implementingClass = typeof(IDictionary<,>).FullName;
                    }
                    else if ("set".Equals(xmlName))
                    {
                        interfaceClass = typeof(ISet<>).FullName;
                        implementingClass = typeof(ISet<>).FullName;
                    }
                }
                else
                {
                    interfaceClass = originalInterface;
                    implementingClass = originalImplementation;
                }

                ClassName interfaceClassName = new ClassName(interfaceClass);
                ClassName implementationClassName = new ClassName(implementingClass);

                // add an import and field for this collection
                AddImport(interfaceClassName);
                AddImport(implementationClassName);

                ClassName foreignClass = null;
                SupportClass.SetSupport foreignKeys = null;
                // Collect bidirectional data
                if (collection.SelectNodes("urn:one-to-many", CodeGenerator.nsmgr).Count != 0)
                {
                    foreignClass = new ClassName(collection["one-to-many"].Attributes["class"].Value);
                }
                else if (collection.SelectNodes("urn:many-to-many", CodeGenerator.nsmgr).Count != 0)
                {
                    foreignClass = new ClassName(collection["many-to-many"].Attributes["class"].Value);
                }

                // Do the foreign keys and import
                if (foreignClass != null)
                {
                    // Collect the keys
                    foreignKeys = new SupportClass.HashSetSupport();
                    if (collection["key"].Attributes["column"] != null)
                        foreignKeys.Add(collection["key"].Attributes["column"].Value);

                    for (IEnumerator iter = collection["key"].SelectNodes("urn:column", CodeGenerator.nsmgr).GetEnumerator();
                         iter.MoveNext();)
                    {
                        if (((Element) iter.Current).Attributes["name"] != null)
                            foreignKeys.Add(((Element) iter.Current).Attributes["name"].Value);
                    }

                    AddImport(foreignClass);
                }
                FieldProperty cf =
                    new FieldProperty(collection, this, propertyName, interfaceClassName, implementationClassName, false, foreignClass,
                                      foreignKeys, metaForCollection);

                AddFieldProperty(cf);
                if (collection.SelectNodes("urn:composite-element", CodeGenerator.nsmgr).Count != 0)
                {
                    for (
                        IEnumerator compositeElements =
                            collection.SelectNodes("urn:composite-element", CodeGenerator.nsmgr).GetEnumerator();
                        compositeElements.MoveNext();)
                    {
                        Element compositeElement = (Element) compositeElements.Current;
                        string compClass = compositeElement.Attributes["class"].Value;

                        try
                        {
                            ClassMapping mapping = new ClassMapping(classPackage, compositeElement, this, true, MetaAttribs);
                            ClassName classType = new ClassName(compClass);
                            // add an import and field for this property
                            AddImport(classType);
                            object tempObject;
                            tempObject = mapping;
                            components[mapping.FullyQualifiedName] = tempObject;
                        }
                        catch (Exception e)
                        {
                            log.Error("Error building composite-element " + compClass, e);
                        }
                    }
                }
                if (collection.SelectNodes("urn:composite-index", CodeGenerator.nsmgr).Count != 0)
                {
                    for (
                        IEnumerator compositeElements =
                            collection.SelectNodes("urn:composite-index", CodeGenerator.nsmgr).GetEnumerator();
                        compositeElements.MoveNext(); )
                    {
                        Element compositeElement = (Element)compositeElements.Current;
                        string compClass = compositeElement.Attributes["class"].Value;

                        try
                        {
                            ClassMapping mapping = new ClassMapping(classPackage, compositeElement, this, true, MetaAttribs);
                            mapping.ImplementEquals();
                            ClassName classType = new ClassName(compClass);
                            // add an import and field for this property
                            AddImport(classType);
                            object tempObject;
                            tempObject = mapping;
                            components[mapping.FullyQualifiedName] = tempObject;
                        }
                        catch (Exception e)
                        {
                            log.Error("Error building composite-index " + compClass, e);
                        }
                    }
                }
                ExtractGenericArguments(cf,xmlName);
            }
        }
Example #2
0
        protected internal virtual void InitWith(string classPackage, ClassName mySuperClass, Element classElement,
		                                         bool component, MultiMap inheritedMeta)
        {
            IsComponent = component;
            string fullyQualifiedName = (classElement.Attributes[component ? "class" : "name"] == null
                                         	? string.Empty : classElement.Attributes[component ? "class" : "name"].Value);

            if (fullyQualifiedName.IndexOf('.') < 0 && (object) classPackage != null && classPackage.Trim().Length > 0)
            {
                fullyQualifiedName = classPackage + "." + fullyQualifiedName;
            }

            log.Debug("Processing mapping for class: " + fullyQualifiedName);

            MetaAttribs = MetaAttributeHelper.LoadAndMergeMetaMap(classElement, inheritedMeta);

            //    class & package names
            name = new ClassName(fullyQualifiedName);

            if (GetMeta("generated-class") != null)
            {
                generatedName = new ClassName(GetMetaAsString("generated-class").Trim());
                shouldBeAbstract_Renamed_Field = true;
                log.Warn("Generating " + generatedName + " instead of " + name);
            }
            else
            {
                generatedName = name;
            }
            XmlAttribute @abstract = classElement.Attributes["abstract"];
            if (null != @abstract)
            {
                bool.TryParse(@abstract.Value, out shouldBeAbstract_Renamed_Field);
            }
            if (mySuperClass != null)
            {
                this.superClass = mySuperClass.Name;
                AddImport(mySuperClass); // can only be done AFTER this class gets its own name.
            }

            // get the properties defined for this class
            SupportClass.ListCollectionSupport propertyList = new SupportClass.ListCollectionSupport();
            propertyList.AddAll(classElement.SelectNodes("urn:property", CodeGenerator.nsmgr));
            propertyList.AddAll(classElement.SelectNodes("urn:version", CodeGenerator.nsmgr));
            propertyList.AddAll(classElement.SelectNodes("urn:timestamp", CodeGenerator.nsmgr));
            propertyList.AddAll(classElement.SelectNodes("urn:key-property", CodeGenerator.nsmgr));
            propertyList.AddAll(classElement.SelectNodes("urn:any", CodeGenerator.nsmgr));

            // get the properties inside a <join/> mapping...
            var joins = classElement.SelectNodes("urn:join",CodeGenerator.nsmgr);
            foreach (XmlNode join in joins)
            {
                propertyList.AddAll( join.SelectNodes("urn:property", CodeGenerator.nsmgr));
            }

            // get all many-to-one associations defined for the class
            SupportClass.ListCollectionSupport manyToOneList = new SupportClass.ListCollectionSupport();
            manyToOneList.AddAll(classElement.SelectNodes("urn:many-to-one", CodeGenerator.nsmgr));
            manyToOneList.AddAll(classElement.SelectNodes("urn:key-many-to-one", CodeGenerator.nsmgr));

            XmlAttribute att = classElement.Attributes["proxy"];
            if (att != null)
            {
                proxyClass = att.Value;
                if (proxyClass.IndexOf(",") > 0)
                    proxyClass = proxyClass.Substring(0, proxyClass.IndexOf(","));
            }

            Element id = classElement["id"];

            if (id != null)
            {
                propertyList.Insert(0, id);
                // implementEquals();
            }

            // composite id
            Element cmpid = classElement["composite-id"];
            if (cmpid != null)
            {
                string cmpname = (cmpid.Attributes["name"] == null ? null : cmpid.Attributes["name"].Value);
                string cmpclass = (cmpid.Attributes["class"] == null ? null : cmpid.Attributes["class"].Value);

                if ((Object) cmpclass == null || cmpclass.Equals(string.Empty))
                {
                    //Embedded composite id
                    //implementEquals();
                    propertyList.AddAll(0, cmpid.SelectNodes("urn:key-property", CodeGenerator.nsmgr));
                    manyToOneList.AddAll(0, cmpid.SelectNodes("urn:key-many-to-one", CodeGenerator.nsmgr));
                    if( manyToOneList.Count == 0 )
                        ImplementEquals();
                }
                else
                {
                    //Composite id class
                    ClassMapping mapping = new ClassMapping(classPackage, cmpid, this, true, MetaAttribs);
                    MultiMap metaForCompositeid = MetaAttributeHelper.LoadAndMergeMetaMap(cmpid, MetaAttribs);
                    mapping.ImplementEquals();
                    ClassName classType = new ClassName(cmpclass);
                    // add an import and field for this property
                    AddImport(classType);
                    if (cmpname != null)
                    {
                        FieldProperty cmpidfield =
                            new FieldProperty(cmpid, this, cmpname, classType, false, true, false, metaForCompositeid);
                        AddFieldProperty(cmpidfield);
                    }
                    else
                    {
                        //composite id with class MUST have a property name associated with...
                        log.Error("Composite id with class MUST have a property name. In:"+mapping.Name);
                    }
                    object tempObject;
                    tempObject = mapping;
                    components[mapping.FullyQualifiedName] = tempObject;
                }
            }

            // checked after the default sets of implement equals.
            if (GetMetaAsBool("implement-equals"))
            {
                ImplementEquals();
            }

            // derive the class imports and fields from the properties
            for (IEnumerator properties = propertyList.GetEnumerator(); properties.MoveNext();)
            {
                Element property = (Element) properties.Current;

                MultiMap metaForProperty = MetaAttributeHelper.LoadAndMergeMetaMap(property, MetaAttribs);
                string propertyName = (property.Attributes["name"] == null ? null : property.Attributes["name"].Value);
                if ((Object) propertyName == null || propertyName.Trim().Equals(string.Empty))
                {
                    continue; //since an id doesn't necessarily need a name
                }

                // ensure that the type is specified
                string type = (property.Attributes["type"] == null ? null : property.Attributes["type"].Value);
                if ((Object) type == null && cmpid != null)
                {
                    // for composite-keys
                    type = (property.Attributes["class"] == null ? null : property.Attributes["class"].Value);
                }
                if ("timestamp".Equals(property.LocalName))
                {
                    type = "System.DateTime";
                }

                if ("any".Equals(property.LocalName))
                {
                    type = "System.Object";
                }

                if ((Object) type == null || type.Trim().Equals(string.Empty))
                {
                    if (property == id)
                    {
                        Element generator = property["generator"];
                        string generatorClass = generator.Attributes["class"] == null ? string.Empty : generator.Attributes["class"].Value;
                        switch (generatorClass)
                        {
                            case "uuid.hex":
                                type = "String";
                                break;
                            case "guid":
                            case "guid.native":
                            case "guid.comb":
                                type = "Guid";
                                break;
                            default:
                                type = "Int32";
                                break;
                        }
                    }
                    else
                        type = "String";
                    log.Warn("property \"" + propertyName + "\" in class " + Name + " is missing a type attribute, guessing " + type);
                }

                // handle in a different way id and properties...
                // ids may be generated and may need to be of object type in order to support
                // the unsaved-value "null" value.
                // Properties may be nullable (ids may not)
                if (property == id)
                {
                    Element generator = property["generator"];
                    string unsavedValue = (property.Attributes["unsaved-value"] == null
                                           	? null : property.Attributes["unsaved-value"].Value);
                    bool mustBeNullable = ((Object) unsavedValue != null && unsavedValue.Equals("null"));
                    bool generated =
                        !(generator.Attributes["class"] == null ? string.Empty : generator.Attributes["class"].Value).Equals("assigned");
                    ClassName rtype = GetFieldType(type, mustBeNullable, false);
                    AddImport(rtype);
                    FieldProperty idField =
                        new FieldProperty(property, this, propertyName, rtype, false, true, generated, metaForProperty);
                    AddFieldProperty(idField);
                }
                else
                {
                    string notnull = (property.Attributes["not-null"] == null ? null : property.Attributes["not-null"].Value);
                    // if not-null property is missing lets see if it has been
                    // defined at column level
                    if ((Object) notnull == null)
                    {
                        Element column = property["column"];
                        if (column != null)
                            notnull = (column.Attributes["not-null"] == null ? null : column.Attributes["not-null"].Value);
                    }
                    bool nullable = ((Object) notnull == null || notnull.Equals("false"));
                    bool key = property.LocalName.StartsWith("key-"); //a composite id property
                    ClassName t = GetFieldType(type);
                    AddImport(t);
                    FieldProperty stdField =
                        new FieldProperty(property, this, propertyName, t, nullable && !key, key, false, metaForProperty);
                    AddFieldProperty(stdField);
                }
            }

            // one to ones
            for (IEnumerator onetoones = classElement.SelectNodes("urn:one-to-one", CodeGenerator.nsmgr).GetEnumerator();
                 onetoones.MoveNext();)
            {
                Element onetoone = (Element) onetoones.Current;

                MultiMap metaForOneToOne = MetaAttributeHelper.LoadAndMergeMetaMap(onetoone, MetaAttribs);
                string propertyName = (onetoone.Attributes["name"] == null ? string.Empty : onetoone.Attributes["name"].Value);

                // ensure that the class is specified
                string clazz = (onetoone.Attributes["class"] == null ? string.Empty : onetoone.Attributes["class"].Value);
                if (clazz.Length == 0)
                {
                    log.Warn("one-to-one \"" + name + "\" in class " + Name + " is missing a class attribute");
                    continue;
                }
                ClassName cn = GetFieldType(clazz);
                AddImport(cn);
                FieldProperty fm = new FieldProperty(onetoone, this, propertyName, cn, true, metaForOneToOne);
                AddFieldProperty(fm);
            }

            // many to ones - TODO: consolidate with code above
            for (IEnumerator manytoOnes = manyToOneList.GetEnumerator(); manytoOnes.MoveNext();)
            {
                Element manyToOne = (Element) manytoOnes.Current;

                MultiMap metaForManyToOne = MetaAttributeHelper.LoadAndMergeMetaMap(manyToOne, MetaAttribs);
                string propertyName = (manyToOne.Attributes["name"] == null ? string.Empty : manyToOne.Attributes["name"].Value);

                // ensure that the type is specified
                string type = (manyToOne.Attributes["class"] == null ? string.Empty : manyToOne.Attributes["class"].Value);
                if (type.Length == 0)
                {
                    log.Warn("many-to-one \"" + propertyName + "\" in class " + Name + " is missing a class attribute");
                    continue;
                }
                ClassName classType = new ClassName(type);

                // is it nullable?
                string notnull = (manyToOne.Attributes["not-null"] == null ? null : manyToOne.Attributes["not-null"].Value);
                bool nullable = ((Object) notnull == null || notnull.Equals("false"));
                bool key = manyToOne.LocalName.StartsWith("key-"); //a composite id property

                // add an import and field for this property
                AddImport(classType);
                FieldProperty f =
                    new FieldProperty(manyToOne, this, propertyName, classType, nullable && !key, key, false, metaForManyToOne);
                AddFieldProperty(f);
            }

            // collections
            DoCollections(classPackage, classElement, "list", "System.Collections.Generic.IList", "System.Collections.Generic.List",
                          MetaAttribs);
            DoCollections(classPackage, classElement, "map", "System.Collections.Generic.IDictionary", "System.Collections.Generic.Dictionary",
                          MetaAttribs);
            DoCollections(classPackage, classElement, "set", "Iesi.Collections.Generic.ISet", "Iesi.Collections.Generic.HashedSet", MetaAttribs);
            DoCollections(classPackage, classElement, "bag", "System.Collections.Generic.IList", "System.Collections.Generic.List",
                          MetaAttribs);
            DoCollections(classPackage, classElement, "idbag", "System.Collections.Generic.IList", "System.Collections.Generic.List",
                          MetaAttribs);
            DoArrays(classElement, "array", MetaAttribs);
            DoArrays(classElement, "primitive-array", MetaAttribs);

            //dynamic-component
            foreach (Element dync in classElement.SelectNodes("urn:dynamic-component", CodeGenerator.nsmgr))
            {
                MultiMap metaForDync = MetaAttributeHelper.LoadAndMergeMetaMap(dync, MetaAttribs);
                string propertyName = (dync.Attributes["name"] == null ? string.Empty : dync.Attributes["name"].Value);
                FieldProperty dynfield = new FieldProperty(dync, this, propertyName, new ClassName("System.Collections.Generic.IDictionary"), false, metaForDync);
                dynfield.AddGenericArgument(new ClassName("System.String"));
                dynfield.AddGenericArgument(new ClassName("System.Object"));
                AddImport("System.Collections.Generic.IDictionary");
                AddFieldProperty(dynfield);
            }
            //components
            for (IEnumerator iter = classElement.SelectNodes("urn:component", CodeGenerator.nsmgr).GetEnumerator();
                 iter.MoveNext();)
            {
                Element cmpe = (Element) iter.Current;
                MultiMap metaForComponent = MetaAttributeHelper.LoadAndMergeMetaMap(cmpe, MetaAttribs);
                string cmpname = (cmpe.Attributes["name"] == null ? null : cmpe.Attributes["name"].Value);
                string cmpclass = (cmpe.Attributes["class"] == null ? null : cmpe.Attributes["class"].Value);
                if ((Object) cmpclass == null || cmpclass.Equals(string.Empty))
                {
                    log.Warn("component \"" + cmpname + "\" in class " + Name + " does not specify a class");
                    continue;
                }
                ClassMapping mapping = new ClassMapping(classPackage, cmpe, this, true, MetaAttribs);

                ClassName classType = new ClassName(cmpclass);
                // add an import and field for this property
                AddImport(classType);
                FieldProperty ff = new FieldProperty(cmpe, this, cmpname, classType, false, metaForComponent);
                AddFieldProperty(ff);
                object tempObject2;
                tempObject2 = mapping;
                components[mapping.FullyQualifiedName] = tempObject2;
            }

            //    subclasses (done last so they can access this superclass for info)
            for (IEnumerator iter = classElement.SelectNodes("urn:subclass", CodeGenerator.nsmgr).GetEnumerator();
                 iter.MoveNext();)
            {
                Element subclass = (Element) iter.Current;
                ClassMapping subclassMapping = new ClassMapping(classPackage, this, name, this, subclass, MetaAttribs);
                AddSubClass(subclassMapping);
            }

            for (IEnumerator iter = classElement.SelectNodes("urn:joined-subclass", CodeGenerator.nsmgr).GetEnumerator();
                 iter.MoveNext();)
            {
                Element subclass = (Element) iter.Current;
                ClassMapping subclassMapping = new ClassMapping(classPackage, this, name, this, subclass, MetaAttribs);
                AddSubClass(subclassMapping);
            }

            ValidateMetaAttributes();
        }