KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > vfs > provider > tar > TarFileSystem


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.vfs.provider.tar;
17
18 import java.io.File JavaDoc;
19 import java.io.FileInputStream JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.zip.GZIPInputStream JavaDoc;
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 /**
43  * A read-only file system for Tar files.
44  *
45  * @author <a HREF="mailto:adammurdoch@apache.org">Adam Murdoch</a>
46  */

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 JavaDoc 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         // Make a local copy of the file
64
file = parentLayer.getFileSystem().replicateFile(parentLayer, Selectors.SELECT_SELF);
65
66         // Open the Tar file
67
if (!file.exists())
68         {
69             // Don't need to do anything
70
tarFile = null;
71             return;
72         }
73
74         // tarFile = createTarFile(this.file);
75
}
76
77     public void init() throws FileSystemException
78     {
79         super.init();
80
81         // Build the index
82
try
83         {
84             List JavaDoc strongRef = new ArrayList JavaDoc(100);
85             TarEntry entry;
86             while ((entry = getTarFile().getNextEntry()) != null)
87             {
88                 FileName name = getFileSystemManager().resolveName(getRootName(), UriParser.encode(entry.getName()));
89
90                 // Create the file
91
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                 // Make sure all ancestors exist
105
// TODO - create these on demand
106
TarFileObject parent = null;
107                 for (FileName parentName = name.getParent();
108                      parentName != null;
109                      fileObj = parent, parentName = parentName.getParent())
110                 {
111                     // Locate the parent
112
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                     // Attach child to parent
122
parent.attachChild(fileObj.getName());
123                 }
124             }
125         }
126         catch (IOException JavaDoc e)
127         {
128             throw new FileSystemException(e);
129         }
130         finally
131         {
132             closeCommunicationLink();
133         }
134     }
135
136     public InputStream JavaDoc 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 JavaDoc e)
147         {
148             throw new FileSystemException(e);
149         }
150     }
151
152     protected void resetTarFile() throws FileSystemException
153     {
154         // Reading specific entries requires skipping through the tar file from the beginning
155
// Not especially elegant, but we don't have the ability to seek to specific positions
156
// with an input stream.
157
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 JavaDoc 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 JavaDoc file) throws FileSystemException
198     {
199         try
200         {
201             if ("tgz".equalsIgnoreCase(getRootName().getScheme()))
202             {
203                 return new TarInputStream(new GZIPInputStream JavaDoc(new FileInputStream JavaDoc(file)));
204             }
205             else if ("tbz2".equalsIgnoreCase(getRootName().getScheme()))
206             {
207                 return new TarInputStream(Bzip2FileObject.wrapInputStream(file.getAbsolutePath(), new FileInputStream JavaDoc(file)));
208             }
209             return new TarInputStream(new FileInputStream JavaDoc(file));
210         }
211         catch (IOException JavaDoc ioe)
212         {
213             throw new FileSystemException("vfs.provider.tar/open-tar-file.error", file, ioe);
214         }
215     }
216
217     protected void doCloseCommunicationLink()
218     {
219         // Release the tar file
220
try
221         {
222             if (tarFile != null)
223             {
224                 tarFile.close();
225                 tarFile = null;
226             }
227         }
228         catch (final IOException JavaDoc e)
229         {
230             // getLogger().warn("vfs.provider.tar/close-tar-file.error :" + file, e);
231
VfsLog.warn(getLogger(), log, "vfs.provider.tar/close-tar-file.error :" + file, e);
232         }
233     }
234
235     /**
236      * Returns the capabilities of this file system.
237      */

238     protected void addCapabilities(final Collection JavaDoc caps)
239     {
240         caps.addAll(TarFileProvider.capabilities);
241     }
242
243     /**
244      * Creates a file object.
245      */

246     protected FileObject createFile(final FileName name) throws FileSystemException
247     {
248         // This is only called for files which do not exist in the Tar file
249
return new TarFileObject(name, null, this, false);
250     }
251
252     /**
253      * will be called after all file-objects closed their streams.
254      */

255     protected void notifyAllStreamsClosed()
256     {
257         closeCommunicationLink();
258     }
259 }
260
Popular Tags