private static void inheritAttribute(FieldAttribute parent, FieldAttribute self, string callSite)
    {
      //merge attributes from parent into self prop by prop
      foreach(var pi in ALL_PROPS)
      {
        if (pi.Name==nameof(MetadataContent))
        {
          if (self.MetadataContent.IsNullOrWhiteSpace())
            self.MetadataContent = parent.MetadataContent;
          else if (parent.MetadataContent.IsNotNullOrWhiteSpace())
          { //merge
            var conf1 = ParseMetadataContent(parent.MetadataContent, callSite);
            var conf2 = ParseMetadataContent(self.MetadataContent, callSite);

            var merged = new LaconicConfiguration();
            merged.CreateFromMerge(conf1, conf2);
            self.MetadataContent = merged.SaveToString();
          }

          continue;
        }//metadata merge

        if (pi.Name==nameof(ValueList))
        {
          if (!self.HasValueList)
            self.ValueList = parent.ValueList;
          else if (parent.HasValueList)
          { //merge
            var vl1 = parent.ParseValueList(true);
            var vl2 = self.ParseValueList(true);

            vl2.Append(vl1);//merge missing in self from parent



            //remove all that start with REMOVE
            // to remove a key include an override with:  `keyABC: #del#` (item keyed on `keyABC` will be removed)
            const string DELETE = "#del#";
            vl2.Where(kvp => kvp.Value.AsString().EqualsOrdIgnoreCase(DELETE))
               .ToArray()
               .ForEach( kvp => vl2.Remove(kvp.Key) );

            self.ValueList = BuildValueListString(vl2);//reconstitute jsonmap back into string
          }

          continue;
        }

        if (self.PropertyWasAssigned(pi.Name)) continue;//was overridden
        pi.SetValue(self, pi.GetValue(parent));//set value
      }
    }
Example #2
0
        public FieldAttribute(
            Type protoType,
            string protoFieldName,             //Schema:Field
            string targetName    = ANY_TARGET,
            object storeFlag     = null,
            object key           = null,
            object kind          = null,
            object required      = null,
            object visible       = null,
            string valueList     = null,
            object dflt          = null,
            object min           = null,
            object max           = null,
            object minLength     = null,
            object maxLength     = null,
            object charCase      = null,
            string backendName   = null,
            string backendType   = null,
            string description   = null,
            string metadata      = null,
            object nonUI         = null,
            string formatRegExp  = null,
            string formatDescr   = null,
            string displayFormat = null,
            object isArow        = null
            ) : base(targetName, null)
        {
            if (protoType == null || protoFieldName.IsNullOrWhiteSpace())
            {
                throw new DataException(StringConsts.ARGUMENT_ERROR + "FieldAttr.ctor(protoType|protoFieldName=null|empty)");
            }
            try
            {
                var schema          = Schema.GetForTypedDoc(protoType);
                var protoTargetName = targetName;
                var segs            = protoFieldName.Split(':');
                if (segs.Length > 1)
                {
                    protoTargetName = segs[0].Trim();
                    protoFieldName  = segs[1].Trim();
                }
                if (protoTargetName.IsNullOrWhiteSpace())
                {
                    throw new Exception("Wrong target syntax");
                }
                if (protoFieldName.IsNullOrWhiteSpace())
                {
                    throw new Exception("Wrong field syntax");
                }

                var protoFieldDef = schema[protoFieldName];
                if (protoFieldDef == null)
                {
                    throw new Exception("Prototype '{0}' field '{1}' not found".Args(protoType.FullName, protoFieldName));
                }
                var protoAttr = protoFieldDef[protoTargetName];

                try
                {
                    StoreFlag         = storeFlag == null? protoAttr.StoreFlag   : (StoreFlag)storeFlag;
                    BackendName       = backendName == null? protoAttr.BackendName : backendName;
                    BackendType       = backendType == null? protoAttr.BackendType : backendType;
                    Key               = key == null? protoAttr.Key         : (bool)key;
                    Kind              = kind == null? protoAttr.Kind        : (DataKind)kind;
                    Required          = required == null? protoAttr.Required    : (bool)required;
                    Visible           = visible == null? protoAttr.Visible     : (bool)visible;
                    Min               = min == null? protoAttr.Min         : min;
                    Max               = max == null? protoAttr.Max         : max;
                    Default           = dflt == null? protoAttr.Default     : dflt;
                    MinLength         = minLength == null? protoAttr.MinLength   : (int)minLength;
                    MaxLength         = maxLength == null? protoAttr.MaxLength   : (int)maxLength;
                    CharCase          = charCase == null? protoAttr.CharCase    : (CharCase)charCase;
                    ValueList         = valueList == null? protoAttr.ValueList   : valueList;
                    Description       = description == null? protoAttr.Description : description;
                    NonUI             = nonUI == null? protoAttr.NonUI       : (bool)nonUI;
                    FormatRegExp      = formatRegExp == null? protoAttr.FormatRegExp: formatRegExp;
                    FormatDescription = formatDescr == null? protoAttr.FormatDescription: formatDescr;
                    DisplayFormat     = displayFormat == null? protoAttr.DisplayFormat : displayFormat;
                    IsArow            = isArow == null? protoAttr.IsArow        : (bool)isArow;



                    if (metadata.IsNullOrWhiteSpace())
                    {
                        m_MetadataContent = protoAttr.m_MetadataContent;
                    }
                    else
                    if (protoAttr.m_MetadataContent.IsNullOrWhiteSpace())
                    {
                        m_MetadataContent = metadata;
                    }
                    else
                    {
                        var conf1 = ParseMetadataContent(protoAttr.m_MetadataContent);
                        var conf2 = ParseMetadataContent(metadata);

                        var merged = new LaconicConfiguration();
                        merged.CreateFromMerge(conf1, conf2);
                        m_MetadataContent = merged.SaveToString();
                    }
                }
                catch (Exception err)
                {
                    throw new Exception("Invalid assignment of prototype override value: " + err.ToMessageWithType());
                }
            }
            catch (Exception error)
            {
                throw new DataException(StringConsts.CRUD_FIELD_ATTR_PROTOTYPE_CTOR_ERROR.Args(error.Message));
            }
        }