| package org.eclipse.ui.internal.dialogs; |
| |
| /* |
| * (c) Copyright IBM Corp. 2000, 2001. |
| * All Rights Reserved. |
| */ |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.WorkbenchMessages; |
| import org.eclipse.jface.operation.*; |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.*; |
| |
| /** |
| * Operation for exporting a resource and its children to a new .zip file |
| */ |
| /*package*/ class ZipFileResourceExportOperation implements IRunnableWithProgress { |
| private ZipFileResourceExporter exporter; |
| private String destinationFilename; |
| private IProgressMonitor monitor; |
| private int leadupStartDepth = 0; |
| private List resourcesToExport; |
| private IResource resource; |
| private List errorTable = new ArrayList(1); //IStatus |
| |
| private boolean useCompression = true; |
| private boolean createLeadupStructure = true; |
| private boolean generateManifestFile = false; |
| /** |
| * Create an instance of this class. Use this constructor if you wish to |
| * export specific resources without a common parent resource |
| * |
| * @param resources java.util.Vector |
| * @param filename java.lang.String |
| */ |
| public ZipFileResourceExportOperation(List resources,String filename) { |
| super(); |
| |
| // Eliminate redundancies in list of resources being exported |
| Iterator elementsEnum = resources.iterator(); |
| while (elementsEnum.hasNext()) { |
| IResource currentResource = (IResource) elementsEnum.next(); |
| if (isDescendent(resources, currentResource)) |
| elementsEnum.remove(); //Removes currentResource; |
| } |
| |
| resourcesToExport = resources; |
| destinationFilename = filename; |
| } |
| /** |
| * Create an instance of this class. Use this constructor if you wish |
| * to recursively export a single resource. |
| * |
| * @param res org.eclipse.core.resources.IResource; |
| * @param filename java.lang.String |
| */ |
| public ZipFileResourceExportOperation(IResource res,String filename) { |
| super(); |
| resource = res; |
| destinationFilename = filename; |
| } |
| /** |
| * Create an instance of this class. Use this constructor if you wish to |
| * export specific resources with a common parent resource (affects container |
| * directory creation) |
| * |
| * @param res org.eclipse.core.resources.IResource |
| * @param resources java.util.Vector |
| * @param filename java.lang.String |
| */ |
| public ZipFileResourceExportOperation(IResource res, List resources, String filename) { |
| this(res,filename); |
| resourcesToExport = resources; |
| } |
| /** |
| * Add a new entry to the error table with the passed information |
| */ |
| protected void addError(String message,Throwable e) { |
| errorTable.add( |
| new Status( |
| IStatus.ERROR, |
| PlatformUI.PLUGIN_ID, |
| 0, |
| message, |
| e)); |
| } |
| /** |
| * Answer the total number of file resources that exist at or below self |
| * in the resources hierarchy. |
| * |
| * @return int |
| * @param resource org.eclipse.core.resources.IResource |
| */ |
| protected int countChildrenOf(IResource resource) throws CoreException { |
| if (resource.getType() == IResource.FILE) |
| return 1; |
| |
| int count = 0; |
| if (resource.isAccessible()) { |
| IResource[] children = ((IContainer) resource).members(); |
| for (int i = 0; i<children.length; i++) |
| count += countChildrenOf(children[i]); |
| } |
| |
| return count; |
| } |
| /** |
| * Answer a boolean indicating the number of file resources that were |
| * specified for export |
| * |
| * @return int |
| */ |
| protected int countSelectedResources() throws CoreException { |
| int result = 0; |
| Iterator resources = resourcesToExport.iterator(); |
| while (resources.hasNext()) |
| result += countChildrenOf((IResource)resources.next()); |
| |
| return result; |
| } |
| /** |
| * Export the passed resource to the destination .zip |
| * |
| * @param resource org.eclipse.core.resources.IResource |
| */ |
| protected void exportResource(IResource resource) throws InterruptedException { |
| if (!resource.isAccessible()) |
| return; |
| |
| if (resource.getType() == IResource.FILE) { |
| String destinationName = resource.getFullPath().removeFirstSegments(leadupStartDepth).toString(); |
| monitor.subTask(destinationName); |
| |
| try { |
| exporter.write((IFile)resource,destinationName); |
| } catch (IOException e) { |
| addError(WorkbenchMessages.format("ZipExport.errorOnResource", new Object[] {resource.getFullPath()}) ,e); //$NON-NLS-1$ |
| } catch (CoreException e) { |
| addError(WorkbenchMessages.format("ZipExport.errorOnResource", new Object[] {resource.getFullPath()}) ,e); //$NON-NLS-1$ |
| } |
| |
| monitor.worked(1); |
| ModalContext.checkCanceled(monitor); |
| } else { |
| IResource[] children = null; |
| |
| try { |
| children = ((IContainer)resource).members(); |
| } catch (CoreException e) { |
| // this should never happen because an #isAccessible check is done before #members is invoked |
| addError(WorkbenchMessages.format("ZipExport.errorOnResource", new Object[] {resource.getFullPath()}) ,e); //$NON-NLS-1$ |
| } |
| |
| for (int i = 0; i<children.length; i++) |
| exportResource(children[i]); |
| } |
| } |
| /** |
| * Export the resources contained in the previously-defined |
| * resourcesToExport collection |
| */ |
| protected void exportSpecifiedResources() throws InterruptedException { |
| Iterator resources = resourcesToExport.iterator(); |
| |
| while (resources.hasNext()) { |
| IResource currentResource = (IResource)resources.next(); |
| if (resource == null && !createLeadupStructure) |
| leadupStartDepth = currentResource.getFullPath().segmentCount() - 1; |
| |
| exportResource(currentResource); |
| } |
| } |
| /** |
| * Answer the error table |
| * |
| * @return Vector of IStatus |
| */ |
| public List getResult() { |
| return errorTable; |
| } |
| /** |
| * Returns the status of the operation. |
| * If there were any errors, the result is a status object containing |
| * individual status objects for each error. |
| * If there were no errors, the result is a status object with error code <code>OK</code>. |
| * |
| * @return the status |
| */ |
| public IStatus getStatus() { |
| IStatus[] errors = new IStatus[errorTable.size()]; |
| errorTable.toArray(errors); |
| return new MultiStatus( |
| PlatformUI.PLUGIN_ID, |
| IStatus.OK, |
| errors, |
| WorkbenchMessages.getString("ZipExport.problemEncountered"), //$NON-NLS-1$ |
| null); |
| } |
| /** |
| * Initialize this operation |
| * |
| * @exception java.io.IOException |
| */ |
| protected void initialize() throws IOException { |
| exporter = new ZipFileResourceExporter(destinationFilename,useCompression,generateManifestFile); |
| |
| if (resource == null) // ie.- no parent resource was specified so just strip out projects |
| leadupStartDepth = 1; |
| else { |
| leadupStartDepth = resource.getFullPath().segmentCount(); |
| |
| if (resource.getType() == IResource.FILE) |
| leadupStartDepth--; |
| |
| if (createLeadupStructure) |
| leadupStartDepth = Math.min(1,leadupStartDepth); |
| } |
| } |
| /** |
| * Answer a boolean indicating whether the passed child is a descendent |
| * of one or more members of the passed resources collection |
| * |
| * @return boolean |
| * @param resources java.util.Vector |
| * @param child org.eclipse.core.resources.IResource |
| */ |
| protected boolean isDescendent(List resources, IResource child) { |
| if (child.getType() == IResource.PROJECT) |
| return false; |
| |
| IResource parent = child.getParent(); |
| if (resources.contains(parent)) |
| return true; |
| |
| return isDescendent(resources,parent); |
| } |
| /** |
| * Export the resources that were previously specified for export |
| * (or if a single resource was specified then export it recursively) |
| */ |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| this.monitor = monitor; |
| |
| try { |
| initialize(); |
| } catch (IOException e) { |
| throw new InvocationTargetException(e, WorkbenchMessages.getString("ZipExport.unableToOpen") + e.getMessage()); //$NON-NLS-1$ |
| } |
| |
| try { |
| // ie.- a single resource for recursive export was specified |
| int totalWork = IProgressMonitor.UNKNOWN; |
| try { |
| if (resourcesToExport == null) |
| totalWork = countChildrenOf(resource); |
| else |
| totalWork = countSelectedResources(); |
| } |
| catch (CoreException e) { |
| // Should not happen |
| } |
| monitor.beginTask(WorkbenchMessages.getString("ZipExport.progress"), totalWork); //$NON-NLS-1$ |
| if (resourcesToExport == null) { |
| exportResource(resource); |
| } |
| else { |
| // ie.- a list of specific resources to export was specified |
| exportSpecifiedResources(); |
| } |
| |
| try { |
| exporter.finished(); |
| } catch (IOException e) { |
| throw new InvocationTargetException(e, WorkbenchMessages.getString("ZipExport.unableToClose") + e.getMessage()); //$NON-NLS-1$ |
| } |
| } finally { |
| monitor.done(); |
| } |
| } |
| /** |
| * Set this boolean indicating whether each exported resource's path should |
| * include containment hierarchies as dictated by its parents |
| * |
| * @param value boolean |
| */ |
| public void setCreateLeadupStructure(boolean value) { |
| createLeadupStructure = value; |
| } |
| /** |
| * Set this boolean indicating whether a manifest.mf file based upon |
| * the exported contents should be created and included in the final |
| * archive |
| * |
| * @param value boolean |
| */ |
| public void setGenerateManifestFile(boolean value) { |
| generateManifestFile = value; |
| } |
| /** |
| * Set this boolean indicating whether exported resources should |
| * be compressed (as opposed to simply being stored) |
| * |
| * @param value boolean |
| */ |
| public void setUseCompression(boolean value) { |
| useCompression = value; |
| } |
| } |