1 11 package org.eclipse.jdt.ui.jarpackager; 12 13 import java.io.BufferedInputStream ; 14 import java.io.BufferedOutputStream ; 15 import java.io.File ; 16 import java.io.FileInputStream ; 17 import java.io.FileNotFoundException ; 18 import java.io.FileOutputStream ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 import java.net.URI ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import java.util.Comparator ; 26 import java.util.HashSet ; 27 import java.util.List ; 28 import java.util.Set ; 29 import java.util.jar.JarEntry ; 30 import java.util.jar.JarOutputStream ; 31 import java.util.jar.Manifest ; 32 import java.util.zip.ZipEntry ; 33 34 import org.eclipse.core.filesystem.EFS; 35 import org.eclipse.core.filesystem.IFileInfo; 36 37 import org.eclipse.core.runtime.Assert; 38 import org.eclipse.core.runtime.CoreException; 39 import org.eclipse.core.runtime.IPath; 40 import org.eclipse.core.runtime.IProgressMonitor; 41 import org.eclipse.core.runtime.NullProgressMonitor; 42 import org.eclipse.core.runtime.OperationCanceledException; 43 import org.eclipse.core.runtime.Path; 44 45 import org.eclipse.core.resources.IContainer; 46 import org.eclipse.core.resources.IFile; 47 import org.eclipse.core.resources.IProject; 48 import org.eclipse.core.resources.IResource; 49 import org.eclipse.core.resources.ResourcesPlugin; 50 51 import org.eclipse.swt.widgets.Shell; 52 53 54 import org.eclipse.ltk.core.refactoring.RefactoringCore; 55 import org.eclipse.ltk.core.refactoring.RefactoringDescriptor; 56 import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy; 57 58 import org.eclipse.jdt.internal.corext.util.Messages; 59 60 import org.eclipse.jdt.internal.ui.JavaPlugin; 61 import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerMessages; 62 import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil; 63 64 73 public class JarWriter3 { 74 75 private Set fDirectories= new HashSet (); 76 77 private JarOutputStream fJarOutputStream; 78 79 private JarPackageData fJarPackage; 80 81 93 public JarWriter3(JarPackageData jarPackage, Shell parent) throws CoreException { 94 Assert.isNotNull(jarPackage, "The JAR specification is null"); fJarPackage= jarPackage; 96 Assert.isTrue(fJarPackage.isValid(), "The JAR package specification is invalid"); if (!canCreateJar(parent)) 98 throw new OperationCanceledException(); 99 100 try { 101 if (fJarPackage.usesManifest() && fJarPackage.areGeneratedFilesExported()) { 102 Manifest manifest= fJarPackage.getManifestProvider().create(fJarPackage); 103 fJarOutputStream= new JarOutputStream (new FileOutputStream (fJarPackage.getAbsoluteJarLocation().toOSString()), manifest); 104 } else 105 fJarOutputStream= new JarOutputStream (new FileOutputStream (fJarPackage.getAbsoluteJarLocation().toOSString())); 106 String comment= jarPackage.getComment(); 107 if (comment != null) 108 fJarOutputStream.setComment(comment); 109 if (fJarPackage.isRefactoringAware()) { 110 Assert.isTrue(fJarPackage.areDirectoryEntriesIncluded()); 111 final IPath metaPath= new Path(JarPackagerUtil.getMetaEntry()); 112 addDirectories(metaPath); 113 addHistory(fJarPackage, new Path(JarPackagerUtil.getRefactoringsEntry()), new NullProgressMonitor()); 114 } 115 } catch (IOException exception) { 116 throw JarPackagerUtil.createCoreException(exception.getLocalizedMessage(), exception); 117 } 118 } 119 120 130 protected void addDirectories(IPath destinationPath) throws IOException { 131 String path= destinationPath.toString().replace(File.separatorChar, '/'); 132 int lastSlash= path.lastIndexOf('/'); 133 List directories= new ArrayList (2); 134 while (lastSlash != -1) { 135 path= path.substring(0, lastSlash + 1); 136 if (!fDirectories.add(path)) 137 break; 138 139 JarEntry newEntry= new JarEntry (path); 140 newEntry.setMethod(ZipEntry.STORED); 141 newEntry.setSize(0); 142 newEntry.setCrc(0); 143 newEntry.setTime(System.currentTimeMillis()); 144 directories.add(newEntry); 145 146 lastSlash= path.lastIndexOf('/', lastSlash - 1); 147 } 148 149 for (int i= directories.size() - 1; i >= 0; --i) { 150 fJarOutputStream.putNextEntry((JarEntry ) directories.get(i)); 151 } 152 } 153 154 166 protected void addDirectories(IResource resource, IPath destinationPath) throws IOException , CoreException { 167 IContainer parent= null; 168 String path= destinationPath.toString().replace(File.separatorChar, '/'); 169 int lastSlash= path.lastIndexOf('/'); 170 List directories= new ArrayList (2); 171 while (lastSlash != -1) { 172 path= path.substring(0, lastSlash + 1); 173 if (!fDirectories.add(path)) 174 break; 175 176 parent= resource.getParent(); 177 long timeStamp= System.currentTimeMillis(); 178 URI location= parent.getLocationURI(); 179 if (location != null) { 180 IFileInfo info= EFS.getStore(location).fetchInfo(); 181 if (info.exists()) 182 timeStamp= info.getLastModified(); 183 } 184 185 JarEntry newEntry= new JarEntry (path); 186 newEntry.setMethod(ZipEntry.STORED); 187 newEntry.setSize(0); 188 newEntry.setCrc(0); 189 newEntry.setTime(timeStamp); 190 directories.add(newEntry); 191 192 lastSlash= path.lastIndexOf('/', lastSlash - 1); 193 } 194 195 for (int i= directories.size() - 1; i >= 0; --i) { 196 fJarOutputStream.putNextEntry((JarEntry ) directories.get(i)); 197 } 198 } 199 200 210 protected void addFile(IFile resource, IPath path) throws IOException , CoreException { 211 JarEntry newEntry= new JarEntry (path.toString().replace(File.separatorChar, '/')); 212 byte[] readBuffer= new byte[4096]; 213 214 if (fJarPackage.isCompressed()) 215 newEntry.setMethod(ZipEntry.DEFLATED); 216 else { 218 newEntry.setMethod(ZipEntry.STORED); 219 JarPackagerUtil.calculateCrcAndSize(newEntry, resource.getContents(false), readBuffer); 220 } 221 222 long lastModified= System.currentTimeMillis(); 223 URI locationURI= resource.getLocationURI(); 224 if (locationURI != null) { 225 IFileInfo info= EFS.getStore(locationURI).fetchInfo(); 226 if (info.exists()) 227 lastModified= info.getLastModified(); 228 } 229 230 newEntry.setTime(lastModified); 232 233 InputStream contentStream = resource.getContents(false); 234 235 try { 236 fJarOutputStream.putNextEntry(newEntry); 237 int count; 238 while ((count= contentStream.read(readBuffer, 0, readBuffer.length)) != -1) 239 fJarOutputStream.write(readBuffer, 0, count); 240 } finally { 241 if (contentStream != null) 242 contentStream.close(); 243 244 250 } 252 } 253 254 268 private void addHistory(final JarPackageData data, final IPath path, final IProgressMonitor monitor) throws IOException , CoreException { 269 Assert.isNotNull(data); 270 Assert.isNotNull(path); 271 Assert.isNotNull(monitor); 272 final RefactoringDescriptorProxy[] proxies= data.getRefactoringDescriptors(); 273 Arrays.sort(proxies, new Comparator () { 274 275 public final int compare(final Object first, final Object second) { 276 final RefactoringDescriptorProxy predecessor= (RefactoringDescriptorProxy) first; 277 final RefactoringDescriptorProxy successor= (RefactoringDescriptorProxy) second; 278 final long delta= predecessor.getTimeStamp() - successor.getTimeStamp(); 279 if (delta > 0) 280 return 1; 281 else if (delta < 0) 282 return -1; 283 return 0; 284 } 285 }); 286 File file= null; 287 OutputStream output= null; 288 try { 289 file= File.createTempFile("history", null); output= new BufferedOutputStream (new FileOutputStream (file)); 291 try { 292 RefactoringCore.getHistoryService().writeRefactoringDescriptors(proxies, output, RefactoringDescriptor.NONE, false, monitor); 293 try { 294 output.close(); 295 output= null; 296 } catch (IOException exception) { 297 } 299 writeMetaData(data, file, path); 300 } finally { 301 if (output != null) { 302 try { 303 output.close(); 304 } catch (IOException exception) { 305 } 307 } 308 } 309 } finally { 310 if (file != null) 311 file.delete(); 312 } 313 } 314 315 324 protected boolean canCreateJar(Shell parent) { 325 File file= fJarPackage.getAbsoluteJarLocation().toFile(); 326 if (file.exists()) { 327 if (!file.canWrite()) 328 return false; 329 if (fJarPackage.allowOverwrite()) 330 return true; 331 return parent != null && JarPackagerUtil.askForOverwritePermission(parent, fJarPackage.getAbsoluteJarLocation().toOSString()); 332 } 333 334 String path= file.getAbsolutePath(); 336 int separatorIndex = path.lastIndexOf(File.separator); 337 if (separatorIndex == -1) return true; 339 File directory= new File (path.substring(0, separatorIndex)); 340 if (!directory.exists()) { 341 if (JarPackagerUtil.askToCreateDirectory(parent, directory)) 342 return directory.mkdirs(); 343 else 344 return false; 345 } 346 return true; 347 } 348 349 356 public void close() throws CoreException { 357 if (fJarOutputStream != null) 358 try { 359 fJarOutputStream.close(); 360 registerInWorkspaceIfNeeded(); 361 } catch (IOException ex) { 362 throw JarPackagerUtil.createCoreException(ex.getLocalizedMessage(), ex); 363 } 364 } 365 366 private void registerInWorkspaceIfNeeded() { 367 IPath jarPath= fJarPackage.getAbsoluteJarLocation(); 368 IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects(); 369 for (int i= 0; i < projects.length; i++) { 370 IProject project= projects[i]; 371 IPath projectLocation= project.getLocation(); 375 if (projectLocation != null && projectLocation.isPrefixOf(jarPath)) { 376 try { 377 jarPath= jarPath.removeFirstSegments(projectLocation.segmentCount()); 378 jarPath= jarPath.removeLastSegments(1); 379 IResource containingFolder= project.findMember(jarPath); 380 if (containingFolder != null && containingFolder.isAccessible()) 381 containingFolder.refreshLocal(IResource.DEPTH_ONE, null); 382 } catch (CoreException ex) { 383 JavaPlugin.log(ex); 385 } 386 } 387 } 388 } 389 390 401 public void write(IFile resource, IPath destinationPath) throws CoreException { 402 try { 403 if (fJarPackage.areDirectoryEntriesIncluded()) 404 addDirectories(resource, destinationPath); 405 addFile(resource, destinationPath); 406 } catch (IOException ex) { 407 String message= null; 409 if (ex.getLocalizedMessage() != null) 410 message= Messages.format(JarPackagerMessages.JarWriter_writeProblemWithMessage, new Object [] {resource.getFullPath(), ex.getLocalizedMessage()}); 411 else 412 message= Messages.format(JarPackagerMessages.JarWriter_writeProblem, resource.getFullPath()); 413 throw JarPackagerUtil.createCoreException(message, ex); 414 } 415 } 416 417 431 private void writeMetaData(final JarPackageData data, final File file, final IPath path) throws FileNotFoundException , IOException , CoreException { 432 Assert.isNotNull(data); 433 Assert.isNotNull(file); 434 Assert.isNotNull(path); 435 final JarEntry entry= new JarEntry (path.toString().replace(File.separatorChar, '/')); 436 byte[] buffer= new byte[4096]; 437 if (data.isCompressed()) 438 entry.setMethod(ZipEntry.DEFLATED); 439 else { 440 entry.setMethod(ZipEntry.STORED); 441 JarPackagerUtil.calculateCrcAndSize(entry, new BufferedInputStream (new FileInputStream (file)), buffer); 442 } 443 entry.setTime(System.currentTimeMillis()); 444 final InputStream stream= new BufferedInputStream (new FileInputStream (file)); 445 try { 446 fJarOutputStream.putNextEntry(entry); 447 int count; 448 while ((count= stream.read(buffer, 0, buffer.length)) != -1) 449 fJarOutputStream.write(buffer, 0, count); 450 } finally { 451 try { 452 stream.close(); 453 } catch (IOException exception) { 454 } 456 } 457 } 458 } 459 | Popular Tags |