/// <summary>
 /// Adds the Standard Custom Headers that dotNetRDF attaches to all responses from it's Handlers
 /// </summary>
 /// <param name="context">HTTP Context</param>
 /// <param name="config">Handler Configuration</param>
 public static void AddStandardHeaders(HttpContext context, BaseHandlerConfiguration config)
 {
     try
     {
         context.Response.Headers.Add("X-dotNetRDF-Version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
     }
     catch (PlatformNotSupportedException)
     {
         context.Response.AddHeader("X-dotNetRDF-Version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
     }
     if (config.IsCorsEnabled) AddCorsHeaders(context);
 }
        /// <summary>
        /// Handles errors in processing SPARQL Update Requests
        /// </summary>
        /// <param name="context">Context of the HTTP Request</param>
        /// <param name="config">Handler Configuration</param>
        /// <param name="title">Error title</param>
        /// <param name="update">SPARQL Update</param>
        /// <param name="ex">Error</param>
        /// <param name="statusCode">HTTP Status Code to return</param>
        public static void HandleUpdateErrors(HttpContext context, BaseHandlerConfiguration config, String title, String update, Exception ex, int statusCode)
        {
            //Clear any existing Response
            context.Response.Clear();

            if (config != null)
            {
                if (!config.ShowErrors)
                {
                    context.Response.StatusCode = statusCode;
                    return;
                }
            }

            //Set to Plain Text output and report the error
            context.Response.ContentEncoding = System.Text.Encoding.UTF8;
            context.Response.ContentType = "text/plain";

            //Error Title
            context.Response.Write(title + "\n");
            context.Response.Write(new String('-', title.Length) + "\n\n");

            //Output Query with Line Numbers
            if (update != null && !update.Equals(String.Empty))
            {
                String[] lines = update.Split('\n');
                for (int l = 0; l < lines.Length; l++)
                {
                    context.Response.Write((l + 1) + ": " + lines[l] + "\n");
                }
                context.Response.Write("\n\n");
            }

            //Error Message
            context.Response.Write(ex.Message + "\n");

#if DEBUG
            //Stack Trace only when Debug build
            context.Response.Write(ex.StackTrace + "\n\n");
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
                context.Response.Write(ex.Message + "\n");
                context.Response.Write(ex.StackTrace + "\n\n");
            }
#endif
        }
        public static void ApplyWriterOptions(Object writer, BaseHandlerConfiguration config)
        {
            if (config != null)
            {
                //Apply Stylesheet to HTML writers
                if (writer is IHtmlWriter)
                {
                    ((IHtmlWriter)writer).Stylesheet = config.Stylesheet;
                }

                //Apply Compression Options
                if (writer is ICompressingWriter)
                {
                    ((ICompressingWriter)writer).CompressionLevel = config.WriterCompressionLevel;
                }
                if (writer is INamespaceWriter)
                {
                    ((INamespaceWriter)writer).DefaultNamespaces = config.DefaultNamespaces;
                }
                if (writer is IDtdWriter)
                {
                    ((IDtdWriter)writer).UseDtd = config.WriterUseDtds;
                }
                if (writer is IHighSpeedWriter)
                {
                    ((IHighSpeedWriter)writer).HighSpeedModePermitted = config.WriterHighSpeedMode;
                }
                if (writer is IPrettyPrintingWriter)
                {
                    ((IPrettyPrintingWriter)writer).PrettyPrintMode = config.WriterPrettyPrinting;
                }
            }
        }
 /// <summary>
 /// Handles errors in processing SPARQL Update Requests
 /// </summary>
 /// <param name="context">Context of the HTTP Request</param>
 /// <param name="config">Handler Configuration</param>
 /// <param name="title">Error title</param>
 /// <param name="update">SPARQL Update</param>
 /// <param name="ex">Error</param>
 public static void HandleUpdateErrors(HttpContext context, BaseHandlerConfiguration config, String title, String update, Exception ex)
 {
     HandleUpdateErrors(context, config, title, update, ex, (int)HttpStatusCode.InternalServerError);
 }
        /// <summary>
        /// Helper function which returns the Results (Graph/Triple Store/SPARQL Results) back to the Client in one of their accepted formats
        /// </summary>
        /// <param name="context">Context of the HTTP Request</param>
        /// <param name="result">Results of the Sparql Query</param>
        /// <param name="config">Handler Configuration</param>
        public static void SendToClient(HttpContext context, Object result, BaseHandlerConfiguration config)
        {
            MimeTypeDefinition definition = null;
            String ctype = "text/plain";
            String[] acceptTypes = HandlerHelper.GetAcceptTypes(context);

            //Return the Results
            if (result is SparqlResultSet)
            {
                ISparqlResultsWriter sparqlwriter = null;      
       
                //Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes != null)
                {
                    definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteSparqlResults);
                } 
                //Try and get the registered Definition for SPARQL Results XML
                if (definition == null)
                {
                    definition = MimeTypesHelper.GetDefinitions(MimeTypesHelper.SparqlXml[0]).FirstOrDefault();
                }
                //If Definition is still null create a temporary definition
                if (definition == null)
                {
                    definition = new MimeTypeDefinition("SPARQL Results XML", MimeTypesHelper.SparqlXml, Enumerable.Empty<String>());
                    definition.SparqlResultsWriterType = typeof(VDS.RDF.Writing.SparqlXmlWriter);
                }
                
                //Set up the Writer appropriately
                sparqlwriter = definition.GetSparqlResultsWriter();

                context.Response.ContentType = definition.CanonicalMimeType;
                HandlerHelper.ApplyWriterOptions(sparqlwriter, config);

                //Clear any existing Response
                context.Response.Clear();

                //Send Result Set to Client
                context.Response.ContentEncoding = definition.Encoding;
                sparqlwriter.Save((SparqlResultSet)result, new StreamWriter(context.Response.OutputStream, definition.Encoding));
            }
            else if (result is IGraph)
            {
                IRdfWriter rdfwriter = null;

                //Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes != null)
                {
                    definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteRdf);
                }
                if (definition == null)
                {
                    //If no appropriate definition then use the GetWriter method instead
                    rdfwriter = MimeTypesHelper.GetWriter(acceptTypes, out ctype);
                }
                else
                {
                    rdfwriter = definition.GetRdfWriter();
                }

                //Setup the writer
                if (definition != null) ctype = definition.CanonicalMimeType;
                context.Response.ContentType = ctype;
                HandlerHelper.ApplyWriterOptions(rdfwriter, config);

                //Clear any existing Response
                context.Response.Clear();

                //Send Graph to Client
                if (definition != null)
                {
                    context.Response.ContentEncoding = definition.Encoding;
                    rdfwriter.Save((IGraph)result, new StreamWriter(context.Response.OutputStream, definition.Encoding));
                }
                else 
                {
                    rdfwriter.Save((IGraph)result, new StreamWriter(context.Response.OutputStream));
                }
            }
            else if (result is ITripleStore)
            {
                IStoreWriter storewriter = null;

                //Try and get a MIME Type Definition using the HTTP Requests Accept Header
                if (acceptTypes != null)
                {
                    definition = MimeTypesHelper.GetDefinitions(acceptTypes).FirstOrDefault(d => d.CanWriteRdfDatasets);
                    storewriter = definition.GetRdfDatasetWriter();
                } 
                if (definition == null)
                {
                    //If no appropriate definition then use the GetStoreWriter method instead
                    storewriter = MimeTypesHelper.GetStoreWriter(acceptTypes, out ctype);
                }

                //Setup the writer
                if (definition != null) ctype = definition.CanonicalMimeType;
                context.Response.ContentType = ctype;
                HandlerHelper.ApplyWriterOptions(storewriter, config);

                //Clear any existing Response
                context.Response.Clear();

                //Send Triple Store to Client
                if (definition != null) 
                {
                    context.Response.ContentEncoding = definition.Encoding;
                    storewriter.Save((ITripleStore)result, new VDS.RDF.Storage.Params.StreamParams(context.Response.OutputStream, definition.Encoding));
                } 
                else
                {
                    storewriter.Save((ITripleStore)result, new VDS.RDF.Storage.Params.StreamParams(context.Response.OutputStream));
                }
            }
            else if (result is ISparqlDataset)
            {
                //Wrap in a Triple Store and then call self so the Triple Store writing branch of this if gets called instead
                TripleStore store = new TripleStore(new DatasetGraphCollection((ISparqlDataset)result));
                HandlerHelper.SendToClient(context, store, config);
            }
            else
            {
                throw new RdfOutputException("Unexpected Result Object of Type '" + result.GetType().ToString() + "' returned - unable to write Objects of this Type to the HTTP Response");
            }
        }