コード例 #1
0
        /// <summary>
        /// Creates a local resource provider chain for this resource path, if it is a local path
        /// (see <see cref="CheckValidLocalPath"/>), and returns its result in a <see cref="IResourceAccessor"/> instance.
        /// </summary>
        /// <param name="result">Returns the resource accessor to access the resource represented by this path, if the
        /// return value is <c>true</c>. Else, this parameter doesn't return a meaningful value.</param>
        /// <returns><c>true</c>, if a resource accessor could successfully be built for this path.</returns>
        /// <exception cref="IllegalCallException">If one of the referenced resource providers is not available in the system or
        /// has the wrong type.</exception>
        /// <exception cref="UnexpectedStateException">If this path is empty.</exception>
        public bool TryCreateLocalResourceAccessor(out IResourceAccessor result)
        {
            IResourceAccessor resourceAccessor = null;

            if (USE_RA_CACHE)
            {
                if (TryGetCloneFromCache(this, out resourceAccessor))
                {
                    result = resourceAccessor;
                    return(true);
                }
            }
            IMediaAccessor mediaAccessor             = ServiceRegistration.Get <IMediaAccessor>();
            IEnumerator <ProviderPathSegment> enumer = _pathSegments.GetEnumerator();

            if (!enumer.MoveNext())
            {
                throw new UnexpectedStateException("Cannot build resource accessor for an empty resource path");
            }
            try
            {
                do
                {
                    ProviderPathSegment pathSegment = enumer.Current;
                    IResourceProvider   resourceProvider;
                    if (!mediaAccessor.LocalResourceProviders.TryGetValue(pathSegment.ProviderId, out resourceProvider))
                    {
                        throw new IllegalCallException("The resource provider with id '{0}' is not accessible in the current system", pathSegment.ProviderId);
                    }
                    if (resourceAccessor == null)
                    {
                        IBaseResourceProvider baseProvider = resourceProvider as IBaseResourceProvider;
                        if (baseProvider == null)
                        {
                            throw new IllegalCallException("The resource provider with id '{0}' does not implement the {1} interface", pathSegment.ProviderId, typeof(IBaseResourceProvider).Name);
                        }
                        if (!baseProvider.TryCreateResourceAccessor(pathSegment.Path, out resourceAccessor))
                        {
                            result = null;
                            return(false);
                        }
                    }
                    else
                    {
                        IChainedResourceProvider chainedProvider = resourceProvider as IChainedResourceProvider;
                        if (chainedProvider == null)
                        {
                            throw new IllegalCallException("The resource provider with id '{0}' does not implement the {1} interface", pathSegment.ProviderId, typeof(IChainedResourceProvider).Name);
                        }
                        IFileSystemResourceAccessor fsra = resourceAccessor as IFileSystemResourceAccessor;
                        if (fsra == null)
                        {
                            throw new IllegalCallException("Cannot chain up a resource provider to resource of type {0} (Path: '{1}')", resourceAccessor.GetType(), ToString());
                        }
                        IFileSystemResourceAccessor chainedRa;
                        if (!chainedProvider.TryChainUp(fsra, pathSegment.Path, out chainedRa))
                        {
                            resourceAccessor.Dispose();
                            result = null;
                            return(false);
                        }
                        resourceAccessor = chainedRa;
                    }
                } while (enumer.MoveNext());
            }
            catch (Exception)
            {
                if (resourceAccessor != null)
                {
                    resourceAccessor.Dispose();
                }
                throw;
            }
            if (USE_RA_CACHE)
            {
                AddToCache(this, resourceAccessor);
            }
            result = resourceAccessor;
            return(true);
        }