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); } }
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); } }
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"); }
public void SetValue(object o) { PropertyValue propVal = new PropertyValue(); propVal.Init(o); ((XmlEntity)Parent).Entity.IfcParse(PropertyIndex - 1, propVal); }
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; }