Пример #1
0
        private static bool IsNullableStringReference(PropertyInfo propertyInfo)
        {
            var dataType = propertyInfo.DeclaringType;

            return(DataAttributeFacade.GetDataReferenceProperties(dataType)
                   .Any(foreignKey => foreignKey.SourcePropertyName == propertyInfo.Name && foreignKey.IsNullableString));
        }
Пример #2
0
        private Func <object, string> GetLabelFunction(out bool shouldBeSortedByLabel)
        {
            if (this.PropertyInfo.PropertyType == typeof(DateTime))
            {
                shouldBeSortedByLabel = false;
                return(f => this.DateTimeFormater.FormatLabel(f));
            }

            var referenceProperties = DataAttributeFacade.GetDataReferenceProperties(PropertyInfo.DeclaringType);
            var referenceInfo       = referenceProperties.FirstOrDefault(p => p.SourcePropertyName == this.PropertyInfo.Name);

            if (referenceInfo == null)
            {
                shouldBeSortedByLabel = false;
                return(f => (f ?? "(NULL)").ToString());
            }

            shouldBeSortedByLabel = true;

            return(key =>
            {
                if (key == null)
                {
                    return "(NULL)";
                }

                IData reference = DataFacade.TryGetDataByUniqueKey(referenceInfo.TargetType, key);
                return reference != null?reference.GetLabel() : key.ToString();
            });
        }
Пример #3
0
        private static void AddNewType(Type interfaceType)
        {
            var foreignKeyProperties = DataAttributeFacade.GetDataReferenceProperties(interfaceType);

            foreach (ForeignPropertyInfo foreignKeyPropertyInfo in foreignKeyProperties)
            {
                if (!foreignKeyPropertyInfo.SourcePropertyInfo.CanRead)
                {
                    throw new InvalidOperationException(
                              $"The property '{foreignKeyPropertyInfo.SourcePropertyInfo}' shoud have a getter");
                }
                if (foreignKeyPropertyInfo.TargetType.IsNotReferenceable())
                {
                    throw new InvalidOperationException(
                              $"The referenced type '{foreignKeyPropertyInfo.TargetType}' is marked NotReferenceable and can not be referenced by the interfaceType '{interfaceType}'");
                }

                PropertyInfo propertyInfo = foreignKeyPropertyInfo.TargetType.GetDataPropertyRecursively(foreignKeyPropertyInfo.TargetKeyPropertyName);

                Verify.IsNotNull(propertyInfo, "The data type '{0}' does not contain a property named '{1}' as specified by the '{2}' attribute on the data type '{3}'", foreignKeyPropertyInfo.TargetType, foreignKeyPropertyInfo.TargetKeyPropertyName, typeof(ForeignKeyAttribute), foreignKeyPropertyInfo.SourcePropertyInfo.DeclaringType);
                Verify.That(propertyInfo.CanRead, "The property '{0}' should have a getter", propertyInfo);
                if (foreignKeyPropertyInfo.IsNullableString && (propertyInfo.PropertyType != typeof(string)))
                {
                    throw new InvalidOperationException("NullableString can only be used when the foreign key is of type string");
                }

                Type sourcePropertyType = foreignKeyPropertyInfo.SourcePropertyInfo.PropertyType;
                if (sourcePropertyType.IsGenericType &&
                    (sourcePropertyType.GetGenericTypeDefinition() == typeof(Nullable <>)))
                {
                    // Handling og Nullable<>
                    sourcePropertyType = sourcePropertyType.GetGenericArguments()[0];
                }

                if (propertyInfo.PropertyType != sourcePropertyType)
                {
                    throw new InvalidOperationException(
                              $"Type mismatch '{propertyInfo.PropertyType}' and '{foreignKeyPropertyInfo.SourcePropertyInfo.PropertyType}' does not match from the two properties '{propertyInfo}' and '{foreignKeyPropertyInfo.SourcePropertyInfo}'");
                }

                foreignKeyPropertyInfo.TargetKeyPropertyInfo = propertyInfo;
            }


            _foreignKeyProperties.Add(interfaceType, foreignKeyProperties);

            foreach (ForeignPropertyInfo foreignKeyPropertyInfo in foreignKeyProperties)
            {
                List <Type> referees;

                if (!_referencedToReferees.TryGetValue(foreignKeyPropertyInfo.TargetType, out referees))
                {
                    referees = new List <Type>();

                    _referencedToReferees.Add(foreignKeyPropertyInfo.TargetType, referees);
                }
                else
                {
                    if (referees.Contains(interfaceType))
                    {
                        continue;
                    }
                }

                referees.Add(interfaceType);

                if (!DataProviderRegistry.AllInterfaces.Contains(foreignKeyPropertyInfo.TargetType))
                {
                    Log.LogCritical(LogTitle, $"The one type '{interfaceType}' is referring the non supported data type '{foreignKeyPropertyInfo.TargetType}'");
                }
            }
        }
Пример #4
0
        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);


            bool isVersionedDataType = typeof(IVersioned).IsAssignableFrom(dataType.InterfaceType);

            var requiredPropertyNames =
                (from dfd in dataTypeDescriptor.Fields
                 where !dfd.IsNullable && !(isVersionedDataType && dfd.Name == nameof(IVersioned.VersionId)) // Compatibility fix
                 select dfd.Name).ToList();

            var nonRequiredPropertyNames = dataTypeDescriptor.Fields.Select(f => f.Name)
                                           .Except(requiredPropertyNames).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())
                {
                    bool missingValues = false;
                    foreach (string propertyName in notAssignedRequiredProperties)
                    {
                        PropertyInfo propertyInfo = dataType.InterfaceType.GetPropertiesRecursively().Single(f => f.Name == propertyName);

                        if (propertyInfo.CanWrite)
                        {
                            var defaultValueAttribute = propertyInfo.GetCustomAttributesRecursively <NewInstanceDefaultFieldValueAttribute>().SingleOrDefault();
                            if (defaultValueAttribute == null || !defaultValueAttribute.HasValue)
                            {
                                _validationResult.AddFatal(GetText("DataPackageFragmentInstaller.MissingPropertyVaule").FormatWith(propertyName, dataType.InterfaceType));
                                missingValues = true;
                            }
                        }
                    }
                    if (missingValues)
                    {
                        continue;
                    }
                }


                // Validating keys already present
                if (!dataType.AllowOverwrite && !dataType.OnlyUpdate)
                {
                    bool dataLocaleExists =
                        !DataLocalizationFacade.IsLocalized(dataType.InterfaceType) ||
                        (!dataType.AddToAllLocales && !dataType.AddToCurrentLocale) ||
                        (dataType.Locale != null && !this.InstallerContext.IsLocalePending(dataType.Locale));

                    if (dataLocaleExists)
                    {
                        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));
            }
        }