| JarFiles |

    1   /*
    2    *  JarFileMerger.java
    3    *
    4    *  Copyright (c) 1998-2001, The University of Sheffield.
    5    *
    6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
    7    *  software, licenced under the GNU Library General Public License,
    8    *  Version 2, June 1991 (in the distribution as file licence.html,
    9    *  and also available at http://gate.ac.uk/gate/licence.html).
    10   *
    11   *  Oana Hamza, 09/06/00
    12   *
    13   *  $Id: JarFiles.java,v 1.13 2001/03/09 13:02:11 cursu Exp $
    14   */
    15
    16  package gate.util;
    17
    18  import java.util.*;
    19  import java.util.jar.*;
    20  import java.util.zip.*;
    21
    22  import java.lang.*;
    23  import java.io.*;
    24
    25  /** This class is used to merge a set of Jar/Zip Files in a Jar File
    26    * It is ignored the manifest.
    27    */
    28  public class JarFiles {
    29
    30    /** Debug flag */
    31    private static final boolean DEBUG = false;
    32    private StringBuffer dbgString = new StringBuffer();
    33    private boolean warning = false;
    34    String buggyJar = null;
    35
    36    private final static int BUFF_SIZE = 65000;
    37
    38    private Set directorySet = null;
    39
    40    private byte buffer[] = null;
    41
    42    public JarFiles(){
    43      directorySet = new HashSet();
    44      buffer = new byte[BUFF_SIZE];
    45    }
    46
    47    /** This method takes the content of all jar/zip files from the set
    48      * jarFileNames and put them in a file with the name outputFileName.
    49      * If the jar entry is manifest then this information isn't added.
    50      * @param jarFileNames is a set of names of files (jar/zip)
    51      * @param outputFileName is the name of the file which contains all the
    52      * classes of jarFilesNames
    53      */
    54    public void merge(Set jarFileNames, String destinationJarName)
    55                                                        throws GateException {
    56      String sourceJarName = null;
    57      JarOutputStream jarFileDestination = null;
    58      JarFile jarFileSource = null;
    59
    60      try {
    61        // create the output jar file
    62        jarFileDestination =
    63          new JarOutputStream(new FileOutputStream(destinationJarName));
    64
    65        dbgString.append("Creating " + destinationJarName + " from these JARs:\n");
    66        // iterate through the Jar files set
    67        Iterator jarFileNamesIterator = jarFileNames.iterator();
    68
    69        while (jarFileNamesIterator.hasNext()) {
    70          sourceJarName = (String) jarFileNamesIterator.next();
    71
    72          // create the new input jar files based on the file name
    73          jarFileSource = new JarFile(sourceJarName);
    74
    75          // Out.println("Adding " + sourceJarName + " to "
    76          // + destinationJarName);
    77          addJar(jarFileDestination, jarFileSource);
    78          if (jarFileSource.getName().equals(buggyJar))
    79            dbgString.append(sourceJarName + "...problems occured ! \n");
    80          else
    81            dbgString.append(sourceJarName + "...added OK ! \n");
    82          jarFileSource.close();
    83        }//End while
    84
    85        jarFileDestination.close();
    86
    87      } catch(IOException ioe) {
    88        ioe.printStackTrace(Err.getPrintWriter());
    89        //System.exit(1);
    90      }
    91      if (warning == true)
    92          Out.prln(dbgString);
    93    }// merge
    94
    95
    96    /**
    97      * This method adds all entries from sourceJar to destinationJar
    98      * NOTE: that manifest information is not added, method will throw
    99      * a gate Exception if a duplicate entry file is found.
    100     * @param destinationJar the jar that will collect all the entries
    101     * from source jar
    102     * @param sourceJar doesn't need any explanation ... DOES it?
    103     */
    104   private void addJar(JarOutputStream destinationJar, JarFile sourceJar)
    105                                                        throws GateException {
    106     try {
    107
    108       // get an enumeration of all entries from the sourceJar
    109       Enumeration jarFileEntriesEnum = sourceJar.entries();
    110
    111       JarEntry currentJarEntry = null;
    112       while (jarFileEntriesEnum.hasMoreElements()) {
    113
    114         // get a JarEntry
    115         currentJarEntry = (JarEntry) jarFileEntriesEnum.nextElement();
    116
    117         // if current entry is manifest then it is skipped
    118         if(currentJarEntry.getName().equalsIgnoreCase("META-INF/") ||
    119           currentJarEntry.getName().equalsIgnoreCase("META-INF/MANIFEST.MF"))
    120           continue;
    121
    122         // if current entry is a directory that was previously added to the
    123         // destination JAR then it is skipped
    124         if( currentJarEntry.isDirectory() &&
    125             directorySet.contains(currentJarEntry.getName())
    126            ) continue;
    127
    128         // otherwise the current entry is added to the final jar file
    129         try {
    130           // if the entry is directory then is added to the directorySet
    131           // NOTE: files entries are not added to this set
    132           if (currentJarEntry.isDirectory())
    133             directorySet.add(currentJarEntry.getName());
    134
    135           // put the entry into the destination JAR
    136           destinationJar.putNextEntry(new JarEntry(currentJarEntry.getName()));
    137
    138           // add the binary data from the entry
    139           // NOTE: if the entry is a directory there will be no binary data
    140           // get an input stream from the entry
    141           InputStream currentEntryStream =
    142             sourceJar.getInputStream(currentJarEntry);
    143
    144           // write data to destinationJar
    145           int  bytesRead = 0;
    146           while((bytesRead = currentEntryStream.read(buffer,0,BUFF_SIZE)) != -1)
    147                 destinationJar.write(buffer,0,bytesRead);
    148
    149           // close the input stream
    150           currentEntryStream.close();
    151
    152           // flush the destinationJar in order to be sure that
    153           // everything is there
    154           destinationJar.flush();
    155
    156           // close the new added entry and  prepare to read and write
    157           // another one
    158           // NOTE: destinationJar.putNextEntry automaticaly closes any previous
    159           // opened entry
    160           destinationJar.closeEntry();
    161
    162         } catch (java.util.zip.ZipException ze) {
    163           if(!currentJarEntry.isDirectory()){
    164             warning = true;
    165             buggyJar = sourceJar.getName();
    166             Out.prln("WARNING: Duplicate file entry " +
    167               currentJarEntry.getName() + " (this file will be discarded)..." +
    168               "It happened while adding " +
    169               sourceJar.getName() +  " !\n");
    170             dbgString.append(currentJarEntry.getName() +" file from " +
    171                 sourceJar.getName() + " was discarded :( !\n");
    172           }// End if
    173         }
    174       }// while(jarFileEntriesEnum.hasMoreElements())
    175     } catch (java.io.IOException e) {
    176       e.printStackTrace(Err.getPrintWriter());
    177       // System.exit(1);
    178     }
    179   }// addJar
    180
    181   /** args[0] is the final jar file and the other are the set of
    182     * jar file names
    183     * e.g. java gate.util.JarFiles libs.jar ../lib/*.jar ../lib/*.zip
    184     * will create a file calls libs.jar which will contain all
    185     * jar files and zip files
    186     */
    187
    188   public static void main(String[] args) {
    189     if(args.length < 2) {
    190                    Err.println("USAGE : JarFiles arg0 arg1 ... argN" +
    191                                     "(must be at least 2 args)");
    192                    //System.exit(1);
    193     } else {
    194       JarFiles jarFiles = new JarFiles();
    195       Set filesToMerge = new HashSet();
    196       for (int i=1; i<args.length; i++) {
    197         filesToMerge.add(args[i]);
    198     }
    199     try {
    200       jarFiles.merge(filesToMerge, args[0]);
    201     } catch (GateException ge) {
    202       ge.printStackTrace(Err.getPrintWriter());
    203     }
    204     }// if
    205   }// main
    206
    207 }// class JarFiles
    208

| JarFiles |