001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.util;
020
021import icy.network.NetworkUtil;
022import icy.network.URLUtil;
023import icy.system.IcyExceptionHandler;
024
025import java.io.IOException;
026import java.net.JarURLConnection;
027import java.net.URL;
028import java.util.ArrayList;
029import java.util.Enumeration;
030import java.util.List;
031import java.util.jar.JarEntry;
032import java.util.jar.JarFile;
033
034/**
035 * JAR utilities class
036 * 
037 * @author Stephane
038 */
039public class JarUtil
040{
041    public static final String FILE_EXTENSION = "jar";
042    public static final String FILE_DOT_EXTENSION = "." + FILE_EXTENSION;
043
044    /**
045     * Return true if specified URL is a JAR url
046     */
047    public static boolean isJarURL(String path)
048    {
049        return (path != null) && path.toUpperCase().startsWith("JAR:") && URLUtil.isURL(path.substring(4));
050    }
051
052    /**
053     * Return a JAR URL from the specified path
054     */
055    public static URL getJarURL(String path)
056    {
057        if (path == null)
058            return null;
059
060        if (path.toUpperCase().startsWith("JAR:"))
061            return URLUtil.getURL(path.substring(4));
062
063        return URLUtil.getURL("jar:" + URLUtil.getURL(path) + "!/");
064    }
065
066    /**
067     * Return a JAR URL from the specified JAR path and JAR entry
068     */
069    public static URL getJarURL(String jarPath, JarEntry entry)
070    {
071        return URLUtil.getURL(getJarURL(jarPath) + entry.getName());
072    }
073
074    /**
075     * Return a JAR File from the specified path
076     */
077    public static JarFile getJarFile(String path)
078    {
079        try
080        {
081            if (isJarURL(path))
082                return ((JarURLConnection) NetworkUtil.openConnection(getJarURL(path), false, true)).getJarFile();
083
084            return new JarFile(path);
085        }
086        catch (IOException e)
087        {
088            System.err.println("Cannot open " + path + ":");
089            IcyExceptionHandler.showErrorMessage(e, false, true);
090            return null;
091        }
092    }
093
094    /**
095     * Find a class entry in the specified JAR file
096     */
097    public static JarEntry getJarClassEntry(JarFile file, String className)
098    {
099        return file.getJarEntry(className.replace('.', '/') + ".class");
100    }
101
102    /**
103     * Find the specified entry in the specified JAR file
104     */
105    public static JarEntry getJarEntry(JarFile file, String entryName)
106    {
107        return file.getJarEntry(entryName);
108    }
109
110    /**
111     * Returns all files contained in the specified JAR file.
112     * 
113     * @param includeFolderEntry
114     *        if <code>true</code> all folder entry are also included
115     * @param includeHidden
116     *        if <code>true</code> all hidden files (starting by '.' character) are also included
117     */
118    public static void getAllFiles(String fileName, boolean includeFolderEntry, boolean includeHidden,
119            List<String> result)
120    {
121        final JarFile jarFile = getJarFile(fileName);
122
123        if (jarFile == null)
124            return;
125
126        final Enumeration<JarEntry> entries = jarFile.entries();
127
128        while (entries.hasMoreElements())
129        {
130            final JarEntry jarEntry = entries.nextElement();
131
132            if (jarEntry.isDirectory() && !includeFolderEntry)
133                continue;
134
135            final String name = jarEntry.getName();
136
137            if (includeHidden || !name.startsWith("."))
138                result.add(jarEntry.getName());
139        }
140
141        try
142        {
143            jarFile.close();
144        }
145        catch (IOException e)
146        {
147            // ignore
148        }
149    }
150
151    /**
152     * Returns all files contained in the specified JAR file.
153     * 
154     * @param includeFolderEntry
155     *        if <code>true</code> all folder entry are also included
156     * @param includeHidden
157     *        if <code>true</code> all hidden files (starting by '.' character) are also included
158     */
159    public static List<String> getAllFiles(String fileName, boolean includeFolderEntry, boolean includeHidden)
160    {
161        final List<String> result = new ArrayList<String>();
162
163        getAllFiles(fileName, includeFolderEntry, includeHidden, result);
164
165        return result;
166    }
167}