/* * JBoss, the OpenSource EJB server * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.deployment; import java.net.URL; import java.net.URLConnection; import java.io.File; import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.BufferedWriter; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; /** * Encapsulates URL bases copy and jar file operations. * Very scratchy! Any improvements are welcome! * * @author Daniel Schulze * @author Andreas Schaefer * @version $Revision: 1.7.6.1 $ */ public class URLWizzard { private static byte[] buffer = new byte[1024*512]; // Static -------------------------------------------------------- public static void main (String[] _args) throws Exception { downloadAndPack (new URL (_args[0]), new URL (_args[1])); } /** copies the source to the destination url. As destination are currently only file:/... urls supported */ public static URL download (URL _src, URL _dest) throws IOException { if (!_dest.getProtocol ().equals ("file")) throw new IOException ("only file: protocoll is allowed as destination!"); InputStream in; OutputStream out; String s = _dest.getFile (); File dir = new File (s.substring (0, s.lastIndexOf("/"))); if (!dir.exists ()) dir.mkdirs (); in = _src.openStream (); out = new FileOutputStream (s); write (in, out); out.close (); in.close (); return _dest; } /** copies the source to the destination. The destination is composed from the _destDirectory, _prefix and _suffix */ public static URL downloadTemporary (URL _src, URL _destDirectory, String _prefix, String _suffix) throws IOException { return download (_src, createTempFile (_destDirectory, _prefix, _suffix)); } /** packs the source directory the _src url points to to a jar archiv at the _dest position */ public static void downloadAndPack (URL _src, URL _dest) throws IOException { if (!_dest.getProtocol ().equals ("file")) throw new IOException ("only file: protocoll is allowed as destination!"); if (!_src.getProtocol ().equals ("file")) throw new IOException ("only file: protocoll is allowed as source!"); InputStream in; OutputStream out; String s = _dest.getFile (); File dir = new File (s.substring (0, s.lastIndexOf("/"))); if (!dir.exists ()) dir.mkdirs (); JarOutputStream jout = new JarOutputStream (new FileOutputStream (_dest.getFile())); // put all into the jar... add (jout, new File (_src.getFile()), ""); jout.close (); } /** used by downloadAndPack*. */ private static void add (JarOutputStream _jout, File _dir, String _prefix) throws IOException { File[] content = _dir.listFiles (); for (int i = 0, l = content.length; i < l; ++i) { if (content[i].isDirectory ()) { add (_jout, content[i], _prefix+(_prefix.equals ("") ? "" : "/")+content[i].getName ()); } else { // If no prefix then no '/' necessary _jout.putNextEntry( new ZipEntry( ( "".equals( _prefix ) ? "" : _prefix + "/" ) + content[i].getName() ) ); FileInputStream in = new FileInputStream (content[i]); write (in, _jout); in.close (); } } } /** packs the source directory the _src url points to to a jar archiv at the position composed from _destDir, _prefix and _suffix */ public static URL downloadAndPackTemporary (URL _src, URL _destDir, String _prefix, String _suffix) throws IOException { if (!_destDir.getProtocol ().equals ("file")) throw new IOException ("only file: protocoll is allowed as destination!"); if (!_src.getProtocol ().equals ("file")) throw new IOException ("only file: protocoll is allowed as source!"); InputStream in; OutputStream out; File dest = new File (createTempFile (_destDir, _prefix, _suffix).getFile ()); JarOutputStream jout = new JarOutputStream (new FileOutputStream (dest)); // put all into the jar... add (jout, new File (_src.getFile()), ""); jout.close (); return dest.toURL (); } /** inflates the given zip file into the given directory */ public static URL downloadAndInflate (URL _src, URL _dest) throws IOException { InputStream in; OutputStream out; in = _src.openStream (); boolean jar = false; String jarPath = ""; String filePath; String fileName; String s = _dest.toString (); if (!_dest.getProtocol ().equals ("file")) throw new IOException ("only file: protocoll is allowed as destination!"); File base = new File (_dest.getFile ()); if (base.exists ()) deleteTree (_dest); base.mkdirs (); ZipInputStream zin = new ZipInputStream (in); ZipEntry entry; while ((entry = zin.getNextEntry ()) != null) { String name = entry.getName (); if (!entry.isDirectory ()) // there are not all directories listed (?!)- so this way... { // create directory structure if necessary // System.out.println ("entry: "+name); int x = name.lastIndexOf ("/"); if (x != -1) { File dir = new File (base.getCanonicalPath () + File.separator + name.substring (0, x)); if (!dir.exists ()) dir.mkdirs (); } // and extract... out = new FileOutputStream (base.getCanonicalPath () + File.separator + name); write (zin, out); out.close (); } } zin.close (); return _dest; } /** inflates the given zip file into a directory created in the dest directory with the given prefix */ public static URL downloadAndInflateTemporary (URL _src, URL _destDir, String _prefix) throws IOException { return downloadAndInflate (_src, createTempDir (_destDir, _prefix)); } /** creates a directory like the File.createTempFile method */ public static URL createTempDir (URL _baseDir, String _prefix) throws IOException { do { File f = new File (_baseDir.getFile (), _prefix + getId ()); if (!f.exists ()) { f.mkdirs (); return new URL("file:"+f.getCanonicalPath()); //return f.toURL (); } } while (true); // the endless loop should never cause trouble } private static int id = 1000; /** used by createTempDir */ private static String getId () { return String.valueOf (++id); } /** creates a temporary file like File.createTempFile() */ public static URL createTempFile (URL _baseDir, String _prefix, String _suffix) throws IOException { File f = new File (_baseDir.getFile ()); if (!f.exists ()) f.mkdirs (); File file; do { file = new File (f, _prefix + getId () + _suffix); } while (!file.createNewFile ()); return new URL("file:"+file.getCanonicalPath()); } /** deletes the given file:/... url recursively */ public static void deleteTree (URL _dir) throws IOException { if (!_dir.getProtocol ().equals ("file")) throw new IOException ("Protocol not supported"); File f = new File (_dir.getFile ()); if (!delete (f)) throw new IOException ("deleting " + _dir.toString () + "recursively failed!"); } /** deletes a file recursively */ private static boolean delete (File _f) throws IOException { if (_f.exists ()) { if (_f.isDirectory ()) { File[] files = _f.listFiles (); for (int i = 0, l = files.length; i < l; ++i) if (!delete (files[i])) return false; } return _f.delete (); } return true; } /** writes the content of the InputStream into the OutputStream */ private static synchronized void write (InputStream _in, OutputStream _out) throws IOException { int read; while (true) { read = _in.read(buffer); if (read == -1) break; _out.write(buffer, 0, read); } _out.flush (); } }