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.provider; 018 019import org.apache.commons.vfs2.FileName; 020import org.apache.commons.vfs2.FileObject; 021import org.apache.commons.vfs2.FileSystem; 022import org.apache.commons.vfs2.FileSystemException; 023import org.apache.commons.vfs2.FileSystemOptions; 024 025/** 026 * A {@link FileProvider} that is layered on top of another, such as the contents of a zip or tar file. 027 */ 028public abstract class AbstractLayeredFileProvider extends AbstractFileProvider { 029 public AbstractLayeredFileProvider() { 030 super(); 031 setFileNameParser(LayeredFileNameParser.getInstance()); 032 } 033 034 /** 035 * Locates a file object, by absolute URI. 036 * 037 * @param baseFile The base FileObject. 038 * @param uri The name of the file to locate. 039 * @param fileSystemOptions The FileSystemOptions. 040 * @return The FileObject if it is located, null otherwise. 041 * @throws FileSystemException if an error occurs. 042 */ 043 @Override 044 public FileObject findFile(final FileObject baseFile, final String uri, final FileSystemOptions fileSystemOptions) 045 throws FileSystemException { 046 // Split the URI up into its parts 047 final LayeredFileName name = (LayeredFileName) parseUri(baseFile != null ? baseFile.getName() : null, uri); 048 049 // Make the URI canonical 050 051 // Resolve the outer file name 052 final FileName fileName = name.getOuterName(); 053 final FileObject file = getContext().resolveFile(baseFile, fileName.getURI(), fileSystemOptions); 054 055 // Create the file system 056 final FileObject rootFile = createFileSystem(name.getScheme(), file, fileSystemOptions); 057 058 // Resolve the file 059 return rootFile.resolveFile(name.getPath()); 060 } 061 062 /** 063 * Creates a layered file system. 064 * 065 * @param scheme The protocol to use. 066 * @param file a FileObject. 067 * @param fileSystemOptions Options to access the FileSystem. 068 * @return A FileObject associated with the new FileSystem. 069 * @throws FileSystemException if an error occurs. 070 */ 071 @Override 072 public synchronized FileObject createFileSystem(final String scheme, final FileObject file, 073 final FileSystemOptions fileSystemOptions) throws FileSystemException { 074 // Check if cached 075 final FileName rootName = file.getName(); 076 FileSystem fs = findFileSystem(rootName, fileSystemOptions); 077 if (fs == null) { 078 // Create the file system 079 fs = doCreateFileSystem(scheme, file, fileSystemOptions); 080 addFileSystem(rootName, fs); 081 } 082 return fs.getRoot(); 083 } 084 085 /** 086 * Creates a layered file system. 087 * <p> 088 * This method is called if the file system is not cached. 089 * 090 * @param scheme The URI scheme. 091 * @param file The file to create the file system on top of. 092 * @param fileSystemOptions options for new and underlying file systems. 093 * @return The file system, never null. Might implement {@link VfsComponent}. 094 * @throws FileSystemException if the file system cannot be created. 095 */ 096 protected abstract FileSystem doCreateFileSystem(final String scheme, final FileObject file, 097 final FileSystemOptions fileSystemOptions) throws FileSystemException; 098 099}