1 16 package org.apache.commons.vfs.provider.tar; 17 18 import java.io.File ; 19 import java.io.FileInputStream ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.List ; 25 import java.util.zip.GZIPInputStream ; 26 27 import org.apache.commons.compress.archivers.tar.TarEntry; 28 import org.apache.commons.compress.archivers.tar.TarInputStream; 29 import org.apache.commons.logging.Log; 30 import org.apache.commons.logging.LogFactory; 31 import org.apache.commons.vfs.FileName; 32 import org.apache.commons.vfs.FileObject; 33 import org.apache.commons.vfs.FileSystem; 34 import org.apache.commons.vfs.FileSystemException; 35 import org.apache.commons.vfs.FileSystemOptions; 36 import org.apache.commons.vfs.Selectors; 37 import org.apache.commons.vfs.VfsLog; 38 import org.apache.commons.vfs.provider.AbstractFileSystem; 39 import org.apache.commons.vfs.provider.UriParser; 40 import org.apache.commons.vfs.provider.bzip2.Bzip2FileObject; 41 42 47 public class TarFileSystem 48 extends AbstractFileSystem 49 implements FileSystem 50 { 51 private final static Log log = LogFactory.getLog(TarFileSystem.class); 52 53 private final File file; 54 private TarInputStream tarFile; 55 56 protected TarFileSystem(final FileName rootName, 57 final FileObject parentLayer, 58 final FileSystemOptions fileSystemOptions) 59 throws FileSystemException 60 { 61 super(rootName, parentLayer, fileSystemOptions); 62 63 file = parentLayer.getFileSystem().replicateFile(parentLayer, Selectors.SELECT_SELF); 65 66 if (!file.exists()) 68 { 69 tarFile = null; 71 return; 72 } 73 74 } 76 77 public void init() throws FileSystemException 78 { 79 super.init(); 80 81 try 83 { 84 List strongRef = new ArrayList (100); 85 TarEntry entry; 86 while ((entry = getTarFile().getNextEntry()) != null) 87 { 88 FileName name = getFileSystemManager().resolveName(getRootName(), UriParser.encode(entry.getName())); 89 90 TarFileObject fileObj; 92 if (entry.isDirectory() && getFileFromCache(name) != null) 93 { 94 fileObj = (TarFileObject) getFileFromCache(name); 95 fileObj.setTarEntry(entry); 96 continue; 97 } 98 99 fileObj = createTarFileObject(name, entry); 100 putFileToCache(fileObj); 101 strongRef.add(fileObj); 102 fileObj.holdObject(strongRef); 103 104 TarFileObject parent = null; 107 for (FileName parentName = name.getParent(); 108 parentName != null; 109 fileObj = parent, parentName = parentName.getParent()) 110 { 111 parent = (TarFileObject) getFileFromCache(parentName); 113 if (parent == null) 114 { 115 parent = createTarFileObject(parentName, null); 116 putFileToCache(parent); 117 strongRef.add(parent); 118 parent.holdObject(strongRef); 119 } 120 121 parent.attachChild(fileObj.getName()); 123 } 124 } 125 } 126 catch (IOException e) 127 { 128 throw new FileSystemException(e); 129 } 130 finally 131 { 132 closeCommunicationLink(); 133 } 134 } 135 136 public InputStream getInputStream(TarEntry entry) throws FileSystemException 137 { 138 resetTarFile(); 139 try 140 { 141 while (!tarFile.getNextEntry().equals(entry)) 142 { 143 } 144 return tarFile; 145 } 146 catch (IOException e) 147 { 148 throw new FileSystemException(e); 149 } 150 } 151 152 protected void resetTarFile() throws FileSystemException 153 { 154 if (this.file.exists()) 158 { 159 recreateTarFile(); 160 } 161 } 162 163 private void recreateTarFile() throws FileSystemException 164 { 165 if (this.tarFile != null) 166 { 167 try 168 { 169 this.tarFile.close(); 170 } 171 catch (IOException e) 172 { 173 throw new FileSystemException("vfs.provider.tar/close-tar-file.error", file, e); 174 } 175 tarFile = null; 176 } 177 TarInputStream tarFile = createTarFile(this.file); 178 this.tarFile = tarFile; 179 } 180 181 protected TarInputStream getTarFile() throws FileSystemException 182 { 183 if (tarFile == null && this.file.exists()) 184 { 185 recreateTarFile(); 186 } 187 188 return tarFile; 189 } 190 191 protected TarFileObject createTarFileObject(final FileName name, 192 final TarEntry entry) throws FileSystemException 193 { 194 return new TarFileObject(name, entry, this, true); 195 } 196 197 protected TarInputStream createTarFile(final File file) throws FileSystemException 198 { 199 try 200 { 201 if ("tgz".equalsIgnoreCase(getRootName().getScheme())) 202 { 203 return new TarInputStream(new GZIPInputStream (new FileInputStream (file))); 204 } 205 else if ("tbz2".equalsIgnoreCase(getRootName().getScheme())) 206 { 207 return new TarInputStream(Bzip2FileObject.wrapInputStream(file.getAbsolutePath(), new FileInputStream (file))); 208 } 209 return new TarInputStream(new FileInputStream (file)); 210 } 211 catch (IOException ioe) 212 { 213 throw new FileSystemException("vfs.provider.tar/open-tar-file.error", file, ioe); 214 } 215 } 216 217 protected void doCloseCommunicationLink() 218 { 219 try 221 { 222 if (tarFile != null) 223 { 224 tarFile.close(); 225 tarFile = null; 226 } 227 } 228 catch (final IOException e) 229 { 230 VfsLog.warn(getLogger(), log, "vfs.provider.tar/close-tar-file.error :" + file, e); 232 } 233 } 234 235 238 protected void addCapabilities(final Collection caps) 239 { 240 caps.addAll(TarFileProvider.capabilities); 241 } 242 243 246 protected FileObject createFile(final FileName name) throws FileSystemException 247 { 248 return new TarFileObject(name, null, this, false); 250 } 251 252 255 protected void notifyAllStreamsClosed() 256 { 257 closeCommunicationLink(); 258 } 259 } 260 | Popular Tags |