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 bool IsPendingForDeletionData(Type interfaceType, DataScopeIdentifier dataScopeIdentifier, CultureInfo locale, DataKeyPropertyCollection dataKeyPropertyCollection) { Verify.ArgumentNotNull(interfaceType, "interfaceType"); Verify.ArgumentNotNull(dataScopeIdentifier, "dataScopeIdentifier"); Verify.ArgumentNotNull(dataKeyPropertyCollection, "dataKeyPropertyCollection"); List<DataKeyPropertyCollection> dataKeyPropertyCollections = GetDataKeyPropertyCollection(interfaceType, dataScopeIdentifier, locale); return dataKeyPropertyCollections.Contains(dataKeyPropertyCollection); }
/// <exclude /> public void AddPendingForDeletionData(Type interfaceType, DataScopeIdentifier dataScopeIdentifier, CultureInfo locale, DataKeyPropertyCollection dataKeyPropertyCollection) { Verify.ArgumentNotNull(interfaceType, "interfaceType"); Verify.ArgumentNotNull(dataScopeIdentifier, "dataScopeIdentifier"); Verify.ArgumentNotNull(dataKeyPropertyCollection, "dataKeyPropertyCollection"); List<DataKeyPropertyCollection> dataKeyPropertyCollections = GetDataKeyPropertyCollection(interfaceType, dataScopeIdentifier, locale); if (dataKeyPropertyCollections.Contains(dataKeyPropertyCollection)) { throw new ArgumentException(string.Format("The data item of type '{0}' with the key '{1}' has already been added", interfaceType, dataKeyPropertyCollection)); } dataKeyPropertyCollections.Add(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; }
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); }
/// <exclude /> public bool Equals(DataKeyPropertyCollection dataKeyPropertyCollection) { if (dataKeyPropertyCollection == null || dataKeyPropertyCollection.Count != Count) return false; foreach (var kvp in this.KeyProperties) { object value; if (!dataKeyPropertyCollection.TryGetKeyValue(kvp.Key, out value) || !kvp.Value.Equals(value)) { return false; } } return true; }
/// <exclude /> public bool Equals(DataKeyPropertyCollection dataKeyPropertyCollection) { if (dataKeyPropertyCollection == null || dataKeyPropertyCollection.Count != Count) { return(false); } foreach (var kvp in this.KeyProperties) { object value; if (!dataKeyPropertyCollection.TryGetKeyValue(kvp.Key, out value) || !kvp.Value.Equals(value)) { return(false); } } return(true); }
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 void RegisterKeyToBeAdded(DataType dataType, DataKeyPropertyCollection dataKeyPropertyCollection) { if (dataKeyPropertyCollection.Count != 1) return; var typeKeyInstallationData = _dataKeysToBeInstalled.GetOrAdd(dataType.InterfaceType, () => new TypeKeyInstallationData(dataType.InterfaceType)); var keyValuePair = dataKeyPropertyCollection.KeyProperties.First(); typeKeyInstallationData.RegisterKeyUsage(dataType, keyValuePair); }
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(); }
private void AddDataToDelete(Type interfaceType, DataScopeIdentifier dataScopeIdentifier, CultureInfo locale, DataKeyPropertyCollection dataKeyPropertyCollection) { DataType dataType = _dataToDelete.SingleOrDefault(dt => dt.InterfaceType == interfaceType && dt.DataScopeIdentifier.Equals(dataScopeIdentifier) && ((dt.Locale == null && locale == null) || (dt.Locale != null && dt.Locale.Equals(locale)))); if (dataType == null) { dataType = new DataType { InterfaceType = interfaceType, DataScopeIdentifier = dataScopeIdentifier, Locale = locale }; _dataToDelete.Add(dataType); } dataType.DataKeys.Add(dataKeyPropertyCollection); this.UninstallerContext.AddPendingForDeletionData(interfaceType, dataScopeIdentifier, locale, dataKeyPropertyCollection); }
/// <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; }
private void CheckForPotentialBrokenReferences(IData data, List<PackageFragmentValidationResult> validationResult, Type type, DataScopeIdentifier dataScopeIdentifier, CultureInfo locale, DataKeyPropertyCollection dataKeyPropertyCollection) { var pagesReferencingPageTypes = new HashSet<string>(); var dataReferencingDataToBeUninstalled = new HashSet<string>(); List<IData> referees = data.GetReferees(); bool addToDelete = true; foreach (IData referee in referees) { if (this.UninstallerContext.IsPendingForDeletionData(referee)) { continue; } addToDelete = false; if (referee is IPage && data is IPageType) { string pathToPage; using (new DataScope(referee.DataSourceId.PublicationScope, referee.DataSourceId.LocaleScope)) { pathToPage = GetPathToPage(referee as IPage); } if (!pagesReferencingPageTypes.Contains(pathToPage)) { validationResult.AddFatal(Texts.DataPackageFragmentUninstaller_PageTypeIsReferenced( data.GetLabel(), pathToPage)); pagesReferencingPageTypes.Add(pathToPage); } } else { var refereeType = referee.DataSourceId.InterfaceType; string label = referee.GetLabel(); string key = label + refereeType.FullName; if (!dataReferencingDataToBeUninstalled.Contains(key)) { validationResult.AddFatal(Texts.DataPackageFragmentUninstaller_DataIsReferenced( data.GetLabel(), type.FullName, label, refereeType.FullName)); dataReferencingDataToBeUninstalled.Add(key); } } } if (addToDelete) { AddDataToDelete(type, dataScopeIdentifier, locale, dataKeyPropertyCollection); } }
/// <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)"); }