1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.vfs2.provider;
18
19 import org.apache.commons.vfs2.FileName;
20 import org.apache.commons.vfs2.FileObject;
21 import org.apache.commons.vfs2.FileSystem;
22 import org.apache.commons.vfs2.FileSystemException;
23 import org.apache.commons.vfs2.FileSystemOptions;
24
25 /**
26 * A {@link FileProvider} that is layered on top of another, such as the contents of a ZIP or tar file.
27 */
28 public abstract class AbstractLayeredFileProvider extends AbstractFileProvider {
29
30 /**
31 * Constructs a new instance for subclasses.
32 */
33 public AbstractLayeredFileProvider() {
34 setFileNameParser(LayeredFileNameParser.getInstance());
35 }
36
37 /**
38 * Creates a layered file system.
39 *
40 * @param scheme The protocol to use.
41 * @param file a FileObject.
42 * @param fileSystemOptions Options to access the FileSystem.
43 * @return A FileObject associated with the new FileSystem.
44 * @throws FileSystemException if an error occurs.
45 */
46 @Override
47 public synchronized FileObject createFileSystem(final String scheme, final FileObject file,
48 final FileSystemOptions fileSystemOptions) throws FileSystemException {
49 // Check if cached
50 final FileName rootName = file.getName();
51 FileSystem fs = findFileSystem(rootName, fileSystemOptions);
52 if (fs == null) {
53 // Create the file system
54 fs = doCreateFileSystem(scheme, file, fileSystemOptions);
55 addFileSystem(rootName, fs);
56 }
57 return fs.getRoot();
58 }
59
60 /**
61 * Creates a layered file system.
62 * <p>
63 * This method is called if the file system is not cached.
64 * </p>
65 *
66 * @param scheme The URI scheme.
67 * @param file The file to create the file system on top of.
68 * @param fileSystemOptions options for new and underlying file systems.
69 * @return The file system, never null. Might implement {@link VfsComponent}.
70 * @throws FileSystemException if the file system cannot be created.
71 */
72 protected abstract FileSystem doCreateFileSystem(String scheme, FileObject file, FileSystemOptions fileSystemOptions) throws FileSystemException;
73
74 /**
75 * Locates a file object, by absolute URI.
76 *
77 * @param baseFile The base FileObject.
78 * @param uri The name of the file to locate.
79 * @param fileSystemOptions The FileSystemOptions.
80 * @return The FileObject if it is located, null otherwise.
81 * @throws FileSystemException if an error occurs.
82 */
83 @Override
84 public FileObject findFile(final FileObject baseFile, final String uri, final FileSystemOptions fileSystemOptions)
85 throws FileSystemException {
86 // Split the URI up into its parts
87 final LayeredFileName name = (LayeredFileName) parseUri(baseFile != null ? baseFile.getName() : null, uri);
88
89 // Make the URI canonical
90
91 // Resolve the outer file name
92 final FileName fileName = name.getOuterName();
93 final FileObject file = getContext().resolveFile(baseFile, fileName.getURI(), fileSystemOptions);
94
95 // Create the file system
96 final FileObject rootFile = createFileSystem(name.getScheme(), file, fileSystemOptions);
97
98 // Resolve the file
99 return rootFile.resolveFile(name.getPath());
100 }
101
102 }