File Input Output Java

/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.security.cert.Certificate;
/**
 * @version $Rev: 726699 $ $Date: 2008-12-15 06:30:36 -0800 (Mon, 15 Dec 2008) $
 */
public class UnpackedJarFile extends JarFile {
    private final File baseDir;
    private boolean manifestLoaded = false;
    private Manifest manifest;
    public UnpackedJarFile(File baseDir) throws IOException {
        super(DeploymentUtil.DUMMY_JAR_FILE);
        this.baseDir = baseDir;
        if (!baseDir.isDirectory()) {
            throw new IOException("File must be a directory: file=" + baseDir.getAbsolutePath());
        }
    }
    public File getBaseDir() {
        return baseDir;
    }
    public Manifest getManifest() throws IOException {
        if (!manifestLoaded) {
            File manifestFile = getFile("META-INF/MANIFEST.MF");
            if (manifestFile != null && manifestFile.isFile()) {
                FileInputStream in = null;
                try {
                    in = new FileInputStream(manifestFile);
                    manifest = new Manifest(in);
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            // ignore
                        }
                    }
                }
            }
            manifestLoaded = true;
        }
        return manifest;
    }
    public UnpackedJarEntry getUnpackedJarEntry(String name) {
        File file = getFile(name);
        if (file == null) {
            return null;
        }
        return new UnpackedJarEntry(name, file, getManifestSafe());
    }
    public JarEntry getJarEntry(String name) {
        return getUnpackedJarEntry(name);
    }
    public ZipEntry getEntry(String name) {
        return getUnpackedJarEntry(name);
    }
    public Enumeration entries() {
        Collection files = DeploymentUtil.listRecursiveFiles(baseDir);
        Manifest manifest = getManifestSafe();
        LinkedList entries = new LinkedList();
        URI baseURI = baseDir.getAbsoluteFile().toURI();
        for (Iterator iterator = files.iterator(); iterator.hasNext();) {
            File entryFile = ((File) iterator.next()).getAbsoluteFile();
            URI entryURI = entryFile.toURI();
            URI relativeURI = baseURI.relativize(entryURI);
            entries.add(new UnpackedJarEntry(relativeURI.getPath(), entryFile, manifest));
        }
        return Collections.enumeration(entries);
    }
    public InputStream getInputStream(ZipEntry zipEntry) throws IOException {
        File file;
        if (zipEntry instanceof UnpackedJarEntry) {
            file = ((UnpackedJarEntry)zipEntry).getFile();
        } else {
            file = getFile(zipEntry.getName());
        }
        if (file == null) {
            throw new IOException("Entry not found: name=" + zipEntry.getName());
        } else if (file.isDirectory()) {
            return new DeploymentUtil.EmptyInputStream();
        }
        return new FileInputStream(file);
    }
    public String getName() {
        return baseDir.getAbsolutePath();
    }
    /**
     * Always returns -1.
     * @return -1
     */
    public int size() {
        return -1;
    }
    public void close() throws IOException {
        try {
            super.close();
        } catch(IOException ignored) {
        }
    }
    protected void finalize() throws IOException {
    }
    public File getFile(String name) {
        File file = new File(baseDir, name);
        if (!file.exists()) {
            return null;
        }
        return file;
    }
    private Manifest getManifestSafe() {
        Manifest manifest = null;
        try {
            manifest = getManifest();
        } catch (IOException e) {
            // ignore
        }
        return manifest;
    }
}
/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/**
 * @version $Rev: 617659 $ $Date: 2008-02-01 13:29:25 -0800 (Fri, 01 Feb 2008) $
 */
 final class DeploymentUtil {
    private DeploymentUtil() {
    }
    public static final File DUMMY_JAR_FILE;
    private static final boolean jarUrlRewrite;
    static {
        jarUrlRewrite = new Boolean(System.getProperty("org.apache.geronimo.deployment.util.DeploymentUtil.jarUrlRewrite", "false"));
        try {
            DUMMY_JAR_FILE = DeploymentUtil.createTempFile();
            new JarOutputStream(new FileOutputStream(DeploymentUtil.DUMMY_JAR_FILE), new Manifest()).close();
        } catch (IOException e) {
            throw new ExceptionInInitializerError(e);
        }
    }
    // be careful to clean up the temp directory
    public static File createTempDir() throws IOException {
        File tempDir = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
        tempDir.delete();
        tempDir.mkdirs();
        return tempDir;
    }
    // be careful to clean up the temp file... we tell the vm to delete this on exit
    // but VMs can't be trusted to acutally delete the file
    public static File createTempFile() throws IOException {
        File tempFile = File.createTempFile("geronimo-deploymentUtil", ".tmpdir");
        tempFile.deleteOnExit();
        return tempFile;
    }
    
    // be careful to clean up the temp file... we tell the vm to delete this on exit
    // but VMs can't be trusted to acutally delete the file
    private static File createTempFile(String extension) throws IOException {
        File tempFile = File.createTempFile("geronimo-deploymentUtil", extension == null? ".tmpdir": extension);
        tempFile.deleteOnExit();
        return tempFile;
    }
    public static void copyFile(File source, File destination) throws IOException {
        File destinationDir = destination.getParentFile();
        if (!destinationDir.exists() && !destinationDir.mkdirs()) {
            throw new java.io.IOException("Cannot create directory : " + destinationDir);
        }
        
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(source);
            out = new FileOutputStream(destination);
            writeAll(in, out);
        } finally {
            close(in);
            close(out);
        }
    }
    private static void writeAll(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[4096];
        int count;
        while ((count = in.read(buffer)) > 0) {
            out.write(buffer, 0, count);
        }
        out.flush();
    }
    public static File toTempFile(JarFile jarFile, String path) throws IOException {
        return toTempFile(createJarURL(jarFile, path));
    }
    public static File toTempFile(URL url) throws IOException {
        InputStream in = null;
        OutputStream out = null;
        JarFile jarFile = null;
        try {
            if(url.getProtocol().equalsIgnoreCase("jar")) {
                // url.openStream() locks the jar file and does not release the lock even after the stream is closed.
                // This problem is avoided by using JarFile APIs.
                File file = new File(url.getFile().substring(5, url.getFile().indexOf("!/")));
                String path = url.getFile().substring(url.getFile().indexOf("!/")+2);
                jarFile = new JarFile(file);
                JarEntry jarEntry = jarFile.getJarEntry(path);
                if(jarEntry != null) {
                    in = jarFile.getInputStream(jarEntry);
                } else {
                    throw new FileNotFoundException("JarEntry "+path+" not found in "+file);
                }
            } else {
                in = url.openStream();
            }
            int index = url.getPath().lastIndexOf(".");
            String extension = null;
            if (index > 0) {
                extension = url.getPath().substring(index);
            }
            File tempFile = createTempFile(extension);
            out = new FileOutputStream(tempFile);
            writeAll(in, out);
            return tempFile;
        } finally {
            close(out);
            close(in);
            close(jarFile);
        }
    }
    public static String readAll(URL url) throws IOException {
        Reader reader = null;
        JarFile jarFile = null;
        try {
            if(url.getProtocol().equalsIgnoreCase("jar")) {
                // url.openStream() locks the jar file and does not release the lock even after the stream is closed.
                // This problem is avoided by using JarFile APIs.
                File file = new File(url.getFile().substring(5, url.getFile().indexOf("!/")));
                String path = url.getFile().substring(url.getFile().indexOf("!/")+2);
                jarFile = new JarFile(file);
                JarEntry jarEntry = jarFile.getJarEntry(path);
                if(jarEntry != null) {
                    reader = new InputStreamReader(jarFile.getInputStream(jarEntry));
                } else {
                    throw new FileNotFoundException("JarEntry "+path+" not found in "+file);
                }
            } else {
                reader = new InputStreamReader(url.openStream());
            }
            char[] buffer = new char[4000];
            StringBuffer out = new StringBuffer();
            for(int count = reader.read(buffer); count >= 0; count = reader.read(buffer)) {
                out.append(buffer, 0, count);
            }
            return out.toString();
        } finally {
            close(reader);
            close(jarFile);
        }
    }
    public static File toFile(JarFile jarFile) throws IOException {
        if (jarFile instanceof UnpackedJarFile) {
            return ((UnpackedJarFile) jarFile).getBaseDir();
        } else {
          throw new IOException("jarFile is not a directory");
        }
    }
    // be careful with this method as it can leave a temp lying around
    public static File toFile(JarFile jarFile, String path) throws IOException {
        if (jarFile instanceof UnpackedJarFile) {
            File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
            File file = new File(baseDir, path);
            if (!file.isFile()) {
                throw new IOException("No such file: " + file.getAbsolutePath());
            }
            return file;
        } else {
            String urlString = "jar:" + new File(jarFile.getName()).toURL() + "!/" + path;
            return toTempFile(new URL(urlString));
        }
    }
    public static URL createJarURL(JarFile jarFile, String path) throws MalformedURLException {
        if (jarFile instanceof NestedJarFile) {
            NestedJarFile nestedJar = (NestedJarFile) jarFile;
            if (nestedJar.isUnpacked()) {
                JarFile baseJar = nestedJar.getBaseJar();
                String basePath = nestedJar.getBasePath();
                if (baseJar instanceof UnpackedJarFile) {
                    File baseDir = ((UnpackedJarFile) baseJar).getBaseDir();
                    baseDir = new File(baseDir, basePath);
                    return new File(baseDir, path).toURL();
                }
            }
        }
        
        if (jarFile instanceof UnpackedJarFile) {
            File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
            return new File(baseDir, path).toURL();
        } else {
            String urlString = "jar:" + new File(jarFile.getName()).toURL() + "!/" + path;
            if(jarUrlRewrite) {
                // To prevent the lockout of archive, instead of returning a jar url, write the content to a
                // temp file and return the url of that file.
                File tempFile = null;
                try {
                    tempFile = toTempFile(new URL(urlString));
                } catch (IOException e) {
                    // The JarEntry does not exist!
                    // Return url of a file that does not exist.
                    try {
                        tempFile = createTempFile();
                        tempFile.delete();
                    } catch (IOException ignored) {
                    }
                 }
                return tempFile.toURL();
            } else {
                return new URL(urlString);
            }
        }
    }
    public static JarFile createJarFile(File jarFile) throws IOException {
        if (jarFile.isDirectory()) {
            return new UnpackedJarFile(jarFile);
        } else {
            return new JarFile(jarFile);
        }
    }
    public static void copyToPackedJar(JarFile inputJar, File outputFile) throws IOException {
        if (inputJar.getClass() == JarFile.class) {
            // this is a plain old jar... nothign special
            copyFile(new File(inputJar.getName()), outputFile);
        } else if (inputJar instanceof NestedJarFile && ((NestedJarFile)inputJar).isPacked()) {
            NestedJarFile nestedJarFile = (NestedJarFile)inputJar;
            JarFile baseJar = nestedJarFile.getBaseJar();
            String basePath = nestedJarFile.getBasePath();
            if (baseJar instanceof UnpackedJarFile) {
                // our target jar is just a file in upacked jar (a plain old directory)... now
                // we just need to find where it is and copy it to the outptu
                copyFile(((UnpackedJarFile)baseJar).getFile(basePath), outputFile);
            } else {
                // out target is just a plain old jar file directly accessabel from the file system
                copyFile(new File(baseJar.getName()), outputFile);
            }
        } else {
            // copy out the module contents to a standalone jar file (entry by entry)
            JarOutputStream out = null;
            try {
                out = new JarOutputStream(new FileOutputStream(outputFile));
                byte[] buffer = new byte[4096];
                Enumeration entries = inputJar.entries();
                while (entries.hasMoreElements()) {
                    ZipEntry entry = (ZipEntry) entries.nextElement();
                    InputStream in = inputJar.getInputStream(entry);
                    try {
                        out.putNextEntry(new ZipEntry(entry.getName()));
                        try {
                            int count;
                            while ((count = in.read(buffer)) > 0) {
                                out.write(buffer, 0, count);
                            }
                        } finally {
                            out.closeEntry();
                        }
                    } finally {
                        close(in);
                    }
                }
            } finally {
                close(out);
            }
        }
    }
    public static void jarDirectory(File sourceDirecotry, File destinationFile) throws IOException {
        JarFile inputJar = new UnpackedJarFile(sourceDirecotry);
        try {
            copyToPackedJar(inputJar, destinationFile);
        } finally {
            close(inputJar);
        }
    }
    private static void createDirectory(File dir) throws IOException {
        if (dir != null && !dir.exists()) {
            boolean success = dir.mkdirs();
            if (!success) {
                throw new IOException("Cannot create directory " + dir.getAbsolutePath());
            }
        }
    }
    public static void unzipToDirectory(ZipFile zipFile, File destDir) throws IOException {
        Enumeration entries = zipFile.entries();
        try {
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                if (entry.isDirectory()) {
                    File dir = new File(destDir, entry.getName());
                    createDirectory(dir);
                } else {
                    File file = new File(destDir, entry.getName());
                    createDirectory(file.getParentFile());
                    OutputStream out = null;
                    InputStream in = null;
                    try {
                        out = new BufferedOutputStream(new FileOutputStream(file));
                        in = zipFile.getInputStream(entry);
                        writeAll(in, out);
                    } finally {
                        if (null != out) {
                            out.close();
                        }
                        if (null != in) {
                            in.close();
                        }
                    }
                }
            }
        } finally {
            zipFile.close();
        }
    }
    
    
    public static boolean recursiveDelete(File root, Collection unableToDeleteCollection) {
        if (root == null) {
            return true;
        }
        if (root.isDirectory()) {
            File[] files = root.listFiles();
            if (files != null) {
                for (int i = 0; i < files.length; i++) {
                    File file = files[i];
                    if (file.isDirectory()) {
                        recursiveDelete(file, unableToDeleteCollection);
                    } else {
                        if (!file.delete() && unableToDeleteCollection != null) {
                            unableToDeleteCollection.add(file.getAbsolutePath());    
                        }
                    }
                    // help out the GC of file handles by nulling the references
                    files[i] = null;
                }
            }
        }
        boolean rootDeleteStatus;
        if (!(rootDeleteStatus = root.delete()) && unableToDeleteCollection != null) 
          unableToDeleteCollection.add(root.getAbsolutePath());
        
        return rootDeleteStatus;
    }
    
    public static boolean recursiveDelete(File root) {
        return recursiveDelete(root, null);
    }
    public static Collection listRecursiveFiles(File file) {
        Collection list = new ArrayList();
        listRecursiveFiles(file, list);
        return Collections.unmodifiableCollection(list);
    }
    public static void listRecursiveFiles(File file, Collection collection) {
        File[] files = file.listFiles();
        if ( null == files ) {
            return;
        }
        for (File file1 : files) {
            collection.add(file1);
            if (file1.isDirectory()) {
                listRecursiveFiles(file1, collection);
            }
        }
    }
    public static void flush(OutputStream thing) {
        if (thing != null) {
            try {
                thing.flush();
            } catch(Exception ignored) {
            }
        }
    }
    public static void flush(Writer thing) {
        if (thing != null) {
            try {
                thing.flush();
            } catch(Exception ignored) {
            }
        }
    }
    public static void close(JarFile thing) {
        if (thing != null) {
            try {
                thing.close();
            } catch(Exception ignored) {
            }
        }
    }
    public static void close(InputStream thing) {
        if (thing != null) {
            try {
                thing.close();
            } catch(Exception ignored) {
            }
        }
    }
    public static void close(OutputStream thing) {
        if (thing != null) {
            try {
                thing.close();
            } catch(Exception ignored) {
            }
        }
    }
    public static void close(Reader thing) {
        if (thing != null) {
            try {
                thing.close();
            } catch(Exception ignored) {
            }
        }
    }
    public static void close(Writer thing) {
        if (thing != null) {
            try {
                thing.close();
            } catch(Exception ignored) {
            }
        }
    }
    public static final class EmptyInputStream extends InputStream {
        public int read() {
            return -1;
        }
        public int read(byte b[])  {
            return -1;
        }
        public int read(byte b[], int off, int len) {
            return -1;
        }
        public long skip(long n) {
            return 0;
        }
        public int available() {
            return 0;
        }
        public void close() {
        }
        public synchronized void mark(int readlimit) {
        }
        public synchronized void reset() {
        }
        public boolean markSupported() {
            return false;
        }
    }
}
 /**
  *  Licensed to the Apache Software Foundation (ASF) under one or more
  *  contributor license agreements.  See the NOTICE file distributed with
  *  this work for additional information regarding copyright ownership.
  *  The ASF licenses this file to You under the Apache License, Version 2.0
  *  (the "License"); you may not use this file except in compliance with
  *  the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 /**
  * @version $Rev: 726699 $ $Date: 2008-12-15 06:30:36 -0800 (Mon, 15 Dec 2008) $
  */
 class NestedJarFile extends JarFile {
     private JarFile baseJar;
     private String basePath;
     private boolean isClosed = false;
     private boolean manifestLoaded = false;
     private Manifest manifest;
     private File tempFile;
     public NestedJarFile(JarFile jarFile, String path) throws IOException {
         super(DeploymentUtil.DUMMY_JAR_FILE);
         // verify that the jar actually contains that path
         JarEntry targetEntry = jarFile.getJarEntry(path + "/");
         if (targetEntry == null) {
             targetEntry = jarFile.getJarEntry(path);
             if (targetEntry == null) {
                 throw new IOException("Jar entry does not exist: jarFile=" + jarFile.getName() + ", path=" + path);
             }
         }
         if (targetEntry.isDirectory()) {
          if(targetEntry instanceof UnpackedJarEntry) {
            //unpacked nested module inside unpacked ear
            File targetFile = ((UnpackedJarEntry) targetEntry).getFile();
            baseJar = new UnpackedJarFile(targetFile);
                 basePath = "";
          } else {
            baseJar = jarFile;
            if (!path.endsWith("/")) {
                     path += "/";
                 }
                 basePath = path;
          }
         } else {
             if (targetEntry instanceof UnpackedJarEntry) {
                 // for unpacked jars we don't need to copy the jar file
                 // out to a temp directory, since it is already available
                 // as a raw file
                 File targetFile = ((UnpackedJarEntry) targetEntry).getFile();
                 baseJar = new JarFile(targetFile);
                 basePath = "";
             } else {
                 tempFile = DeploymentUtil.toFile(jarFile, targetEntry.getName());
                 baseJar = new JarFile(tempFile);
                 basePath = "";
             }
         }
     }
     public boolean isUnpacked() {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return ( basePath.length() > 0 ) ||
                ( ( baseJar != null ) && ( baseJar instanceof UnpackedJarFile ) );
     }
     public boolean isPacked() {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return ( basePath.length() == 0 ) &&
                ( ( baseJar == null ) || !( baseJar instanceof UnpackedJarFile ) );
     }
     public JarFile getBaseJar() {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return baseJar;
     }
     public String getBasePath() {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return basePath;
     }
     public Manifest getManifest() throws IOException {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         if (!manifestLoaded) {
             JarEntry manifestEntry = getBaseEntry("META-INF/MANIFEST.MF");
             if (manifestEntry != null && !manifestEntry.isDirectory()) {
                 InputStream in = null;
                 try {
                     in = baseJar.getInputStream(manifestEntry);
                     manifest = new Manifest(in);
                 } finally {
                     if (in != null) {
                         try {
                             in.close();
                         } catch (IOException e) {
                             // ignore
                         }
                     }
                 }
             }
             manifestLoaded = true;
         }
         return manifest;
     }
     public NestedJarEntry getNestedJarEntry(String name) {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         JarEntry baseEntry = getBaseEntry(name);
         if (baseEntry == null) {
             return null;
         }
         return new NestedJarEntry(name, baseEntry, getManifestSafe());
     }
     public JarEntry getJarEntry(String name) {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return getNestedJarEntry(name);
     }
     public ZipEntry getEntry(String name) {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return getNestedJarEntry(name);
     }
     public Enumeration entries() {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         Collection baseEntries = Collections.list(baseJar.entries());
         Collection entries = new LinkedList();
         for (Iterator iterator = baseEntries.iterator(); iterator.hasNext();) {
             JarEntry baseEntry = (JarEntry) iterator.next();
             String path = baseEntry.getName();
             if (path.startsWith(basePath)) {
                 entries.add(new NestedJarEntry(path.substring(basePath.length()), baseEntry, getManifestSafe()));
             }
         }
         return Collections.enumeration(entries);
     }
     public InputStream getInputStream(ZipEntry zipEntry) throws IOException {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         JarEntry baseEntry;
         if (zipEntry instanceof NestedJarEntry) {
             baseEntry = ((NestedJarEntry)zipEntry).getBaseEntry();
         } else {
             baseEntry = getBaseEntry(zipEntry.getName());
         }
         if (baseEntry == null) {
             throw new IOException("Entry not found: name=" + zipEntry.getName());
         } else if (baseEntry.isDirectory()) {
             return new DeploymentUtil.EmptyInputStream();
         }
         return baseJar.getInputStream(baseEntry);
     }
     public String getName() {
         return baseJar.getName();
     }
     /**
      * Always returns -1.
      * @return -1
      */
     public int size() {
         if (isClosed) {
             throw new IllegalStateException("NestedJarFile is closed");
         }
         return -1;
     }
     public void close() throws IOException {
         if (isClosed) {
             return;
         }
         try {
             try {
                 super.close();
             } catch(IOException ignored) {
             }
             if (baseJar != null && basePath.length() == 0) {
                 // baseJar is created by us.  We should be closing it too.
                 baseJar.close();
             }
         } finally {
             isClosed = true;
             baseJar = null;
             basePath = null;
             manifestLoaded = false;
             manifest = null;
             if (tempFile != null) {
                 tempFile.delete();
                 tempFile = null;
             }
         }
     }
     protected void finalize() throws IOException {
         close();
     }
     private JarEntry getBaseEntry(String name) {
         return baseJar.getJarEntry(basePath + name);
     }
     private Manifest getManifestSafe() {
         Manifest manifest = null;
         try {
             manifest = getManifest();
         } catch (IOException e) {
             // ignore
         }
         return manifest;
     }
 }
 /**
  *  Licensed to the Apache Software Foundation (ASF) under one or more
  *  contributor license agreements.  See the NOTICE file distributed with
  *  this work for additional information regarding copyright ownership.
  *  The ASF licenses this file to You under the Apache License, Version 2.0
  *  (the "License"); you may not use this file except in compliance with
  *  the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software
  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
 /**
  * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
  */
  class NestedJarEntry extends JarEntry {
     private final JarEntry baseEntry;
     private final Manifest manifest;
     public NestedJarEntry(String name, JarEntry baseEntry, Manifest manifest) {
         super(name);
         this.baseEntry = baseEntry;
         this.manifest = manifest;
     }
     public JarEntry getBaseEntry() {
         return baseEntry;
     }
     public Attributes getAttributes() throws IOException {
         if (manifest == null) {
             return null;
         }
         return manifest.getAttributes(getName());
     }
 
     public long getTime() {
         return baseEntry.getTime();
     }
     public void setTime(long time) {
         baseEntry.setTime(time);
     }
     public long getSize() {
         return baseEntry.getSize();
     }
     public void setSize(long size) {
         baseEntry.setSize(size);
     }
     public long getCompressedSize() {
         return baseEntry.getCompressedSize();
     }
     public void setCompressedSize(long csize) {
         baseEntry.setCompressedSize(csize);
     }
     public long getCrc() {
         return baseEntry.getCrc();
     }
     public void setCrc(long crc) {
         baseEntry.setCrc(crc);
     }
     public int getMethod() {
         return baseEntry.getMethod();
     }
     public void setMethod(int method) {
         baseEntry.setMethod(method);
     }
     public byte[] getExtra() {
         return baseEntry.getExtra();
     }
     public void setExtra(byte[] extra) {
         baseEntry.setExtra(extra);
     }
     public String getComment() {
         return baseEntry.getComment();
     }
     public void setComment(String comment) {
         baseEntry.setComment(comment);
     }
     public boolean isDirectory() {
         return baseEntry.isDirectory();
     }
     public String toString() {
         return baseEntry.toString();
     }
     public int hashCode() {
         return baseEntry.hashCode();
     }
     public Object clone() {
         return new NestedJarEntry(getName(), baseEntry, manifest);
     }
 }
  /**
   *  Licensed to the Apache Software Foundation (ASF) under one or more
   *  contributor license agreements.  See the NOTICE file distributed with
   *  this work for additional information regarding copyright ownership.
   *  The ASF licenses this file to You under the Apache License, Version 2.0
   *  (the "License"); you may not use this file except in compliance with
   *  the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  /**
   * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
   */
  class UnpackedJarEntry extends JarEntry {
      private final File file;
      private final Manifest manifest;
      public UnpackedJarEntry(String name, File file, Manifest manifest) {
          super(name);
          this.file = file;
          this.manifest = manifest;
      }
      public File getFile() {
          return file;
      }
      public Attributes getAttributes() throws IOException {
          if (manifest == null) {
              return null;
          }
          return manifest.getAttributes(getName());
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param time ignored
       * @throws UnsupportedOperationException always
       */
      public void setTime(long time) throws UnsupportedOperationException {
          throw new UnsupportedOperationException("Can not change the time of unpacked jar entry");
      }
      public long getTime() {
          return file.lastModified();
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param size ignored
       * @throws UnsupportedOperationException always
       */
      public void setSize(long size) throws UnsupportedOperationException {
          throw new UnsupportedOperationException("Can not change the size of unpacked jar entry");
      }
      public long getSize() {
          if (file.isDirectory()) {
              return -1;
          } else {
              return file.length();
          }
      }
      /**
       * An unpacked jar is not compressed, so this method returns getSize().
       * @return getSize()
       */
      public long getCompressedSize() {
          return getSize();
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param compressedSize ignored
       * @throws UnsupportedOperationException always
       */
      public void setCompressedSize(long compressedSize) {
          throw new UnsupportedOperationException("Can not change the compressed size of unpacked jar entry");
      }
      public long getCrc() {
          return super.getCrc();    //To change body of overridden methods use File | Settings | File Templates.
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param crc ignored
       * @throws UnsupportedOperationException always
       */
      public void setCrc(long crc) {
          throw new UnsupportedOperationException("Can not change the crc of unpacked jar entry");
      }
      public int getMethod() {
          return ZipEntry.STORED;
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param method ignored
       * @throws UnsupportedOperationException always
       */
      public void setMethod(int method) {
          throw new UnsupportedOperationException("Can not change the method of unpacked jar entry");
      }
      /**
       * Always returns null.
       * @return null
       */
      public byte[] getExtra() {
          return null;
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param extra ignored
       * @throws UnsupportedOperationException always
       */
      public void setExtra(byte[] extra) {
          throw new UnsupportedOperationException("Can not change the extra data of unpacked jar entry");
      }
      /**
       * Always returns null.
       * @return null
       */
      public String getComment() {
          return null;
      }
      /**
       * An unpacked jar is read only, so this method always throws an UnsupportedOperationException.
       * @param comment ignored
       * @throws UnsupportedOperationException always
       */
      public void setComment(String comment) {
          throw new UnsupportedOperationException("Can not change the comment of unpacked jar entry");
      }
      public boolean isDirectory() {
          return file.isDirectory();
      }
      public Object clone() {
          return new UnpackedJarEntry(getName(), file, manifest);
      }
  }