Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
RdfCodec.cs
1using System;
3using System.Text;
4using System.Threading.Tasks;
5using System.Xml;
13
15{
20 {
24 public RdfCodec()
25 {
26 }
27
31 public string[] ContentTypes => RdfContentTypes;
32
33 private static readonly string[] RdfContentTypes = new string[]
34 {
36 };
37
41 public string[] FileExtensions => RdfFileExtensions;
42
43 private static readonly string[] RdfFileExtensions = new string[]
44 {
46 };
47
51 public const string DefaultContentType = "application/rdf+xml";
52
56 public const string DefaultExtension = "rdf";
57
64 public bool Decodes(string ContentType, out Grade Grade)
65 {
66 if (Array.IndexOf(RdfContentTypes, ContentType) >= 0)
67 {
68 Grade = Grade.Ok;
69 return true;
70 }
71 else
72 {
73 Grade = Grade.NotAtAll;
74 return false;
75 }
76 }
77
88 public Task<ContentResponse> DecodeAsync(string ContentType, byte[] Data, Encoding Encoding,
89 KeyValuePair<string, string>[] Fields, Uri BaseUri, ICodecProgress Progress)
90 {
91 string s = Strings.GetString(Data, Encoding ?? Encoding.UTF8);
92 RdfDocument Parsed = new RdfDocument(s, BaseUri, "n", BlankNodeIdMode.Guid);
93 return Task.FromResult(new ContentResponse(ContentType, Parsed, Data));
94 }
95
103 public bool Encodes(object Object, out Grade Grade, params string[] AcceptedContentTypes)
104 {
105 if (Object is RdfDocument &&
106 InternetContent.IsAccepted(RdfContentTypes, AcceptedContentTypes))
107 {
108 Grade = Grade.Excellent;
109 return true;
110 }
111 else if (Object is ISemanticModel)
112 {
113 if (InternetContent.IsAccepted(RdfContentTypes, AcceptedContentTypes))
114 {
115 Grade = Grade.Ok;
116 return true;
117 }
118 else if (InternetContent.IsAccepted(XmlCodec.XmlContentTypes, AcceptedContentTypes))
119 {
120 Grade = Grade.Barely;
121 return true;
122 }
123 }
124
125 Grade = Grade.NotAtAll;
126 return false;
127 }
128
137 public Task<ContentResponse> EncodeAsync(object Object, Encoding Encoding, ICodecProgress Progress, params string[] AcceptedContentTypes)
138 {
139 if (Encoding is null)
140 Encoding = Encoding.UTF8;
141
142 string Text;
143
144 if (Object is RdfDocument Doc)
145 Text = Doc.Text;
146 else if (Object is ISemanticModel Model)
147 {
148 StringBuilder sb = new StringBuilder();
149 sb.Append("<?xml version=\"1.0\" encoding=\"");
150 sb.Append(Encoding.WebName);
151 sb.AppendLine("\"?>");
152
153 XmlWriterSettings Settings = new XmlWriterSettings()
154 {
155 ConformanceLevel = ConformanceLevel.Document,
156 Encoding = Encoding,
157 Indent = false,
158 NamespaceHandling = NamespaceHandling.OmitDuplicates,
159 NewLineHandling = NewLineHandling.None,
160 NewLineOnAttributes = false,
161 OmitXmlDeclaration = true,
162 WriteEndDocumentOnClose = true
163 };
164
165 using (XmlWriter w = XmlWriter.Create(sb, Settings))
166 {
167 Dictionary<string, string> Prefixes = new Dictionary<string, string>();
168 Dictionary<string, ChunkedList<ISemanticTriple>> PerSubject = new Dictionary<string, ChunkedList<ISemanticTriple>>();
169 string s;
170
171 foreach (ISemanticTriple Triple in Model)
172 {
173 CheckPrefix(Triple.Subject, Prefixes);
174 CheckPrefix(Triple.Predicate, Prefixes);
175 CheckPrefix(Triple.Object, Prefixes);
176
177 if (Triple.Subject is UriNode UriNode)
178 s = UriNode.Uri.ToString();
179 else
180 s = Triple.Subject.ToString();
181
182 if (!PerSubject.TryGetValue(s, out ChunkedList<ISemanticTriple> List))
183 {
184 List = new ChunkedList<ISemanticTriple>();
185 PerSubject[s] = List;
186 }
187
188 List.Add(Triple);
189 }
190
191 w.WriteStartElement("rdf", "RDF", Rdf.Namespace);
192
193 foreach (KeyValuePair<string, string> P in Prefixes)
194 w.WriteAttributeString("xmlns", P.Value, string.Empty, P.Key);
195
196 foreach (KeyValuePair<string, ChunkedList<ISemanticTriple>> Subject in PerSubject)
197 {
198 w.WriteStartElement("rdf", "Description", Rdf.Namespace);
199
200 if (Subject.Key.StartsWith("_:"))
201 w.WriteAttributeString("rdf", "nodeID", Rdf.Namespace, Subject.Key.Substring(2));
202 else
203 w.WriteAttributeString("rdf", "about", Rdf.Namespace, Subject.Key);
204
205 foreach (ISemanticTriple Triple in Subject.Value)
206 {
207 if (Triple.Predicate is UriNode Predicate)
208 {
209 string Uri = Predicate.UriString;
210 string Namespace = GetNamespace(Uri);
211
212 if (!(Namespace is null) &&
213 Prefixes.TryGetValue(Namespace, out string Prefix))
214 {
215 string LocalName = Uri.Substring(Namespace.Length);
216 w.WriteStartElement(Prefix, LocalName, Namespace);
217 }
218 else
219 w.WriteStartElement(Uri);
220
221 if (Triple.Object is SemanticLiteral Literal)
222 {
223 if (string.IsNullOrEmpty(Literal.StringType))
224 {
225 if (Literal is StringLiteral StringLiteral &&
226 !string.IsNullOrEmpty(StringLiteral.Language))
227 {
228 w.WriteAttributeString("xml", "lang", null, StringLiteral.Language);
229 w.WriteValue(Literal.StringValue);
230 }
231 else
232 w.WriteValue(Literal.StringValue);
233 }
234 else
235 {
236 w.WriteAttributeString("rdf", "datatype", Rdf.Namespace, Literal.StringType);
237 w.WriteValue(Literal.StringValue);
238 }
239 }
240 else if (Triple.Object is BlankNode BlankNode)
241 w.WriteAttributeString("rdf", "nodeID", Rdf.Namespace, BlankNode.NodeId);
242 else if (Triple.Object is UriNode UriNode)
243 w.WriteAttributeString("rdf", "resource", Rdf.Namespace, UriNode.UriString);
244 else
245 w.WriteValue(Triple.Object.ToString());
246
247 w.WriteEndElement();
248 }
249 else
250 return Task.FromResult(new ContentResponse(new Exception("Unable to encode semantic model as RDF document. RDF documents require predicates to be URIs.")));
251 }
252
253 w.WriteEndElement();
254 }
255
256 w.WriteEndElement();
257 w.Flush();
258
259 Text = sb.ToString();
260 }
261 }
262 else
263 return Task.FromResult(new ContentResponse(new ArgumentException("Unable to encode object.", nameof(Object))));
264
265 byte[] Bin = Encoding.GetBytes(Text);
266 string ContentType = RdfContentTypes[0] + "; charset=" + Encoding.WebName;
267
268 return Task.FromResult(new ContentResponse(ContentType, Object, Bin));
269 }
270
271 private static void CheckPrefix(ISemanticElement Element, Dictionary<string, string> Prefixes)
272 {
273 if (Element is UriNode UriNode)
274 {
275 string Namespace = GetNamespace(UriNode.UriString);
276 if (!string.IsNullOrEmpty(Namespace) && !Prefixes.ContainsKey(Namespace))
277 {
278 string Prefix = "p" + (Prefixes.Count + 1).ToString();
279 Prefixes[Namespace] = Prefix;
280 }
281 }
282 }
283
284 private static string GetNamespace(string Uri)
285 {
286 int i = Uri.LastIndexOf('#');
287 if (i >= 0)
288 return Uri.Substring(0, i + 1);
289
290 i = Uri.LastIndexOf('/');
291 if (i >= 0)
292 return Uri.Substring(0, i + 1);
293
294 i = Uri.LastIndexOf(':');
295 if (i >= 0)
296 return Uri.Substring(0, i + 1);
297
298 return null;
299 }
300
307 public bool TryGetContentType(string FileExtension, out string ContentType)
308 {
309 if (string.Compare(FileExtension, RdfFileExtensions[0], true) == 0)
310 {
311 ContentType = RdfContentTypes[0];
312 return true;
313 }
314 else
315 {
316 ContentType = null;
317 return false;
318 }
319 }
320
327 public bool TryGetFileExtension(string ContentType, out string FileExtension)
328 {
329 if (Array.IndexOf(RdfContentTypes, ContentType) >= 0)
330 {
331 FileExtension = RdfFileExtensions[0];
332 return true;
333 }
334 else
335 {
336 FileExtension = null;
337 return false;
338 }
339 }
340 }
341}
Contains information about a response to a content request.
Static class managing encoding and decoding of internet content.
static bool IsAccepted(string ContentType, params string[] AcceptedContentTypes)
Checks if a given content type is acceptable.
Represents a blank node
Definition: BlankNode.cs:7
string NodeId
Blank node Node ID.
Definition: BlankNode.cs:33
Abstract base class for semantic literal values.
const string Namespace
http://www.w3.org/1999/02/22-rdf-syntax-ns#
Definition: Rdf.cs:46
Encoder and Decoder of semantic information in RDF Documents.
Definition: RdfCodec.cs:20
bool Encodes(object Object, out Grade Grade, params string[] AcceptedContentTypes)
If the encoder encodes a specific object.
Definition: RdfCodec.cs:103
const string DefaultExtension
rdf
Definition: RdfCodec.cs:56
bool Decodes(string ContentType, out Grade Grade)
If the decoder decodes content of a given Internet Content Type.
Definition: RdfCodec.cs:64
bool TryGetFileExtension(string ContentType, out string FileExtension)
Tries to get the file extension of content of a given content type.
Definition: RdfCodec.cs:327
RdfCodec()
Encoder and Decoder of semantic information in RDF Documents.
Definition: RdfCodec.cs:24
Task< ContentResponse > EncodeAsync(object Object, Encoding Encoding, ICodecProgress Progress, params string[] AcceptedContentTypes)
Encodes an object
Definition: RdfCodec.cs:137
const string DefaultContentType
application/rdf+xml
Definition: RdfCodec.cs:51
string[] ContentTypes
Supported Internet Content Types.
Definition: RdfCodec.cs:31
Task< ContentResponse > DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri, ICodecProgress Progress)
Decodes an object
Definition: RdfCodec.cs:88
string[] FileExtensions
Supported file extensions.
Definition: RdfCodec.cs:41
bool TryGetContentType(string FileExtension, out string ContentType)
Tries to get the content type of content of a given file extension.
Definition: RdfCodec.cs:307
Contains semantic information stored in an RDF document.
Definition: RdfDocument.cs:23
XML encoder/decoder.
Definition: XmlCodec.cs:19
static readonly string[] XmlContentTypes
XML content types.
Definition: XmlCodec.cs:40
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
Static class managing binary representations of strings.
Definition: Strings.cs:10
static string GetString(byte[] Data, int Offset, int Count, Encoding DefaultEncoding)
Gets a string from its binary representation, taking any Byte Order Mark (BOM) into account.
Definition: Strings.cs:148
Interface for reporting progress about an encoding or decoding.
Basic interface for Internet Content decoders. A class implementing this interface and having a defau...
Basic interface for Internet Content encoders. A class implementing this interface and having a defau...
Interface for semantic nodes.
Interface for semantic models.
Interface for semantic triples.
ISemanticElement Object
Object element
ISemanticElement Predicate
Predicate element
ISemanticElement Subject
Subject element
BlankNodeIdMode
How blank node IDs are generated
delegate string ToString(IElement Element)
Delegate for callback methods that convert an element value to a string.
Grade
Grade enumeration
Definition: Grade.cs:7