Example #1
0
        private void SetValue(XmlReader input, XmlNodeType prevInputType, string prevInputName)
        {
            try
            {
                // we are here because this node is of type Text or WhiteSpace
                if (prevInputType == XmlNodeType.Element) // previous node should be of Type Element before we go next
                {
                    if (_currentNode is XmlExpressType)
                    {
                        XmlExpressType node = (XmlExpressType)_currentNode;
                        node.Value = input.Value;
                    }
                    else if (_currentNode is XmlBasicType)
                    {
                        XmlBasicType node = (XmlBasicType)_currentNode;
                        node.Value = input.Value;
                    }
                    else if (_currentNode is XmlProperty)
                    {
                        XmlProperty   node    = (XmlProperty)_currentNode;
                        PropertyValue propVal = new PropertyValue();
                        Type          t       = node.Property.PropertyType;
                        if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable <>)))
                        {
                            t = Nullable.GetUnderlyingType(t);
                        }


                        // if the propertytype is abstract, we cant possibly set any text value on it
                        // effectively this ignores white spaces, e.g. NominalValue of IfcPropertySingleValue
                        if (!t.IsAbstract)
                        {
                            IfcParserType parserType;
                            if (typeof(ExpressType).IsAssignableFrom(t) && !(typeof(ExpressComplexType).IsAssignableFrom(t)))
                            {
                                ExpressType et = (ExpressType)(Activator.CreateInstance(t));
                                if (et.GetType() == typeof(IfcLogical))
                                {
                                    parserType = IfcParserType.Boolean;
                                }
                                else
                                {
                                    parserType = primitives[et.UnderlyingSystemType.Name];
                                }
                            }
                            else if (t.IsEnum)
                            {
                                parserType = IfcParserType.Enum;
                            }
                            else
                            {
                                if (!primitives.TryGetValue(t.Name, out parserType))
                                {
                                    parserType = IfcParserType.Undefined;
                                }
                            }

                            if (parserType == IfcParserType.String)
                            {
                                propVal.Init("'" + input.Value + "'", parserType);
                                ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                            }
                            else if (parserType != IfcParserType.Undefined && !string.IsNullOrWhiteSpace(input.Value))
                            {
                                if (parserType == IfcParserType.Boolean)
                                {
                                    if (string.Compare(input.Value, "unknown", true) != 0) //do nothing with IfcLogicals that are undefined
                                    {
                                        propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F.", parserType);
                                    }
                                }
                                else
                                {
                                    propVal.Init(input.Value, parserType);
                                }

                                ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Error reading IfcXML data at node " + input.LocalName, e);
            }
        }
Example #2
0
        private void EndElement(XmlReader input, XmlNodeType prevInputType, string prevInputName, out IPersistIfcEntity writeEntity)
        {
            try
            {
                // before end element, we need to deal with SetCollection
                if (_currentNode is XmlCollectionProperty)
                {
                    // SetCollection will handle SetValue for Collection
                    CollectionType CType = ((XmlCollectionProperty)_currentNode).CType;
                    switch (CType)
                    {
                    case CollectionType.List:
                    case CollectionType.ListUnique:
                        ((XmlCollectionProperty)_currentNode).Entities.Sort(XmlCollectionProperty.CompareNodes);
                        break;

                    case CollectionType.Set:
                        break;

                    default:
                        throw new Exception("Unknown list type, " + CType);
                    }

                    foreach (XmlNode item in ((XmlCollectionProperty)_currentNode).Entities)
                    {
                        if (item is XmlEntity)
                        {
                            XmlEntity             node               = (XmlEntity)item;
                            XmlEntity             collectionOwner    = item.Parent.Parent as XmlEntity;
                            XmlCollectionProperty collection         = item.Parent as XmlCollectionProperty; //the collection to add to;
                            IPersistIfc           ifcCollectionOwner = collectionOwner.Entity;
                            PropertyValue         pv = new PropertyValue();
                            pv.Init(node.Entity);
                            ifcCollectionOwner.IfcParse(collection.PropertyIndex - 1, pv);
                        }
                    }
                }
                else if (_currentNode.Parent is XmlProperty)
                {
                    XmlProperty propNode = (XmlProperty)_currentNode.Parent;
                    if (_currentNode is XmlEntity)
                    {
                        XmlEntity entityNode = (XmlEntity)_currentNode;
                        propNode.SetValue(entityNode.Entity);
                    }
                    else if (_currentNode is XmlExpressType)
                    {
                        //create ExpressType, call ifcparse with propindex and object
                        //((XmlProperty)_currentNode.Parent).SetValue((XmlExpressType)_currentNode);

                        XmlExpressType expressNode = (XmlExpressType)_currentNode;
                        if (expressNode.Type != propNode.Property.PropertyType)
                        {
                            //propNode.SetValue(expressNode);
                            IfcType ifcType;
                            if (IsIfcType(input.LocalName, out ifcType))
                            //we have an IPersistIfc
                            {
                                IPersistIfc ent;
                                object[]    param = new object[1];
                                param[0] = expressNode.Value;
                                ent      = (IPersistIfc)Activator.CreateInstance(ifcType.Type, param);

                                propNode.SetValue(ent);
                            }
                        }
                        else
                        {
                            propNode.SetValue(expressNode.Value, primitives[expressNode.Type.Name]);
                        }
                    }
                    else if (_currentNode is XmlBasicType)
                    {
                        //set PropertyValue to write type boolean, integer, call ifcparse with string

                        XmlBasicType basicNode = (XmlBasicType)_currentNode;
                        propNode.SetValue(basicNode.Value, basicNode.Type);
                    }
                }


                else if (prevInputType == XmlNodeType.Element && prevInputName == input.LocalName &&
                         _currentNode is XmlProperty && _currentNode.Parent != null && _currentNode.Parent is XmlEntity)
                {
                    // WE SHOULDNT EXECUTE THE FOLLOWING CODE IF THIS PROPERTY ALREADY CALLED SETVALUE
                    XmlProperty   node    = (XmlProperty)_currentNode;
                    PropertyValue propVal = new PropertyValue();
                    Type          t       = node.Property.PropertyType;
                    if (t != null && t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable <>)))
                    {
                        t = Nullable.GetUnderlyingType(t);
                    }
                    ExpressType et = null;
                    if (t != null && typeof(ExpressType).IsAssignableFrom(t))
                    {
                        et = (ExpressType)(Activator.CreateInstance(t));
                    }

                    IfcParserType pt = IfcParserType.Undefined;
                    if (et != null)
                    {
                        pt = primitives[et.UnderlyingSystemType.Name];
                    }
                    else
                    {
                        if (t.IsEnum)
                        {
                            pt = IfcParserType.Enum;
                        }
                        else if (primitives.ContainsKey(t.Name))
                        {
                            pt = primitives[t.Name];
                        }
                    }

                    if (pt != IfcParserType.Undefined)
                    {
                        if (pt.ToString().ToLower() == "string")
                        {
                            propVal.Init("'" + input.Value + "'", pt);
                        }
                        else
                        {
                            if (pt.ToString().ToLower() == "boolean")
                            {
                                propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F", pt);
                            }
                            else
                            {
                                propVal.Init(input.Value, pt);
                            }
                        }

                        ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                    }
                }

                else if (_currentNode.Parent is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    if (_currentNode is XmlEntity)
                    {
                        ((XmlCollectionProperty)_currentNode.Parent).Entities.Add(((XmlEntity)_currentNode));
                    }
                    else if (_currentNode is XmlExpressType)
                    {
                        XmlExpressType expressNode = (XmlExpressType)_currentNode;
                        //actualEntityType is the actual type of the value to create
                        Type actualEntityType = expressNode.Type;
                        //Determine if the Express Type is a Nullable, if so get the type of the Nullable
                        if (actualEntityType.IsGenericType && actualEntityType.GetGenericTypeDefinition().Equals(typeof(Nullable <>)))
                        {
                            actualEntityType = Nullable.GetUnderlyingType(actualEntityType);
                        }

                        //need to resolve what the Parser type is
                        //if the generic type of the collection is different from the actualEntityType then we need to create an entity and call Ifc Parse
                        //otherwise we need to call Ifcparse with a string value and the type of the underlying type
                        XmlCollectionProperty collection           = _currentNode.Parent as XmlCollectionProperty; //the collection to add to;
                        Type          collectionValueType          = collection.Property.PropertyType;
                        Type          collectionGenericType        = GetItemTypeFromGenericType(collectionValueType);;
                        bool          genericTypeIsSameAsValueType = (collectionGenericType == actualEntityType);
                        PropertyValue pv = new PropertyValue();

                        if (genericTypeIsSameAsValueType) //call IfcParse with string value and parser type
                        {
                            ExpressType actualEntityValue = (ExpressType)(Activator.CreateInstance(actualEntityType));
                            //resolve the underlying type
                            IfcParserType parserType = primitives[actualEntityValue.UnderlyingSystemType.Name];
                            if (parserType == IfcParserType.String)
                            {
                                pv.Init("'" + expressNode.Value + "'", parserType);
                            }
                            else
                            {
                                pv.Init(expressNode.Value, parserType);
                            }
                        }
                        else //call IfcParse with an entity
                        {
                            object[] param = new object[1];
                            param[0] = expressNode.Value;
                            ExpressType actualEntityValue = (ExpressType)(Activator.CreateInstance(expressNode.Type, param));
                            pv.Init(actualEntityValue);
                        }

                        XmlEntity   collectionOwner    = _currentNode.Parent.Parent as XmlEntity; //go to owner of collection
                        IPersistIfc ifcCollectionOwner = collectionOwner.Entity;
                        ifcCollectionOwner.IfcParse(collection.PropertyIndex - 1, pv);
                    }
                    else if (_currentNode is XmlBasicType)
                    {
                        XmlBasicType          basicNode          = (XmlBasicType)_currentNode;
                        XmlEntity             collectionOwner    = _currentNode.Parent.Parent as XmlEntity;
                        XmlCollectionProperty collection         = _currentNode.Parent as XmlCollectionProperty; //the collection to add to;
                        IPersistIfc           ifcCollectionOwner = collectionOwner.Entity;
                        PropertyValue         pv = new PropertyValue();
                        pv.Init(basicNode.Value, basicNode.Type);
                        ifcCollectionOwner.IfcParse(collection.PropertyIndex - 1, pv);
                    }
                }


                writeEntity = null;
                if (_currentNode.Parent != null) // we are not at UOS yet
                {
                    if (_currentNode is XmlEntity)
                    {
                        writeEntity = ((XmlEntity)_currentNode).Entity;
                    }
                    _currentNode = _currentNode.Parent;
                }
            }
            catch (Exception e)
            {
                throw new Exception("Error reading IfcXML data at node " + input.LocalName, e);
            }
        }
        private void StartElement(XmlReader input)
        {
            var  elementName = input.LocalName;
            bool isRefType;
            var  id = GetId(input, out isRefType);

            ExpressType expressType;

            StepParserType      parserType;
            ExpressMetaProperty prop;
            int propIndex;


            if (id.HasValue && IsIfcEntity(elementName, out expressType)) //we have an element which is an Ifc Entity
            {
                var ent = _create(id.Value, expressType.Type);

                var xmlEnt = new XmlEntity(_currentNode, ent);

                //if we have a completely empty element that is not a ref we need to make sure it is written to the database as EndElement will not be called
                if (input.IsEmptyElement && !isRefType)
                {
                    _entitiesParsed++;
                    _finish(ent);
                }


                var pos = input.GetAttribute(_posAttribute);
                if (string.IsNullOrEmpty(pos))
                {
                    pos = input.GetAttribute("pos");                            //try without namespace
                }
                if (!string.IsNullOrEmpty(pos))
                {
                    xmlEnt.Position = Convert.ToInt32(pos);
                }
                if (!input.IsEmptyElement)
                {
                    // add the entity to its parent if its parent is a list
                    //if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    //    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);

                    _currentNode = xmlEnt;
                }
                else if (_currentNode is XmlProperty)
                {
                    // if it is a ref then it will be empty element and wont have an end tag
                    // so nither SetValue nor EndElement will be called, so set the value of ref here e.g. #3
                    ((XmlProperty)(_currentNode)).SetValue(ent);
                }
                else if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);
                }
            }
            else if (input.IsEmptyElement)
            {
                if (IsIfcProperty(elementName, out propIndex, out prop))
                {
                    var node    = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);
                    var propVal = new PropertyValue();
                    var t       = node.Property.PropertyType;

                    if (typeof(IExpressEnumerable).IsAssignableFrom(t))
                    {
                        return;
                    }
                    if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        t = Nullable.GetUnderlyingType(t);
                    }
                    IExpressValueType et = null;
                    if (t != null && typeof(IExpressValueType).IsAssignableFrom(t))
                    {
                        et = (IExpressValueType)(Activator.CreateInstance(t));
                    }

                    var pt = StepParserType.Undefined;
                    if (et != null)
                    {
                        pt = Primitives[et.UnderlyingSystemType.Name];
                    }
                    else
                    {
                        if (t != null && t.IsEnum)
                        {
                            pt = StepParserType.Enum;
                        }
                        else
                        {
                            if (t != null)
                            {
                                pt = Primitives[t.Name];
                            }
                        }
                    }

                    switch (pt.ToString().ToLower())
                    {
                    case "string":
                        propVal.Init("'" + input.Value + "'", pt);
                        break;

                    case "boolean":
                        propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F", pt);
                        break;

                    default:
                        propVal.Init(input.Value, pt);
                        break;
                    }
                    ((XmlEntity)node.Parent).Entity.Parse(node.PropertyIndex - 1, propVal, null);
                }
                else if (IsIfcType(elementName, out expressType))
                {
                    var param = new object[1];
                    param[0] = ""; // empty element
                    var ent = (IPersist)Activator.CreateInstance(expressType.Type, param);

                    ((XmlProperty)_currentNode).SetValue(ent);
                }
            }
            else if (!id.HasValue && IsIfcProperty(elementName, out propIndex, out prop)) //we have an element which is a property
            {
                var cType = input.GetAttribute(_cTypeAttribute);
                if (string.IsNullOrEmpty(cType))
                {
                    cType = input.GetAttribute("cType"); //in case namespace omitted
                }
                if (IsCollection(prop))                  //the property is a collection
                {
                    var xmlColl = new XmlCollectionProperty(_currentNode, prop.PropertyInfo, propIndex);
                    switch (cType)
                    {
                    case "list":
                        xmlColl.CType = CollectionType.List;
                        break;

                    case "list-unique":
                        xmlColl.CType = CollectionType.ListUnique;
                        break;

                    case "set":
                        xmlColl.CType = CollectionType.Set;
                        break;

                    default:
                        xmlColl.CType = CollectionType.List;
                        break;
                    }

                    _currentNode = xmlColl;
                }
                else //it is a simple value property;
                {
                    // its parent can be a collection, if yes then this property needs to be added to parent
                    XmlNode n = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);
                    var     collectionProperty = _currentNode as XmlCollectionProperty;
                    if (collectionProperty != null && !(collectionProperty.Parent is XmlUosCollection))
                    {
                        collectionProperty.Entities.Add(n);
                    }

                    if (!input.IsEmptyElement)
                    {
                        _currentNode = n;
                    }
                }
            }
            else if (!id.HasValue && IsIfcType(elementName, out expressType)) // we have an Ifc ExpressType
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlExpressType(_currentNode, expressType.Type);
                var     collectionProperty = _currentNode as XmlCollectionProperty;
                if (collectionProperty != null && !(collectionProperty.Parent is XmlUosCollection))
                {
                    collectionProperty.Entities.Add(n);
                }

                if (!input.IsEmptyElement)
                {
                    _currentNode = n;
                }
            }
            else if (!id.HasValue && IsPrimitiveType(elementName, out parserType)) // we have an basic type i.e. double, bool etc
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlBasicType(_currentNode, parserType);
                var     collectionProperty = _currentNode as XmlCollectionProperty;
                if (collectionProperty != null && !(collectionProperty.Parent is XmlUosCollection))
                {
                    collectionProperty.Entities.Add(n);
                }

                if (!input.IsEmptyElement)
                {
                    _currentNode = n;
                }
            }
            else
            {
                throw new Exception("Illegal XML element tag");
            }
        }
Example #4
0
        private void StartElement(IfcPersistedInstanceCache cache, XmlReader input, XbimEntityCursor entityTable, XbimLazyDBTransaction transaction)
        {
            string elementName = input.LocalName;
            bool   isRefType;
            int?   id = GetId(input, out isRefType);

            IfcType ifcType;

            IfcParserType   parserType;
            IfcMetaProperty prop;
            int             propIndex;


            if (id.HasValue && IsIfcEntity(elementName, out ifcType)) //we have an element which is an Ifc Entity
            {
                IPersistIfcEntity ent;
                if (!cache.Contains(id.Value))
                {
                    // not been declared in a ref yet
                    // model.New creates an instance uisng type and id
                    ent = cache.CreateNew(ifcType.Type, id.Value);
                }
                else
                {
                    ent = cache.GetInstance(id.Value, false, true);
                }

                XmlEntity xmlEnt = new XmlEntity(_currentNode, ent);

                //if we have a completely empty element that is not a ref we need to make sure it is written to the database as EndElement will not be called
                if (input.IsEmptyElement && !isRefType)
                {
                    _entitiesParsed++;
                    //now write the entity to the database
                    entityTable.AddEntity(xmlEnt.Entity);
                    if (_entitiesParsed % _transactionBatchSize == (_transactionBatchSize - 1))
                    {
                        transaction.Commit();
                        transaction.Begin();
                    }
                }


                string pos = input.GetAttribute(_posAttribute);
                if (string.IsNullOrEmpty(pos))
                {
                    pos = input.GetAttribute("pos");                            //try without namespace
                }
                if (!string.IsNullOrEmpty(pos))
                {
                    xmlEnt.Position = Convert.ToInt32(pos);
                }
                if (!input.IsEmptyElement)
                {
                    // add the entity to its parent if its parent is a list
                    //if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    //    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);

                    _currentNode = xmlEnt;
                }
                else if (_currentNode is XmlProperty)
                {
                    // if it is a ref then it will be empty element and wont have an end tag
                    // so nither SetValue nor EndElement will be called, so set the value of ref here e.g. #3
                    ((XmlProperty)(_currentNode)).SetValue(ent);
                }
                else if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);
                }
            }
            else if (input.IsEmptyElement)
            {
                if (IsIfcProperty(elementName, out propIndex, out prop))
                {
                    XmlProperty   node    = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);;
                    PropertyValue propVal = new PropertyValue();
                    Type          t       = node.Property.PropertyType;

                    if (!typeof(ExpressEnumerable).IsAssignableFrom(t)) // if its a empty collection then dont do anything
                    {
                        if (t != null && t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable <>)))
                        {
                            t = Nullable.GetUnderlyingType(t);
                        }
                        ExpressType et = null;
                        if (t != null && typeof(ExpressType).IsAssignableFrom(t))
                        {
                            et = (ExpressType)(Activator.CreateInstance(t));
                        }

                        IfcParserType pt;
                        if (et != null)
                        {
                            pt = primitives[et.UnderlyingSystemType.Name];
                        }
                        else
                        {
                            if (t.IsEnum)
                            {
                                pt = IfcParserType.Enum;
                            }
                            else
                            {
                                pt = primitives[t.Name];
                            }
                        }

                        if (pt.ToString().ToLower() == "string")
                        {
                            propVal.Init("'" + input.Value + "'", pt);
                        }
                        else
                        {
                            if (pt.ToString().ToLower() == "boolean")
                            {
                                propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F", pt);
                            }
                            else
                            {
                                propVal.Init(input.Value, pt);
                            }
                        }
                        ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                    }
                }
                else if (IsIfcType(elementName, out ifcType))
                {
                    IPersistIfc ent;
                    object[]    param = new object[1];
                    param[0] = ""; // empty element
                    ent      = (IPersistIfc)Activator.CreateInstance(ifcType.Type, param);

                    ((XmlProperty)_currentNode).SetValue(ent);
                }

                return;
            }
            else if (!id.HasValue && IsIfcProperty(elementName, out propIndex, out prop)) //we have an element which is a property
            {
                string cType = input.GetAttribute(_cTypeAttribute);
                if (string.IsNullOrEmpty(cType))
                {
                    cType = input.GetAttribute("cType"); //in case namespace omitted
                }
                if (IsCollection(prop))                  //the property is a collection
                {
                    XmlCollectionProperty xmlColl = new XmlCollectionProperty(_currentNode, prop.PropertyInfo, propIndex);
                    switch (cType)
                    {
                    case "list":
                        xmlColl.CType = CollectionType.List;
                        break;

                    case "list-unique":
                        xmlColl.CType = CollectionType.ListUnique;
                        break;

                    case "set":
                        xmlColl.CType = CollectionType.Set;
                        break;

                    default:
                        xmlColl.CType = CollectionType.List;
                        break;
                    }

                    _currentNode = xmlColl;
                }
                else //it is a simple value property;
                {
                    // its parent can be a collection, if yes then this property needs to be added to parent
                    XmlNode n = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);
                    if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    {
                        ((XmlCollectionProperty)_currentNode).Entities.Add(n);
                    }

                    if (!input.IsEmptyElement)
                    {
                        _currentNode = n;
                    }
                }
            }
            else if (!id.HasValue && IsIfcType(elementName, out ifcType)) // we have an Ifc ExpressType
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlExpressType(_currentNode, ifcType.Type);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);
                }

                if (!input.IsEmptyElement)
                {
                    _currentNode = n;
                }
            }
            else if (!id.HasValue && IsPrimitiveType(elementName, out parserType)) // we have an basic type i.e. double, bool etc
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlBasicType(_currentNode, parserType);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);
                }

                if (!input.IsEmptyElement)
                {
                    _currentNode = n;
                }
            }
            else
            {
                throw new Exception("Illegal XML element tag");
            }
        }
Example #5
0
        private void StartElement(IfcPersistedInstanceCache cache, XmlReader input, XbimEntityCursor entityTable, XbimLazyDBTransaction transaction)
        {
            string elementName = input.LocalName;
            bool isRefType;
            int id = GetId(input, out isRefType);

            IfcType ifcType;
            
            IfcParserType parserType;
            IfcMetaProperty prop;
            int propIndex;


            if (id > -1 && IsIfcEntity(elementName, out ifcType)) //we have an element which is an Ifc Entity
            {
                IPersistIfcEntity ent;
                if (!cache.Contains(id))
                {
                    // not been declared in a ref yet
                    // model.New creates an instance uisng type and id
                    ent = cache.CreateNew(ifcType.Type, id);
                   
                }
                else
                {
                    ent = cache.GetInstance(id, false, true);
                }

                XmlEntity xmlEnt = new XmlEntity(_currentNode, ent);
               
                //if we have a completely empty element that is not a ref we need to make sure it is written to the database as EndElement will not be called
                if (input.IsEmptyElement && !isRefType)
                {
                    _entitiesParsed++;
                    //now write the entity to the database
                    entityTable.AddEntity(xmlEnt.Entity);
                    if (_entitiesParsed % _transactionBatchSize == (_transactionBatchSize - 1))
                    {
                        transaction.Commit();
                        transaction.Begin();
                    }
                    

                }


                string pos = input.GetAttribute(_posAttribute);
                if (string.IsNullOrEmpty(pos)) pos = input.GetAttribute("pos"); //try without namespace
                if (!string.IsNullOrEmpty(pos))
                    xmlEnt.Position = Convert.ToInt32(pos);
                if (!input.IsEmptyElement)
                {
                    // add the entity to its parent if its parent is a list
                    //if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    //    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);

                    _currentNode = xmlEnt;
                }
                else if (_currentNode is XmlProperty)
                {
                    // if it is a ref then it will be empty element and wont have an end tag
                    // so nither SetValue nor EndElement will be called, so set the value of ref here e.g. #3
                    ((XmlProperty)(_currentNode)).SetValue(ent);
                }
                else if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);
                }
            }
            else if (input.IsEmptyElement)
            {
                if (IsIfcProperty(elementName, out propIndex, out prop))
                {
                    XmlProperty node = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex); ;
                    PropertyValue propVal = new PropertyValue();
                    Type t = node.Property.PropertyType;

                    if (!typeof(ExpressEnumerable).IsAssignableFrom(t)) // if its a empty collection then dont do anything
                    {
                        if (t != null && t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                            t = Nullable.GetUnderlyingType(t);
                        ExpressType et = null;
                        if (t != null && typeof(ExpressType).IsAssignableFrom(t))
                            et = (ExpressType)(Activator.CreateInstance(t));

                        IfcParserType pt;
                        if (et != null)
                            pt = primitives[et.UnderlyingSystemType.Name];
                        else
                        {
                            if (t.IsEnum)
                            {
                                pt = IfcParserType.Enum;
                            }
                            else
                                pt = primitives[t.Name];
                        }

                        if (pt.ToString().ToLower() == "string")
                            propVal.Init("'" + input.Value + "'", pt);
                        else
                        {
                            if (pt.ToString().ToLower() == "boolean")
                                propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F", pt);
                            else
                                propVal.Init(input.Value, pt);
                        }
                        ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                    }

                }
                else if (IsIfcType(elementName, out ifcType))
                {
                    IPersistIfc ent;
                    object[] param = new object[1];
                    param[0] = ""; // empty element
                    ent = (IPersistIfc)Activator.CreateInstance(ifcType.Type, param);

                    ((XmlProperty)_currentNode).SetValue(ent);
                }

                return;
            }
            else if (id == -1 && IsIfcProperty(elementName, out propIndex, out prop)) //we have an element which is a property
            {

                string cType = input.GetAttribute(_cTypeAttribute);
                if (string.IsNullOrEmpty(cType)) cType = input.GetAttribute("cType"); //in case namespace omitted
                if (IsCollection(prop)) //the property is a collection
                {
                    XmlCollectionProperty xmlColl = new XmlCollectionProperty(_currentNode, prop.PropertyInfo, propIndex);
                    switch (cType)
                    {
                        case "list":
                            xmlColl.CType = CollectionType.List;
                            break;
                        case "list-unique":
                            xmlColl.CType = CollectionType.ListUnique;
                            break;
                        case "set":
                            xmlColl.CType = CollectionType.Set;
                            break;
                        default:
                            xmlColl.CType = CollectionType.List;
                            break;
                    }

                    _currentNode = xmlColl;
                }
                else //it is a simple value property;
                {


                    // its parent can be a collection, if yes then this property needs to be added to parent
                    XmlNode n = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);
                    if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                        ((XmlCollectionProperty)_currentNode).Entities.Add(n);

                    if (!input.IsEmptyElement) _currentNode = n;
                }
            }
            else if (id == -1 && IsIfcType(elementName, out ifcType)) // we have an Ifc ExpressType
            {


                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlExpressType(_currentNode, ifcType.Type);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);

                if (!input.IsEmptyElement) _currentNode = n;
            }
            else if (id == -1 && IsPrimitiveType(elementName, out parserType)) // we have an basic type i.e. double, bool etc
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlBasicType(_currentNode, parserType);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);

                if (!input.IsEmptyElement) _currentNode = n;
            }
            else
                throw new Exception("Illegal XML element tag");
        }