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