public IQuery GetQuery <TEntity>() { var query = Create(Take, 1 + Skip / Math.Max(1, Take), SearchTerm, ActiveTab); query.CollectionAlias = CollectionAlias; if (OrderBys != null) { query.SetOrderBys(OrderBys .Select(x => { var property = PropertyMetadataHelper.GetPropertyMetadata(typeof(TEntity), x.PropertyName); if (property == null || x.Fingerprint != property.Fingerprint) { throw new InvalidOperationException("The used orderByExpression could not be converted back into IPropertyMetadata. " + "Only properties are supported for conversion, so x.Property or x.Property.NestedProperty. More complicated expressions cannot" + "be converted to and from strings easily and will not work with ApiRepositories. If these complex expressions are required, " + "please convert to ServerSide RapidCMS."); } return(new OrderByModel(x.OrderByType, property)); })); } return(query); }
public void ReferenceTypePropertyCanHandleNull() { var instance = new ReferenceType { Data = "x" }; var dataProperty = (IFullPropertyMetadata)PropertyMetadataHelper.GetPropertyMetadata <ReferenceType, string>(x => x.Data); Assert.IsNotNull(dataProperty); Assert.DoesNotThrow(() => dataProperty.Setter(instance, null)); Assert.IsNull(instance.Data); }
public void NullableValueTypePropertyCanHandleNull() { var instance = new NullableValueType { Data = 1 }; var dataProperty = (IFullPropertyMetadata)PropertyMetadataHelper.GetPropertyMetadata <NullableValueType, int?>(x => x.Data); Assert.IsNotNull(dataProperty); Assert.DoesNotThrow(() => dataProperty.Setter(instance, null)); Assert.IsNull(instance.Data); }
public void BasicNotNullNullableStringExpression() { var instance = new BasicClass { NullableTest = "test" }; Expression <Func <BasicClass, string?> > func = (BasicClass x) => x.NullableTest; var data = PropertyMetadataHelper.GetExpressionMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("test", data.StringGetter(instance)); }
public void SelfAsProperty() { var instance = new RecursiveClass { Name = "Self" }; Expression <Func <RecursiveClass, RecursiveClass> > func = x => x; var data = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("Self", ((RecursiveClass)data.Getter(instance)).Name); }
public void PropertyFingerprintEquality3() { Expression <Func <ParentCollectionClass, IEnumerable <int> > > func1 = (ParentCollectionClass z) => z.Basics.Select(q => q.Id); var data1 = PropertyMetadataHelper.GetPropertyMetadata(func1); Expression <Func <ParentCollectionClass, IEnumerable <int> > > func2 = (ParentCollectionClass x) => x.Basics.Select(x => 1); var data2 = PropertyMetadataHelper.GetPropertyMetadata(func2); Assert.IsNotNull(data1.Fingerprint); Assert.IsNotNull(data2.Fingerprint); Assert.AreNotEqual(data1.Fingerprint, data2.Fingerprint); }
public void PropertyFromPropertyName() { var expected = "string"; var instance = new BasicClass { Test = expected }; var data = PropertyMetadataHelper.GetPropertyMetadata(instance.GetType(), "Test"); Assert.IsNotNull(data); Assert.AreEqual(nameof(BasicClass.Test), data.PropertyName); Assert.AreEqual(expected, data.Getter(instance)); }
public void ParentAsPropertyViaInterface() { IRecursiveClass instance = new RecursiveClass { Name = "Self", Parent = new RecursiveClass { Name = "Parent" } }; Expression <Func <IRecursiveClass, IRecursiveClass> > func = x => x.Parent; var data = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("Parent", ((RecursiveClass)data.Getter(instance)).Name); }
public void PropertyFromNestedPropertyName() { var expected = "string"; var instance = new ParentClass { Basic = new BasicClass { Test = expected } }; var data = PropertyMetadataHelper.GetPropertyMetadata(instance.GetType(), "Basic.Test"); Assert.IsNotNull(data); Assert.AreEqual($"{nameof(ParentClass.Basic)}.{nameof(BasicClass.Test)}", data.PropertyName); Assert.AreEqual(expected, data.Getter(instance)); }
public IEnumerable <FieldConfig> GetFields(Type subject, Features features) { var properties = subject.GetProperties(); return(properties .Select(property => { var fieldAttribute = property.GetCustomAttribute <FieldAttribute>(); if (fieldAttribute != null) { var useListName = !features.HasFlag(Features.CanEdit) || features.HasFlag(Features.CanGoToEdit); var useName = features.HasFlag(Features.CanEdit) && !useListName; if ((useName && !string.IsNullOrEmpty(fieldAttribute.Name)) || (useListName && !string.IsNullOrEmpty(fieldAttribute.ListName))) { return (property, fieldAttribute); } } return default; }) .Where(x => x != default) .Select((data, index) => { if (data.fieldAttribute.EditorType?.IsSameTypeOrDerivedFrom(typeof(ComponentBase)) == false) { throw new InvalidOperationException("ResourceType of [Display] must be a valid BaseEditor derived component."); } var propertyMetadata = PropertyMetadataHelper.GetPropertyMetadata(subject, data.property); var propertyType = data.property.PropertyType.IsGenericType && data.property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>) ? Nullable.GetUnderlyingType(data.property.PropertyType) ! : data.property.PropertyType; var displayType = features.HasFlag(Features.CanEdit) ? DisplayType.None : DisplayType.Label; var editorType = !features.HasFlag(Features.CanEdit) ? EditorType.None : data.fieldAttribute.EditorType != null ? EditorType.Custom : EditorTypeHelper.TryFindDefaultEditorType(propertyType); var customType = editorType == EditorType.Custom ? data.fieldAttribute.EditorType : null; var relationConfig = editorType != EditorType.Select ? null : new DataProviderRelationConfig(typeof(EnumDataProvider <>).MakeGenericType(propertyType), default); return new FieldConfig { Description = features.HasFlag(Features.CanEdit) ? data.fieldAttribute.Description : default,
public void BasicNullableNonStringProperty() { var instance = new BasicClass { NullableTest = "Test Value", Id = 1 }; Expression <Func <BasicClass, int?> > func = (BasicClass x) => x.NullableTest == null ? default(int?) : x.NullableTest.Length; var data = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(data); Assert.AreEqual(10, data.Getter(instance)); Assert.AreEqual(typeof(int?), data.PropertyType); Assert.AreEqual(typeof(BasicClass), data.ObjectType); Assert.IsNull(data as IFullPropertyMetadata); }
public void BasicReadonlyNonStringProperty() { var instance = new BasicClass { Test = "Test Value", Id = 1 }; Expression <Func <BasicClass, int> > func = (BasicClass x) => x.Id * 2; var data = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("x => (x.Id * 2)", data.PropertyName); Assert.AreEqual(2, data.Getter(instance)); Assert.AreEqual(typeof(int), data.PropertyType); Assert.AreEqual(typeof(BasicClass), data.ObjectType); Assert.IsNull(data as IFullPropertyMetadata); }
public void BasicNullableProperty() { var instance = new BasicClass { NullableTest = "Test Value" }; Expression <Func <BasicClass, string?> > func = (BasicClass x) => x.NullableTest; var data = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("NullableTest", data.PropertyName); Assert.AreEqual("Test Value", data.Getter(instance)); Assert.AreEqual(typeof(string), data.PropertyType); Assert.AreEqual(typeof(BasicClass), data.ObjectType); Assert.IsNotNull(data as IFullPropertyMetadata); }
public void BasicReadonlyProperty() { var instance = new BasicClass { Test = "Test Value" }; Expression <Func <BasicClass, string> > func = (BasicClass x) => x.Test.ToLower(); var data = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("x => x.Test.ToLower()", data.PropertyName); Assert.AreEqual("test value", data.Getter(instance)); Assert.AreEqual(typeof(string), data.PropertyType); Assert.AreEqual(typeof(BasicClass), data.ObjectType); Assert.IsNull(data as IFullPropertyMetadata); }
public void PropertyFingerprintEquality4() { Expression <Func <ParentClass, string> > func1 = (ParentClass z) => z.Basic.Test; var data1 = PropertyMetadataHelper.GetPropertyMetadata(func1); var data2 = PropertyMetadataHelper.GetPropertyMetadata(typeof(ParentClass), new[] { typeof(ParentClass).GetProperty(nameof(ParentClass.Basic)) }, typeof(BasicClass).GetProperty(nameof(BasicClass.Test))); var data3 = PropertyMetadataHelper.GetPropertyMetadata(typeof(ParentClass), "Basic.Test"); Assert.IsNotNull(data1.Fingerprint); Assert.IsNotNull(data2.Fingerprint); Assert.IsNotNull(data3.Fingerprint); Assert.AreEqual(data1.Fingerprint, data2.Fingerprint); Assert.AreEqual(data2.Fingerprint, data3.Fingerprint); Assert.AreEqual(data1.Fingerprint, data3.Fingerprint); }
public void BasicNonStringExpression() { var instance = new BasicClass { Test = "Test Value", Id = 3 }; Expression <Func <BasicClass, int> > func = (BasicClass x) => x.Id; var data = PropertyMetadataHelper.GetExpressionMetadata(func); Assert.IsNull(data); var propertyData = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(propertyData); Assert.AreEqual("Id", propertyData.PropertyName); Assert.AreEqual(3, propertyData.Getter(instance)); Assert.AreEqual(typeof(int), propertyData.PropertyType); }
public void PropertyFromProperties() { var expected = "string"; var instance = new ParentClass { Basic = new BasicClass { Test = expected } }; var property1 = typeof(ParentClass).GetProperty(nameof(ParentClass.Basic)); var property2 = typeof(BasicClass).GetProperty(nameof(BasicClass.Test)); var data = PropertyMetadataHelper.GetPropertyMetadata(instance.GetType(), new[] { property1 }, property2); Assert.IsNotNull(data); Assert.AreEqual($"{nameof(ParentClass.Basic)}.{nameof(BasicClass.Test)}", data.PropertyName); Assert.AreEqual(expected, data.Getter(instance)); }
public void BasicNullStringExpression() { var instance = new BasicClass { Test = null }; Expression <Func <BasicClass, string> > func = (BasicClass x) => x.Test; var data = PropertyMetadataHelper.GetExpressionMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("", data.StringGetter(instance)); var propertyData = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(propertyData as IFullPropertyMetadata); Assert.AreEqual("Test", propertyData.PropertyName); Assert.AreEqual(null, propertyData.Getter(instance)); Assert.AreEqual(typeof(string), propertyData.PropertyType); }
public void BasicStringExpressionConverted() { var instance = new BasicClass { Test = "Test Value" }; Expression <Func <BasicClass, string> > func = (BasicClass x) => string.Join(' ', x.Test.ToCharArray()); var propertyData = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(propertyData); Assert.IsNull(propertyData as IFullPropertyMetadata); Assert.AreEqual("x => Join( , x.Test.ToCharArray())", propertyData.PropertyName); Assert.AreEqual("T e s t V a l u e", propertyData.Getter(instance)); var data = PropertyMetadataHelper.GetExpressionMetadata(propertyData); Assert.IsNotNull(data); Assert.AreEqual("T e s t V a l u e", data.StringGetter(instance)); }
public void BasicStringExpression() { var instance = new BasicClass { Test = "Test Value" }; Expression <Func <BasicClass, string> > func = (BasicClass x) => $"{x.Test} - Blub"; var data = PropertyMetadataHelper.GetExpressionMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("Test Value - Blub", data.StringGetter(instance)); var propertyData = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(propertyData); Assert.IsNull(propertyData as IFullPropertyMetadata); Assert.AreEqual("x => Format(\"{0} - Blub\", x.Test)", propertyData.PropertyName); Assert.AreEqual("Test Value - Blub", propertyData.Getter(instance)); Assert.AreEqual(typeof(string), propertyData.PropertyType); }
public IPropertyDetailConfig AddPropertyDetail <TDetailConfig, TValueForEditor>( string alias, string name, string?description, EditorType editorType, Expression <Func <IPropertyDetailModel <TDetailConfig>, TValueForEditor> > configEditor) where TDetailConfig : class, IDetailConfig { var validator = new PropertyDetailConfig( alias, name, description, GetEditorByEditorType(editorType), typeof(TDetailConfig), PropertyMetadataHelper.GetPropertyMetadata(configEditor) as IFullPropertyMetadata); _details.Add(validator); return(validator); }
public void BasicStringExpression2() { var instance = new BasicClass { Test = "Test Value" }; Expression <Func <BasicClass, string> > func = (BasicClass x) => $"Blaat"; var data = PropertyMetadataHelper.GetExpressionMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("Blaat", data.StringGetter(instance)); var propertyData = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(propertyData); Assert.IsNull(propertyData as IFullPropertyMetadata); Assert.AreEqual("x => (\"Blaat\" ?? \"\")", propertyData.PropertyName); Assert.AreEqual("Blaat", propertyData.Getter(instance)); Assert.AreEqual(typeof(string), propertyData.PropertyType); }
public void NestedNonStringProperty() { var instance = new ParentClass { Basic = new BasicClass { Test = "Test Value", Id = 1 } }; Expression <Func <ParentClass, int> > func = (ParentClass x) => x.Basic.Id; var data = PropertyMetadataHelper.GetPropertyMetadata(func) as IFullPropertyMetadata; Assert.IsNotNull(data); Assert.AreEqual("BasicId", data.PropertyName); Assert.AreEqual(1, data.Getter(instance)); Assert.AreEqual(typeof(int), data.PropertyType); Assert.AreEqual(typeof(ParentClass), data.ObjectType); data.Setter(instance, 2); Assert.AreEqual(2, instance.Basic.Id); }
public void NestedProperty() { var instance = new ParentClass { Basic = new BasicClass { Test = "Test Value" } }; Expression <Func <ParentClass, string> > func = (ParentClass x) => x.Basic.Test; var data = PropertyMetadataHelper.GetPropertyMetadata(func) as IFullPropertyMetadata; Assert.IsNotNull(data); Assert.AreEqual("BasicTest", data.PropertyName); Assert.AreEqual("Test Value", data.Getter(instance)); Assert.AreEqual(typeof(string), data.PropertyType); Assert.AreEqual(typeof(ParentClass), data.ObjectType); data.Setter(instance, "New Value"); Assert.AreEqual("New Value", instance.Basic.Test); }
public void NestedStringExpression() { var instance = new ParentClass { Basic = new BasicClass { Test = "Test Value" } }; Expression <Func <ParentClass, string> > func = (ParentClass x) => $"{x.Basic} {x.Basic.Test}"; var data = PropertyMetadataHelper.GetExpressionMetadata(func); Assert.IsNotNull(data); Assert.AreEqual("RapidCMS.Common.Tests.PropertyMetadata.PropertyMetadataTests+BasicClass Test Value", data.StringGetter(instance)); var propertyData = PropertyMetadataHelper.GetPropertyMetadata(func); Assert.IsNotNull(propertyData); Assert.IsNull(propertyData as IFullPropertyMetadata); Assert.AreEqual("x => Format(\"{0} {1}\", x.Basic, x.Basic.Test)", propertyData.PropertyName); Assert.AreEqual("RapidCMS.Common.Tests.PropertyMetadata.PropertyMetadataTests+BasicClass Test Value", propertyData.Getter(instance)); Assert.AreEqual(typeof(string), propertyData.PropertyType); }
public IEnumerable <FieldConfig> GetFields(Type subject, Features features) { var properties = subject.GetProperties(); return(properties .Select(property => { var displayAttribute = property.GetCustomAttribute <DisplayAttribute>(); if (displayAttribute != null) { if ((features.HasFlag(Features.CanEdit) && !string.IsNullOrEmpty(displayAttribute.Name)) || (!features.HasFlag(Features.CanEdit) && !string.IsNullOrEmpty(displayAttribute.ShortName))) { return (property, displayAttribute); } } return default; }) .Where(x => x != default) .Select((data, index) => { if (data.displayAttribute.ResourceType?.IsSameTypeOrDerivedFrom(typeof(ComponentBase)) == false) { throw new InvalidOperationException("ResourceType of [Display] must be a valid BaseEditor derived component."); } var propertyMetadata = PropertyMetadataHelper.GetPropertyMetadata(subject, data.property); var displayType = features.HasFlag(Features.CanEdit) ? DisplayType.None : DisplayType.Label; var editorType = !features.HasFlag(Features.CanEdit) ? EditorType.None : data.displayAttribute.ResourceType != null ? EditorType.Custom : EditorTypeHelper.TryFindDefaultEditorType(data.property.PropertyType); var customType = editorType == EditorType.Custom ? data.displayAttribute.ResourceType : null; return new FieldConfig { Description = features.HasFlag(Features.CanEdit) ? data.displayAttribute.Description : default,
private IEnumerable <IPropertyMetadata> GetPropertyMetadatas(IEntity reference, IEnumerable <PropertyInfo>?objectGetters = default) { Func <object, object> getObject; if (objectGetters == null) { getObject = (root) => root; } else { getObject = (root) => objectGetters.Aggregate(root, (@obj, objectGetter) => objectGetter.GetValue(@obj)); } var properties = getObject(reference).GetType().GetProperties(); foreach (var property in properties) { var validateObjectAttribute = property.GetCustomAttribute <ValidateObjectAttribute>(); if (validateObjectAttribute != null) { // only venture into nested objects when the model wants them validated foreach (var nestedPropertyMetadata in GetPropertyMetadatas(reference, (objectGetters ?? new PropertyInfo[] { }).Union(new[] { property }))) { yield return(nestedPropertyMetadata); } } var propertyMetadata = PropertyMetadataHelper.GetPropertyMetadata(reference.GetType(), objectGetters, property); if (propertyMetadata == null) { continue; } yield return(propertyMetadata); } }
private IPropertyMetadata GetMetadata <TValue>(Expression <Func <TEntity, TValue> > property) => PropertyMetadataHelper.GetPropertyMetadata(property) ?? throw new InvalidOperationException("Given expression cannot be converted to PropertyMetadata");
public async Task <FormDataProvider?> GetDataProviderAsync(FieldSetup field) { if (!(field is PropertyFieldSetup propertyField && propertyField.Relation != null)) { return(null); } switch (propertyField.Relation) { case RepositoryRelationSetup collectionRelation: var collectionSetup = collectionRelation.CollectionAlias == null ? default : await _collectionSetupResolver.ResolveSetupAsync(collectionRelation.CollectionAlias); var repo = collectionRelation.RepositoryAlias != null ? _repositoryResolver.GetRepository(collectionRelation.RepositoryAlias) : collectionSetup != null ? _repositoryResolver.GetRepository(collectionSetup) : default; if (repo == null) { throw new InvalidOperationException($"Field {propertyField.Property!.PropertyName} has incorrectly configure relation, cannot find repository for alias {(collectionRelation.CollectionAlias ?? collectionRelation.RepositoryAlias)}."); } // TODO: investigate whether this can be moved to Setup to allow for better caching var idProperty = collectionRelation.IdProperty ?? collectionSetup?.ElementSetup?.IdProperty ?? throw new InvalidOperationException($"Field {propertyField.Property!.PropertyName} has incorrect Id property metadata."); var displayProperties = collectionRelation.DisplayProperties ?? collectionSetup?.ElementSetup?.DisplayProperties ?? throw new InvalidOperationException($"Field {propertyField.Property!.PropertyName} has incorrect display properties metadata."); var relatedElementGetter = collectionRelation.RelatedElementsGetter ?? ((collectionRelation.IsRelationToMany && propertyField.Property != null && propertyField.Property.PropertyType.IsAssignableTo(typeof(IEnumerable <IEntity>))) ? PropertyMetadataHelper.GetPropertyMetadata <IEnumerable <IEntity>, IEnumerable <object?> >(x => x.Select(idProperty.Getter)) : default); var provider = new CollectionDataProvider( repo, _concurrencyService, collectionRelation.RepositoryAlias, collectionRelation.CollectionAlias, relatedElementGetter, collectionRelation.EntityAsParent, collectionRelation.RepositoryParentSelector, idProperty, displayProperties, collectionRelation.RelatedEntityType ?? collectionSetup?.EntityVariant.Type ?? typeof(object), propertyField.Property !, _mediator); return(new FormDataProvider( propertyField.Property !, provider)); case DataProviderRelationSetup dataProviderRelation: var dataCollection = _serviceProvider.GetService <IDataCollection>(dataProviderRelation.DataCollectionType); if (dataProviderRelation.Configuration != null) { dataCollection.Configure(dataProviderRelation.Configuration); } return(new FormDataProvider(propertyField.Property !, dataCollection)); case ConcreteDataProviderRelationSetup concreteDataProvider: return(new FormDataProvider(propertyField.Property !, concreteDataProvider.DataCollection)); default: throw new InvalidOperationException(); } ; }
public IReadOnlyList <IElement>?GetRelatedElementsFor <TEntity, TValue>(Expression <Func <TEntity, TValue> > propertyExpression) where TEntity : IEntity { var property = PropertyMetadataHelper.GetPropertyMetadata(propertyExpression); return(Relations.FirstOrDefault(x => x.Property.Fingerprint == property?.Fingerprint)?.RelatedElements ?? default); }