예제 #1
0
        private void EndElement(XmlReader input, XmlNodeType prevInputType, string prevInputName, out IPersistEntity writeEntity)
        {
            try
            {
                // before end element, we need to deal with SetCollection
                var collectionProperty = _currentNode as XmlCollectionProperty;
                if (collectionProperty != null)
                {
                    // SetCollection will handle SetValue for Collection
                    var cType = collectionProperty.CType;
                    switch (cType)
                    {
                    case CollectionType.List:
                    case CollectionType.ListUnique:
                        collectionProperty.Entities.Sort(XmlCollectionProperty.CompareNodes);
                        break;

                    case CollectionType.Set:
                        break;

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

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

                        var expressNode = (XmlExpressType)_currentNode;
                        if (expressNode.Type != propNode.Property.PropertyType)
                        {
                            //propNode.SetValue(expressNode);
                            ExpressType expressType;
                            if (IsIfcType(input.LocalName, out expressType))
                            //we have an IPersistIfc
                            {
                                var param = new object[1];
                                param[0] = expressNode.Value;
                                var ent = (IPersist)Activator.CreateInstance(expressType.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

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


                else if (prevInputType == XmlNodeType.Element && prevInputName == input.LocalName &&
                         _currentNode is XmlProperty && _currentNode.Parent is XmlEntity)
                {
                    // WE SHOULDNT EXECUTE THE FOLLOWING CODE IF THIS PROPERTY ALREADY CALLED SETVALUE
                    var node    = (XmlProperty)_currentNode;
                    var propVal = new PropertyValue();
                    var t       = node.Property.PropertyType;
                    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 && Primitives.ContainsKey(t.Name))
                        {
                            pt = Primitives[t.Name];
                        }
                    }

                    if (pt != StepParserType.Undefined)
                    {
                        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 (_currentNode.Parent is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    var entity = _currentNode as XmlEntity;
                    if (entity != null)
                    {
                        ((XmlCollectionProperty)entity.Parent).Entities.Add(entity);
                    }
                    else if (_currentNode is XmlExpressType)
                    {
                        var expressNode = (XmlExpressType)_currentNode;
                        //actualEntityType is the actual type of the value to create
                        var actualEntityType = expressNode.Type;
                        //Determine if the Express Type is a Nullable, if so get the type of the Nullable
                        if (actualEntityType.IsGenericType && actualEntityType.GetGenericTypeDefinition() == 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
                        var collection                   = (XmlCollectionProperty)_currentNode.Parent; //the collection to add to;
                        var collectionValueType          = collection.Property.PropertyType;
                        var collectionGenericType        = GetItemTypeFromGenericType(collectionValueType);
                        var genericTypeIsSameAsValueType = (collectionGenericType == actualEntityType);
                        var pv = new PropertyValue();

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

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


                writeEntity = null;
                if (_currentNode.Parent == null)
                {
                    return;
                }
                var currentNode = _currentNode as XmlEntity;
                if (currentNode != null)
                {
                    writeEntity = currentNode.Entity;
                }
                _currentNode = _currentNode.Parent;
            }
            catch (Exception e)
            {
                throw new Exception("Error reading IfcXML data at node " + input.LocalName, e);
            }
        }
예제 #2
0
        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");
            }
        }
예제 #3
0
        //private static void SetCoBieAttributeValue<TCoBieValueBaseType>(TCoBieValueBaseType result, IIfcValue ifcValue) where TCoBieValueBaseType : AttributeValue
        //{
        //    SetCoBieAttributeValue(result, (IExpressValueType)ifcValue);
        //}


        private static bool TryGetSimpleValue <TSimpleType>(IExpressValueType ifcValue, out TSimpleType result)
        {
            var targetType = typeof(TSimpleType);

            //handle null value if is it acceptable
            if (ifcValue == null || ifcValue.Value == null)
            {
                result = default(TSimpleType);
                //return true if null is acceptable value
                return(targetType.IsClass ||
                       (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable <>)));
            }

            if (typeof(TSimpleType) == typeof(string))
            {
                result = (TSimpleType)(object)ifcValue.ToString();
                return(true);
            }

            if (targetType == typeof(float) ||
                targetType == typeof(float?) ||
                targetType == typeof(double) ||
                targetType == typeof(double?))
            {
                try
                {
                    result = (TSimpleType)(object)Convert.ToDouble(ifcValue.Value, CultureInfo.InvariantCulture);
                    return(true);
                }
                catch (NullReferenceException)
                {
                    if (typeof(TSimpleType) == typeof(float?) ||
                        typeof(TSimpleType) == typeof(double?))
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("ifcValue is null.");
                }
                catch (ArgumentNullException)
                {
                    if (typeof(TSimpleType) == typeof(float?) ||
                        typeof(TSimpleType) == typeof(double?))
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("Decimal Conversion: String is null.");
                }
                catch (FormatException)
                {
                    if (typeof(TSimpleType) == typeof(float?) ||
                        typeof(TSimpleType) == typeof(double?))
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("Decimal Conversion: String does not consist of an " + "optional sign followed by a series of digits.");
                }
                catch (OverflowException)
                {
                    if (typeof(TSimpleType) == typeof(float?) ||
                        typeof(TSimpleType) == typeof(double?))
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("Decimal Conversion: Overflow in string to int conversion.");
                }
                result = default(TSimpleType);
                return(false);
            }
            if (targetType == typeof(bool) || targetType == typeof(bool?))
            {
                try
                {
                    result = (TSimpleType)(object)Convert.ToBoolean(ifcValue.Value);
                    return(true);
                }
                catch (NullReferenceException)
                {
                    if (typeof(TSimpleType) == typeof(bool?))
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("ifcValue is null.");
                }
                catch (ArgumentNullException)
                {
                    if (typeof(TSimpleType) == typeof(bool?))
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("Boolean Conversion: String is null.");
                }
                catch (FormatException)
                {
                    //logger.WarnFormat("Boolean Conversion: String does not consist of an " + "optional sign followed by a series of digits.");
                }
                catch (OverflowException)
                {
                    //logger.WarnFormat("Boolean Conversion: Overflow in string to int conversion.");
                }
                result = default(TSimpleType);
                return(false);
            }

            if (
                targetType == typeof(int) ||
                targetType == typeof(int?) ||
                targetType == typeof(long) ||
                targetType == typeof(long?)
                )
            {
                try
                {
                    //this looks like an error in COBieLite, suggest should be same as Decimal and Boolean
                    result = (TSimpleType)(object)Convert.ToInt32(ifcValue.Value);
                    return(true);
                }
                catch (NullReferenceException)
                {
                    if (
                        targetType == typeof(int?) ||
                        targetType == typeof(long?)
                        )
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("ifcValue is null.");
                }
                catch (ArgumentNullException)
                {
                    if (
                        targetType == typeof(int?) ||
                        targetType == typeof(long?)
                        )
                    {
                        result = default(TSimpleType);
                        return(true);
                    }
                    //logger.WarnFormat("Integer Conversion: String is null.");
                }
                catch (FormatException)
                {
                    //logger.WarnFormat("Integer Conversion: String does not consist of an " +
                    //                                  "optional sign followed by a series of digits.");
                }
                catch (OverflowException)
                {
                    //logger.WarnFormat("Integer Conversion: Overflow in string to int conversion.");
                }
                result = default(TSimpleType);
                return(false);
            }
            if (targetType == typeof(DateTime) || targetType == typeof(DateTime?))
            {
                try
                {
                    result = (TSimpleType)(object)Convert.ToDateTime(ifcValue.Value);
                    return(true);
                }
                catch (Exception)
                {
                    result = default(TSimpleType);
                    return(targetType == typeof(DateTime?));
                }
            }

            logger.LogWarning("Unexpected type {target}", targetType.Name);
            result = default(TSimpleType);
            return(false);
        }
예제 #4
0
        private static void SetCoBieAttributeValue <TCoBieValueBaseType>(TCoBieValueBaseType result, IExpressValueType ifcValue) where TCoBieValueBaseType : AttributeValue
        {
            var stringValueType  = result as StringAttributeValue;
            var decimalValueType = result as DecimalAttributeValue;
            var booleanValueType = result as BooleanAttributeValue;
            var integerValueType = result as IntegerAttributeValue;
            var str = ifcValue.ToString();

            if (string.IsNullOrWhiteSpace(str))
            {
                return;
            }
            if (stringValueType != null)
            {
                stringValueType.Value = ifcValue.ToString();
            }
            else if (decimalValueType != null)
            {
                try
                {
                    decimalValueType.Value = ConvertToDouble(str);
                }
                catch (NullReferenceException)
                {
                    //Logger.WarnFormat("ifcValue is null.");
                }
                catch (ArgumentNullException)
                {
                    //Logger.WarnFormat("Decimal Conversion: String is null.");
                }
                catch (FormatException)
                {
                    //Logger.WarnFormat("Decimal Conversion: String does not consist of an " + "optional sign followed by a series of digits.");
                }
                catch (OverflowException)
                {
                    //Logger.WarnFormat("Decimal Conversion: Overflow in string to int conversion.");
                }
            }
            else if (booleanValueType != null)
            {
                try
                {
                    booleanValueType.Value = Convert.ToBoolean(ifcValue.Value);
                }
                catch (NullReferenceException)
                {
                    //Logger.WarnFormat("ifcValue is null.");
                }
                catch (ArgumentNullException)
                {
                    //Logger.WarnFormat("Boolean Conversion: String is null.");
                }
                catch (FormatException)
                {
                    //Logger.WarnFormat("Boolean Conversion: String does not consist of an " + "optional sign followed by a series of digits.");
                }
                catch (OverflowException)
                {
                    //Logger.WarnFormat("Boolean Conversion: Overflow in string to int conversion.");
                }
            }
            else if (integerValueType != null)
            {
                try
                {
                    //this looks like an error in COBieLite, suggest should be same as Decimal and Boolean
                    integerValueType.Value = ConvertToInt(str);
                }
                catch (NullReferenceException)
                {
                    //Logger.WarnFormat("ifcValue is null.");
                }
                catch (ArgumentNullException)
                {
                    //Logger.WarnFormat("Integer Conversion: String is null.");
                }
                catch (FormatException)
                {
                    //Logger.WarnFormat("Integer Conversion: String does not consist of an " +
                    //                                  "optional sign followed by a series of digits.");
                }
                catch (OverflowException)
                {
                    //Logger.WarnFormat("Integer Conversion: Overflow in string to int conversion.");
                }
            }
            else
            {
                Logger.LogWarning("Unexpected ValueBaseType", ifcValue);
            }
        }
예제 #5
0
 public void Set(IExpressValueType value)
 {
     Set(value.Value);
 }