Skip to content

Commit bb2d2c2

Browse files
committed
Proposal: Opening/Closing Mechanism for Zip Files
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 <David.Erdoes@vector.com> remove javadoc
1 parent e5c00ef commit bb2d2c2

File tree

6 files changed

+191
-15
lines changed

6 files changed

+191
-15
lines changed

bundles/org.eclipse.ui.ide/plugin.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ command.copyMarkerResourceQualifiedName.name=Copy Resource Qualified Name To Cli
201201
command.copyMarkerResourceQualifiedName.label=Resource Qualified Name
202202
command.copyMarkerResourceQualifiedName.description=Copies markers resource qualified name to the clipboard
203203
command.copyMarkerResourceQualifiedName.mnemonic=Q
204-
204+
command.name.openZipFile=Open Zip File
205+
command.name.closeZipFile=Close Zip File
206+
filesystem.file.zip=Zip file
205207

206208
command.showInQuickMenu.name= Show In...
207209
command.showInQuickMenu.description = Open the Show In menu

bundles/org.eclipse.ui.ide/plugin.xml

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,17 @@
10891089
id="org.eclipse.ui.ide.markers.copyMarkerResourceQualifiedName"
10901090
name="%command.copyMarkerResourceQualifiedName.name"
10911091
defaultHandler="org.eclipse.ui.internal.views.markers.CopyMarkerResourceQualifiedNameHandler">
1092-
</command>
1092+
</command>
1093+
<command
1094+
id="org.eclipse.ui.commands.openZipFile"
1095+
name="%command.name.openZipFile"
1096+
defaultHandler="org.eclipse.ui.ide.fileSystem.zip.OpenZipFileHandler">
1097+
</command>
1098+
<command
1099+
id="org.eclipse.ui.commands.closeZipFile"
1100+
name="%command.name.closeZipFile"
1101+
defaultHandler="org.eclipse.ui.ide.fileSystem.zip.CloseZipFileHandler">
1102+
</command>
10931103
</extension>
10941104

10951105
<extension
@@ -2190,6 +2200,56 @@
21902200
</visibleWhen>
21912201
</command>
21922202
</menuContribution>
2203+
<menuContribution
2204+
allPopups="false"
2205+
locationURI="popup:org.eclipse.ui.popup.any?after=additions">
2206+
<command
2207+
commandId="org.eclipse.ui.commands.openZipFile"
2208+
label="%command.name.openZipFile"
2209+
style="push">
2210+
<visibleWhen
2211+
checkEnabled="false">
2212+
<with
2213+
variable="activeMenuSelection">
2214+
<iterate
2215+
ifEmpty="false">
2216+
<adapt
2217+
type="org.eclipse.core.resources.IFile">
2218+
<or>
2219+
<test
2220+
property="org.eclipse.core.resources.zipFile"
2221+
value="true">
2222+
</test>
2223+
</or>
2224+
</adapt>
2225+
</iterate>
2226+
</with>
2227+
</visibleWhen>
2228+
</command>
2229+
<command
2230+
commandId="org.eclipse.ui.commands.closeZipFile"
2231+
label="%command.name.closeZipFile"
2232+
style="push">
2233+
<visibleWhen
2234+
checkEnabled="false">
2235+
<with
2236+
variable="activeMenuSelection">
2237+
<iterate
2238+
ifEmpty="false">
2239+
<adapt
2240+
type="org.eclipse.core.resources.IFolder">
2241+
<or>
2242+
<test
2243+
property="org.eclipse.core.resources.extension"
2244+
value="zip">
2245+
</test>
2246+
</or>
2247+
</adapt>
2248+
</iterate>
2249+
</with>
2250+
</visibleWhen>
2251+
</command>
2252+
</menuContribution>
21932253
</extension>
21942254
<extension
21952255
point="org.eclipse.ui.handlers">
@@ -2718,5 +2778,11 @@
27182778
markerType="org.eclipse.core.resources.noExplicitEncoding">
27192779
</markerResolutionGenerator>
27202780
</extension>
2721-
2781+
<extension
2782+
point="org.eclipse.ui.ide.filesystemSupport">
2783+
<filesystemContributor
2784+
class="org.eclipse.ui.ide.fileSystem.zip.ZipFileSystemContributor"
2785+
label="%filesystem.file.zip"
2786+
scheme="zip"/>
2787+
</extension>
27222788
</plugin>

bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/fileSystem/zip/CloseZipFileHandler.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,15 @@
1212

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

15-
import java.net.URISyntaxException;
16-
1715
import org.eclipse.core.commands.AbstractHandler;
1816
import org.eclipse.core.commands.ExecutionEvent;
1917
import org.eclipse.core.resources.IFolder;
2018
import org.eclipse.core.resources.ZipFileTransformer;
21-
import org.eclipse.core.runtime.CoreException;
19+
import org.eclipse.jface.dialogs.MessageDialog;
2220
import org.eclipse.jface.viewers.ISelection;
2321
import org.eclipse.jface.viewers.IStructuredSelection;
22+
import org.eclipse.swt.widgets.Shell;
2423
import org.eclipse.ui.handlers.HandlerUtil;
25-
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
2624

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

4342
if (!(selection instanceof IStructuredSelection)) {
@@ -51,8 +50,9 @@ public Object execute(ExecutionEvent event) {
5150
}
5251
try {
5352
ZipFileTransformer.closeZipFile((IFolder) element);
54-
} catch (CoreException | URISyntaxException e) {
55-
IDEWorkbenchPlugin.log(e.getMessage(), e);
53+
} catch (Exception e) {
54+
MessageDialog.openError(shell, "Error", "Error opening zip file"); //$NON-NLS-1$ //$NON-NLS-2$
55+
e.printStackTrace();
5656
}
5757
return null;
5858
}

bundles/org.eclipse.ui.ide/src/org/eclipse/ui/ide/fileSystem/zip/OpenZipFileHandler.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@
1212

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

15+
import java.lang.reflect.InvocationTargetException;
1516
import java.net.URISyntaxException;
1617

1718
import org.eclipse.core.commands.AbstractHandler;
1819
import org.eclipse.core.commands.ExecutionEvent;
1920
import org.eclipse.core.resources.IFile;
2021
import org.eclipse.core.resources.ZipFileTransformer;
2122
import org.eclipse.core.runtime.CoreException;
23+
import org.eclipse.core.runtime.IProgressMonitor;
2224
import org.eclipse.jface.dialogs.MessageDialog;
25+
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
26+
import org.eclipse.jface.operation.IRunnableWithProgress;
2327
import org.eclipse.jface.viewers.ISelection;
2428
import org.eclipse.jface.viewers.IStructuredSelection;
2529
import org.eclipse.swt.widgets.Shell;
@@ -41,21 +45,35 @@ public class OpenZipFileHandler extends AbstractHandler {
4145
@Override
4246
public Object execute(ExecutionEvent event) {
4347
Shell shell = HandlerUtil.getActiveShell(event);
48+
ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell);
4449
ISelection selection = HandlerUtil.getCurrentSelection(event);
4550
if (!(selection instanceof IStructuredSelection)) {
4651
return null;
4752
}
4853

4954
Object element = ((IStructuredSelection) selection).getFirstElement();
55+
5056
if (!(element instanceof IFile)) {
5157
return null;
5258
}
53-
54-
try {
55-
ZipFileTransformer.openZipFile((IFile) element, true);
56-
} catch (CoreException | URISyntaxException e) {
57-
MessageDialog.openError(shell, "Error opening zip file", e.getMessage()); //$NON-NLS-1$
58-
}
59+
try {
60+
dialog.run(true, false, new IRunnableWithProgress() {
61+
@Override
62+
public void run(IProgressMonitor monitor) throws InterruptedException {
63+
monitor.beginTask("Opening Zip File", 5); //$NON-NLS-1$
64+
try {
65+
ZipFileTransformer.openZipFile((IFile) element, monitor, true);
66+
} catch (URISyntaxException | CoreException e) {
67+
throw new InterruptedException(e.getMessage());
68+
}
69+
monitor.worked(1);
70+
}
71+
});
72+
} catch (InvocationTargetException e) {
73+
e.printStackTrace();
74+
} catch (InterruptedException e) {
75+
MessageDialog.openError(shell, "Error opening zip file", e.getMessage()); //$NON-NLS-1$
76+
}
5977
return null;
6078
}
6179
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2022 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+
15+
package org.eclipse.ui.ide.fileSystem.zip;
16+
17+
import java.io.File;
18+
import java.net.URI;
19+
import java.net.URISyntaxException;
20+
21+
import org.eclipse.swt.widgets.FileDialog;
22+
import org.eclipse.swt.widgets.Shell;
23+
import org.eclipse.ui.ide.fileSystem.FileSystemContributor;
24+
25+
/**
26+
* ZipFileSystemContributor is the zip example of a file system contributor.
27+
*
28+
* @since 3.23
29+
*/
30+
public class ZipFileSystemContributor extends FileSystemContributor {
31+
32+
public ZipFileSystemContributor() {
33+
super();
34+
}
35+
36+
@Override
37+
public URI getURI(String pathString) {
38+
try {
39+
if (pathString.startsWith("zip")) //$NON-NLS-1$
40+
return new URI(pathString);
41+
} catch (URISyntaxException e1) {
42+
return null;
43+
}
44+
if (File.separatorChar != '/')
45+
pathString = pathString.replace(File.separatorChar, '/');
46+
final int length = pathString.length();
47+
StringBuffer pathBuf = new StringBuffer(length + 1);
48+
pathBuf.append("file:"); //$NON-NLS-1$
49+
// There must be a leading slash in a hierarchical URI
50+
if (length > 0 && (pathString.charAt(0) != '/'))
51+
pathBuf.append('/');
52+
// additional double-slash for UNC paths to distinguish from host
53+
// separator
54+
if (pathString.startsWith("//")) //$NON-NLS-1$
55+
pathBuf.append('/').append('/');
56+
pathBuf.append(pathString);
57+
try {
58+
//scheme, host, path, query, fragment
59+
return new URI("zip", null, "/", pathBuf.toString(), null); //$NON-NLS-1$ //$NON-NLS-2$
60+
} catch (URISyntaxException e) {
61+
return null;
62+
}
63+
}
64+
65+
@Override
66+
public URI browseFileSystem(String initialPath, Shell shell) {
67+
68+
FileDialog dialog = new FileDialog(shell);
69+
70+
if (initialPath.length() > 0)
71+
dialog.setFilterPath(initialPath);
72+
73+
dialog.setFilterExtensions(new String[] {"*.zip"});//$NON-NLS-1$
74+
75+
String selectedFile = dialog.open();
76+
if (selectedFile == null)
77+
return null;
78+
return getURI(selectedFile);
79+
}
80+
81+
}

bundles/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/datatransfer/ImportOperation.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.zip.ZipEntry;
2626

2727
import org.eclipse.core.filesystem.URIUtil;
28+
import org.eclipse.core.filesystem.ZipFileUtil;
2829
import org.eclipse.core.resources.IContainer;
2930
import org.eclipse.core.resources.IFile;
3031
import org.eclipse.core.resources.IFolder;
@@ -544,6 +545,14 @@ void importFile(Object fileObject, int policy, IProgressMonitor mon) {
544545
targetResource.createLink(
545546
createRelativePath(IPath.fromOSString(provider.getFullPath(fileObject)), targetResource), 0,
546547
subMonitor.split(50));
548+
} else if (ZipFileUtil.isOpenZipFile(targetResource.getLocationURI())) {// $NON-NLS-1$
549+
// When overwriting an opened Zip File with a new Zip File that has the same
550+
// name, the opened zip file needs to be deleted first.
551+
IFolder openedZipFile = targetResource.getProject().getFolder(targetResource.getName());
552+
if (openedZipFile.exists()) {
553+
openedZipFile.delete(true, subMonitor.split(50));
554+
}
555+
targetResource.create(contentStream, false, subMonitor.split(50));
547556
} else if (targetResource.exists()) {
548557
if (targetResource.isLinked()) {
549558
targetResource.delete(true, subMonitor.split(50));

0 commit comments

Comments
 (0)