/// <summary>
 /// Returns an instance from the Model with the corresponding label
 /// </summary>
 /// <param name="label">entity label to retrieve</param>
 /// <returns></returns>
 public IPersistIfcEntity this[int label]
 {
     get
     {
         return(cache.GetInstance(label, true, true));
     }
 }
        /// <summary>
        /// Populates an entites properties from the binary stream
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cache"></param>
        /// <param name="br"></param>
        /// <param name="unCached">If true instances inside the properties are not added to the cache</param>
        /// <param name="fromCache"> If true the instance is read from the cache if not present it is created, used during parsing
        public static void ReadEntityProperties(this IPersistIfcEntity entity, IfcPersistedInstanceCache cache, BinaryReader br, bool unCached = false,bool fromCache = false)
        {
            P21ParseAction action = (P21ParseAction)br.ReadByte();

            XbimParserState parserState = new XbimParserState(entity);
            while (action != P21ParseAction.EndEntity)
            {
                switch (action)
                {
                    case P21ParseAction.BeginList:
                        parserState.BeginList();
                        break;
                    case P21ParseAction.EndList:
                        parserState.EndList();
                        break;
                    case P21ParseAction.BeginComplex:
                        break;
                    case P21ParseAction.EndComplex:
                        break;
                    case P21ParseAction.SetIntegerValue:
                        parserState.SetIntegerValue(br.ReadInt64());
                        break;
                    case P21ParseAction.SetHexValue:
                        parserState.SetHexValue(br.ReadInt64());
                        break;
                    case P21ParseAction.SetFloatValue:
                        parserState.SetFloatValue(br.ReadDouble());
                        break;
                    case P21ParseAction.SetStringValue:
                        parserState.SetStringValue(br.ReadString());
                        break;
                    case P21ParseAction.SetEnumValue:
                        parserState.SetEnumValue(br.ReadString());
                        break;
                    case P21ParseAction.SetBooleanValue:
                        parserState.SetBooleanValue(br.ReadBoolean());
                        break;
                    case P21ParseAction.SetNonDefinedValue:
                        parserState.SetNonDefinedValue();
                        break;
                    case P21ParseAction.SetOverrideValue:
                        parserState.SetOverrideValue();
                        break;
                    case P21ParseAction.SetObjectValueUInt16:
                        if (fromCache)
                        {
                            int label = br.ReadUInt16();
                            IPersistIfcEntity refEntity;
                            if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity)) //if we are in a list then make a forward reference anyway to make sure we maintain list order
                                parserState.SetObjectValue(refEntity);
                            else
                            {
                                cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                                parserState.SkipProperty();
                            }
                        }
                        else
                            parserState.SetObjectValue(cache.GetInstance(br.ReadUInt16(), false, unCached));
                        break;
                    case P21ParseAction.SetObjectValueInt32:
                        if (fromCache)
                        {
                            int label = br.ReadInt32();
                            IPersistIfcEntity refEntity;
                            if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity)) //if we are in a list then make a forward reference anyway to make sure we maintain list order
                                parserState.SetObjectValue(refEntity);
                            else
                            {
                                cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                                parserState.SkipProperty();
                            }
                        }
                        else
                            parserState.SetObjectValue(cache.GetInstance(br.ReadInt32(), false, unCached));
                        break;
                    case P21ParseAction.SetObjectValueInt64:
                        throw new XbimException("Entity Label is int64, this is not currently supported");
                        //parserState.SetObjectValue(cache.GetInstance(br.ReadInt64(), false, unCached));
                        //break;
                    case P21ParseAction.BeginNestedType:
                        parserState.BeginNestedType(br.ReadString());
                        break;
                    case P21ParseAction.EndNestedType:
                        parserState.EndNestedType();
                        break;
                    case P21ParseAction.EndEntity:
                        parserState.EndEntity();
                        break;
                    case P21ParseAction.NewEntity:
                        parserState = new XbimParserState(entity);
                        break;
                    default:
                        throw new XbimException("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name);
                }
                action = (P21ParseAction)br.ReadByte();
            }
        }
Exemple #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");
        }
Exemple #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");
            }
        }
Exemple #5
0
        /// <summary>
        /// Populates an entites properties from the binary stream
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cache"></param>
        /// <param name="br"></param>
        /// <param name="unCached">If true instances inside the properties are not added to the cache</param>
        /// <param name="fromCache"> If true the instance is read from the cache if not present it is created, used during parsing</param>
        public static void ReadEntityProperties(this IPersistIfcEntity entity, IfcPersistedInstanceCache cache, BinaryReader br, bool unCached = false, bool fromCache = false)
        {
            P21ParseAction action = (P21ParseAction)br.ReadByte();

            XbimParserState parserState = new XbimParserState(entity);

            while (action != P21ParseAction.EndEntity)
            {
                switch (action)
                {
                case P21ParseAction.BeginList:
                    parserState.BeginList();
                    break;

                case P21ParseAction.EndList:
                    parserState.EndList();
                    break;

                case P21ParseAction.BeginComplex:
                    break;

                case P21ParseAction.EndComplex:
                    break;

                case P21ParseAction.SetIntegerValue:
                    parserState.SetIntegerValue(br.ReadInt64());
                    break;

                case P21ParseAction.SetHexValue:
                    parserState.SetHexValue(br.ReadInt64());
                    break;

                case P21ParseAction.SetFloatValue:
                    parserState.SetFloatValue(br.ReadDouble());
                    break;

                case P21ParseAction.SetStringValue:
                    parserState.SetStringValue(br.ReadString());
                    break;

                case P21ParseAction.SetEnumValue:
                    parserState.SetEnumValue(br.ReadString());
                    break;

                case P21ParseAction.SetBooleanValue:
                    parserState.SetBooleanValue(br.ReadBoolean());
                    break;

                case P21ParseAction.SetNonDefinedValue:
                    parserState.SetNonDefinedValue();
                    break;

                case P21ParseAction.SetOverrideValue:
                    parserState.SetOverrideValue();
                    break;

                case P21ParseAction.SetObjectValueUInt16:
                    if (fromCache)
                    {
                        int label = br.ReadUInt16();
                        IPersistIfcEntity refEntity;
                        if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity))     //if we are in a list then make a forward reference anyway to make sure we maintain list order
                        {
                            parserState.SetObjectValue(refEntity);
                        }
                        else
                        {
                            cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                            parserState.SkipProperty();
                        }
                    }
                    else
                    {
                        parserState.SetObjectValue(cache.GetInstance(br.ReadUInt16(), false, unCached));
                    }
                    break;

                case P21ParseAction.SetObjectValueInt32:
                    if (fromCache)
                    {
                        int label = br.ReadInt32();
                        IPersistIfcEntity refEntity;
                        if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity))     //if we are in a list then make a forward reference anyway to make sure we maintain list order
                        {
                            parserState.SetObjectValue(refEntity);
                        }
                        else
                        {
                            cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                            parserState.SkipProperty();
                        }
                    }
                    else
                    {
                        parserState.SetObjectValue(cache.GetInstance(br.ReadInt32(), false, unCached));
                    }
                    break;

                case P21ParseAction.SetObjectValueInt64:
                    throw new XbimException("Entity Label is int64, this is not currently supported");

                //parserState.SetObjectValue(cache.GetInstance(br.ReadInt64(), false, unCached));
                //break;
                case P21ParseAction.BeginNestedType:
                    parserState.BeginNestedType(br.ReadString());
                    break;

                case P21ParseAction.EndNestedType:
                    parserState.EndNestedType();
                    break;

                case P21ParseAction.EndEntity:
                    parserState.EndEntity();
                    break;

                case P21ParseAction.NewEntity:
                    parserState = new XbimParserState(entity);
                    break;

                default:
                    throw new XbimException("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name);
                }
                action = (P21ParseAction)br.ReadByte();
            }
        }