Ejemplo n.º 1
0
        private void ProcessPropertyValue(IHypermediaResolver resolver, List <CuriesLink> curies, IEnumerable <IResource> resources)
        {
            var resourceList = resources.ToList();

            var relationName = resources is IResourceList list ? list.RelationName : resourceList.FirstOrDefault()?.Rel ?? string.Empty;

            var embeddedResource = new EmbeddedResource {
                IsSourceAnArray = true, RelationName = relationName
            };

            foreach (var resourceItem in resourceList)
            {
                embeddedResource.Resources.Add(resourceItem);

                if (!(resourceItem is Representation representation))
                {
                    continue;
                }

                representation.RepopulateRecursively(resolver, curies); // traverse ...
                var link = representation.ToLink(resolver);

                if (link != null)
                {
                    Links.Add(link); // add a link to embedded to the container ...
                }
            }

            Embedded.Add(embeddedResource);
        }
Ejemplo n.º 2
0
        private void FillCommand(
            HypermediaClientObject hypermediaObjectInstance,
            PropertyInfo propertyInfo,
            IToken rootObject,
            IHypermediaResolver resolver)
        {
            var commandAttribute = propertyInfo.GetCustomAttribute <HypermediaCommandAttribute>();

            if (commandAttribute == null)
            {
                throw new Exception($"Hypermedia command '{propertyInfo.Name}' requires a {nameof(HypermediaCommandAttribute)} ");
            }

            // create instance in any case so CanExecute can be called
            var commandInstance = this.CreateHypermediaClientCommand(propertyInfo.PropertyType);

            propertyInfo.SetValue(hypermediaObjectInstance, commandInstance);

            var actions       = rootObject["actions"];
            var desiredAction = actions.FirstOrDefault(e => this.IsDesiredAction(e, commandAttribute.Name));

            if (actions == null || desiredAction == null)
            {
                if (IsMandatoryHypermediaProperty(propertyInfo))
                {
                    throw new Exception($"Mandatory hypermedia command '{propertyInfo.Name}' not found.");
                }
                return;
            }

            this.FillCommandParameters(commandInstance, desiredAction, commandAttribute.Name, resolver);
        }
Ejemplo n.º 3
0
        protected static void Append <T>(IResource resource, IHypermediaResolver resolver) where T : class, IResource
        // called using reflection ...
        {
            var typed = resource as T;

            if (typed == null)
            {
                throw new ArgumentOutOfRangeException(nameof(resource), "resource must be of type " + typeof(T));
            }

            IHypermediaAppender <T> appender   = resolver.ResolveAppender(typed);
            List <Link>             configured = resolver.ResolveLinks(typed).ToList();
            Link link = resolver.ResolveSelf(typed);

            if (link != null)
            {
                configured.Insert(0, link);
            }

            if (configured.Count > 0 && (appender != null))
            {
                if (typed.Links == null)
                {
                    typed.Links = new List <Link>(); // make sure resource.Links.Add() can safely be called inside the appender
                }
                appender.Append(typed, configured);

                if ((typed.Links != null) && !typed.Links.Any())
                {
                    typed.Links = null; // prevent _links property serialization
                }
            }
        }
Ejemplo n.º 4
0
        public ResourceConverter(IHypermediaResolver hypermediaConfiguration)
        {
            if (hypermediaConfiguration == null)
                throw new ArgumentNullException("hypermediaConfiguration");

            this.hypermediaConfiguration = hypermediaConfiguration;
        }
Ejemplo n.º 5
0
        //todo linked entities
        //todo no derived types considered
        private void FillEntities(
            HypermediaClientObject hypermediaObjectInstance,
            PropertyInfo propertyInfo,
            IToken rootObject,
            IHypermediaResolver resolver)
        {
            var relationsAttribute = propertyInfo.GetCustomAttribute <HypermediaRelationsAttribute>();
            var classes            = this.GetClassesFromEntitiesListProperty(propertyInfo);

            var entityCollection = Activator.CreateInstance(propertyInfo.PropertyType);

            propertyInfo.SetValue(hypermediaObjectInstance, entityCollection);

            var entities = rootObject["entities"];

            if (entities == null)
            {
                return;
            }

            var matchingEntities = entities.Where(e =>
                                                  this.EntityRelationsMatch(e, relationsAttribute.Relations) && this.EntityClassMatch(e, classes, propertyInfo.Name));

            var genericAddFunction = entityCollection.GetType().GetTypeInfo().GetMethod("Add");

            foreach (var match in matchingEntities)
            {
                var entity = this.ReadHypermediaObject(match, resolver);
                genericAddFunction.Invoke(entityCollection, new object[] { entity });
            }
        }
Ejemplo n.º 6
0
        void ProcessPropertyValue(IHypermediaResolver resolver, List <CuriesLink> curies, IResource resource)
        {
            var embeddedResource = new EmbeddedResource {
                IsSourceAnArray = false
            };

            embeddedResource.Resources.Add(resource);

            Embedded.Add(embeddedResource);

            var representation = resource as Representation;

            if (representation == null)
            {
                return;
            }

            representation.RepopulateRecursively(resolver, curies);         // traverse ...
            var link = representation.ToLink(resolver);

            if (link != null)
            {
                Links.Add(link);             // add a link to embedded to the container ...
            }
        }
Ejemplo n.º 7
0
        void ProcessPropertyValue(IHypermediaResolver resolver, List <CuriesLink> curies, IEnumerable <IResource> resources)
        {
            var resourceList = resources.ToList();

            if (!resourceList.Any())
            {
                return;
            }

            var embeddedResource = new EmbeddedResource {
                IsSourceAnArray = true
            };

            foreach (var resourceItem in resourceList)
            {
                embeddedResource.Resources.Add(resourceItem);

                var representation = resourceItem as Representation;

                if (representation == null)
                {
                    continue;
                }

                representation.RepopulateRecursively(resolver, curies);         // traverse ...
                var link = representation.ToLink(resolver);

                if (link != null)
                {
                    Links.Add(link);             // add a link to embedded to the container ...
                }
            }

            Embedded.Add(embeddedResource);
        }
Ejemplo n.º 8
0
        protected static void Append <T>(IResource resource, IHypermediaResolver resolver) where T : class, IResource
        // called using reflection ...
        {
            var typed = resource as T;

            var appender   = resolver.ResolveAppender(typed);
            var configured = resolver.ResolveLinks(typed).ToList();
            var link       = resolver.ResolveSelf(typed);

            if (link != null)
            {
                configured.Insert(0, link);
            }

            if (configured.Any() && (appender != null))
            {
                if (typed.Links == null)
                {
                    typed.Links = new List <Link>();                // make sure resource.Links.Add() can safely be called inside the appender
                }
                appender.Append(typed, configured);

                if ((typed.Links != null) && !typed.Links.Any())
                {
                    typed.Links = null;                 // prevent _links property serialisation
                }
            }
        }
Ejemplo n.º 9
0
        Link ToLink(IHypermediaResolver resolver)
        {
            Link link = null;

            if (resolver != null)
            {
                link = resolver.ResolveSelf(this);

                if (link != null)
                {
                    link     = link.Clone();
                    link.Rel = resolver.ResolveRel(this);
                }
            }

            if ((resolver == null) || (link == null))
            {
                link = Links.SingleOrDefault(x => x.Rel == "self");

                if (link != null)
                {
                    link     = link.Clone();
                    link.Rel = Rel;
                }
            }

            return(link);
        }
Ejemplo n.º 10
0
        public JsonHalInputFormatter(IHypermediaResolver hypermediaConfiguration)
        {
            if (hypermediaConfiguration == null) 
                throw new ArgumentNullException(nameof(hypermediaConfiguration));

            Initialize();
        }
        public HalJsonConverterContext(IHypermediaResolver hypermediaResolver) : this()
        {
            if (hypermediaResolver == null) 
                throw new ArgumentNullException("hypermediaResolver");

            this.hypermediaResolver = hypermediaResolver;
        }
        public JsonHalMediaTypeFormatter(IHypermediaResolver hypermediaConfiguration)
        {
            if (hypermediaConfiguration == null) 
                throw new ArgumentNullException("hypermediaConfiguration");

            resourceConverter = new ResourceConverter(hypermediaConfiguration);
            Initialize();
        }
Ejemplo n.º 13
0
        public ResourceConverter(IHypermediaResolver hypermediaConfiguration)
        {
            if (hypermediaConfiguration == null)
            {
                throw new ArgumentNullException("hypermediaConfiguration");
            }

            this.hypermediaConfiguration = hypermediaConfiguration;
        }
Ejemplo n.º 14
0
        public ResourceConverter(IHypermediaResolver hypermediaConfiguration)
        {
            if (hypermediaConfiguration == null)
            {
                throw new ArgumentNullException(nameof(hypermediaConfiguration));
            }

            HypermediaResolver = hypermediaConfiguration;
        }
Ejemplo n.º 15
0
        public HalJsonConverterContext(IHypermediaResolver hypermediaResolver) : this()
        {
            if (hypermediaResolver == null)
            {
                throw new ArgumentNullException("hypermediaResolver");
            }

            this.hypermediaResolver = hypermediaResolver;
        }
Ejemplo n.º 16
0
        void ResolveAndAppend(IHypermediaResolver resolver, Type type)
        {
            // We need reflection here, because appenders are of type IHypermediaAppender<T> whilst we define this logic in the base class of T

            var methodInfo    = type.GetMethod("Append", BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.NonPublic);
            var genericMethod = methodInfo.MakeGenericMethod(type);

            genericMethod.Invoke(this, new object[] { this, resolver });
        }
Ejemplo n.º 17
0
        public ResourceConverter(IHypermediaResolver hypermediaConfiguration, JsonSerializerSettings jsonSerializerSettings) : this(jsonSerializerSettings)
        {
            if (hypermediaConfiguration == null)
            {
                throw new ArgumentNullException(nameof(hypermediaConfiguration));
            }

            HypermediaResolver = hypermediaConfiguration;
        }
Ejemplo n.º 18
0
        public JsonHalMediaTypeFormatter(IHypermediaResolver hypermediaConfiguration)
        {
            if (hypermediaConfiguration == null)
            {
                throw new ArgumentNullException("hypermediaConfiguration");
            }

            resourceConverter = new ResourceConverter(hypermediaConfiguration);
            Initialize();
        }
Ejemplo n.º 19
0
        public async Task <HypermediaClientObject> ReadAsync(
            Stream contentStream,
            IHypermediaResolver resolver)
        {
            var rootObject = await this.stringParser.ParseAsync(contentStream);

            var result = this.ReadHypermediaObject(rootObject, resolver);

            return(result);
        }
Ejemplo n.º 20
0
        public JsonHalMediaTypeOutputFormatter(IHypermediaResolver hypermediaResolver)
        {
            if (hypermediaResolver == null)
            {
                throw new ArgumentNullException(nameof(hypermediaResolver));
            }

            _resourceConverter = new ResourceConverter(hypermediaResolver);
            Initialize();
        }
Ejemplo n.º 21
0
        public HypermediaClientObject Read(
            string contentString,
            IHypermediaResolver resolver)
        {
            // TODO inject deserializer
            // todo catch exception: invalid format
            var rootObject = this.stringParser.Parse(contentString);
            var result     = this.ReadHypermediaObject(rootObject, resolver);

            return(result);
        }
Ejemplo n.º 22
0
        protected static void Append <T>(IResource resource, IHypermediaResolver resolver) where T : class, IResource // called using reflection ...
        {
            var typed = resource as T;

            var appender   = resolver.ResolveAppender(typed);
            var configured = resolver.ResolveLinks(typed).ToList();

            configured.Insert(0, resolver.ResolveSelf(typed));

            appender.Append(typed, configured);
        }
Ejemplo n.º 23
0
        public async Task <(HypermediaClientObject, string)> ReadAndSerializeAsync(
            Stream contentStream,
            IHypermediaResolver resolver)
        {
            var rootObject = await this.stringParser.ParseAsync(contentStream);

            var result = this.ReadHypermediaObject(rootObject, resolver);
            var export = rootObject.Serialize();

            return(result, export);
        }
Ejemplo n.º 24
0
        private void RepopulateRecursively(IHypermediaResolver resolver, List <CuriesLink> curies)
        {
            var type = GetType();

            if (resolver == null)
            {
                RepopulateHyperMedia();
            }
            else
            {
                ResolveAndAppend(resolver, type);
            }

            // put all embedded resources and lists of resources into Embedded for the _embedded serializer
            Embedded = new List <EmbeddedResource>();

            foreach (var property in type.GetProperties().Where(p => IsEmbeddedResourceType(p.PropertyType)))
            {
                var value = property.GetValue(this, null);

                if (value == null)
                {
                    continue; // nothing to serialize for this property ...
                }
                // remember embedded resource property for restoring after serialization
                embeddedResourceProperties.Add(property, value);

                var resource = value as IResource;

                if (resource != null)
                {
                    ProcessPropertyValue(resolver, curies, resource);
                }
                else
                {
                    ProcessPropertyValue(resolver, curies, (IEnumerable <IResource>)value);
                }

                // null out the embedded property so it doesn't serialize separately as a property
                property.SetValue(this, null, null);
            }

            if (Links != null)
            {
                curies.AddRange(Links.Where(l => l.Curie != null).Select(l => l.Curie));
            }

            if (Embedded.Count == 0)
            {
                Embedded = null; // avoid the property from being serialized ...
            }
        }
Ejemplo n.º 25
0
        public static async Task <HypermediaCommandResult> ExecuteAsync(
            this IHypermediaClientAction action,
            IHypermediaResolver resolver)
        {
            if (action.CanExecute)
            {
                throw new Exception("Can not execute Action.");
            }

            var result = await resolver.ResolveActionAsync(action.Uri, action.Method);

            return(result);
        }
Ejemplo n.º 26
0
        public JsonHalMediaTypeOutputFormatter(
            JsonSerializerSettings serializerSettings,
            ArrayPool <char> charPool,
            IHypermediaResolver hypermediaResolver) :
            base(serializerSettings, charPool)
        {
            if (hypermediaResolver == null)
            {
                throw new ArgumentNullException(nameof(hypermediaResolver));
            }

            _resourceConverter = new ResourceConverter(hypermediaResolver);
            Initialize();
        }
Ejemplo n.º 27
0
        public static async Task <HypermediaFunctionResult <TResultType> > ExecuteAsync <TResultType>(
            this IHypermediaClientFunction <TResultType> function,
            IHypermediaResolver resolver)
            where TResultType : HypermediaClientObject
        {
            if (!function.CanExecute)
            {
                throw new Exception("Can not execute Function.");
            }

            var result = await resolver.ResolveFunctionAsync <TResultType>(function.Uri, function.Method);

            return(result);
        }
Ejemplo n.º 28
0
        private HypermediaClientObject ReadHypermediaObject(
            IToken rootObject,
            IHypermediaResolver resolver)
        {
            var classes = ReadClasses(rootObject);
            var hypermediaObjectInstance = this.hypermediaObjectRegister.CreateFromClasses(classes);

            this.ReadTitle(hypermediaObjectInstance, rootObject);
            this.ReadRelations(hypermediaObjectInstance, rootObject);
            this.FillHypermediaProperties(hypermediaObjectInstance, rootObject, resolver);


            return(hypermediaObjectInstance);
        }
        public void Initialize()
        {
            var httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Authorization =
                new UsernamePasswordCredentials("User", "Password").CreateBasicAuthHeaderValue();
            httpClient.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en", 1.0));
            this.Resolver = HypermediaResolverBuilder
                            .CreateBuilder()
                            .ConfigureObjectRegister(ConfigureHypermediaObjectRegister)
                            .WithSingleSystemTextJsonObjectParameterSerializer()
                            .WithSystemTextJsonStringParser()
                            .WithSystemTextJsonProblemReader()
                            .WithSirenHypermediaReader()
                            .CreateHttpHypermediaResolver(httpClient);
        }
Ejemplo n.º 30
0
        public static async Task <HypermediaCommandResult> ExecuteAsync <TParameters>(
            this IHypermediaClientAction <TParameters> action,
            TParameters parameters,
            IHypermediaResolver resolver)
        {
            if (!action.CanExecute)
            {
                throw new Exception("Can not execute Action.");
            }

            var result = await resolver.ResolveActionAsync(
                action.Uri,
                action.Method,
                action.ParameterDescriptions,
                parameters);

            return(result);
        }
Ejemplo n.º 31
0
        public static IMvcBuilder AddJsonHalFormatters(this IMvcBuilder builder, IHypermediaResolver hypermediaResolver)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (hypermediaResolver != null)
            {
                builder.Services.TryAddEnumerable(ServiceDescriptor.Transient(x => hypermediaResolver));
            }

            ServiceDescriptor descriptor = ServiceDescriptor.Transient <IConfigureOptions <MvcOptions>, JsonHalFormattersMvcOptionsSetup>();

            builder.Services.TryAddEnumerable(descriptor);

            return(builder);
        }
Ejemplo n.º 32
0
        private void FillHypermediaProperties(
            HypermediaClientObject hypermediaObjectInstance,
            IToken rootObject,
            IHypermediaResolver resolver)
        {
            var typeInfo   = hypermediaObjectInstance.GetType().GetTypeInfo();
            var properties = typeInfo.GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var propertyInfo in properties)
            {
                var ignore = propertyInfo.GetCustomAttribute <ClientIgnoreHypermediaPropertyAttribute>() != null;
                if (ignore)
                {
                    continue;
                }

                var hypermediaPropertyType = GetHypermediaPropertyType(propertyInfo);
                switch (hypermediaPropertyType)
                {
                case HypermediaPropertyType.Property:
                    FillProperty(hypermediaObjectInstance, propertyInfo, rootObject);
                    break;

                case HypermediaPropertyType.Link:
                    this.FillLink(hypermediaObjectInstance, propertyInfo, rootObject, resolver);
                    break;

                case HypermediaPropertyType.Entity:
                    this.FillEntity(hypermediaObjectInstance, propertyInfo, rootObject, resolver);
                    break;

                case HypermediaPropertyType.EntityCollection:
                    this.FillEntities(hypermediaObjectInstance, propertyInfo, rootObject, resolver);
                    break;

                case HypermediaPropertyType.Command:
                    this.FillCommand(hypermediaObjectInstance, propertyInfo, rootObject, resolver);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Ejemplo n.º 33
0
        private void FillLink(
            HypermediaClientObject hypermediaObjectInstance,
            PropertyInfo propertyInfo,
            IToken rootObject,
            IHypermediaResolver resolver)
        {
            var linkAttribute = propertyInfo.GetCustomAttribute <HypermediaRelationsAttribute>();

            if (linkAttribute == null)
            {
                throw new Exception($"{nameof(IHypermediaLink)} requires a {nameof(HypermediaRelationsAttribute)} Attribute.");
            }

            var hypermediaLink = (IHypermediaLink)Activator.CreateInstance(propertyInfo.PropertyType);

            propertyInfo.SetValue(hypermediaObjectInstance, hypermediaLink);

            var links = rootObject["links"];

            if (links == null)
            {
                if (IsMandatoryHypermediaLink(propertyInfo))
                {
                    throw new Exception($"Mandatory link not found {propertyInfo.Name}");
                }
                return;
            }

            var link = links.FirstOrDefault(l => this.distinctOrderedStringCollectionComparer.Equals(new DistinctOrderedStringCollection(l["rel"].ChildrenAsStrings()), linkAttribute.Relations));

            if (link == null)
            {
                if (IsMandatoryHypermediaLink(propertyInfo))
                {
                    throw new Exception($"Mandatory link not found {propertyInfo.Name}");
                }
                return;
            }

            hypermediaLink.Uri       = new Uri(link["href"].ValueAsString());
            hypermediaLink.Relations = link["rel"].ChildrenAsStrings().ToList();
            hypermediaLink.Resolver  = resolver;
        }
Ejemplo n.º 34
0
        public ResolvingHalResourceTest()
        {
            //
            // Create representation

            representation = new ProductRepresentation
            {
                Id       = 9,
                Title    = "Morpheus in a chair statuette",
                Price    = 20.14,
                Category = new CategoryRepresentation
                {
                    Id    = 99,
                    Title = "Action Figures"
                }
            };

            //
            // Build hypermedia configuration

            var example            = new CuriesLink("example-namespace", "http://api.example.com/docs/{rel}");
            var productLink        = example.CreateLink("product", "http://api.example.com/products/{id}");
            var relatedProductLink = example.CreateLink("related-product", productLink.Href);
            var saleProductLink    = example.CreateLink("product-on-sale", "http://api.example.com/products/sale/{id}");
            var categoryLink       = example.CreateLink("category", "http://api.example.com/categories/{id}");

            var builder = Hypermedia.CreateBuilder();

            builder.RegisterAppender(new ProductRepresentationHypermediaAppender());
            builder.RegisterAppender(new CategoryRepresentationHypermediaAppender());

            builder.RegisterSelf <ProductRepresentation>(productLink);
            builder.RegisterSelf <CategoryRepresentation>(categoryLink);
            builder.RegisterLinks <ProductRepresentation>(relatedProductLink, saleProductLink);

            config = builder.Build();
        }
        public ResolvingHalResourceTest()
        {
            //
            // Create representation

            representation = new ProductRepresentation
            {
                Id = 9,
                Title = "Morpheus in a chair statuette",
                Price = 20.14,
                Category = new CategoryRepresentation
                {
                    Id = 99,
                    Title = "Action Figures"
                }
            };

            //
            // Build hypermedia configuration

            var example = new CuriesLink("example-namespace", "http://api.example.com/docs/{rel}");
            var productLink = example.CreateLink("product", "http://api.example.com/products/{id}");
            var relatedProductLink = example.CreateLink("related-product", productLink.Href);
            var saleProductLink = example.CreateLink("product-on-sale", "http://api.example.com/products/sale/{id}");
            var categoryLink = example.CreateLink("category", "http://api.example.com/categories/{id}");

            var builder = Hypermedia.CreateBuilder();

            builder.RegisterAppender(new ProductRepresentationHypermediaAppender());
            builder.RegisterAppender(new CategoryRepresentationHypermediaAppender());

            builder.RegisterSelf<ProductRepresentation>(productLink);
            builder.RegisterSelf<CategoryRepresentation>(categoryLink);
            builder.RegisterLinks<ProductRepresentation>(relatedProductLink, saleProductLink);

            config = builder.Build();
        }