Exemplo n.º 1
0
        private IToken TryGetNumericLiteral()
        {
            bool dotoccurred  = false;
            bool expoccurred  = false;
            bool signoccurred = false;

            if (this.Length == 1)
            {
                dotoccurred = true;
            }

            char next = this.Peek();

            //Read the Characters of the Numeric Literal
            while (Char.IsDigit(next) || next == '-' || next == '+' || (next == '.' && !dotoccurred) || next == 'e' || next == 'E')
            {
                if (next == '-' || next == '+')
                {
                    //Sign can occur at start and immediatedly after an exponent
                    if ((signoccurred || expoccurred) && !(this.Value.EndsWith("e") || this.Value.EndsWith("E")))
                    {
                        //+/- can only occur once at start and once after exponent
                        throw Error("Unexpected Character " + next + " encountered while parsing a Numeric Literal from input '" + this.Value + "', a +/- to specify sign has already occurred in this Numeric Literal");
                    }
                    signoccurred = true;
                }
                else if (next == '.')
                {
                    dotoccurred = true;
                }
                else if (next == 'e' || next == 'E')
                {
                    if (expoccurred)
                    {
                        throw Error("Unexpected Character " + next + " encountered while parsing a Numeric Literal from input '" + this.Value + "', a e/E to specify exponent has already occurred in this Numeric Literal");
                    }
                    expoccurred = true;
                }

                this.ConsumeCharacter();
                next = this.Peek();
            }

            if (this.Value.EndsWith("."))
            {
                this.Backtrack();
            }

            //Validate
            if (TurtleSpecsHelper.IsValidPlainLiteral(this.Value, TurtleSyntax.Original))
            {
                this._lasttokentype = Token.PLAINLITERAL;
                return(new PlainLiteralToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition));
            }
            else
            {
                throw Error("The input '" + this.Value + "' is not a valid Plain Literal in {0}");
            }
        }
Exemplo n.º 2
0
        private IToken TryGetPlainLiteralOrQName()
        {
            //Read Valid Plain Literal and QName Chars
            char next = this.Peek();

            bool colonoccurred = false;

            while (Char.IsLetterOrDigit(next) || next == '_' || next == '-' || next == ':')
            {
                this.ConsumeCharacter();

                if (next == ':')
                {
                    if (colonoccurred)
                    {
                        throw Error("Unexpected Colon encountered in input '" + this.Value + "', a Colon may only occur once in a QName");
                    }
                    colonoccurred = true;
                }

                next = this.Peek();
            }

            //Validate
            String value = this.Value;

            //If it ends in a trailing . then we need to backtrack
            if (value.EndsWith("."))
            {
                this.Backtrack();
                value = value.Substring(0, value.Length - 1);
            }

            if (value.Equals("a"))
            {
                //Keyword 'a'
                this._lasttokentype = Token.KEYWORDA;
                return(new KeywordAToken(this.CurrentLine, this.StartPosition));
            }
            else if (value.Equals("true") || value.Equals("false"))
            {
                //Boolean Plain Literal
                this._lasttokentype = Token.PLAINLITERAL;
                return(new PlainLiteralToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition));
            }
            else if (TurtleSpecsHelper.IsValidQName(value))
            {
                //QName
                this._lasttokentype = Token.QNAME;
                return(new QNameToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition));
            }
            else
            {
                //Error
                throw Error("Unexpected input '" + value + "', expected a QName, the 'a' Keyword or a Plain Literal");
            }
        }
Exemplo n.º 3
0
        private IToken TryGetQName()
        {
            bool colonoccurred = false;

            char next = this.Peek();

            while (Char.IsLetterOrDigit(next) || next == '-' || next == '_' || next == ':')
            {
                this.ConsumeCharacter();
                if (next == ':')
                {
                    if (colonoccurred)
                    {
                        throw Error("Unexpected Colon encountered in input '" + this.Value + "', a Colon may only occur once in a QName");
                    }
                    colonoccurred = true;
                }

                next = this.Peek();
            }

            if (this.Value.StartsWith("."))
            {
                this.Backtrack();
            }

            //Validate the QName
            if (this.Value.StartsWith("_:"))
            {
                //Blank Node ID
                this._lasttokentype = Token.BLANKNODEWITHID;
                return(new BlankNodeWithIDToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition));
            }
            else if (TurtleSpecsHelper.IsValidQName(this.Value))
            {
                //QName
                this._lasttokentype = Token.QNAME;
                return(new QNameToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition));
            }
            else
            {
                throw Error("The input '" + this.Value + "' is not a valid QName in {0}");
            }
        }
Exemplo n.º 4
0
        private IToken TryGetPlainLiteral()
        {
            this.ConsumeCharacter();
            char next = this.Peek();

            while (Char.IsLetter(next))
            {
                this.ConsumeCharacter();
                next = this.Peek();
            }

            if (TurtleSpecsHelper.IsValidPlainLiteral(this.Value))
            {
                this.LastTokenType = Token.PLAINLITERAL;
                return(new PlainLiteralToken(this.Value, this.StartLine, this.StartPosition, this.EndPosition));
            }
            else
            {
                throw new RdfParseException("'" + this.Value + "' is not a valid Plain Literal!");
            }
        }
Exemplo n.º 5
0
        private IToken TryGetPlainLiteral()
        {
            ConsumeCharacter();
            char next = Peek();

            while (Char.IsLetter(next))
            {
                ConsumeCharacter();
                next = Peek();
            }

            if (TurtleSpecsHelper.IsValidPlainLiteral(Value, TurtleSyntax.Original))
            {
                LastTokenType = Token.PLAINLITERAL;
                return(new PlainLiteralToken(Value, StartLine, StartPosition, EndPosition));
            }
            else
            {
                throw new RdfParseException("'" + Value + "' is not a valid Plain Literal!");
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Generates the Output for a Graph as a String in TriG 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(TriGWriterContext globalContext, TurtleWriterContext context)
        {
            if (!WriterHelper.IsDefaultGraph(context.Graph.BaseUri))
            {
                //Named Graph
                String gname;
                String sep = (globalContext.N3CompatabilityMode) ? " = " : " ";
                if (globalContext.CompressionLevel > WriterCompressionLevel.None && globalContext.QNameMapper.ReduceToQName(context.Graph.BaseUri.ToString(), out gname))
                {
                    if (TurtleSpecsHelper.IsValidQName(gname))
                    {
                        context.Output.WriteLine(gname + sep + "{");
                    }
                    else
                    {
                        context.Output.WriteLine("<" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">" + sep + "{");
                    }
                }
                else
                {
                    context.Output.WriteLine("<" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">" + sep + "{");
                }
            }
            else
            {
                context.Output.WriteLine("{");
            }

            //Generate Triples
            this.GenerateTripleOutput(globalContext, context);

            //Close the Graph
            context.Output.WriteLine("}");

            return(context.Output.ToString());
        }
Exemplo n.º 7
0
        private IToken TryGetPrefix()
        {
            //Get the prefix
            char next = this.Peek();

            while (!Char.IsWhiteSpace(next))
            {
                this.ConsumeCharacter();
                next = this.Peek();
            }

            //Last character must be a :
            if (!this.Value.EndsWith(":"))
            {
                throw this.UnexpectedCharacter(next, "expected a : to end a Prefix specification");
            }
            if (!TurtleSpecsHelper.IsValidQName(this.Value))
            {
                throw new RdfParseException("The value '" + this.Value + "' is not a valid Prefix in TriG", new PositionInfo(this.StartLine, this.CurrentLine, this.StartPosition, this.EndPosition));
            }

            this._lasttokentype = Token.PREFIX;
            return(new PrefixToken(this.Value, this.CurrentLine, this.StartPosition, this.EndPosition));
        }
Exemplo n.º 8
0
        private IToken TryGetPrefix()
        {
            // Get the prefix
            char next = Peek();

            while (!Char.IsWhiteSpace(next))
            {
                ConsumeCharacter();
                next = Peek();
            }

            // Last character must be a :
            if (!Value.EndsWith(":"))
            {
                throw UnexpectedCharacter(next, "expected a : to end a Prefix specification");
            }
            if (!TurtleSpecsHelper.IsValidQName(Value, _syntax == TriGSyntax.Recommendation ? TurtleSyntax.W3C : TurtleSyntax.Original))
            {
                throw new RdfParseException("The value '" + Value + "' is not a valid Prefix in TriG", new PositionInfo(StartLine, CurrentLine, StartPosition, EndPosition));
            }

            _lasttokentype = Token.PREFIX;
            return(new PrefixToken(Value, CurrentLine, StartPosition, EndPosition));
        }
Exemplo n.º 9
0
 /// <summary>
 /// Gets whether a QName is valid in Turtle as specified by the W3C.
 /// </summary>
 /// <param name="value">QName.</param>
 /// <returns></returns>
 protected override bool IsValidQName(string value)
 {
     return(TurtleSpecsHelper.IsValidQName(value, TurtleSyntax.W3C));
 }
Exemplo n.º 10
0
        /// <summary>
        /// Formats a Literal Node as a String
        /// </summary>
        /// <param name="l">Literal Node</param>
        /// <param name="segment">Triple Segment</param>
        /// <returns></returns>
        protected override string FormatLiteralNode(ILiteralNode l, TripleSegment?segment)
        {
            StringBuilder output = new StringBuilder();
            String        value, qname;
            bool          longlit = false, plainlit = false;

            longlit  = TurtleSpecsHelper.IsLongLiteral(l.Value);
            plainlit = TurtleSpecsHelper.IsValidPlainLiteral(l.Value, l.DataType);

            if (plainlit)
            {
                if (TurtleSpecsHelper.IsValidDecimal(l.Value) && l.Value.EndsWith("."))
                {
                    //Ensure we strip the trailing dot of any xsd:decimal and add a datatype definition
                    output.Append('"');
                    output.Append(l.Value.Substring(0, l.Value.Length - 1));
                    output.Append("\"^^<");
                    output.Append(this.FormatUri(XmlSpecsHelper.XmlSchemaDataTypeDecimal));
                    output.Append('>');
                }
                else
                {
                    //Otherwise just write out the value
                    output.Append(l.Value);
                }
                //For integers ensure we insert a space after the literal to ensure it can't ever be confused with a decimal
                if (TurtleSpecsHelper.IsValidInteger(l.Value))
                {
                    output.Append(' ');
                }
            }
            else
            {
                output.Append('"');
                if (longlit)
                {
                    output.Append("\"\"");
                }

                value = l.Value;

                bool fullyEscaped = (longlit) ? value.IsFullyEscaped(this._validEscapes, this._longLitMustEscape) : value.IsFullyEscaped(this._validEscapes, this._litMustEscape);

                if (!fullyEscaped)
                {
                    //This first replace escapes all back slashes for good measure
                    value = value.EscapeBackslashes(this._validEscapes);

                    //Then remove null character since it doesn't change the meaning of the Literal
                    value = value.Replace("\0", "");

                    //Don't need all the other escapes for long literals as the characters that would be escaped are permitted in long literals
                    //Need to escape " still
                    value = value.Escape('"');

                    if (!longlit)
                    {
                        //Then if we're not a long literal we'll escape tabs
                        value = value.Replace("\t", "\\t");
                    }
                }
                output.Append(value);
                output.Append('"');
                if (longlit)
                {
                    output.Append("\"\"");
                }

                if (!l.Language.Equals(String.Empty))
                {
                    output.Append('@');
                    output.Append(l.Language.ToLower());
                }
                else if (l.DataType != null)
                {
                    output.Append("^^");
                    if (this._qnameMapper.ReduceToQName(l.DataType.ToString(), out qname))
                    {
                        if (TurtleSpecsHelper.IsValidQName(qname))
                        {
                            output.Append(qname);
                        }
                        else
                        {
                            output.Append('<');
                            output.Append(this.FormatUri(l.DataType));
                            output.Append('>');
                        }
                    }
                    else
                    {
                        output.Append('<');
                        output.Append(this.FormatUri(l.DataType));
                        output.Append('>');
                    }
                }
            }

            return(output.ToString());
        }
Exemplo n.º 11
0
        /// <summary>
        /// Saves a Store in TriG (Turtle with Named Graphs) format.
        /// </summary>
        /// <param name="store">Store to save.</param>
        /// <param name="writer">Writer to save to.</param>
        /// <param name="leaveOpen">Boolean flag indicating if <paramref name="writer"/> should be left open after the store is saved.</param>
        public void Save(ITripleStore store, TextWriter writer, bool leaveOpen)
        {
            if (store == null)
            {
                throw new RdfOutputException("Cannot output a null Triple Store");
            }
            if (writer == null)
            {
                throw new RdfOutputException("Cannot output to a null writer");
            }

            TriGWriterContext context = new TriGWriterContext(store, writer, _prettyprint, _allowHiSpeed, _compressionLevel, _n3compat);

            // Check there's something to do
            if (context.Store.Graphs.Count == 0)
            {
                if (!leaveOpen)
                {
                    context.Output.Close();
                }
                return;
            }

            // Write the Header of the File
            foreach (var g in context.Store.Graphs)
            {
                context.NamespaceMap.Import(g.NamespaceMap);
            }
            if (context.CompressionLevel > WriterCompressionLevel.None)
            {
                // Only add @prefix declarations if compression is enabled
                context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap);
                foreach (string prefix in context.NamespaceMap.Prefixes)
                {
                    if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                    {
                        context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">.");
                    }
                }
                context.Output.WriteLine();
            }
            else
            {
                context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true));
            }

            if (_useMultiThreading)
            {
                // Standard Multi-Threaded Writing

                // Queue the Graphs to be written
                foreach (IGraph g in context.Store.Graphs)
                {
                    context.Add(g.BaseUri);
                }

                // Start making the async calls
                var workers = new Task[_threads];
                for (int i = 0; i < _threads; i++)
                {
                    workers[i] = Task.Factory.StartNew(() => SaveGraphs(context));
                }

                try
                {
                    Task.WaitAll(workers);
                }
                catch (AggregateException ex)
                {
                    var outputException =
                        new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG"));
                    foreach (var innerException in ex.InnerExceptions)
                    {
                        outputException.AddException(innerException);
                    }
                }
                finally
                {
                    // Make sure to close the output
                    if (!leaveOpen)
                    {
                        context.Output.Close();
                    }
                }
            }
            else
            {
                try
                {
                    // Optional Single Threaded Writing
                    foreach (IGraph g in store.Graphs)
                    {
                        TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted);
                        if (context.CompressionLevel > WriterCompressionLevel.None)
                        {
                            graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper);
                        }
                        else
                        {
                            graphContext.NodeFormatter = new UncompressedTurtleFormatter();
                        }
                        context.Output.WriteLine(GenerateGraphOutput(context, graphContext));
                    }

                    // Make sure to close the output
                    if (!leaveOpen)
                    {
                        context.Output.Close();
                    }
                }
                catch
                {
                    try
                    {
                        // Close the output
                        if (!leaveOpen)
                        {
                            context.Output.Close();
                        }
                    }
                    catch
                    {
                        // No catch actions, just cleaning up the output stream
                    }
                    throw;
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Generates the Output for a Graph
        /// </summary>
        /// <param name="context">Context for writing the Graph</param>
        private void GenerateOutput(TurtleWriterContext context)
        {
            //Write Base Uri
            if (context.Graph.BaseUri != null)
            {
                context.Output.WriteLine("@base <" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">.");
                context.Output.WriteLine();
            }

            //Write Prefixes
            foreach (String prefix in context.Graph.NamespaceMap.Prefixes)
            {
                if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                {
                    context.Output.Write("@prefix " + prefix + ": <");
                    String nsUri = context.UriFormatter.FormatUri(context.Graph.NamespaceMap.GetNamespaceUri(prefix));
                    context.Output.WriteLine(nsUri + ">.");
                }
            }
            context.Output.WriteLine();

            //Decide which write mode to use
            bool   hiSpeed   = false;
            double subjNodes = context.Graph.Triples.SubjectNodes.Count();
            double triples   = context.Graph.Triples.Count;

            if ((subjNodes / triples) > 0.75)
            {
                hiSpeed = true;
            }

            if (hiSpeed && context.HighSpeedModePermitted)
            {
                //High Speed Writing Mode
                //Writes everything as individual Triples
                this.RaiseWarning("High Speed Write Mode in use - minimal syntax compressions will be used");
                context.NodeFormatter = new UncompressedTurtleFormatter();
                foreach (Triple t in context.Graph.Triples)
                {
                    context.Output.Write(this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject));
                    context.Output.Write(" ");
                    context.Output.Write(this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate));
                    context.Output.Write(" ");
                    context.Output.Write(this.GenerateNodeOutput(context, t.Object, TripleSegment.Object));
                    context.Output.WriteLine(".");
                }
            }
            else
            {
                //Get the Triples as a Sorted List
                List <Triple> ts = context.Graph.Triples.ToList();
                ts.Sort();

                //Variables we need to track our writing
                INode lastSubj, lastPred;
                lastSubj = lastPred = null;
                int    subjIndent = 0, predIndent = 0;
                String temp;

                for (int i = 0; i < ts.Count; i++)
                {
                    Triple t = ts[i];
                    if (lastSubj == null || !t.Subject.Equals(lastSubj))
                    {
                        //Terminate previous Triples
                        if (lastSubj != null)
                        {
                            context.Output.WriteLine(".");
                        }

                        //Start a new set of Triples
                        temp = this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject);
                        context.Output.Write(temp);
                        context.Output.Write(" ");
                        subjIndent = temp.Length + 1;
                        lastSubj   = t.Subject;

                        //Write the first Predicate
                        temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate);
                        context.Output.Write(temp);
                        context.Output.Write(" ");
                        predIndent = temp.Length + 1;
                        lastPred   = t.Predicate;
                    }
                    else if (lastPred == null || !t.Predicate.Equals(lastPred))
                    {
                        //Terminate previous Predicate Object list
                        context.Output.WriteLine(";");

                        if (context.PrettyPrint)
                        {
                            context.Output.Write(new String(' ', subjIndent));
                        }

                        //Write the next Predicate
                        temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate);
                        context.Output.Write(temp);
                        context.Output.Write(" ");
                        predIndent = temp.Length + 1;
                        lastPred   = t.Predicate;
                    }
                    else
                    {
                        //Continue Object List
                        context.Output.WriteLine(",");

                        if (context.PrettyPrint)
                        {
                            context.Output.Write(new String(' ', subjIndent + predIndent));
                        }
                    }

                    //Write the Object
                    context.Output.Write(this.GenerateNodeOutput(context, t.Object, TripleSegment.Object));
                }

                //Terminate Triples
                if (ts.Count > 0)
                {
                    context.Output.WriteLine(".");
                }
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Saves a Store in TriG (Turtle with Named Graphs) format
        /// </summary>
        /// <param name="store">Store to save</param>
        /// <param name="parameters">Parameters indicating a Stream to write to</param>
        public void Save(ITripleStore store, IStoreParams parameters)
        {
            //Try and determine the TextWriter to output to
            TriGWriterContext context = null;

            if (parameters is StreamParams)
            {
                //Create a new Writer Context
                ((StreamParams)parameters).Encoding = new UTF8Encoding(Options.UseBomForUtf8);
                context = new TriGWriterContext(store, ((StreamParams)parameters).StreamWriter, this._prettyprint, this._allowHiSpeed, this._compressionLevel, this._n3compat);
            }
            else if (parameters is TextWriterParams)
            {
                context = new TriGWriterContext(store, ((TextWriterParams)parameters).TextWriter, this._prettyprint, this._allowHiSpeed, this._compressionLevel, this._n3compat);
            }

            if (context != null)
            {
                //Check there's something to do
                if (context.Store.Graphs.Count == 0)
                {
                    context.Output.Close();
                    return;
                }

                //Write the Header of the File
                foreach (IGraph g in context.Store.Graphs)
                {
                    context.NamespaceMap.Import(g.NamespaceMap);
                }
                if (context.CompressionLevel > WriterCompressionLevel.None)
                {
                    //Only add @prefix declarations if compression is enabled
                    context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap);
                    foreach (String prefix in context.NamespaceMap.Prefixes)
                    {
                        if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                        {
                            context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">.");
                        }
                    }
                    context.Output.WriteLine();
                }
                else
                {
                    context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true));
                }

                if (this._useMultiThreading)
                {
                    //Standard Multi-Threaded Writing

                    //Queue the Graphs to be written
                    foreach (IGraph g in context.Store.Graphs)
                    {
                        if (g.BaseUri == null)
                        {
                            context.Add(new Uri(GraphCollection.DefaultGraphUri));
                        }
                        else
                        {
                            context.Add(g.BaseUri);
                        }
                    }

                    //Start making the async calls
                    List <IAsyncResult> results = new List <IAsyncResult>();
                    SaveGraphsDelegate  d       = new SaveGraphsDelegate(this.SaveGraphs);
                    for (int i = 0; i < this._threads; i++)
                    {
                        results.Add(d.BeginInvoke(context, null, null));
                    }

                    //Wait for all the async calls to complete
                    WaitHandle.WaitAll(results.Select(r => r.AsyncWaitHandle).ToArray());
                    RdfThreadedOutputException outputEx = new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG"));
                    foreach (IAsyncResult result in results)
                    {
                        try
                        {
                            d.EndInvoke(result);
                        }
                        catch (Exception ex)
                        {
                            outputEx.AddException(ex);
                        }
                    }
                    //Make sure to close the output
                    context.Output.Close();

                    //If there were any errors we'll throw an RdfThreadedOutputException now
                    if (outputEx.InnerExceptions.Any())
                    {
                        throw outputEx;
                    }
                }
                else
                {
                    try
                    {
                        //Optional Single Threaded Writing
                        foreach (IGraph g in store.Graphs)
                        {
                            TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted);
                            if (context.CompressionLevel > WriterCompressionLevel.None)
                            {
                                graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper);
                            }
                            else
                            {
                                graphContext.NodeFormatter = new UncompressedTurtleFormatter();
                            }
                            context.Output.WriteLine(this.GenerateGraphOutput(context, graphContext));
                        }

                        //Make sure to close the output
                        context.Output.Close();
                    }
                    catch
                    {
                        try
                        {
                            //Close the output
                            context.Output.Close();
                        }
                        catch
                        {
                            //No catch actions, just cleaning up the output stream
                        }
                        throw;
                    }
                }
            }
            else
            {
                throw new RdfStorageException("Parameters for the TriGWriter must be of the type StreamParams/TextWriterParams");
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Internal method which generates the HTML Output for the Graph
        /// </summary>
        /// <param name="context">Writer Context</param>
        private void GenerateOutput(HtmlWriterContext context)
        {
            Object results;

            // Add the Namespaces we want to use later on
            context.QNameMapper.AddNamespace("owl", UriFactory.Create(NamespaceMapper.OWL));
            context.QNameMapper.AddNamespace("rdf", UriFactory.Create(NamespaceMapper.RDF));
            context.QNameMapper.AddNamespace("rdfs", UriFactory.Create(NamespaceMapper.RDFS));
            context.QNameMapper.AddNamespace("dc", UriFactory.Create("http://purl.org/dc/elements/1.1/"));
            context.QNameMapper.AddNamespace("dct", UriFactory.Create("http://purl.org/dc/terms/"));
            context.QNameMapper.AddNamespace("vann", UriFactory.Create("http://purl.org/vocab/vann/"));
            context.QNameMapper.AddNamespace("vs", UriFactory.Create("http://www.w3.org/2003/06/sw-vocab-status/ns#"));

            // Find the Node that represents the Schema Ontology
            // Assumes there is exactly one thing given rdf:type owl:Ontology
            IUriNode ontology  = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "Ontology"));
            IUriNode rdfType   = context.Graph.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfType));
            IUriNode rdfsLabel = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "label"));
            INode    ontoNode  = context.Graph.GetTriplesWithPredicateObject(rdfType, ontology).Select(t => t.Subject).FirstOrDefault();
            INode    ontoLabel = (ontoNode != null) ? context.Graph.GetTriplesWithSubjectPredicate(ontoNode, rdfsLabel).Select(t => t.Object).FirstOrDefault() : null;

            // Stuff for formatting
            // We'll use the Turtle Formatter to get nice QNames wherever possible
            context.NodeFormatter = new TurtleFormatter(context.QNameMapper);
            context.UriFormatter  = (IUriFormatter)context.NodeFormatter;

            // Page Header
            context.HtmlWriter.Write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML+RDFa 1.0//EN\" \"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd\">");
            context.HtmlWriter.WriteLine();
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Html);
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Head);
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Title);
            context.HtmlWriter.WriteEncodedText("Schema");
            if (ontoNode != null && ontoLabel != null)
            {
                context.HtmlWriter.WriteEncodedText(" - " + ontoLabel.ToSafeString());
            }
            else if (context.Graph.BaseUri != null)
            {
                context.HtmlWriter.WriteEncodedText(" - " + context.Graph.BaseUri.AbsoluteUri);
            }
            context.HtmlWriter.RenderEndTag();
            if (!this.Stylesheet.Equals(String.Empty))
            {
                context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Href, this.Stylesheet);
                context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
                context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
                context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Link);
                context.HtmlWriter.RenderEndTag();
            }
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            // Start Body
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Body);

            // Title
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H2);
            context.HtmlWriter.WriteEncodedText("Schema");
            if (ontoNode != null && ontoLabel != null)
            {
                context.HtmlWriter.WriteEncodedText(" - " + ontoLabel.ToSafeString());
            }
            else if (context.Graph.BaseUri != null)
            {
                context.HtmlWriter.WriteEncodedText(" - " + context.Graph.BaseUri.AbsoluteUri);
            }
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            // Show the Description of the Schema (if any)
            if (ontoNode != null)
            {
                SparqlParameterizedString getOntoDescrip = new SparqlParameterizedString();
                getOntoDescrip.Namespaces  = context.QNameMapper;
                getOntoDescrip.CommandText = "SELECT * WHERE { @onto a owl:Ontology . OPTIONAL { @onto rdfs:comment ?description } . OPTIONAL { @onto vann:preferredNamespacePrefix ?nsPrefix ; vann:preferredNamespaceUri ?nsUri } . OPTIONAL { @onto dc:creator ?creator . ?creator (foaf:name | rdfs:label) ?creatorName } }";
                getOntoDescrip.SetParameter("onto", ontoNode);

                try
                {
                    results = context.Graph.ExecuteQuery(getOntoDescrip);
                    if (results is SparqlResultSet)
                    {
                        if (!((SparqlResultSet)results).IsEmpty)
                        {
                            SparqlResult ontoInfo = ((SparqlResultSet)results)[0];

                            // Show rdfs:comment on the Ontology
                            if (ontoInfo.HasValue("description"))
                            {
                                INode descrip = ontoInfo["description"];
                                if (descrip.NodeType == NodeType.Literal)
                                {
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
                                    context.HtmlWriter.Write(((ILiteralNode)descrip).Value);
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();
                                }
                            }

                            // Show Author Information
                            if (ontoInfo.HasValue("creator"))
                            {
                                INode author     = ontoInfo["creator"];
                                INode authorName = ontoInfo["creatorName"];
                                context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
                                context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Em);
                                context.HtmlWriter.WriteEncodedText("Schema created by ");
                                if (author.NodeType == NodeType.Uri)
                                {
                                    context.HtmlWriter.AddAttribute("href", ((IUriNode)author).Uri.AbsoluteUri);
                                    context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri);
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
                                }
                                switch (authorName.NodeType)
                                {
                                case NodeType.Uri:
                                    context.HtmlWriter.WriteEncodedText(((IUriNode)authorName).Uri.AbsoluteUri);
                                    break;

                                case NodeType.Literal:
                                    context.HtmlWriter.WriteEncodedText(((ILiteralNode)authorName).Value);
                                    break;

                                default:
                                    context.HtmlWriter.WriteEncodedText(authorName.ToString());
                                    break;
                                }
                                if (author.NodeType == NodeType.Uri)
                                {
                                    context.HtmlWriter.RenderEndTag();
                                }
                                context.HtmlWriter.RenderEndTag();
                                context.HtmlWriter.RenderEndTag();
                                context.HtmlWriter.WriteLine();
                            }

                            // Show the Namespace information for the Schema
                            if (ontoInfo.HasValue("nsPrefix"))
                            {
                                if (ontoInfo["nsPrefix"].NodeType == NodeType.Literal && ontoInfo["nsUri"].NodeType == NodeType.Uri)
                                {
                                    // Add this QName to the QName Mapper so we can get nice QNames later on
                                    String prefix = ((ILiteralNode)ontoInfo["nsPrefix"]).Value;
                                    context.QNameMapper.AddNamespace(prefix, ((IUriNode)ontoInfo["nsUri"]).Uri);

                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4);
                                    context.HtmlWriter.WriteEncodedText("Preferred Namespace Definition");
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();

                                    // Show human readable description of preferred Namespace Settings
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
                                    context.HtmlWriter.WriteEncodedText("Preferred Namespace Prefix is ");
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Strong);
                                    context.HtmlWriter.WriteEncodedText(prefix);
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteEncodedText(" and preferred Namespace URI is ");
                                    context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Href, context.QNameMapper.GetNamespaceUri(prefix).AbsoluteUri);
                                    context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri);
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
                                    context.HtmlWriter.WriteEncodedText(context.QNameMapper.GetNamespaceUri(prefix).AbsoluteUri);
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.RenderEndTag();

                                    // RDF/XML Syntax
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H5);
                                    context.HtmlWriter.WriteEncodedText("RDF/XML Syntax");
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();
                                    context.HtmlWriter.AddStyleAttribute(HtmlTextWriterStyle.Width, "90%");
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Pre);
                                    int currIndent = context.HtmlWriter.Indent;
                                    context.HtmlWriter.Indent = 0;
                                    context.HtmlWriter.WriteEncodedText("<?xml version=\"1.0\" charset=\"utf-8\"?>");
                                    context.HtmlWriter.WriteLine();
                                    context.HtmlWriter.WriteEncodedText("<rdf:RDF xmlns:rdf=\"" + NamespaceMapper.RDF + "\" xmlns:" + prefix + "=\"" + context.UriFormatter.FormatUri(context.QNameMapper.GetNamespaceUri(prefix)) + "\">");
                                    context.HtmlWriter.WriteLine();
                                    context.HtmlWriter.WriteEncodedText("   <!-- Your RDF here... -->");
                                    context.HtmlWriter.WriteLine();
                                    context.HtmlWriter.WriteEncodedText("</rdf:RDF>");
                                    context.HtmlWriter.Indent = currIndent;
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();

                                    // Turtle/N3 Syntax
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H5);
                                    context.HtmlWriter.WriteEncodedText("Turtle/N3 Syntax");
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();
                                    context.HtmlWriter.AddStyleAttribute(HtmlTextWriterStyle.Width, "90%");
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Pre);
                                    currIndent = context.HtmlWriter.Indent;
                                    context.HtmlWriter.Indent = 0;
                                    context.HtmlWriter.WriteEncodedText("@prefix " + prefix + ": <" + context.UriFormatter.FormatUri(context.QNameMapper.GetNamespaceUri(prefix)) + "> .");
                                    context.HtmlWriter.Indent = currIndent;
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();

                                    // SPARQL Syntax
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H5);
                                    context.HtmlWriter.WriteEncodedText("SPARQL Syntax");
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();
                                    context.HtmlWriter.AddStyleAttribute(HtmlTextWriterStyle.Width, "90%");
                                    context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Pre);
                                    currIndent = context.HtmlWriter.Indent;
                                    context.HtmlWriter.Indent = 0;
                                    context.HtmlWriter.WriteEncodedText("PREFIX " + prefix + ": <" + context.UriFormatter.FormatUri(context.QNameMapper.GetNamespaceUri(prefix)) + ">");
                                    context.HtmlWriter.Indent = currIndent;
                                    context.HtmlWriter.RenderEndTag();
                                    context.HtmlWriter.WriteLine();
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new RdfOutputException("Tried to make a SPARQL Query to determine Schema Information but an unexpected Query Result was returned");
                    }
                }
                catch (RdfQueryException queryEx)
                {
                    throw new RdfOutputException("Tried to make a SPARQL Query to determine Schema Information but a Query Error occurred", queryEx);
                }
            }

            SparqlParameterizedString getPropertyRanges = new SparqlParameterizedString();

            getPropertyRanges.Namespaces = new NamespaceMapper();
            getPropertyRanges.Namespaces.AddNamespace("owl", UriFactory.Create(NamespaceMapper.OWL));
            getPropertyRanges.CommandText = "SELECT ?range WHERE { { @property rdfs:range ?range . FILTER(ISURI(?range)) } UNION { @property rdfs:range ?union . ?union owl:unionOf ?ranges . { ?ranges rdf:first ?range } UNION { ?ranges rdf:rest+/rdf:first ?range } } }";
            SparqlParameterizedString getPropertyDomains = new SparqlParameterizedString();

            getPropertyDomains.Namespaces  = getPropertyRanges.Namespaces;
            getPropertyDomains.CommandText = "SELECT ?domain WHERE { { @property rdfs:domain ?domain . FILTER(ISURI(?domain)) } UNION { @property rdfs:domain ?union . ?union owl:unionOf ?domains . { ?domains rdf:first ?domain } UNION { ?domains rdf:rest+/rdf:first ?domain } } }";

            // Show lists of all Classes and Properties in the Schema
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4);
            context.HtmlWriter.WriteEncodedText("Class and Property Summary");
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
            context.HtmlWriter.WriteEncodedText("This Schema defines the following classes:");
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();
            context.HtmlWriter.AddStyleAttribute("width", "90%");
            context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox);
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);

            // Get the Classes and Display
            SparqlParameterizedString getClasses = new SparqlParameterizedString();

            getClasses.Namespaces  = context.QNameMapper;
            getClasses.CommandText = "SELECT DISTINCT ?class WHERE { { ?class a rdfs:Class } UNION { ?class a owl:Class } FILTER(ISURI(?class)) } ORDER BY ?class";
            try
            {
                results = context.Graph.ExecuteQuery(getClasses);
                if (results is SparqlResultSet)
                {
                    SparqlResultSet rs = (SparqlResultSet)results;
                    for (int i = 0; i < rs.Count; i++)
                    {
                        SparqlResult r = rs[i];

                        // Get the QName and output a Link to an anchor that we'll generate later to let
                        // users jump to a Class/Property definition
                        String qname = context.NodeFormatter.Format(r["class"]);
                        context.HtmlWriter.AddAttribute("href", "#" + qname);
                        context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri);
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
                        context.HtmlWriter.WriteEncodedText(qname);
                        context.HtmlWriter.RenderEndTag();

                        if (i < rs.Count - 1)
                        {
                            context.HtmlWriter.WriteEncodedText(" , ");
                        }
                    }
                }
                else
                {
                    throw new RdfOutputException("Tried to make a SPARQL Query to find Classes in the Schema but an unexpected Query Result was returned");
                }
            }
            catch (RdfQueryException queryEx)
            {
                throw new RdfOutputException("Tried to make a SPARQL Query to find Classes in the Schema but a Query Error occurred", queryEx);
            }

            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
            context.HtmlWriter.WriteEncodedText("This Schema defines the following properties:");
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();
            context.HtmlWriter.AddStyleAttribute("width", "90%");
            context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox);
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);

            // Get the Properties and Display
            SparqlParameterizedString getProperties = new SparqlParameterizedString();

            getProperties.Namespaces  = context.QNameMapper;
            getProperties.CommandText = "SELECT DISTINCT ?property WHERE { { ?property a rdf:Property } UNION { ?property a owl:DatatypeProperty } UNION { ?property a owl:ObjectProperty } FILTER(ISURI(?property)) } ORDER BY ?property";
            try
            {
                results = context.Graph.ExecuteQuery(getProperties);
                if (results is SparqlResultSet)
                {
                    SparqlResultSet rs = (SparqlResultSet)results;
                    for (int i = 0; i < rs.Count; i++)
                    {
                        SparqlResult r = rs[i];

                        // Get the QName and output a Link to an anchor that we'll generate later to let
                        // users jump to a Class/Property definition
                        String qname = context.NodeFormatter.Format(r["property"]);
                        context.HtmlWriter.AddAttribute("href", "#" + qname);
                        context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassUri);
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
                        context.HtmlWriter.WriteEncodedText(qname);
                        context.HtmlWriter.RenderEndTag();

                        if (i < rs.Count - 1)
                        {
                            context.HtmlWriter.WriteEncodedText(" , ");
                        }
                    }
                }
                else
                {
                    throw new RdfOutputException("Tried to make a SPARQL Query to find Properties in the Schema but an unexpected Query Result was returned");
                }
            }
            catch (RdfQueryException queryEx)
            {
                throw new RdfOutputException("Tried to make a SPARQL Query to find Properties in the Schema but a Query Error occurred", queryEx);
            }

            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            // Show details for each class
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H3);
            context.HtmlWriter.WriteEncodedText("Classes");
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            // Now create the URI Nodes we need for the next stage of Output
            IUriNode rdfsDomain            = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "domain"));
            IUriNode rdfsRange             = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "range"));
            IUriNode rdfsSubClassOf        = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "subClassOf"));
            IUriNode rdfsSubPropertyOf     = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.RDFS + "subPropertyOf"));
            IUriNode owlDisjointClass      = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "disjointWith"));
            IUriNode owlEquivalentClass    = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "equivalentClass"));
            IUriNode owlEquivalentProperty = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "equivalentProperty"));
            IUriNode owlInverseProperty    = context.Graph.CreateUriNode(UriFactory.Create(NamespaceMapper.OWL + "inverseOf"));

            // Alter our previous getClasses query to get additional details
            getClasses.CommandText = "SELECT ?class (SAMPLE(?label) AS ?classLabel) (SAMPLE(?description) AS ?classDescription) WHERE { { ?class a rdfs:Class } UNION { ?class a owl:Class } FILTER(ISURI(?class)) OPTIONAL { ?class rdfs:label ?label } OPTIONAL { ?class rdfs:comment ?description } } GROUP BY ?class ORDER BY ?class";
            try
            {
                results = context.Graph.ExecuteQuery(getClasses);
                if (results is SparqlResultSet)
                {
                    foreach (SparqlResult r in (SparqlResultSet)results)
                    {
                        if (!r.HasValue("class"))
                        {
                            continue;
                        }
                        String qname = context.NodeFormatter.Format(r["class"]);

                        // Use a <div> for each Class
                        context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox);
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Div);

                        // Add the Anchor to which earlier Class summary links to
                        context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Name, qname);
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
                        context.HtmlWriter.RenderEndTag();

                        // Show Basic Class Information
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4);
                        context.HtmlWriter.WriteEncodedText("Class: " + qname);
                        context.HtmlWriter.RenderEndTag();

                        // Show "Local Name - Label"
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Em);
                        if (TurtleSpecsHelper.IsValidQName(qname))
                        {
                            context.HtmlWriter.WriteEncodedText(qname);
                        }
                        else
                        {
                            Uri temp = new Uri(qname, UriKind.RelativeOrAbsolute);
                            if (!temp.Fragment.Equals(String.Empty))
                            {
                                context.HtmlWriter.WriteEncodedText(temp.Fragment);
                            }
                            else
                            {
                                context.HtmlWriter.WriteEncodedText(temp.Segments.Last());
                            }
                        }
                        context.HtmlWriter.RenderEndTag();
                        if (r.HasValue("classLabel"))
                        {
                            if (r["classLabel"] != null && r["classLabel"].NodeType == NodeType.Literal)
                            {
                                context.HtmlWriter.WriteEncodedText(" - ");
                                context.HtmlWriter.WriteEncodedText(((ILiteralNode)r["classLabel"]).Value);
                            }
                        }
                        context.HtmlWriter.WriteLine();
                        context.HtmlWriter.WriteBreak();
                        context.HtmlWriter.WriteLine();

                        // Output further information about the class
                        IEnumerable <Triple> ts;

                        // Output any Subclasses
                        ts = context.Graph.GetTriplesWithSubjectPredicate(rdfsSubClassOf, r["class"]);
                        this.GenerateCaptionedInformation(context, "Has Sub Classes", ts, t => t.Object);

                        // Output Properties which have this as domain/range
                        ts = context.Graph.GetTriplesWithPredicateObject(rdfsDomain, r["class"]);
                        this.GenerateCaptionedInformation(context, "Properties Include", ts, t => t.Subject);
                        ts = context.Graph.GetTriplesWithPredicateObject(rdfsRange, r["class"]);
                        this.GenerateCaptionedInformation(context, "Used With", ts, t => t.Subject);

                        // Output any Equivalent Classes
                        ts = context.Graph.GetTriplesWithSubjectPredicate(r["class"], owlEquivalentClass).Concat(context.Graph.GetTriplesWithPredicateObject(owlEquivalentClass, r["class"]));
                        this.GenerateCaptionedInformation(context, "Equivalent Classes", ts, t => t.Subject.Equals(r["class"]) ? t.Object : t.Subject);
                        // Output any Disjoint Classes
                        ts = context.Graph.GetTriplesWithSubjectPredicate(r["class"], owlDisjointClass).Concat(context.Graph.GetTriplesWithPredicateObject(owlDisjointClass, r["class"]));
                        this.GenerateCaptionedInformation(context, "Disjoint Classes", ts, t => t.Subject.Equals(r["class"]) ? t.Object : t.Subject);

                        // Show the Class Description
                        if (r.HasValue("classDescription"))
                        {
                            if (r["classDescription"] != null && r["classDescription"].NodeType == NodeType.Literal)
                            {
                                context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
                                context.HtmlWriter.Write(((ILiteralNode)r["classDescription"]).Value);
                                context.HtmlWriter.RenderEndTag();
                            }
                        }

                        // End the </div> for the Class
                        context.HtmlWriter.RenderEndTag();
                        context.HtmlWriter.WriteLine();
                    }
                }
                else
                {
                    throw new RdfOutputException("Tried to make a SPARQL Query to get Class Information from the Schema but an unexpected Query Result was returned");
                }
            }
            catch (RdfQueryException queryEx)
            {
                throw new RdfOutputException("Tried to make a SPARQL Query to get Class Information from the Schema but a Query Error occurred", queryEx);
            }

            // Show details for each property
            context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H3);
            context.HtmlWriter.WriteEncodedText("Properties");
            context.HtmlWriter.RenderEndTag();
            context.HtmlWriter.WriteLine();

            // Alter our previous getProperties query to get additional details
            getProperties.CommandText = "SELECT ?property (SAMPLE(?label) AS ?propertyLabel) (SAMPLE(?description) AS ?propertyDescription) WHERE { { ?property a rdf:Property } UNION { ?property a owl:ObjectProperty } UNION { ?property a owl:DatatypeProperty } FILTER(ISURI(?property)) OPTIONAL { ?property rdfs:label ?label } OPTIONAL { ?property rdfs:comment ?description } } GROUP BY ?property ORDER BY ?property";
            try
            {
                results = context.Graph.ExecuteQuery(getProperties);
                if (results is SparqlResultSet)
                {
                    foreach (SparqlResult r in (SparqlResultSet)results)
                    {
                        if (!r.HasValue("property"))
                        {
                            continue;
                        }
                        String qname = context.NodeFormatter.Format(r["property"]);

                        // Use a <div> for each Property
                        context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClassBox);
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Div);

                        // Add the Anchor to which earlier Property summary links to
                        context.HtmlWriter.AddAttribute(HtmlTextWriterAttribute.Name, qname);
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.A);
                        context.HtmlWriter.RenderEndTag();

                        // Show Basic Property Information
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.H4);
                        context.HtmlWriter.WriteEncodedText("Property: " + qname);
                        context.HtmlWriter.RenderEndTag();

                        // Show "Local Name - Label"
                        context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.Em);
                        if (TurtleSpecsHelper.IsValidQName(qname))
                        {
                            context.HtmlWriter.WriteEncodedText(qname);
                        }
                        else
                        {
                            Uri temp = new Uri(qname, UriKind.RelativeOrAbsolute);
                            if (!temp.Fragment.Equals(String.Empty))
                            {
                                context.HtmlWriter.WriteEncodedText(temp.Fragment);
                            }
                            else
                            {
                                context.HtmlWriter.WriteEncodedText(temp.Segments.Last());
                            }
                        }
                        context.HtmlWriter.RenderEndTag();
                        if (r.HasValue("propertyLabel"))
                        {
                            if (r["propertyLabel"] != null && r["propertyLabel"].NodeType == NodeType.Literal)
                            {
                                context.HtmlWriter.WriteEncodedText(" - ");
                                context.HtmlWriter.WriteEncodedText(((ILiteralNode)r["propertyLabel"]).Value);
                            }
                        }
                        context.HtmlWriter.WriteLine();
                        context.HtmlWriter.WriteBreak();
                        context.HtmlWriter.WriteLine();

                        // Output further information about the property
                        IEnumerable <Triple> ts;

                        // Output any Subproperties
                        ts = context.Graph.GetTriplesWithSubjectPredicate(rdfsSubPropertyOf, r["property"]);
                        this.GenerateCaptionedInformation(context, "Has Sub Properties", ts, t => t.Object);

                        // Output Domain and Range
                        // ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], rdfsDomain);
                        // this.GenerateCaptionedInformation(context, "Has Domain", ts, t => t.Object);
                        // ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], rdfsRange);
                        // this.GenerateCaptionedInformation(context, "Has Range", ts, t => t.Object);
                        getPropertyDomains.SetParameter("property", r["property"]);
                        this.GenerateCaptionedInformation(context, "Has Domain", context.Graph.ExecuteQuery(getPropertyDomains) as SparqlResultSet, "domain");
                        getPropertyRanges.SetParameter("property", r["property"]);
                        this.GenerateCaptionedInformation(context, "Has Range", context.Graph.ExecuteQuery(getPropertyRanges) as SparqlResultSet, "range");

                        // Output any Equivalent Properties
                        ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], owlEquivalentProperty).Concat(context.Graph.GetTriplesWithPredicateObject(owlEquivalentProperty, r["property"]));
                        this.GenerateCaptionedInformation(context, "Equivalent Properties", ts, t => t.Subject.Equals(r["property"]) ? t.Object : t.Subject);
                        // Output any Disjoint Classes
                        ts = context.Graph.GetTriplesWithSubjectPredicate(r["property"], owlInverseProperty).Concat(context.Graph.GetTriplesWithPredicateObject(owlInverseProperty, r["property"]));
                        this.GenerateCaptionedInformation(context, "Inverse Property", ts, t => t.Subject.Equals(r["property"]) ? t.Object : t.Subject);

                        // Show the Property Description
                        if (r.HasValue("propertyDescription"))
                        {
                            if (r["propertyDescription"] != null && r["propertyDescription"].NodeType == NodeType.Literal)
                            {
                                context.HtmlWriter.RenderBeginTag(HtmlTextWriterTag.P);
                                context.HtmlWriter.Write(((ILiteralNode)r["propertyDescription"]).Value);
                                context.HtmlWriter.RenderEndTag();
                            }
                        }

                        // End the </div> for the Property
                        context.HtmlWriter.RenderEndTag();
                        context.HtmlWriter.WriteLine();
                    }
                }
                else
                {
                    throw new RdfOutputException("Tried to make a SPARQL Query to get Property Information from the Schema but an unexpected Query Result was returned");
                }
            }
            catch (RdfQueryException queryEx)
            {
                throw new RdfOutputException("Tried to make a SPARQL Query to get Property Information from the Schema but a Query Error occurred", queryEx);
            }


            // End of Page
            context.HtmlWriter.RenderEndTag(); //End Body
            context.HtmlWriter.RenderEndTag(); //End Html
        }
Exemplo n.º 15
0
        public void ParsingTurtleW3CComplexPrefixedNames9()
        {
            String input = @"p:AZazÀÖØöø˿Ͱͽ΄῾‌‍⁰↉Ⰰ⿕、ퟻ﨎ﷇﷰ￯𐀀󠇯";

            Assert.IsTrue(TurtleSpecsHelper.IsValidQName(input, TurtleSyntax.W3C));
        }
Exemplo n.º 16
0
        public void ParsingTurtleW3CComplexPrefixedNames2()
        {
            String input = "AZazÀÖØöø˿ͰͽͿ῿‌‍⁰↏Ⰰ⿯、퟿豈﷏ﷰ�𐀀�:o";

            Assert.IsTrue(TurtleSpecsHelper.IsValidQName(input, TurtleSyntax.W3C));
        }
Exemplo n.º 17
0
        /// <summary>
        /// Formats a Literal Node as a String.
        /// </summary>
        /// <param name="l">Literal Node.</param>
        /// <param name="segment">Triple Segment.</param>
        /// <returns></returns>
        protected override string FormatLiteralNode(ILiteralNode l, TripleSegment?segment)
        {
            var  output = new StringBuilder();
            bool longlit, plainlit;

            longlit  = TurtleSpecsHelper.IsLongLiteral(l.Value);
            plainlit = TurtleSpecsHelper.IsValidPlainLiteral(l.Value, l.DataType, TurtleSyntax.Original);

            if (plainlit)
            {
                if (TurtleSpecsHelper.IsValidDecimal(l.Value) && l.Value.EndsWith("."))
                {
                    // Ensure we strip the trailing dot of any xsd:decimal and add a datatype definition
                    output.Append('"');
                    output.Append(l.Value.Substring(0, l.Value.Length - 1));
                    output.Append("\"^^<");
                    output.Append(FormatUri(XmlSpecsHelper.XmlSchemaDataTypeDecimal));
                    output.Append('>');
                }
                else
                {
                    // Otherwise just write out the value
                    output.Append(l.Value);
                }
                // For integers ensure we insert a space after the literal to ensure it can't ever be confused with a decimal
                if (TurtleSpecsHelper.IsValidInteger(l.Value))
                {
                    output.Append(' ');
                }
            }
            else
            {
                output.Append('"');
                if (longlit)
                {
                    output.Append("\"\"");
                }

                var value = l.Value;
                value = longlit ? Escape(value, _longLitMustEscape) : Escape(value, _litMustEscape);

                output.Append(value);
                output.Append('"');
                if (longlit)
                {
                    output.Append("\"\"");
                }

                if (!l.Language.Equals(string.Empty))
                {
                    output.Append('@');
                    output.Append(l.Language.ToLower());
                }
                else if (l.DataType != null)
                {
                    output.Append("^^");
                    if (_qnameMapper.ReduceToQName(l.DataType.AbsoluteUri, out var qname))
                    {
                        if (TurtleSpecsHelper.IsValidQName(qname))
                        {
                            output.Append(qname);
                        }
                        else
                        {
                            output.Append('<');
                            output.Append(FormatUri(l.DataType));
                            output.Append('>');
                        }
                    }
                    else
                    {
                        output.Append('<');
                        output.Append(FormatUri(l.DataType));
                        output.Append('>');
                    }
                }
            }

            return(output.ToString());
        }
Exemplo n.º 18
0
        internal void Parse(INode n, XsdtType x)
        {
            switch (n.NodeType)
            {
            case NodeType.Uri:
                x.NetType      = typeof(Uri);
                x.ValuePart    = n.ToString();
                x.XsdtTypeName = XsdtPrimitiveDataType.XsdtAnyUri;
                ConvertValueToNet(x);
                break;

            case NodeType.Literal:
                ILiteralNode lit = (ILiteralNode)n;

                x.XsdtTypeName = XsdtPrimitiveDataType.XsdtUnknown;
                x.ValuePart    = lit.Value;

                if (lit.DataType != null)
                {
                    if (lit.DataType.ToString().StartsWith(NamespaceMapper.XMLSCHEMA))
                    {
                        x.TypePart = lit.DataType.ToString().Substring(NamespaceMapper.XMLSCHEMA.Length);
                    }
                    else
                    {
                        x.TypePart = "string";
                    }
                }
                else
                {
                    if (TurtleSpecsHelper.IsValidPlainLiteral(lit.Value))
                    {
                        if (TurtleSpecsHelper.IsValidInteger(lit.Value))
                        {
                            x.TypePart = "integer";
                        }
                        else if (TurtleSpecsHelper.IsValidDecimal(lit.Value))
                        {
                            x.TypePart = "decimal";
                        }
                        else if (TurtleSpecsHelper.IsValidDouble(lit.Value))
                        {
                            x.TypePart = "double";
                        }
                        else
                        {
                            x.TypePart = "boolean";
                        }
                    }
                    else
                    {
                        x.TypePart = "string";
                    }
                }

                foreach (int i in Enum.GetValues(typeof(XsdtPrimitiveDataType)))
                {
                    var           result = (XsdtPrimitiveDataType)i;
                    XsdtAttribute attr   = GetXsdtAttrFor(result);
                    if (attr.TypeUri == x.TypePart)
                    {
                        x.XsdtTypeName = result;
                    }
                }

                if (TypeLookup.ContainsKey(x.XsdtTypeName))
                {
                    x.NetType = TypeLookup[x.XsdtTypeName];
                }
                else
                {
                    throw new LinqToRdfException("XsdtTypeConverter does not know how to convert the XML Schema Datatype " + x.TypePart);
                }

                ConvertValueToNet(x);
                break;

            default:
                throw new LinqToRdfException("XsdtTypeConverter can only convert URI and Literal Nodes");
            }
        }
 public void ParsingTurtleOriginalPrefixedNames1()
 {
     Assert.IsTrue(TurtleSpecsHelper.IsValidQName(":a1", TurtleSyntax.Original));
 }
Exemplo n.º 20
0
        public void ParsingTurtleW3CComplexPrefixedNames8()
        {
            String input = ":%bb";

            Assert.IsTrue(TurtleSpecsHelper.IsValidQName(input, TurtleSyntax.W3C));
        }
Exemplo n.º 21
0
        /// <summary>
        /// Formats a Literal Node
        /// </summary>
        /// <param name="lit">Literal Node</param>
        /// <param name="segment">Triple Segment</param>
        /// <returns></returns>
        protected override string FormatLiteralNode(ILiteralNode lit, TripleSegment?segment)
        {
            StringBuilder output = new StringBuilder();

            if (TurtleSpecsHelper.IsValidPlainLiteral(lit.Value, lit.DataType, TurtleSyntax.Original))
            {
                output.Append(lit.Value);
            }
            else
            {
                String value = lit.Value;

                if (TurtleSpecsHelper.IsLongLiteral(value))
                {
                    value = this.Escape(value, this._delimEscapes);

                    //If there are no wrapper characters then we must escape the deliminator
                    if (value.Contains(this._deliminatorChar))
                    {
                        if (this._literalWrapperChar == null && this._longLiteralWrapperChar == null)
                        {
                            //Replace the deliminator
                            value = value.Replace(new String(new char[] { this._deliminatorChar }), new String(new char[] { this._escapeChar, this._deliminatorChar }));
                        }
                    }

                    //Apply appropriate wrapper characters
                    if (this._longLiteralWrapperChar != null)
                    {
                        output.Append(this._longLiteralWrapperChar + value + this._longLiteralWrapperChar);
                    }
                    else if (this._literalWrapperChar != null)
                    {
                        output.Append(this._literalWrapperChar + value + this._literalWrapperChar);
                    }
                    else
                    {
                        output.Append(value);
                    }
                }
                else
                {
                    //Replace the deliminator
                    value = this.Escape(value, this._delimEscapes);

                    //Apply appropriate wrapper characters
                    if (this._literalWrapperChar != null)
                    {
                        output.Append(this._literalWrapperChar + value + this._literalWrapperChar);
                    }
                    else
                    {
                        output.Append(value);
                    }
                }

                if (this._fullLiteralOutput)
                {
                    if (!lit.Language.Equals(String.Empty))
                    {
                        output.Append("@" + lit.Language.ToLower());
                    }
                    else if (lit.DataType != null)
                    {
                        output.Append("^^");
                        if (this._uriStartChar != null)
                        {
                            output.Append(this._uriStartChar);
                        }
                        if (this._uriEndChar != null)
                        {
                            output.Append(this.FormatUri(lit.DataType));
                            output.Append(this._uriEndChar);
                        }
                        else
                        {
                            output.Append(this.FormatUri(lit.DataType));
                        }
                    }
                }
            }
            return(output.ToString());
        }
Exemplo n.º 22
0
        public void ParsingTurtleW3CNumericLiterals1()
        {
            String input = "123.E+1";

            Assert.IsTrue(TurtleSpecsHelper.IsValidDouble(input));
        }
Exemplo n.º 23
0
 /// <summary>
 /// Determines whether a QName is valid
 /// </summary>
 /// <param name="value">Value</param>
 /// <returns></returns>
 protected virtual bool IsValidQName(String value)
 {
     return(TurtleSpecsHelper.IsValidQName(value));
 }
        private IToken TryGetNumericLiteral()
        {
            bool dotoccurred  = false;
            bool expoccurred  = false;
            bool signoccurred = false;

            if (Length == 1)
            {
                dotoccurred = true;
            }

            char next = Peek();

            while (Char.IsDigit(next) || next == '-' || next == '+' || next == 'e' || next == 'E' || (next == '.' && !dotoccurred))
            {
                // Consume the Character
                ConsumeCharacter();

                if (next == '-' || next == '+')
                {
                    if (signoccurred || expoccurred)
                    {
                        char last = Value[Value.Length - 2];
                        if (expoccurred)
                        {
                            if (last != 'e' && last != 'E')
                            {
                                // Can't occur here as isn't directly after the exponent
                                throw UnexpectedCharacter(next, "The +/- Sign can only occur at the start of a Numeric Literal or at the start of the Exponent");
                            }
                        }
                        else
                        {
                            // Negative sign already seen
                            throw UnexpectedCharacter(next, "The +/- Sign can only occur at the start of a Numeric Literal or at the start of the Exponent");
                        }
                    }
                    else
                    {
                        signoccurred = true;

                        // Check this is at the start of the string
                        if (Length > 1)
                        {
                            throw UnexpectedCharacter(next, "The +/- Sign can only occur at the start of a Numeric Literal or at the start of the Exponent");
                        }
                    }
                }
                else if (next == 'e' || next == 'E')
                {
                    if (expoccurred)
                    {
                        // Exponent already seen
                        throw Error("Unexpected Character (Code " + (int)next + " e\nThe Exponent specifier can only occur once in a Numeric Literal");
                    }
                    else
                    {
                        expoccurred = true;

                        // Check that it isn't the start of the string
                        if (Length == 1)
                        {
                            throw UnexpectedCharacter(next, "The Exponent specifier cannot occur at the start of a Numeric Literal");
                        }
                    }
                }
                else if (next == '.')
                {
                    dotoccurred = true;
                }

                next = Peek();
            }

            // Validate the final result
            if (Value.EndsWith("."))
            {
                Backtrack();
            }
            if (!TurtleSpecsHelper.IsValidPlainLiteral(Value, TurtleSyntax.Original))
            {
                throw Error("The format of the Numeric Literal '" + Value + "' is not valid!");
            }

            // Return the Token
            LastTokenType = Token.PLAINLITERAL;
            return(new PlainLiteralToken(Value, CurrentLine, StartPosition, EndPosition));
        }
        private IToken TryGetPlainLiteralOrQName()
        {
            char next = Peek();

            if (!_keywordsmode)
            {
                #region Non-Keywords Mode

                // Not in Keywords Mode
                bool colonoccurred = false;
                while (Char.IsLetterOrDigit(next) || next == ':' || next == '-' || next == '_')
                {
                    // Consume Character
                    ConsumeCharacter();

                    if (next == ':')
                    {
                        if (colonoccurred)
                        {
                            // Can't contain more than 1 Colon
                            throw Error("Unexpected Character (Code " + (int)next + " :\nThe Colon Character can only occur once in a QName");
                        }
                        else
                        {
                            colonoccurred = true;
                        }
                    }

                    next = Peek();
                }

                // Validate
                String value = Value;

                // If it ends in a trailing . then we need to backtrack
                if (value.EndsWith("."))
                {
                    Backtrack();
                    value = value.Substring(0, value.Length - 1);
                }

                if (value.Equals("a"))
                {
                    // Keyword 'a'
                    LastTokenType = Token.KEYWORDA;
                    return(new KeywordAToken(CurrentLine, StartPosition));
                }
                else if (value.Equals("is"))
                {
                    // Keyword 'is'
                    LastTokenType = Token.KEYWORDIS;
                    return(new KeywordIsToken(CurrentLine, StartPosition));
                }
                else if (value.Equals("of"))
                {
                    // Keyword 'of'
                    LastTokenType = Token.KEYWORDOF;
                    return(new KeywordOfToken(CurrentLine, StartPosition));
                }
                else if (TurtleSpecsHelper.IsValidPlainLiteral(value, TurtleSyntax.Original))
                {
                    // Other Valid Plain Literal
                    LastTokenType = Token.PLAINLITERAL;
                    return(new PlainLiteralToken(value, CurrentLine, StartPosition, EndPosition));
                }
                else if (IsValidQName(value) && value.Contains(":"))
                {
                    // Valid QName
                    // Note that in the above condition we require a : since without Keywords mode
                    // all QNames must be in a Namespace
                    if (value.StartsWith("_:"))
                    {
                        // A Blank Node QName
                        LastTokenType = Token.BLANKNODEWITHID;
                        return(new BlankNodeWithIDToken(value, CurrentLine, StartPosition, EndPosition));
                    }
                    else
                    {
                        // Normal QName
                        LastTokenType = Token.QNAME;
                        return(new QNameToken(value, CurrentLine, StartPosition, EndPosition));
                    }
                }
                else
                {
                    // Not Valid
                    throw Error("The value '" + value + "' is not valid as a Plain Literal or QName");
                }

                #endregion
            }
            else
            {
                #region Keywords Mode

                // Since we're in Keywords Mode this is actually a QName
                // UNLESS it's in the Keywords list

                bool colonoccurred = false;

                while (Char.IsLetterOrDigit(next) || next == '_' || next == '-' || next == ':')
                {
                    // Consume
                    ConsumeCharacter();

                    if (next == ':')
                    {
                        if (colonoccurred)
                        {
                            // Can't contain more than 1 Colon
                            throw Error("Unexpected Character (Code " + (int)next + " :\nThe Colon Character can only occur once in a QName");
                        }
                        else
                        {
                            colonoccurred = true;
                        }
                    }

                    next = Peek();
                }

                // Validate
                String value = Value;

                // If it ends in a trailing . then we need to backtrack
                if (value.EndsWith("."))
                {
                    Backtrack();
                    value = value.Substring(0, value.Length - 1);
                }

                if (_keywords.Contains(value))
                {
                    // A Custom Keyword
                    LastTokenType = Token.KEYWORDCUSTOM;
                    return(new CustomKeywordToken(value, CurrentLine, StartPosition, EndPosition));
                }
                else if (!IsValidQName(value))
                {
                    // Not a valid QName
                    throw Error("The value '" + value + "' is not valid as a QName");
                }
                else if (value.StartsWith("_:"))
                {
                    // A Blank Node QName
                    LastTokenType = Token.BLANKNODEWITHID;
                    return(new BlankNodeWithIDToken(value, CurrentLine, StartPosition, EndPosition));
                }
                else
                {
                    // Return the QName
                    LastTokenType = Token.QNAME;

                    // If no Colon need to append it to the front to make a QName in the Default namespace
                    if (!colonoccurred)
                    {
                        value = ":" + value;
                    }

                    return(new QNameToken(value, CurrentLine, StartPosition, EndPosition));
                }

                #endregion
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// Generates the Turtle Syntax for the Graph
        /// </summary>
        private void GenerateOutput(CompressingTurtleWriterContext context)
        {
            //Create the Header
            //Base Directive
            if (context.Graph.BaseUri != null)
            {
                context.Output.WriteLine("@base <" + context.UriFormatter.FormatUri(context.Graph.BaseUri) + ">.");
                context.Output.WriteLine();
            }
            //Prefix Directives
            foreach (String prefix in context.Graph.NamespaceMap.Prefixes)
            {
                if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                {
                    if (!prefix.Equals(String.Empty))
                    {
                        context.Output.WriteLine("@prefix " + prefix + ": <" + context.UriFormatter.FormatUri(context.Graph.NamespaceMap.GetNamespaceUri(prefix)) + ">.");
                    }
                    else
                    {
                        context.Output.WriteLine("@prefix : <" + context.UriFormatter.FormatUri(context.Graph.NamespaceMap.GetNamespaceUri(String.Empty)) + ">.");
                    }
                }
            }
            context.Output.WriteLine();

            //Decide on the Write Mode to use
            bool   hiSpeed   = false;
            double subjNodes = context.Graph.Triples.SubjectNodes.Count();
            double triples   = context.Graph.Triples.Count;

            if ((subjNodes / triples) > 0.75)
            {
                hiSpeed = true;
            }

            if (context.CompressionLevel == WriterCompressionLevel.None || (hiSpeed && context.HighSpeedModePermitted))
            {
                this.RaiseWarning("High Speed Write Mode in use - minimal syntax compression will be used");
                context.CompressionLevel = WriterCompressionLevel.Minimal;
                context.NodeFormatter    = new UncompressedTurtleFormatter();

                foreach (Triple t in context.Graph.Triples)
                {
                    context.Output.WriteLine(this.GenerateTripleOutput(context, t));
                }
            }
            else
            {
                if (context.CompressionLevel >= WriterCompressionLevel.More)
                {
                    WriterHelper.FindCollections(context);
                }

                //Get the Triples as a Sorted List
                List <Triple> ts = context.Graph.Triples.Where(t => !context.TriplesDone.Contains(t)).ToList();
                ts.Sort(new FullTripleComparer(new FastNodeComparer()));

                //Variables we need to track our writing
                INode lastSubj, lastPred;
                lastSubj = lastPred = null;
                int    subjIndent = 0, predIndent = 0;
                String temp;

                for (int i = 0; i < ts.Count; i++)
                {
                    Triple t = ts[i];

                    if (lastSubj == null || !t.Subject.Equals(lastSubj))
                    {
                        //Terminate previous Triples
                        if (lastSubj != null)
                        {
                            context.Output.WriteLine(".");
                        }

                        //Start a new set of Triples
                        temp = this.GenerateNodeOutput(context, t.Subject, TripleSegment.Subject, 0);
                        context.Output.Write(temp);
                        context.Output.Write(" ");
                        if (temp.Contains('\n'))
                        {
                            subjIndent = temp.Split('\n').Last().Length + 1;
                        }
                        else
                        {
                            subjIndent = temp.Length + 1;
                        }
                        lastSubj = t.Subject;

                        //Write the first Predicate
                        temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate, subjIndent);
                        context.Output.Write(temp);
                        context.Output.Write(" ");
                        predIndent = temp.Length + 1;
                        lastPred   = t.Predicate;
                    }
                    else if (lastPred == null || !t.Predicate.Equals(lastPred))
                    {
                        //Terminate previous Predicate Object list
                        context.Output.WriteLine(";");

                        if (context.PrettyPrint)
                        {
                            context.Output.Write(new String(' ', subjIndent));
                        }

                        //Write the next Predicate
                        temp = this.GenerateNodeOutput(context, t.Predicate, TripleSegment.Predicate, subjIndent);
                        context.Output.Write(temp);
                        context.Output.Write(" ");
                        predIndent = temp.Length + 1;
                        lastPred   = t.Predicate;
                    }
                    else
                    {
                        //Continue Object List
                        context.Output.WriteLine(",");

                        if (context.PrettyPrint)
                        {
                            context.Output.Write(new String(' ', subjIndent + predIndent));
                        }
                    }

                    //Write the Object
                    context.Output.Write(this.GenerateNodeOutput(context, t.Object, TripleSegment.Object, subjIndent + predIndent));
                }

                //Terminate Triples
                if (ts.Count > 0)
                {
                    context.Output.WriteLine(".");
                }

                return;
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Saves a Store in TriG (Turtle with Named Graphs) format
        /// </summary>
        /// <param name="store">Store to save</param>
        /// <param name="writer">Writer to save to</param>
        /// <param name="leaveOpen">Boolean flag indicating if <paramref name="writer"/> should be left open after the store is saved</param>
        public void Save(ITripleStore store, TextWriter writer, bool leaveOpen)
        {
            if (store == null)
            {
                throw new RdfOutputException("Cannot output a null Triple Store");
            }
            if (writer == null)
            {
                throw new RdfOutputException("Cannot output to a null writer");
            }

            TriGWriterContext context = new TriGWriterContext(store, writer, _prettyprint, _allowHiSpeed, _compressionLevel, _n3compat);

            // Check there's something to do
            if (context.Store.Graphs.Count == 0)
            {
                if (!leaveOpen)
                {
                    context.Output.Close();
                }
                return;
            }

            // Write the Header of the File
            foreach (var g in context.Store.Graphs)
            {
                context.NamespaceMap.Import(g.NamespaceMap);
            }
            if (context.CompressionLevel > WriterCompressionLevel.None)
            {
                // Only add @prefix declarations if compression is enabled
                context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap);
                foreach (string prefix in context.NamespaceMap.Prefixes)
                {
                    if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                    {
                        context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">.");
                    }
                }
                context.Output.WriteLine();
            }
            else
            {
                context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true));
            }

            if (_useMultiThreading)
            {
                // Standard Multi-Threaded Writing

                // Queue the Graphs to be written
                foreach (IGraph g in context.Store.Graphs)
                {
                    context.Add(g.BaseUri);
                }

                // Start making the async calls
                List <IAsyncResult> results = new List <IAsyncResult>();
                SaveGraphsDelegate  d       = new SaveGraphsDelegate(SaveGraphs);
                for (int i = 0; i < _threads; i++)
                {
                    results.Add(d.BeginInvoke(context, null, null));
                }

                // Wait for all the async calls to complete
                WaitHandle.WaitAll(results.Select(r => r.AsyncWaitHandle).ToArray());
                RdfThreadedOutputException outputEx = new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG"));
                foreach (IAsyncResult result in results)
                {
                    try
                    {
                        d.EndInvoke(result);
                    }
                    catch (Exception ex)
                    {
                        outputEx.AddException(ex);
                    }
                }
                // Make sure to close the output
                if (!leaveOpen)
                {
                    context.Output.Close();
                }

                // If there were any errors we'll throw an RdfThreadedOutputException now
                if (outputEx.InnerExceptions.Any())
                {
                    throw outputEx;
                }
            }
            else
            {
                try
                {
                    // Optional Single Threaded Writing
                    foreach (IGraph g in store.Graphs)
                    {
                        TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted);
                        if (context.CompressionLevel > WriterCompressionLevel.None)
                        {
                            graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper);
                        }
                        else
                        {
                            graphContext.NodeFormatter = new UncompressedTurtleFormatter();
                        }
                        context.Output.WriteLine(GenerateGraphOutput(context, graphContext));
                    }

                    // Make sure to close the output
                    if (!leaveOpen)
                    {
                        context.Output.Close();
                    }
                }
                catch
                {
                    try
                    {
                        // Close the output
                        if (!leaveOpen)
                        {
                            context.Output.Close();
                        }
                    }
                    catch
                    {
                        // No catch actions, just cleaning up the output stream
                    }
                    throw;
                }
            }
        }