Skip to content

Commit

Permalink
simplify rdf deserializer hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Dec 2, 2016
1 parent 362c0e5 commit 37ec97e
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 207 deletions.
2 changes: 1 addition & 1 deletion Nancy.Rdf.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nancy.Rdf", "src\Nancy.Rdf\Nancy.Rdf.csproj", "{D789D63C-821B-410B-A953-DFEBCBFC9D40}"
EndProject
Expand Down
47 changes: 47 additions & 0 deletions src/Nancy.Rdf.Tests/ModelBinding/JsonldBodyDeserializerTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.IO;
using System.Text;
using FakeItEasy;
using FluentAssertions;
using JsonLD.Entities;
using Nancy.ModelBinding;
using Nancy.Rdf.ModelBinding;
using Newtonsoft.Json.Linq;
using NUnit.Framework;

namespace Nancy.Rdf.Tests.ModelBinding
{
public class JsonldBodyDeserializerTests
{
[Test]
public void Should_support_jsonld()
{
// given
var entitySerializer = A.Fake<IEntitySerializer>();
var deserializer = new JsonldBodyDeserializer(entitySerializer);

// then
deserializer.CanDeserialize(RdfSerialization.JsonLd.MediaType, new BindingContext())
.Should().BeTrue();
}

[Test]
public void Deserialize_should_deserialize_JSONLD_proper_type_using_entity_serializer()
{
// given
var entitySerializer = A.Fake<IEntitySerializer>();
var binder = new JsonldBodyDeserializer(entitySerializer);
var bindingContext = new BindingContext { DestinationType = typeof(TestModel) };
var body = new MemoryStream(Encoding.UTF8.GetBytes("{}"));

// when
binder.Deserialize(RdfSerialization.JsonLd.MediaType, body, bindingContext);

// then
A.CallTo(() => entitySerializer.Deserialize<TestModel>(A<JToken>._)).MustHaveHappened();
}

private class TestModel
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using FakeItEasy;
using FluentAssertions;
using JsonLD.Entities;
using Nancy.ModelBinding;
using Nancy.Rdf.ModelBinding;
using Nancy.Rdf.Responses;
using NUnit.Framework;
using VDS.RDF;
using VDS.RDF.Parsing;

namespace Nancy.Rdf.Tests.ModelBinding
{
public class NonJsonLdRdfBodyDeserializerTests
{
private readonly BindingContext bindingContext = new BindingContext { DestinationType = typeof(TestModel) };

[TestCaseSource(nameof(NonJsonLdSerializations))]
public void Should_support_serialization(RdfSerialization serialization)
{
// given
var deserializer = new NonJsonLdRdfBodyDeserializer(A.Fake<IEntitySerializer>());

// when
deserializer.CanDeserialize(serialization.MediaType, new BindingContext());
}

[Test]
public void Deserialize_should_deserialize_directly_from_ntriples()
{
// given
var entitySerializer = A.Fake<IEntitySerializer>();
var binder = new NonJsonLdRdfBodyDeserializer(entitySerializer);
const string bodyString = "some nquads";
var body = new MemoryStream(Encoding.UTF8.GetBytes(bodyString));

// when
binder.Deserialize(RdfSerialization.NTriples.MediaType, body, this.bindingContext);

// then
A.CallTo(() => entitySerializer.Deserialize<TestModel>(bodyString)).MustHaveHappened();
}

[Test, Sequential]
public void Deserialize_should_convert_to_ntriples(
[ValueSource(nameof(NonJsonLdSerializations))] RdfSerialization serialization,
[Values(typeof(Notation3Parser), typeof(TurtleParser), typeof(RdfXmlParser))] Type serializerType)
{
// given
var converter = A.Fake<IRdfConverter>();
var deserializer = new NonJsonLdRdfBodyDeserializer(A.Fake<IEntitySerializer>(), converter);
var body = new MemoryStream();

// when
deserializer.Deserialize(serialization.MediaType, body, this.bindingContext);

// then
A.CallTo(() => converter.ConvertToNtriples(body, A<IRdfReader>.That.Matches(rr => rr.GetType() == serializerType))).MustHaveHappened();
}

public IEnumerable<RdfSerialization> NonJsonLdSerializations()
{
yield return RdfSerialization.Notation3;
yield return RdfSerialization.Turtle;
yield return RdfSerialization.RdfXml;
}

private class TestModel
{
}
}
}
79 changes: 0 additions & 79 deletions src/Nancy.Rdf.Tests/ModelBinding/RdfModelBinderTests.cs

This file was deleted.

3 changes: 2 additions & 1 deletion src/Nancy.Rdf.Tests/Nancy.Rdf.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
<Compile Include="CompressingSerializerTests.cs" />
<Compile Include="ContextModuleTests.cs" />
<Compile Include="JsonLdSerializerTests.cs" />
<Compile Include="ModelBinding\RdfModelBinderTests.cs" />
<Compile Include="ModelBinding\JsonldBodyDeserializerTests.cs" />
<Compile Include="ModelBinding\NonJsonLdRdfBodyDeserializerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Bindings\SerializationContext.cs" />
<Compile Include="RdfResponseProcessorTests.cs" />
Expand Down
17 changes: 17 additions & 0 deletions src/Nancy.Rdf/ModelBinding/IRdfConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.IO;
using VDS.RDF;

namespace Nancy.Rdf.ModelBinding
{
/// <summary>
/// Converts RDF serializations to n-triples
/// </summary>
public interface IRdfConverter
{
/// <summary>
/// Converts to nquads.
/// </summary>
/// <returns>input rdf serialized as n-triples</returns>
string ConvertToNtriples(Stream rdf, IRdfReader reader);
}
}
2 changes: 1 addition & 1 deletion src/Nancy.Rdf/ModelBinding/JsonldBodyDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class JsonldBodyDeserializer : RdfBodyDeserializer
/// Initializes a new instance of the <see cref="JsonldBodyDeserializer"/> class.
/// </summary>
public JsonldBodyDeserializer(IEntitySerializer serializer)
: base(RdfSerialization.JsonLd, serializer)
: base(serializer, RdfSerialization.JsonLd)
{
}

Expand Down
65 changes: 39 additions & 26 deletions src/Nancy.Rdf/ModelBinding/NonJsonLdRdfBodyDeserializer.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,78 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using JsonLD.Entities;
using Nancy.ModelBinding;
using Nancy.Responses.Negotiation;
using VDS.RDF;
using VDS.RDF.Parsing;
using VDS.RDF.Writing;
using StringWriter = System.IO.StringWriter;

namespace Nancy.Rdf.ModelBinding
{
/// <summary>
/// Converts body, first converting it to NQuads
/// Deserializers request body, first converting it to n-triples
/// </summary>
public abstract class NonJsonLdRdfBodyDeserializer : RdfBodyDeserializer
public class NonJsonLdRdfBodyDeserializer : RdfBodyDeserializer
{
private static readonly MethodInfo DeserializeNquadsMethod = typeof(IEntitySerializer).GetMethod("Deserialize", new[] { typeof(string) });

private static readonly IRdfWriter RdfWriter = new NTriplesWriter(NTriplesSyntax.Rdf11);
private readonly IRdfReader reader;
private readonly IDictionary<RdfSerialization, IRdfReader> readers;
private readonly IRdfConverter converter;

/// <summary>
/// Initializes a new instance of the <see cref="NonJsonLdRdfBodyDeserializer"/> class.
/// </summary>
protected NonJsonLdRdfBodyDeserializer(
RdfSerialization serialization,
IEntitySerializer serializer,
IRdfReader reader)
: base(serialization, serializer)
public NonJsonLdRdfBodyDeserializer(IEntitySerializer serializer)
: this(serializer, new RdfConverter())
{
this.reader = reader;
}

/// <summary>
/// Deserialize the request body to a model
/// Initializes a new instance of the <see cref="NonJsonLdRdfBodyDeserializer"/> class.
/// </summary>
public override object Deserialize(MediaRange contentType, Stream body, BindingContext context)
public NonJsonLdRdfBodyDeserializer(
IEntitySerializer serializer,
IRdfConverter converter)
: this(serializer, RdfSerialization.RdfXml, RdfSerialization.NTriples, RdfSerialization.Notation3, RdfSerialization.Turtle)
{
var deserialize = DeserializeNquadsMethod.MakeGenericMethod(context.DestinationType);
this.converter = converter;
}

return deserialize.Invoke(this.Serializer, new object[] { this.GetNquads(body) });
private NonJsonLdRdfBodyDeserializer(IEntitySerializer serializer, params RdfSerialization[] serializations)
: base(serializer, serializations)
{
this.readers = new Dictionary<RdfSerialization, IRdfReader>
{
{ RdfSerialization.Notation3, new Notation3Parser() },
{ RdfSerialization.RdfXml, new RdfXmlParser() },
{ RdfSerialization.Turtle, new TurtleParser() }
};
}

/// <summary>
/// Converts body to N-Triples
/// Deserialize the request body to a model
/// </summary>
protected virtual string GetNquads(Stream body)
public override object Deserialize(MediaRange contentType, Stream body, BindingContext context)
{
// todo: implement actual parsers for json-ld.net so that it's not necessary to parse and write to ntriples
IGraph g = new Graph();
var deserialize = DeserializeNquadsMethod.MakeGenericMethod(context.DestinationType);
string nquads;

using (var streamReader = new StreamReader(body))
if (contentType.Matches(RdfSerialization.NTriples.MediaType))
{
this.reader.Load(g, streamReader);
using (var bodyReader = new StreamReader(body))
{
nquads = bodyReader.ReadToEnd();
}
}

using (var stringWriter = new StringWriter())
else
{
RdfWriter.Save(g, stringWriter);
return stringWriter.ToString();
var reader = this.readers.First(r => contentType.Matches(r.Key.MediaType)).Value;
nquads = this.converter.ConvertToNtriples(body, reader);
}

return deserialize.Invoke(this.Serializer, new object[] { nquads });
}
}
}
19 changes: 0 additions & 19 deletions src/Nancy.Rdf/ModelBinding/Notation3BodyDeserializer.cs

This file was deleted.

0 comments on commit 37ec97e

Please sign in to comment.