/// <summary>
        /// Reverts part of the schema relevant to a problem to the state which when compared to its current
        /// state, regenerates the problem. The inverse of ResolveProblem.
        /// </summary>
        /// <param name="oldSchema">the old schema which generated the problem when compared to the current schema</param>
        /// <param name="problem">the problem it generated</param>
        public void ApplyProblem(ContentModelSchema oldSchema, ChangeProblem problem)
        {
            string aqTypeName = problem.GetAssemblyQualifiedTypeName();

            switch (problem.ProblemType)
            {
            case ChangeProblemType.DeletionNeeded:
                // copy the deleted type to the new schema
                TypeProperties.Add(aqTypeName, oldSchema.TypeProperties[aqTypeName]);
                break;

            case ChangeProblemType.PropertyDropped:
                // copy the dropped property to the new schema
                TypeProperties[aqTypeName].Add(problem.PropertyName, oldSchema.TypeProperties[aqTypeName][problem.PropertyName]);
                break;

            case ChangeProblemType.PropertyDroppedFromSummary:
                Type   contentType       = ContentTypeHierarchy.GetContentType(problem.TypeName);
                string aqSummaryTypeName = ContentTypeHierarchy.SummaryTypes[contentType].AssemblyQualifiedName;
                TypeProperties[aqTypeName].Add(problem.PropertyName, oldSchema.TypeProperties[aqTypeName][problem.PropertyName]);
                TypeProperties[aqSummaryTypeName].Add(problem.PropertyName, oldSchema.TypeProperties[aqSummaryTypeName][problem.PropertyName]);
                break;

            // Problems not requiring data modification
            case ChangeProblemType.NullObjectValue:
                break;
            }
        }
Exemple #2
0
        /// <summary>
        /// Run a filter based on the user inputs from the Filter page including the version key values for the selected version,
        /// the list of allowed content class names, the filters and a paging spec
        /// </summary>
        /// <param name="versionFilter">list of version keys in the order they appear in VersionManager.SelectionViewModel</param>
        /// <param name="classFilter">List of content class names</param>
        /// <param name="filters">List of filters</param>
        /// <param name="pagingSpec">Specification of paging</param>
        /// <returns>A list of container x summary tuples which are the results of filtering</returns>
        public List <Tuple <object, Summary> > RunFilter(List <string> versionFilter, string[] classFilter, List <ListFilter> filters, PagingSpec pagingSpec)
        {
            if (filters == null)
            {
                filters = new List <ListFilter>();
            }

            var reqVersion = new ItemVersion();
            var u          = LyniconSecurityManager.Current.User;
            var v          = VersionManager.Instance.CurrentVersion;
            var vsvms      = VersionManager.Instance.SelectionViewModel(u, v);
            int vIdx       = 0;

            foreach (var vsvm in vsvms)
            {
                object vVal = JsonConvert.DeserializeObject(versionFilter[vIdx]);
                reqVersion.Add(vsvm.VersionKey, vVal is Int64 ? Convert.ToInt32(vVal) : vVal);
                vIdx++;
            }

            VersionManager.Instance.PushState(VersioningMode.Specific, reqVersion);

            List <Tuple <object, Summary> > pagedResult = null;

            try
            {
                var types = (classFilter ?? new string[0]).Select(c => ContentTypeHierarchy.GetAnyType(c)).ToList();

                var vm = new ItemListerViewModel();

                for (var i = 0; i < filters.Count; i++)
                {
                    filters[i].MergeOriginal(vm.Filters[filters[i].Idx]);
                }

                var containerFilters = filters.Where(f => (f.Active || f.Sort != 0) && !typeof(Summary).IsAssignableFrom(f.ApplicableType)).ToList();
                var summaryFilters   = filters.Where(f => (f.Active || f.Sort != 0) && typeof(Summary).IsAssignableFrom(f.ApplicableType)).ToList();

                var filterResult = FilterManager.Instance.GetFilterSummaries(types, containerFilters, summaryFilters);

                pagingSpec.Total = filterResult.Count;

                pagedResult = filterResult.ApplyPaging(pagingSpec).ToList();

                //var resultView = pagedResult.Select(t => new List<string> { t.Item2.Url, t.Item2.Title }).ToList();

                //foreach (var filt in filters.Where(f => f.Show))
                //{
                //    for (int i = 0; i < resultView.Count; i++)
                //        resultView[i].Add(filt.GetShowText(pagedResult[i]));
                //}
            }
            finally
            {
                VersionManager.Instance.PopState();
            }

            return(pagedResult);
        }
        /// <summary>
        /// Find problems in the changes between two schemas by comparing this
        /// recorded schema to a given schema (usually the current schema)
        /// </summary>
        /// <param name="codeSchema">The current schema</param>
        /// <returns>List of potential problems arising from the differences between the schemas</returns>
        public List <ChangeProblem> FindProblems(ContentModelSchema codeSchema)
        {
            var changeProblems = new List <ChangeProblem>();

            foreach (string typeName in this.ContentTypes.Except(codeSchema.ContentTypes))
            {
                changeProblems.Add(new ChangeProblem(typeName, null, ChangeProblemType.DeletionNeeded));
            }

            var otherTypes = new Dictionary <string, Type>();

            foreach (string aqTypeName in codeSchema.TypeProperties.Keys)
            {
                string typeName = aqTypeName.UpTo(",");
                Type   type     = ContentTypeHierarchy.GetAnyType(typeName);
                if (type == null)
                {
                    type = Type.GetType(aqTypeName);
                    otherTypes.Add(aqTypeName, type);
                }
            }

            foreach (string typeName in codeSchema.ContentTypes)
            {
                // Check it doesn't initialise with a null value for an object or list property
                Type type = ContentTypeHierarchy.GetAnyType(typeName);
                if (type == null)
                {
                    type = otherTypes[typeName];
                }
                PropertyInfo nullProperty = new NoNullObjectCheck().Run(type);
                // Exception for UniqueId of Summary
                if (nullProperty != null && !(nullProperty.DeclaringType == typeof(Summary) && nullProperty.Name == "UniqueId"))
                {
                    changeProblems.Add(new ChangeProblem(type.FullName, nullProperty.Name, ChangeProblemType.NullObjectValue));
                }
            }

            // Types existing in both code and data schemas
            foreach (string aqTypeName in codeSchema.TypeProperties.Keys.Intersect(TypeProperties.Keys))
            {
                string typeName  = aqTypeName.UpTo(",");
                bool   isSummary = ContentTypeHierarchy.GetSummaryType(typeName) != null;
                if (isSummary && !this.SummaryMap.ContainsKey(typeName))
                {
                    log.Warn("Unused summary type: " + typeName);
                    continue;
                }
                foreach (string deletedProp in TypeProperties[aqTypeName].Keys.Except(codeSchema.TypeProperties[aqTypeName].Keys))
                {
                    if (isSummary)
                    {
                        // Test for when a property is dropped from the summary which was mapped to the content type
                        // In this case the property data needs copied from the Summary db field to the Content one
                        if (this.SummaryMap[typeName].ContainsValue(deletedProp) &&
                            this.SummaryTypes.ContainsValue(typeName))
                        {
                            var  oldContentProp            = this.SummaryMap[typeName].Single(kvp => kvp.Value == deletedProp).Key;
                            bool anyContentTypeHadProperty = this.SummaryTypes
                                                             .Where(kvp => kvp.Value == typeName)
                                                             .Any(kvp => TypeProperties[ContentTypeHierarchy.GetContentType(kvp.Key).AssemblyQualifiedName].ContainsKey(oldContentProp));
                            if (anyContentTypeHadProperty)
                            {
                                changeProblems.Add(new ChangeProblem(typeName, deletedProp, ChangeProblemType.PropertyDroppedFromSummary));
                            }
                        }
                    }
                    else
                    {
                        changeProblems.Add(new ChangeProblem(typeName, deletedProp, ChangeProblemType.PropertyDropped));
                    }
                }

                foreach (string addedProp in codeSchema.TypeProperties[aqTypeName].Keys.Except(TypeProperties[aqTypeName].Keys))
                {
                    if (isSummary)
                    {
                        // Test for when a property is added to the summary which is mapped from the content type
                        // In this case the data needs copied from the Content db field to the Summary
                        if (codeSchema.SummaryMap[typeName].ContainsValue(addedProp) &&
                            codeSchema.SummaryTypes.ContainsValue(typeName))
                        {
                            var newContentProp = codeSchema.SummaryMap[typeName].Single(kvp => kvp.Value == addedProp).Key;
                            var anyContentTypeContainedProp = codeSchema.SummaryTypes
                                                              .Where(kvp => kvp.Value == typeName)
                                                              .Any(kvp => TypeProperties[ContentTypeHierarchy.GetContentType(kvp.Key).AssemblyQualifiedName].ContainsKey(newContentProp));
                            if (anyContentTypeContainedProp)
                            {
                                changeProblems.Add(new ChangeProblem(typeName, addedProp, ChangeProblemType.PropertyAddedToSummary));
                            }
                        }
                    }
                }
            }

            return(changeProblems);
        }