diff --git a/resources/bundles/org.eclipse.core.resources/META-INF/MANIFEST.MF b/resources/bundles/org.eclipse.core.resources/META-INF/MANIFEST.MF
index 6a011fa99a9..bcfaaeb9ae8 100644
--- a/resources/bundles/org.eclipse.core.resources/META-INF/MANIFEST.MF
+++ b/resources/bundles/org.eclipse.core.resources/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.core.resources; singleton:=true
-Bundle-Version: 3.23.300.qualifier
+Bundle-Version: 3.24.0.qualifier
Bundle-Activator: org.eclipse.core.resources.ResourcesPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java
index 54a72e30207..eff57d98b85 100644
--- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java
+++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java
@@ -41,6 +41,7 @@
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -61,6 +62,12 @@
*/
public class File extends Resource implements IFile {
+ /**
+ * Session property used to mark a file as containing restricted content
+ */
+ private static final QualifiedName RESTRICTED_CONTENT =
+ new QualifiedName(ResourcesPlugin.PI_RESOURCES, "restrictedContent"); //$NON-NLS-1$
+
protected File(IPath path, Workspace container) {
super(path, container);
}
@@ -670,4 +677,14 @@ public String getLineSeparator(boolean checkParent) throws CoreException {
return checkParent ? getProject().getDefaultLineSeparator() : null;
}
+ @Override
+ public boolean isContentRestricted() throws CoreException {
+ Object sessionProperty = getSessionProperty(RESTRICTED_CONTENT);
+ return Boolean.TRUE.equals(sessionProperty);
+ }
+
+ @Override
+ public void setContentRestricted(boolean restricted) throws CoreException {
+ setSessionProperty(RESTRICTED_CONTENT, restricted ? Boolean.TRUE : null);
+ }
}
diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java
index 65864100f6b..c95fde8fd4f 100644
--- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java
+++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2026 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -21,7 +21,9 @@
import java.io.Reader;
import java.net.URI;
import java.util.Objects;
+import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.internal.utils.FileUtil;
+import org.eclipse.core.internal.utils.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
@@ -32,6 +34,7 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentTypeManager;
+import org.eclipse.osgi.util.NLS;
/**
* Files are leaf resources which contain data.
@@ -1414,4 +1417,37 @@ public default String readString() throws CoreException {
public default String getLineSeparator(boolean checkParent) throws CoreException {
return getProject().getDefaultLineSeparator();
}
+
+ /**
+ * Returns whether the current file is marked as containing restricted
+ * (sensitive) content, where some IDE functionality related to the file content
+ * might be limited. The file must exist.
+ *
+ * @return whether the current file is marked as containing sensitive content.
+ * This flag is not persisted and is {@code false} by default
+ * @throws CoreException if the file doesn't exist or if this method fails
+ * @since 3.24
+ */
+ default boolean isContentRestricted() throws CoreException {
+ if (!exists()) {
+ String message = NLS.bind(Messages.resources_mustExist, getFullPath());
+ throw new ResourceException(IResourceStatus.RESOURCE_NOT_FOUND, getFullPath(), message, null);
+ }
+ return false;
+ }
+
+ /**
+ * Marks the current file as containing restricted (sensitive) content. Some IDE
+ * functionality related to the file content might be limited as long as the
+ * file is marked as restricted. The file must exist. This flag is not persisted
+ * and is {@code false} by default.
+ *
+ * @param restricted true if the file should be marked restricted,
+ * false if the file should be unmarked
+ * @throws CoreException if the file doesn't exist or if this method fails
+ * @since 3.24
+ */
+ default void setContentRestricted(boolean restricted) throws CoreException {
+ throw new CoreException(Status.error("Not implemented")); //$NON-NLS-1$
+ }
}
diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/AllInternalResourcesTests.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/AllInternalResourcesTests.java
index 013b69e6e5b..fdfee9a0a0c 100644
--- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/AllInternalResourcesTests.java
+++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/AllInternalResourcesTests.java
@@ -32,6 +32,7 @@
ResourceInfoTest.class, //
WorkspaceConcurrencyTest.class, //
WorkspacePreferencesTest.class, //
+ RestrictedFileTests.class, //
})
public class AllInternalResourcesTests {
}
diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/RestrictedFileTests.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/RestrictedFileTests.java
new file mode 100644
index 00000000000..ddb7fdb7003
--- /dev/null
+++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/RestrictedFileTests.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Simeon Andreev 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:
+ * Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.tests.internal.resources;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(WorkspaceResetExtension.class)
+public class RestrictedFileTests {
+
+ @Test
+ public void testRestrictedFile() throws Exception {
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceRoot root = workspace.getRoot();
+ IProject project = root.getProject(RestrictedFileTests.class.getSimpleName());
+ try {
+ project.create(null);
+ project.open(null);
+
+ IFile file1 = project.getFile("test1.txt");
+ IFile file2 = project.getFile("test2.txt");
+
+ try {
+ file1.isContentRestricted();
+ fail("Should not work on not existing files");
+ } catch (CoreException e) {
+ // expected, file should not exist
+ }
+
+ file1.create("line 1".getBytes(), IResource.FORCE, null);
+ file2.create("line 1".getBytes(), IResource.FORCE, null);
+
+ assertFalse(file1.isContentRestricted(), "Expected file to not be restricted");
+ assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
+
+ file1.setContentRestricted(true);
+ assertTrue(file1.isContentRestricted(), "Expected file to be restricted");
+ assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
+
+ file1 = project.getFile("test1.txt");
+ file2 = project.getFile("test2.txt");
+ assertTrue(file1.isContentRestricted(), "Expected file to be restricted");
+ assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
+ } finally {
+ project.delete(true, null);
+ }
+ }
+}