/// <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(); }
/// <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 = globalContext.GetNextUri(); while (u != null) { //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 = this.GenerateGraphOutput(globalContext, context); try { Monitor.Enter(globalContext.Output); globalContext.Output.WriteLine(graphContent); globalContext.Output.Flush(); } catch { throw; } finally { Monitor.Exit(globalContext.Output); } //Get the Next Uri u = globalContext.GetNextUri(); } } catch (ThreadAbortException) { //We've been terminated, don't do anything #if !SILVERLIGHT Thread.ResetAbort(); #endif } catch (Exception ex) { throw new RdfStorageException("Error in Threaded Writer in Thread ID " + Thread.CurrentThread.ManagedThreadId, ex); } }
/// <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(this._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(this._formatter.Format(n)); break; case NodeType.Uri: context.Output.Write(this._formatter.Format(n)); break; default: throw new RdfOutputException(WriterErrorMessages.UnknownNodeTypeUnserializable("CSV")); } }
/// <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 (!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(','); this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); context.Output.Write(','); this.GenerateNodeOutput(context, t.Object, TripleSegment.Object); context.Output.Write(','); context.Output.Write(this._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) { this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject); context.Output.Write(','); this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate); context.Output.Write(','); this.GenerateNodeOutput(context, t.Object, TripleSegment.Object); context.Output.Write(','); context.Output.Write("\r\n"); } } return context.Output.ToString(); }
/// <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(); }
/// <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"); } }