示例#1
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));
        }
示例#2
0
        /// <summary>
        /// Allows to use a ConceptTemplate for extracting datatables of values from an entity.
        /// Columns returned depend on specified dataIndicators
        /// </summary>
        /// <param name="entity">the entity of interest</param>
        /// <param name="template">the ConceptTemplate to apply</param>
        /// <param name="dataIndicators">the indicators of interest</param>
        /// <returns></returns>
        public DataTable GetData(IPersistEntity entity, ConceptTemplate template, IEnumerable <DataIndicator> dataIndicators)
        {
            var dt         = new DataTable();
            var indicators = dataIndicators as DataIndicator[] ?? dataIndicators.ToArray();

            foreach (var dataIndicator in indicators)
            {
                var c = new DataColumn(dataIndicator.ColumnName);
                dt.Columns.Add(c);
            }

            var fastIndicators = new DataIndicatorLookup(indicators);
            // template.DebugTemplateTree();

            // when ending row or going deeper it fills row
            var vls = GetAttributes(template, entity, fastIndicators, "");

            vls?.Populate(dt);

            return(dt);
        }
示例#3
0
        internal DataFragment FillEntities(EntityRule[] rules, IPersistEntity entity, DataIndicatorLookup dataIndicators, string prefix)
        {
            // todo: review the return logic;

            //
            if (entity == null)
            {
                return(null);
            }
            foreach (var entityRule in rules)
            {
                // it's probably safe to assume that if we are here then the whole schema is the same of the element we are using
                // regardless from _forceModelSchema settings; it would otherwise be complicated to consider which of the schemas to use of the
                // array of schemes of the parent ConceptTemplate.
                var filterType = GetExpressType(entity.Model.Metadata, entityRule.EntityName.ToUpper());
                if (filterType == null)
                {
                    continue;
                }
                if (!filterType.NonAbstractSubTypes.Contains(entity.ExpressType))
                {
                    continue;
                }

                if (entityRule.References != null)
                {
                    // need to resolve reference
                    if (string.IsNullOrEmpty(entityRule.References.Template?.@ref))
                    {
                        continue;
                    }
                    var tPrefix = prefix;
                    // Debug.Print(@"Ref: {0} on {1} ({2})", entityRule.References.Template.@ref, entity.EntityLabel, entity.GetType().Name);
                    var refTemplate = Mvd.GetConceptTemplate(entityRule.References.Template.@ref);
                    if (!string.IsNullOrEmpty(entityRule.References.IdPrefix))
                    {
                        tPrefix += entityRule.References.IdPrefix;
                    }
                    // todo: xxx this is wrong! what about the following rules?
                    var t = GetAttributes(refTemplate, entity, dataIndicators, tPrefix);
                    return(t);
                }
                else if (entityRule.AttributeRules != null)
                {
                    // todo: xxx this is wrong! what about the following rules?
                    // rules nested directly
                    return(GetAttributes(entityRule.AttributeRules.AttributeRule, entity, dataIndicators, prefix));
                }
            }
            return(null);
        }
示例#4
0
        private DataFragment ExtractRulesValues(IPersistEntity entity, DataIndicatorLookup dataIndicators, AttributeRule[] rules, string prefix)
        {
            var tmp = new List <DataFragment>();

            if (rules == null)
            {
                return(null);
            }
            foreach (var attributeRule in rules)
            {
                // sort out values at current level
                // we have an id and indicators require it
                if (string.IsNullOrEmpty(attributeRule.RuleID))
                {
                    continue;
                }
                var storageName = prefix + attributeRule.RuleID;
                if (!dataIndicators.Contains(storageName))
                {
                    continue;
                }
                ExpressMetaProperty retProp;
                var value = GetFieldValue(entity, attributeRule.AttributeName, out retProp);
                if (retProp == null)
                {
                    // propery not found in class... ignore
                    //
                    continue;
                }
                // set the value
                if (dataIndicators.Requires(storageName, DataIndicator.ValueSelectorEnum.Value))
                {
                    DataFragment tF;
                    if (value is IEnumerable <object> )
                    {
                        var asEnum = value as IEnumerable <object>;
                        tF = new DataFragment(storageName, asEnum);
                    }
                    else
                    {
                        tF = new DataFragment(storageName, value);
                    }
                    tmp.Add(tF);
                }

                // set the type
                //
                if (dataIndicators.Requires(storageName, DataIndicator.ValueSelectorEnum.Type))
                {
                    var storName = DataIndicator.GetColumnName(storageName, DataIndicator.ValueSelectorEnum.Type);
                    tmp.Add(new DataFragment(storName, value.GetType().Name));
                }

                // set the Size
                //
                if (dataIndicators.Requires(storageName, DataIndicator.ValueSelectorEnum.Size))
                {
                    var storName = DataIndicator.GetColumnName(storageName, DataIndicator.ValueSelectorEnum.Size);

                    if (value is IEnumerable <object> )
                    {
                        var asEnum = value as IEnumerable <object>;
                        tmp.Add(new DataFragment(storName, asEnum.Count()));
                    }
                    else if (value == null)
                    {
                        tmp.Add(new DataFragment(storName, 0));
                    }
                    else
                    {
                        tmp.Add(new DataFragment(storName, 1)); // there's one entity
                    }
                }

                // set Existence
                // ReSharper disable once InvertIf // for symmetry in code
                //
                if (dataIndicators.Requires(storageName, DataIndicator.ValueSelectorEnum.Exists))
                {
                    var storName  = DataIndicator.GetColumnName(storageName, DataIndicator.ValueSelectorEnum.Exists);
                    var storValue = value != null;
                    if (value != null)
                    {
                        storValue = value.ToString().Trim() != "";
                    }
                    tmp.Add(new DataFragment(storName, storValue)); // true if not null
                }
            }
            return(DataFragment.Combine(tmp));
        }
示例#5
0
        private DataFragment GetAttributes(AttributeRule[] attributeRules, IPersistEntity entity, DataIndicatorLookup dataIndicators, string prefix)
        {
            // 1.  get all values

            // add values at this level
            //
            var fragments = new List <DataFragment>();
            var t1        = ExtractRulesValues(entity, dataIndicators, attributeRules, prefix);

            if (t1 != null)
            {
                fragments.Add(t1);
            }

            // process the rest of the tree
            //
            var t = ProcessRuleTree(entity, dataIndicators, attributeRules, prefix);

            if (t != null)
            {
                fragments.Add(t);
            }


            // 2. combine them and return
            return(DataFragment.Combine(fragments));
        }
示例#6
0
        internal DataFragment GetAttributes(ConceptTemplate template, IPersistEntity entity, DataIndicatorLookup dataIndicators, string prefix)
        {
            var useT = template.GetSpecificConceptTemplateFor(entity);

            return(GetAttributes(useT.Rules, entity, dataIndicators, prefix));
        }