001package edu.pdx.cs410J.examples;
002
003import java.io.*;
004import java.util.*;
005import java.util.jar.*;
006import java.util.zip.*;
007
008/**
009 * This class demonstrates the file compression utilities in the
010 * <code>java.util.zip</code> and <code>java.util.jar</code> packages
011 * by creating a jar file whose contents are specified on the command
012 * line.
013 *
014 * @author David Whitlock
015 */
016public class MakeJar {
017
018  private static PrintWriter err = new PrintWriter(System.err, true);
019
020  /**
021   * Prints out information about how this program is used.
022   */
023  private static void usage() {
024    err.println("usage: MakeJar [options] jarFile [file]+");
025    err.println("  Where [options] are:");
026    err.println("  -nocompress    Don't compress Jar file");
027    err.println("  -author name   Author of Jar file (default: CS410J)");
028    err.println("  -version n     Version of Jar file " +
029                "(default: 1.0)");
030    System.exit(1);
031  }
032
033  /**
034   * Reads the name of the Jar file followed by the names of the files
035   * to be added to the jar file from the command line.
036   */
037  public static void main(String[] args) {
038    String jarFileName = null;
039    Set<String> fileNames = new HashSet<String>();
040    boolean compress = true;
041    String author = "CS410J";   // Author of Jar file
042    String version = "1.0";     // Version of Jar file
043
044    // Parse the command line
045    for (int i = 0; i < args.length; i++) {
046      if (args[i].equals("-nocompress")) {
047        compress = false;
048
049      } else if (args[i].equals("-author")) {
050        if(++i >= args.length) {
051          err.println("** Missing author name");
052          usage();
053        }
054
055        author = args[i];
056
057      } else if (args[i].equals("-version")) {
058        if(++i >= args.length) {
059          err.println("** Missing version");
060          usage();
061        }
062
063        version = args[i];
064
065      } else if (jarFileName == null) {
066        jarFileName = args[i];
067
068      } else {
069        // Add this file to the Jar
070        fileNames.add(args[i]);
071      }
072    }
073
074    if (jarFileName == null) {
075      err.println("** No Jar file specified");
076      usage();
077    }
078
079    if (fileNames.isEmpty()) {
080      err.println("** No files specified");
081      usage();
082    }
083
084    // Make note of the author and version in the Manifest file in the
085    // Jar
086    Manifest manifest = new Manifest();
087    Attributes global = manifest.getMainAttributes();
088    global.put(Attributes.Name.MANIFEST_VERSION, version);
089    global.put(new Attributes.Name("Created-By"), author);
090
091    // Create a JarOutputStream around the jar file
092    JarOutputStream jos = null;
093    try {
094      File jarFile = new File(jarFileName);
095      OutputStream os = new FileOutputStream(jarFile);
096      jos = new JarOutputStream(os, manifest);
097 
098    } catch (IOException ex) {
099      err.println("** IOException: " + ex.getMessage());
100      System.exit(1);
101    }
102
103    if (compress) {
104      jos.setMethod(JarOutputStream.DEFLATED);
105    } else {
106      jos.setMethod(JarOutputStream.STORED);
107    }
108
109    // Now open all the files and add them to the JAR file
110    Iterator names = fileNames.iterator();
111    while (names.hasNext()) {
112      String fileName = (String) names.next();
113      try {
114        File file = new File(fileName);
115
116        JarEntry entry = new JarEntry(fileName);
117        entry.setTime((new Date()).getTime());
118        entry.setSize(file.length());
119
120        InputStream is = 
121          new BufferedInputStream(new FileInputStream(file));
122        byte[] buffer = new byte[1024];
123        int read = 0;
124
125        if(compress) {
126          entry.setMethod(JarEntry.DEFLATED);
127
128        } else {
129          entry.setMethod(JarEntry.STORED);
130
131          // Compute the checksum of the file using CRC32
132          CRC32 checksum = new CRC32();
133          checksum.reset();
134          long total = 0;
135          while ((read = is.read(buffer)) != -1) {
136            checksum.update(buffer, 0, read);
137            total += read;
138          }
139          if (total != file.length()) {
140            throw new JarException("File length problems during " +
141                                   file.getPath() + " (" + total + 
142                                   " out of " + file.length() + ")");
143          }
144          entry.setCrc(checksum.getValue());
145        }
146
147        // Add the entry to the JAR file
148        jos.putNextEntry(entry);
149        is = new BufferedInputStream(new FileInputStream(file));
150        while((read = is.read(buffer, 0, buffer.length)) != -1) {
151          jos.write(buffer, 0, read);
152        }
153        is.close();
154        jos.closeEntry();
155
156      } catch (IOException ex) {
157        err.println("** IOException: " + ex.getMessage());
158        System.exit(1);
159      }
160    }
161
162  }
163
164}