blob: 7266c28acce87b55b6197a56b8c9400107e7b3f4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.internal.ui.wizards.imports;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.zip.ZipFile;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.*;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.wizards.datatransfer.*;
/**
* Helper class for the plugin import operation. Contains methods to assist in the copying and extracting
* of jar a folder files.
*/
public class PluginImportHelper {
/**
* Imports the contents of a zip file or folder, extracting the necessary files and
* putting them in the specified destination.
* @param source the file or folder to import from, should either be the root of the zip file or the File representing the folder
* @param dstPath
* @param provider
* @param filesToImport
* @param monitor
* @throws CoreException
*/
public static void importContent(Object source, IPath dstPath, IImportStructureProvider provider, List filesToImport, IProgressMonitor monitor) throws CoreException {
IOverwriteQuery query = new IOverwriteQuery() {
public String queryOverwrite(String file) {
return ALL;
}
};
try {
ImportOperation op = new ImportOperation(dstPath, source, provider, query);
op.setCreateContainerStructure(false);
if (filesToImport != null) {
op.setFilesToImport(filesToImport);
}
op.run(monitor);
} catch (InvocationTargetException e) {
IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e);
throw new CoreException(status);
} catch (InterruptedException e) {
throw new OperationCanceledException(e.getMessage());
}
}
/**
* Extracts the contents of the specified zip file to the specified destination
* @param file
* @param dstPath
* @param monitor
* @throws CoreException
*/
public static void extractArchive(File file, IPath dstPath, IProgressMonitor monitor) throws CoreException {
ZipFile zipFile = null;
try {
zipFile = new ZipFile(file);
ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile);
importContent(provider.getRoot(), dstPath, provider, null, monitor);
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e);
throw new CoreException(status);
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
}
}
}
}
/**
* Extracts all of the files and subfolders from a single folder within an archive file.
* @param file archive file to search for files
* @param folderPath path to the folder to extract from
* @param dstPath destination to import content to
* @param monitor progress monitor
* @throws CoreException if a problem occurs while extracting
* @since 3.4
*/
public static void extractFolderFromArchive(File file, IPath folderPath, IPath dstPath, IProgressMonitor monitor) throws CoreException {
ZipFile zipFile = null;
try {
zipFile = new ZipFile(file);
ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile);
ArrayList collected = new ArrayList();
collectResourcesFromFolder(provider, provider.getRoot(), folderPath, collected);
importContent(provider.getRoot(), dstPath, provider, collected, monitor);
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e);
throw new CoreException(status);
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
}
}
}
}
/**
* Searches the given archive file for java source folders. Imports the files in the
* source folders to the specified destination unless the folder is in the list of
* folders to exclude.
* @param file archive file to search for source in
* @param excludeFolders list of IPaths describing folders to ignore while searching
* @param dstPath full path to destination to put the extracted source
* @param monitor progress monitor
* @throws CoreException if there is a problem extracting source from the zip
*/
public static void extractJavaSourceFromArchive(File file, List excludeFolders, IPath dstPath, IProgressMonitor monitor) throws CoreException {
ZipFile zipFile = null;
try {
zipFile = new ZipFile(file);
ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile);
ArrayList collected = new ArrayList();
collectJavaSourceFromRoot(provider, excludeFolders, collected);
importContent(provider.getRoot(), dstPath, provider, collected, monitor);
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e);
throw new CoreException(status);
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
}
}
}
}
/**
* Copies an archive file to an IFile
* @param file
* @param dstFile
* @throws CoreException
*/
public static void copyArchive(File file, IFile dstFile, IProgressMonitor monitor) throws CoreException {
try {
FileInputStream fstream = new FileInputStream(file);
if (dstFile.exists())
dstFile.setContents(fstream, true, false, monitor);
else
dstFile.create(fstream, true, monitor);
fstream.close();
} catch (IOException e) {
IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.OK, e.getMessage(), e);
throw new CoreException(status);
}
}
public static String[] getTopLevelResources(File file) {
ArrayList result = new ArrayList();
ZipFile zipFile = null;
try {
zipFile = new ZipFile(file);
ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile);
List children = provider.getChildren(provider.getRoot());
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr)) {
if (!isClassFolder(provider, curr))
result.add(provider.getLabel(curr) + "/"); //$NON-NLS-1$
else {
if (!result.contains(".")) //$NON-NLS-1$
result.add("."); //$NON-NLS-1$
}
} else {
result.add(provider.getLabel(curr));
}
}
}
} catch (IOException e) {
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
}
}
}
return (String[]) result.toArray(new String[result.size()]);
}
public static void collectRequiredBundleFiles(IImportStructureProvider provider, Object element, ArrayList collected) {
List children = provider.getChildren(element);
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
String name = provider.getLabel(curr);
if (provider.isFolder(curr)) {
if (!name.equals("src") && !isClassFolder(provider, curr)) { //$NON-NLS-1$
// Do not import source folders and class folders
collectRequiredBundleFiles(provider, curr, collected);
}
} else if (!name.endsWith(".class") && !name.endsWith(".RSA") && !name.endsWith(".DSA") && !name.endsWith(".SF")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
// Do no import class files and signing files
collected.add(curr);
}
}
}
}
public static void collectNonJavaNonBuildFiles(IImportStructureProvider provider, Object element, ArrayList collected) {
List children = provider.getChildren(element);
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr)) {
// ignore source folders
if (folderContainsFileExtension(provider, curr, ".java")) //$NON-NLS-1$
continue;
if (provider.getFullPath(curr).equals("META-INF/")) { //$NON-NLS-1$
continue;
}
collected.add(curr);
} else if (!provider.getLabel(curr).endsWith(".java")) { //$NON-NLS-1$
collected.add(curr);
}
}
}
}
private static void collectResources(IImportStructureProvider provider, Object element, ArrayList collected) {
List children = provider.getChildren(element);
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr)) {
collectResources(provider, curr, collected);
} else if (!provider.getLabel(curr).endsWith(".class")) { //$NON-NLS-1$
collected.add(curr);
}
}
}
}
/**
* Recursively searches through the zip files searching for files inside of
* the specified folder. The files found will be added to the given list.
* @param provider zip provider
* @param element element of the zip currently being looked at
* @param folderPath location of the folder to get resources from
* @param collected list of files found
* @since 3.4
*/
private static void collectResourcesFromFolder(ZipFileStructureProvider provider, Object element, IPath folderPath, ArrayList collected) {
List children = provider.getChildren(element);
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr)) {
if (provider.getLabel(curr).equals(folderPath.segment(0))) {
if (folderPath.segmentCount() > 1) {
collectResourcesFromFolder(provider, curr, folderPath.removeFirstSegments(1), collected);
} else {
collectResources(provider, curr, collected);
}
}
}
}
}
}
/**
* Searches through the zip file for java source folders. Collects the files
* within the source folders. If a folder is in the list of folder paths to
* ignore, the folder will be skipped.
* @param provider zip provider
* @param ignoreFolders list of IPaths describing folders to ignore
* @param collected list that source files will be added to
* @since 3.4
*/
private static void collectJavaSourceFromRoot(ZipFileStructureProvider provider, List ignoreFolders, ArrayList collected) {
List children = provider.getChildren(provider.getRoot());
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr) && folderContainsFileExtension(provider, curr, ".java")) { //$NON-NLS-1$
// Check if we are in an ignored folder
List ignoreSubFolders = new ArrayList();
boolean ignoreThisChild = false;
for (Iterator iterator = ignoreFolders.iterator(); iterator.hasNext();) {
IPath currentPath = (IPath) iterator.next();
if (provider.getLabel(curr).equals(currentPath.segment(0))) {
if (currentPath.segmentCount() > 1) {
// There is a subfolder that should be ignored
ignoreSubFolders.add(currentPath.removeFirstSegments(1));
} else {
// This folder should be ignored
ignoreThisChild = true;
break;
}
}
}
if (!ignoreThisChild) {
collectJavaSource(provider, curr, ignoreSubFolders, collected);
}
}
}
}
}
/**
* Recursively searches the children of the given element inside of a zip file.
* If the folder path is in the set of folders to ignore, the folder will be skipped.
* All files found, except for .class files, will be added. The given list will be
* updated with the source files.
*
* @param provider zip provider
* @param element current element inside the zip
* @param ignoreFolders list of IPath folder paths to skip while searching
* @param collected list to update with new files found to import
* @since 3.4
*/
private static void collectJavaSource(ZipFileStructureProvider provider, Object element, List ignoreFolders, ArrayList collected) {
List children = provider.getChildren(element);
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr)) {
// Check if we are in an ignored folder
List ignoreSubFolders = new ArrayList();
boolean ignoreThisChild = false;
for (Iterator iterator = ignoreFolders.iterator(); iterator.hasNext();) {
IPath currentPath = (IPath) iterator.next();
if (provider.getLabel(curr).equals(currentPath.segment(0))) {
if (currentPath.segmentCount() > 1) {
// There is a subfolder that should be ignored. Remove segment referencing current folder.
ignoreSubFolders.add(currentPath.removeFirstSegments(1));
} else {
// This folder should be ignored
ignoreThisChild = true;
break;
}
}
}
if (!ignoreThisChild) {
collectJavaSource(provider, curr, ignoreSubFolders, collected);
}
// Add the file to the list
} else if (!provider.getLabel(curr).endsWith(".class")) { //$NON-NLS-1$
collected.add(curr);
}
}
}
}
private static boolean folderContainsFileExtension(IImportStructureProvider provider, Object element, String fileExtension) {
List children = provider.getChildren(element);
if (children != null && !children.isEmpty()) {
for (int i = 0; i < children.size(); i++) {
Object curr = children.get(i);
if (provider.isFolder(curr)) {
if (folderContainsFileExtension(provider, curr, fileExtension)) {
return true;
}
} else if (provider.getLabel(curr).endsWith(fileExtension)) {
return true;
}
}
}
return false;
}
private static boolean isClassFolder(IImportStructureProvider provider, Object element) {
return folderContainsFileExtension(provider, element, ".class"); //$NON-NLS-1$
}
}