Esempio n. 1
0
        private static void GetDependsOnWriteableDataStructure(DataStructureInfo dataStructure, List <DataStructureInfo> dependencies, IDslModel allConcepts, IConceptInfo errorContext, HashSet <string> done)
        {
            var conceptKey = dataStructure.GetKey();

            if (done.Contains(conceptKey))
            {
                return;
            }
            done.Add(conceptKey);

            if (dataStructure is EntityInfo)
            {
                dependencies.Add(dataStructure);
            }
            else if (dataStructure is SqlQueryableInfo)
            {
                var deps = allConcepts.FindByType <SqlDependsOnDataStructureInfo>().Where(dep => dep.Dependent == dataStructure).ToArray();
                foreach (var dep in deps)
                {
                    GetDependsOnWriteableDataStructure(dep.DependsOn, dependencies, allConcepts, errorContext, done);
                }
            }
            else
            {
                throw new DslSyntaxException(errorContext.GetKeywordOrTypeName()
                                             + " is not supported on dependency type '" + dataStructure.GetKeywordOrTypeName() + "'. "
                                             + errorContext.GetUserDescription() + " depends on " + dataStructure.GetUserDescription() + ".");
            }
        }
Esempio n. 2
0
        public void Set <T>(IConceptInfo conceptInfo, ConceptMetadataKey <T> metadataKey, T value)
        {
            Dictionary <Guid, object> conceptInfoMetadata;
            string conceptKey = conceptInfo.GetKey();

            if (!_metadata.TryGetValue(conceptKey, out conceptInfoMetadata))
            {
                conceptInfoMetadata = new Dictionary <Guid, object>();
                _metadata.Add(conceptKey, conceptInfoMetadata);
            }

            object oldValue;

            if (!conceptInfoMetadata.TryGetValue(metadataKey.Id, out oldValue))
            {
                conceptInfoMetadata.Add(metadataKey.Id, value);
            }
            else
            {
                if (!SameValue(value, oldValue))
                {
                    throw new FrameworkException(
                              $"Different metadata value is already set for concept {conceptInfo.GetUserDescription()}, key {metadataKey}." +
                              $" Previous value '{oldValue}', new value '{value}'.");
                }
            }
        }
Esempio n. 3
0
        private string ReportPreviousConcept(IConceptInfo conceptInfo)
        {
            var sb = new StringBuilder();

            if (conceptInfo != null)
            {
                sb.AppendFormat("Previous concept: {0}", conceptInfo.GetUserDescription()).AppendLine();
                var properties = conceptInfo.GetType().GetProperties().ToList();
                properties.ForEach(it =>
                                   sb.AppendFormat("Property {0} ({1}) = {2}",
                                                   it.Name,
                                                   it.PropertyType.Name,
                                                   it.GetValue(conceptInfo, null) ?? "<null>")
                                   .AppendLine());
            }
            return(sb.ToString());
        }
Esempio n. 4
0
        public void Set <T>(IConceptInfo conceptInfo, ConceptMetadataType <T> metadataType, T value)
        {
            Dictionary <Guid, object> conceptMetadataByType;
            string conceptKey = conceptInfo.GetKey();

            if (!_metadata.TryGetValue(conceptKey, out conceptMetadataByType))
            {
                conceptMetadataByType = new Dictionary <Guid, object>();
                _metadata.Add(conceptKey, conceptMetadataByType);
            }

            if (conceptMetadataByType.ContainsKey(metadataType.Id))
            {
                throw new FrameworkException(string.Format(
                                                 "The metadata is already set for concept {0}. Metadata type {1}.",
                                                 conceptInfo.GetUserDescription(),
                                                 metadataType));
            }

            conceptMetadataByType.Add(metadataType.Id, value);
        }
Esempio n. 5
0
 private static void AddReferencesBeforeConcept(IConceptInfo concept, List <IConceptInfo> sortedList, Dictionary <IConceptInfo, bool> processed)
 {
     if (!processed.ContainsKey(concept))
     {
         throw new FrameworkException(string.Format(
                                          "Unexpected inner state: Referenced concept {0} is not found in list of all concepts.",
                                          concept.GetUserDescription()));
     }
     if (processed[concept]) // eliminates duplication of referenced concepts and stops circular references from infinite recursion
     {
         return;
     }
     processed[concept] = true;
     foreach (ConceptMember member in ConceptMembers.Get(concept))
     {
         if (member.IsConceptInfo)
         {
             AddReferencesBeforeConcept((IConceptInfo)member.GetValue(concept), sortedList, processed);
         }
     }
     sortedList.Add(concept);
 }
Esempio n. 6
0
        public static void ValidatePropertyListSyntax(string dslList, IConceptInfo errorContext)
        {
            var errorHeader = new Lazy<string>(() =>
                "Invalid format of list '" + dslList + "' in '" + errorContext.GetUserDescription() + "': ");

            if (string.IsNullOrWhiteSpace(dslList))
                throw new DslSyntaxException(errorHeader.Value + "The list is empty.");

            if (dslList.Contains(',') || dslList.Contains(';'))
                throw new DslSyntaxException(errorHeader.Value + "Property names in the list must be separated with spaces.");

            if (dslList.Contains('.'))
                throw new DslSyntaxException(errorHeader.Value + "The list must contain only property names, without data structure or entity names (or dot character).");

            // Ensure uniqueness of the concept's key. There should not exists different instances of SqlIndexMultiple that generate same index in database.
            if (dslList.Contains("  "))
                throw new DslSyntaxException(errorHeader.Value + "Property names in the list must be separated by single space character. Verify that there are no multiple spaces.");
            if (dslList.StartsWith(" "))
                throw new DslSyntaxException(errorHeader.Value + "The list of property names must not start with a space character.");
            if (dslList.EndsWith(" "))
                throw new DslSyntaxException(errorHeader.Value + "The list of property names must not end with a space character.");
        }
Esempio n. 7
0
        public static void ValidatePropertyListSyntax(string propertyList, IConceptInfo errorContext)
        {
            var errorHeader = new Lazy <string>(() =>
                                                "Invalid format of list '" + propertyList + "' in '" + errorContext.GetUserDescription() + "': ");

            if (string.IsNullOrWhiteSpace(propertyList))
            {
                throw new DslSyntaxException(errorHeader.Value + "The list is empty.");
            }

            if (propertyList.Contains(',') || propertyList.Contains(';'))
            {
                throw new DslSyntaxException(errorHeader.Value + "Property names in the list must be separated with spaces.");
            }

            if (propertyList.Contains('.'))
            {
                throw new DslSyntaxException(errorHeader.Value + "The list must contain only property names, without data structure or entity names (or dot character).");
            }

            // Ensure uniqueness of the concept's key. There should not exists different instances of SqlIndexMultiple that generate same index in database.
            if (propertyList.Contains("  "))
            {
                throw new DslSyntaxException(errorHeader.Value + "Property names in the list must be separated by single space character. Verify that there are no multiple spaces.");
            }
            if (propertyList.StartsWith(" "))
            {
                throw new DslSyntaxException(errorHeader.Value + "The list of property names must not start with a space character.");
            }
            if (propertyList.EndsWith(" "))
            {
                throw new DslSyntaxException(errorHeader.Value + "The list of property names must not end with a space character.");
            }
        }
Esempio n. 8
0
 public DslSyntaxException(IConceptInfo concept, string additionalMessage, Exception inner)
     : base(concept.GetUserDescription() + ": " + additionalMessage, inner)
 {
 }
Esempio n. 9
0
        /// <summary>
        /// Returns a string that describes the concept instance cast as a base concept.
        /// The string contains base concept's type name and the base concept's properties.
        /// </summary>
        public static string GetFullDescriptionAsBaseConcept(this IConceptInfo ci, Type baseConceptType)
        {
            if (!baseConceptType.IsAssignableFrom(ci.GetType()))
            {
                throw new FrameworkException($"{baseConceptType} is not assignable from {ci.GetUserDescription()}.");
            }
            StringBuilder desc = new StringBuilder(200);

            desc.Append(baseConceptType.FullName);
            desc.Append(" ");
            AppendMembers(desc, ci, SerializationOptions.AllMembers, false, baseConceptType);
            return(desc.ToString());
        }
Esempio n. 10
0
 private static void AddReferencesBeforeConcept(IConceptInfo concept, List<IConceptInfo> sortedList, Dictionary<IConceptInfo, bool> processed)
 {
     if (!processed.ContainsKey(concept))
         throw new FrameworkException(string.Format(
             "Unexpected inner state: Referenced concept {0} is not found in list of all concepts.",
             concept.GetUserDescription()));
     if (processed[concept]) // eliminates duplication of referenced concepts and stops circular references from infinite recursion
         return;
     processed[concept] = true;
     foreach (ConceptMember member in ConceptMembers.Get(concept))
         if (member.IsConceptInfo)
             AddReferencesBeforeConcept((IConceptInfo)member.GetValue(concept), sortedList, processed);
     sortedList.Add(concept);
 }
Esempio n. 11
0
        internal static IList<IConceptInfo> CreateNewConcepts(
            BrowseDataStructureInfo browse, string path, string newPropertyName,
            IEnumerable<IConceptInfo> existingConcepts, IConceptInfo errorContext)
        {
            var newConcepts = new List<IConceptInfo>();

            ValueOrError<PropertyInfo> sourceProperty = GetSelectedPropertyByPath(browse, path, existingConcepts);
            if (sourceProperty.IsError)
                return null; // Creating the browse property may be delayed for other macro concepts to generate the needed properties. If this condition is not resolved, the CheckSemantics function below will throw an exception.

            if (!IsValidIdentifier(newPropertyName))
                throw new DslSyntaxException(string.Format(
                    "Invalid format of {0}: Property name '{1}' is not a valid identifier. Specify a valid name before the path to override the generated name.",
                    errorContext.GetUserDescription(),
                    newPropertyName));

            var cloneMethod = typeof(object).GetMethod("MemberwiseClone", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var browseProperty = (PropertyInfo)cloneMethod.Invoke(sourceProperty.Value, null);
            browseProperty.DataStructure = browse;
            browseProperty.Name = newPropertyName;

            var browsePropertySelector = new BrowseFromPropertyInfo { PropertyInfo = browseProperty, Path = path };

            return new IConceptInfo[] { browseProperty, browsePropertySelector };
        }
Esempio n. 12
0
        public T Get <T>(IConceptInfo conceptInfo, ConceptMetadataKey <T> metadataKey)
        {
            Func <string> missingMetadataMessage = () => "There is no requested metadata for concept " + conceptInfo.GetUserDescription() + ". Metadata key is " + metadataKey + ".";
            var           conceptInfoMetadata    = _metadata.GetValue(conceptInfo.GetKey(), missingMetadataMessage);
            var           metadataValue          = conceptInfoMetadata.GetValue(metadataKey.Id, missingMetadataMessage);

            return((T)metadataValue);
        }
Esempio n. 13
0
 public DslSyntaxException(IConceptInfo concept, string additionalMessage, Exception inner) : base(concept.GetUserDescription() + ": " + additionalMessage, inner)
 {
 }
Esempio n. 14
0
        public static ConceptSyntaxNode CreateConceptSyntaxNode(this DslSyntax dslSyntax, IConceptInfo ci)
        {
            var conceptInfoType = ci.GetType();
            var node            = new ConceptSyntaxNode(dslSyntax.GetConceptType(conceptInfoType));
            var members         = ConceptMembers.Get(conceptInfoType);

            if (node.Parameters.Length != members.Length)
            {
                throw new InvalidOperationException(
                          $"{nameof(ConceptSyntaxNode)} parameters count ({node.Parameters.Length})" +
                          $" does not match {nameof(ConceptMembers)} count ({members.Length}).");
            }

            for (int m = 0; m < members.Length; m++)
            {
                object value = members[m].GetValue(ci);

                node.Parameters[m] = value;

                if (value == null)
                {
                    node.Parameters[m] = null;
                }
                else if (value is string)
                {
                    node.Parameters[m] = value;
                }
                else if (value is IConceptInfo referencedConceptInfo)
                {
                    var referencedNode = CreateConceptSyntaxNode(dslSyntax, referencedConceptInfo);
                    node.Parameters[m] = referencedNode;
                }
                else
                {
                    var valueType = value?.GetType().Name ?? "null";
                    throw new ArgumentException($"Value type {valueType} is not expected in '{ci.GetUserDescription()}', parameter {members[m].Name}.");
                }
            }

            return(node);
        }
Esempio n. 15
0
 protected string ReportErrorContext(IConceptInfo conceptInfo, int index)
 {
     var sb = new StringBuilder();
     sb.AppendLine(_dslSource.ReportError(index));
     if (conceptInfo != null)
     {
         sb.AppendFormat("Previous concept: {0}", conceptInfo.GetUserDescription()).AppendLine();
         var properties = conceptInfo.GetType().GetProperties().ToList();
         properties.ForEach(it =>
             sb.AppendFormat("Property {0} ({1}) = {2}",
                 it.Name,
                 it.PropertyType.Name,
                 it.GetValue(conceptInfo, null) ?? "<null>")
                 .AppendLine());
     }
     return sb.ToString();
 }
Esempio n. 16
0
        public T Get <T>(IConceptInfo conceptInfo, ConceptMetadataType <T> metadataType)
        {
            Func <string> missingMetadataMessage = () => "There is no metadata of requested type for concept " + conceptInfo.GetUserDescription() + ". Metadata type is " + metadataType + ".";
            var           conceptMetadataByType  = _metadata.GetValue(conceptInfo.GetKey(), missingMetadataMessage);
            var           metadataValue          = conceptMetadataByType.GetValue(metadataType.Id, missingMetadataMessage);

            return((T)metadataValue);
        }
Esempio n. 17
0
        private static void GetDependsOnWriteableDataStructure(DataStructureInfo dataStructure, List<DataStructureInfo> dependencies, IEnumerable<IConceptInfo> allConcepts, IConceptInfo errorContext, HashSet<string> done)
        {
            var conceptKey = dataStructure.GetKey();
            if (done.Contains(conceptKey))
                return;
            done.Add(conceptKey);

            if (dataStructure is EntityInfo)
                dependencies.Add(dataStructure);
            else if (dataStructure is SqlQueryableInfo)
            {
                var deps = allConcepts.OfType<SqlDependsOnDataStructureInfo>().Where(dep => dep.Dependent == dataStructure).ToArray();
                foreach (var dep in deps)
                    GetDependsOnWriteableDataStructure(dep.DependsOn, dependencies, allConcepts, errorContext, done);
            }
            else
                throw new DslSyntaxException(errorContext.GetKeywordOrTypeName()
                    + " is not supported on dependency type '" + dataStructure.GetKeywordOrTypeName() + "'. "
                    + errorContext.GetUserDescription() + " depends on " + dataStructure.GetUserDescription() + ".");
        }
Esempio n. 18
0
        private static string GetPropertyName <T>(Expression <Func <T, object> > referenceProperty, IConceptInfo checkValueType)
        {
            var memberExpression = referenceProperty.Body as MemberExpression;

            if (memberExpression == null)
            {
                throw new FrameworkException("Invalid FindByReference method argument: referenceProperty. The argument should be a lambda expression selecting a property of the class "
                                             + typeof(T).Name + ". For example: \"conceptInfo => conceptInfo.SomeProperty\".");
            }

            var property = memberExpression.Member as PropertyInfo;

            if (property == null || memberExpression.Expression.NodeType != ExpressionType.Parameter)
            {
                throw new FrameworkException("Invalid FindByReference method argument: referenceProperty. The argument should be a lambda expression selecting a property of the class "
                                             + typeof(T).Name + ". For example: \"conceptInfo => conceptInfo.SomeProperty\".");
            }

            if (!typeof(IConceptInfo).IsAssignableFrom(property.PropertyType))
            {
                throw new FrameworkException("Invalid FindByReference method argument: referenceProperty. The selected property should be of type that implements IConceptInfo."
                                             + " Property '" + property.Name + "' is of type '" + property.PropertyType.Name + "'.");
            }

            if (!property.PropertyType.IsAssignableFrom(checkValueType.GetType()))
            {
                throw new FrameworkException("Invalid FindByReference method arguments: The selected property " + property.Name
                                             + " type '" + property.PropertyType.Name
                                             + "' does not match the given referenced concept '" + checkValueType.GetUserDescription() + "'.");
            }

            return(property.Name);
        }
Esempio n. 19
0
 internal static void CheckSemantics(BrowseDataStructureInfo browse, string path, IEnumerable<IConceptInfo> concepts, IConceptInfo errorContext)
 {
     var property = GetSelectedPropertyByPath(browse, path, concepts);
     if (property.IsError)
         throw new DslSyntaxException("Invalid format of " + errorContext.GetUserDescription() + ": " + property.Error);
 }