private static bool ValueIsInUse(Type interfaceType, PropertyInfo property, string value, bool isKeyField)
        {
            if (isKeyField)
            {
                var keyCollection = new DataKeyPropertyCollection();
                keyCollection.AddKeyProperty(property, value);

                return(DataFacade.TryGetDataByUniqueKey(interfaceType, keyCollection) != null);
            }

            var parameter           = Expression.Parameter(interfaceType, "data");
            var predicateExpression = ExpressionHelper.CreatePropertyPredicate(parameter, new[]
            {
                new Tuple <PropertyInfo, object>(property, value)
            });

            Type delegateType = typeof(Func <,>).MakeGenericType(new [] { interfaceType, typeof(bool) });

            LambdaExpression lambdaExpression = Expression.Lambda(delegateType, predicateExpression, new [] { parameter });

            MethodInfo methodInfo = DataFacade.GetGetDataWithPredicatMethodInfo(interfaceType);

            var queryable = (IQueryable)methodInfo.Invoke(null, new object[] { lambdaExpression });

            return(queryable.OfType <IData>().Any());
        }
        public static DataKeyPropertyCollection CreateDataKeyPropertyCollection(this IData data)
        {
            Verify.ArgumentNotNull(data, "data");

            var dataKeyPropertyCollection = new DataKeyPropertyCollection();

            foreach (PropertyInfo propertyInfo in data.GetKeyProperties())
            {
                object value = propertyInfo.GetValue(data, null);

                dataKeyPropertyCollection.AddKeyProperty(propertyInfo, value);
            }

            return dataKeyPropertyCollection;
        }
        public static DataKeyPropertyCollection CreateDataKeyPropertyCollection(this IData data)
        {
            Verify.ArgumentNotNull(data, "data");

            var dataKeyPropertyCollection = new DataKeyPropertyCollection();

            foreach (PropertyInfo propertyInfo in data.GetKeyProperties())
            {
                object value = propertyInfo.GetValue(data, null);

                dataKeyPropertyCollection.AddKeyProperty(propertyInfo, value);
            }

            return(dataKeyPropertyCollection);
        }
        private void ValidateNonDynamicAddedType(DataType dataType)
        {
            if (dataType.InterfaceType == null)
            {
                _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.TypeNotConfigured").FormatWith(dataType.InterfaceTypeName));
                return;
            }

            if (!typeof(IData).IsAssignableFrom(dataType.InterfaceType))
            {
                _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.TypeNotInheriting").FormatWith(dataType.InterfaceType, typeof(IData)));
                return;
            }

            bool dataTypeLocalized = DataLocalizationFacade.IsLocalized(dataType.InterfaceType);
            if (!ValidateTargetLocaleInfo(dataType, dataTypeLocalized))
            {
                return;
            }

            int itemsAlreadyPresentInDatabase = 0;

            DataTypeDescriptor dataTypeDescriptor = DynamicTypeManager.BuildNewDataTypeDescriptor(dataType.InterfaceType);

            List<string> requiredPropertyNames =
                (from dfd in dataTypeDescriptor.Fields
                where !dfd.IsNullable
                select dfd.Name).ToList();

            List<string> nonRequiredPropertyNames =
                (from dfd in dataTypeDescriptor.Fields
                where dfd.IsNullable
                select dfd.Name).ToList();

            foreach (XElement addElement in dataType.Dataset)
            {
                var dataKeyPropertyCollection = new DataKeyPropertyCollection();

                bool propertyValidationPassed = true;
                var assignedPropertyNames = new List<string>();
                var fieldValues = new Dictionary<string, object>();

                var properties = GetDataTypeProperties(dataType.InterfaceType);

                foreach (XAttribute attribute in addElement.Attributes())
                {
                    string fieldName = attribute.Name.LocalName;

                    PropertyInfo propertyInfo;
                    if (!properties.TryGetValue(fieldName, out propertyInfo))
                    {
                        // A compatibility fix
                        if (IsObsoleteField(dataType, fieldName))
                        {
                            continue;
                        }

                        _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.MissingProperty").FormatWith(dataType.InterfaceType, fieldName));
                        propertyValidationPassed = false;
                        continue;
                    }

                    if (!propertyInfo.CanWrite)
                    {
                        _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.MissingWritableProperty").FormatWith(dataType.InterfaceType, fieldName));
                        propertyValidationPassed = false;
                        continue;
                    }

                    object fieldValue;
                    try
                    {
                        fieldValue = ValueTypeConverter.Convert(attribute.Value, propertyInfo.PropertyType);
                    }
                    catch (Exception)
                    {
                        _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.ConversionFailed").FormatWith(attribute.Value, propertyInfo.PropertyType));
                        propertyValidationPassed = false;
                        continue;
                    }

                    if (dataType.InterfaceType.GetKeyPropertyNames().Contains(fieldName))
                    {
                        dataKeyPropertyCollection.AddKeyProperty(fieldName, fieldValue);
                    }

                    assignedPropertyNames.Add(fieldName);
                    fieldValues.Add(fieldName, fieldValue);
                }

                if (!propertyValidationPassed)
                {
                    continue;
                }

                var notAssignedRequiredProperties = requiredPropertyNames.Except(assignedPropertyNames.Except(nonRequiredPropertyNames)).ToArray();
                if (notAssignedRequiredProperties.Any())
                {
                    foreach (string propertyName in notAssignedRequiredProperties)
                    {
                        PropertyInfo propertyInfo = dataType.InterfaceType.GetPropertiesRecursively().Single(f => f.Name == propertyName);

                        // Made for backward compatibility
                        if (propertyInfo.ReflectedType == typeof(IChangeHistory))
                        {
                            continue;
                        }

                        if (propertyInfo.CanWrite)
                        {
                            _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.MissingPropertyVaule").FormatWith(propertyName, dataType.InterfaceType));
                        }
                    }
                    continue;
                }

                // Validating keys already present
                if (!DataLocalizationFacade.IsLocalized(dataType.InterfaceType)
                    || (!dataType.AddToAllLocales && !dataType.AddToCurrentLocale)
                    || (dataType.Locale != null && !this.InstallerContext.IsLocalePending(dataType.Locale)))
                {
                    using (new DataScope(dataType.DataScopeIdentifier, dataType.Locale))
                    {
                        IData data = DataFacade.TryGetDataByUniqueKey(dataType.InterfaceType, dataKeyPropertyCollection);

                        if (data != null)
                        {
                            itemsAlreadyPresentInDatabase++;
                        }
                    }
                }

                RegisterKeyToBeAdded(dataType, dataKeyPropertyCollection);

                // Checking foreign key references
                foreach (var foreignKeyProperty in DataAttributeFacade.GetDataReferenceProperties(dataType.InterfaceType))
                {
                    if(!fieldValues.ContainsKey(foreignKeyProperty.SourcePropertyName)) continue;

                    object propertyValue = fieldValues[foreignKeyProperty.SourcePropertyName];

                    if (propertyValue == null || propertyValue == foreignKeyProperty.NullReferenceValue)
                    {
                        continue;
                    }

                    CheckForBrokenReference(dataType, foreignKeyProperty.TargetType, foreignKeyProperty.TargetKeyPropertyName, propertyValue);
                }
            }

            if(itemsAlreadyPresentInDatabase > 0)
            {
                _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.DataExists").FormatWith(dataType.InterfaceType, itemsAlreadyPresentInDatabase));
            }
        }
        private void ValidateDynamicAddedType(DataType dataType)
        {
            DataTypeDescriptor dataTypeDescriptor = this.InstallerContext.GetPendingDataTypeDescriptor(dataType.InterfaceTypeName);

            if (dataTypeDescriptor == null)
            {
                _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.MissingTypeDescriptor").FormatWith(dataType.InterfaceTypeName));
                return;
            }

            bool dataTypeLocalized = dataTypeDescriptor.SuperInterfaces.Contains(typeof (ILocalizedControlled));

            if (!ValidateTargetLocaleInfo(dataType, dataTypeLocalized))
            {
                return;
            }

            foreach (XElement addElement in dataType.Dataset)
            {
                var dataKeyPropertyCollection = new DataKeyPropertyCollection();
                bool propertyValidationPassed = true;
                var fieldValues = new Dictionary<string, object>();

                foreach (XAttribute attribute in addElement.Attributes())
                {
                    string fieldName = attribute.Name.LocalName;

                    // A compatibility fix
                    if (IsObsoleteField(dataTypeDescriptor, fieldName))
                    {
                        continue;
                    }

                    DataFieldDescriptor dataFieldDescriptor = dataTypeDescriptor.Fields[fieldName];

                    if (dataFieldDescriptor == null)
                    {
                        _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.MissingProperty").FormatWith(dataTypeDescriptor, fieldName));
                        propertyValidationPassed = false;
                        continue;
                    }

                    object fieldValue;
                    try
                    {
                        fieldValue = ValueTypeConverter.Convert(attribute.Value, dataFieldDescriptor.InstanceType);
                    }
                    catch (Exception)
                    {
                        _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.ConversionFailed").FormatWith(attribute.Value, dataFieldDescriptor.InstanceType));
                        propertyValidationPassed = false;
                        continue;
                    }

                    if (dataTypeDescriptor.KeyPropertyNames.Contains(fieldName))
                    {
                        dataKeyPropertyCollection.AddKeyProperty(fieldName, fieldValue);
                    }

                    fieldValues.Add(fieldName, fieldValue);
                }

                if (!propertyValidationPassed)
                {
                    continue;
                }

                // TODO: implement check if the same key has already been added

                // TODO: to be implemented for dynamic types
                // RegisterKeyToBeAdded(dataType, dataKeyPropertyCollection);

                // Checking foreign key references
                foreach (var referenceField in dataTypeDescriptor.Fields.Where(f => f.ForeignKeyReferenceTypeName != null))
                {
                    object propertyValue;
                    if (!fieldValues.TryGetValue(referenceField.Name, out propertyValue)
                        || propertyValue == null
                        || (propertyValue is Guid && (Guid)propertyValue == Guid.Empty)
                        || propertyValue is string && (string)propertyValue == "")
                    {
                        continue;
                    }

                    string referredTypeName = referenceField.ForeignKeyReferenceTypeName;
                    var referredType = TypeManager.TryGetType(referredTypeName);
                    if (referredType == null)
                    {
                        // TODO: implement reference check for dynamic types as well
                        continue;
                    }

                    string targetKeyPropertyName = referredType.GetKeyPropertyNames().SingleOrDefault();

                    CheckForBrokenReference(dataType, referredType, targetKeyPropertyName, propertyValue);
                }
            }
        }
        private static DataKeyPropertyCollection CopyFieldValues(DataType dataType, IData data, XElement addElement)
        {
            var dataKeyPropertyCollection = new DataKeyPropertyCollection();

            var properties = GetDataTypeProperties(dataType.InterfaceType);

            foreach (XAttribute attribute in addElement.Attributes())
            {
                string fieldName = attribute.Name.LocalName;
                if (IsObsoleteField(dataType, fieldName))
                {
                    continue;
                }

                PropertyInfo propertyInfo = properties[fieldName];

                object fieldValue = ValueTypeConverter.Convert(attribute.Value, propertyInfo.PropertyType);
                propertyInfo.SetValue(data, fieldValue, null);

                if (dataType.InterfaceType.GetKeyPropertyNames().Contains(fieldName))
                {
                    dataKeyPropertyCollection.AddKeyProperty(fieldName, fieldValue);
                }
            }

            return dataKeyPropertyCollection;
        } 
        private static bool ValueIsInUse(Type interfaceType, PropertyInfo property, string value, bool isKeyField)
        {
            if (isKeyField)
            {
                var keyCollection = new DataKeyPropertyCollection();
                keyCollection.AddKeyProperty(property, value);

                return DataFacade.TryGetDataByUniqueKey(interfaceType, keyCollection) != null;
            }

            var parameter = Expression.Parameter(interfaceType, "data");
            var predicateExpression = ExpressionHelper.CreatePropertyPredicate(parameter, new[]
            {
                new Tuple<PropertyInfo, object>(property, value)
            });

            Type delegateType = typeof(Func<,>).MakeGenericType(new [] { interfaceType, typeof(bool) });

            LambdaExpression lambdaExpression = Expression.Lambda(delegateType, predicateExpression, new [] { parameter });

            MethodInfo methodInfo = DataFacade.GetGetDataWithPredicatMethodInfo(interfaceType);

            var queryable = (IQueryable)methodInfo.Invoke(null, new object[] { lambdaExpression });

            return queryable.OfType<IData>().Any();
        }
        /// <exclude />
        public override IEnumerable<PackageFragmentValidationResult> Validate()
        {
            var validationResult = new List<PackageFragmentValidationResult>();

            if (this.Configuration.Count(f => f.Name == "Types") > 1)
            {
                validationResult.AddFatal(Texts.DataPackageFragmentUninstaller_OnlyOneElement);
                return validationResult;
            }

            _dataToDelete = new List<DataType>();

            XElement typesElement = this.Configuration.SingleOrDefault(f => f.Name == "Types");

            if (typesElement == null)
            {
                return validationResult;
            }

            foreach (XElement typeElement in typesElement.Elements("Type").Reverse())
            {
                XAttribute typeAttribute = typeElement.Attribute("type");
                XAttribute dataScopeIdentifierAttribute = typeElement.Attribute("dataScopeIdentifier");

                if (typeAttribute == null) 
                {
                    validationResult.AddFatal(Texts.DataPackageFragmentUninstaller_MissingAttribute("type"), typeElement); 
                    continue; 
                }

                if (dataScopeIdentifierAttribute == null) 
                {
                    validationResult.AddFatal(Texts.DataPackageFragmentUninstaller_MissingAttribute("dataScopeIdentifier"), typeElement); 
                    continue; 
                }

                Type type = TypeManager.TryGetType(typeAttribute.Value);
                if (type == null) continue;

                if (!DataFacade.GetAllInterfaces().Contains(type)) continue;


                DataScopeIdentifier dataScopeIdentifier;
                try
                {
                    dataScopeIdentifier = DataScopeIdentifier.Deserialize(dataScopeIdentifierAttribute.Value);
                }
                catch (Exception)
                {
                    validationResult.AddFatal("Wrong DataScopeIdentifier ({0}) name in the configuration".FormatWith(dataScopeIdentifierAttribute.Value), dataScopeIdentifierAttribute);
                    continue;
                }


                foreach (XElement datasElement in typeElement.Elements("Datas").Reverse())
                {
                    CultureInfo locale = null;

                    XAttribute localeAttribute = datasElement.Attribute("locale");
                    if (localeAttribute != null)
                    {
                        locale = CultureInfo.CreateSpecificCulture(localeAttribute.Value);
                    }

                    foreach (XElement keysElement in datasElement.Elements("Keys").Reverse())
                    {
                        bool allKeyPropertiesValidated = true;
                        var dataKeyPropertyCollection = new DataKeyPropertyCollection();

                        foreach (XElement keyElement in keysElement.Elements("Key"))
                        {
                            XAttribute keyNameAttribute = keyElement.Attribute("name");
                            XAttribute keyValueAttribute = keyElement.Attribute("value");


                            if (keyNameAttribute == null || keyValueAttribute == null)
                            {
                                if (keyNameAttribute == null) validationResult.AddFatal(GetText("DataPackageFragmentUninstaller.MissingAttribute").FormatWith("name"), keyElement);
                                if (keyValueAttribute == null) validationResult.AddFatal(GetText("DataPackageFragmentUninstaller.MissingAttribute").FormatWith("value"), keyElement);

                                allKeyPropertiesValidated = false;
                                continue;
                            }
                                
                            string keyName = keyNameAttribute.Value;
                            PropertyInfo keyPropertyInfo = type.GetPropertiesRecursively().SingleOrDefault(f => f.Name == keyName);
                            if (keyPropertyInfo == null)
                            {
                                validationResult.AddFatal(GetText("DataPackageFragmentUninstaller.MissingKeyProperty").FormatWith(type, keyName));
                                allKeyPropertiesValidated = false;
                            }
                            else
                            {
                                try
                                {
                                    object keyValue = ValueTypeConverter.Convert(keyValueAttribute.Value, keyPropertyInfo.PropertyType);
                                    dataKeyPropertyCollection.AddKeyProperty(keyName, keyValue);
                                }
                                catch (Exception)
                                {
                                    allKeyPropertiesValidated = false;
                                    validationResult.AddFatal(GetText("DataPackageFragmentUninstaller.DataPackageFragmentUninstaller").FormatWith(keyValueAttribute.Value, keyPropertyInfo.PropertyType));
                                }
                            }
                        }

                        if (allKeyPropertiesValidated)
                        {
                            IData data;
                            using (new DataScope(dataScopeIdentifier, locale))
                            {
                                data = DataFacade.TryGetDataByUniqueKey(type, dataKeyPropertyCollection);
                            }

                            if (data != null)
                            {
                                CheckForPotentialBrokenReferences(data, validationResult, type, dataScopeIdentifier, locale, dataKeyPropertyCollection);
                            }
                        }
                    }
                }
            }
            

            if (validationResult.Count > 0)
            {
                _dataToDelete = null;
            }

            return validationResult;
        }
示例#9
0
        /// <summary>
        /// This method finds the callers tree node own entity token by searching up/down using filters.
        /// In some cases this can be expensive.
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="entityToken"></param>
        /// <param name="dynamicContext"></param>
        /// <returns></returns>
        private EntityToken FindOwnEntityToken(TreeNode treeNode, EntityToken entityToken, TreeNodeDynamicContext dynamicContext)
        {
            DataElementsTreeNode dataElementsTreeNode = treeNode as DataElementsTreeNode;
            if (dataElementsTreeNode != null)
            {
                if (dataElementsTreeNode.InterfaceType == this.OwnerNode.InterfaceType) // We found it :)
                {
                    return entityToken;
                }
            }


            TreeDataFieldGroupingElementEntityToken dataFieldGroupingElementEntityToken = entityToken as TreeDataFieldGroupingElementEntityToken;
            if (dataFieldGroupingElementEntityToken != null) // Search 'downwards'
            {

                ParameterExpression parameterExpression = Expression.Parameter(this.OwnerNode.InterfaceType, "data");

                DataKeyPropertyCollection dataKeyPropertyCollection = new DataKeyPropertyCollection();
                dataKeyPropertyCollection.AddKeyProperty("Id", dataFieldGroupingElementEntityToken.ChildGeneratingDataElementsReferenceValue);

                Type dataType = dataFieldGroupingElementEntityToken.ChildGeneratingDataElementsReferenceType;

                IData parentData = DataFacade.GetDataByUniqueKey(dataType, dataKeyPropertyCollection);

                TreeNodeDynamicContext dummyContext = new TreeNodeDynamicContext(TreeNodeDynamicContextDirection.Down);
                dummyContext.CustomData.Add("ParentData", parentData);

                IData resultData;
                if (this.OwnerNode.InterfaceType == TypeManager.GetType(dataFieldGroupingElementEntityToken.Type))
                {
                    Expression filterExpression = this.CreateDownwardsFilterExpression(parameterExpression, dummyContext);

                    Expression whereExpression = ExpressionHelper.CreateWhereExpression(DataFacade.GetData(this.OwnerNode.InterfaceType).Expression, parameterExpression, filterExpression);

                    resultData = (IData)DataFacade.GetData(this.OwnerNode.InterfaceType).Provider.CreateQuery(whereExpression).ToEnumerableOfObjects().First();
                }
                else
                {
                    resultData = parentData;
                }

                return resultData.GetDataEntityToken();
            }


            AncestorResult ancestorResult = treeNode.GetParentEntityToken(entityToken, this.ParentFilterType, dynamicContext);

            if ((this.OwnerNode.Id == ancestorResult.TreeNode.Id) || (this.OwnerNode.IsDescendant(ancestorResult.TreeNode))) // Search upwards
            {
                return FindOwnEntityToken(ancestorResult.TreeNode, ancestorResult.EntityToken, dynamicContext);
            }


            // Search 'downwards' by using the parent datas key value to get 
            DataElementsTreeNode parentDataElementsTreeNode = (DataElementsTreeNode)ancestorResult.TreeNode;
            if (this.ParentFilterType == parentDataElementsTreeNode.InterfaceType)
            {
                DataEntityToken dataEntityToken = (DataEntityToken)ancestorResult.EntityToken;

                ParameterExpression parameterExpression = Expression.Parameter(this.OwnerNode.InterfaceType, "data");

                TreeNodeDynamicContext dummyContext = new TreeNodeDynamicContext(TreeNodeDynamicContextDirection.Down);
                dummyContext.CustomData.Add("ParentData", dataEntityToken.Data);

                Expression filterExpression = this.CreateDownwardsFilterExpression(parameterExpression, dummyContext);

                Expression whereExpression = ExpressionHelper.CreateWhereExpression(DataFacade.GetData(this.OwnerNode.InterfaceType).Expression, parameterExpression, filterExpression);

                IData resultData = (IData)DataFacade.GetData(this.OwnerNode.InterfaceType).Provider.CreateQuery(whereExpression).ToEnumerableOfObjects().First();

                return resultData.GetDataEntityToken();
            }


            throw new InvalidOperationException("Missing parent id filtering or try to simplify the parent id filterings (Unable to find own entity token)");
        }