Skip to content

Commit

Permalink
Proposal: Opening/Closing Mechanism for Zip Files
Browse files Browse the repository at this point in the history
The Eclipse IDE has no built in functionality to open Zip Files and read or manipulate their content. Because of this, other operations like searching inside of Zip Files or comparing two Zip Files were also not possible.

This PR introduces UI support for accesing the opening/closing mechanism for Zip Files over the UI-menu. It is accessed by right-clicking the Zip File that should be opened and then clicking on "Open Zip File". Closing is accessed the same way but when right-clicking an opened Zip File.

Please see #1408 for the PR on the repository **eclipse.platform** for the platform implementation and further information.

Co-Authored-By: David Erdös <[email protected]>

remove javadoc
  • Loading branch information
Michael5601 committed Jun 18, 2024
1 parent e5c00ef commit bb2d2c2
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 15 deletions.
4 changes: 3 additions & 1 deletion bundles/org.eclipse.ui.ide/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ command.copyMarkerResourceQualifiedName.name=Copy Resource Qualified Name To Cli
command.copyMarkerResourceQualifiedName.label=Resource Qualified Name
command.copyMarkerResourceQualifiedName.description=Copies markers resource qualified name to the clipboard
command.copyMarkerResourceQualifiedName.mnemonic=Q

command.name.openZipFile=Open Zip File
command.name.closeZipFile=Close Zip File
filesystem.file.zip=Zip file

command.showInQuickMenu.name= Show In...
command.showInQuickMenu.description = Open the Show In menu
Expand Down
70 changes: 68 additions & 2 deletions bundles/org.eclipse.ui.ide/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,17 @@
id="org.eclipse.ui.ide.markers.copyMarkerResourceQualifiedName"
name="%command.copyMarkerResourceQualifiedName.name"
defaultHandler="org.eclipse.ui.internal.views.markers.CopyMarkerResourceQualifiedNameHandler">
</command>
</command>
<command
id="org.eclipse.ui.commands.openZipFile"
name="%command.name.openZipFile"
defaultHandler="org.eclipse.ui.ide.fileSystem.zip.OpenZipFileHandler">
</command>
<command
id="org.eclipse.ui.commands.closeZipFile"
name="%command.name.closeZipFile"
defaultHandler="org.eclipse.ui.ide.fileSystem.zip.CloseZipFileHandler">
</command>
</extension>

<extension
Expand Down Expand Up @@ -2190,6 +2200,56 @@
</visibleWhen>
</command>
</menuContribution>
<menuContribution
allPopups="false"
locationURI="popup:org.eclipse.ui.popup.any?after=additions">
<command
commandId="org.eclipse.ui.commands.openZipFile"
label="%command.name.openZipFile"
style="push">
<visibleWhen
checkEnabled="false">
<with
variable="activeMenuSelection">
<iterate
ifEmpty="false">
<adapt
type="org.eclipse.core.resources.IFile">
<or>
<test
property="org.eclipse.core.resources.zipFile"
value="true">
</test>
</or>
</adapt>
</iterate>
</with>
</visibleWhen>
</command>
<command
commandId="org.eclipse.ui.commands.closeZipFile"
label="%command.name.closeZipFile"
style="push">
<visibleWhen
checkEnabled="false">
<with
variable="activeMenuSelection">
<iterate
ifEmpty="false">
<adapt
type="org.eclipse.core.resources.IFolder">
<or>
<test
property="org.eclipse.core.resources.extension"
value="zip">
</test>
</or>
</adapt>
</iterate>
</with>
</visibleWhen>
</command>
</menuContribution>
</extension>
<extension
point="org.eclipse.ui.handlers">
Expand Down Expand Up @@ -2718,5 +2778,11 @@
markerType="org.eclipse.core.resources.noExplicitEncoding">
</markerResolutionGenerator>
</extension>

<extension
point="org.eclipse.ui.ide.filesystemSupport">
<filesystemContributor
class="org.eclipse.ui.ide.fileSystem.zip.ZipFileSystemContributor"
label="%filesystem.file.zip"
scheme="zip"/>
</extension>
</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@

package org.eclipse.ui.ide.fileSystem.zip;

import java.net.URISyntaxException;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.ZipFileTransformer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;

/**
* This class represents a handler for closing an opened zip file.
Expand All @@ -38,6 +36,7 @@ public class CloseZipFileHandler extends AbstractHandler {
*/
@Override
public Object execute(ExecutionEvent event) {
Shell shell = HandlerUtil.getActiveShell(event);
ISelection selection = HandlerUtil.getCurrentSelection(event);

if (!(selection instanceof IStructuredSelection)) {
Expand All @@ -51,8 +50,9 @@ public Object execute(ExecutionEvent event) {
}
try {
ZipFileTransformer.closeZipFile((IFolder) element);
} catch (CoreException | URISyntaxException e) {
IDEWorkbenchPlugin.log(e.getMessage(), e);
} catch (Exception e) {
MessageDialog.openError(shell, "Error", "Error opening zip file"); //$NON-NLS-1$ //$NON-NLS-2$
e.printStackTrace();
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@

package org.eclipse.ui.ide.fileSystem.zip;

import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ZipFileTransformer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
Expand All @@ -41,21 +45,35 @@ public class OpenZipFileHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) {
Shell shell = HandlerUtil.getActiveShell(event);
ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (!(selection instanceof IStructuredSelection)) {
return null;
}

Object element = ((IStructuredSelection) selection).getFirstElement();

if (!(element instanceof IFile)) {
return null;
}

try {
ZipFileTransformer.openZipFile((IFile) element, true);
} catch (CoreException | URISyntaxException e) {
MessageDialog.openError(shell, "Error opening zip file", e.getMessage()); //$NON-NLS-1$
}
try {
dialog.run(true, false, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InterruptedException {
monitor.beginTask("Opening Zip File", 5); //$NON-NLS-1$
try {
ZipFileTransformer.openZipFile((IFile) element, monitor, true);
} catch (URISyntaxException | CoreException e) {
throw new InterruptedException(e.getMessage());
}
monitor.worked(1);
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
MessageDialog.openError(shell, "Error opening zip file", e.getMessage()); //$NON-NLS-1$
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2022 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.ide.fileSystem.zip;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;

import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ide.fileSystem.FileSystemContributor;

/**
* ZipFileSystemContributor is the zip example of a file system contributor.
*
* @since 3.23
*/
public class ZipFileSystemContributor extends FileSystemContributor {

public ZipFileSystemContributor() {
super();
}

@Override
public URI getURI(String pathString) {
try {
if (pathString.startsWith("zip")) //$NON-NLS-1$
return new URI(pathString);
} catch (URISyntaxException e1) {
return null;
}
if (File.separatorChar != '/')
pathString = pathString.replace(File.separatorChar, '/');
final int length = pathString.length();
StringBuffer pathBuf = new StringBuffer(length + 1);
pathBuf.append("file:"); //$NON-NLS-1$
// There must be a leading slash in a hierarchical URI
if (length > 0 && (pathString.charAt(0) != '/'))
pathBuf.append('/');
// additional double-slash for UNC paths to distinguish from host
// separator
if (pathString.startsWith("//")) //$NON-NLS-1$
pathBuf.append('/').append('/');
pathBuf.append(pathString);
try {
//scheme, host, path, query, fragment
return new URI("zip", null, "/", pathBuf.toString(), null); //$NON-NLS-1$ //$NON-NLS-2$
} catch (URISyntaxException e) {
return null;
}
}

@Override
public URI browseFileSystem(String initialPath, Shell shell) {

FileDialog dialog = new FileDialog(shell);

if (initialPath.length() > 0)
dialog.setFilterPath(initialPath);

dialog.setFilterExtensions(new String[] {"*.zip"});//$NON-NLS-1$

String selectedFile = dialog.open();
if (selectedFile == null)
return null;
return getURI(selectedFile);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.zip.ZipEntry;

import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.filesystem.ZipFileUtil;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
Expand Down Expand Up @@ -544,6 +545,14 @@ void importFile(Object fileObject, int policy, IProgressMonitor mon) {
targetResource.createLink(
createRelativePath(IPath.fromOSString(provider.getFullPath(fileObject)), targetResource), 0,
subMonitor.split(50));
} else if (ZipFileUtil.isOpenZipFile(targetResource.getLocationURI())) {// $NON-NLS-1$
// When overwriting an opened Zip File with a new Zip File that has the same
// name, the opened zip file needs to be deleted first.
IFolder openedZipFile = targetResource.getProject().getFolder(targetResource.getName());
if (openedZipFile.exists()) {
openedZipFile.delete(true, subMonitor.split(50));
}
targetResource.create(contentStream, false, subMonitor.split(50));
} else if (targetResource.exists()) {
if (targetResource.isLinked()) {
targetResource.delete(true, subMonitor.split(50));
Expand Down

0 comments on commit bb2d2c2

Please sign in to comment.