diff options
Diffstat (limited to 'tools/gnu/classpath/tools/jar/Creator.java')
-rw-r--r-- | tools/gnu/classpath/tools/jar/Creator.java | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/tools/gnu/classpath/tools/jar/Creator.java b/tools/gnu/classpath/tools/jar/Creator.java new file mode 100644 index 000000000..55159660d --- /dev/null +++ b/tools/gnu/classpath/tools/jar/Creator.java @@ -0,0 +1,247 @@ +/* Creator.java - create a new jar file + Copyright (C) 2006 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.classpath.tools.jar; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.CRC32; +import java.util.zip.ZipEntry; + +public class Creator + extends Action +{ + JarOutputStream outputStream; + HashSet writtenItems = new HashSet(); + // The manifest to use, or null if we don't want a manifest. + Manifest manifest; + + private long copyFile(CRC32 crc, InputStream is, OutputStream output) + throws IOException + { + byte[] buffer = new byte[1024]; + long size = 0; + while (true) + { + int len = is.read(buffer); + if (len == - 1) + break; + size += len; + output.write(buffer, 0, len); + crc.update(buffer, 0, len); + } + output.close(); + return size; + } + + protected void writeFile(boolean isDirectory, InputStream inputFile, + String filename, boolean verbose) + throws IOException + { + if (writtenItems.contains(filename)) + { + if (verbose) + { + String msg = MessageFormat.format(Messages.getString("Creator.Ignoring"), //$NON-NLS-1$ + new Object[] { filename }); + System.err.println(msg); + } + return; + } + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + CRC32 crc = new CRC32(); + long size; + if (isDirectory) + { + size = 0; + } + else + { + size = copyFile(crc, inputFile, out); + } + + ZipEntry entry = new ZipEntry(filename); + entry.setCrc(crc.getValue()); + entry.setSize(size); + + outputStream.putNextEntry(entry); + out.writeTo(outputStream); + outputStream.closeEntry(); + writtenItems.add(filename); + + if (verbose) + { + long csize = entry.getCompressedSize(); + long perc; + if (size == 0) + perc = 0; + else + perc = 100 - (100 * csize) / size; + String msg = MessageFormat.format(Messages.getString("Creator.Adding"), //$NON-NLS-1$ + new Object[] + { + filename, + Long.valueOf(size), + Long.valueOf(entry.getSize()), + Long.valueOf(perc) + }); + System.err.println(msg); + } + } + + protected void writeFile(File file, String filename, boolean verbose) + throws IOException + { + boolean isDirectory = file.isDirectory(); + InputStream inputStream = null; + if (isDirectory) + { + if (filename.charAt(filename.length() - 1) != '/') + filename += '/'; + } + else + inputStream = new FileInputStream(file); + writeFile(isDirectory, inputStream, filename, verbose); + } + + private void addEntries(ArrayList result, Entry entry) + { + if (entry.file.isDirectory()) + { + String name = entry.name; + if (name.charAt(name.length() - 1) != '/') + { + name += '/'; + entry = new Entry(entry.file, name); + } + result.add(entry); + String[] files = entry.file.list(); + for (int i = 0; i < files.length; ++i) + addEntries(result, new Entry(new File(entry.file, files[i]), + entry.name + files[i])); + } + else + result.add(entry); + } + + private ArrayList getAllEntries(Main parameters) + { + Iterator it = parameters.entries.iterator(); + ArrayList allEntries = new ArrayList(); + while (it.hasNext()) + { + Entry entry = (Entry) it.next(); + addEntries(allEntries, entry); + } + return allEntries; + } + + private void writeCommandLineEntries(Main parameters) + throws IOException + { + // We've already written the manifest, make sure to mark it. + writtenItems.add("META-INF/"); //$NON-NLS-1$ + writtenItems.add(JarFile.MANIFEST_NAME); + + ArrayList allEntries = getAllEntries(parameters); + Iterator it = allEntries.iterator(); + while (it.hasNext()) + { + Entry entry = (Entry) it.next(); + writeFile(entry.file, entry.name, parameters.verbose); + } + } + + protected Manifest createManifest(Main parameters) + throws IOException + { + if (! parameters.wantManifest) + return null; + if (parameters.manifestFile != null) + { + // User specified a manifest file. + InputStream contents = new FileInputStream(parameters.manifestFile); + return new Manifest(contents); + } + return new Manifest(); + } + + protected void writeCommandLineEntries(Main parameters, OutputStream os) + throws IOException + { + manifest = createManifest(parameters); + outputStream = new JarOutputStream(os, manifest); + // FIXME: in Classpath this sets the method too late for the + // manifest file. + outputStream.setMethod(parameters.storageMode); + writeCommandLineEntries(parameters); + } + + protected void close() throws IOException + { + outputStream.finish(); + outputStream.close(); + } + + public void run(Main parameters) throws IOException + { + if (parameters.archiveFile == null || parameters.archiveFile.equals("-")) //$NON-NLS-1$ + writeCommandLineEntries(parameters, System.out); + else + { + OutputStream os + = new BufferedOutputStream(new FileOutputStream(parameters.archiveFile)); + writeCommandLineEntries(parameters, os); + } + close(); + } +} |