|
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 |
|