/// <summary> /// Thread Worker method which writes Graphs to the output. /// </summary> /// <param name="globalContext">Context for writing the Store.</param> private void SaveGraphs(ThreadedStoreWriterContext globalContext) { try { Uri u = null; while (globalContext.TryGetNextUri(out u)) { // Get the Graph from the Store IGraph g = globalContext.Store.Graphs[u]; // Generate the Graph Output and add to Stream BaseWriterContext context = new BaseWriterContext(g, new System.IO.StringWriter()); String graphContent = GenerateGraphOutput(globalContext, context); try { Monitor.Enter(globalContext.Output); globalContext.Output.WriteLine(graphContent); globalContext.Output.Flush(); } finally { Monitor.Exit(globalContext.Output); } } } catch (ThreadAbortException) { // We've been terminated, don't do anything } catch (Exception ex) { throw new RdfStorageException("Error in Threaded Writer in Thread ID " + Thread.CurrentThread.ManagedThreadId, ex); } }
private static void Prettify(string value, BaseWriterContext context) { if (context.PrettyPrint) { context.Output.Write(value); } }
/// <summary> /// Internal Helper Method for converting a Triple into DOT notation /// </summary> /// <param name="t">Triple to convert</param> /// <param name="context">Writer Context</param> /// <returns></returns> private String TripleToDot(Triple t, BaseWriterContext context) { StringBuilder output = new StringBuilder(); // Output Node lines for Literal Node so we show them as Boxes // This is in keeping with Standard Graph representation of RDF // Literals are shown in Boxes, Uri Nodes in ellipses (GraphViz's default shape) if (t.Subject.NodeType == NodeType.Literal) { output.Append(this.NodeToDot(t.Subject, context)); output.Append(" [shape=box];\n"); } if (t.Object.NodeType == NodeType.Literal) { output.Append(this.NodeToDot(t.Object, context)); output.Append(" [shape=box];\n"); } // Output the actual lines that state the relationship between the Nodes // We use the Predicate as the Label on the relationship output.Append(this.NodeToDot(t.Subject, context)); output.Append(" -> "); output.Append(this.NodeToDot(t.Object, context)); output.Append(" [label="); output.Append(this.NodeToDot(t.Predicate, context)); output.Append("];"); return(output.ToString()); }
private static string WriteLiteralNode(ILiteralNode literalnode, Triple t, BaseWriterContext context, bool collapseLiterals) { // Example output: // "h" [label = "v", shape = box]; // where h is the hash of the triple containing the literal node // and v is value of literal node // Literal nodes are identified either by their value or by their containing triple. // When identified by value, there will be a single node representing all literals with the same value. // When identified by triple, there will be a separate node representing each triple that has an object with that value. var idObject = collapseLiterals ? literalnode as object : t as object; var nodeId = idObject.GetHashCode().ToString(); GraphVizWriter.Prettify(DOT.Tab, context); GraphVizWriter.WriteQuoted(nodeId, context); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.OpenSquare); context.Output.Write(DOT.Label); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.Equal); GraphVizWriter.Prettify(DOT.Space, context); GraphVizWriter.WriteLiteralNodeLabel(literalnode, context); context.Output.Write(DOT.Comma); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.Shape); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.Equal); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.Box); context.Output.Write(DOT.CloseSquare); context.Output.Write(DOT.NewLine, context); return(nodeId); }
private static void WriteTriple(Triple triple, BaseWriterContext context, bool collapseLiterals) { // Output Node lines for Literal Node so we show them as Boxes // This is in keeping with Standard Graph representation of RDF // Literals are shown in Boxes, Uri Nodes in ellipses (GraphViz's default shape) var subjectId = GraphVizWriter.ProcessNode(triple, TripleSegment.Subject, context, collapseLiterals); var objectId = GraphVizWriter.ProcessNode(triple, TripleSegment.Object, context, collapseLiterals); // Output the actual lines that state the relationship between the Nodes // We use the Predicate as the Label on the relationship var predicateLabel = GraphVizWriter.ReduceToQName((triple.Predicate as IUriNode).Uri, context); GraphVizWriter.Prettify(DOT.Tab, context); GraphVizWriter.WriteQuoted(subjectId, context); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.Arrow); GraphVizWriter.Prettify(DOT.Space, context); GraphVizWriter.WriteQuoted(objectId, context); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.OpenSquare); context.Output.Write(DOT.Label); GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.Equal); GraphVizWriter.Prettify(DOT.Space, context); GraphVizWriter.WriteQuoted(predicateLabel, context); context.Output.Write(DOT.CloseSquare); context.Output.Write(DOT.Semicolon); GraphVizWriter.Prettify(DOT.NewLine, context); }
/// <summary> /// Generates the Output for a Graph as a String in CSV syntax. /// </summary> /// <param name="globalContext">Context for writing the Store.</param> /// <param name="context">Context for writing the Graph.</param> /// <returns></returns> private String GenerateGraphOutput(ThreadedStoreWriterContext globalContext, BaseWriterContext context) { if (context.Graph.BaseUri != null) { // Named Graphs have a fourth context field added foreach (Triple t in context.Graph.Triples) { GenerateNodeOutput(context, t.Subject, TripleSegment.Subject); context.Output.Write(','); GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); context.Output.Write(','); GenerateNodeOutput(context, t.Object, TripleSegment.Object); context.Output.Write(','); context.Output.Write(_formatter.FormatUri(context.Graph.BaseUri)); context.Output.Write("\r\n"); } } else { // Default Graph has an empty field added foreach (Triple t in context.Graph.Triples) { GenerateNodeOutput(context, t.Subject, TripleSegment.Subject); context.Output.Write(','); GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); context.Output.Write(','); GenerateNodeOutput(context, t.Object, TripleSegment.Object); context.Output.Write(','); context.Output.Write("\r\n"); } } return(context.Output.ToString()); }
private static void WriteQuoted(string value, BaseWriterContext context) { context.Output.Write(DOT.Quote); context.Output.Write(value); context.Output.Write(DOT.Quote); }
private static string ReduceToQName(Uri uri, BaseWriterContext context) { if (!context.QNameMapper.ReduceToQName(uri.ToString(), out string result)) { result = uri.ToString(); } return(result); }
/// <summary> /// Saves a Graph into GraphViz DOT Format /// </summary> /// <param name="g">Graph to save</param> /// <param name="output">Stream to save to</param> protected override void SaveInternal(IGraph g, TextWriter output) { var context = new BaseWriterContext(g, output) { PrettyPrint = this.PrettyPrintMode }; GraphVizWriter.WriteGraph(context, this.CollapseLiterals); }
/// <summary> /// Saves a Graph into GraphViz DOT Format /// </summary> /// <param name="g">Graph to save</param> /// <param name="output">Stream to save to</param> protected override void SaveInternal(IGraph g, TextWriter output) { // Start the Graph output.WriteLine("digraph G {"); BaseWriterContext context = new BaseWriterContext(g, output); // Write all the Triples to the Graph foreach (Triple t in g.Triples) { output.WriteLine(this.TripleToDot(t, context)); } // End the Graph output.WriteLine("}"); }
/// <summary> /// Generates Output for the given Node /// </summary> /// <param name="context">Writer Context</param> /// <param name="n">Node</param> /// <param name="segment">Triple Context</param> private void GenerateNodeOutput(BaseWriterContext context, INode n, TripleSegment segment) { switch (n.NodeType) { case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("TSV")); case NodeType.Blank: case NodeType.Literal: case NodeType.Uri: context.Output.Write(this._formatter.Format(n)); break; default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("TSV")); } }
/// <summary> /// Saves a Graph into GraphViz DOT Format /// </summary> /// <param name="g">Graph to save</param> /// <param name="output">Stream to save to</param> public void Save(IGraph g, TextWriter output) { //Start the Graph output.WriteLine("digraph G {"); BaseWriterContext context = new BaseWriterContext(g, output); //Write all the Triples to the Graph foreach (Triple t in g.Triples) { output.WriteLine(this.TripleToDot(t, context)); } //End the Graph output.WriteLine("}"); output.Close(); }
private static string ProcessNode(Triple t, TripleSegment segment, BaseWriterContext context, bool collapseLiterals) { var node = GraphVizWriter.GetNode(t, segment); switch (node) { case ILiteralNode literalnode: return(GraphVizWriter.WriteLiteralNode(literalnode, t, context, collapseLiterals)); case IUriNode uriNode: return(GraphVizWriter.ReduceToQName(uriNode.Uri, context)); case IBlankNode blankNode: return(blankNode.ToString()); default: throw new RdfOutputException("Only Uri nodes, literal nodes and blank nodes can be converted to GraphViz DOT Format."); } }
/// <summary> /// Internal Helper method for converting Uri Nodes to DOT Notation /// </summary> /// <param name="u">Uri Node to convert</param> /// <param name="context">Writer Context</param> /// <returns></returns> private String UriNodeToDot(IUriNode u, BaseWriterContext context) { StringBuilder output = new StringBuilder(); output.Append("\""); //Try QName reduction String qname; if (context.QNameMapper.ReduceToQName(u.Uri.ToString(), out qname)) { //Use the QName output.Append(qname); } else { //Use the full Uri output.Append(u.Uri); } output.Append("\""); return output.ToString(); }
/// <summary> /// Internal Helper method for converting a Node into DOT notation /// </summary> /// <param name="n">Node to Convert</param> /// <param name="context">Writer Context</param> /// <returns></returns> /// <remarks>Currently Graphs containing Graph Literal Nodes cannot be converted</remarks> private String NodeToDot(INode n, BaseWriterContext context) { if (n.NodeType == NodeType.Uri) { return(this.UriNodeToDot((IUriNode)n, context)); } else if (n.NodeType == NodeType.Literal) { return(this.LiteralNodeToDot((ILiteralNode)n)); } else if (n.NodeType == NodeType.Blank) { return(this.BlankNodeToDot((IBlankNode)n)); } else if (n.NodeType == NodeType.GraphLiteral) { throw new RdfOutputException("Graphs containing Graph Literal Nodes cannot be converted into GraphViz DOT Format"); } else { throw new RdfOutputException("Unknown Node Type cannot be converted into GraphViz DOT Format"); } }
private static void WriteLiteralNodeLabel(ILiteralNode literalnode, BaseWriterContext context) { var nodeValue = GraphVizWriter.Escape(literalnode.Value); context.Output.Write(DOT.Quote); context.Output.Write(nodeValue); if (!string.IsNullOrEmpty(literalnode.Language)) { context.Output.Write("@"); context.Output.Write(literalnode.Language); } if (literalnode.DataType != null) { string datatype = GraphVizWriter.ReduceToQName(literalnode.DataType, context); context.Output.Write("^^"); context.Output.Write(datatype); } context.Output.Write(DOT.Quote); }
private static void WriteGraph(BaseWriterContext context, bool collapseLiterals) { context.Output.Write(DOT.Digraph); if (context.Graph.BaseUri != null) { var graphId = GraphVizWriter.ReduceToQName(context.Graph.BaseUri, context); GraphVizWriter.Prettify(DOT.Space, context); GraphVizWriter.WriteQuoted(graphId, context); } GraphVizWriter.Prettify(DOT.Space, context); context.Output.Write(DOT.OpenCurly); GraphVizWriter.Prettify(DOT.NewLine, context); foreach (var t in context.Graph.Triples) { GraphVizWriter.WriteTriple(t, context, collapseLiterals); } context.Output.Write(DOT.CloseCurly); }
/// <summary> /// Generates Output for the given Node. /// </summary> /// <param name="context">Writer Context.</param> /// <param name="n">Node.</param> /// <param name="segment">Triple Segment.</param> private void GenerateNodeOutput(BaseWriterContext context, INode n, TripleSegment segment) { switch (n.NodeType) { case NodeType.Blank: if (segment == TripleSegment.Predicate) { throw new RdfOutputException(WriterErrorMessages.BlankPredicatesUnserializable("CSV")); } context.Output.Write(_formatter.Format(n)); break; case NodeType.GraphLiteral: throw new RdfOutputException(WriterErrorMessages.GraphLiteralsUnserializable("CSV")); case NodeType.Literal: if (segment == TripleSegment.Subject) { throw new RdfOutputException(WriterErrorMessages.LiteralSubjectsUnserializable("CSV")); } if (segment == TripleSegment.Predicate) { throw new RdfOutputException(WriterErrorMessages.LiteralPredicatesUnserializable("CSV")); } context.Output.Write(_formatter.Format(n)); break; case NodeType.Uri: context.Output.Write(_formatter.Format(n)); break; default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("CSV")); } }
/// <summary> /// Generates the Output for a Graph as a String in TSV syntax /// </summary> /// <param name="globalContext">Context for writing the Store</param> /// <param name="context">Context for writing the Graph</param> /// <returns></returns> private String GenerateGraphOutput(ThreadedStoreWriterContext globalContext, BaseWriterContext context) { if (!WriterHelper.IsDefaultGraph(context.Graph.BaseUri)) { //Named Graphs have a fourth context field added foreach (Triple t in context.Graph.Triples) { this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject); context.Output.Write('\t'); this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); context.Output.Write('\t'); this.GenerateNodeOutput(context, t.Object, TripleSegment.Object); context.Output.Write('\t'); context.Output.Write('<'); context.Output.Write(this._formatter.FormatUri(context.Graph.BaseUri)); context.Output.Write('>'); context.Output.Write('\n'); } } else { //Default Graph has an empty field added foreach (Triple t in context.Graph.Triples) { this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject); context.Output.Write('\t'); this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); context.Output.Write('\t'); this.GenerateNodeOutput(context, t.Object, TripleSegment.Object); context.Output.Write('\t'); context.Output.Write('\n'); } } return(context.Output.ToString()); }