示例#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);
            }
        }
示例#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);
            }
        }
示例#3
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");
        }
示例#4
0
 public void SetValue(object o)
 {
     PropertyValue propVal = new PropertyValue();
     propVal.Init(o);
     ((XmlEntity)Parent).Entity.IfcParse(PropertyIndex - 1, propVal);
 }
示例#5
0
 public void SetValue(string val, IfcParserType parserType)
 {
     if (parserType == IfcParserType.Boolean && string.Compare(val, "unknown", true) == 0) //do nothing with IfcLogicals that are undefined
         return;
     PropertyValue propVal = new PropertyValue();
     propVal.Init(val, parserType);
     ((XmlEntity)Parent).Entity.IfcParse(PropertyIndex - 1, propVal);
 }
 public bool Resolve(ConcurrentDictionary<int, IPersistIfcEntity> references)
 {
     IPersistIfcEntity entity;
     if (references.TryGetValue(ReferenceEntityLabel, out entity))
     {
         PropertyValue pv = new PropertyValue();
         pv.Init(entity);
         try
         {
             ReferencingEntity.IfcParse(ReferencingPropertyId, pv);
             return true;
         }
         catch (Exception)
         {
             IfcType ifcType = IfcMetaData.IfcType(ReferencingEntity);
             
             XbimModel.Logger.ErrorFormat("Data Error. Cannot set the property = {0} of entity #{1} = {2} to entity #{3}, schema violation. Ignored", 
                 ifcType.IfcProperties[ReferencingPropertyId+1].PropertyInfo.Name, 
                 ReferencingEntity.EntityLabel,
                 ReferencingEntity.GetType().Name,
                 ReferenceEntityLabel);
             return false;
         }
     }
     else
         return false;
 }