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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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);
                }
            }
        }
Esempio n. 6
0
 public static XbimMaterialProvider GetDefaultMaterial(IPersistEntity obj)
 {
     if (obj != null)
     {
         return(GetDefaultMaterial(obj.Model, obj.GetType().Name));
     }
     return(null);
 }
Esempio n. 7
0
 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);
     }
 }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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);
            }
        }
Esempio n. 10
0
        /// <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);
            }
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        /// <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();
        }
Esempio n. 16
0
        // 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));
        }