1 /******************************************************************************* 2 * Copyright (c) 2000, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.internal.wizards.datatransfer; 15 16 import java.io.FileOutputStream; 17 import java.io.IOException; 18 import java.io.InputStream; 19 import java.util.zip.CRC32; 20 import java.util.zip.ZipEntry; 21 import java.util.zip.ZipOutputStream; 22 23 import org.eclipse.core.resources.IContainer; 24 import org.eclipse.core.resources.IFile; 25 import org.eclipse.core.resources.IResource; 26 import org.eclipse.core.runtime.CoreException; 27 28 29 /** 30 * Exports resources to a .zip file 31 */ 32 public class ZipFileExporter implements IFileExporter { 33 private ZipOutputStream outputStream; 34 35 private boolean useCompression = true; 36 37 private boolean resolveLinks; 38 39 /** 40 * Create an instance of this class. 41 * 42 * @param filename 43 * java.lang.String 44 * @param compress 45 * boolean 46 * @param resolveLinks 47 * boolean 48 * @exception java.io.IOException 49 */ ZipFileExporter(String filename, boolean compress, boolean resolveLinks)50 public ZipFileExporter(String filename, boolean compress, boolean resolveLinks) throws IOException { 51 this.resolveLinks = resolveLinks; 52 outputStream = new ZipOutputStream(new FileOutputStream(filename)); 53 useCompression = compress; 54 } 55 56 /** 57 * Do all required cleanup now that we're finished with the 58 * currently-open .zip 59 * 60 * @exception java.io.IOException 61 */ 62 @Override finished()63 public void finished() throws IOException { 64 outputStream.close(); 65 } 66 67 /** 68 * Write the contents of the file to the tar archive. 69 * 70 * @param entry 71 * @param contents 72 * @exception java.io.IOException 73 * @exception org.eclipse.core.runtime.CoreException 74 */ write(ZipEntry entry, IFile contents)75 private void write(ZipEntry entry, IFile contents) throws IOException, CoreException { 76 byte[] readBuffer = new byte[4096]; 77 78 // If the contents are being compressed then we get the below for free. 79 if (!useCompression) { 80 entry.setMethod(ZipEntry.STORED); 81 InputStream contentStream = contents.getContents(false); 82 int length = 0; 83 CRC32 checksumCalculator = new CRC32(); 84 try { 85 int n; 86 while ((n = contentStream.read(readBuffer)) > 0) { 87 checksumCalculator.update(readBuffer, 0, n); 88 length += n; 89 } 90 } finally { 91 if (contentStream != null) { 92 contentStream.close(); 93 } 94 } 95 96 entry.setSize(length); 97 entry.setCrc(checksumCalculator.getValue()); 98 } 99 100 // set the timestamp 101 long localTimeStamp = contents.getLocalTimeStamp(); 102 if(localTimeStamp != IResource.NULL_STAMP) 103 entry.setTime(localTimeStamp); 104 105 outputStream.putNextEntry(entry); 106 try (InputStream contentStream = contents.getContents(false)) { 107 int n; 108 while ((n = contentStream.read(readBuffer)) > 0) { 109 outputStream.write(readBuffer, 0, n); 110 } 111 } 112 outputStream.closeEntry(); 113 } 114 115 @Override write(IContainer container, String destinationPath)116 public void write(IContainer container, String destinationPath) 117 throws IOException { 118 if (!resolveLinks && container.isLinked(IResource.DEPTH_INFINITE)) { 119 return; 120 } 121 ZipEntry newEntry = new ZipEntry(destinationPath); 122 outputStream.putNextEntry(newEntry); 123 } 124 125 /** 126 * Write the passed resource to the current archive. 127 * 128 * @param resource org.eclipse.core.resources.IFile 129 * @param destinationPath java.lang.String 130 * @exception java.io.IOException 131 * @exception org.eclipse.core.runtime.CoreException 132 */ 133 @Override write(IFile resource, String destinationPath)134 public void write(IFile resource, String destinationPath) 135 throws IOException, CoreException { 136 if (!resolveLinks && resource.isLinked(IResource.DEPTH_INFINITE)) { 137 return; 138 } 139 ZipEntry newEntry = new ZipEntry(destinationPath); 140 write(newEntry, resource); 141 } 142 } 143