-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRestApiTemplate.cs
107 lines (91 loc) · 3.3 KB
/
RestApiTemplate.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Collections.Generic;
using System.Linq;
namespace Arcane.Framework.Sources.RestApi.Services;
/// <summary>
/// REST API template resolver for templated fields.
/// </summary>
public sealed class RestApiTemplate
{
private readonly string baseTemplate;
private readonly List<string> templatedFieldNames;
private List<string> remainingFieldNames;
private string resolvedTemplate;
/// <summary>
/// Constructor for the REST API template resolver.
/// </summary>
/// <param name="baseTemplate">The template string</param>
/// <param name="templatedFieldNames">Templated fields names</param>
public RestApiTemplate(string baseTemplate, List<string> templatedFieldNames)
{
this.baseTemplate = baseTemplate;
this.templatedFieldNames = templatedFieldNames;
}
private bool IsEmpty => string.IsNullOrEmpty(this.baseTemplate);
/// <summary>
/// Create a resolver for the template.
/// </summary>
public RestApiTemplate CreateResolver()
{
if (this.IsEmpty)
{
return this;
}
this.resolvedTemplate = this.baseTemplate;
this.remainingFieldNames = this.templatedFieldNames.Select(v => v).ToList();
return this;
}
/// <summary>
/// Create an empty REST API template.
/// </summary>
public static RestApiTemplate Empty()
{
return new RestApiTemplate(null, new List<string>());
}
/// <summary>
/// Courtesy of https://stackoverflow.com/questions/36759694/is-there-a-string-format-that-can-accept-named-input-parameters-instead-of-ind
/// </summary>
/// <param name="fieldName"></param>
/// <param name="fieldValue"></param>
/// <returns></returns>
public RestApiTemplate ResolveField(string fieldName, string fieldValue)
{
if (this.IsEmpty)
{
return this;
}
if (!this.remainingFieldNames.Contains(fieldName))
{
return this;
}
// some resolvers may return a full uri - in this case we replace the resolved template with that value and clear out the template queue
if (Uri.TryCreate(fieldValue, UriKind.Absolute, out _))
{
this.resolvedTemplate = fieldValue;
this.remainingFieldNames.Clear();
return this;
}
var parameters = new Dictionary<string, object> { { $"@{fieldName}", fieldValue } };
this.resolvedTemplate = parameters.Aggregate(this.resolvedTemplate, (current, parameter)=> current.Replace(parameter.Key, parameter.Value.ToString()));
this.remainingFieldNames.Remove(fieldName);
return this;
}
/// <summary>
/// Return the resolved request element.
/// </summary>
/// <returns>The resolved template as string</returns>
/// <exception cref="ApplicationException">Thrown when there are unresolved fields</exception>
public string GetResolvedRequestElement()
{
if (this.IsEmpty)
{
return string.Empty;
}
if (this.remainingFieldNames.Count > 0)
{
throw new ApplicationException(
$"Cannot return the resolved template as there are unresolved fields: {string.Join(",", this.remainingFieldNames)}");
}
return this.resolvedTemplate;
}
}