internal bool TrySetObjectValue(IPersist host, int paramIndex, int refId, int[] listNextLevel) { if (_deferListItems) { return(false); } try { if (host != null && Entities.TryGetValue(refId, out IPersist refEntity)) { PropertyValue.Init(refEntity); host.Parse(paramIndex, PropertyValue, listNextLevel); return(true); } } catch (Exception e) { // return silently if this kind of error has already been reported if (_errors.AddPropertyNotSet(host, paramIndex, PropertyValue, e)) { Logger?.LogError(LogEventIds.FailedPropertySetter, e, "Entity #{0,-5} {1}, error at parameter {2}", refId, host.GetType().Name.ToUpper(), paramIndex + 1); ErrorCount++; } } return(false); }
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); } }