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); }
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); }
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 } } }
public ResourceConverter(IHypermediaResolver hypermediaConfiguration) { if (hypermediaConfiguration == null) throw new ArgumentNullException("hypermediaConfiguration"); this.hypermediaConfiguration = hypermediaConfiguration; }
//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 }); } }
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 ... } }
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); }
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 } } }
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); }
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(); }
public ResourceConverter(IHypermediaResolver hypermediaConfiguration) { if (hypermediaConfiguration == null) { throw new ArgumentNullException("hypermediaConfiguration"); } this.hypermediaConfiguration = hypermediaConfiguration; }
public ResourceConverter(IHypermediaResolver hypermediaConfiguration) { if (hypermediaConfiguration == null) { throw new ArgumentNullException(nameof(hypermediaConfiguration)); } HypermediaResolver = hypermediaConfiguration; }
public HalJsonConverterContext(IHypermediaResolver hypermediaResolver) : this() { if (hypermediaResolver == null) { throw new ArgumentNullException("hypermediaResolver"); } this.hypermediaResolver = hypermediaResolver; }
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 }); }
public ResourceConverter(IHypermediaResolver hypermediaConfiguration, JsonSerializerSettings jsonSerializerSettings) : this(jsonSerializerSettings) { if (hypermediaConfiguration == null) { throw new ArgumentNullException(nameof(hypermediaConfiguration)); } HypermediaResolver = hypermediaConfiguration; }
public JsonHalMediaTypeFormatter(IHypermediaResolver hypermediaConfiguration) { if (hypermediaConfiguration == null) { throw new ArgumentNullException("hypermediaConfiguration"); } resourceConverter = new ResourceConverter(hypermediaConfiguration); Initialize(); }
public async Task <HypermediaClientObject> ReadAsync( Stream contentStream, IHypermediaResolver resolver) { var rootObject = await this.stringParser.ParseAsync(contentStream); var result = this.ReadHypermediaObject(rootObject, resolver); return(result); }
public JsonHalMediaTypeOutputFormatter(IHypermediaResolver hypermediaResolver) { if (hypermediaResolver == null) { throw new ArgumentNullException(nameof(hypermediaResolver)); } _resourceConverter = new ResourceConverter(hypermediaResolver); Initialize(); }
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); }
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); }
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); }
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 ... } }
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); }
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(); }
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); }
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); }
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); }
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); }
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(); } } }
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; }
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(); }