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); } }
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"); } }
//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); }
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); } }
public void Set(IExpressValueType value) { Set(value.Value); }