KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > deploy > shared > FileArchive


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.deployment.deploy.shared;
25
26 import java.io.*;
27 import java.util.Vector JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.jar.Manifest JavaDoc;
33 import java.util.jar.JarFile JavaDoc;
34 import java.net.URI JavaDoc;
35
36 import com.sun.enterprise.util.io.FileUtils;
37 import com.sun.enterprise.deployment.deploy.shared.Archive;
38
39 /**
40  * This implementation of the AbstractArchive interface maps to a directory/file
41  * structure.
42  *
43  * @author Jerome Dochez
44  */

45 public class FileArchive extends AbstractArchive {
46   
47     // the archive abstraction directory.
48
File JavaDoc archive;
49     String JavaDoc path;
50     
51     // the currently opened entry
52
OutputStream os=null;
53     
54     /** Creates a new instance of FileArchive */
55     public FileArchive() {
56     }
57     
58     /**
59      * Open an abstract archive
60      * @param the path to the archive
61      */

62     public void open(String JavaDoc path) throws IOException {
63         this.path = path.replace('/', File.separatorChar);
64         archive = new File JavaDoc(path);
65         if (!archive.exists()) {
66             throw new FileNotFoundException(path);
67         }
68     }
69     
70     /**
71      * Get the size of the archive
72      * @return tje the size of this archive or -1 on error
73      */

74     public long getArchiveSize() throws NullPointerException JavaDoc, SecurityException JavaDoc {
75         if(getArchiveUri() == null) {
76             return -1;
77         }
78         File JavaDoc tmpFile = new File JavaDoc(getArchiveUri());
79         return(tmpFile.length());
80     }
81     
82     /**
83      * creates a new abstract archive with the given path
84      * @param the path to create the archive
85      */

86     public void create(String JavaDoc path) throws IOException {
87         this.path = path.replace('/', File.separatorChar);
88         archive = new File JavaDoc(path);
89         archive.mkdirs();
90     }
91         
92     /**
93      * close the abstract archive
94      */

95     public void close() throws IOException {
96         // nothing to do
97
}
98     
99     /**
100      * close a previously returned @see java.io.OutputStream returned
101      * by an addEntry call
102      *
103      * @param the output stream to close
104      */

105     public void closeEntry(AbstractArchive os) throws IOException {
106         os.close();
107     }
108         
109     /**
110      * delete the archive
111      */

112     public boolean delete() {
113         // delete the directory structure...
114
try {
115             return deleteDir(archive);
116         } catch (IOException e) {
117             return false;
118         }
119     }
120     
121     /**
122      * @return an @see java.util.Enumeration of entries in this abstract
123      * archive
124      */

125     public Enumeration JavaDoc entries() {
126         Vector JavaDoc namesList = new Vector JavaDoc();
127         getListOfFiles(archive, namesList, null);
128         return namesList.elements();
129     }
130     
131     /**
132      * @return an @see java.util.Enumeration of entries in this abstract
133      * archive, providing the list of embedded archive to not count their
134      * entries as part of this archive
135      */

136      public Enumeration JavaDoc entries(Enumeration JavaDoc embeddedArchives) {
137         Vector JavaDoc nameList = new Vector JavaDoc();
138         List JavaDoc massagedNames = new ArrayList JavaDoc();
139     while (embeddedArchives.hasMoreElements()) {
140         String JavaDoc subArchiveName = (String JavaDoc) embeddedArchives.nextElement();
141         massagedNames.add(FileUtils.makeFriendlyFileName(subArchiveName));
142     }
143         getListOfFiles(archive, nameList, massagedNames);
144         return nameList.elements();
145      }
146
147     /**
148      * Returns an enumeration of the module file entries with the
149      * specified prefix. All elements in the enumeration are of
150      * type String. Each String represents a file name relative
151      * to the root of the module.
152      *
153      * @param prefix the prefix of entries to be included
154      * @return an enumeration of the archive file entries.
155      */

156     public Enumeration JavaDoc entries(String JavaDoc prefix) {
157         prefix = prefix.replace('/', File.separatorChar);
158         File JavaDoc file = new File JavaDoc(archive, prefix);
159         Vector JavaDoc namesList = new Vector JavaDoc();
160         getListOfFiles(file, namesList, null);
161         return namesList.elements();
162     }
163     
164     /**
165      * @return true if this archive exists
166      */

167     public boolean exists() {
168         return archive.exists();
169     }
170     
171     /**
172      * @return the archive uri
173      */

174     public String JavaDoc getArchiveUri() {
175         return path;
176     }
177     
178     /**
179      * create or obtain an embedded archive within this abstraction.
180      *
181      * @param the name of the embedded archive.
182      */

183     public AbstractArchive getEmbeddedArchive(String JavaDoc name) throws IOException {
184        // Convert name to native form. See bug #6345029 for more details.
185
name = name.replace('/', File.separatorChar);
186        File JavaDoc file = new File JavaDoc(name);
187        File JavaDoc subDir;
188        if (file.isAbsolute()) {
189            subDir = file;
190        } else {
191            // first we try to see if a sub directory with the right file
192
// name exist
193
subDir = new File JavaDoc(archive, FileUtils.makeFriendlyFileName(name));
194            if (!subDir.exists()) {
195                // now we try to open a sub jar file...
196
subDir = new File JavaDoc(archive, name);
197                if (!subDir.exists()) {
198                    // ok, nothing worked, reassing the name to the
199
// sub directory one
200
subDir = new File JavaDoc(archive, FileUtils.makeFriendlyFileName(name));
201               }
202            }
203        }
204        String JavaDoc subName = subDir.getPath();
205        if (!subDir.exists()) {
206            // time to create a new sub directory
207
File JavaDoc newDir = new File JavaDoc(subName);
208            newDir.mkdirs();
209        }
210        AbstractArchive sub;
211        if (subDir.isDirectory()) {
212             sub = new FileArchive();
213             ((FileArchive) sub).open(subName);
214        } else {
215             sub = new InputJarArchive();
216             ((InputJarArchive) sub).open(subName);
217        }
218        return sub;
219     }
220     
221     /**
222      * @return a @see java.io.InputStream for an existing entry in
223      * the current abstract archive
224      * @param the entry name
225      */

226     public InputStream getEntry(String JavaDoc name) throws IOException {
227             
228         name = name.replace('/', File.separatorChar);
229         File JavaDoc input = new File JavaDoc(archive, name);
230         if (!input.exists()) {
231             return null;
232         }
233         FileInputStream fis = new FileInputStream(input);
234         try {
235             BufferedInputStream bis = new BufferedInputStream(fis);
236             return bis;
237         } catch (Throwable JavaDoc tx) {
238             if (fis != null) {
239                 try {
240                     fis.close();
241                 } catch (Throwable JavaDoc thr) {
242                     IOException ioe = new IOException("Error closing FileInputStream after error opening BufferedInputStream for entry " + name);
243                     ioe.initCause(thr);
244                     throw ioe;
245                 }
246             }
247             IOException ioe = new IOException("Error opening BufferedInputStream for entry " + name);
248             ioe.initCause(tx);
249             throw ioe;
250         }
251     }
252
253     /**
254      * @return the manifest information for this abstract archive
255      */

256     public Manifest JavaDoc getManifest() throws IOException {
257         InputStream is = null;
258         try {
259             is = getEntry(JarFile.MANIFEST_NAME);
260             if (is!=null) {
261                 Manifest JavaDoc m = new Manifest JavaDoc(is);
262                 return m;
263             }
264         } finally {
265             if (is != null) {
266                 is.close();
267             }
268         }
269         return null;
270     }
271     
272     /**
273      * rename the archive
274      *
275      * @param name the archive name
276      */

277     public boolean renameTo(String JavaDoc name) {
278         return FileUtils.renameFile(archive, new File JavaDoc(name));
279     }
280     
281     
282     /**
283      * utility method for deleting a directory and all its content
284      */

285     private boolean deleteDir(File JavaDoc directory) throws IOException {
286         if (!directory.isDirectory()) {
287             throw new FileNotFoundException(directory.getPath());
288         }
289         
290         // delete contents
291
File JavaDoc[] entries = directory.listFiles();
292         for (int i=0;i<entries.length;i++) {
293             if (entries[i].isDirectory()) {
294                 deleteDir(entries[i]);
295             } else {
296                 FileUtils.deleteFile(entries[i]);
297             }
298         }
299         // delete self
300
return FileUtils.deleteFile(directory);
301     }
302     
303     /**
304      * utility method for getting contents of directory and
305      * sub directories
306      */

307     private void getListOfFiles(File JavaDoc directory, Vector JavaDoc files, List JavaDoc embeddedArchives) {
308         File JavaDoc[] list = directory.listFiles();
309         for (int i=0;i<list.length;i++) {
310         String JavaDoc fileName = list[i].getAbsolutePath().substring(archive.getAbsolutePath().length()+1);
311             if (!list[i].isDirectory()) {
312                 fileName = fileName.replace(File.separatorChar, '/');
313                 if (!fileName.equals(JarFile.MANIFEST_NAME)) {
314                     files.add(fileName);
315                 }
316             } else {
317         if (embeddedArchives!=null) {
318             if (!embeddedArchives.contains(fileName)) {
319                 getListOfFiles(list[i], files, null);
320             }
321         } else {
322                     getListOfFiles(list[i], files, null);
323         }
324             }
325         }
326     }
327     
328     /** @return true if this archive abstraction supports overwriting of elements
329      *
330      */

331     public boolean supportsElementsOverwriting() {
332         return true;
333     }
334     
335     /** delete an entry in the archive
336      * @param the entry name
337      * @return true if the entry was successfully deleted
338      *
339      */

340     public boolean deleteEntry(String JavaDoc name) {
341         name = name.replace('/', File.separatorChar);
342         File JavaDoc input = new File JavaDoc(archive, name);
343         if (!input.exists()) {
344             return false;
345         }
346         return input.delete();
347     }
348
349     /**
350      * Closes the current entry
351      */

352     public void closeEntry() throws IOException {
353         if (os!=null) {
354             os.flush();
355             os.close();
356             os = null;
357         }
358     }
359     
360     public URI JavaDoc getURI() {
361         return archive.toURI();
362     }
363     
364     /**
365      * @returns an @see java.io.OutputStream for a new entry in this
366      * current abstract archive.
367      * @param the entry name
368      */

369     public OutputStream putNextEntry(String JavaDoc name) throws java.io.IOException JavaDoc {
370         name = name.replace('/', File.separatorChar);
371         
372         File JavaDoc newFile = new File JavaDoc(archive, name);
373         if (newFile.exists()) {
374             if (!deleteEntry(name))
375                 throw new IOException(name + " already exists and cannot be deleted");
376         }
377         // if the entry name contains directory structure, we need
378
// to create those directories first.
379
if (name.lastIndexOf(File.separatorChar)!=-1) {
380             String JavaDoc dirs = name.substring(0, name.lastIndexOf(File.separatorChar));
381             (new File JavaDoc(archive, dirs)).mkdirs();
382         }
383         os = new BufferedOutputStream(new FileOutputStream(newFile));
384         return os;
385     }
386     
387 }
388
Popular Tags