1 2 24 package org.enhydra.tool.archive; 25 26 import org.enhydra.tool.ToolBoxInfo; 28 import org.enhydra.tool.common.FileUtil; 29 import org.enhydra.tool.common.PathHandle; 30 import org.enhydra.tool.common.ResUtil; 31 32 import java.io.BufferedInputStream ; 34 import java.io.BufferedOutputStream ; 35 import java.io.InputStream ; 36 import java.io.IOException ; 37 import java.io.File ; 38 import java.io.FileInputStream ; 39 import java.io.FileNotFoundException ; 40 import java.io.FileOutputStream ; 41 import java.util.jar.Attributes ; 42 import java.util.jar.JarEntry ; 43 import java.util.jar.JarOutputStream ; 44 import java.util.jar.Manifest ; 45 import java.util.ResourceBundle ; 46 47 public class JarBuilder implements Constants, ManifestKeys { 49 50 static ResourceBundle res = 52 ResourceBundle.getBundle("org.enhydra.tool.archive.Res"); 54 private JarPlan plan = null; 56 private JarOutputStream jarStream = null; 57 private String archivePath = new String (); 58 59 static public void main(String [] args) { 60 JarPlan plan = new JarPlan(); 61 JarBuilder builder = new JarBuilder(); 62 63 try { 64 plan.setArchivePath("d:\\temp\\test.jar"); 65 plan.setClassRoot("d:\\tmp"); 66 plan.setManifestPath("d:\\tmp\\META-INF\\MANIFEST.MF"); 67 builder.setPlan(plan); 68 builder.buildArchive(); 69 } catch (ArchiveException e) { 70 e.printStackTrace(); 71 } 72 } 73 74 public JarPlan getPlan() { 75 return plan; 76 } 77 78 public void setPlan(JarPlan p) { 79 plan = p; 80 } 81 82 public File buildArchive() throws ArchiveException { 83 File jar = null; 84 String root = null; 85 File [] files = new File [0]; 86 Descriptor[] dd = new Descriptor[0]; 87 88 jar = openJarStream(getPlan().getArchivePath()); 89 root = getPlan().getClassRoot(); 90 dd = getPlan().getDescriptors(); 91 files = getPlan().getClassFileArray(); 92 addJarClasses(); 93 for (int i = 0; i < dd.length; i++) { 94 addDescriptor(dd[i], root, files); 95 } 96 closeJarStream(); 97 return jar; 98 } 99 100 private Manifest readManifest() throws ArchiveException { 101 Manifest manifest = null; 102 FileInputStream fileStream = null; 103 BufferedInputStream bufStream = null; 104 105 try { 106 fileStream = new FileInputStream (plan.getManifestPath()); 107 bufStream = new BufferedInputStream (fileStream); 108 manifest = new Manifest (bufStream); 109 } catch (FileNotFoundException e) { 110 throw new ArchiveException(e, 111 "Unable to read manifest: " 112 + plan.getManifestPath()); 113 } catch (IOException e) { 114 throw new ArchiveException(e, 115 "Unable to read manifest: " 116 + plan.getManifestPath()); 117 } 118 return manifest; 119 } 120 121 protected Manifest buildManifest(Manifest m) { 122 Manifest manifest = m; 123 String [] libs = new String [0]; 124 StringBuffer buf = new StringBuffer (); 125 Descriptor[] dd = new Descriptor[0]; 126 127 manifest.getMainAttributes().put(new Attributes.Name (MANIFEST_VERSION), 128 VERSION_VALUE); 129 buf.append(System.getProperty(JAVA_VERSION)); 130 buf.append(' '); 131 buf.append('('); 132 buf.append(System.getProperty(JAVA_VENDOR)); 133 buf.append(')'); 134 manifest.getMainAttributes().put(new Attributes.Name (CREATED_BY), 135 buf.toString()); 136 manifest.getMainAttributes().put(new Attributes.Name (KELP_VERSION), 137 ToolBoxInfo.getToolBoxVersion()); 138 if (getPlan().getClassRoot() != null) { 139 manifest.getMainAttributes().put(new Attributes.Name (CLASS_ROOT), 140 getPlan().getClassRoot()); 141 } 142 143 libs = getPlan().getLibFiles(); 145 for (int i = 0; i < libs.length; i++) { 146 manifest.getMainAttributes().put(new Attributes.Name (LIBRARY + i), 147 libs[i]); 148 } 149 150 dd = getPlan().getDescriptors(); 152 for (int i = 0; i < dd.length; i++) { 153 if (dd[i].isValid()) { 154 manifest.getMainAttributes().put(new Attributes.Name (dd[i].getType()), 155 dd[i].getPath()); 156 } 157 } 158 return manifest; 159 } 160 161 protected void closeJarStream() throws ArchiveException { 162 try { 163 jarStream.flush(); 164 jarStream.finish(); 165 jarStream.close(); 166 } catch (IOException e) { 167 throw new ArchiveException(e, res.getString("Unable_to_close")); 168 } 169 } 170 171 protected File openJarStream(String p) throws ArchiveException { 172 FileOutputStream fileStream = null; 173 File archiveFile = null; 174 Manifest manifest = null; 175 176 archivePath = p; 177 archiveFile = new File (archivePath); 178 archivePath = archiveFile.getAbsolutePath(); 179 verifyArchiveFile(archiveFile); 180 try { 181 fileStream = new FileOutputStream (archiveFile); 182 if (plan.getManifestPath() == null) { 183 manifest = buildManifest(new Manifest ()); 184 } else { 185 manifest = readManifest(); 186 } 187 jarStream = new JarOutputStream (fileStream, manifest); 188 } catch (FileNotFoundException e) { 189 throw new ArchiveException(e, res.getString("Unable_to_create")); 190 } catch (IOException e) { 191 throw new ArchiveException(e, res.getString("Unable_to_create")); 192 } 193 return archiveFile; 194 } 195 196 protected void createEntry(File source, String entryPath) 197 throws FileNotFoundException , IOException { 198 if (source.getAbsolutePath().equalsIgnoreCase(archivePath)) { 199 200 } else { 202 BufferedInputStream in = null; 203 204 in = new BufferedInputStream (new FileInputStream (source)); 205 createEntry(in, entryPath); 206 } 207 } 208 209 protected void createEntry(InputStream source, String entryPath) 210 throws FileNotFoundException , IOException { 211 JarEntry entry = null; 212 213 entry = new JarEntry (entryPath); 214 entry.setTime(System.currentTimeMillis()); 215 jarStream.putNextEntry(entry); 216 217 FileUtil.copy(source, jarStream); 218 jarStream.flush(); 219 jarStream.closeEntry(); 220 source.close(); 221 } 222 223 protected void addJarClasses() throws ArchiveException { 224 File [] files = new File [0]; 225 226 files = getPlan().getClassFileArray(); 227 for (int i = 0; i < files.length; i++) { 228 addJarClassesFile(files[i]); 229 } 230 } 231 232 private void verifyArchiveFile(File archiveFile) throws ArchiveException { 235 if (archiveFile.isDirectory()) { 236 String exMess = res.getString("Target_is_a_directory"); 237 238 exMess = ResUtil.format(exMess, archiveFile); 239 throw new ArchiveException(exMess); 240 } else if (archiveFile.getParentFile() == null) { 241 String exMess = res.getString("Target_has_invalid"); 242 243 exMess = ResUtil.format(exMess, archiveFile); 244 throw new ArchiveException(exMess); 245 } else { 246 archiveFile.getParentFile().mkdirs(); 247 } 248 } 249 250 private void addJarClassesFile(File source) throws ArchiveException { 251 StringBuffer entryPath = new StringBuffer (); 252 String classRoot = null; 253 String relative = null; 254 255 classRoot = getPlan().getClassRoot(); 257 relative = source.getAbsolutePath().substring(classRoot.length() + 1); 258 relative = relative.replace('\\', '/'); 259 260 entryPath.append(relative); 262 263 try { 265 createEntry(source, entryPath.toString()); 266 } catch (IOException e) { 267 String exMess = res.getString("JarBuilder_Unable_to"); 268 269 exMess = ResUtil.format(exMess, source); 270 throw new ArchiveException(e, exMess); 271 } 272 } 273 274 protected void addDescriptor(Descriptor desc, String root, 275 File [] files) throws ArchiveException { 276 if (isDescriptorFound(desc, root, files)) { 277 278 } else if (desc.getPath().length() > 0) { 280 try { 281 createEntry(desc.getInputStream(), desc.getArchivePath()); 282 } catch (IOException e) { 283 throw new ArchiveException(e, 284 "Unable to add " + desc.getType() 285 + " descriptor: " 286 + desc.getPath()); 287 } 288 } 289 } 290 291 private boolean isDescriptorFound(Descriptor dd, String root, 292 File [] files) { 293 boolean in = false; 294 StringBuffer jarPath = new StringBuffer (); 295 String relative = null; 296 297 for (int i = 0; i < files.length; i++) { 298 relative = files[i].getAbsolutePath().substring(root.length() 299 + 1); 300 relative = relative.replace('\\', '/'); 301 if (relative.equals(dd.getArchivePath())) { 302 in = true; 303 break; 304 } 305 } 306 return in; 307 } 308 309 } 310 | Popular Tags |