/
EncounterResource.cs
143 lines (124 loc) · 6.73 KB
/
EncounterResource.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Collections.Generic;
using System.IO;
using System.Json;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.ServiceModel;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.Xml;
using HydrasAndHypermedia.MediaTypes;
using HydrasAndHypermedia.Server.Domain;
using HydrasAndHypermedia.Server.Xhtml;
using Microsoft.ApplicationServer.Http;
using Microsoft.ApplicationServer.Http.Dispatcher;
namespace HydrasAndHypermedia.Server.Resources
{
[ServiceContract]
public class EncounterResource
{
private static readonly Uri BaseUri = new Uri(string.Format("http://{0}:8081/", Environment.MachineName));
private readonly Repository<Encounter> encounters;
public EncounterResource(Repository<Encounter> encounters)
{
this.encounters = encounters;
}
[WebGet(UriTemplate = "{id}")]
public HttpResponseMessage<SyndicationFeed> Get(string id, HttpRequestMessage request)
{
Encounter encounter;
try
{
encounter = encounters.Get(int.Parse(id));
}
catch (KeyNotFoundException)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var feed = new SyndicationFeed
{
BaseUri = BaseUri,
Title = SyndicationContent.CreatePlaintextContent(encounter.Title),
Description = SyndicationContent.CreatePlaintextContent(encounter.Description)
};
feed.Categories.Add(new SyndicationCategory("encounter"));
feed.Authors.Add(new SyndicationPerson {Name = "Dungeon Master", Email = "dungeon.master@restinpractice.com"});
if (encounter.IsResolved)
{
feed.Links.Add(new SyndicationLink {RelationshipType = "continue", Uri = new Uri("/rooms/" + encounter.GuardedRoomId, UriKind.Relative)});
}
else
{
feed.Links.Add(new SyndicationLink {RelationshipType = "flee", Uri = new Uri("/rooms/" + encounter.FleeRoomId, UriKind.Relative)});
var xhtml = new FormWriter(new Uri("/encounters/" + encounter.Id, UriKind.RelativeOrAbsolute), HttpMethod.Post, new TextInput("endurance")).ToXhtml();
feed.ElementExtensions.Add(XmlReader.Create(new StringReader(xhtml)));
}
feed.Items = encounter.GetAllRounds()
.Reverse()
.Select(round =>
{
var entry = new SyndicationItem
{
Title = SyndicationContent.CreatePlaintextContent("Round " + round.Id),
Summary = SyndicationContent.CreatePlaintextContent(string.Format("The {0} has {1} Endurance Points", encounter.Title, round.Endurance))
};
entry.Links.Add(SyndicationLink.CreateSelfLink(new Uri(string.Format("http://{0}:8081/encounters/{1}/rounds/{2}", Environment.MachineName, encounter.Id, round.Id))));
entry.Categories.Add(new SyndicationCategory("round"));
return entry;
});
var response = new HttpResponseMessage<SyndicationFeed>(feed) {StatusCode = HttpStatusCode.OK};
response.Headers.CacheControl = new CacheControlHeaderValue {NoCache = true, NoStore = true};
response.Content.Headers.ContentType = AtomMediaType.Feed;
return response;
}
[WebInvoke(Method = "POST", UriTemplate = "{id}")]
public HttpResponseMessage<SyndicationItem> Post(string id, HttpRequestMessage request)
{
Encounter encounter;
try
{
encounter = encounters.Get(int.Parse(id));
}
catch (KeyNotFoundException)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
if (encounter.IsResolved)
{
var methodNotAllowedResponse = new HttpResponseMessage {StatusCode = HttpStatusCode.MethodNotAllowed, Content = new ByteArrayContent(new byte[] {})};
methodNotAllowedResponse.Content.Headers.Allow.Add("GET");
throw new HttpResponseException(methodNotAllowedResponse);
}
var form = request.Content.ReadAs<JsonValue>(new[] {new FormUrlEncodedMediaTypeFormatter()});
var clientEndurance = form["endurance"].ReadAs<int>();
var result = encounter.Action(clientEndurance);
var round = result.Round;
var xhtml = new FormWriter(new Uri("/encounters/" + encounter.Id, UriKind.RelativeOrAbsolute), HttpMethod.Post, new TextInput("endurance", result.ClientEndurance.ToString())).ToXhtml();
var entry = new SyndicationItem
{
BaseUri = BaseUri,
Title = SyndicationContent.CreatePlaintextContent("Round " + round.Id),
Summary = SyndicationContent.CreatePlaintextContent(string.Format("The {0} has {1} Endurance Point{2}", encounter.Title, round.Endurance, Math.Abs(round.Endurance).Equals(1) ? "" : "s")),
Content = SyndicationContent.CreateXhtmlContent(xhtml),
};
entry.Links.Add(SyndicationLink.CreateSelfLink(new Uri(string.Format("http://{0}:8081/encounters/{1}/rounds/{2}", Environment.MachineName, encounter.Id, round.Id))));
entry.Categories.Add(new SyndicationCategory("round"));
if (encounter.IsResolved)
{
entry.Links.Add(new SyndicationLink {RelationshipType = "continue", Uri = new Uri("/rooms/" + encounter.GuardedRoomId, UriKind.Relative)});
}
else
{
entry.Content = SyndicationContent.CreateXhtmlContent(xhtml);
entry.Links.Add(new SyndicationLink {RelationshipType = "flee", Uri = new Uri("/rooms/" + encounter.FleeRoomId, UriKind.Relative)});
}
var response = new HttpResponseMessage<SyndicationItem>(entry) {StatusCode = HttpStatusCode.Created};
response.Headers.Location = new Uri(string.Format("http://{0}:8081/encounters/{1}/rounds/{2}", Environment.MachineName, encounter.Id, result.Round.Id));
response.Content.Headers.ContentType = AtomMediaType.Entry;
return response;
}
}
}