Exemple #1
0
        /// <summary>
        /// Attempts to load a RDF dataset asynchronously from the given URI using a RDF Handler
        /// </summary>
        /// <param name="handler">RDF Handler to use</param>
        /// <param name="u">URI to attempt to get a RDF dataset from</param>
        /// <param name="parser">Parser to use to parse the RDF dataset</param>
        /// <param name="callback">Callback to invoke when the operation completes</param>
        /// <param name="state">State to pass to the callback</param>
        /// <remarks>
        /// <para>
        /// If the <paramref name="parser"/> parameter is set to null then this method attempts to select the relevant Store Parser based on the Content Type header returned in the HTTP Response.
        /// </para>
        /// <para>
        /// If you know ahead of time the Content Type you can explicitly pass in the parser to use.
        /// </para>
        /// </remarks>
        public static void Load(IRdfHandler handler, Uri u, IStoreReader parser, RdfHandlerCallback callback, Object state)
        {
            if (u == null)
            {
                throw new RdfParseException("Cannot read a RDF dataset from a null URI");
            }
            if (handler == null)
            {
                throw new RdfParseException("Cannot read a RDF dataset using a null RDF handler");
            }

            try
            {
#if SILVERLIGHT
                if (u.IsFile())
#else
                if (u.IsFile)
#endif
                {
                    //Invoke FileLoader instead
                    RaiseWarning("This is a file: URI so invoking the FileLoader instead");
                    if (Path.DirectorySeparatorChar == '/')
                    {
                        FileLoader.Load(handler, u.ToString().Substring(7), parser);
                    }
                    else
                    {
                        FileLoader.Load(handler, u.ToString().Substring(8), parser);
                    }
                    //FileLoader.Load() will run synchronously so once this completes we can invoke the callback
                    callback(handler, state);
                    return;
                }
                if (u.Scheme.Equals("data"))
                {
                    //Invoke DataUriLoader instead
                    RaiseWarning("This is a data: URI so invoking the DataUriLoader instead");
                    DataUriLoader.Load(handler, u);
                    //After DataUriLoader.Load() has run (which happens synchronously) can invoke the callback
                    callback(handler, state);
                    return;
                }

                //Sanitise the URI to remove any Fragment ID
                u = Tools.StripUriFragment(u);

                //Setup the Request
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(u);

                //Want to ask for RDF dataset formats
                if (parser != null)
                {
                    //If a non-null parser set up a HTTP Header that is just for the given parser
                    request.Accept = MimeTypesHelper.CustomHttpAcceptHeader(parser);
                }
                else
                {
                    request.Accept = MimeTypesHelper.HttpAcceptHeader;
                }

                //Use HTTP GET
                request.Method = "GET";
#if !SILVERLIGHT
                request.Timeout = Options.UriLoaderTimeout;
#endif
                if (_userAgent != null && !_userAgent.Equals(String.Empty))
                {
                    request.UserAgent = _userAgent;
                }

#if DEBUG
                //HTTP Debugging
                if (Options.HttpDebugging)
                {
                    Tools.HttpDebugRequest(request);
                }
#endif

                request.BeginGetResponse(result =>
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result))
                    {
#if DEBUG
                        if (Options.HttpDebugging)
                        {
                            Tools.HttpDebugResponse(response);
                        }
#endif

                        //Get a Parser and load the RDF
                        if (parser == null)
                        {
                            try
                            {
                                //Only need to auto-detect the parser if a specific one wasn't specified
                                parser          = MimeTypesHelper.GetStoreParser(response.ContentType);
                                parser.Warning += RaiseWarning;
                                parser.Load(handler, new StreamParams(response.GetResponseStream()));
                            }
                            catch (RdfParserSelectionException selEx)
                            {
                                String data     = new StreamReader(response.GetResponseStream()).ReadToEnd();
                                parser          = StringParser.GetDatasetParser(data);
                                parser.Warning += RaiseStoreWarning;
                                parser.Load(handler, new TextReaderParams(new StringReader(data)));
                            }
                        }
                        else
                        {
                            parser.Warning += RaiseStoreWarning;
                            parser.Load(handler, new StreamParams(response.GetResponseStream()));
                        }

                        //Finally can invoke the callback
                        callback(handler, state);
                    }
                }, null);
            }
            catch (UriFormatException uriEx)
            {
                //Uri Format Invalid
                throw new RdfException("Unable to load from the given URI '" + u.ToString() + "' since it's format was invalid, see inner exception for details", uriEx);
            }
            catch (WebException webEx)
            {
#if DEBUG
                if (Options.HttpDebugging)
                {
                    if (webEx.Response != null)
                    {
                        Tools.HttpDebugResponse((HttpWebResponse)webEx.Response);
                    }
                }
#endif
                //Some sort of HTTP Error occurred
                throw new WebException("A HTTP Error occurred resolving the URI '" + u.ToString() + "', see innner exception for details", webEx);
            }
        }
        /// <summary>
        /// Loads RDF data using an RDF Handler from a data: URI
        /// </summary>
        /// <param name="handler">RDF Handler</param>
        /// <param name="u">URI to load from</param>
        /// <remarks>
        /// Invokes the normal <see cref="UriLoader">UriLoader</see> instead if a the URI provided is not a data: URI
        /// </remarks>
        /// <exception cref="UriFormatException">Thrown if the metadata portion of the URI which indicates the MIME Type, Character Set and whether Base64 encoding is used is malformed</exception>
        public static void Load(IRdfHandler handler, Uri u)
        {
            if (u == null)
            {
                throw new RdfParseException("Cannot load RDF from a null URI");
            }
            if (handler == null)
            {
                throw new RdfParseException("Cannot read RDF into a null RDF Handler");
            }

            if (!u.Scheme.Equals("data"))
            {
                //Invoke the normal URI Loader if not a data: URI
#if !SILVERLIGHT
                UriLoader.Load(handler, u);
#else
                UriLoader.Load(handler, u, (_, _1) => { }, null);
#endif
                return;
            }

            String   mimetype = "text/plain";
            bool     mimeSet  = false;
            bool     base64   = false;
            String[] uri      = u.AbsolutePath.Split(',');
            String   metadata = uri[0];
            String   data     = uri[1];

            //Process the metadata
            if (metadata.Equals(String.Empty))
            {
                //Nothing to do
            }
            else if (metadata.Contains(';'))
            {
                if (metadata.StartsWith(";"))
                {
                    metadata = metadata.Substring(1);
                }
                String[] meta = metadata.Split(';');
                for (int i = 0; i < meta.Length; i++)
                {
                    if (meta[i].StartsWith("charset="))
                    {
                        //OPT: Do we need to process the charset parameter here at all?
                        //String charset = meta[i].Substring(meta[i].IndexOf('=') + 1);
                    }
                    else if (meta[i].Equals("base64"))
                    {
                        base64 = true;
                    }
                    else if (meta[i].Contains('/'))
                    {
                        mimetype = meta[i];
                        mimeSet  = true;
                    }
                    else
                    {
                        throw new UriFormatException("This data: URI appears to be malformed as encountered the parameter value '" + meta[i] + "' in the metadata section of the URI");
                    }
                }
            }
            else
            {
                if (metadata.StartsWith("charset="))
                {
                    //OPT: Do we need to process the charset parameter here at all?
                }
                else if (metadata.Equals(";base64"))
                {
                    base64 = true;
                }
                else if (metadata.Contains('/'))
                {
                    mimetype = metadata;
                    mimeSet  = true;
                }
                else
                {
                    throw new UriFormatException("This data: URI appears to be malformed as encountered the parameter value '" + metadata + "' in the metadata section of the URI");
                }
            }

            //Process the data
            if (base64)
            {
                StringWriter temp = new StringWriter();
                foreach (byte b in Convert.FromBase64String(data))
                {
                    temp.Write((char)((int)b));
                }
                data = temp.ToString();
            }
            else
            {
                data = Uri.UnescapeDataString(data);
            }

            //Now either select a parser based on the MIME type or let StringParser guess the format
            try
            {
                if (mimeSet)
                {
                    //If the MIME Type was explicitly set then we'll try and get a parser and use it
                    IRdfReader reader = MimeTypesHelper.GetParser(mimetype);
                    reader.Load(handler, new StringReader(data));
                }
                else
                {
                    //If the MIME Type was not explicitly set we'll let the StringParser guess the format
                    IRdfReader reader = StringParser.GetParser(data);
                    reader.Load(handler, new StringReader(data));
                }
            }
            catch (RdfParserSelectionException)
            {
                //If we fail to get a parser then we'll let the StringParser guess the format
                IRdfReader reader = StringParser.GetParser(data);
                reader.Load(handler, new StringReader(data));
            }
        }