/// <summary> /// Create a new entity of the specified type, the entity will be blank, all properties with default values /// The entity label will be as specified, an exception will be raised if the label is already in use /// </summary> /// <param name="type">Type of entity to create, this must support IPersistIfcEntity</param> /// <returns>A handle to the entity</returns> internal XbimInstanceHandle AddEntity(Type type, int entityLabel) { IfcType ifcType = IfcMetaData.IfcType(type); XbimInstanceHandle h = new XbimInstanceHandle(this.model, entityLabel, ifcType.TypeId); AddEntity(h.EntityLabel, h.EntityTypeId, null, null, ifcType.IndexedClass); return(h); }
/// <summary> /// Converts a XbimInstanceHandle into an XbimInstance, this is NOT and undoable action /// </summary> /// <param name="model"></param> /// <param name="handle"></param> /// <returns></returns> internal IPersistIfcEntity CreateEntity(IModel model, XbimInstanceHandle handle) { IPersistIfcEntity entity = (IPersistIfcEntity)Activator.CreateInstance(handle.EntityType); entity.Bind(model, (handle.EntityLabel * -1)); //a negative handle determines that the attributes of this entity have not been loaded yet XbimInstance inst = new XbimInstance(entity, handle.FileOffset); this[handle.EntityLabel] = inst; return(entity); }
/// <summary> /// Create a new entity of the specified type, the entity will be blank, all properties with default values /// </summary> /// <param name="type">Type of entity to create, this must support IPersistIfcEntity</param> /// <returns>A handle to the entity</returns> internal XbimInstanceHandle AddEntity(Type type) { //System.Diagnostics.Debug.Assert(typeof(IPersistIfcEntity).IsAssignableFrom(type)); int highest = RetrieveHighestLabel(); IfcType ifcType = IfcMetaData.IfcType(type); XbimInstanceHandle h = new XbimInstanceHandle(this.model, highest + 1, ifcType.TypeId); AddEntity(h.EntityLabel, h.EntityTypeId, null, null, ifcType.IndexedClass); return(h); }
/// <summary> /// For use only on the index table, accesses data from the index only /// </summary> /// <param name="ih"></param> /// <returns></returns> public bool TryMoveNextEntityType(out XbimInstanceHandle ih) { if (Api.TryMoveNext(this.sesid, this._indexTable)) { ih = new XbimInstanceHandle(this.model, Api.RetrieveColumnAsInt32(sesid, _indexTable, _colIdIdxEntityLabel, RetrieveColumnGrbit.RetrieveFromIndex), Api.RetrieveColumnAsInt16(sesid, _indexTable, _colIdIdxIfcType, RetrieveColumnGrbit.RetrieveFromIndex)); return(true); } else { ih = new XbimInstanceHandle(); return(false); } }
/// <summary> /// Trys to move to the first entity of the specified type, assumes the current index has been set to order by type (SetOrderByType) /// Secondary keys are specific to the type and defined as IfcAttributes in the class declaration /// </summary> /// <param name="typeId">the type of entity to look up</param> /// <param name="lookupKey">Secondary key on the search</param> /// <returns>Returns an instance handle to the first or an empty handle if not found</returns> public bool TrySeekEntityType(short typeId, out XbimInstanceHandle ih, int lookupKey) { Api.MakeKey(sesid, _indexTable, typeId, MakeKeyGrbit.NewKey); Api.MakeKey(sesid, _indexTable, lookupKey, MakeKeyGrbit.None); if (Api.TrySeek(sesid, _indexTable, SeekGrbit.SeekGE)) { Api.MakeKey(sesid, _indexTable, typeId, MakeKeyGrbit.NewKey); Api.MakeKey(sesid, _indexTable, lookupKey, MakeKeyGrbit.FullColumnEndLimit); if (Api.TrySetIndexRange(sesid, _indexTable, SetIndexRangeGrbit.RangeUpperLimit | SetIndexRangeGrbit.RangeInclusive)) { ih = new XbimInstanceHandle(this.model, Api.RetrieveColumnAsInt32(sesid, _indexTable, _colIdIdxEntityLabel, RetrieveColumnGrbit.RetrieveFromIndex), Api.RetrieveColumnAsInt16(sesid, _indexTable, _colIdIdxIfcType, RetrieveColumnGrbit.RetrieveFromIndex)); return(true); } } ih = new XbimInstanceHandle(); return(false); }
/// <summary> /// Inserts deep copy of an object into this model. The entity must originate from the same schema (the same EntityFactory). /// This operation happens within a transaction which you have to handle yourself unless you set the parameter "noTransaction" to true. /// Insert will happen outside of transactional behaviour in that case. Resulting model is not guaranteed to be valid according to any /// model view definition. However, it is granted to be consistent. You can optionaly bring in all inverse relationships. Be carefull as it /// might easily bring in almost full model. /// /// </summary> /// <typeparam name="T">Type of the copied entity</typeparam> /// <param name="model">Model to be used as a target</param> /// <param name="toCopy">Entity to be copied</param> /// <param name="mappings">Mappings of previous inserts</param> /// <param name="includeInverses">Option if to bring in all inverse entities (enumerations in original entity)</param> /// <param name="keepLabels">Option if to keep entity labels the same</param> /// <param name="propTransform">Optional delegate which you can use to filter the content which will get coppied over.</param> /// <param name="getLabeledEntity">Functor to be used to create entity with specified label</param> /// <returns>Copy from this model</returns> public static T InsertCopy <T>(IModel model, T toCopy, XbimInstanceHandleMap mappings, PropertyTranformDelegate propTransform, bool includeInverses, bool keepLabels, Func <Type, int, IPersistEntity> getLabeledEntity) where T : IPersistEntity { try { var toCopyLabel = toCopy.EntityLabel; XbimInstanceHandle copyHandle; var toCopyHandle = new XbimInstanceHandle(toCopy); //try to get the value if it was created before if (mappings.TryGetValue(toCopyHandle, out copyHandle)) { return((T)copyHandle.GetEntity()); } var expressType = model.Metadata.ExpressType(toCopy); var copy = keepLabels ? getLabeledEntity(toCopy.GetType(), toCopyLabel) : model.Instances.New(toCopy.GetType()); copyHandle = new XbimInstanceHandle(copy); //key is the label in original model mappings.Add(toCopyHandle, copyHandle); var props = expressType.Properties.Values.Where(p => !p.EntityAttribute.IsDerived); if (includeInverses) { props = props.Union(expressType.Inverses); } foreach (var prop in props) { var value = propTransform != null ? propTransform(prop, toCopy) : prop.PropertyInfo.GetValue(toCopy, null); if (value == null) { continue; } var isInverse = (prop.EntityAttribute.Order == -1); //don't try and set the values for inverses var theType = value.GetType(); //if it is an express type or a value type, set the value if (theType.IsValueType || typeof(ExpressType).IsAssignableFrom(theType) || theType == typeof(string)) { prop.PropertyInfo.SetValue(copy, value, null); } else if (!isInverse && typeof(IPersistEntity).IsAssignableFrom(theType)) { prop.PropertyInfo.SetValue(copy, InsertCopy(model, (IPersistEntity)value, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity), null); } else if (!isInverse && typeof(IList).IsAssignableFrom(theType)) { var itemType = theType.GetItemTypeFromGenericType(); var copyColl = prop.PropertyInfo.GetValue(copy, null) as IList; if (copyColl == null) { throw new Exception(string.Format("Unexpected collection type ({0}) found", itemType.Name)); } foreach (var item in (IList)value) { var actualItemType = item.GetType(); if (actualItemType.IsValueType || typeof(ExpressType).IsAssignableFrom(actualItemType)) { copyColl.Add(item); } else if (typeof(IPersistEntity).IsAssignableFrom(actualItemType)) { var cpy = InsertCopy(model, (IPersistEntity)item, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); copyColl.Add(cpy); } else if (typeof(IList).IsAssignableFrom(actualItemType)) //list of lists { var listColl = (IList)item; var getAt = copyColl.GetType().GetMethod("GetAt"); if (getAt == null) { throw new Exception(string.Format("GetAt Method not found on ({0}) found", copyColl.GetType().Name)); } var copyListColl = getAt.Invoke(copyColl, new object[] { copyColl.Count }) as IList; if (copyListColl == null) { throw new XbimException("Collection can't be used as IList"); } foreach (var listItem in listColl) { var actualListItemType = listItem.GetType(); if (actualListItemType.IsValueType || typeof(ExpressType).IsAssignableFrom(actualListItemType)) { copyListColl.Add(listItem); } else if (typeof(IPersistEntity).IsAssignableFrom(actualListItemType)) { var cpy = InsertCopy(model, (IPersistEntity)listItem, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); copyListColl.Add(cpy); } else { throw new Exception(string.Format("Unexpected collection item type ({0}) found", itemType.Name)); } } } else { throw new Exception(string.Format("Unexpected collection item type ({0}) found", itemType.Name)); } } } else if (isInverse && value is IEnumerable <IPersistEntity> ) //just an enumeration of IPersistEntity { foreach (var ent in (IEnumerable <IPersistEntity>)value) { InsertCopy(model, ent, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); } } else if (isInverse && value is IPersistEntity) //it is an inverse and has a single value { InsertCopy(model, (IPersistEntity)value, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); } else { throw new Exception(string.Format("Unexpected item type ({0}) found", theType.Name)); } } return((T)copy); } catch (Exception e) { throw new XbimException(string.Format("General failure in InsertCopy ({0})", e.Message), e); } }
/// <summary> /// Returns the instance that corresponds to this handle /// </summary> /// <param name="handle"></param> /// <returns></returns> public IPersistIfcEntity this[XbimInstanceHandle handle] { get { return(handle.GetEntity()); } }
/// <summary> /// Trys to move to the first entity of the specified type, assumes the current index has been set to order by type (SetOrderByType) /// </summary> /// <param name="typeId"></param> /// <returns></returns> public bool TrySeekEntityType(short typeId, out XbimInstanceHandle ih) { return(TrySeekEntityType(typeId, out ih, -1)); }