public void TestRdfXmlCollectionSerialization() { List <ChangeRequest> crListOut = new List <ChangeRequest>(); ChangeRequest changeRequest1 = new ChangeRequest(new Uri("http://com/somewhere/changeRequest1")); changeRequest1.SetFixed(true); changeRequest1.AddAffectedByDefect(new Link(new Uri("http://com/somewhere/changeRequest2"), "Test of links")); crListOut.Add(changeRequest1); ChangeRequest changeRequest2 = new ChangeRequest(new Uri("http://com/somewhere/changeRequest2")); changeRequest2.SetFixed(false); changeRequest2.AddAffectedByDefect(new Link(new Uri("http://com/somewhere/changeRequest1"), "Test of links")); crListOut.Add(changeRequest2); IGraph rdfGraph = DotNetRdfHelper.CreateDotNetRdfGraph("http://com/somewhere/changerequests", "http://com/somewhere/changerequests?page=20", "http://com/somewhere/changerequests?page=21", null, crListOut, null); RdfXmlMediaTypeFormatter formatter = new RdfXmlMediaTypeFormatter(rdfGraph); string rdfXml = SerializeCollection <ChangeRequest>(formatter, crListOut, OslcMediaType.APPLICATION_RDF_XML_TYPE); Debug.WriteLine(rdfXml); List <ChangeRequest> crListIn = DeserializeCollection <ChangeRequest>(formatter, rdfXml, OslcMediaType.APPLICATION_RDF_XML_TYPE).ToList(); Assert.AreEqual(crListOut.Count, crListIn.Count); //No guarantees of order in a collection, use the "about" attribute to identify individual ChangeRequests foreach (ChangeRequest cr in crListIn) { string crAboutUri = cr.GetAbout().AbsoluteUri; if (crAboutUri.Equals("http://com/somewhere/changeRequest1")) { Assert.AreEqual(cr.IsFixed(), changeRequest1.IsFixed()); Assert.AreEqual(cr.GetAffectedByDefects()[0].GetValue(), changeRequest1.GetAffectedByDefects()[0].GetValue()); Assert.AreEqual(cr.GetAffectedByDefects()[0].GetLabel(), changeRequest1.GetAffectedByDefects()[0].GetLabel()); } else if (crAboutUri.Equals("http://com/somewhere/changeRequest2")) { Assert.AreEqual(cr.IsFixed(), changeRequest2.IsFixed()); Assert.AreEqual(cr.GetAffectedByDefects()[0].GetValue(), changeRequest2.GetAffectedByDefects()[0].GetValue()); Assert.AreEqual(cr.GetAffectedByDefects()[0].GetLabel(), changeRequest2.GetAffectedByDefects()[0].GetLabel()); } else { Assert.Fail("Deserialized ChangeRequest about attribute not recognized: " + crAboutUri); } } }
/// <summary> /// Read RDF/XML from an HTTP input stream and convert to .NET objects /// </summary> /// <param name="type"></param> /// <param name="readStream"></param> /// <param name="content"></param> /// <param name="formatterLogger"></param> /// <returns></returns> public override Task <object> ReadFromStreamAsync( Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger ) { var tcs = new TaskCompletionSource <object>(); if (content != null && content.Headers != null && content.Headers.ContentLength == 0) { return(null); } try { IRdfReader rdfParser; if (content == null || content.Headers == null || content.Headers.ContentType.MediaType.Equals(OslcMediaType.APPLICATION_RDF_XML)) { rdfParser = new RdfXmlParser(); } else if (content.Headers.ContentType.MediaType.Equals(OslcMediaType.TEXT_TURTLE)) { rdfParser = new TurtleParser(TurtleSyntax.W3C); } else { //For now, use the dotNetRDF RdfXmlParser() for application/xml. This could change //rdfParser = new OslcXmlParser(); rdfParser = new RdfXmlParser(); } IGraph graph = new Graph(); StreamReader streamReader = new StreamReader(readStream); using (streamReader) { rdfParser.Load(graph, streamReader); bool isSingleton = IsSinglton(type); object output = DotNetRdfHelper.FromDotNetRdfGraph(graph, isSingleton ? type : GetMemberType(type)); if (isSingleton) { bool haveOne = (int)output.GetType().GetProperty("Count").GetValue(output, null) > 0; tcs.SetResult(haveOne ? output.GetType().GetProperty("Item").GetValue(output, new object[] { 0 }): null); } else if (type.IsArray) { tcs.SetResult(output.GetType().GetMethod("ToArray", Type.EmptyTypes).Invoke(output, null)); } else { tcs.SetResult(output); } } } catch (Exception e) { if (formatterLogger == null) { throw; } formatterLogger.LogError(String.Empty, e.Message); tcs.SetResult(GetDefaultValueForType(type)); } return(tcs.Task); }
/// <summary> /// Write a .NET object to an output stream /// </summary> /// <param name="type"></param> /// <param name="value"></param> /// <param name="writeStream"></param> /// <param name="content"></param> /// <param name="transportContext"></param> /// <returns></returns> public override Task WriteToStreamAsync( Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext ) { return(Task.Factory.StartNew(() => { if ((Graph == null) || (Graph.IsEmpty) || RebuildGraph) { if (ImplementsGenericType(typeof(FilteredResource <>), type)) { PropertyInfo resourceProp = value.GetType().GetProperty("Resource"); Type[] actualTypeArguments = GetChildClassParameterArguments(typeof(FilteredResource <>), type); object objects = resourceProp.GetValue(value, null); PropertyInfo propertiesProp = value.GetType().GetProperty("Properties"); if (!ImplementsICollection(actualTypeArguments[0])) { objects = new EnumerableWrapper(objects); } if (ImplementsGenericType(typeof(ResponseInfo <>), type)) { //Subject URI for the collection is the query capability //TODO: should this be set by the app based on service provider info int portNum = httpRequest.RequestUri.Port; string portString = null; if (portNum == 80 || portNum == 443) { portString = ""; } else { portString = ":" + portNum.ToString(); } string descriptionAbout = httpRequest.RequestUri.Scheme + "://" + httpRequest.RequestUri.Host + portString + httpRequest.RequestUri.LocalPath; //Subject URI for the responseInfo is the full request URI string responseInfoAbout = httpRequest.RequestUri.ToString(); PropertyInfo totalCountProp = value.GetType().GetProperty("TotalCount"); PropertyInfo nextPageProp = value.GetType().GetProperty("NextPage"); Graph = DotNetRdfHelper.CreateDotNetRdfGraph(descriptionAbout, responseInfoAbout, (string)nextPageProp.GetValue(value, null), (int)totalCountProp.GetValue(value, null), objects as IEnumerable <object>, (IDictionary <string, object>)propertiesProp.GetValue(value, null)); } else { Graph = DotNetRdfHelper.CreateDotNetRdfGraph(null, null, null, null, objects as IEnumerable <object>, (IDictionary <string, object>)propertiesProp.GetValue(value, null)); } } else if (InheritedGenericInterfacesHelper.ImplementsGenericInterface(typeof(IEnumerable <>), value.GetType())) { Graph = DotNetRdfHelper.CreateDotNetRdfGraph(value as IEnumerable <object>); } else if (type.GetCustomAttributes(typeof(OslcResourceShape), false).Length > 0) { Graph = DotNetRdfHelper.CreateDotNetRdfGraph(new object[] { value }); } else { Graph = DotNetRdfHelper.CreateDotNetRdfGraph(new EnumerableWrapper(value)); } } IRdfWriter rdfWriter; if (content == null || content.Headers == null || content.Headers.ContentType.MediaType.Equals(OslcMediaType.APPLICATION_RDF_XML)) { RdfXmlWriter rdfXmlWriter = new RdfXmlWriter(); rdfXmlWriter.UseDtd = false; rdfXmlWriter.PrettyPrintMode = false; rdfXmlWriter.CompressionLevel = 20; //turtlelWriter.UseTypedNodes = false; rdfWriter = rdfXmlWriter; } else if (content.Headers.ContentType.MediaType.Equals(OslcMediaType.TEXT_TURTLE)) { TurtleWriter turtlelWriter = new TurtleWriter(TurtleSyntax.W3C); turtlelWriter.PrettyPrintMode = false; rdfWriter = turtlelWriter; } else { //For now, use the dotNetRDF RdfXmlWriter for application/xml //OslcXmlWriter oslcXmlWriter = new OslcXmlWriter(); RdfXmlWriter oslcXmlWriter = new RdfXmlWriter(); oslcXmlWriter.UseDtd = false; oslcXmlWriter.PrettyPrintMode = false; oslcXmlWriter.CompressionLevel = 20; rdfWriter = oslcXmlWriter; } StreamWriter streamWriter = new NonClosingStreamWriter(writeStream); rdfWriter.Save(Graph, streamWriter); })); }
public IEnumerable <T> DeserializeCollection <T>( string strRDF, IEnumerable <T> value, string contentType, string descriptionAbout = null, string responseInfoAbout = null, string nextPageAbout = null) where T : class { if (String.IsNullOrEmpty(descriptionAbout)) { descriptionAbout = "http://com/undefined/descriptionAbout"; } if (String.IsNullOrEmpty(responseInfoAbout)) { responseInfoAbout = "http://com/undefined/responseInfoAbout"; } if (String.IsNullOrEmpty(responseInfoAbout)) { responseInfoAbout = "http://com/undefined/nextPageAbout"; } Stream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); HttpContent content = new StreamContent(stream); System.Net.Http.Formatting.MediaTypeFormatter formatter = null; if (contentType == OslcMediaType.APPLICATION_JSON) { JsonValue json = OSLC4Net.Core.JsonProvider.JsonHelper.CreateJson( descriptionAbout, responseInfoAbout, nextPageAbout, null, value, null); formatter = new OSLC4Net.Core.JsonProvider.JsonMediaTypeFormatter(json, false); content.Headers.ContentType = OslcMediaType.APPLICATION_JSON_TYPE; } else if (contentType == OslcMediaType.APPLICATION_RDF_XML) { IGraph rdfGraph = DotNetRdfHelper.CreateDotNetRdfGraph( descriptionAbout, responseInfoAbout, nextPageAbout, null, value, null); formatter = new RdfXmlMediaTypeFormatter(rdfGraph); content.Headers.ContentType = OslcMediaType.APPLICATION_RDF_XML_TYPE; } if (formatter == null) { return(null); } writer.Write(strRDF); writer.Flush(); stream.Position = 0; return(formatter.ReadFromStreamAsync(typeof(List <T>), stream, content, null).Result as IEnumerable <T>); }