| /******************************************************************************* |
| * Copyright (c) 2005, 2018 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.tests.datatransfer; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.zip.GZIPInputStream; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.tests.harness.FileSystemHelper; |
| import org.eclipse.ui.dialogs.IOverwriteQuery; |
| import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileExportOperation; |
| import org.eclipse.ui.internal.wizards.datatransfer.TarEntry; |
| import org.eclipse.ui.internal.wizards.datatransfer.TarException; |
| import org.eclipse.ui.internal.wizards.datatransfer.TarFile; |
| import org.eclipse.ui.tests.harness.util.FileUtil; |
| import org.eclipse.ui.tests.harness.util.UITestCase; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| @RunWith(JUnit4.class) |
| public class ExportArchiveFileOperationTest extends UITestCase implements |
| IOverwriteQuery { |
| |
| private static final String FILE_NAME = "test"; |
| private static final String ZIP_FILE_EXT = "zip"; |
| private static final String TAR_FILE_EXT = "tar"; |
| private static final String[] directoryNames = { "dir1", "dir2" }; |
| private static final String[] emptyDirectoryNames = { "dir3" }; |
| private static final String[] fileNames = { "file1.txt", "file2.txt" }; |
| |
| private String localDirectory; |
| |
| private String filePath; |
| |
| private IProject project; |
| |
| private boolean flattenPaths = false; |
| private boolean excludeProjectPath = false; |
| |
| public ExportArchiveFileOperationTest() { |
| super(ExportArchiveFileOperationTest.class.getSimpleName()); |
| } |
| |
| @Override |
| public String queryOverwrite(String pathString) { |
| return ""; |
| } |
| |
| @Test |
| public void testExportStatus(){ |
| List<IProject> resources = new ArrayList<>(); |
| resources.add(project); |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, localDirectory); |
| |
| assertTrue(operation.getStatus().getCode() == IStatus.OK); |
| } |
| |
| @Test |
| public void testExportZip() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT; |
| List<IProject> resources = new ArrayList<>(); |
| resources.add(project); |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setUseCompression(false); |
| operation.setUseTarFormat(false); |
| operation.run(new NullProgressMonitor()); |
| |
| // +1 for .settings |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length + 1, ZIP_FILE_EXT); |
| |
| } |
| |
| @Test |
| public void testExportZipCompressed() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT; |
| List<IProject> resources = new ArrayList<>(); |
| resources.add(project); |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setUseCompression(true); |
| operation.setUseTarFormat(false); |
| operation.run(new NullProgressMonitor()); |
| verifyCompressed(ZIP_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportZipCreateSelectedDirectories() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| IResource[] members = project.members(); |
| for (IResource member : members) { |
| if (isDirectory(member)){ |
| IResource[] folderMembers = ((IFolder)member).members(); |
| for (IResource folderMember : folderMembers) { |
| if (isFile(folderMember)){ |
| resources.add(folderMember); |
| } |
| } |
| } |
| } |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(false); |
| operation.setUseTarFormat(false); |
| operation.run(new NullProgressMonitor()); |
| flattenPaths = true; |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length, ZIP_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportZipCreateSelectedDirectoriesProject() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT; |
| ArchiveFileExportOperation operation = new ArchiveFileExportOperation(project, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(false); |
| operation.setUseTarFormat(false); |
| operation.run(new NullProgressMonitor()); |
| // +1 for .settings |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length + 1, ZIP_FILE_EXT); |
| |
| try (ZipFile zipFile = new ZipFile(filePath)) { |
| Enumeration<? extends ZipEntry> entries = zipFile.entries(); |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| String name = entry.getName(); |
| assertTrue(name, name.startsWith(project.getName() + "/")); |
| } |
| } |
| |
| } |
| |
| @Test |
| public void testExportZipCreateSelectedDirectoriesWithFolders() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| IResource[] members = project.members(); |
| for (IResource member : members) { |
| if (isDirectory(member)) { |
| resources.add(member); |
| } |
| } |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(false); |
| operation.setUseTarFormat(false); |
| operation.run(new NullProgressMonitor()); |
| excludeProjectPath = true; |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length, ZIP_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportZipCreateSelectedDirectoriesCompressed() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + ZIP_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| IResource[] members = project.members(); |
| for (IResource member : members) { |
| if (isDirectory(member)){ |
| IResource[] folderMembers = ((IFolder)member).members(); |
| for (IResource folderMember : folderMembers) { |
| if (isFile(folderMember)){ |
| resources.add(folderMember); |
| } |
| } |
| } |
| } |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(true); |
| operation.setUseTarFormat(false); |
| operation.run(new NullProgressMonitor()); |
| flattenPaths = true; |
| verifyCompressed(ZIP_FILE_EXT); |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length, ZIP_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportTar() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| resources.add(project); |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| operation.setUseTarFormat(true); |
| operation.setUseCompression(false); |
| |
| operation.run(new NullProgressMonitor()); |
| |
| // +1 for .settings |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length + 1, TAR_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportTarCompressed() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| resources.add(project); |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setUseTarFormat(true); |
| operation.setUseCompression(true); |
| operation.run(new NullProgressMonitor()); |
| verifyCompressed(TAR_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportTarCreateSelectedDirectories() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| IResource[] members = project.members(); |
| for (IResource member : members) { |
| if (isDirectory(member)){ |
| IResource[] folderMembers = ((IFolder)member).members(); |
| for (IResource folderMember : folderMembers) { |
| if (isFile(folderMember)){ |
| resources.add(folderMember); |
| } |
| } |
| } |
| } |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(false); |
| operation.setUseTarFormat(true); |
| operation.run(new NullProgressMonitor()); |
| flattenPaths = true; |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length, TAR_FILE_EXT); |
| } |
| |
| @Test |
| public void testExportTarCreateSelectedDirectoriesWithFolders() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| IResource[] members = project.members(); |
| for (IResource member : members) { |
| if (isDirectory(member)) { |
| resources.add(member); |
| } |
| } |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(false); |
| operation.setUseTarFormat(true); |
| operation.run(new NullProgressMonitor()); |
| excludeProjectPath = true; |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length, TAR_FILE_EXT); |
| |
| } |
| |
| @Test |
| public void testExportTarCreateSelectedDirectoriesCompressed() throws Exception { |
| filePath = localDirectory + "/" + FILE_NAME + "." + TAR_FILE_EXT; |
| List<IResource> resources = new ArrayList<>(); |
| IResource[] members = project.members(); |
| for (IResource member : members) { |
| if (isDirectory(member)){ |
| IResource[] folderMembers = ((IFolder)member).members(); |
| for (IResource folderMember : folderMembers) { |
| if (isFile(folderMember)){ |
| resources.add(folderMember); |
| } |
| } |
| } |
| } |
| ArchiveFileExportOperation operation = |
| new ArchiveFileExportOperation(resources, filePath); |
| |
| operation.setCreateLeadupStructure(false); |
| operation.setUseCompression(true); |
| operation.setUseTarFormat(true); |
| operation.run(new NullProgressMonitor()); |
| flattenPaths = true; |
| verifyCompressed(TAR_FILE_EXT); |
| verifyFolders(directoryNames.length + emptyDirectoryNames.length, TAR_FILE_EXT); |
| |
| } |
| |
| @Override |
| protected void doSetUp() throws Exception { |
| super.doSetUp(); |
| project = FileUtil.createProject("Export" + getName()); |
| File destination = |
| new File(FileSystemHelper.getRandomLocation(FileSystemHelper.getTempDir()) |
| .toOSString()); |
| localDirectory = destination.getAbsolutePath(); |
| if (!destination.mkdirs()) { |
| fail("Could not set up destination directory for " + getName()); |
| } |
| setUpData(); |
| flattenPaths = false; |
| excludeProjectPath = false; |
| } |
| |
| @Override |
| protected void doTearDown() throws Exception { |
| super.doTearDown(); |
| // delete exported data |
| File root = new File(localDirectory); |
| if (root.exists()){ |
| File[] files = root.listFiles(); |
| if (files != null){ |
| for (File file : files) { |
| if (!file.delete()) { |
| fail("Could not delete " + file.getAbsolutePath()); |
| } |
| } |
| } |
| root.delete(); |
| } |
| try { |
| project.delete(true, true, null); |
| } catch (CoreException e) { |
| fail(e.toString()); |
| } |
| finally{ |
| project = null; |
| localDirectory = null; |
| filePath = null; |
| } |
| } |
| |
| private void setUpData(){ |
| try{ |
| for (String directoryName : directoryNames) { |
| IFolder folder = project.getFolder(directoryName); |
| folder.create(false, true, new NullProgressMonitor()); |
| for (String fileName : fileNames) { |
| IFile file = folder.getFile(fileName); |
| String contents = |
| directoryName + ", " + fileName; |
| file.create(new ByteArrayInputStream(contents.getBytes()), |
| true, new NullProgressMonitor()); |
| } |
| } |
| |
| // create empty folders to test bug 278402 |
| for (String emptyDirectoryName : emptyDirectoryNames) { |
| IFolder folder = project.getFolder(emptyDirectoryName); |
| folder.create(false, true, new NullProgressMonitor()); |
| } |
| } |
| catch(Exception e){ |
| fail(e.toString()); |
| } |
| } |
| |
| private void verifyCompressed(String type){ |
| String fileName = ""; |
| boolean compressed = false; |
| try { |
| if (ZIP_FILE_EXT.equals(type)) { |
| try (ZipFile zipFile = new ZipFile(filePath)) { |
| fileName = zipFile.getName(); |
| Enumeration<? extends ZipEntry> entries = zipFile.entries(); |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| compressed = entry.getMethod() == ZipEntry.DEFLATED; |
| } |
| } |
| } else { |
| File file = new File(filePath); |
| try (InputStream fin = new FileInputStream(file)) { |
| // Check if it's a GZIPInputStream. |
| try (InputStream in = new GZIPInputStream(fin)) { |
| compressed = true; |
| } catch (IOException e) { |
| compressed = false; |
| } |
| fileName = file.getName(); |
| } |
| } |
| } catch (IOException e) { |
| fail(e.getMessage()); |
| } |
| assertTrue(fileName + " does not appear to be compressed.", compressed); |
| } |
| |
| private void verifyFolders(int folderCount, String type){ |
| try{ |
| List<String> allEntries = new ArrayList<>(); |
| if (ZIP_FILE_EXT.equals(type)){ |
| try (ZipFile zipFile = new ZipFile(filePath)) { |
| Enumeration<? extends ZipEntry> entries = zipFile.entries(); |
| while (entries.hasMoreElements()) { |
| ZipEntry entry = entries.nextElement(); |
| allEntries.add(entry.getName()); |
| } |
| } |
| } |
| else{ |
| TarFile tarFile = new TarFile(filePath); |
| Enumeration<?> entries = tarFile.entries(); |
| while (entries.hasMoreElements()){ |
| TarEntry entry = (TarEntry)entries.nextElement(); |
| allEntries.add(entry.getName()); |
| } |
| tarFile.close(); |
| } |
| if (flattenPaths) { |
| verifyFiles(allEntries); |
| } else { |
| verifyArchive(folderCount, allEntries); |
| } |
| } |
| catch (IOException | TarException e){ |
| fail(e.getMessage()); |
| } |
| } |
| |
| private void verifyArchive(int folderCount, List<String> entries) { |
| int count = 0; |
| Set<String> folderNames = new HashSet<>(); |
| List<String> files = new ArrayList<>(); |
| Iterator<String> archiveEntries = entries.iterator(); |
| while (archiveEntries.hasNext()){ |
| String entryName = archiveEntries.next(); |
| int idx = entryName.lastIndexOf('/'); |
| String folderPath = entryName.substring(0, idx); |
| String fileName = entryName.substring(idx+1, entryName.length()); |
| // we get empty strings for folder entries, don't add them as a file name |
| if (!fileName.isEmpty()) { |
| files.add(fileName); |
| } |
| int idx2 = folderPath.lastIndexOf('/'); |
| if (idx2 != -1){ |
| String folderName = folderPath.substring(idx2 + 1, folderPath.length()); |
| folderNames.add(folderName); |
| } else { |
| folderNames.add(folderPath); |
| } |
| |
| } |
| verifyFolders(folderNames); |
| verifyFiles(files); |
| count += folderNames.size(); |
| if (!flattenPaths && !excludeProjectPath) { |
| folderCount++; |
| } |
| assertTrue( |
| "Number of folders expected and found not equal: expected=" + folderCount + ", actual=" + count, |
| folderCount == count); |
| |
| } |
| |
| private void verifyFiles(List<String> files) { |
| Iterator<String> iter = files.iterator(); |
| while (iter.hasNext()){ |
| String file = iter.next(); |
| verifyFile(file); |
| } |
| } |
| |
| private void verifyFile(String entryName){ |
| for (String fileName : fileNames) { |
| boolean dotProjectFileShouldBePresent = ".project".equals(entryName) && !flattenPaths && !excludeProjectPath; |
| if (fileName.equals(entryName) || dotProjectFileShouldBePresent) { |
| return; |
| } |
| } |
| if (entryName.equals("org.eclipse.core.resources.prefs")) { |
| return; |
| } |
| fail("Could not find file named: " + entryName); |
| } |
| |
| private void verifyFolders(Set<String> folderNames) { |
| Iterator<String> folders = folderNames.iterator(); |
| while (folders.hasNext()){ |
| String folderName = folders.next(); |
| if (".settings".equals(folderName)) { |
| continue; |
| } |
| if (!isDirectory(folderName)){ |
| if (flattenPaths) { |
| fail(folderName + " is not an expected folder"); |
| } else if (!project.getName().equals(folderName)) { |
| fail(folderName + " is not an expected folder"); |
| } |
| } |
| } |
| } |
| |
| private boolean isDirectory(String name){ |
| for (String directoryName : directoryNames) { |
| if (directoryName.equals(name)) { |
| return true; |
| } |
| } |
| for (String emptyDirectoryName : emptyDirectoryNames) { |
| if (emptyDirectoryName.equals(name)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private boolean isDirectory(IResource resource){ |
| return isDirectory(resource.getName()); |
| } |
| |
| private boolean isFile(IResource resource){ |
| for (String fileName : fileNames) { |
| if (fileName.equals(resource.getName())) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| } |