-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 pull request introduces a mechanism for handling Zip Files within the Eclipse workspace, enhancing the functionality to read and write Zip files. The primary goal is to provide a seamless experience for developers working with zip archives directly within Eclipse. Zip files must be opened manually within the workspace by using the new command "Open Zip File" in the menu when right clicking the zip file. It is also possible to open nested zip files. Zip Files are opened by replacing the file in the workspace with a linked folder that reads and writes the Zip File in the file system. By closing the Zip FIle, the linked folder will be deleted and the file can be seen in the workspace again. Please note that only ZIP Archives are supported in this current implementation. Other archive types can be added in future improvements. Also linked Zip Files can not be opened with this implementation because the Zip File must be local. An additional PR for the repository **eclipse.platform.ui** that grants access to the open/close mechanism for zip files over UI can be found in the following: eclipse-platform/eclipse.platform.ui#1947 Co-Authored-By: David <David.Erdoes @vector.com>
- Loading branch information
1 parent
309a7f0
commit ff816b0
Showing
36 changed files
with
2,308 additions
and
571 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
...rces/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/ZipFileUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2024 Vector Informatik GmbH 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: Vector Informatik GmbH - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package org.eclipse.core.filesystem; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.net.URI; | ||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import org.eclipse.core.internal.filesystem.zip.ZipFileStore; | ||
import org.eclipse.core.runtime.CoreException; | ||
|
||
/** | ||
* Utility class to determine if a file is an archive based on file header information. | ||
* This class checks for known file signatures to identify if a given file is a ZIP archive | ||
* or a format based on ZIP, such as EPUB, JAR, ODF, and OOXML. | ||
* | ||
* @since 1.11 | ||
*/ | ||
public class ZipFileUtil { | ||
|
||
private static final Set<Integer> ARCHIVE_FILE_SIGNATURES = new HashSet<>(); | ||
|
||
static { | ||
// Initializes known archive file signatures from Wikipedia's list of file signatures | ||
// (https://en.wikipedia.org/wiki/List_of_file_signatures) | ||
ARCHIVE_FILE_SIGNATURES.add(0x504B0304); // Standard ZIP file | ||
ARCHIVE_FILE_SIGNATURES.add(0x504B0506); // Empty archive | ||
ARCHIVE_FILE_SIGNATURES.add(0x504B0708); // Spanned archive | ||
} | ||
|
||
/** | ||
* Determines if the given {@link IFileStore} represents an open ZIP file. | ||
* This can be used to check if operations on a ZIP file should be allowed or handled differently. | ||
* | ||
* @param store The file store to check. | ||
* @return true if the store is an instance of {@link ZipFileStore}, false otherwise. | ||
*/ | ||
public static boolean isInsideOpenZipFile(IFileStore store) { | ||
return store instanceof ZipFileStore; | ||
} | ||
|
||
public static boolean isInsideOpenZipFile(URI locationURI) { | ||
IFileStore store; | ||
try { | ||
store = EFS.getStore(locationURI); | ||
} catch (CoreException e) { | ||
return false; | ||
} | ||
return isInsideOpenZipFile(store); | ||
} | ||
|
||
//TODO Implement this method | ||
public static boolean isOpenZipFile(IFileStore store) { | ||
if (isInsideOpenZipFile(store)) { | ||
ZipFileStore zipStore = (ZipFileStore) store; | ||
return zipStore.getPath().isEmpty(); //if path is empty its the root | ||
} | ||
return false; | ||
} | ||
|
||
public static boolean isOpenZipFile(URI locationURI) { | ||
IFileStore store; | ||
try { | ||
store = EFS.getStore(locationURI); | ||
} catch (CoreException e) { | ||
return false; | ||
} | ||
return isOpenZipFile(store); | ||
} | ||
|
||
public static boolean isNested(URI fileURI) { | ||
if (fileURI.getScheme().contains("zip")) { //$NON-NLS-1$ | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Checks if the provided {@link InputStream} represents a ZIP archive | ||
* by reading its first four bytes and comparing them against known ZIP file signatures. | ||
* This method throws {@link IOException} if the file signature does not match any known ZIP archive signatures. | ||
* | ||
* @param fis The {@link InputStream} of the file to check. | ||
* @throws IOException If the file signature does not match known ZIP archive signatures | ||
* or an I/O error occurs during reading from the stream. | ||
*/ | ||
public static void checkFileForZipHeader(InputStream fis) throws IOException { | ||
byte[] bytes = new byte[4]; | ||
if (fis.read(bytes) == bytes.length) { | ||
ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN); | ||
int header = buffer.getInt(); | ||
|
||
if (!ARCHIVE_FILE_SIGNATURES.contains(header)) { | ||
throw new IOException("Invalid archive file signature."); // Throws IOException if header is not recognized //$NON-NLS-1$ | ||
} | ||
} else { | ||
// Handle the case where not enough bytes are read | ||
throw new IOException("Could not read enough data to check ZIP file header."); //$NON-NLS-1$ | ||
} | ||
} | ||
} |
Oops, something went wrong.