001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2;
018
019import java.io.File;
020import java.lang.reflect.Constructor;
021import java.net.URI;
022import java.net.URL;
023import java.net.URLStreamHandlerFactory;
024import java.nio.file.Path;
025import java.util.Collection;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.vfs2.operations.FileOperationProvider;
029
030/**
031 * A FileSystemManager manages a set of file systems. This interface is used to locate a {@link FileObject} by name from
032 * one of those file systems.
033 * <p>
034 * To locate a {@link FileObject}, use one of the {@code resolveFile()} methods.
035 * </p>
036 *
037 * <h2><a id="naming">File Naming</a></h2>
038 * <p>
039 * A file system manager can recognize several types of file names:
040 * </p>
041 * <ul>
042 * <li>Absolute URI. These must start with a scheme, such as {@code file:} or {@code ftp:}, followed by a scheme
043 * dependent file name. Some examples: {@code file:/c:/somefile} or {@code ftp://somewhere.org/somefile}.</li>
044 * <li>Absolute local file name. For example, {@code /home/someuser/a-file} or {@code c:\dir\somefile.html}. Elements in
045 * the name can be separated using any of the following characters: {@code /}, {@code \}, or the native file separator
046 * character. For example, the following file names are the same: {@code c:\somedir\somefile.xml} and
047 * {@code c:/somedir/somefile.xml}.</li>
048 * <li>Relative path. For example: {@code ../somefile} or {@code somedir/file.txt}. The file system manager resolves
049 * relative paths against its <em>base file</em>. Elements in the relative path can be separated using {@code /},
050 * {@code \}, or file system specific separator characters. Relative paths may also contain {@code ..} and {@code .}
051 * elements. See {@link FileObject#resolveFile} for more details.</li>
052 * </ul>
053 */
054public interface FileSystemManager extends AutoCloseable {
055
056    /**
057     * Adds the specified FileOperationProvider for the specified scheme.
058     * <p>
059     * Several FileOperationProvider's might be registered for the same scheme. For example, for {@code "file"} scheme
060     * we can register {@code SvnWsOperationProvider} and {@code CvsOperationProvider.}
061     * </p>
062     *
063     * @param scheme The scheme associated with this provider.
064     * @param operationProvider The FileOperationProvider to add.
065     * @throws FileSystemException if an error occurs.
066     */
067    void addOperationProvider(String scheme, FileOperationProvider operationProvider) throws FileSystemException;
068
069    /**
070     * Adds an operation provider.
071     *
072     * @see FileSystemManager#addOperationProvider(String, org.apache.commons.vfs2.operations.FileOperationProvider)
073     * @param schemes The schemes that will be associated with the provider.
074     * @param operationProvider The FileOperationProvider to add.
075     * @throws FileSystemException if an error occurs.
076     */
077    void addOperationProvider(String[] schemes, FileOperationProvider operationProvider) throws FileSystemException;
078
079    /**
080     * Determines if a layered file system can be created for a given file.
081     *
082     * @param file The file to check for.
083     * @return true if the FileSystem can be created.
084     * @throws FileSystemException if an error occurs.
085     */
086    boolean canCreateFileSystem(FileObject file) throws FileSystemException;
087
088    /**
089     * Closes this file system manager.
090     *
091     * @since 2.5.0
092     */
093    @Override
094    default void close() {
095        // noop
096    }
097
098    /**
099     * Closes the given file system.
100     * <p>
101     * If you use VFS as singleton it is VERY dangerous to call this method.
102     * </p>
103     *
104     * @param fileSystem The FileSystem to close.
105     */
106    void closeFileSystem(FileSystem fileSystem);
107
108    /**
109     * Creates a layered file system. A layered file system is a file system that is created from the contents of a
110     * file, such as a ZIP or tar file.
111     *
112     * @param file The file to use to create the file system.
113     * @return The root file of the new file system.
114     * @throws FileSystemException On error creating the file system.
115     */
116    FileObject createFileSystem(FileObject file) throws FileSystemException;
117
118    /**
119     * Creates a layered file system. A layered file system is a file system that is created from the contents of a
120     * file, such as a ZIP or tar file.
121     *
122     * @param provider The name of the file system provider to use. This name is the same as the scheme used in URI to
123     *            identify the provider.
124     * @param file The file to use to create the file system.
125     * @return The root file of the new file system.
126     * @throws FileSystemException On error creating the file system.
127     */
128    FileObject createFileSystem(String provider, FileObject file) throws FileSystemException;
129
130    /**
131     * Creates a virtual file system. The file system will contain a junction at the fs root to the supplied root file.
132     *
133     * @param rootFile The root file to backs the file system.
134     * @return The root of the new file system.
135     * @throws FileSystemException if an error occurs creating the VirtualFileSystem.
136     */
137    FileObject createVirtualFileSystem(FileObject rootFile) throws FileSystemException;
138
139    /**
140     * Creates an empty virtual file system. Can be populated by adding junctions to it.
141     *
142     * @param rootUri The root URI to use for the new file system. Can be null.
143     * @return The root file of the new file system.
144     * @throws FileSystemException if an error occurs creating the VirtualFileSystem.
145     */
146    FileObject createVirtualFileSystem(String rootUri) throws FileSystemException;
147
148    /**
149     * Returns the base file used to resolve relative paths.
150     *
151     * @return The base FileObject.
152     * @throws FileSystemException if an error occurs.
153     */
154    FileObject getBaseFile() throws FileSystemException;
155
156    /**
157     * Gets the cache strategy used.
158     *
159     * @return the CacheStrategy.
160     */
161    CacheStrategy getCacheStrategy();
162
163    /**
164     * Gets the class to use to determine the content-type (mime-type).
165     *
166     * @return the FileContentInfoFactory.
167     */
168    FileContentInfoFactory getFileContentInfoFactory();
169
170    /**
171     * Gets the file object decorator used.
172     *
173     * @return the file object decorator Class.
174     */
175    Class<?> getFileObjectDecorator();
176
177    /**
178     * Gets the constructor associated to the fileObjectDecorator. We cache it here for performance reasons.
179     *
180     * @return the Constructor associated with the FileObjectDecorator.
181     */
182    Constructor<?> getFileObjectDecoratorConst();
183
184    /**
185     * Gets the cache used to cache file objects.
186     *
187     * @return The FilesCache.
188     */
189    FilesCache getFilesCache();
190
191    /**
192     * Gets the configuration builder for the given scheme.
193     *
194     * @param scheme The scheme to use to obtain the FileSystemConfigBuilder.
195     * @return A FileSystemConfigBuilder appropriate for the given scheme.
196     * @throws FileSystemException if the given scheme is not known.
197     */
198    FileSystemConfigBuilder getFileSystemConfigBuilder(String scheme) throws FileSystemException;
199
200    /**
201     * Gets Providers for file operations.
202     *
203     * @param scheme the scheme for which we want to get the list af registered providers.
204     * @return the registered FileOperationProviders for the specified scheme. If there were no providers registered for
205     *         the scheme, it returns null.
206     *
207     * @throws FileSystemException if an error occurs.
208     */
209    FileOperationProvider[] getOperationProviders(String scheme) throws FileSystemException;
210
211    /**
212     * Gets the capabilities for a given scheme.
213     *
214     * @param scheme The scheme to use to locate the provider's capabilities.
215     * @return A Collection of the various capabilities.
216     * @throws FileSystemException if the given scheme is not known.
217     */
218    Collection<Capability> getProviderCapabilities(String scheme) throws FileSystemException;
219
220    /**
221     * Gets the schemes currently available.
222     *
223     * @return An array of available scheme names that are supported.
224     */
225    String[] getSchemes();
226
227    /**
228     * Returns a stream handler factory to enable URL lookup using this FileSystemManager.
229     *
230     * @return the URLStreamHandlerFactory.
231     */
232    URLStreamHandlerFactory getURLStreamHandlerFactory();
233
234    /**
235     * Returns true if this manager has a provider for a particular scheme.
236     *
237     * @param scheme The scheme for which a provider should be checked.
238     * @return true if a provider for the scheme is available.
239     */
240    boolean hasProvider(String scheme);
241
242    /**
243     * Locates a file by name. See {@link #resolveFile(FileObject, String)} for details.
244     *
245     * @param baseFile The base file to use to resolve relative paths. Must not be {@code null}, not even if the
246     *            <em>name</em> is absolute.
247     * @param name The name of the file.
248     * @return The file. Never returns null.
249     * @throws FileSystemException On error parsing the file name.
250     */
251    FileObject resolveFile(File baseFile, String name) throws FileSystemException;
252
253    /**
254     * Locates a file by name. The name is resolved as described <a href="#naming">above</a>. That is, the name can be
255     * either an absolute URI, an absolute file name, or a relative path to be resolved against {@code baseFile}.
256     * <p>
257     * Note that the file does not have to exist when this method is called.
258     * </p>
259     *
260     * @param baseFile The base file to use to resolve relative paths. May be null if the name is an absolute file name.
261     * @param name The name of the file.
262     * @return The file. Never returns null.
263     * @throws FileSystemException On error parsing the file name.
264     */
265    FileObject resolveFile(FileObject baseFile, String name) throws FileSystemException;
266
267    /**
268     * Locates a file by name. Equivalent to calling {@code resolveFile(getBaseFile(), name)}.
269     *
270     * @param name The name of the file.
271     * @return The file. Never returns null.
272     * @throws FileSystemException On error parsing the file name.
273     */
274    FileObject resolveFile(String name) throws FileSystemException;
275
276    /**
277     * Locates a file by name. Equivalent to calling {@code resolveFile(getBaseFile(), name)}.
278     *
279     * @param name The name of the file.
280     * @param fileSystemOptions The FileSystemOptions used for FileSystem creation. All files that are later resolved
281     *            relative to the returned {@code FileObject} share the options.
282     * @return The file. Never returns null.
283     * @throws FileSystemException On error parsing the file name.
284     */
285    FileObject resolveFile(String name, FileSystemOptions fileSystemOptions) throws FileSystemException;
286
287    /**
288     * Resolves a URI into a {@link FileObject}.
289     *
290     * @param uri The URI to convert.
291     * @return The {@link FileObject} that represents the URI. Never returns null.
292     * @throws FileSystemException On error converting the file.
293     * @since 2.1
294     */
295    FileObject resolveFile(URI uri) throws FileSystemException;
296
297    /**
298     * Resolves a URL into a {@link FileObject}.
299     *
300     * @param url The URL to convert.
301     * @return The {@link FileObject} that represents the URL. Never returns null.
302     * @throws FileSystemException On error converting the file.
303     * @since 2.1
304     */
305    FileObject resolveFile(URL url) throws FileSystemException;
306
307    /**
308     * Resolves a name, relative to this file name. Equivalent to calling
309     * {@code resolveName( path, NameScope.FILE_SYSTEM )}.
310     *
311     * @param root the base file name
312     * @param name The name to resolve.
313     * @return A {@link FileName} object representing the resolved file name.
314     * @throws FileSystemException If the name is invalid.
315     */
316    FileName resolveName(FileName root, String name) throws FileSystemException;
317
318    /**
319     * Resolves a name, relative to the "root" file name. Refer to {@link NameScope} for a description of how names are
320     * resolved.
321     *
322     * @param root the base file name
323     * @param name The name to resolve.
324     * @param scope The {@link NameScope} to use when resolving the name.
325     * @return A {@link FileName} object representing the resolved file name.
326     * @throws FileSystemException If the name is invalid.
327     */
328    FileName resolveName(FileName root, String name, NameScope scope) throws FileSystemException;
329
330    /**
331     * Resolves the URI to a file name.
332     *
333     * @param uri The URI to resolve.
334     * @return A FileName that matches the URI.
335     * @throws FileSystemException if this is not possible.
336     */
337    FileName resolveURI(String uri) throws FileSystemException;
338
339    /**
340     * Sets the logger to use.
341     *
342     * @param log The logger to use.
343     */
344    void setLogger(Log log);
345
346    /**
347     * Converts a local file into a {@link FileObject}.
348     *
349     * @param file The file to convert.
350     * @return The {@link FileObject} that represents the local file. Never returns null.
351     * @throws FileSystemException On error converting the file.
352     */
353    FileObject toFileObject(File file) throws FileSystemException;
354
355    /**
356     * Converts a local path into a {@link FileObject}.
357     *
358     * @param path The path to convert.
359     * @return The {@link FileObject} that represents the local file. Never returns null.
360     * @throws FileSystemException On error converting the file.
361     * @since 2.10.0
362     */
363    default FileObject toFileObject(final Path path) throws FileSystemException {
364        return toFileObject(path.toFile());
365    }
366
367}