diff --git a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/ZipFileUtil.java b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/ZipFileUtil.java
index a98e963cda2..e87ca9b7140 100644
--- a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/ZipFileUtil.java
+++ b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/filesystem/ZipFileUtil.java
@@ -20,19 +20,13 @@
import org.eclipse.core.runtime.CoreException;
/**
- * Utility class to determine if a file is ZIP archive.
+ * Utility class for zip files.
*
* @since 1.11
*/
public class ZipFileUtil {
- /**
- * 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;
}
@@ -51,6 +45,13 @@ public static boolean isInsideOpenZipFile(URI locationURI) {
return isInsideOpenZipFile(store);
}
+ /**
+ * 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 isOpenZipFile(IFileStore store) {
if (isInsideOpenZipFile(store)) {
ZipFileStore zipStore = (ZipFileStore) store;
@@ -59,6 +60,9 @@ public static boolean isOpenZipFile(IFileStore store) {
return false;
}
+ /**
+ * @see ZipFileUtil#isOpenZipFile(IFileStore)
+ */
public static boolean isOpenZipFile(URI locationURI) {
IFileStore store;
try {
diff --git a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/zip/ZipFileStore.java b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/zip/ZipFileStore.java
index 832bbf9175c..7bf55c54a76 100644
--- a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/zip/ZipFileStore.java
+++ b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/zip/ZipFileStore.java
@@ -1,14 +1,15 @@
/*******************************************************************************
- * Copyright (c) 2022 IBM Corporation and others.
+ * 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/
+ * 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
+ * Contributors: Vector Informatik GmbH - initial API and implementation
*******************************************************************************/
+
package org.eclipse.core.internal.filesystem.zip;
import java.io.ByteArrayOutputStream;
@@ -53,7 +54,19 @@
* @since 1.11
*/
public class ZipFileStore extends FileStore {
+
+ /**
+ * A thread-safe map that associates each zip file's URI with a corresponding {@link ReentrantLock}.
+ *
+ * This map is used to ensure that each zip file is accessed by only one thread at a time, preventing
+ * concurrent access issues. The keys in the map are {@link URI} objects representing the zip files, and
+ * the values are {@link ReentrantLock} objects that are used to control access to the corresponding zip file.
+ * The map itself is wrapped with {@link Collections#synchronizedMap(Map)} to ensure thread safety
+ * when accessing the map.
+ *
+ */
private static final Map uriLockMap = Collections.synchronizedMap(new HashMap<>());
+
/**
* The path of this store within the zip file.
*/
@@ -64,9 +77,6 @@ public class ZipFileStore extends FileStore {
*/
private final IFileStore rootStore;
- /**
- * Creates a new zip file store.
- */
public ZipFileStore(IFileStore rootStore, IPath path) {
this.rootStore = rootStore;
this.path = path.makeRelative();
@@ -85,7 +95,6 @@ private ZipEntry[] childEntries(IProgressMonitor monitor) throws CoreException {
}
}
-
@Override
public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException {
ZipEntry[] entries = childEntries(monitor);
@@ -108,16 +117,13 @@ public String[] childNames(int options, IProgressMonitor monitor) throws CoreExc
return names;
}
- /**
- * Computes the simple file name for a given zip entry.
- */
private static String computeName(ZipEntry entry) {
String name = entry.getName();
// removes "/" at the end
if (name.endsWith("/")) { //$NON-NLS-1$
name = name.substring(0, name.length() - 1);
}
- // creates last segment after last /
+
int lastIndex = name.lastIndexOf('/');
if (lastIndex != -1) {
@@ -138,12 +144,6 @@ private IFileInfo convertToIFileInfo(Path zipEntryPath, BasicFileAttributes attr
return info;
}
- /**
- * Creates a file info object corresponding to a given zip entry
- *
- * @param entry the zip entry
- * @return The file info for a zip entry
- */
private static IFileInfo convertZipEntryToFileInfo(ZipEntry entry) {
FileInfo info = new FileInfo(computeName(entry));
if (entry.isDirectory()) {
@@ -308,6 +308,9 @@ private String getPluginId() {
return FrameworkUtil.getBundle(this.getClass()).getSymbolicName();
}
+ /**
+ * Returns the path of this file store.
+ */
public IPath getPath() {
return path;
}
@@ -424,7 +427,6 @@ public void close() throws IOException {
// Write the ByteArrayOutputStream's data to the entry
// in the ZIP file
Files.write(entryPath, this.toByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
-
} catch (Exception e) {
throw new IOException("Failed to integrate data into ZIP file", e); //$NON-NLS-1$
} finally {
@@ -499,7 +501,6 @@ public URI toURI() {
try {
return new URI(scheme, null, pathString, rootStoreQuery, null);
} catch (URISyntaxException e) {
- // should not happen
throw new RuntimeException(e);
}
}
@@ -513,7 +514,7 @@ private URI toNioURI() throws URISyntaxException {
return new URI(ret);
}
- void unlock() throws CoreException {
+ private void unlock() throws CoreException {
try {
ReentrantLock lock = getLockForURI(toNioURI());
if (lock.isHeldByCurrentThread()) {
diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/VirtualZipFolder.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/VirtualZipFolder.java
index ec4c9f52eb7..de73ce40c8f 100644
--- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/VirtualZipFolder.java
+++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/VirtualZipFolder.java
@@ -1,16 +1,15 @@
/*******************************************************************************
- * Copyright (c) 2024 IBM Corporation and others.
+ * 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
+ * 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
+ * Contributors: Vector Informatik GmbH - initial API and implementation
*******************************************************************************/
+
package org.eclipse.core.internal.resources;
import java.net.URISyntaxException;
@@ -38,23 +37,15 @@ public VirtualZipFolder(IPath path, Workspace container) {
@Override
public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
try {
- // Close the current ZIP file
ZipFileTransformer.closeZipFile(this);
-
- // Get the file representing the closed ZIP
IFile closedZipFile = this.getParent().getFile(new Path(this.getName()));
-
- // Copy the closed ZIP file to the destination
closedZipFile.copy(destination, updateFlags, monitor);
-
- // Get the copied ZIP file at the new destination
IFile copiedZipFile = ResourcesPlugin.getWorkspace().getRoot().getFile(destination);
// If the destination is not a nested ZIP, open the copied ZIP file
if (!ZipFileUtil.isInsideOpenZipFile(copiedZipFile.getLocationURI())) {
ZipFileTransformer.openZipFile(copiedZipFile, false);
}
-
// Reopen the original ZIP file
if (!ZipFileUtil.isInsideOpenZipFile(closedZipFile.getLocationURI())) {
ZipFileTransformer.openZipFile(closedZipFile, false);
@@ -85,16 +76,9 @@ public void delete(int updateFlags, IProgressMonitor monitor) throws CoreExcepti
@Override
public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
try {
- // Close the current ZIP file
ZipFileTransformer.closeZipFile(this);
-
- // Get the file representing the closed ZIP
IFile closedZipFile = this.getParent().getFile(new Path(this.getName()));
-
- // Move the closed ZIP file to the destination
closedZipFile.move(destination, updateFlags, monitor);
-
- // Get the moved ZIP file at the new destination
IFile movedZipFile = ResourcesPlugin.getWorkspace().getRoot().getFile(destination);
// If the destination is not a nested ZIP, open the moved ZIP file
diff --git a/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/ZipFileContentDescriber.java b/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/ZipFileContentDescriber.java
index ed1ef2b556f..ff1e9f88eee 100644
--- a/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/ZipFileContentDescriber.java
+++ b/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/ZipFileContentDescriber.java
@@ -17,7 +17,6 @@
/**
* @since 3.10
- *
*/
public class ZipFileContentDescriber extends TextContentDescriber {