private void AddReversible(IPersistEntity entity) { if (_model.IsTransactional && _model.CurrentTransaction == null) { throw new Exception("Operation out of transaction"); } var key = entity.GetType(); Action undo = () => { _internal.Remove(key, entity); _collection.Remove(entity.EntityLabel); if (_naturalOrder != null) { _naturalOrder.Remove(entity.EntityLabel); } }; Action doAction = () => { _internal.Add(key, entity); _collection.Add(entity.EntityLabel, entity); if (_naturalOrder != null) { _naturalOrder.Add(entity.EntityLabel); } }; if (!_model.IsTransactional) { doAction(); return; } _model.CurrentTransaction.DoReversibleAction(doAction, undo, entity, ChangeType.New, 0); }
internal bool RemoveReversible(IPersistEntity entity) { if (_model.IsTransactional && _model.CurrentTransaction == null) { throw new Exception("Operation out of transaction"); } var key = entity.GetType(); bool removed = false; Action doAction = () => { _internal.Remove(key, entity); removed = _collection.Remove(entity.EntityLabel); _naturalOrder?.Remove(entity.EntityLabel); }; Action undo = () => { _internal.Add(key, entity); _collection.Add(entity.EntityLabel, entity); _naturalOrder?.Add(entity.EntityLabel); }; if (!_model.IsTransactional) { doAction(); return(removed); } _model.CurrentTransaction.DoReversibleAction(doAction, undo, entity, ChangeType.Deleted, 0); return(removed); }
internal static TextHighliter ReportAcadScript(IPersistEntity obj) { var sb = new TextHighliter(); if (obj is IIfcGeometricRepresentationItem cnv) { Report(cnv, sb); } else if (obj is IIfcClosedShell) { Report((IIfcClosedShell)obj, sb); } else if (obj is IIfcPolyLoop) { Report((IIfcPolyLoop)obj, sb); } else if (obj is IIfcSweptDiskSolid) { Report((IIfcSweptDiskSolid)obj, sb); } else if (obj is IIfcProductDefinitionShape) { Report((IIfcProductDefinitionShape)obj, sb); } else { sb.Append($"No information for {obj.GetType()}", Brushes.Black); return(sb); } sb.Append("3DORBIT", Brushes.Black); sb.Append("", Brushes.Black); sb.Append("===", Brushes.Black); return(sb); }
public bool Resolve(ConcurrentDictionary <int, IPersistEntity> references, ExpressMetaData metadata) { IPersistEntity entity; if (references.TryGetValue(ReferenceEntityLabel, out entity)) { var pv = new PropertyValue(); pv.Init(entity); try { _referencingEntity.Parse(_referencingPropertyId, pv, _nestedIndex); return(true); } catch (Exception) { var expressType = metadata.ExpressType(_referencingEntity); EsentModel.Logger.ErrorFormat("Data Error. Cannot set the property = {0} of entity #{1} = {2} to entity #{3}, schema violation. Ignored", expressType.Properties[_referencingPropertyId + 1].PropertyInfo.Name, _referencingEntity.EntityLabel, _referencingEntity.GetType().Name, ReferenceEntityLabel); return(false); } } else { return(false); } }
internal void InternalAdd(IPersistEntity entity) { if (entity == null) { return; } var key = entity.GetType(); _internal.Add(key, entity); try { _collection.Add(entity.EntityLabel, entity); if (_naturalOrder != null) { _naturalOrder.Add(entity.EntityLabel); } } catch (Exception ex) { var exist = _collection[entity.EntityLabel]; if (entity.ExpressType != exist.ExpressType) { _model.Logger?.LogError($"Duplicate entity #{entity.EntityLabel} with different data type ({exist.ExpressType.Name}/{entity.ExpressType.Name})", ex); } else { _model.Logger?.LogWarning($"Duplicate entity #{entity.EntityLabel}", ex); } } }
public static XbimMaterialProvider GetDefaultMaterial(IPersistEntity obj) { if (obj != null) { return(GetDefaultMaterial(obj.Model, obj.GetType().Name)); } return(null); }
public Tracer(string methodName, ILogger logger, IPersistEntity entity) { this.methodName = methodName; this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); if (logger.IsEnabled(LogLevel.Trace)) // Optimisation to avoid GetType reflection unless Trace enabled { logger.LogTrace("Entering GeometryEngine {function} with #{entity} [{type}]", methodName, entity.EntityLabel, entity.GetType().Name); } }
internal void Add(int key, IPersistEntity value) { var index = GetIndex(value.GetType()); if (!index.TryGetValue(key, out HashSet <int> set)) { set = new HashSet <int>(); index.Add(key, set); } set.Add(value.EntityLabel); }
internal void InternalAdd(IPersistEntity entity) { var key = entity.GetType(); _internal.Add(key, entity); _collection.Add(entity.EntityLabel, entity); if (_naturalOrder != null) { _naturalOrder.Add(entity.EntityLabel); } }
/// <summary> /// This will delete the entity from model dictionary and also from any references in the model. /// Be carefull as this might take a while to check for all occurances of the object. Also make sure /// you don't use this object anymore yourself because it won't get disposed until than. This operation /// doesn't guarantee that model is compliant with any kind of schema but it leaves it consistent. So if you /// serialize the model there won't be any references to the object which wouldn't be there. /// </summary> /// <param name="model">Model from which the entity should be deleted</param> /// <param name="entity">Entity to be deleted</param> /// <param name="instanceRemoval">Delegate to be used to remove entity from instance collection. /// This should be reversable action within a transaction.</param> public static void Delete(IModel model, IPersistEntity entity, Func <IPersistEntity, bool> instanceRemoval) { var referingTypes = GetReferingTypes(model, entity.GetType()); foreach (var referingType in referingTypes) { ReplaceReferences <IPersistEntity, IPersistEntity>(model, entity, referingType, null); } //Remove from entity collection. This must be at the end for case it is being used in the meantime. instanceRemoval(entity); }
internal void InternalAdd(IPersistEntity entity) { var key = entity.GetType(); _internal.Add(key, entity); try { _collection.Add(entity.EntityLabel, entity); if (_naturalOrder != null) { _naturalOrder.Add(entity.EntityLabel); } } catch (Exception ex) { _model.Logger?.LogError(string.Format("Duplicate entity label: #{0}", entity.EntityLabel), ex); } }
private static IEnumerable <ReferingType> GetReferingTypes(IModel model, IPersistEntity entity) { var entityType = entity.GetType(); List <ReferingType> referingTypes; if (ReferingTypesCache.TryGetValue(entityType, out referingTypes)) { return(referingTypes); } referingTypes = new List <ReferingType>(); if (!ReferingTypesCache.TryAdd(entityType, referingTypes)) { //it is there already (done in another thread) return(ReferingTypesCache[entityType]); } //find all potential references var types = model.Metadata.Types().Where(t => typeof(IInstantiableEntity).GetTypeInfo().IsAssignableFrom(t.Type)); // ReSharper disable once LoopCanBeConvertedToQuery foreach (var type in types) { var singleReferences = type.Properties.Values.Where(p => p.EntityAttribute != null && p.EntityAttribute.Order > 0 && p.PropertyInfo.PropertyType.GetTypeInfo().IsAssignableFrom(entityType)).ToList(); var listReferences = type.Properties.Values.Where(p => p.EntityAttribute != null && p.EntityAttribute.Order > 0 && p.PropertyInfo.PropertyType.GetTypeInfo().IsGenericType&& p.PropertyInfo.PropertyType.GenericTypeArgumentIsAssignableFrom(entityType)).ToList(); if (!singleReferences.Any() && !listReferences.Any()) { continue; } referingTypes.Add(new ReferingType { Type = type, SingleReferences = singleReferences, ListReferences = listReferences }); } return(referingTypes); }
/// <summary> /// When SubTemplates are available return the most suitable amongst them for the entity specified /// </summary> /// <param name="entity">an entity whose type is used to determine the most suitable ConceptTemplate match</param> /// <returns>the most suitable ConceptTemplate match</returns> public ConceptTemplate GetSpecificConceptTemplateFor(IPersistEntity entity) { if (SubTemplates == null) { return(this); } // try to use the lowest valid subtemplate var currType = entity.GetType(); var currTypeName = currType.Name; // while stepping up the inheritance tree has not reached the concepTemplate's own applicable scope // while (!ApplicableIs(currTypeName)) { // look for a matching subtemplate use that var firstValidSub = SubTemplates.FirstOrDefault(subTemplate => subTemplate.Rules != null && subTemplate.ApplicableIs(currTypeName) ); // if found, return if (firstValidSub != null) { // useRules = firstValidSub.Rules; return(firstValidSub); } // otherwise look one level up if (currType.BaseType == null) { break; } currType = currType.BaseType; currTypeName = currType.Name; } // if nothing then return the top level return(this); }
/// <summary> /// Populates an entites properties from the binary stream /// </summary> /// <param name="entity"></param> /// <param name="cache"></param> /// <param name="br"></param> /// <param name="unCached">If true instances inside the properties are not added to the cache</param> /// <param name="fromCache"> If true the instance is read from the cache if not present it is created, used during parsing</param> internal static void ReadEntityProperties(this IPersistEntity entity, PersistedEntityInstanceCache cache, BinaryReader br, bool unCached = false, bool fromCache = false) { var action = (P21ParseAction)br.ReadByte(); var parserState = new XbimParserState(entity); while (action != P21ParseAction.EndEntity) { switch (action) { case P21ParseAction.BeginList: parserState.BeginList(); break; case P21ParseAction.EndList: parserState.EndList(); break; case P21ParseAction.BeginComplex: break; case P21ParseAction.EndComplex: break; case P21ParseAction.SetIntegerValue: parserState.SetIntegerValue(br.ReadInt64()); break; case P21ParseAction.SetHexValue: parserState.SetHexValue(br.ReadInt64()); break; case P21ParseAction.SetFloatValue: parserState.SetFloatValue(br.ReadDouble()); break; case P21ParseAction.SetStringValue: parserState.SetStringValue(br.ReadString()); break; case P21ParseAction.SetEnumValue: parserState.SetEnumValue(br.ReadString()); break; case P21ParseAction.SetBooleanValue: parserState.SetBooleanValue(br.ReadBoolean()); break; case P21ParseAction.SetNonDefinedValue: parserState.SetNonDefinedValue(); break; case P21ParseAction.SetOverrideValue: parserState.SetOverrideValue(); break; case P21ParseAction.SetObjectValueUInt16: if (fromCache) { int label = br.ReadUInt16(); IPersistEntity refEntity; if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity)) //if we are in a list then make a forward reference anyway to make sure we maintain list order { parserState.SetObjectValue(refEntity); } else { cache.AddForwardReference(new StepForwardReference(label, parserState.CurrentPropertyId, entity, parserState.NestedIndex)); parserState.SkipProperty(); } } else { parserState.SetObjectValue(cache.GetInstance(br.ReadUInt16(), false, unCached)); } break; case P21ParseAction.SetObjectValueInt32: if (fromCache) { var label = br.ReadInt32(); IPersistEntity refEntity; if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity)) //if we are in a list then make a forward reference anyway to make sure we maintain list order { parserState.SetObjectValue(refEntity); } else { cache.AddForwardReference(new StepForwardReference(label, parserState.CurrentPropertyId, entity, parserState.NestedIndex)); parserState.SkipProperty(); } } else { parserState.SetObjectValue(cache.GetInstance(br.ReadInt32(), false, unCached)); } break; case P21ParseAction.SetObjectValueInt64: throw new XbimException("Entity Label is int64, this is not currently supported"); //parserState.SetObjectValue(cache.GetInstance(br.ReadInt64(), false, unCached)); //break; case P21ParseAction.BeginNestedType: parserState.BeginNestedType(br.ReadString()); break; case P21ParseAction.EndNestedType: parserState.EndNestedType(); break; case P21ParseAction.EndEntity: parserState.EndEntity(); break; case P21ParseAction.NewEntity: parserState = new XbimParserState(entity); break; default: throw new XbimException("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name); } action = (P21ParseAction)br.ReadByte(); } }
internal static void WriteEntity(this IPersistEntity entity, TextWriter tw, byte[] propertyData, ExpressMetaData metadata) { var type = metadata.ExpressType(entity); tw.Write("#{0}={1}", entity.EntityLabel, type.ExpressNameUpper); var br = new BinaryReader(new MemoryStream(propertyData)); var action = (P21ParseAction)br.ReadByte(); var comma = false; //the first property while (action != P21ParseAction.EndEntity) { switch (action) { case P21ParseAction.BeginList: tw.Write("("); break; case P21ParseAction.EndList: tw.Write(")"); break; case P21ParseAction.BeginComplex: tw.Write("&SCOPE"); break; case P21ParseAction.EndComplex: tw.Write("ENDSCOPE"); break; case P21ParseAction.SetIntegerValue: if (comma) { tw.Write(","); } comma = true; tw.Write(br.ReadInt64().ToString()); break; case P21ParseAction.SetHexValue: if (comma) { tw.Write(","); } comma = true; tw.Write(Convert.ToString(br.ReadInt64(), 16)); break; case P21ParseAction.SetFloatValue: if (comma) { tw.Write(","); } comma = true; tw.Write(br.ReadDouble().AsPart21()); break; case P21ParseAction.SetStringValue: if (comma) { tw.Write(","); } comma = true; tw.Write(br.ReadString()); break; case P21ParseAction.SetEnumValue: if (comma) { tw.Write(","); } comma = true; tw.Write("." + br.ReadString() + "."); break; case P21ParseAction.SetBooleanValue: if (comma) { tw.Write(","); } comma = true; tw.Write(br.ReadBoolean() ? ".T." : ".F."); break; case P21ParseAction.SetNonDefinedValue: if (comma) { tw.Write(","); } comma = true; tw.Write("$"); break; case P21ParseAction.SetOverrideValue: if (comma) { tw.Write(","); } comma = true; tw.Write("*"); break; case P21ParseAction.SetObjectValueUInt16: if (comma) { tw.Write(","); } comma = true; tw.Write("#" + br.ReadUInt16()); break; case P21ParseAction.SetObjectValueInt32: if (comma) { tw.Write(","); } comma = true; tw.Write("#" + br.ReadInt32()); break; case P21ParseAction.SetObjectValueInt64: if (comma) { tw.Write(","); } comma = true; tw.Write("#" + br.ReadInt64()); break; case P21ParseAction.BeginNestedType: if (comma) { tw.Write(","); } comma = false; tw.Write(br.ReadString() + "("); break; case P21ParseAction.EndNestedType: comma = true; tw.Write(")"); break; case P21ParseAction.EndEntity: tw.Write(");"); break; case P21ParseAction.NewEntity: comma = false; tw.Write("("); break; default: throw new Exception("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name); } action = (P21ParseAction)br.ReadByte(); } tw.WriteLine(); }
// this is only internal for testing purposes; it should be private otherwise... // is there a way to do that? internal DataFragment ProcessRuleTree(IPersistEntity entity, DataIndicatorLookup dataIndicators, AttributeRule[] rules, string prefix) { // todo: xxx review return value logic var f = new List <DataFragment>(); if (rules == null) { return(null); } foreach (var attributeRule in rules) { var attributeFragment = new DataFragment(); // todo: if no entity is specified then the attribute is not set; is this correct? // see at deeper tree levels if (attributeRule.EntityRules == null || attributeRule.EntityRules.EntityRule.Length <= 0) { continue; } // here we have to see if the attribute gets values that we can use ExpressMetaProperty retProp; var entityRuleValue = GetFieldValue(entity, attributeRule.AttributeName, out retProp); if (retProp == null) // we are in the case where the property does not exist in the schema { Log.Warn($"{attributeRule.AttributeName} property is not available for type {entity.GetType().Name} (as expected on attributeRule '{attributeRule.RuleID}' in {attributeRule.ParentConceptTemplate.uuid})"); continue; } if (retProp.EntityAttribute.IsEnumerable) { var propCollection = entityRuleValue as IEnumerable <object>; if (propCollection == null) { continue; } var children = propCollection.OfType <IPersistEntity>().ToArray(); foreach (var child in children) { // todo: this is likely to return the same variable names for the datatable var t = FillEntities(attributeRule.EntityRules.EntityRule, child, dataIndicators, prefix); attributeFragment.Merge(t); } } else { var t = FillEntities(attributeRule.EntityRules.EntityRule, entityRuleValue as IPersistEntity, dataIndicators, prefix); attributeFragment.Merge(t); } if (!attributeFragment.IsEmpty) { f.Add(attributeFragment); } } return(DataFragment.Combine(f)); }