blob: 11acd0717d8815765e5b8334ea56c54e11d37cc5 [file] [log] [blame]
using System;
using System.IO;
namespace Lucene.Net.Analysis.Util
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <summary>
/// Simple <see cref="IResourceLoader"/> that opens resource files
/// from the local file system, optionally resolving against
/// a base directory.
///
/// <para>This loader wraps a delegate <see cref="IResourceLoader"/>
/// that is used to resolve all files, the current base directory
/// does not contain. <see cref="NewInstance"/> is always resolved
/// against the delegate, as an <see cref="T:System.Assembly"/> is needed.
///
/// </para>
/// <para>You can chain several <see cref="FilesystemResourceLoader"/>s
/// to allow lookup of files in more than one base directory.
/// </para>
/// </summary>
public sealed class FilesystemResourceLoader : IResourceLoader
{
private readonly DirectoryInfo baseDirectory;
private readonly IResourceLoader @delegate;
/// <summary>
/// Creates a resource loader that requires absolute filenames or relative to CWD
/// to resolve resources. Files not found in file system and class lookups
/// are delegated to context classloader.
/// </summary>
public FilesystemResourceLoader()
: this((DirectoryInfo)null)
{
}
/// <summary>
/// Creates a resource loader that resolves resources against the given
/// base directory (may be <c>null</c> to refer to CWD).
/// Files not found in file system and class lookups are delegated to context
/// classloader.
/// </summary>
public FilesystemResourceLoader(DirectoryInfo baseDirectory)
: this(baseDirectory, new ClasspathResourceLoader(typeof(FilesystemResourceLoader)))
{
}
/// <summary>
/// Creates a resource loader that resolves resources against the given
/// base directory (may be <c>null</c> to refer to CWD).
/// Files not found in file system and class lookups are delegated
/// to the given delegate <see cref="IResourceLoader"/>.
/// </summary>
public FilesystemResourceLoader(DirectoryInfo baseDirectory, IResourceLoader @delegate)
{
// LUCENENET NOTE: If you call DirectoryInfo.Create() it doesn't set the DirectoryInfo.Exists
// flag to true, so we use the Directory object to check the path explicitly.
if (baseDirectory != null && !Directory.Exists(baseDirectory.FullName))
{
throw new ArgumentException("baseDirectory is not a directory or null");
}
if (@delegate == null)
{
throw new ArgumentException("delegate ResourceLoader may not be null");
}
this.baseDirectory = baseDirectory;
this.@delegate = @delegate;
}
public Stream OpenResource(string resource)
{
try
{
FileInfo file = null;
// First try absolute.
if (File.Exists(resource))
{
file = new FileInfo(resource);
}
else
{
// Try as a relative path
var fullPath = System.IO.Path.GetFullPath(resource);
if (File.Exists(fullPath))
{
file = new FileInfo(fullPath);
}
else if (baseDirectory != null)
{
// Try to combine with the base directory
string based = System.IO.Path.Combine(baseDirectory.FullName, resource);
if (File.Exists(based))
{
file = new FileInfo(based);
}
}
}
if (file != null)
{
return file.OpenRead();
}
// Fallback on the inner resource loader (this could fail)
return @delegate.OpenResource(resource);
}
catch (Exception e)
{
throw new IOException("The requested file could not be found", e);
}
}
public T NewInstance<T>(string cname)
{
return @delegate.NewInstance<T>(cname);
}
public Type FindType(string cname)
{
return @delegate.FindType(cname);
}
}
}