diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 00000000000..c6c3f3df57b --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,32 @@ +name: "Copilot Setup Steps" + +# Automatically run the setup steps when they are changed to allow for easy validation, and +# allow manual testing through the repository's "Actions" tab +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + copilot-setup-steps: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Set up Maven 3.9.11 + uses: stCarolas/setup-maven@v5 + with: + maven-version: '3.9.11' + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..f152e6cacf6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,273 @@ +# Eclipse Platform Repository - AI Agent Instructions + +This file provides guidance for AI coding assistants (GitHub Copilot, Claude Code, etc.) working with this repository. + +## Repository Overview + +This repository contains the core Eclipse Platform components that form the basis for the Eclipse IDE. It is a **large-scale Java/OSGi project** (~120MB, 5,600+ Java files across 38 Maven modules) using **Maven/Tycho** for building Eclipse RCP bundles and features. + +**Key Technologies:** +- Language: Java (JDK 21) +- Build: Maven 3.9.11 with Eclipse Tycho (OSGi/RCP build tooling) +- Architecture: OSGi bundles organized as Eclipse plugins +- Testing: JUnit with Tycho Surefire plugin + +**Main Modules:** +- `runtime/` - Core runtime, jobs, expressions, content types (org.eclipse.core.runtime, org.eclipse.core.jobs) +- `resources/` - Workspace, filesystem, project management (org.eclipse.core.resources, org.eclipse.core.filesystem) +- `debug/` - Debug framework and UI, external tools, launch configurations +- `team/` - Version control framework (CVS examples) +- `ua/` - User assistance: help system, cheatsheets, tips +- `ant/` - Ant integration and UI +- `terminal/` - Terminal view +- `platform/` - SDK packaging + +## Critical Build Information + +The `-Pbuild-individual-bundles` profile (configured in `.mvn/maven.config`) enables the bundle to fetch the parent POM from https://repo.eclipse.org/content/repositories/eclipse/. + +**Note:** If network access to Eclipse repositories is blocked, individual bundle builds will fail. In such environments, code exploration and analysis can still be performed, but build verification is not possible. + +### Build Profiles Used in CI + +The Jenkinsfile shows the complete build command: +```bash +mvn clean verify --batch-mode --fail-at-end \ + -Pbree-libs -Papi-check -Pjavadoc \ + -Dmaven.test.failure.ignore=true \ + -Dcompare-version-with-baselines.skip=false \ + -Dmaven.compiler.failOnWarning=false +``` + +Key profiles: +- `-Pbree-libs` - Bundle Runtime Execution Environment libraries +- `-Papi-check` - API baseline comparison (detects breaking changes) +- `-Pjavadoc` - Generate Javadoc + +## Testing + +**Test Organization:** +- Tests are in `/tests/` subdirectories (e.g., `runtime/tests/`, `resources/tests/`) +- Test bundles follow naming: `org.eclipse..tests.` +- Tests use JUnit 4/5 with Tycho Surefire + +**Running Tests:** +```bash +# Run tests for a specific bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# Tests are automatically run during 'mvn verify' +# Test results: target/surefire-reports/TEST-*.xml +``` + +**Important Test Notes:** +- Some tests require graphical display (use Xvnc in CI - see Jenkinsfile) +- Tests in `debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/LocalSuite.java` require user terminal and should NOT run on build machines +- Test failures are allowed in CI (`-Dmaven.test.failure.ignore=true`) + +## Validation & CI Checks + +### GitHub Actions Workflows + +All workflows delegate to the aggregator repository: + +1. **PR Checks** (`.github/workflows/pr-checks.yml`): + - Freeze period verification + - No merge commits check + - Version increment verification (uses PDE API Tools) + +2. **Continuous Integration** (`.github/workflows/ci.yml`): + - Delegates to `mavenBuild.yml` in aggregator + - Runs full build with all profiles + +3. **CodeQL** (`.github/workflows/codeql.yml`): + - Security scanning for Java code + +### Local Validation Steps + +Before committing, verify your changes: + +```bash +# 1. Build the affected bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# 2. Check for API issues (PDE API Tools) +# API baseline checks run automatically with -Papi-check +# Results in: target/apianalysis/*.xml + +# 3. Check for compiler warnings +# Results in: target/compilelogs/*.xml +``` + +### API Tools & Version Management + +**Critical:** Eclipse uses semantic versioning with API tooling enforcement: +- Major version: Breaking API changes +- Minor version: Binary compatible API additions, significant changes +- Service version: Bug fixes (increments: +1 for maintenance, +100 for next release) +- Qualifier: Build timestamp + +**Version Change Rules:** +1. API breaking change → Increment major version, reset minor/service to 0 +2. API addition (binary compatible) → Increment minor version, reset service to 0 +3. Bug fix in maintenance → Increment service by 1 +4. Bug fix in next release → Increment service by 100 + +**PDE API Tools automatically detects API changes and enforces version increments.** + +See `docs/VersionNumbering.md` and `docs/Evolving-Java-based-APIs.md` for complete details. + +## Project Structure + +### Root Files +- `pom.xml` - Main reactor POM (defines modules) +- `Jenkinsfile` - Jenkins CI pipeline configuration +- `.mvn/maven.config` - Default Maven options (includes `-Pbuild-individual-bundles`) +- `.gitignore` - Excludes `target/`, `bin/`, `*.class`, etc. + +### Key Configuration Files + +**Per Bundle:** +- `pom.xml` - Maven coordinates and build config +- `META-INF/MANIFEST.MF` - OSGi bundle manifest (Bundle-SymbolicName, Bundle-Version, dependencies) +- `build.properties` - Tycho/PDE build configuration (source folders, bin.includes) +- `.project` - Eclipse project descriptor +- `.classpath` - Eclipse classpath (typically generated) + +**Coding Standards:** +- `docs/Coding_Conventions.md` - Java coding style (follows Oracle conventions with modifications) +- `docs/Naming_Conventions.md` - Package/class naming rules +- Indent with tabs (4 spaces wide) +- Encoding: UTF-8 (see `.settings/org.eclipse.core.resources.prefs`) + +## Common Pitfalls & Solutions + +### 1. Parent POM Resolution Failure +**Error:** `Non-resolvable parent POM for org.eclipse.platform:eclipse.platform` + +**Solution:** Always use `-Pbuild-individual-bundles` profile when building individual bundles. This profile is pre-configured in `.mvn/maven.config` but may be needed explicitly in some contexts. + +### 2. Missing Dependencies During Build +**Error:** Cannot resolve bundle dependencies + +**Solution:** +- Individual bundles fetch dependencies from Eclipse repositories +- Ensure https://repo.eclipse.org is accessible +- Clean local Maven cache if corrupted: `rm -rf ~/.m2/repository/org/eclipse` + +### 3. Test Failures Requiring Display +**Error:** Tests fail with "No display available" + +**Solution:** +- Tests requiring GUI run automatically on CI (Xvnc configured in Jenkinsfile) +- For local testing, use Xvfb: `xvfb-run mvn verify` +- Or skip tests: `mvn verify -DskipTests` + +### 4. API Tools Errors +**Error:** "API baseline errors found" + +**Solution:** +- Review changes in `target/apianalysis/*.xml` +- If API changed, update bundle version in `META-INF/MANIFEST.MF` +- Follow version increment rules (see docs/VersionNumbering.md) +- For intentional API breaks, update baseline comparison + +### 5. Build Timeouts +Maven operations can take considerable time: +- Clean build of single bundle: 1-3 minutes +- Full platform build (aggregator): 30-60 minutes +- Test execution: Variable, some test suites take 10+ minutes + +**Set adequate timeouts when building (default 120s may not be enough):** +```bash +mvn verify -Pbuild-individual-bundles # May need 180-300 seconds +``` + +## Making Changes + +### Typical Change Workflow + +1. **Locate the Bundle:** + - Runtime/core services → `runtime/bundles/` + - Resource/workspace → `resources/bundles/` + - Debug/launch → `debug/` + - Help/documentation → `ua/` + +2. **Make Code Changes:** + - Edit Java sources in bundle's `src/` directory + - Follow coding conventions (see `docs/Coding_Conventions.md`) + - Add/update Javadoc for public APIs + +3. **Update MANIFEST.MF if needed:** + - Changed API? Update `Bundle-Version` following semantic versioning + - New dependencies? Add to `Require-Bundle` or `Import-Package` + +4. **Build and Test:** + ```bash + cd + mvn clean verify -Pbuild-individual-bundles + ``` + +5. **Verify No API Issues:** + - Check `target/apianalysis/*.xml` for API baseline errors + - Address any version increment requirements + +6. **Commit:** + - Write clear commit message + - Reference issue number if applicable + +## File Locations Reference + +**Documentation:** All in `docs/` +- `docs/Coding_Conventions.md` - Code style +- `docs/API_Central.md` - API guidelines hub +- `docs/VersionNumbering.md` - Version management +- `docs/FAQ/` - 200+ FAQ markdown files + +**Build Configuration:** +- `.mvn/maven.config` - Maven CLI defaults +- `Jenkinsfile` - CI build definition (60 min timeout) +- `.github/workflows/*.yml` - GitHub Actions (all delegate to aggregator) + +**Key Bundle Directories:** +- `runtime/bundles/org.eclipse.core.runtime` - Core Platform Runtime +- `runtime/bundles/org.eclipse.core.jobs` - Jobs and scheduling +- `resources/bundles/org.eclipse.core.resources` - Workspace API +- `resources/bundles/org.eclipse.core.filesystem` - Filesystem abstraction + +## Working Efficiently + +**Trust these instructions first.** This repository has a complex build setup that cannot be fully explored from the repository alone. The information above captures the essential knowledge needed to: +- Understand build requirements and limitations +- Make targeted changes without breaking CI +- Navigate the codebase effectively +- Avoid common build pitfalls + +Only search beyond these instructions if: +- Specific API behavior needs clarification (check `docs/FAQ/`) +- Detailed versioning rules are needed (check `docs/VersionNumbering.md`) +- You need examples of existing code patterns (search Java sources) +- CI is failing with an error not covered here (check Jenkinsfile and workflow YAMLs) + +**When in doubt:** Build at the bundle level with `-Pbuild-individual-bundles` profile and verify tests pass locally before pushing changes. + +## AI Agent-Specific Notes + +### For GitHub Copilot +- This file is automatically read by GitHub Copilot when providing code suggestions +- Copilot uses this context to understand the project structure and conventions +- Copilot excels at inline code completion and small-scale refactoring + +### For Claude Code +- Claude Code has access to this file via the `CLAUDE.md` file in the repository root +- Claude Code is better suited for multi-file refactoring and architectural changes +- Use Claude Code for tasks requiring deep codebase understanding across multiple modules +- Claude Code can execute builds and tests directly via Maven commands + +### For Other AI Agents +- Read this file to understand the repository structure and build requirements +- Follow the coding conventions in `docs/Coding_Conventions.md` +- Always test changes with `mvn clean verify -Pbuild-individual-bundles` before committing +- Check API baseline with `-Papi-check` when modifying public APIs diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..20a6465a4e4 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,267 @@ +# Eclipse Platform Repository - Copilot Instructions + +## Repository Overview + +This repository contains the core Eclipse Platform components that form the basis for the Eclipse IDE. It is a **large-scale Java/OSGi project** (~120MB, 5,600+ Java files across 38 Maven modules) using **Maven/Tycho** for building Eclipse RCP bundles and features. + +**Key Technologies:** +- Language: Java (JDK 17+, targets JDK 21 in CI) +- Build: Maven 3.9+ with Eclipse Tycho (OSGi/RCP build tooling) +- Architecture: OSGi bundles organized as Eclipse plugins +- Testing: JUnit with Tycho Surefire plugin + +**Main Modules:** +- `runtime/` - Core runtime, jobs, expressions, content types (org.eclipse.core.runtime, org.eclipse.core.jobs) +- `resources/` - Workspace, filesystem, project management (org.eclipse.core.resources, org.eclipse.core.filesystem) +- `debug/` - Debug framework and UI, external tools, launch configurations +- `team/` - Version control framework (CVS examples) +- `ua/` - User assistance: help system, cheatsheets, tips +- `ant/` - Ant integration and UI +- `terminal/` - Terminal view +- `platform/` - SDK packaging + +## Critical Build Information + +**⚠️ IMPORTANT: This repository CANNOT be built in isolation.** It depends on a parent POM (`eclipse-platform-parent`) from the [eclipse.platform.releng.aggregator](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator) repository. + +### Individual Bundle Builds + +Individual bundles CAN be built using the pre-configured profile if you have network access to Eclipse repositories: + +```bash +cd # e.g., runtime/bundles/org.eclipse.core.runtime +mvn clean verify -Pbuild-individual-bundles +``` + +The `-Pbuild-individual-bundles` profile (configured in `.mvn/maven.config`) enables the bundle to fetch the parent POM from https://repo.eclipse.org/content/repositories/eclipse/. + +**Note:** If network access to Eclipse repositories is blocked, individual bundle builds will fail. In such environments, code exploration and analysis can still be performed, but build verification is not possible. + +### Full Platform Build + +For full platform builds, use the aggregator repository which includes this repo as a Git submodule. The CI workflows in this repository delegate to workflows in the aggregator repository. + +### Build Profiles Used in CI + +The Jenkinsfile shows the complete build command: +```bash +mvn clean verify --batch-mode --fail-at-end \ + -Pbree-libs -Papi-check -Pjavadoc \ + -Dmaven.test.failure.ignore=true \ + -Dcompare-version-with-baselines.skip=false \ + -Dmaven.compiler.failOnWarning=false +``` + +Key profiles: +- `-Pbree-libs` - Bundle Runtime Execution Environment libraries +- `-Papi-check` - API baseline comparison (detects breaking changes) +- `-Pjavadoc` - Generate Javadoc + +## Testing + +**Test Organization:** +- Tests are in `/tests/` subdirectories (e.g., `runtime/tests/`, `resources/tests/`) +- Test bundles follow naming: `org.eclipse..tests.` +- Tests use JUnit 4/5 with Tycho Surefire + +**Running Tests:** +```bash +# Run tests for a specific bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# Tests are automatically run during 'mvn verify' +# Test results: target/surefire-reports/TEST-*.xml +``` + +**Important Test Notes:** +- Some tests require graphical display (use Xvnc in CI - see Jenkinsfile) +- Tests in `debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/LocalSuite.java` require user terminal and should NOT run on build machines +- Test failures are allowed in CI (`-Dmaven.test.failure.ignore=true`) + +## Validation & CI Checks + +### GitHub Actions Workflows + +All workflows delegate to the aggregator repository: + +1. **PR Checks** (`.github/workflows/pr-checks.yml`): + - Freeze period verification + - No merge commits check + - Version increment verification (uses PDE API Tools) + +2. **Continuous Integration** (`.github/workflows/ci.yml`): + - Delegates to `mavenBuild.yml` in aggregator + - Runs full build with all profiles + +3. **CodeQL** (`.github/workflows/codeql.yml`): + - Security scanning for Java code + +### Local Validation Steps + +Before committing, verify your changes: + +```bash +# 1. Build the affected bundle +cd +mvn clean verify -Pbuild-individual-bundles + +# 2. Check for API issues (PDE API Tools) +# API baseline checks run automatically with -Papi-check +# Results in: target/apianalysis/*.xml + +# 3. Check for compiler warnings +# Results in: target/compilelogs/*.xml +``` + +### API Tools & Version Management + +**Critical:** Eclipse uses semantic versioning with API tooling enforcement: +- Major version: Breaking API changes +- Minor version: Binary compatible API additions, significant changes +- Service version: Bug fixes (increments: +1 for maintenance, +100 for next release) +- Qualifier: Build timestamp + +**Version Change Rules:** +1. API breaking change → Increment major version, reset minor/service to 0 +2. API addition (binary compatible) → Increment minor version, reset service to 0 +3. Bug fix in maintenance → Increment service by 1 +4. Bug fix in next release → Increment service by 100 + +**PDE API Tools automatically detects API changes and enforces version increments.** + +See `docs/VersionNumbering.md` and `docs/Evolving-Java-based-APIs.md` for complete details. + +## Project Structure + +### Root Files +- `pom.xml` - Main reactor POM (defines modules) +- `Jenkinsfile` - Jenkins CI pipeline configuration +- `.mvn/maven.config` - Default Maven options (includes `-Pbuild-individual-bundles`) +- `.gitignore` - Excludes `target/`, `bin/`, `*.class`, etc. + +### Key Configuration Files + +**Per Bundle:** +- `pom.xml` - Maven coordinates and build config +- `META-INF/MANIFEST.MF` - OSGi bundle manifest (Bundle-SymbolicName, Bundle-Version, dependencies) +- `build.properties` - Tycho/PDE build configuration (source folders, bin.includes) +- `.project` - Eclipse project descriptor +- `.classpath` - Eclipse classpath (typically generated) + +**Coding Standards:** +- `docs/Coding_Conventions.md` - Java coding style (follows Oracle conventions with modifications) +- `docs/Naming_Conventions.md` - Package/class naming rules +- Indent with tabs (4 spaces wide) +- Encoding: UTF-8 (see `.settings/org.eclipse.core.resources.prefs`) + +## Common Pitfalls & Solutions + +### 1. Parent POM Resolution Failure +**Error:** `Non-resolvable parent POM for org.eclipse.platform:eclipse.platform` + +**Solution:** Always use `-Pbuild-individual-bundles` profile when building individual bundles. This profile is pre-configured in `.mvn/maven.config` but may be needed explicitly in some contexts. + +### 2. Missing Dependencies During Build +**Error:** Cannot resolve bundle dependencies + +**Solution:** +- Individual bundles fetch dependencies from Eclipse repositories +- Ensure https://repo.eclipse.org is accessible +- Clean local Maven cache if corrupted: `rm -rf ~/.m2/repository/org/eclipse` + +### 3. Test Failures Requiring Display +**Error:** Tests fail with "No display available" + +**Solution:** +- Tests requiring GUI run automatically on CI (Xvnc configured in Jenkinsfile) +- For local testing, use Xvfb: `xvfb-run mvn verify` +- Or skip tests: `mvn verify -DskipTests` + +### 4. API Tools Errors +**Error:** "API baseline errors found" + +**Solution:** +- Review changes in `target/apianalysis/*.xml` +- If API changed, update bundle version in `META-INF/MANIFEST.MF` +- Follow version increment rules (see docs/VersionNumbering.md) +- For intentional API breaks, update baseline comparison + +### 5. Build Timeouts +Maven operations can take considerable time: +- Clean build of single bundle: 1-3 minutes +- Full platform build (aggregator): 30-60 minutes +- Test execution: Variable, some test suites take 10+ minutes + +**Set adequate timeouts when building (default 120s may not be enough):** +```bash +mvn verify -Pbuild-individual-bundles # May need 180-300 seconds +``` + +## Making Changes + +### Typical Change Workflow + +1. **Locate the Bundle:** + - Runtime/core services → `runtime/bundles/` + - Resource/workspace → `resources/bundles/` + - Debug/launch → `debug/` + - Help/documentation → `ua/` + +2. **Make Code Changes:** + - Edit Java sources in bundle's `src/` directory + - Follow coding conventions (see `docs/Coding_Conventions.md`) + - Add/update Javadoc for public APIs + +3. **Update MANIFEST.MF if needed:** + - Changed API? Update `Bundle-Version` following semantic versioning + - New dependencies? Add to `Require-Bundle` or `Import-Package` + +4. **Build and Test:** + ```bash + cd + mvn clean verify -Pbuild-individual-bundles + ``` + +5. **Verify No API Issues:** + - Check `target/apianalysis/*.xml` for API baseline errors + - Address any version increment requirements + +6. **Commit:** + - Write clear commit message + - Reference issue number if applicable + +## File Locations Reference + +**Documentation:** All in `docs/` +- `docs/Coding_Conventions.md` - Code style +- `docs/API_Central.md` - API guidelines hub +- `docs/VersionNumbering.md` - Version management +- `docs/FAQ/` - 200+ FAQ markdown files + +**Build Configuration:** +- `.mvn/maven.config` - Maven CLI defaults +- `Jenkinsfile` - CI build definition (60 min timeout) +- `.github/workflows/*.yml` - GitHub Actions (all delegate to aggregator) + +**Key Bundle Directories:** +- `runtime/bundles/org.eclipse.core.runtime` - Core Platform Runtime +- `runtime/bundles/org.eclipse.core.jobs` - Jobs and scheduling +- `resources/bundles/org.eclipse.core.resources` - Workspace API +- `resources/bundles/org.eclipse.core.filesystem` - Filesystem abstraction + +## Working Efficiently + +**Trust these instructions first.** This repository has a complex build setup that cannot be fully explored from the repository alone. The information above captures the essential knowledge needed to: +- Understand build requirements and limitations +- Make targeted changes without breaking CI +- Navigate the codebase effectively +- Avoid common build pitfalls + +Only search beyond these instructions if: +- Specific API behavior needs clarification (check `docs/FAQ/`) +- Detailed versioning rules are needed (check `docs/VersionNumbering.md`) +- You need examples of existing code patterns (search Java sources) +- CI is failing with an error not covered here (check Jenkinsfile and workflow YAMLs) + +**When in doubt:** Build at the bundle level with `-Pbuild-individual-bundles` profile and verify tests pass locally before pushing changes. diff --git a/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF index 9c9a10f1a42..b3c019c6195 100644 --- a/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.launching/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Localization: plugin Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.launching;singleton:=true -Bundle-Version: 1.4.800.qualifier +Bundle-Version: 1.4.900.qualifier Bundle-Activator: org.eclipse.ant.internal.launching.AntLaunching Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)", diff --git a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java index e1cf4bcd058..a86b89148c2 100644 --- a/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java +++ b/ant/org.eclipse.ant.launching/src/org/eclipse/ant/internal/launching/AntLaunchingUtil.java @@ -345,7 +345,7 @@ public static IFile getFileForLocation(String path, File buildFileParent) { * if unable to migrate * @since 3.0 */ - @SuppressWarnings({ "restriction", "deprecation" }) + @SuppressWarnings({ "deprecation" }) public static void migrateToNewClasspathFormat(ILaunchConfiguration configuration) throws CoreException { String oldClasspath = configuration.getAttribute(AntLaunching.ATTR_ANT_CUSTOM_CLASSPATH, (String) null); String oldAntHome = configuration.getAttribute(AntLaunching.ATTR_ANT_HOME, (String) null); diff --git a/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF index 94398ae36fa..9e60c66d22b 100644 --- a/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.tests.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.tests.core; singleton:=true -Bundle-Version: 3.7.600.qualifier +Bundle-Version: 3.7.700.qualifier Bundle-ClassPath: anttestscore.jar Bundle-Activator: org.eclipse.ant.tests.core.testplugin.AntTestPlugin Bundle-Vendor: %providerName @@ -17,9 +17,9 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional, org.eclipse.ant.core, org.eclipse.core.runtime Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir diff --git a/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF index 41bfd504e19..3b147d54a5a 100644 --- a/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.tests.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.tests.ui; singleton:=true -Bundle-Version: 3.12.200.qualifier +Bundle-Version: 3.12.300.qualifier Bundle-ClassPath: anttestsui.jar Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -39,8 +39,8 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional, org.eclipse.core.externaltools Import-Package: org.assertj.core.api, org.assertj.core.api.iterable, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-21 Eclipse-BundleShape: dir diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java index e4ae08edbf6..ad540ae4db5 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/datatransfer/AntNewJavaProjectPage.java @@ -270,7 +270,7 @@ private void handleBrowseButtonPressed() { String lastUsedPath = IAntCoreConstants.EMPTY_STRING; FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ ; + dialog.setFilterExtensions("*.xml"); //$NON-NLS-1$ ; dialog.setFilterPath(lastUsedPath); String result = dialog.open(); diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java index b95781c1511..ce5a3c79b6c 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java @@ -239,7 +239,7 @@ private void addExternalJars() { lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString(); } FileDialog dialog = new FileDialog(treeViewer.getControl().getShell(), SWT.MULTI | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.jar;*.zip" }); //$NON-NLS-1$ + dialog.setFilterExtensions("*.jar;*.zip"); //$NON-NLS-1$ dialog.setFilterPath(lastUsedPath); String result = dialog.open(); diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java index ac765190200..7e4e667f8ea 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPropertiesBlock.java @@ -411,7 +411,7 @@ private void addExternalPropertyFile() { lastUsedPath = IAntCoreConstants.EMPTY_STRING; } FileDialog dialog = new FileDialog(fileTableViewer.getControl().getShell(), SWT.MULTI | SWT.SHEET); - dialog.setFilterExtensions(new String[] { "*.properties", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$ ; + dialog.setFilterExtensions("*.properties", "*.*"); //$NON-NLS-1$ //$NON-NLS-2$ ; dialog.setFilterPath(lastUsedPath); String result = dialog.open(); diff --git a/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF b/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF index 5ba2810b4d3..c14ad5fe8e8 100644 --- a/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF +++ b/ant/org.eclipse.ant.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ant.ui; singleton:=true -Bundle-Version: 3.10.200.qualifier +Bundle-Version: 3.10.300.qualifier Bundle-Activator: org.eclipse.ant.internal.ui.AntUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java index 36c94571fa2..06ffe1c8dd0 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java @@ -1006,6 +1006,7 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env public static Process exec(String[] cmdLine, File workingDirectory, String[] envp, boolean mergeOutput) throws CoreException { List factories = DebugPlugin.getDefault().getExecFactories(); Optional directory = shortenWindowsPath(workingDirectory); + String[] shortenedCmdLine = shortenWindowsCommandLine(cmdLine); Optional> envMap = Optional.ofNullable(envp).map(array -> { Map map = new LinkedHashMap<>(); for (String e : array) { @@ -1017,7 +1018,7 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env return Map.copyOf(map); }); for (ExecFactoryFacade holder : factories) { - Optional exec = holder.exec(cmdLine.clone(), directory, envMap, mergeOutput); + Optional exec = holder.exec(shortenedCmdLine.clone(), directory, envMap, mergeOutput); if (exec.isPresent()) { return exec.get(); } @@ -1029,7 +1030,7 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env // ProcessBuilder and Runtime.exec only the new option uses process // builder to not break existing caller of this method if (mergeOutput) { - ProcessBuilder pb = new ProcessBuilder(cmdLine); + ProcessBuilder pb = new ProcessBuilder(shortenedCmdLine); directory.ifPresent(pb::directory); pb.redirectErrorStream(mergeOutput); if (envMap.isPresent()) { @@ -1039,9 +1040,9 @@ public static Process exec(String[] cmdLine, File workingDirectory, String[] env } return pb.start(); } else if (directory.isEmpty()) { - return Runtime.getRuntime().exec(cmdLine, envp); + return Runtime.getRuntime().exec(shortenedCmdLine, envp); } else { - return Runtime.getRuntime().exec(cmdLine, envp, directory.get()); + return Runtime.getRuntime().exec(shortenedCmdLine, envp, directory.get()); } } catch (IOException e) { Status status = new Status(IStatus.ERROR, getUniqueIdentifier(), ERROR, DebugCoreMessages.DebugPlugin_0, e); @@ -1083,6 +1084,50 @@ private static Optional shortenWindowsPath(File path) { return Optional.ofNullable(path); } + /** + * Shortens the command line elements if they exceed Windows MAX_PATH limit. + * This is necessary because Windows process creation APIs have problems with + * long paths, even when launching executables or passing file arguments. + * + * @param cmdLine the command line array + * @return the potentially shortened command line array + */ + private static String[] shortenWindowsCommandLine(String[] cmdLine) { + if (cmdLine == null || cmdLine.length == 0 || !Platform.OS.isWindows()) { + return cmdLine; + } + + String[] result = cmdLine.clone(); + boolean modified = false; + + // Check and shorten each path-like argument in the command line + // The first element is typically the executable path, which is most critical + for (int i = 0; i < result.length; i++) { + String arg = result[i]; + if (arg != null && arg.length() > WINDOWS_MAX_PATH) { + // Check if this looks like a file path + File file = new File(arg); + if (file.isAbsolute()) { + @SuppressWarnings("restriction") + String shortPath = org.eclipse.core.internal.filesystem.local.Win32Handler.getShortPathName(arg); + if (shortPath != null) { + result[i] = shortPath; + modified = true; + if (i == 0) { + // Log only for the executable (first argument) + logDebugMessage("Shortened executable path from " + arg.length() + " to " + shortPath.length() + " characters"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } else if (i == 0) { + // Only warn for the executable path, as that's the most critical + log(Status.warning("Executable path exceeds Window's MAX_PATH limit and shortening the path failed: " + arg)); //$NON-NLS-1$ + } + } + } + } + + return modified ? result : cmdLine; + } + /** * Returns whether this plug-in is in the process of * being shutdown. @@ -1285,8 +1330,8 @@ public boolean equals(Object obj) { private static class ExecFactoryFacade implements ExecFactory { - private IConfigurationElement element; - private int priority; + private final IConfigurationElement element; + private final int priority; ExecFactoryFacade(IConfigurationElement element, int priority) { this.element = element; diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java index 566d367fa52..13dcc0d45ba 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IFilteredStep.java @@ -33,6 +33,7 @@ public interface IFilteredStep extends IStep { * * @return whether this element can currently perform a filtered step into */ + @Deprecated boolean canStepWithFilters(); /** * Steps into the current statement, generating RESUME @@ -46,5 +47,6 @@ public interface IFilteredStep extends IStep { *
  • NOT_SUPPORTED - The capability is not supported by the target
  • * */ + @Deprecated void stepWithFilters() throws DebugException; } diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java index f8619288729..474eb81acf2 100644 --- a/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/groups/GroupLaunchConfigurationDelegate.java @@ -96,13 +96,9 @@ public void launch(ILaunchConfiguration groupConfig, String mode, final ILaunch SubMonitor progress = SubMonitor.convert(monitor, NLS.bind(DebugCoreMessages.GroupLaunchConfigurationDelegate_Launching, groupConfig.getName()), 1000); List launches = createLaunchElements(groupConfig); - int nbEnabledLaunches = launches.stream().filter(l -> l.enabled).toList().size(); - for (int i = 0; i < launches.size(); ++i) { - GroupLaunchElement le = launches.get(i); - - if (!le.enabled) { - continue; - } + List enabledLaunches = launches.stream().filter(l -> l.enabled).toList(); + for (int i = 0; i < enabledLaunches.size(); ++i) { + GroupLaunchElement le = enabledLaunches.get(i); // find launch; if not found, skip (error?) final ILaunchConfiguration conf = findLaunchConfiguration(le.name); @@ -128,7 +124,7 @@ public void launch(ILaunchConfiguration groupConfig, String mode, final ILaunch // loop detected. report as appropriate and die. IStatusHandler cycleHandler = DebugPlugin.getDefault().getStatusHandler(GROUP_CYCLE); cycleHandler.handleStatus(GROUP_CYCLE, conf.getName()); - } else if (!launchChild(progress.newChild(1000 / nbEnabledLaunches), group, le, conf, localMode, (i == nbEnabledLaunches - 1))) { + } else if (!launchChild(progress.newChild(1000 / enabledLaunches.size()), group, le, conf, localMode, (i == enabledLaunches.size() - 1))) { break; } diff --git a/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF b/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF index 2e9d0678fb5..9ec58f99085 100644 --- a/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.debug.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.debug.tests;singleton:=true -Bundle-Version: 3.15.100.qualifier +Bundle-Version: 3.15.200.qualifier Bundle-Localization: plugin Require-Bundle: org.eclipse.ui;bundle-version="[3.6.0,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", diff --git a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java index 07cd3af313a..f7f2eff48e3 100644 --- a/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java +++ b/debug/org.eclipse.debug.tests/src/org/eclipse/debug/tests/launching/LaunchTests.java @@ -20,6 +20,7 @@ import java.io.BufferedReader; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; @@ -29,7 +30,9 @@ import java.util.Locale; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; +import java.util.jar.JarOutputStream; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -55,6 +58,18 @@ */ public class LaunchTests extends AbstractLaunchTest { + /** + * Windows MAX_PATH limit for file paths. See + * https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + */ + private static final int WINDOWS_MAX_PATH = 258; + + /** + * Target length for long path tests. This should be well above MAX_PATH to + * ensure the tests exercise the long path handling code. + */ + private static final int LONG_PATH_LENGTH_TARGET = 400; + private InvocationHandler handler; private Runnable readIsTerminatedTask; private Runnable readIsDisconnectedTask; @@ -146,10 +161,10 @@ public void testProcessLaunchWithLongWorkingDirectory() throws CoreException, IO assumeTrue(Platform.OS.isWindows()); int rootLength = tempFolder.getRoot().toString().length(); - String subPathElementsName = "subfolder-with-relativly-long-name"; - String[] segments = Collections.nCopies((400 - rootLength) / subPathElementsName.length(), subPathElementsName).toArray(String[]::new); + String subPathElementsName = "subfolder-with-relatively-long-name"; + String[] segments = Collections.nCopies((LONG_PATH_LENGTH_TARGET - rootLength) / subPathElementsName.length(), subPathElementsName).toArray(String[]::new); File workingDirectory = tempFolder.newFolder(segments); - assertTrue(workingDirectory.toString().length() > 300); + assertTrue(workingDirectory.toString().length() > WINDOWS_MAX_PATH); // Just launch any process in a directory with a path longer than // Window's MAX_PATH length limit @@ -157,6 +172,27 @@ public void testProcessLaunchWithLongWorkingDirectory() throws CoreException, IO startProcessAndAssertOutputContains(List.of("java", "--version"), workingDirectory, true, "jdk"); } + @Test + public void testProcessLaunchWithLongExecutablePath() throws CoreException, IOException { + assumeTrue(Platform.OS.isWindows()); + + int rootLength = tempFolder.getRoot().toString().length(); + String subPathElementsName = "another-one-with-a-long-path-name-2"; + String[] segments = Collections.nCopies((LONG_PATH_LENGTH_TARGET - rootLength) / subPathElementsName.length(), subPathElementsName).toArray(String[]::new); + File workingDirectory = tempFolder.newFolder(segments); + assertTrue(workingDirectory.toString().length() > WINDOWS_MAX_PATH); + File jar = new File(workingDirectory, "dummy.jar"); + try (JarOutputStream stream = new JarOutputStream(new FileOutputStream(jar))) { + stream.putNextEntry(new ZipEntry("TEST")); + stream.write(1); + } + + // Just launch any process in a directory with a path longer than + // Window's MAX_PATH length limit and an argument that is even longer! + startProcessAndAssertOutputContains(List.of("java", "--version", "-cp", jar.getAbsolutePath()), workingDirectory, false, "jdk"); + startProcessAndAssertOutputContains(List.of("java", "--version", "-cp", jar.getAbsolutePath()), workingDirectory, true, "jdk"); + } + private static void startProcessAndAssertOutputContains(List cmdLine, File workingDirectory, boolean mergeOutput, String expectedOutput) throws CoreException, IOException { Process process = DebugPlugin.exec(cmdLine.toArray(String[]::new), workingDirectory, null, mergeOutput); String output; diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg deleted file mode 100644 index 556f280628f..00000000000 --- a/debug/org.eclipse.debug.ui/icons/full/elcl16/export_config.svg +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg new file mode 100644 index 00000000000..fda1ba2d577 --- /dev/null +++ b/debug/org.eclipse.debug.ui/icons/full/elcl16/export_wiz.svg @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + provider + + + + arrow + + + diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg deleted file mode 100644 index d396f12699f..00000000000 --- a/debug/org.eclipse.debug.ui/icons/full/elcl16/import_config.svg +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg b/debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg new file mode 100644 index 00000000000..9d3384c9107 --- /dev/null +++ b/debug/org.eclipse.debug.ui/icons/full/elcl16/import_wiz.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + receiver + + + + arrow + + + diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java index c99f8bd660d..93c3f68c8d3 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugPluginImages.java @@ -163,9 +163,9 @@ private static void declareImages() { declareRegistryImage(IInternalDebugUIConstants.IMG_ELCL_RESTART, IInternalDebugUIConstants.IMG_DLCL_RESTART, ELCL + "restart_co.svg"); //$NON-NLS-1$ declareRegistryImage(IInternalDebugUIConstants.IMG_ELCL_EXPORT_CONFIG, - IInternalDebugUIConstants.IMG_DLCL_EXPORT_CONFIG, ELCL + "export_config.svg"); //$NON-NLS-1$ + IInternalDebugUIConstants.IMG_DLCL_EXPORT_CONFIG, ELCL + "export_wiz.svg"); //$NON-NLS-1$ declareRegistryImage(IInternalDebugUIConstants.IMG_ELCL_IMPORT_CONFIG, - IInternalDebugUIConstants.IMG_DLCL_IMPORT_CONFIG, ELCL + "import_config.svg"); //$NON-NLS-1$ + IInternalDebugUIConstants.IMG_DLCL_IMPORT_CONFIG, ELCL + "import_wiz.svg"); //$NON-NLS-1$ //Object declareRegistryImage(IDebugUIConstants.IMG_OBJS_LAUNCH_DEBUG, OBJECT + "ldebug_obj.svg"); //$NON-NLS-1$ diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java index d72f84adf8a..c45e64351dc 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -81,6 +81,7 @@ public interface IDebugHelpContextIds { String DEBUG_TOOLBAR_VIEW_ACTION = PREFIX + "debug_toolbar_view_action_context"; //$NON-NLS-1$ String DEBUG_TOOLBAR_WINDOW_ACTION = PREFIX + "debug_toolbar_window_action_context"; //$NON-NLS-1$ String DEBUG_TOOLBAR_BOTH_ACTION = PREFIX + "debug_toolbar_both_action_context"; //$NON-NLS-1$ + String ADD_LAUNCH_CONFIGURATION_TO_FAV_ACTION = PREFIX + "Add_launch_configuration_to_favorites_action_context"; //$NON-NLS-1$ // Views String DEBUG_VIEW = PREFIX + "debug_view_context"; //$NON-NLS-1$ diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java index 7fbb10a0afd..cba82e7430f 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java @@ -253,5 +253,6 @@ public class ActionMessages extends NLS { public static String EnableAllBreakpointsAction_1; public static String EnableAllBreakpointsAction_3; public static String BreakpointLabelDialog; + public static String RemoveFromFavoritesAction; } \ No newline at end of file diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties index 72ec51c2cf3..2e1defe031d 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties @@ -16,6 +16,7 @@ AddToFavoritesAction_1=Add to {0} &Favorites AddToFavoritesAction_2=Error AddToFavoritesAction_3=Unable to add to favorites. +RemoveFromFavoritesAction=Remove from {0} Favorites ChangeVariableValue_errorDialogMessage=Setting the value failed. ChangeVariableValue_errorDialogTitle=Setting Value diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java index beafb6fdef2..940a0f826a8 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AddToFavoritesAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -52,7 +52,8 @@ public class AddToFavoritesAction extends SelectionListenerAction { public AddToFavoritesAction() { super(IInternalDebugCoreConstants.EMPTY_STRING); setEnabled(false); - PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugHelpContextIds.EDIT_LAUNCH_CONFIGURATION_ACTION); + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, + IDebugHelpContextIds.ADD_LAUNCH_CONFIGURATION_TO_FAV_ACTION); } /** @@ -66,29 +67,42 @@ protected boolean updateSelection(IStructuredSelection selection) { if (selection.size() == 1) { Object object = selection.getFirstElement(); ILaunch launch = null; - if (object instanceof IAdaptable) { - launch = ((IAdaptable)object).getAdapter(ILaunch.class); + if (object instanceof IAdaptable iAdaptable) { + launch = iAdaptable.getAdapter(ILaunch.class); } if (launch == null) { - if (object instanceof ILaunch) { - launch = (ILaunch)object; - } else if (object instanceof IDebugElement) { - launch = ((IDebugElement)object).getLaunch(); - } else if (object instanceof IProcess) { - launch = ((IProcess)object).getLaunch(); + if (object instanceof ILaunch iLaunch) { + launch = iLaunch; + } else if (object instanceof IDebugElement iDebugElement) { + launch = iDebugElement.getLaunch(); + } else if (object instanceof IProcess iProcess) { + launch = iProcess.getLaunch(); } } if (launch != null) { ILaunchConfiguration configuration = launch.getLaunchConfiguration(); if (configuration != null) { - ILaunchGroup group= DebugUITools.getLaunchGroup(configuration, getMode()); + ILaunchGroup group = DebugUITools.getLaunchGroup(configuration, launch.getLaunchMode()); if (group == null) { return false; } setGroup(group); setLaunchConfiguration(configuration); setMode(launch.getLaunchMode()); - setText(MessageFormat.format(ActionMessages.AddToFavoritesAction_1, DebugUIPlugin.removeAccelerators(getGroup().getLabel()))); + try { + List favoriteGroups = configuration.getAttribute(IDebugUIConstants.ATTR_FAVORITE_GROUPS, + new ArrayList<>()); + if (favoriteGroups.contains(group.getIdentifier())) { + setText(MessageFormat.format(ActionMessages.RemoveFromFavoritesAction, + fMode.substring(0, 1).toUpperCase() + fMode.substring(1))); + } else { + setText(MessageFormat.format(ActionMessages.AddToFavoritesAction_1, + DebugUIPlugin.removeAccelerators( + fMode.substring(0, 1).toUpperCase() + fMode.substring(1)))); + } + } catch (CoreException e) { + DebugUIPlugin.log(e); + } } } } @@ -101,20 +115,7 @@ protected boolean updateSelection(IStructuredSelection selection) { if (DebugUITools.isPrivate(config)) { return false; } - - if (getGroup() != null) { - try { - List groups = config.getAttribute(IDebugUIConstants.ATTR_FAVORITE_GROUPS, (List) null); - if (groups != null) { - return !groups.contains(getGroup().getIdentifier()); - } - return true; - } catch (CoreException e) { - } - - } - - return false; + return true; } /** @@ -177,7 +178,12 @@ public void run() { if (list == null) { list = new ArrayList<>(); } - list.add(getGroup().getIdentifier()); + String groupIdentifier = getGroup().getIdentifier(); + if (list.contains(groupIdentifier)) { + list.remove(groupIdentifier); + } else { + list.add(groupIdentifier); + } ILaunchConfigurationWorkingCopy copy = getLaunchConfiguration().getWorkingCopy(); copy.setAttribute(IDebugUIConstants.ATTR_FAVORITE_GROUPS, list); copy.doSave(); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java index 6aac205528a..cd4fa4071dc 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/breakpoints/BreakpointLabelAction.java @@ -19,7 +19,6 @@ import org.eclipse.debug.internal.ui.actions.ActionMessages; import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView; -import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -27,7 +26,6 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; @@ -37,8 +35,6 @@ import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IViewActionDelegate; import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; public class BreakpointLabelAction implements IViewActionDelegate { @@ -51,88 +47,104 @@ protected void setView(IViewPart view) { fView = view; } + private static record InlineEditor(Label label, Text text) { + void dispose() { + label.dispose(); + text.dispose(); + } + } + @Override public void run(IAction action) { - String emptyString = ""; //$NON-NLS-1$ IStructuredSelection selection = getSelection(); - - if (selection instanceof TreeSelection treeSelect && selection.getFirstElement() instanceof Breakpoint breakpoint) { - if (treeSelect.size() == 1) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IViewPart viewPart = page.findView(IDebugUIConstants.ID_BREAKPOINT_VIEW); - if (viewPart instanceof BreakpointsView breakpointView) { - TreeModelViewer treeViewer = breakpointView.getTreeModelViewer(); - Widget item = treeViewer.findItem(treeSelect.getPaths()[0]); - if (item instanceof TreeItem tree) { - String current = tree.getText(); - Rectangle bounds; - try { - bounds = tree.getBounds(); - } catch (ArrayIndexOutOfBoundsException e) { // TreeItem having FontData [Breakpoints having - // custom label] - tree.setFont(null); - GC gc = new GC(tree.getParent()); - Font currentFont = gc.getFont(); - gc.setFont(currentFont); - Point textWidth = gc.textExtent(tree.getText()); - gc.dispose(); - bounds = tree.getBounds(0); - bounds.x = bounds.x + 10; - bounds.width = textWidth.x + 20; - - } - Label label = new Label(tree.getParent(), SWT.WRAP); - label.setText(ActionMessages.BreakpointLabelDialog); - label.setBounds(bounds.x, bounds.y - 20, label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, - label.computeSize(SWT.DEFAULT, SWT.DEFAULT).y); - - Text inlineEditor = new Text(tree.getParent(), SWT.BORDER); - inlineEditor.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); - inlineEditor.setText(current); - inlineEditor.selectAll(); - inlineEditor.setFocus(); - - inlineEditor.addListener(SWT.FocusOut, event -> { - tree.setText(current); - label.dispose(); - inlineEditor.dispose(); - - }); - inlineEditor.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.keyCode == SWT.ESC) { - tree.setText(current); - inlineEditor.dispose(); - label.dispose(); - } else if (e.keyCode == SWT.CR) { - String newLabel = inlineEditor.getText(); - if (!newLabel.isEmpty() && !newLabel.equals(current)) { - try { - breakpoint.setBreakpointLabel(newLabel); - } catch (CoreException e1) { - DebugUIPlugin.log(e1); - } - } else if (newLabel.isEmpty()) { - try { - breakpoint.setBreakpointLabel(null); // Set to default - } catch (CoreException e2) { - DebugUIPlugin.log(e2); - } - } - inlineEditor.dispose(); - label.dispose(); - } - } - }); - tree.setText(emptyString); - + if (!(selection instanceof TreeSelection treeSelect) + || treeSelect.size() != 1 + || !(selection.getFirstElement() instanceof Breakpoint breakpoint) + || !(fView instanceof BreakpointsView breakpointView)) { + return; + } + TreeModelViewer treeViewer = breakpointView.getTreeModelViewer(); + Widget item = treeViewer.findItem(treeSelect.getPaths()[0]); + if (!(item instanceof TreeItem treeItem)) { + return; + } + Rectangle editorBounds = computeInlineEditorBounds(treeItem); + + Label label = new Label(treeItem.getParent(), SWT.WRAP); + label.setText(ActionMessages.BreakpointLabelDialog); + Point defaultLabelSize = label.computeSize(SWT.DEFAULT, SWT.DEFAULT); + label.setBounds(editorBounds.x, editorBounds.y - 20, defaultLabelSize.x, defaultLabelSize.y); + label.setBackground(treeItem.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + + String current = treeItem.getText(); + Text textEditor = new Text(treeItem.getParent(), SWT.BORDER); + textEditor.setBounds(editorBounds.x, editorBounds.y, editorBounds.width, editorBounds.height); + textEditor.setText(current); + textEditor.selectAll(); + textEditor.setFocus(); + + final InlineEditor inlineEditor = new InlineEditor(label, textEditor); + textEditor.addListener(SWT.FocusOut, event -> inlineEditor.dispose()); + textEditor.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.ESC) { + inlineEditor.dispose(); + } else if (e.keyCode == SWT.CR) { + String newLabel = textEditor.getText().strip(); + if (newLabel.equals(current)) { + inlineEditor.dispose(); + return; } - + if (newLabel.isEmpty()) { + newLabel = null; // reset to default breakpoint label + } + try { + breakpoint.setBreakpointLabel(newLabel); + } catch (CoreException e1) { + DebugUIPlugin.log(e1); + } + inlineEditor.dispose(); } } + }); + } + + private static Rectangle computeInlineEditorBounds(TreeItem treeItem) { + Rectangle bounds; + try { + bounds = treeItem.getBounds(); + } catch (ArrayIndexOutOfBoundsException e) { + // TreeItem having FontData [Breakpoints having custom label] + bounds = macBugWorkaround(treeItem); } + int editorWidth = Math.max(computeEditorExtent(treeItem), bounds.width); + return new Rectangle(bounds.x, bounds.y, editorWidth, bounds.height); + } + + // Workaround for SWT bug on Mac where TreeItem.getBounds() throws exception + // when custom fonts are used, see + // https://github.com/eclipse-platform/eclipse.platform.swt/issues/2749 + private static Rectangle macBugWorkaround(TreeItem treeItem) { + treeItem.setFont(null); + Rectangle bounds = treeItem.getBounds(0); + bounds.x = bounds.x + 10; + bounds.width = computeEditorExtent(treeItem); + return bounds; + } + private static int computeEditorExtent(TreeItem treeItem) { + GC gc = new GC(treeItem.getParent()); + try { + Point textWidth = gc.textExtent(treeItem.getText()); + // Editor needs space on both sides around text + int width = textWidth.x + 20; + // Give editor more room to grow for new text + width = Math.max(100, width); + return width; + } finally { + gc.dispose(); + } } protected IStructuredSelection getSelection() { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java index 45f039d3698..f9915d57fbe 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/CopyExpressionsToClipboardActionDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Bachmann electronic GmbH and others. + * Copyright (c) 2017, 2025 Bachmann electronic GmbH and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,15 +10,17 @@ * * Contributors: * Bachmann electronic GmbH - initial API and implementation + * IBM Corporation - Exclude Expression UI values while copying *******************************************************************************/ package org.eclipse.debug.internal.ui.actions.expressions; +import org.eclipse.debug.internal.core.WatchExpression; +import org.eclipse.debug.internal.ui.DebugUIMessages; import org.eclipse.debug.internal.ui.viewers.model.VirtualCopyToClipboardActionDelegate; public class CopyExpressionsToClipboardActionDelegate extends VirtualCopyToClipboardActionDelegate { private static final String QUOTE = "\""; //$NON-NLS-1$ - @Override protected String trimLabel(String rawLabel) { String label = super.trimLabel(rawLabel); @@ -34,5 +36,25 @@ protected String trimLabel(String rawLabel) { return label; } - + @Override + protected String exludeLabels(Object itemData, String label) { + if (itemData instanceof WatchExpression watchExp) { + if (watchExp.isPending() || watchExp.hasErrors()) { + if (label.equals(DebugUIMessages.DefaultLabelProvider_12) + || label.contains(DebugUIMessages.DefaultLabelProvider_13)) { + return null; + } + } + if (!watchExp.isEnabled()) { + if (label.equals(DebugUIMessages.DefaultLabelProvider_15)) { + return null; + } + int index = label.lastIndexOf(DebugUIMessages.DefaultLabelProvider_15); + if (index != -1) { + label = label.substring(0, index); + } + } + } + return label; + } } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java index 496bb1c76bb..58395322f2e 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/commands/actions/TerminateAndRemoveAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2013 IBM Corporation and others. + * Copyright (c) 2006, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -109,7 +109,7 @@ public void debugContextChanged(DebugContextEvent event) { // enable the action, which whill just remove the terminated launches (bug 324959). fCanTerminate = !isAllTerminated; if (isAllTerminated) { - setEnabled(true); + setEnabled(!context.isEmpty()); } else { super.debugContextChanged(event); } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java index a02d5c50913..69779ecf1f8 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardExportBreakpointsPage.java @@ -144,7 +144,7 @@ protected void handlePathTextModifiedEvent() { */ protected void handleDestinationBrowseButtonPressed() { FileDialog dialog = new FileDialog(getContainer().getShell(), SWT.SAVE | SWT.SHEET); - dialog.setFilterExtensions(new String[]{"*."+IImportExportConstants.EXTENSION}); //$NON-NLS-1$ + dialog.setFilterExtensions("*."+IImportExportConstants.EXTENSION); //$NON-NLS-1$ dialog.setText(ImportExportMessages.WizardExportBreakpoints_0); String file = dialog.open(); if(file != null) { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java index a7b4f33eed0..7ee6bdaf28c 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/breakpoints/WizardImportBreakpointsPage.java @@ -91,7 +91,7 @@ public void handleEvent(Event event) { */ protected void handleBrowseForFileButtonPressed() { FileDialog dialog = new FileDialog(getContainer().getShell(), SWT.OPEN | SWT.SHEET); - dialog.setFilterExtensions(new String[]{"*."+IImportExportConstants.EXTENSION}); //$NON-NLS-1$ + dialog.setFilterExtensions("*."+IImportExportConstants.EXTENSION); //$NON-NLS-1$ String file = dialog.open(); if(file != null) { fFileNameField.setText(file); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java index 49854e787f2..513bb11858a 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/ExportLaunchConfigurationsWizardPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2017 IBM Corporation and others. + * Copyright (c) 2007, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -52,6 +52,8 @@ import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -155,12 +157,44 @@ public void createControl(Composite parent) { * @param parent the parent to add the check table viewer to */ protected void createViewer(Composite parent) { + Text filterText = new Text(parent, SWT.SEARCH | SWT.CANCEL); + filterText.setMessage(WizardMessages.ImportLaunchTypeToFilter); + filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + ViewerFilter filter = new ViewerFilter() { + @Override + public boolean select(Viewer viewer2, Object parentElement, Object element) { + String search = filterText.getText().toLowerCase(); + if (search.isEmpty()) { + fViewer.collapseAll(); + return true; + } + if (element instanceof ILaunchConfiguration launchConfig) { + return launchConfig.getName().toLowerCase().contains(search); + } + if (element instanceof ILaunchConfigurationType launchConfigType) { + try { + for (ILaunchConfiguration config2 : lm.getLaunchConfigurations(launchConfigType)) { + if (config2.getName().toLowerCase().contains(search)) { + return true; + } + } + } catch (Exception e) { + DebugPlugin.log(e); + return false; + } + return false; + } + return true; + } + }; SWTFactory.createWrapLabel(parent, WizardMessages.ExportLaunchConfigurationsWizardPage_3, 2); Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.CHECK); GridData gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; tree.setLayoutData(gd); fViewer = new CheckboxTreeViewer(tree); + fViewer.addFilter(filter); + fViewer.setLabelProvider(DebugUITools.newDebugModelPresentation()); fViewer.setComparator(new WorkbenchViewerComparator()); fContentProvider = new ConfigContentProvider(); @@ -206,6 +240,10 @@ public void widgetSelected(SelectionEvent e) { setPageComplete(isComplete()); } }); + filterText.addModifyListener(e -> { + fViewer.refresh(); + fViewer.expandAll(); + }); } /** diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java index 6d6ab8ded87..06d48d23b3e 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -46,6 +46,7 @@ public class WizardMessages extends NLS { public static String ImportLaunchConfigurationsWizardPage_5; public static String ImportLaunchConfigurationsWizardPage_6; public static String ImportLaunchConfigurationsWizardPage_7; + public static String ImportLaunchTypeToFilter; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, WizardMessages.class); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties index f67406b84d1..78004647e54 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/importexport/launchconfigurations/WizardMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2008 IBM Corporation and others. +# Copyright (c) 2005, 2025 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -40,3 +40,4 @@ ImportLaunchConfigurationsWizardPage_4=You must select at least one configuratio ImportLaunchConfigurationsWizardPage_5=Import launch configurations from the local file system ImportLaunchConfigurationsWizardPage_6=From &Directory: ImportLaunchConfigurationsWizardPage_7=Brows&e... +ImportLaunchTypeToFilter=Type filter text diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java index c6195ea7095..cf372252dad 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -61,6 +61,11 @@ protected void performAction() { // Construct a new config of the selected type if (object instanceof ILaunchConfiguration config) { try { + if (!config.exists()) { + ILaunchConfiguration[] launches = DebugPlugin.getDefault().getLaunchManager() + .getLaunchConfigurations(); + config = launches[launches.length - 1]; + } type = config.getType(); } catch (CoreException e) { errorDialog(e); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java index ecf6de71807..11941d7c9b5 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java @@ -32,9 +32,10 @@ public class BreakpointLabelProvider extends DebugElementLabelProvider { @Override protected String getLabel(TreePath elementPath, IPresentationContext presentationContext, String columnId, int columnIndex) throws CoreException { if (columnIndex == 0) { - if (elementPath.getFirstSegment() instanceof Breakpoint breakpoint) { - if (breakpoint.getBreakpointLabel() != null) { - return breakpoint.getBreakpointLabel(); + if (elementPath.getLastSegment() instanceof Breakpoint breakpoint) { + String breakpointLabel = breakpoint.getBreakpointLabel(); + if (breakpointLabel != null) { + return breakpointLabel; } } return super.getLabel(elementPath, presentationContext, columnId, columnIndex); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java index 18d93fc60b9..b742bb66ac0 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/browsers/ExternalArchiveSourceContainerBrowser.java @@ -42,7 +42,7 @@ public ISourceContainer[] addSourceContainers(Shell shell, ISourceLookupDirector .getDialogSettings(); String rootDir = dialogSettings.get(ROOT_DIR); dialog.setText(SourceLookupUIMessages.ExternalArchiveSourceContainerBrowser_2); - dialog.setFilterExtensions(new String[]{"*.jar;*.zip"}); //$NON-NLS-1$ + dialog.setFilterExtensions("*.jar;*.zip"); //$NON-NLS-1$ if (rootDir != null) { dialog.setFilterPath(rootDir); } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java index 1e2f148f23a..89b81e73ca7 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/PartPresentationContext.java @@ -30,10 +30,12 @@ public class PartPresentationContext extends PresentationContext { * * @param part part */ + @Deprecated public PartPresentationContext(IWorkbenchPart part) { super(part); } + @Deprecated @Override public IWorkbenchPart getPart() { return super.getPart(); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java index 1c46d887f36..990fffb0ade 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/VirtualCopyToClipboardActionDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -146,7 +146,8 @@ protected void append(VirtualItem item, StringBuilder buffer, int indent) { String[] labels = (String[]) item.getData(VirtualItem.LABEL_KEY); if(labels != null && labels.length > 0) { for (String label : labels) { - String text = trimLabel(label); + String text = exludeLabels(item.getData(), label); + text = trimLabel(text); if (text != null && !text.equals(IInternalDebugCoreConstants.EMPTY_STRING)) { buffer.append(text); } @@ -171,6 +172,19 @@ protected String trimLabel(String label) { return label.trim(); } + /** + * Excludes unwanted labels from the selected item + * + * @param itemData Selected object + * @param label Current label + * @return filtered label or null if label or item is null + */ + protected String exludeLabels(Object itemData, String label) { + if (itemData == null || label == null) { + return null; + } + return label; + } private static class ItemsToCopyVirtualItemValidator implements IVirtualItemValidator { Set fItemsToCopy = Collections.EMPTY_SET; @@ -367,4 +381,5 @@ protected boolean getEnableStateForSelection(IStructuredSelection selection) { public void runWithEvent(IAction action, Event event) { run(action); } + } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java index b9de9b753da..7798cf93f66 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java @@ -30,7 +30,6 @@ import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.widgets.Display; /** * Translates images, colors, and fonts into image descriptors, RGBs, and font @@ -146,14 +145,7 @@ public static RGB getForeground(Object element, IDebugModelPresentation presenta if (element instanceof Breakpoint breakpoint) { if (breakpoint.getBreakpointLabel() != null) { - final RGB[] rgb = new RGB[1]; - Display.getDefault().syncExec(() -> { - Color redColor = Display.getDefault().getSystemColor(SWT.COLOR_RED); - rgb[0] = redColor.getRGB(); - }); - if (rgb[0] != null) { - return rgb[0]; - } + return new RGB(255, 0, 0); } return null; } diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java index 310bdbcea26..5da15f78310 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugElementWorkbenchAdapter.java @@ -37,26 +37,31 @@ @Deprecated public abstract class DebugElementWorkbenchAdapter implements IWorkbenchAdapter, IWorkbenchAdapter2 { + @Deprecated @Override public ImageDescriptor getImageDescriptor(Object object) { return DebugElementHelper.getImageDescriptor(object); } + @Deprecated @Override public String getLabel(Object o) { return DebugElementHelper.getLabel(o); } + @Deprecated @Override public RGB getForeground(Object element) { return DebugElementHelper.getForeground(element); } + @Deprecated @Override public RGB getBackground(Object element) { return DebugElementHelper.getBackground(element); } + @Deprecated @Override public FontData getFont(Object element) { return DebugElementHelper.getFont(element); diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java index 755daac87f1..7bb540e485d 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DeferredDebugElementWorkbenchAdapter.java @@ -39,18 +39,22 @@ public abstract class DeferredDebugElementWorkbenchAdapter extends DebugElementW /** * An empty collection of children */ + @Deprecated protected static final Object[] EMPTY = new Object[0]; + @Deprecated @Override public boolean isContainer() { return true; } + @Deprecated @Override public ISchedulingRule getRule(Object object) { return null; } + @Deprecated @Override public void fetchDeferredChildren(Object object, IElementCollector collector, IProgressMonitor monitor) { if (monitor.isCanceled()) { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java index 26645199cae..997358e721a 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAsAction.java @@ -76,6 +76,7 @@ public class LaunchAsAction extends Action implements IMenuCreator, IWorkbenchWi * * @param launchGroupIdentifier launch group identifier */ + @Deprecated public LaunchAsAction(String launchGroupIdentifier) { super(); fLaunchGroupIdentifier = launchGroupIdentifier; @@ -96,6 +97,7 @@ private LaunchGroupExtension getLaunchGroup() { /** * @see IAction#run() */ + @Deprecated @Override public void run() { //do nothing, this action just creates a cascading menu. @@ -118,6 +120,7 @@ private void createAction(Menu parent, IAction action, int count) { /** * @see IMenuCreator#dispose() */ + @Deprecated @Override public void dispose() { if (getCreatedMenu() != null) { @@ -128,6 +131,7 @@ public void dispose() { /** * @see IMenuCreator#getMenu(Control) */ + @Deprecated @Override public Menu getMenu(Control parent) { return null; @@ -136,6 +140,7 @@ public Menu getMenu(Control parent) { /** * @see IMenuCreator#getMenu(Menu) */ + @Deprecated @Override public Menu getMenu(Menu parent) { if (getCreatedMenu() != null) { @@ -267,6 +272,7 @@ private LaunchConfigurationManager getLaunchConfigurationManager() { /** * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) */ + @Deprecated @Override public void init(IWorkbenchWindow window) { // if (window instanceof WorkbenchWindow) { @@ -277,6 +283,7 @@ public void init(IWorkbenchWindow window) { /** * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */ + @Deprecated @Override public void run(IAction action) { // do nothing - this is just a menu @@ -285,6 +292,7 @@ public void run(IAction action) { /** * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) */ + @Deprecated @Override public void selectionChanged(IAction action, ISelection selection) { if (fAction == null) { diff --git a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java index 60c14b0a9ad..99acc808df4 100644 --- a/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java +++ b/debug/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RulerBreakpointTypesActionDelegate.java @@ -111,16 +111,19 @@ public void run() { } + @Deprecated @Override public void selectionChanged(IAction action, ISelection selection) { // In the editor we're not using the selection. } + @Deprecated @Override public void run(IAction action) { // Do nothing, this is a pull-down menu. } + @Deprecated @Override public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { // Clean up old editor data. @@ -148,6 +151,7 @@ public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) { } + @Deprecated @Override public void dispose() { if (fCallerAction != null) { @@ -159,6 +163,7 @@ public void dispose() { fRulerInfo = null; } + @Deprecated @Override public void menuAboutToShow(IMenuManager manager) { fSelection = StructuredSelection.EMPTY; @@ -196,6 +201,7 @@ private void setMenu(Menu menu) { fMenu = menu; } + @Deprecated @Override public Menu getMenu(Menu parent) { setMenu(new Menu(parent)); @@ -204,6 +210,7 @@ public Menu getMenu(Menu parent) { return fMenu; } + @Deprecated @Override public Menu getMenu(Control parent) { setMenu(new Menu(parent)); diff --git a/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF index cc0097a372f..1175b9d3922 100644 --- a/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.unittest.ui/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.unittest.ui Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.unittest.ui;singleton:=true -Bundle-Version: 1.1.700.qualifier +Bundle-Version: 1.1.800.qualifier Bundle-Activator: org.eclipse.unittest.internal.UnitTestPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java b/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java index 04cad9da15c..e5b32c57fa4 100644 --- a/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java +++ b/debug/org.eclipse.unittest.ui/src/org/eclipse/unittest/internal/ui/history/HistoryDialog.java @@ -108,7 +108,7 @@ private void createButtons(Composite res) { Button importButton = new Button(buttons, SWT.PUSH); importButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { FileDialog fileDialog = new FileDialog(getShell()); - fileDialog.setFilterExtensions(new String[] { "*.xml" }); //$NON-NLS-1$ + fileDialog.setFilterExtensions("*.xml"); //$NON-NLS-1$ fileDialog.setText(Messages.HistoryDialog_selectImport); String path = fileDialog.open(); if (path == null) { diff --git a/platform/org.eclipse.platform/about.ini b/platform/org.eclipse.platform/about.ini index 167f5068a6c..750bf909d4a 100644 --- a/platform/org.eclipse.platform/about.ini +++ b/platform/org.eclipse.platform/about.ini @@ -9,7 +9,7 @@ aboutText=%blurb # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "welcomePage" contains path to welcome page (special XML-based format) # ($nl$/ prefix to permit locale-specific translations of entire file) diff --git a/platform/org.eclipse.sdk/about.ini b/platform/org.eclipse.sdk/about.ini index 188896b22e1..2263d0a7603 100644 --- a/platform/org.eclipse.sdk/about.ini +++ b/platform/org.eclipse.sdk/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java index c8912f5aeac..30405005f3f 100644 --- a/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java +++ b/resources/bundles/org.eclipse.core.filesystem/src/org/eclipse/core/internal/filesystem/local/Win32Handler.java @@ -118,7 +118,7 @@ public static String getShortPathName(String longPath) { int newLength = com.sun.jna.platform.win32.Kernel32.INSTANCE.GetShortPathName(longPath, buffer, buffer.length); if (0 < newLength && newLength < buffer.length) { // zero means error int offset = longPath.startsWith(WIN32_UNC_RAW_PATH_PREFIX) ? WIN32_UNC_RAW_PATH_PREFIX.length() : WIN32_RAW_PATH_PREFIX.length(); - return new String(buffer, offset, newLength); + return new String(buffer, offset, newLength - offset); } return null; } diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java index c610492bd69..5881c153842 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/UnifiedTree.java @@ -438,9 +438,6 @@ private static class PatternHolder { //Pattern: A UNIX or Windows relative path that just points backward static final Pattern TRIVIAL_SYMLINK_PATTERN = Pattern.compile( // Platform.OS.isWindows() ? "\\.[.\\\\]*" : "\\.[./]*"); //$NON-NLS-1$//$NON-NLS-2$ - - static final Pattern REPEATING_BACKWARDS_PATTERN = Pattern.compile( // - Platform.OS.isWindows() ? "(\\.\\.\\\\)+.*" : "(\\.\\./)+.*"); //$NON-NLS-1$//$NON-NLS-2$ } /** @@ -522,20 +519,10 @@ private boolean isRecursiveLink(IFileStore parentStore, IFileInfo localInfo) { Path realParentPath = parent.toRealPath(); if (disable_advanced_recursive_link_checks) { // Multiple ../ backwards links can go outside the project tree - if (linkTarget != null && PatternHolder.REPEATING_BACKWARDS_PATTERN.matcher(linkTarget).matches()) { - Path targetPath = parent.resolve(linkTarget).normalize(); - - // Recursive if literal target points to the literal parent of this tree - if (parent.normalize().startsWith(targetPath)) { + if (linkTarget != null) { + if (isRecursiveBackwardsLink(realParentPath, linkTarget)) { return true; } - - // Recursive if resolved target points to the resolved parent of this tree - Path realTargetPath = targetPath.toRealPath(); - if (realParentPath.startsWith(realTargetPath)) { - return true; - } - // If link is outside the project tree, consider as non recursive // The link still can create recursion in the tree, but we can't detect it here. } @@ -573,6 +560,51 @@ private boolean isRecursiveLink(IFileStore parentStore, IFileInfo localInfo) { return false; } + /** + * @param realParentPath real parent path object obtained as a result + * of @code{Path.toRealPath()} + * @param linkTarget the link target path as a string, may be relative or + * absolute + * @return true if the given target points backwards recursively to the given + * parent path + * @throws IOException + */ + private static boolean isRecursiveBackwardsLink(Path realParentPath, String linkTarget) + throws IOException { + // Cheap test first: literal target points to the literal parent + Path normalizedLink = realParentPath.resolve(linkTarget).normalize(); + if (realParentPath.startsWith(normalizedLink)) { + return true; + } + // Next check costs more time because it does real IO when resolving paths + Path realTarget = normalizedLink.toRealPath(); + if (realParentPath.startsWith(realTarget)) { + return true; + } + return false; + } + + /** + * Disable or enable advanced recursive link checks. Advanced link checks may + * hide valid directories in some cases, see bug 537449. + * + * @param enable true to enable advanced recursive link checks, + * false to disable them. + */ + public static void enableAdvancedRecursiveLinkChecks(boolean enable) { + disable_advanced_recursive_link_checks = !enable; + } + + /** + * Returns whether advanced recursive link checks are enabled. + * + * @return true if advanced recursive link checks are enabled, + * false otherwise. + */ + public static boolean isAdvancedRecursiveLinkChecksEnabled() { + return !disable_advanced_recursive_link_checks; + } + protected boolean isValidLevel(int currentLevel, int depth) { return switch (depth) { case IResource.DEPTH_INFINITE -> true; diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java index 0112726a74e..2fdcf71f8a7 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/AliasManager.java @@ -24,10 +24,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map.Entry; import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import org.eclipse.core.filesystem.EFS; @@ -126,15 +125,56 @@ public void accept(IResource match) { } + /** + * A HashMap that also maintains its keys in sorted order. It combines the fast + * access to the content with the ability to get sorted keys and key subsets. + */ + private static final class HashMapWithSortedKeys { + private final SortedSet keys; + private final HashMap map; + + HashMapWithSortedKeys() { + keys = new TreeSet<>(IFileStore::compareTo); + map = new HashMap<>(100); + } + + Object put(IFileStore key, Object value) { + keys.add(key); + return map.put(key, value); + } + + Object remove(Object key) { + keys.remove(key); + return map.remove(key); + } + + Object get(IFileStore location) { + return map.get(location); + } + + void clear() { + keys.clear(); + map.clear(); + } + + Set keys() { + return keys; + } + + SortedSet keysSubSet(IFileStore fromKey, IFileStore toKey) { + return keys.subSet(fromKey, toKey); + } + } + /** * Maintains a mapping of FileStore->IResource, such that multiple resources * mapped from the same location are tolerated. */ - class LocationMap { + private static final class LocationMap { /** * Map of FileStore->IResource OR FileStore->ArrayList of (IResource) */ - private final SortedMap map = new TreeMap<>(IFileStore::compareTo); + private final HashMapWithSortedKeys map = new HashMapWithSortedKeys(); /** * Adds the given resource to the map, keyed by the given location. @@ -177,17 +217,18 @@ public void clear() { * given location as a prefix. */ public void matchingPrefixDo(IFileStore prefix, Consumer doit) { - SortedMap matching; + Set matching; IFileStore prefixParent = prefix.getParent(); if (prefixParent != null) { //endPoint is the smallest possible path greater than the prefix that doesn't //match the prefix IFileStore endPoint = prefixParent.getChild(prefix.getName() + "\0"); //$NON-NLS-1$ - matching = map.subMap(prefix, endPoint); + matching = map.keysSubSet(prefix, endPoint); } else { - matching = map; + matching = map.keys(); } - for (Object value : matching.values()) { + for (IFileStore key : matching) { + Object value = map.get(key); if (value == null) { return; } @@ -230,11 +271,10 @@ public void matchingResourcesDo(IFileStore location, Consumer doit) { public void overLappingResourcesDo(Consumer doit) { IFileStore previousStore = null; IResource previousResource = null; - for (Entry current : map.entrySet()) { + for (IFileStore currentStore : map.keys()) { //value is either single resource or List of resources - IFileStore currentStore = current.getKey(); IResource currentResource = null; - Object value = current.getValue(); + Object value = map.get(currentStore); if (value instanceof List) { for (Object element : ((List) value)) { if (element instanceof IResource) { diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java index 5a1b5d02f6c..69c5e408513 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectDescription.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; @@ -581,7 +582,7 @@ public boolean hasPrivateChanges(ProjectDescription description) { return true; } // has natures changed? - if (!Set.of(natures).equals(Set.of(description.natures))) { + if (!new HashSet<>(Arrays.asList(natures)).equals(new HashSet<>(Arrays.asList(description.natures)))) { return true; } // has buildspec changed? diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java index efc60fd5760..c70f8d052f7 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFileModificationValidator.java @@ -49,6 +49,7 @@ public interface IFileModificationValidator { * reasons why modifying the given files is not reasonable * @see IWorkspace#validateEdit(IFile[], Object) */ + @Deprecated IStatus validateEdit(IFile[] files, Object context); /** @@ -67,5 +68,6 @@ public interface IFileModificationValidator { * @see IFile#setContents(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor) * @see IFile#appendContents(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor) */ + @Deprecated IStatus validateSave(IFile file); } diff --git a/resources/bundles/org.eclipse.core.tools.resources/about.ini b/resources/bundles/org.eclipse.core.tools.resources/about.ini index 34870781b24..130e80d1ed7 100644 --- a/resources/bundles/org.eclipse.core.tools.resources/about.ini +++ b/resources/bundles/org.eclipse.core.tools.resources/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/resources/bundles/org.eclipse.core.tools.resources/build.properties b/resources/bundles/org.eclipse.core.tools.resources/build.properties index dfac95d3825..f46098951ce 100644 --- a/resources/bundles/org.eclipse.core.tools.resources/build.properties +++ b/resources/bundles/org.eclipse.core.tools.resources/build.properties @@ -14,5 +14,12 @@ source.. = src/ output.. = bin/ src.includes=*.html -bin.includes=plugin.xml,icons/,doc/,*.html,.options, META-INF/,. +bin.includes = plugin.xml,\ + icons/,\ + doc/,\ + *.html,\ + .options,\ + META-INF/,\ + .,\ + eclipse32.svg qualifier=context diff --git a/resources/bundles/org.eclipse.core.tools.resources/eclipse32.png b/resources/bundles/org.eclipse.core.tools.resources/eclipse32.png deleted file mode 100644 index bf856800755..00000000000 Binary files a/resources/bundles/org.eclipse.core.tools.resources/eclipse32.png and /dev/null differ diff --git a/resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg b/resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg new file mode 100644 index 00000000000..4f0e95ebbf3 --- /dev/null +++ b/resources/bundles/org.eclipse.core.tools.resources/eclipse32.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF b/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF index a334a59d147..13d919c08dc 100644 --- a/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF +++ b/resources/tests/org.eclipse.core.tests.resources.saveparticipant/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Automatic-Module-Name: org.eclipse.core.tests.resources.saveparticipant Bundle-Name: Eclipse Core Tests Save Participant Bundle-SymbolicName: org.eclipse.core.tests.resources.saveparticipant; singleton:=true -Bundle-Version: 3.6.100.qualifier +Bundle-Version: 3.6.200.qualifier Bundle-Vendor: Eclipse.org Export-Package: org.eclipse.core.tests.resources.saveparticipant Require-Bundle: org.eclipse.core.resources, @@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.core.tests.resources.saveparticipant2, org.eclipse.core.tests.resources.saveparticipant3, org.eclipse.core.filesystem -Import-Package: org.junit.jupiter.api, - org.junit.jupiter.api.extension +Import-Package: org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-ActivationPolicy: lazy diff --git a/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF b/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF index 794aacbe651..0af9e7d8aa7 100644 --- a/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF +++ b/resources/tests/org.eclipse.core.tests.resources/META-INF/MANIFEST.MF @@ -36,13 +36,13 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.core.runtime, org.eclipse.pde.junit.runtime;bundle-version="3.5.0" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.jupiter.api.function, - org.junit.jupiter.api.io, - org.junit.jupiter.params, - org.junit.jupiter.params.provider, - org.junit.platform.suite.api, + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.io;version="[5.14.0,6.0.0)", + org.junit.jupiter.params;version="[5.14.0,6.0.0)", + org.junit.jupiter.params.provider;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)", org.mockito Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java index 7f7310fb29f..d121db58b7a 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/localstore/SymlinkResourceTest.java @@ -21,28 +21,33 @@ import static org.eclipse.core.tests.resources.ResourceTestUtil.createInWorkspace; import static org.eclipse.core.tests.resources.ResourceTestUtil.createTestMonitor; import static org.eclipse.core.tests.resources.ResourceTestUtil.waitForRefresh; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.internal.localstore.UnifiedTree; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.tests.resources.WorkspaceTestRule; -import org.junit.Rule; -import org.junit.Test; - +import org.eclipse.core.runtime.Platform.OS; +import org.eclipse.core.tests.resources.util.WorkspaceResetExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@ExtendWith(WorkspaceResetExtension.class) public class SymlinkResourceTest { - @Rule - public WorkspaceTestRule workspaceRule = new WorkspaceTestRule(); - private void mkLink(IFileStore dir, String src, String tgt, boolean isDir) throws CoreException, IOException { createSymLink(dir.toLocalFile(EFS.NONE, createTestMonitor()), src, tgt, isDir); } @@ -70,6 +75,88 @@ protected void createBug358830Structure(IFileStore rootDir) throws CoreException mkLink(folderA, "link", IPath.fromOSString("../").toOSString(), true); } + /** + * Test a case of both recursive and non recursive symbolic links that uncovered + * issue described in GitHub bug + * 2220. + * + *
    {@code
    +	 *      /A/B -> /X/Y/Z  	(B is symbolic link as precondition)
    +	 *      /A/B/C/D -> ../../D (non-recursive)
    +	 *      /A/B/C/E -> ../../Z (recursive)
    +	 * }
    + * + * The starting path /A/B/C is already based on link. The real path of start is + * /X/Y/Z/C so ../../Z points (recursive) to /X/Y/Z. /X/Y/D and /X/Y/Z is what + * we expect to resolve but we fail in both cases with NoSuchFileException. + */ + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void testGithubBug2220(boolean useAdvancedLinkCheck) throws Exception { + assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links"); + assumeTrue(!OS.isWindows(), "Windows file system handles recursive links differently"); + final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled(); + try { + UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck); + IProject project = getWorkspace().getRoot().getProject("testGithubBug2220"); + createInWorkspace(project); + + /* Re-use projects which are cleaned up automatically */ + getWorkspace().run((IWorkspaceRunnable) monitor -> { + /* delete open project because we must re-open with BACKGROUND_REFRESH */ + project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, createTestMonitor()); + project.create(null); + try { + createGithubBug2220Structure(EFS.getStore(project.getLocationURI())); + } catch (IOException e) { + throw new IllegalStateException("unexpected IOException occurred", e); + } + // Bug only happens with BACKGROUND_REFRESH. + project.open(IResource.BACKGROUND_REFRESH, createTestMonitor()); + }, null); + + // wait for BACKGROUND_REFRESH to complete. + waitForRefresh(); + project.accept(new IResourceVisitor() { + int resourceCount = 0; + + @Override + public boolean visit(IResource resource) { + resourceCount++; + // We have 1 root + .settings + prefs + + .project + 10 elements --> 14 elements + // to visit at most + System.out.println(resourceCount + " visited: " + resource.getFullPath()); + assertTrue(resourceCount <= 15, "Expected max 15 elements to visit, got: " + resourceCount); + return true; + } + }); + } finally { + UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue); + } + } + + /** + *
    {@code
    +	 *      /A/B -> /X/Y/Z  	(B is symbolic link as precondition)
    +	 *      /A/B/C/D -> ../../D (non-recursive)
    +	 *      /A/B/C/E -> ../../Z (recursive)
    +	 * }
    + * + * The starting path /A/B/C is already based on link. The real path of start is + * /X/Y/Z/C so ../../Z points (recursive) to /X/Y/Z. + */ + protected void createGithubBug2220Structure(IFileStore rootDir) throws CoreException, IOException { + Path root = rootDir.toLocalFile(EFS.NONE, createTestMonitor()).toPath(); + Files.createDirectories(root.resolve("A")); + Files.createDirectories(root.resolve("X/Y/Z")); + Files.createDirectories(root.resolve("X/Y/D")); + Files.createSymbolicLink(root.resolve("A/B"), root.resolve("X/Y/Z")); + Files.createDirectories(root.resolve("A/B/C")); + Files.createSymbolicLink(root.resolve("A/B/C/D"), Paths.get("../../D")); + Files.createSymbolicLink(root.resolve("A/B/C/E"), Paths.get("../../Z")); + } + /** * Test a very specific case of mutually recursive symbolic links: *
     {@code
    @@ -85,7 +172,7 @@ protected void createBug358830Structure(IFileStore rootDir) throws CoreException
     	 */
     	@Test
     	public void testBug232426() throws Exception {
    -		assumeTrue("only relevant for platforms supporting symbolic links", canCreateSymLinks());
    +		assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links");
     
     		IProject project = getWorkspace().getRoot().getProject("Project");
     		createInWorkspace(project);
    @@ -118,36 +205,42 @@ public boolean visit(IResource resource) {
     		});
     	}
     
    -	@Test
    -	public void testBug358830() throws Exception {
    -		assumeTrue("only relevant for platforms supporting symbolic links", canCreateSymLinks());
    -
    -		IProject project = getWorkspace().getRoot().getProject("Project");
    -		createInWorkspace(project);
    -		/* Re-use projects which are cleaned up automatically */
    -		getWorkspace().run((IWorkspaceRunnable) monitor -> {
    -			/* delete open project because we must re-open with BACKGROUND_REFRESH */
    -			project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, createTestMonitor());
    -			project.create(null);
    -			try {
    -				createBug358830Structure(EFS.getStore(project.getLocationURI()));
    -			} catch (IOException e) {
    -				throw new IllegalStateException("unexpected IOException occurred", e);
    -			}
    -			project.open(IResource.BACKGROUND_REFRESH, createTestMonitor());
    -		}, null);
    -
    -		//wait for BACKGROUND_REFRESH to complete.
    -		waitForRefresh();
    -		final int resourceCount[] = new int[] {0};
    -		project.accept(resource -> {
    -			resourceCount[0]++;
    -			return true;
    -		});
    -		// We have 1 root + 1 folder + 1 file (.project)
    -		// + .settings / resources prefs
    -		// --> 5 elements to visit
    -		assertEquals(5, resourceCount[0]);
    +	@ParameterizedTest
    +	@ValueSource(booleans = { false, true })
    +	public void testBug358830(boolean useAdvancedLinkCheck) throws Exception {
    +		assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links");
    +		final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled();
    +		try {
    +			UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck);
    +			IProject project = getWorkspace().getRoot().getProject("Project");
    +			createInWorkspace(project);
    +			/* Re-use projects which are cleaned up automatically */
    +			getWorkspace().run((IWorkspaceRunnable) monitor -> {
    +				/* delete open project because we must re-open with BACKGROUND_REFRESH */
    +				project.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, createTestMonitor());
    +				project.create(null);
    +				try {
    +					createBug358830Structure(EFS.getStore(project.getLocationURI()));
    +				} catch (IOException e) {
    +					throw new IllegalStateException("unexpected IOException occurred", e);
    +				}
    +				project.open(IResource.BACKGROUND_REFRESH, createTestMonitor());
    +			}, null);
    +
    +			// wait for BACKGROUND_REFRESH to complete.
    +			waitForRefresh();
    +			final int resourceCount[] = new int[] { 0 };
    +			project.accept(resource -> {
    +				resourceCount[0]++;
    +				return true;
    +			});
    +			// We have 1 root + 1 folder + 1 file (.project)
    +			// + .settings / resources prefs
    +			// --> 5 elements to visit
    +			assertEquals(5, resourceCount[0]);
    +		} finally {
    +			UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue);
    +		}
     	}
     
     }
    diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java
    index c5483cd4bc9..d4c82a80eae 100644
    --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java
    +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/NatureTest.java
    @@ -167,6 +167,30 @@ public void testInvalidRemovals() throws Throwable {
     		assertHasEnabledNature(NATURE_SNOW);
     	}
     
    +	/**
    +	 * Tests that duplicate natures in the project description don't cause
    +	 * IllegalArgumentException. This is a regression test for a bug where
    +	 * Set.of() was used which throws on duplicates.
    +	 */
    +	@Test
    +	public void testDuplicateNatures() throws Throwable {
    +		createInWorkspace(project);
    +
    +		// Set initial nature
    +		setNatures(project, new String[] { NATURE_SIMPLE }, false);
    +		assertHasEnabledNature(NATURE_SIMPLE);
    +
    +		// Try to set natures with a duplicate - this should not throw IllegalArgumentException
    +		// The duplicate should be handled gracefully (deduplication happens automatically)
    +		IProjectDescription desc = project.getDescription();
    +		desc.setNatureIds(new String[] { NATURE_SIMPLE, NATURE_SIMPLE });
    +		// This should not throw IllegalArgumentException when hasPrivateChanges is called
    +		project.setDescription(desc, IResource.KEEP_HISTORY, createTestMonitor());
    +		
    +		// After deduplication, only one instance of the nature should remain
    +		assertHasEnabledNature(NATURE_SIMPLE);
    +	}
    +
     	@Test
     	public void testNatureLifecyle() throws Throwable {
     		createInWorkspace(project);
    diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java
    index 274fe6913c9..c4dce863533 100644
    --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java
    +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_LinuxTests.java
    @@ -11,10 +11,10 @@
     package org.eclipse.core.tests.resources.regression;
     
     import static org.eclipse.core.tests.resources.ResourceTestUtil.createTestMonitor;
    -import static org.junit.Assume.assumeTrue;
     import static org.junit.jupiter.api.Assertions.assertEquals;
     import static org.junit.jupiter.api.Assertions.assertNotNull;
     import static org.junit.jupiter.api.Assertions.assertTrue;
    +import static org.junit.jupiter.api.Assumptions.assumeTrue;
     
     import java.io.File;
     import java.io.IOException;
    @@ -26,6 +26,7 @@
     import java.util.ArrayList;
     import java.util.Arrays;
     import java.util.List;
    +import org.eclipse.core.internal.localstore.UnifiedTree;
     import org.eclipse.core.internal.resources.ProjectDescription;
     import org.eclipse.core.resources.IProject;
     import org.eclipse.core.resources.IProjectDescription;
    @@ -38,10 +39,11 @@
     import org.eclipse.core.runtime.URIUtil;
     import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
     import org.junit.jupiter.api.BeforeEach;
    -import org.junit.jupiter.api.Test;
     import org.junit.jupiter.api.TestInfo;
     import org.junit.jupiter.api.extension.ExtendWith;
     import org.junit.jupiter.api.io.TempDir;
    +import org.junit.jupiter.params.ParameterizedTest;
    +import org.junit.jupiter.params.provider.ValueSource;
     
     /**
      * Test cases for symbolic links in projects.
    @@ -56,7 +58,7 @@ public class Bug_185247_LinuxTests {
     
     	@BeforeEach
     	public void setUp(TestInfo testInfo) throws Exception {
    -		assumeTrue("only relevant on Linux", OS.isLinux());
    +		assumeTrue(OS.isLinux(), "only relevant on Linux");
     
     		testMethodName = testInfo.getTestMethod().get().getName();
     		IPath randomLocation = IPath.fromPath(tempDirectory);
    @@ -74,34 +76,45 @@ private void extractTestCasesArchive(IPath outputLocation) throws Exception {
     		unzip(archive, outputLocation.toFile());
     	}
     
    -	@Test
    -	public void test1_trivial() throws Exception {
    -		runProjectTestCase();
    +	@ParameterizedTest
    +	@ValueSource(booleans = { false, true })
    +	public void test1_trivial(boolean useAdvancedLinkCheck) throws Exception {
    +		runProjectTestCase(useAdvancedLinkCheck);
     	}
     
    -	@Test
    -	public void test2_mutual() throws Exception {
    -		runProjectTestCase();
    +	@ParameterizedTest
    +	@ValueSource(booleans = { false, true })
    +	public void test2_mutual(boolean useAdvancedLinkCheck) throws Exception {
    +		runProjectTestCase(useAdvancedLinkCheck);
     	}
     
    -	@Test
    -	public void test3_outside_tree() throws Exception {
    -		runProjectTestCase();
    +	@ParameterizedTest
    +	@ValueSource(booleans = { false, true })
    +	public void test3_outside_tree(boolean useAdvancedLinkCheck) throws Exception {
    +		runProjectTestCase(useAdvancedLinkCheck);
     	}
     
    -	@Test
    -	public void test5_transitive_mutual() throws Exception {
    -		runProjectTestCase();
    +	@ParameterizedTest
    +	@ValueSource(booleans = { false, true })
    +	public void test5_transitive_mutual(boolean useAdvancedLinkCheck) throws Exception {
    +		runProjectTestCase(useAdvancedLinkCheck);
     	}
     
    -	@Test
    -	public void test6_nonrecursive() throws Exception {
    -		runProjectTestCase();
    +	@ParameterizedTest
    +	@ValueSource(booleans = { false, true })
    +	public void test6_nonrecursive(boolean useAdvancedLinkCheck) throws Exception {
    +		runProjectTestCase(useAdvancedLinkCheck);
     	}
     
    -	private void runProjectTestCase() throws Exception {
    -		// refresh should hang, if bug 105554 re-occurs
    -		importProjectAndRefresh(testMethodName);
    +	private void runProjectTestCase(boolean useAdvancedLinkCheck) throws Exception {
    +		final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled();
    +		try {
    +			UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck);
    +			// refresh should hang, if bug 105554 re-occurs
    +			importProjectAndRefresh(testMethodName);
    +		} finally {
    +			UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue);
    +		}
     	}
     
     	private void importProjectAndRefresh(String projectName) throws Exception {
    diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java
    index 34487877e93..3875bb952b1 100644
    --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java
    +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/Bug_185247_recursiveLinks.java
    @@ -13,8 +13,8 @@
     import static org.eclipse.core.tests.harness.FileSystemHelper.canCreateSymLinks;
     import static org.eclipse.core.tests.harness.FileSystemHelper.createSymLink;
     import static org.eclipse.core.tests.resources.ResourceTestUtil.createTestMonitor;
    -import static org.junit.Assume.assumeTrue;
     import static org.junit.jupiter.api.Assertions.assertTrue;
    +import static org.junit.jupiter.api.Assumptions.assumeTrue;
     
     import java.io.File;
     import java.io.IOException;
    @@ -22,6 +22,7 @@
     import java.net.URI;
     import java.nio.file.Path;
     import org.eclipse.core.filesystem.URIUtil;
    +import org.eclipse.core.internal.localstore.UnifiedTree;
     import org.eclipse.core.internal.resources.ProjectDescription;
     import org.eclipse.core.resources.IProject;
     import org.eclipse.core.resources.IProjectDescription;
    @@ -30,10 +31,11 @@
     import org.eclipse.core.runtime.IPath;
     import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
     import org.junit.jupiter.api.BeforeEach;
    -import org.junit.jupiter.api.Test;
     import org.junit.jupiter.api.TestInfo;
     import org.junit.jupiter.api.extension.ExtendWith;
     import org.junit.jupiter.api.io.TempDir;
    +import org.junit.jupiter.params.ParameterizedTest;
    +import org.junit.jupiter.params.provider.ValueSource;
     
     /**
      * Tests for recursive symbolic links in projects.
    @@ -47,7 +49,7 @@ public class Bug_185247_recursiveLinks {
     
     	@BeforeEach
     	public void requireCanCreateSymlinks(TestInfo testInfo) throws IOException {
    -		assumeTrue("only relevant for platforms supporting symbolic links", canCreateSymLinks());
    +		assumeTrue(canCreateSymLinks(), "only relevant for platforms supporting symbolic links");
     		testMethodName = testInfo.getTestMethod().get().getName();
     	}
     
    @@ -62,13 +64,14 @@ public void requireCanCreateSymlinks(TestInfo testInfo) throws IOException {
     	 *         |-- link_current -> ./ (links "directory")
     	 * 
    */ - @Test - public void test1_linkCurrentDirectory() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test1_linkCurrentDirectory(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { createSymlink(directory, "link_current", "./"); }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -82,13 +85,14 @@ public void test1_linkCurrentDirectory() throws Exception { * |-- link_parent -> ../ (links "project root") * */ - @Test - public void test2_linkParentDirectory() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test2_linkParentDirectory(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { createSymlink(directory, "link_parent", "../"); }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -104,15 +108,16 @@ public void test2_linkParentDirectory() throws Exception { * |-- link_grandparent -> ../../ (links "project root") * */ - @Test - public void test3_linkGrandparentDirectory() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test3_linkGrandparentDirectory(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { File subdirectory = new File(directory, "subdirectory"); createDirectory(subdirectory); createSymlink(subdirectory, "link_grandparent", "../../"); }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -132,8 +137,9 @@ public void test3_linkGrandparentDirectory() throws Exception { * |-- link_parent -> ../ (links directory) * */ - @Test - public void test4_linkParentDirectoryTwice() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test4_linkParentDirectoryTwice(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { String[] subdirectoryNames = { "subdirectory1", "subdirectory2" }; for (String subdirectoryName : subdirectoryNames) { @@ -143,7 +149,7 @@ public void test4_linkParentDirectoryTwice() throws Exception { } }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } /** @@ -163,8 +169,9 @@ public void test4_linkParentDirectoryTwice() throws Exception { * |-- link_parent -> /tmp/<random string>/bug185247recursive/test5_linkParentDirectoyTwiceWithAbsolutePath/directory * */ - @Test - public void test5_linkParentDirectoyTwiceWithAbsolutePath() throws Exception { + @ParameterizedTest + @ValueSource(booleans = { false, true }) + public void test5_linkParentDirectoyTwiceWithAbsolutePath(boolean useAdvancedLinkCheck) throws Exception { CreateTestProjectStructure createSymlinks = directory -> { String[] subdirectoryNames = { "subdirectory1", "subdirectory2" }; for (String subdirectoryName : subdirectoryNames) { @@ -174,22 +181,28 @@ public void test5_linkParentDirectoyTwiceWithAbsolutePath() throws Exception { } }; - runTest(createSymlinks); + runTest(createSymlinks, useAdvancedLinkCheck); } - private void runTest(CreateTestProjectStructure createSymlinks) throws MalformedURLException, Exception { - String projectName = testMethodName; - IPath testRoot = IPath.fromPath(tempDirectory); - IPath projectRoot = testRoot.append("bug185247recursive").append(projectName); - File directory = projectRoot.append("directory").toFile(); - createDirectory(directory); - - createSymlinks.accept(directory); - - - URI projectRootLocation = URIUtil.toURI((projectRoot)); - // refreshing the project with recursive symlinks should not hang - importProjectAndRefresh(projectName, projectRootLocation); + private void runTest(CreateTestProjectStructure createSymlinks, boolean useAdvancedLinkCheck) + throws MalformedURLException, Exception { + final boolean originalValue = UnifiedTree.isAdvancedRecursiveLinkChecksEnabled(); + try { + UnifiedTree.enableAdvancedRecursiveLinkChecks(useAdvancedLinkCheck); + String projectName = testMethodName; + IPath testRoot = IPath.fromPath(tempDirectory); + IPath projectRoot = testRoot.append("bug185247recursive").append(projectName); + File directory = projectRoot.append("directory").toFile(); + createDirectory(directory); + + createSymlinks.accept(directory); + + URI projectRootLocation = URIUtil.toURI((projectRoot)); + // refreshing the project with recursive symlinks should not hang + importProjectAndRefresh(projectName, projectRootLocation); + } finally { + UnifiedTree.enableAdvancedRecursiveLinkChecks(originalValue); + } } private static void createDirectory(File directory) { diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java index 46e8259b772..1edb209e035 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/session/TestWorkspaceEncodingWithJvmArgs.java @@ -29,7 +29,7 @@ */ public class TestWorkspaceEncodingWithJvmArgs { - private static final String CHARSET = "UTF-16"; + private static final String CHARSET = "ASCII"; @RegisterExtension SessionTestExtension sessionTestExtension = SessionTestExtension.forPlugin(PI_RESOURCES_TESTS) @@ -38,7 +38,7 @@ public class TestWorkspaceEncodingWithJvmArgs { @BeforeEach @ExecuteInHost public void setUpSession() { - sessionTestExtension.setSystemProperty("file.encoding", "UTF-16"); + sessionTestExtension.setSystemProperty("file.encoding", CHARSET); } @Test diff --git a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java index 937eeb73c1b..81af73f6faf 100644 --- a/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java +++ b/resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/util/WorkspaceResetExtension.java @@ -40,7 +40,7 @@ public class WorkspaceResetExtension implements AfterEachCallback, BeforeEachCal public void beforeEach(ExtensionContext context) throws Exception { // Wait for any pending refresh operation, in particular from startup waitForRefresh(); - TestUtil.log(IStatus.INFO, context.getDisplayName(), "setUp"); + TestUtil.log(IStatus.INFO, getTestName(context), "setUp"); assertNotNull(getWorkspace(), "Workspace was not set up"); FreezeMonitor.expectCompletionInAMinute(); waitForRefresh(); @@ -48,7 +48,7 @@ public void beforeEach(ExtensionContext context) throws Exception { @Override public void afterEach(ExtensionContext context) throws Exception { - TestUtil.log(IStatus.INFO, context.getDisplayName(), "tearDown"); + TestUtil.log(IStatus.INFO, getTestName(context), "tearDown"); try { restoreCleanWorkspace(); } finally { @@ -57,6 +57,16 @@ public void afterEach(ExtensionContext context) throws Exception { } } + private String getTestName(ExtensionContext context) { + String className = context.getRequiredTestClass().getSimpleName(); + String methodName = context.getRequiredTestMethod().getName(); + String displayName = context.getDisplayName(); + if (!displayName.contains(methodName)) { + methodName += displayName; + } + return className + "." + methodName; + } + private void restoreCleanWorkspace() { List exceptions = new ArrayList<>(); try { diff --git a/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java b/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java index 7fe6dc86300..d86a3319fde 100644 --- a/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java +++ b/runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/runtime/content/XMLRootElementContentDescriber.java @@ -96,6 +96,7 @@ private int checkCriteria(Map properties) throws IOException { /* (Intentionally not included in javadoc) * @see IContentDescriber#describe(InputStream, IContentDescription) */ + @Deprecated @Override public int describe(InputStream contents, IContentDescription description) throws IOException { return describe(contents, description, new HashMap<>()); @@ -104,6 +105,7 @@ public int describe(InputStream contents, IContentDescription description) throw /** * @noreference This method is not intended to be referenced by clients. */ + @Deprecated public int describe(InputStream contents, IContentDescription description, Map properties) throws IOException { // call the basic XML describer to do basic recognition if (super.describe2(contents, description, properties) == INVALID) { @@ -118,6 +120,7 @@ public int describe(InputStream contents, IContentDescription description, Map()); @@ -126,6 +129,7 @@ public int describe(Reader contents, IContentDescription description) throws IOE /** * @noreference This method is not intended to be referenced by clients. */ + @Deprecated public int describe(Reader contents, IContentDescription description, Map properties) throws IOException { // call the basic XML describer to do basic recognition if (super.describe2(contents, description, properties) == INVALID) { @@ -140,6 +144,7 @@ public int describe(Reader contents, IContentDescription description, Map 0 && pluginID.equals(event.getChild().name())) { @@ -75,6 +78,7 @@ public synchronized void added(IEclipsePreferences.NodeChangeEvent event) { /* * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#removed(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent) */ + @Deprecated @Override public synchronized void removed(IEclipsePreferences.NodeChangeEvent event) { // Do nothing. We can't remove ourselves from the node's list of preference change @@ -87,6 +91,7 @@ public synchronized void removed(IEclipsePreferences.NodeChangeEvent event) { * * @param listener a property change listener */ + @Deprecated @Override public synchronized void addPropertyChangeListener(IPropertyChangeListener listener) { if (listeners.size() == 0) { @@ -103,6 +108,7 @@ public synchronized void addPropertyChangeListener(IPropertyChangeListener liste /* * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) */ + @Deprecated @Override public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) { // if we are the ones making this change, then don't broadcast @@ -145,6 +151,7 @@ private IEclipsePreferences getDefaultPreferences() { * * @param listener a property change listener */ + @Deprecated @Override public synchronized void removePropertyChangeListener(IPropertyChangeListener listener) { listeners.remove(listener); @@ -194,6 +201,7 @@ private Object getDefault(String key, Object obj) { * @return true if either a current value or a default * value is known for the named property, and falseotherwise */ + @Deprecated @Override public boolean contains(String name) { if (name == null) { @@ -216,6 +224,7 @@ public boolean contains(String name) { * @param name the name of the property * @return the boolean-valued property */ + @Deprecated @Override public boolean getBoolean(String name) { return getPluginPreferences(true).getBoolean(name, getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT)); @@ -240,6 +249,7 @@ public boolean getBoolean(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, boolean value) { Boolean oldValue = getBoolean(name) ? Boolean.TRUE : Boolean.FALSE; @@ -270,6 +280,7 @@ public void setValue(String name, boolean value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public boolean getDefaultBoolean(String name) { return getDefaultPreferences().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT); @@ -290,6 +301,7 @@ public boolean getDefaultBoolean(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, boolean value) { getDefaultPreferences().putBoolean(name, value); @@ -305,6 +317,7 @@ public void setDefault(String name, boolean value) { * @param name the name of the property * @return the double-valued property */ + @Deprecated @Override public double getDouble(String name) { return getPluginPreferences(true).getDouble(name, getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT)); @@ -330,6 +343,7 @@ public double getDouble(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setValue(String name, double value) { if (Double.isNaN(value)) { @@ -364,6 +378,7 @@ public void setValue(String name, double value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public double getDefaultDouble(String name) { return getDefaultPreferences().getDouble(name, DOUBLE_DEFAULT_DEFAULT); @@ -385,6 +400,7 @@ public double getDefaultDouble(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setDefault(String name, double value) { if (Double.isNaN(value)) { @@ -403,6 +419,7 @@ public void setDefault(String name, double value) { * @param name the name of the property * @return the float-valued property */ + @Deprecated @Override public float getFloat(String name) { return getPluginPreferences(true).getFloat(name, getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT)); @@ -428,6 +445,7 @@ public float getFloat(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setValue(String name, float value) { if (Float.isNaN(value)) { @@ -462,6 +480,7 @@ public void setValue(String name, float value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public float getDefaultFloat(String name) { return getDefaultPreferences().getFloat(name, FLOAT_DEFAULT_DEFAULT); @@ -483,6 +502,7 @@ public float getDefaultFloat(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated @Override public void setDefault(String name, float value) { if (Float.isNaN(value)) { @@ -501,6 +521,7 @@ public void setDefault(String name, float value) { * @param name the name of the property * @return the int-valued property */ + @Deprecated @Override public int getInt(String name) { return getPluginPreferences(true).getInt(name, getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT)); @@ -525,6 +546,7 @@ public int getInt(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, int value) { final int intValue = getInt(name); @@ -556,6 +578,7 @@ public void setValue(String name, int value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public int getDefaultInt(String name) { return getDefaultPreferences().getInt(name, INT_DEFAULT_DEFAULT); @@ -576,6 +599,7 @@ public int getDefaultInt(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, int value) { getDefaultPreferences().putInt(name, value); @@ -591,6 +615,7 @@ public void setDefault(String name, int value) { * @param name the name of the property * @return the long-valued property */ + @Deprecated @Override public long getLong(String name) { return getPluginPreferences(true).getLong(name, getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT)); @@ -615,6 +640,7 @@ public long getLong(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, long value) { final long longValue = getLong(name); @@ -646,6 +672,7 @@ public void setValue(String name, long value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public long getDefaultLong(String name) { return getDefaultPreferences().getLong(name, LONG_DEFAULT_DEFAULT); @@ -666,6 +693,7 @@ public long getDefaultLong(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, long value) { getDefaultPreferences().putLong(name, value); @@ -680,6 +708,7 @@ public void setDefault(String name, long value) { * @param name the name of the property * @return the string-valued property */ + @Deprecated @Override public String getString(String name) { return getPluginPreferences(true).get(name, getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT)); @@ -704,6 +733,7 @@ public String getString(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated @Override public void setValue(String name, String value) { if (value == null) { @@ -736,6 +766,7 @@ public void setValue(String name, String value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated @Override public String getDefaultString(String name) { return getDefaultPreferences().get(name, STRING_DEFAULT_DEFAULT); @@ -756,6 +787,7 @@ public String getDefaultString(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated @Override public void setDefault(String name, String value) { if (value == null) { @@ -773,6 +805,7 @@ public void setDefault(String name, String value) { * and false otherwise (including the case where the property * is unknown to this object) */ + @Deprecated @Override public boolean isDefault(String name) { if (name == null) { @@ -800,6 +833,7 @@ public boolean isDefault(String name) { * * @param name the name of the property */ + @Deprecated @Override public void setToDefault(String name) { IEclipsePreferences preferences = getPluginPreferences(true); @@ -815,6 +849,7 @@ public void setToDefault(String name) { * * @return an array of property names */ + @Deprecated @Override public String[] propertyNames() { return getPluginPreferences(true).keys(); @@ -826,6 +861,7 @@ public String[] propertyNames() { * * @return an array of property names */ + @Deprecated @Override public String[] defaultPropertyNames() { try { @@ -844,6 +880,7 @@ public String[] defaultPropertyNames() { * known to this preference object has a current value different from its * default value, and false otherwise */ + @Deprecated @Override public boolean needsSaving() { return getPluginPreferences(true).isDirty(); @@ -852,6 +889,7 @@ public boolean needsSaving() { /** * Flush the values of these plug-in preferences to disk. */ + @Deprecated public void flush() throws BackingStoreException { IEclipsePreferences node = getPluginPreferences(false); if (node != null) { @@ -870,6 +908,7 @@ private void logError(String message, Exception e) { /* * @see org.eclipse.core.runtime.Preferences#load(java.io.InputStream) */ + @Deprecated @Override public void load(InputStream in) throws IOException { Properties result = new Properties(); @@ -888,6 +927,7 @@ public void load(InputStream in) throws IOException { /* * @see org.eclipse.core.runtime.Preferences#store(java.io.OutputStream, java.lang.String) */ + @Deprecated @Override public void store(OutputStream out, String header) throws IOException { Properties result = convertToProperties(); @@ -913,6 +953,7 @@ private void convertFromProperties(Properties props) { } } + @Deprecated @Override public String toString() { return "PreferenceForwarder(" + pluginID + ")"; //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java new file mode 100644 index 00000000000..e0e41f49f91 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/CollectionTrustManager.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE 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: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import javax.net.ssl.X509TrustManager; + +public class CollectionTrustManager implements X509TrustManager { + + private final List trustManagers; + + public CollectionTrustManager(List trustManagers) { + this.trustManagers = trustManagers; + } + + public List getTrustManagers() { + return trustManagers; + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + CertificateException ce = null; + for (X509TrustManager trustManager : this.getTrustManagers()) { + try { + trustManager.checkClientTrusted(chain, authType); + return; + } catch (CertificateException e) { + if (ce == null) { + ce = e; + } else { + ce.addSuppressed(e); + } + } + } + if (ce != null) { + throw ce; + } + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + CertificateException ce = null; + for (X509TrustManager trustManager : this.getTrustManagers()) { + try { + trustManager.checkServerTrusted(chain, authType); + return; + } catch (CertificateException e) { + if (ce == null) { + ce = e; + } else { + ce.addSuppressed(e); + } + } + } + if (ce != null) { + throw ce; + } + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return this.getTrustManagers().stream() // + .map(X509TrustManager::getAcceptedIssuers) // + .filter(Objects::nonNull).flatMap(Arrays::stream).toArray(X509Certificate[]::new); + } + +} diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java index 990d7d3c9cf..7148f259a8d 100644 --- a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java @@ -48,6 +48,7 @@ import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.RegistryFactory; import org.eclipse.core.runtime.ServiceCaller; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.content.IContentTypeManager; import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.equinox.app.IApplicationContext; @@ -585,6 +586,14 @@ private void initializeAuthorizationHandler() { } } + private void initializeSSLContext() { + try { + new KeyStoreUtil(getOS()).setUpSslContext(); + } catch (Exception e) { + RuntimeLog.log(Status.error("Exception setting up SSLContext", e)); //$NON-NLS-1$ + } + } + /* * Finds and loads the options file */ @@ -701,6 +710,7 @@ public void start(BundleContext runtimeContext) { initialized = true; stopped = false; initializeAuthorizationHandler(); + initializeSSLContext(); startServices(); } diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java new file mode 100644 index 00000000000..20299109d48 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/KeyStoreUtil.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE 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: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509KeyManager; +import javax.net.ssl.X509TrustManager; +import org.eclipse.osgi.service.environment.Constants; + +public class KeyStoreUtil { + + @SuppressWarnings("nls") + private static final String SYSTEM_PROPERTY_MERGE_TRUST = "eclipse.platform.mergeTrust"; + + private final String os; + + private static final record KeyStoreAndPassword(KeyStore keyStore, char[] password) { + } + + public KeyStoreUtil(String os) { + this.os = os; + } + + @SuppressWarnings("nls") + public void setUpSslContext() throws GeneralSecurityException, IOException { + + if (!Boolean.getBoolean(SYSTEM_PROPERTY_MERGE_TRUST)) { + return; + } + + List keyStores = new ArrayList<>(); + // null will loads JVM cacerts OR store indicated by "javax.net.ssl.trustStore" properties + keyStores.add(new KeyStoreAndPassword(null, null)); + if (System.getProperty("javax.net.ssl.trustStore", "").isEmpty()) { + if (Constants.OS_MACOSX.equals(os)) { + keyStores.add(createKeyStore("KeychainStore", "Apple")); + } else if (Constants.OS_WIN32.equals(os)) { + keyStores.add(createKeyStore("Windows-ROOT", null)); + } + } + List trustManagers = new ArrayList<>(); + for (KeyStoreAndPassword storeAndPassword : keyStores) { + trustManagers.add(createX509TrustManager(storeAndPassword.keyStore())); + } + TrustManager[] tm = { new CollectionTrustManager(trustManagers) }; + + KeyManager[] km = {}; + KeyStoreAndPassword keyStore = createKeyStoreFromSystemProperties(); + if (keyStore != null) { + km = new KeyManager[] { createX509KeyManager(keyStore.keyStore(), keyStore.password()) }; + } + + SSLContext sslContext = SSLContext.getInstance("TLS"); + initSSLContext(sslContext, tm, km, null); + SSLContext.setDefault(sslContext); + } + + private KeyStoreAndPassword createKeyStore(String type, String provider) + throws GeneralSecurityException, IOException { + KeyStore keyStore; + if (provider == null) { + keyStore = KeyStore.getInstance(type); + } else { + keyStore = KeyStore.getInstance(type, provider); + } + keyStore.load(null, null); + return new KeyStoreAndPassword(keyStore, null); + } + + protected X509TrustManager createX509TrustManager(KeyStore keyStore) throws GeneralSecurityException { + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + return Arrays.stream(tmf.getTrustManagers()).filter(X509TrustManager.class::isInstance) // + .map(X509TrustManager.class::cast) // + .findFirst().orElse(null); + } + + protected X509KeyManager createX509KeyManager(KeyStore keyStore, char[] password) throws GeneralSecurityException { + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, password); + return Arrays.stream(kmf.getKeyManagers()).filter(X509KeyManager.class::isInstance) // + .map(X509KeyManager.class::cast) // + .findFirst().orElse(null); + } + + protected void initSSLContext(SSLContext context, TrustManager[] trustManagers, KeyManager[] keyManagers, + SecureRandom random) throws KeyManagementException { + context.init(keyManagers, trustManagers, random); + } + + /** + * Coding based on + * sun.security.ssl.SSLContextImpl.DefaultManagersHolder.getKeyManagers() with + * minor adjustments (access properties directy without AccessController, return + * nothing if properties not set). + */ + @SuppressWarnings("nls") + private KeyStoreAndPassword createKeyStoreFromSystemProperties() throws GeneralSecurityException, IOException { + String p11KeyStore = "PKCS11"; + String none = "NONE"; + String keyStore = System.getProperty("javax.net.ssl.keyStore", ""); + String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", ""); + String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider", ""); + String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword", ""); + + if (keyStoreType.isEmpty()) { + if (keyStore.isEmpty()) { + return null; + } + keyStoreType = KeyStore.getDefaultType(); + } + if (p11KeyStore.equals(keyStoreType) && !none.equals(keyStore)) { + throw new IllegalArgumentException("if keyStoreType is " + p11KeyStore + ", then keyStore must be " + none); + } + char[] passwd = null; + if (!keyStorePassword.isEmpty()) { + passwd = keyStorePassword.toCharArray(); + } + KeyStore ks = null; + if (keyStoreProvider.isEmpty()) { + ks = KeyStore.getInstance(keyStoreType); + } else { + ks = KeyStore.getInstance(keyStoreType, keyStoreProvider); + } + if (!keyStore.isEmpty() && !none.equals(keyStore)) { + try (InputStream is = new FileInputStream(keyStore)) { + ks.load(is, passwd); + } + } else { + ks.load(null, passwd); + } + return new KeyStoreAndPassword(ks, p11KeyStore.equals(keyStoreType) ? null : passwd); + } + +} diff --git a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java index dfdc23c44b8..bc9bff88185 100644 --- a/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java +++ b/runtime/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Preferences.java @@ -98,43 +98,51 @@ public class Preferences { /** * The default-default value for boolean properties (false). */ + @Deprecated public static final boolean BOOLEAN_DEFAULT_DEFAULT = false; /** * The default-default value for double properties (0.0). */ + @Deprecated public static final double DOUBLE_DEFAULT_DEFAULT = 0.0; /** * The default-default value for float properties (0.0f). */ + @Deprecated public static final float FLOAT_DEFAULT_DEFAULT = 0.0f; /** * The default-default value for int properties (0). */ + @Deprecated public static final int INT_DEFAULT_DEFAULT = 0; /** * The default-default value for long properties (0L). */ + @Deprecated public static final long LONG_DEFAULT_DEFAULT = 0L; /** * The default-default value for String properties (""). */ + @Deprecated public static final String STRING_DEFAULT_DEFAULT = ""; //$NON-NLS-1$ /** * The string representation used for true * ("true"). */ + @Deprecated protected static final String TRUE = "true"; //$NON-NLS-1$ /** * The string representation used for false * ("false"). */ + @Deprecated protected static final String FALSE = "false"; //$NON-NLS-1$ /** @@ -150,6 +158,7 @@ public class Preferences { * * @since 3.2 */ + @Deprecated public static final String PT_PREFERENCES = "preferences"; //$NON-NLS-1$ /** @@ -168,6 +177,7 @@ public class Preferences { * @see Preferences#addPropertyChangeListener(Preferences.IPropertyChangeListener) * @see Preferences.IPropertyChangeListener */ + @Deprecated public static class PropertyChangeEvent extends EventObject { /** * All serializable objects should have a stable serialVersionUID @@ -202,6 +212,7 @@ public static class PropertyChangeEvent extends EventObject { * @param newValue the new value of the property, or * null if none */ + @Deprecated protected PropertyChangeEvent(Object source, String property, Object oldValue, Object newValue) { super(source); @@ -223,6 +234,7 @@ protected PropertyChangeEvent(Object source, String property, Object oldValue, O * * @return the name of the property that changed */ + @Deprecated public String getProperty() { return propertyName; } @@ -233,6 +245,7 @@ public String getProperty() { * @return the new value, or null if not known * or not relevant */ + @Deprecated public Object getNewValue() { return newValue; } @@ -243,6 +256,7 @@ public Object getNewValue() { * @return the old value, or null if not known * or not relevant */ + @Deprecated public Object getOldValue() { return oldValue; } @@ -272,6 +286,7 @@ public Object getOldValue() { * three cases in their implementation of the property change listener. *

    */ + @Deprecated @FunctionalInterface public interface IPropertyChangeListener extends EventListener { @@ -285,6 +300,7 @@ public interface IPropertyChangeListener extends EventListener { * @param event the property change event object describing which * property changed and how */ + @Deprecated public void propertyChange(Preferences.PropertyChangeEvent event); } @@ -294,6 +310,7 @@ public interface IPropertyChangeListener extends EventListener { * These listeners are to be informed when the current value of a property * changes. */ + @Deprecated protected ListenerList listeners = new ListenerList<>(); /** @@ -313,6 +330,7 @@ public interface IPropertyChangeListener extends EventListener { * Indicates whether a value has been changed by setToDefault * or setValue; initially false. */ + @Deprecated protected boolean dirty = false; /** @@ -330,6 +348,7 @@ public interface IPropertyChangeListener extends EventListener { * @see #importPreferences(IPath) * @see #validatePreferenceVersions(IPath) */ + @Deprecated public static void exportPreferences(IPath path) throws CoreException { File file = path.toFile(); if (file.exists()) { @@ -372,6 +391,7 @@ public static void exportPreferences(IPath path) throws CoreException { * @see #exportPreferences(IPath) * @see #validatePreferenceVersions(IPath) */ + @Deprecated public static void importPreferences(IPath path) throws CoreException { if (!path.toFile().exists()) { String msg = NLS.bind(PrefsMessages.preferences_fileNotFound, path.toOSString()); @@ -410,6 +430,7 @@ public static void importPreferences(IPath path) throws CoreException { * @see #exportPreferences(IPath) * @see #importPreferences(IPath) */ + @Deprecated public static IStatus validatePreferenceVersions(IPath file) { PreferencesService service = PreferencesService.getDefault(); return service.validateVersions(file); @@ -424,6 +445,7 @@ public static IStatus validatePreferenceVersions(IPath file) { * @see #load(InputStream) * @see #store(OutputStream, String) */ + @Deprecated public Preferences() { defaultProperties = new Properties(); properties = new Properties(defaultProperties); @@ -441,6 +463,7 @@ public Preferences() { *

    * @param listener a property change listener */ + @Deprecated public void addPropertyChangeListener(IPropertyChangeListener listener) { listeners.add(listener); } @@ -451,6 +474,7 @@ public void addPropertyChangeListener(IPropertyChangeListener listener) { * * @param listener a property change listener */ + @Deprecated public void removePropertyChangeListener(IPropertyChangeListener listener) { listeners.remove(listener); } @@ -464,6 +488,7 @@ public void removePropertyChangeListener(IPropertyChangeListener listener) { * @return true if either a current value or a default * value is known for the named property, and falseotherwise */ + @Deprecated public boolean contains(String name) { return (properties.containsKey(name) || defaultProperties.containsKey(name)); } @@ -479,6 +504,7 @@ public boolean contains(String name) { * @param newValue the new value, or null if not known or not * relevant */ + @Deprecated protected void firePropertyChangeEvent(String name, Object oldValue, Object newValue) { if (name == null) { throw new IllegalArgumentException(); @@ -515,6 +541,7 @@ public void run() throws Exception { * @param name the name of the property * @return the boolean-valued property */ + @Deprecated public boolean getBoolean(String name) { String value = properties.getProperty(name); if (value == null) { @@ -542,6 +569,7 @@ public boolean getBoolean(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, boolean value) { boolean defaultValue = getDefaultBoolean(name); boolean oldValue = getBoolean(name); @@ -573,6 +601,7 @@ public void setValue(String name, boolean value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public boolean getDefaultBoolean(String name) { String value = defaultProperties.getProperty(name); if (value == null) { @@ -596,6 +625,7 @@ public boolean getDefaultBoolean(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, boolean value) { defaultProperties.put(name, value ? Preferences.TRUE : Preferences.FALSE); } @@ -611,6 +641,7 @@ public void setDefault(String name, boolean value) { * @param name the name of the property * @return the double-valued property */ + @Deprecated public double getDouble(String name) { return convertToDouble(properties.getProperty(name), DOUBLE_DEFAULT_DEFAULT); } @@ -635,6 +666,7 @@ public double getDouble(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated public void setValue(String name, double value) { if (Double.isNaN(value)) { throw new IllegalArgumentException(); @@ -669,6 +701,7 @@ public void setValue(String name, double value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public double getDefaultDouble(String name) { return convertToDouble(defaultProperties.getProperty(name), DOUBLE_DEFAULT_DEFAULT); } @@ -689,6 +722,7 @@ public double getDefaultDouble(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated public void setDefault(String name, double value) { if (Double.isNaN(value)) { throw new IllegalArgumentException(); @@ -729,6 +763,7 @@ private double convertToDouble(String rawPropertyValue, double defaultValue) { * @param name the name of the property * @return the float-valued property */ + @Deprecated public float getFloat(String name) { return convertToFloat(properties.getProperty(name), FLOAT_DEFAULT_DEFAULT); } @@ -753,6 +788,7 @@ public float getFloat(String name) { * @param value the new current value of the property; must be * a number (not a NaN) */ + @Deprecated public void setValue(String name, float value) { if (Float.isNaN(value)) { throw new IllegalArgumentException(); @@ -787,6 +823,7 @@ public void setValue(String name, float value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public float getDefaultFloat(String name) { return convertToFloat(defaultProperties.getProperty(name), FLOAT_DEFAULT_DEFAULT); } @@ -807,6 +844,7 @@ public float getDefaultFloat(String name) { * @param value the new default value for the property; must be * a number (not a NaN) */ + @Deprecated public void setDefault(String name, float value) { if (Float.isNaN(value)) { throw new IllegalArgumentException(); @@ -847,6 +885,7 @@ private float convertToFloat(String rawPropertyValue, float defaultValue) { * @param name the name of the property * @return the int-valued property */ + @Deprecated public int getInt(String name) { return convertToInt(properties.getProperty(name), INT_DEFAULT_DEFAULT); } @@ -870,6 +909,7 @@ public int getInt(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, int value) { int defaultValue = getDefaultInt(name); int oldValue = getInt(name); @@ -901,6 +941,7 @@ public void setValue(String name, int value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public int getDefaultInt(String name) { return convertToInt(defaultProperties.getProperty(name), INT_DEFAULT_DEFAULT); } @@ -920,6 +961,7 @@ public int getDefaultInt(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, int value) { defaultProperties.put(name, Integer.toString(value)); } @@ -957,6 +999,7 @@ private int convertToInt(String rawPropertyValue, int defaultValue) { * @param name the name of the property * @return the long-valued property */ + @Deprecated public long getLong(String name) { return convertToLong(properties.getProperty(name), LONG_DEFAULT_DEFAULT); } @@ -980,6 +1023,7 @@ public long getLong(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, long value) { long defaultValue = getDefaultLong(name); long oldValue = getLong(name); @@ -1011,6 +1055,7 @@ public void setValue(String name, long value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public long getDefaultLong(String name) { return convertToLong(defaultProperties.getProperty(name), LONG_DEFAULT_DEFAULT); } @@ -1030,6 +1075,7 @@ public long getDefaultLong(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, long value) { defaultProperties.put(name, Long.toString(value)); } @@ -1066,6 +1112,7 @@ private long convertToLong(String rawPropertyValue, long defaultValue) { * @param name the name of the property * @return the string-valued property */ + @Deprecated public String getString(String name) { String value = properties.getProperty(name); return (value != null ? value : STRING_DEFAULT_DEFAULT); @@ -1090,6 +1137,7 @@ public String getString(String name) { * @param name the name of the property * @param value the new current value of the property */ + @Deprecated public void setValue(String name, String value) { if (value == null) { throw new IllegalArgumentException(); @@ -1124,6 +1172,7 @@ public void setValue(String name, String value) { * @param name the name of the property * @return the default value of the named property */ + @Deprecated public String getDefaultString(String name) { String value = defaultProperties.getProperty(name); return (value != null ? value : STRING_DEFAULT_DEFAULT); @@ -1144,6 +1193,7 @@ public String getDefaultString(String name) { * @param name the name of the property * @param value the new default value for the property */ + @Deprecated public void setDefault(String name, String value) { if (value == null) { throw new IllegalArgumentException(); @@ -1161,6 +1211,7 @@ public void setDefault(String name, String value) { * and false otherwise (including the case where the property * is unknown to this object) */ + @Deprecated public boolean isDefault(String name) { return !properties.containsKey(name); } @@ -1184,6 +1235,7 @@ public boolean isDefault(String name) { * * @param name the name of the property */ + @Deprecated public void setToDefault(String name) { Object oldPropertyValue = properties.remove(name); if (oldPropertyValue != null) { @@ -1201,6 +1253,7 @@ public void setToDefault(String name) { * * @return an array of property names */ + @Deprecated public String[] propertyNames() { return properties.keySet().toArray(EMPTY_STRING_ARRAY); } @@ -1211,6 +1264,7 @@ public String[] propertyNames() { * * @return an array of property names */ + @Deprecated public String[] defaultPropertyNames() { return defaultProperties.keySet().toArray(EMPTY_STRING_ARRAY); } @@ -1223,6 +1277,7 @@ public String[] defaultPropertyNames() { * known to this preference object has a current value different from its * default value, and false otherwise */ + @Deprecated public boolean needsSaving() { return dirty; } @@ -1242,6 +1297,7 @@ public boolean needsSaving() { * @exception IOException if there is a problem saving this preference object * @see Properties#store(OutputStream,String) */ + @Deprecated public void store(OutputStream out, String header) throws IOException { properties.store(out, header); dirty = false; @@ -1258,6 +1314,7 @@ public void store(OutputStream out, String header) throws IOException { * object * @see java.util.Properties#load(InputStream) */ + @Deprecated public void load(InputStream in) throws IOException { properties.load(in); dirty = false; diff --git a/runtime/bundles/org.eclipse.core.tools/about.ini b/runtime/bundles/org.eclipse.core.tools/about.ini index f893efd31f2..130e80d1ed7 100644 --- a/runtime/bundles/org.eclipse.core.tools/about.ini +++ b/runtime/bundles/org.eclipse.core.tools/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.gif +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/runtime/bundles/org.eclipse.core.tools/build.properties b/runtime/bundles/org.eclipse.core.tools/build.properties index b0d9780d0bb..561ae6d5e00 100644 --- a/runtime/bundles/org.eclipse.core.tools/build.properties +++ b/runtime/bundles/org.eclipse.core.tools/build.properties @@ -23,5 +23,6 @@ bin.includes = plugin.xml,\ plugin.properties,\ about.ini,\ about.mappings,\ - about.properties + about.properties,\ + eclipse32.svg qualifier=context diff --git a/runtime/bundles/org.eclipse.core.tools/eclipse32.svg b/runtime/bundles/org.eclipse.core.tools/eclipse32.svg new file mode 100644 index 00000000000..4f0e95ebbf3 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.tools/eclipse32.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF index b7070695144..ddbb119a28c 100644 --- a/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.contenttype.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.core.contenttype.tests;singleton:=true -Bundle-Version: 1.4.100.qualifier +Bundle-Version: 1.4.200.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: @@ -11,8 +11,8 @@ Require-Bundle: org.eclipse.core.contenttype;bundle-version="3.6", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.core.contenttype.tests diff --git a/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF index 69e2e7115c2..1c9eae3130f 100644 --- a/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.expressions.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.core.expressions.tests; singleton:=true -Bundle-Version: 3.7.500.qualifier +Bundle-Version: 3.7.600.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: @@ -11,9 +11,9 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.100,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir Bundle-ActivationPolicy: lazy diff --git a/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF index 4487952ac0c..4e515734337 100644 --- a/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.harness/META-INF/MANIFEST.MF @@ -14,12 +14,12 @@ Require-Bundle: org.junit, org.eclipse.jdt.junit4.runtime, org.eclipse.jdt.junit5.runtime, org.eclipse.pde.junit.runtime, - junit-platform-launcher, - junit-platform-engine, - junit-jupiter-engine, - junit-vintage-engine, - junit-platform-suite-commons, - junit-platform-suite-engine + junit-platform-launcher;bundle-version="[1.14.0,2.0.0)", + junit-platform-engine;bundle-version="[1.14.0,2.0.0)", + junit-jupiter-engine;bundle-version="[5.14.0,6.0.0)", + junit-vintage-engine;bundle-version="[5.14.0,6.0.0)", + junit-platform-suite-commons;bundle-version="[1.14.0,2.0.0)", + junit-platform-suite-engine;bundle-version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Import-Package: javax.xml.parsers, @@ -31,14 +31,14 @@ Import-Package: javax.xml.parsers, net.bytebuddy, org.apiguardian.api, org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.condition, - org.junit.jupiter.api.extension, - org.junit.jupiter.migrationsupport, - org.junit.jupiter.params, - org.junit.platform.commons, - org.junit.platform.runner, - org.junit.platform.suite.api, + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.condition;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.migrationsupport;version="[5.14.0,6.0.0)", + org.junit.jupiter.params;version="[5.14.0,6.0.0)", + org.junit.platform.commons;version="[1.14.0,2.0.0)", + org.junit.platform.runner;version="[1.14.0,2.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)", org.opentest4j, org.w3c.dom, org.xml.sax diff --git a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF index 31efec75674..2487c0c862b 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF +++ b/runtime/tests/org.eclipse.core.tests.runtime/META-INF/MANIFEST.MF @@ -15,11 +15,12 @@ Require-Bundle: org.junit, org.eclipse.core.runtime;bundle-version="3.29.0", org.eclipse.core.tests.harness;bundle-version="3.11.0" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.jupiter.api.function, - org.junit.jupiter.api.io, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.condition;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.io;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Plugin-Class: org.eclipse.core.tests.runtime.RuntimeTestsPlugin diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java index 765014a6b7a..57bff2dcc33 100644 --- a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/AllInternalRuntimeTests.java @@ -18,6 +18,8 @@ @Suite @SelectClasses({ // + CollectionTrustManagerTest.class, // + KeyStoreUtilTest.class, // LogSerializationTest.class, // PlatformURLLocalTest.class, // PlatformURLSessionTest.class }) diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java new file mode 100644 index 00000000000..ac5c36feb96 --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/CollectionTrustManagerTest.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE 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: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.tests.internal.runtime; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayContaining; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThrows; + +import java.math.BigInteger; +import java.security.Principal; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Set; +import javax.net.ssl.X509TrustManager; +import org.eclipse.core.internal.runtime.CollectionTrustManager; +import org.junit.Test; + +@SuppressWarnings("restriction") +public class CollectionTrustManagerTest { + + @Test + public void testAcceptedIssuers() throws Exception { + X509Certificate[] acceptedIssuers1 = { new StubX509Certificate(), new StubX509Certificate() }; + X509Certificate[] acceptedIssuers2 = { new StubX509Certificate(), new StubX509Certificate() }; + X509TrustManager manager1 = new StubX509TrustManager(List.of(acceptedIssuers1)); + X509TrustManager manager2 = new StubX509TrustManager(List.of(acceptedIssuers2)); + CollectionTrustManager collectionTrustManager = new CollectionTrustManager(Arrays.asList(manager1, manager2)); + + X509Certificate[] allAcceptedIssuers = collectionTrustManager.getAcceptedIssuers(); + + assertThat(allAcceptedIssuers, + arrayContaining(acceptedIssuers1[0], acceptedIssuers1[1], acceptedIssuers2[0], acceptedIssuers2[1])); + } + + @Test + public void testCheckClientTrusted() throws Exception { + X509Certificate[] chainTrustedBy1 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedBy2 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByNone = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByBoth = { new StubX509Certificate() }; + String authType = "testAuthType"; + + StubX509TrustManager manager1 = new StubX509TrustManager(List.of(chainTrustedBy1, chainTrustedByBoth)); + StubX509TrustManager manager2 = new StubX509TrustManager(List.of(chainTrustedBy2, chainTrustedByBoth)); + + CollectionTrustManager collectionTrustManager = new CollectionTrustManager(Arrays.asList(manager1, manager2)); + + collectionTrustManager.checkClientTrusted(chainTrustedBy1, authType); + collectionTrustManager.checkClientTrusted(chainTrustedBy2, authType); + collectionTrustManager.checkClientTrusted(chainTrustedByBoth, authType); + + CertificateException exception = assertThrows(CertificateException.class, () -> { + collectionTrustManager.checkClientTrusted(chainTrustedByNone, authType); + }); + assertThat(exception, sameInstance(manager1.exception)); // first in the list + assertThat(exception.getSuppressed(), arrayContaining(sameInstance(manager2.exception))); // second, suppressed + } + + @Test + public void testCheckServerTrusted() throws Exception { + X509Certificate[] chainTrustedBy1 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedBy2 = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByNone = { new StubX509Certificate() }; + X509Certificate[] chainTrustedByBoth = { new StubX509Certificate() }; + String authType = "testAuthType"; + + StubX509TrustManager manager1 = new StubX509TrustManager(List.of(chainTrustedBy1, chainTrustedByBoth)); + StubX509TrustManager manager2 = new StubX509TrustManager(List.of(chainTrustedBy2, chainTrustedByBoth)); + + CollectionTrustManager collectionTrustManager = new CollectionTrustManager(Arrays.asList(manager1, manager2)); + + collectionTrustManager.checkServerTrusted(chainTrustedBy1, authType); + collectionTrustManager.checkServerTrusted(chainTrustedBy2, authType); + collectionTrustManager.checkServerTrusted(chainTrustedByBoth, authType); + + CertificateException exception = assertThrows(CertificateException.class, () -> { + collectionTrustManager.checkServerTrusted(chainTrustedByNone, authType); + }); + assertThat(exception, sameInstance(manager1.exception)); // first in the list + assertThat(exception.getSuppressed(), arrayContaining(sameInstance(manager2.exception))); // second, suppressed + } + + private static class StubX509TrustManager implements X509TrustManager { + + public final CertificateException exception = new CertificateException(); + private List trusted; + + public StubX509TrustManager(List trusted) { + this.trusted = trusted; + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + for (X509Certificate[] trustedChain : trusted) { + if (Arrays.equals(chain, trustedChain)) { + return; + } + } + throw exception; + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + for (X509Certificate[] trustedChain : trusted) { + if (Arrays.equals(chain, trustedChain)) { + return; + } + } + throw exception; + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return trusted.stream().flatMap(Arrays::stream).toArray(X509Certificate[]::new); + } + + } + + private static class StubX509Certificate extends X509Certificate { + + @Override + public boolean hasUnsupportedCriticalExtension() { + throw new IllegalStateException(); + } + + @Override + public Set getCriticalExtensionOIDs() { + throw new IllegalStateException(); + } + + @Override + public Set getNonCriticalExtensionOIDs() { + throw new IllegalStateException(); + } + + @Override + public byte[] getExtensionValue(String oid) { + throw new IllegalStateException(); + } + + @Override + public void checkValidity() { + throw new IllegalStateException(); + } + + @Override + public void checkValidity(Date date) { + throw new IllegalStateException(); + } + + @Override + public int getVersion() { + throw new IllegalStateException(); + } + + @Override + public BigInteger getSerialNumber() { + throw new IllegalStateException(); + } + + @SuppressWarnings("deprecation") + @Override + public Principal getIssuerDN() { + throw new IllegalStateException(); + } + + @SuppressWarnings("deprecation") + @Override + public Principal getSubjectDN() { + throw new IllegalStateException(); + } + + @Override + public Date getNotBefore() { + throw new IllegalStateException(); + } + + @Override + public Date getNotAfter() { + throw new IllegalStateException(); + } + + @Override + public byte[] getTBSCertificate() { + throw new IllegalStateException(); + } + + @Override + public byte[] getSignature() { + throw new IllegalStateException(); + } + + @Override + public String getSigAlgName() { + throw new IllegalStateException(); + } + + @Override + public String getSigAlgOID() { + throw new IllegalStateException(); + } + + @Override + public byte[] getSigAlgParams() { + throw new IllegalStateException(); + } + + @Override + public boolean[] getIssuerUniqueID() { + throw new IllegalStateException(); + } + + @Override + public boolean[] getSubjectUniqueID() { + throw new IllegalStateException(); + } + + @Override + public boolean[] getKeyUsage() { + throw new IllegalStateException(); + } + + @Override + public int getBasicConstraints() { + throw new IllegalStateException(); + } + + @Override + public byte[] getEncoded() { + throw new IllegalStateException(); + } + + @Override + public void verify(PublicKey key) { + throw new IllegalStateException(); + } + + @Override + public void verify(PublicKey key, String sigProvider) { + throw new IllegalStateException(); + } + + @Override + public PublicKey getPublicKey() { + throw new IllegalStateException(); + } + + @Override + public String toString() { + return Integer.toHexString(System.identityHashCode(this)); + } + + @Override + public boolean equals(Object other) { + return other == this; + } + + } +} diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java new file mode 100644 index 00000000000..86409911337 --- /dev/null +++ b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/KeyStoreUtilTest.java @@ -0,0 +1,328 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP SE 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: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.tests.internal.runtime; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.matchesRegex; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509KeyManager; +import javax.net.ssl.X509TrustManager; +import javax.security.auth.x500.X500Principal; +import org.eclipse.core.internal.runtime.CollectionTrustManager; +import org.eclipse.core.internal.runtime.KeyStoreUtil; +import org.eclipse.core.runtime.Platform; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.api.io.TempDir; + +@SuppressWarnings("restriction") +public class KeyStoreUtilTest { + + private static final List SYSTEM_PROPERTIES_TO_BACKUP_AND_RESTORE = List.of( // + "eclipse.platform.mergeTrust", // + "javax.net.ssl.trustStore", // + "javax.net.ssl.trustStorePassword", // + "javax.net.ssl.trustStoreProvider", // + "javax.net.ssl.trustStoreType", // + "javax.net.ssl.keyStore", // + "javax.net.ssl.keyStorePassword", // + "javax.net.ssl.keyStoreProvider", // + "javax.net.ssl.keyStoreType"); + + @TempDir + private Path tempDir; + + private Map systemPropertyBackups = new HashMap<>(); + private SSLContext previousSslContext; + + @BeforeEach + public void setup() throws Exception { + for (String property : SYSTEM_PROPERTIES_TO_BACKUP_AND_RESTORE) { + systemPropertyBackups.put(property, System.getProperty(property, null)); + } + previousSslContext = SSLContext.getDefault(); + System.setProperty("eclipse.platform.mergeTrust", "true"); + } + + @AfterEach + public void teardown() { + systemPropertyBackups.forEach((property, backupValue) -> { + if (backupValue == null) { + System.clearProperty(property); + } else { + System.setProperty(property, backupValue); + } + }); + SSLContext.setDefault(previousSslContext); + } + + @Test + public void loadTrustManagers_Default() throws Exception { + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedTrustManagers, arrayWithSize(1)); + assertThat(keyStoreUtil.recordedTrustManagers[0], instanceOf(CollectionTrustManager.class)); + assertThat(((CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]).getAcceptedIssuers(), + not(emptyArray())); + + CollectionTrustManager tm = (CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]; + + // jvm + assertThat(tm.getTrustManagers(), not(empty())); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, not(empty())); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).manager(), is(tm.getTrustManagers().get(0))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).store(), is(nullValue())); + assertThat( + Arrays.stream(tm.getTrustManagers().get(0).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem(matchesRegex("(?i).*digicert.*root.*"))); + + if (OS.WINDOWS.equals(OS.current())) { + assertThat(tm.getTrustManagers(), hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).manager(), + is(tm.getTrustManagers().get(1))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).store().getType(), is("Windows-ROOT")); + assertThat( + Arrays.stream(tm.getTrustManagers().get(1).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem(matchesRegex("(?i).*digicert.*root.*"))); + } else if (OS.MAC.equals(OS.current())) { + assertThat(tm.getTrustManagers(), hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(2)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).manager(), + is(tm.getTrustManagers().get(1))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(1).store().getType(), is("KeychainStore")); + // Apple KeychainStore only includes the 'System' certificates + // (enterprise/admin managed) + // but not the 'System Roots' ones (public CAs). + // There's nothing guaranteed / deterministic in the 'System' on CI machines + // that we could check for here... + } else { + assertThat(tm.getTrustManagers(), hasSize(1)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(1)); + } + + // no private keys + assertThat(keyStoreUtil.recordedKeyManagers, emptyArray()); + } + + @Test + public void loadTrustManagers_TrustSystemPropertiesPointToCustomTrustStore() throws Exception { + + System.setProperty("javax.net.ssl.trustStore", copyResourceToTempDirAndGetPath("truststore.jks")); + System.setProperty("javax.net.ssl.trustStorePassword", "verysecret"); + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedTrustManagers, arrayWithSize(1)); + assertThat(((CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]).getAcceptedIssuers(), + not(emptyArray())); + + CollectionTrustManager tm = (CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]; + + assertThat(tm.getTrustManagers(), hasSize(1)); // only the properties-based store + + assertThat( + Arrays.stream(tm.getTrustManagers().get(0).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem("CN=Test,C=DE")); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(1)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).manager(), is(tm.getTrustManagers().get(0))); + // null caused KeyManagerFactory to load default system properties + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).store(), is(nullValue())); + + assertThat(keyStoreUtil.recordedKeyManagers, emptyArray()); + } + + @Test + @EnabledOnOs({ OS.WINDOWS, OS.MAC }) + public void loadTrustManagers_TrustSystemPropertiesPointToPlatformSpecificKeystore() throws Exception { + if (OS.WINDOWS.equals(OS.current())) { + System.setProperty("javax.net.ssl.trustStore", "NONE"); + System.setProperty("javax.net.ssl.trustStoreType", "Windows-ROOT"); + } else if (OS.MAC.equals(OS.current())) { + System.setProperty("javax.net.ssl.trustStore", "NONE"); + System.setProperty("javax.net.ssl.trustStoreType", "KeychainStore"); + System.setProperty("javax.net.ssl.trustStoreProvider", "Apple"); + } + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedTrustManagers, arrayWithSize(1)); + + CollectionTrustManager tm = (CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]; + + assertThat(tm.getTrustManagers(), hasSize(1)); // only the properties-based store + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores, hasSize(1)); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).manager(), is(tm.getTrustManagers().get(0))); + assertThat(keyStoreUtil.createdTrustManagersAndKeyStores.get(0).store(), is(nullValue())); + + if (OS.WINDOWS.equals(OS.current())) { + assertThat(((CollectionTrustManager) keyStoreUtil.recordedTrustManagers[0]).getAcceptedIssuers(), + not(emptyArray())); + assertThat( + Arrays.stream(tm.getTrustManagers().get(0).getAcceptedIssuers()) + .map(X509Certificate::getSubjectX500Principal).map(X500Principal::getName).toList(), + hasItem(matchesRegex("(?i).*digicert.*root.*"))); + } else if (OS.MAC.equals(OS.current())) { + // Apple KeychainStore only includes the 'System' certificates + // (enterprise/admin managed) + // but not the 'System Roots' ones (public CAs). + // There's nothing guaranteed / deterministic in the 'System' on CI machines + // that we could check for here... + } + } + + @Test + public void loadKeyManagers_Default() throws Exception { + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedKeyManagers, emptyArray()); + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores, hasSize(0)); + } + + @Test + public void loadKeyManagers_KeySystemPropertiesPointToCustomKeyStore() throws Exception { + + System.setProperty("javax.net.ssl.keyStore", copyResourceToTempDirAndGetPath("keystore.p12")); + System.setProperty("javax.net.ssl.keyStorePassword", "verysecret"); + System.setProperty("javax.net.ssl.keyStoreType", "PKCS12"); + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(keyStoreUtil.recordedSslContext)); + + assertThat(keyStoreUtil.recordedKeyManagers, arrayWithSize(1)); + assertThat(keyStoreUtil.recordedKeyManagers[0], instanceOf(X509KeyManager.class)); + + X509KeyManager km = (X509KeyManager) keyStoreUtil.recordedKeyManagers[0]; + + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores, hasSize(1)); + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores.get(0).manager(), is(km)); + assertThat(keyStoreUtil.createdKeyManagersAndKeyStores.get(0).store().getType(), is("PKCS12")); + + assertThat(km.getPrivateKey("test.key"), not(nullValue())); + } + + @Test + public void optInSystemPropertyNotSet() throws Exception { + System.clearProperty("eclipse.platform.mergeTrust"); + + TestSpecificKeyStoreUtil keyStoreUtil = new TestSpecificKeyStoreUtil(); + + keyStoreUtil.setUpSslContext(); + + assertThat(SSLContext.getDefault(), is(previousSslContext)); + } + + private String copyResourceToTempDirAndGetPath(String resourceName) throws IOException { + Path file = tempDir.resolve(resourceName); + Files.copy(getClass().getResourceAsStream(resourceName), file, StandardCopyOption.REPLACE_EXISTING); + return file.toAbsolutePath().toString(); + } + + private static final class TestSpecificKeyStoreUtil extends KeyStoreUtil { + + public TestSpecificKeyStoreUtil() { + super(Platform.getOS()); + } + + public static record X509TrustManagerAndKeyStore(X509TrustManager manager, KeyStore store) { + } + + public static record X509KeyManagerAndKeyStore(X509KeyManager manager, KeyStore store) { + } + + public TrustManager[] recordedTrustManagers; + public KeyManager[] recordedKeyManagers; + public SSLContext recordedSslContext; + public final List createdTrustManagersAndKeyStores = new ArrayList<>(); + public final List createdKeyManagersAndKeyStores = new ArrayList<>(); + + @Override + protected X509TrustManager createX509TrustManager(KeyStore keyStore) throws GeneralSecurityException { + X509TrustManager manager = super.createX509TrustManager(keyStore); + this.createdTrustManagersAndKeyStores.add(new X509TrustManagerAndKeyStore(manager, keyStore)); + return manager; + } + + @Override + protected X509KeyManager createX509KeyManager(KeyStore keyStore, char[] password) + throws GeneralSecurityException { + X509KeyManager manager = super.createX509KeyManager(keyStore, password); + this.createdKeyManagersAndKeyStores.add(new X509KeyManagerAndKeyStore(manager, keyStore)); + return manager; + } + + @Override + protected void initSSLContext(SSLContext context, TrustManager[] trustManagers, KeyManager[] keyManagers, + SecureRandom random) throws KeyManagementException { + this.recordedTrustManagers = trustManagers; + this.recordedKeyManagers = keyManagers; + this.recordedSslContext = context; + super.initSSLContext(context, trustManagers, keyManagers, random); + } + } + +} diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/keystore.p12 b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/keystore.p12 new file mode 100644 index 00000000000..b86cf756e4e Binary files /dev/null and b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/keystore.p12 differ diff --git a/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/truststore.jks b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/truststore.jks new file mode 100644 index 00000000000..792a80521e3 Binary files /dev/null and b/runtime/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/internal/runtime/truststore.jks differ diff --git a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java index 9d70bbe589f..4d749396440 100644 --- a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java +++ b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/EditionSelectionDialog.java @@ -237,6 +237,7 @@ public int hashCode() { * @param parent if not null the new dialog stays on top of this parent shell * @param bundle ResourceBundle to configure the dialog */ + @Deprecated public EditionSelectionDialog(Shell parent, ResourceBundle bundle) { super(parent, bundle); } @@ -268,6 +269,7 @@ public void setStatusMessage(String message) { * @param contextId the help context id. * @since 3.2 */ + @Deprecated @Override public void setHelpContextId(String contextId) { super.setHelpContextId(contextId); @@ -279,6 +281,7 @@ public void setHelpContextId(String contextId) { * @param titleArgument an optional argument for the edition pane's title * @since 2.0 */ + @Deprecated public void setEditionTitleArgument(String titleArgument) { fTitleArg= titleArgument; } @@ -289,6 +292,7 @@ public void setEditionTitleArgument(String titleArgument) { * @param titleImage an optional image for the edition pane's title * @since 2.0 */ + @Deprecated public void setEditionTitleImage(Image titleImage) { fTitleImage= titleImage; } @@ -305,6 +309,7 @@ public void setEditionTitleImage(Image titleImage) { * it is an ITypedElement returned from IStructureCreator.locate(path, item) * @since 2.0 */ + @Deprecated public ITypedElement selectPreviousEdition(final ITypedElement target, ITypedElement[] inputEditions, Object ppath) { Assert.isNotNull(target); fTargetPair= new Pair(null, target); @@ -380,6 +385,7 @@ public ITypedElement selectPreviousEdition(final ITypedElement target, ITypedEle * if path was null; otherwise * it is an ITypedElement returned from IStructureCreator.locate(path, item) */ + @Deprecated public ITypedElement selectEdition(final ITypedElement target, ITypedElement[] inputEditions, Object ppath) { Assert.isNotNull(target); @@ -544,6 +550,7 @@ private Pair createPair(IStructureCreator sc, Object path, ITypedElement input) * @param hide if true identical entries are hidden; otherwise they are shown. * @since 2.0 */ + @Deprecated public void setHideIdenticalEntries(boolean hide) { fHideIdentical= hide; } @@ -554,6 +561,7 @@ public void setHideIdenticalEntries(boolean hide) { * @param isRight if true target is shown on right hand side. * @since 2.0 */ + @Deprecated public void setTargetIsRight(boolean isRight) { fTargetIsRight= isRight; } @@ -565,6 +573,7 @@ public void setTargetIsRight(boolean isRight) { * @param addMode if true dialog is in 'add' mode. * @since 2.0 */ + @Deprecated public void setAddMode(boolean addMode) { fAddMode= addMode; fMultiSelect= addMode; @@ -577,6 +586,7 @@ public void setAddMode(boolean addMode) { * @param compareMode if true dialog is in 'add' mode. * @since 2.0 */ + @Deprecated public void setCompareMode(boolean compareMode) { fCompareMode= compareMode; fStructureCompare= fCompareMode && !fAddMode; @@ -593,6 +603,7 @@ public void setCompareMode(boolean compareMode) { * * @return the last specified target or a subsection thereof. */ + @Deprecated public ITypedElement getTarget() { return fTargetPair.getItem(); } @@ -604,6 +615,7 @@ public ITypedElement getTarget() { * @return the selected editions as an array. * @since 2.1 */ + @Deprecated public ITypedElement[] getSelection() { ArrayList result= new ArrayList<>(); if (fMemberSelection != null) { @@ -635,6 +647,7 @@ public ITypedElement[] getSelection() { * @param item if a path has been specified in selectEdition a sub element of the given target; otherwise the same as target * @return a label the target side of a compare viewer */ + @Deprecated protected String getTargetLabel(ITypedElement target, ITypedElement item) { String format= null; if (target instanceof ResourceNode) { @@ -680,6 +693,7 @@ private boolean hasVariable(String string) { * @param item if a path has been specified in selectEdition a sub element of the given selectedEdition; otherwise the same as selectedEdition * @return a label for the edition side of a compare viewer */ + @Deprecated protected String getEditionLabel(ITypedElement selectedEdition, ITypedElement item) { String format= null; if (selectedEdition instanceof ResourceNode) { @@ -721,6 +735,7 @@ protected String getEditionLabel(ITypedElement selectedEdition, ITypedElement it * @return a label of a node in the edition tree viewer * @since 2.0 */ + @Deprecated protected String getShortEditionLabel(ITypedElement edition, ITypedElement item, Date date) { String format= null; if (edition instanceof ResourceNode) { @@ -752,6 +767,7 @@ protected String getShortEditionLabel(ITypedElement edition, ITypedElement item, * @return a label the edition side of a compare viewer * @since 2.0 */ + @Deprecated protected Image getEditionImage(ITypedElement selectedEdition, ITypedElement item) { if (selectedEdition instanceof ResourceNode) { return selectedEdition.getImage(); @@ -769,6 +785,7 @@ protected Image getEditionImage(ITypedElement selectedEdition, ITypedElement ite return null; } + @Deprecated @Override protected synchronized Control createDialogArea(Composite parent2) { @@ -905,6 +922,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { return parent; } + @Deprecated @Override protected void createButtonsForButtonBar(Composite parent) { String buttonLabel= Utilities.getString(fBundle, "buttonLabel", IDialogConstants.OK_LABEL); //$NON-NLS-1$ @@ -923,6 +941,7 @@ protected void createButtonsForButtonBar(Composite parent) { * Overidden to disable dismiss on double click in compare mode. * @since 2.0 */ + @Deprecated @Override protected void okPressed() { if (fCompareMode) { diff --git a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java index 6c2c622ea0f..70fa80fcad3 100644 --- a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java +++ b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/IStreamMerger.java @@ -35,16 +35,19 @@ public interface IStreamMerger { /** * Indicates the successful completion of the merge operation (value IStatus.OK) */ + @Deprecated public static final int OK= IStatus.OK; /** * Indicates that a change conflict prevented the merge from successful completion (value 1) */ + @Deprecated public static final int CONFLICT= 1; /** * Status code describing an internal error (value 2) */ + @Deprecated public static final int INTERNAL_ERROR= 2; /** @@ -65,6 +68,7 @@ public interface IStreamMerger { * @param monitor reports progress of the merge operation * @return returns the completion status of the operation */ + @Deprecated IStatus merge(OutputStream output, String outputEncoding, InputStream ancestor, String ancestorEncoding, InputStream target, String targetEncoding, diff --git a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java index a523d7d5611..28d442a4943 100644 --- a/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java +++ b/team/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareWithOtherResourceAction.java @@ -26,6 +26,7 @@ @Deprecated public class CompareWithOtherResourceAction extends CompareAction { + @Deprecated @Override public void run(ISelection selection) { // Show CompareWithOtherResourceDialog which return resources to compare @@ -34,6 +35,7 @@ public void run(ISelection selection) { super.run(selection); } + @Deprecated @Override protected boolean isEnabled(ISelection selection) { int selectionSize = 0; diff --git a/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF b/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF index 3c0d9123e70..e3d5ba8e736 100644 --- a/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF +++ b/team/bundles/org.eclipse.team.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.team.core; singleton:=true -Bundle-Version: 3.10.800.qualifier +Bundle-Version: 3.10.900.qualifier Bundle-Activator: org.eclipse.team.internal.core.TeamPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java index 5cb19af60f7..4f0b3aa1fee 100644 --- a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java +++ b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java @@ -28,6 +28,7 @@ public interface IFileTypeInfo { * * @return the file extension */ + @Deprecated public String getExtension(); /** @@ -41,5 +42,6 @@ public interface IFileTypeInfo { * * @return the file type */ + @Deprecated public int getType(); } diff --git a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java index f1c3aeb84cd..55cda2204b0 100644 --- a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java +++ b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java @@ -49,6 +49,7 @@ public interface IProjectSetSerializer { * @return String[] an array of serialized reference strings uniquely identifying the projects * @throws TeamException on failures; depends on concrete implementation */ + @Deprecated public String[] asReference(IProject[] providerProjects, Object context, IProgressMonitor monitor) throws TeamException; /** @@ -69,5 +70,6 @@ public interface IProjectSetSerializer { * @return IProject[] an array of projects that were created * @throws TeamException on failures; depends on concrete implementation */ + @Deprecated public IProject[] addToWorkspace(String[] referenceStrings, String filename, Object context, IProgressMonitor monitor) throws TeamException; } diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java index fde06acc8ce..8586204a6c5 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetLocationPage.java @@ -131,8 +131,8 @@ private void createExportToFile(Composite composite) { } FileDialog d = new FileDialog(getShell(), SWT.SAVE); - d.setFilterExtensions(new String[] {"*.psf"}); //$NON-NLS-1$ - d.setFilterNames(new String[] {TeamUIMessages.ExportProjectSetMainPage_Project_Set_Files_3}); + d.setFilterExtensions("*.psf"); //$NON-NLS-1$ + d.setFilterNames(TeamUIMessages.ExportProjectSetMainPage_Project_Set_Files_3); d.setFileName(TeamUIMessages.ExportProjectSetMainPage_default); String fileName = getFileName(); if (fileName != null) { diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java index 3514a030c22..4b88ad83571 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java @@ -165,8 +165,8 @@ public void widgetSelected(SelectionEvent e) { browseButton.setLayoutData(data); browseButton.addListener(SWT.Selection, event -> { FileDialog d = new FileDialog(getShell()); - d.setFilterExtensions(new String[] {"*.psf", "*"}); //$NON-NLS-1$ //$NON-NLS-2$ - d.setFilterNames(new String[] {TeamUIMessages.ImportProjectSetMainPage_Project_Set_Files_2, TeamUIMessages.ImportProjectSetMainPage_allFiles}); // + d.setFilterExtensions("*.psf", "*"); //$NON-NLS-1$ //$NON-NLS-2$ + d.setFilterNames(TeamUIMessages.ImportProjectSetMainPage_Project_Set_Files_2, TeamUIMessages.ImportProjectSetMainPage_allFiles); // String fileName= getFileName(); if (fileName != null && fileName.length() > 0) { int separator= fileName.lastIndexOf(File.separatorChar); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java index 1beb347a0be..e56a92fe5d9 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/ISaveableWorkbenchPart.java @@ -33,5 +33,6 @@ public interface ISaveableWorkbenchPart extends ISaveablePart, IWorkbenchPart { /** * The property id for isDirty. */ + @Deprecated public static final int PROP_DIRTY = ISaveablePart.PROP_DIRTY; } diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java index 68c8e7b2473..fc53db3bfce 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java @@ -66,6 +66,7 @@ public abstract class PageSaveablePart extends SaveablePartAdapter implements IContentChangeListener{ private final CompareConfiguration cc; + @Deprecated Shell shell; // Tracking of dirty state @@ -87,6 +88,7 @@ public abstract class PageSaveablePart extends SaveablePartAdapter implements IC * @param shell the shell for the part * @param compareConfiguration the compare configuration */ + @Deprecated protected PageSaveablePart(Shell shell, CompareConfiguration compareConfiguration){ this.shell = shell; this.cc = compareConfiguration; @@ -104,11 +106,13 @@ protected PageSaveablePart(Shell shell, CompareConfiguration compareConfiguratio }; } + @Deprecated @Override public boolean isDirty() { return fDirty || fDirtyViewers.size() > 0; } + @Deprecated @Override public void createPartControl(Composite parent) { Composite composite = new Composite(parent, SWT.NULL); @@ -185,6 +189,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { * selection listener on the page. * @return the selection provider for the page */ + @Deprecated protected abstract ISelectionProvider getSelectionProvider(); /** @@ -194,6 +199,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { * @param toolBarManager the toolbar manager for the page * @return the top-level control for the page */ + @Deprecated protected abstract Control createPage(Composite parent, ToolBarManager toolBarManager); /** @@ -201,6 +207,7 @@ protected Viewer getViewer(Viewer oldViewer, Object input) { * will appear in the header of the pane containing the page. * @param title the page's title */ + @Deprecated protected void setPageDescription(String title) { fEditionPane.setText(title); } @@ -209,6 +216,7 @@ protected void setPageDescription(String title) { * Set the saveable part's dirty state to the given state. * @param dirty the dirty state */ + @Deprecated protected void setDirty(boolean dirty) { boolean confirmSave= true; Object o= cc.getProperty(CompareEditor.CONFIRM_SAVE_PROPERTY); @@ -263,6 +271,7 @@ private void feedInput2(ISelection sel) { * with a progress monitor. * @param input the compare input to be prepared */ + @Deprecated protected void prepareCompareInput(final ICompareInput input) { if (input == null) { return; @@ -295,6 +304,7 @@ protected void prepareCompareInput(final ICompareInput input) { * @param monitor a progress monitor * @throws InvocationTargetException if an error occurs */ + @Deprecated protected abstract void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException; private void hookContentChangeListener(ICompareInput node) { @@ -313,6 +323,7 @@ private void hookContentChangeListener(ICompareInput node) { * Return the parent shell of this part. * @return the parent shell of this part */ + @Deprecated protected Shell getShell() { return shell; } @@ -321,6 +332,7 @@ protected Shell getShell() { * This method is internal to the framework and should not be called by clients * outside of the framework. */ + @Deprecated protected void setNavigator(ISynchronizePageConfiguration configuration) { configuration.setProperty(SynchronizePageConfiguration.P_NAVIGATOR, new CompareEditorInputNavigator( new Object[] { @@ -366,6 +378,7 @@ private Viewer findContentViewer(Composite parent, Viewer oldViewer, ICompareInp * @param selection the selection * @return a compare input representing the selection */ + @Deprecated protected ICompareInput getCompareInput(ISelection selection) { if (selection != null && selection instanceof IStructuredSelection ss) { if (ss.size() == 1) { @@ -384,6 +397,7 @@ protected ICompareInput getCompareInput(ISelection selection) { * * @param showContentPanes whether to show contents pane */ + @Deprecated public void setShowContentPanes(boolean showContentPanes) { this.showContentPanes = showContentPanes; } @@ -393,6 +407,7 @@ public void setShowContentPanes(boolean showContentPanes) { * * @return the primary control for this part. */ + @Deprecated public Control getControl() { return control; } @@ -413,6 +428,7 @@ private CompareConfiguration getCompareConfiguration() { * @param monitor * a progress monitor */ + @Deprecated @Override public void doSave(IProgressMonitor monitor) { flushViewers(monitor); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java index 6b81f98df2f..72a89457add 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartAdapter.java @@ -34,46 +34,56 @@ @Deprecated public abstract class SaveablePartAdapter implements ISaveableWorkbenchPart { + @Deprecated @Override public void doSaveAs() { } + @Deprecated @Override public boolean isSaveAsAllowed() { return false; } + @Deprecated @Override public boolean isSaveOnCloseNeeded() { return false; } + @Deprecated @Override public void addPropertyListener(IPropertyListener listener) { } + @Deprecated @Override public void dispose() { } + @Deprecated @Override public IWorkbenchPartSite getSite() { return null; } + @Deprecated @Override public String getTitleToolTip() { return null; } + @Deprecated @Override public void removePropertyListener(IPropertyListener listener) { } + @Deprecated @Override public void setFocus() { } + @Deprecated @Override public T getAdapter(Class adapter) { return null; diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java index 1d1bef60411..7e344ea9430 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java @@ -55,17 +55,20 @@ public class SaveablePartDialog extends TrayDialog { * @param shell the parent shell or null to create a top level shell. * @param input the part to show in the dialog. */ + @Deprecated public SaveablePartDialog(Shell shell, ISaveableWorkbenchPart input) { super(shell); setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); this.input = input; } + @Deprecated @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); } + @Deprecated @Override protected Control createDialogArea(Composite parent2) { Composite parent = (Composite) super.createDialogArea(parent2); @@ -77,6 +80,7 @@ protected Control createDialogArea(Composite parent2) { return parent; } + @Deprecated @Override public boolean close() { saveChanges(); @@ -102,10 +106,12 @@ private void saveChanges() { * @return the input to the dialog * @since 3.2 */ + @Deprecated protected ISaveableWorkbenchPart getInput() { return input; } + @Deprecated @Override protected IDialogSettings getDialogBoundsSettings() { IDialogSettings compareSettings = PlatformUI.getDialogSettingsProvider(FrameworkUtil.getBundle(SaveablePartDialog.class)).getDialogSettings(); @@ -122,10 +128,12 @@ protected IDialogSettings getDialogBoundsSettings() { * Set the help content id of this dialog. * @param contextId the help context id */ + @Deprecated public void setHelpContextId(String contextId) { fContextId= contextId; } + @Deprecated @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); @@ -134,6 +142,7 @@ protected void configureShell(Shell newShell) { } } + @Deprecated @Override protected Point getInitialSize() { Point initialSize = super.getInitialSize(); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java index 46a2a03b7b0..7c8b61ec1fc 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/history/HistoryPageSaveablePart.java @@ -57,6 +57,7 @@ public class HistoryPageSaveablePart extends PageSaveablePart { * @param object the object * @return whether the object had an {@link IHistoryPageSource} available or not */ + @Deprecated public static boolean showHistoryInDialog(Shell shell, Object object) { IHistoryPageSource pageSource = HistoryPageSource.getHistoryPageSource(object); if (pageSource != null && pageSource.canShowHistoryFor(object)) { @@ -88,26 +89,31 @@ private static boolean isFile(Object object) { * @param pageSource the page source * @param object the object whose history is to be displayed */ + @Deprecated public HistoryPageSaveablePart(Shell shell, CompareConfiguration configuration, IHistoryPageSource pageSource, Object object) { super(shell,configuration); this.pageSource = pageSource; this.object = object; } + @Deprecated @Override public String getTitle() { return historyPage.getName(); } + @Deprecated @Override public Image getTitleImage() { return null; } + @Deprecated @Override public void contentChanged(IContentChangeNotifier source) { } + @Deprecated @Override protected Control createPage(Composite parent, ToolBarManager toolBarManager) { site = new DialogHistoryPageSite(getShell()); @@ -124,11 +130,13 @@ protected Control createPage(Composite parent, ToolBarManager toolBarManager) { return ((Page) historyPage).getControl(); } + @Deprecated @Override protected final ISelectionProvider getSelectionProvider() { return site.getSelectionProvider(); } + @Deprecated @Override protected ICompareInput getCompareInput(ISelection selection) { ICompareInput compareInput = super.getCompareInput(selection); @@ -147,6 +155,7 @@ protected ICompareInput getCompareInput(ISelection selection) { return null; } + @Deprecated @Override protected void prepareInput(ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException { IHistoryCompareAdapter compareAdapter = Adapters.adapt(historyPage, IHistoryCompareAdapter.class); @@ -155,6 +164,7 @@ protected void prepareInput(ICompareInput input, CompareConfiguration configurat } } + @Deprecated @Override public void dispose() { super.dispose(); diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java index 306faf80316..0eaa813f723 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageDialog.java @@ -51,11 +51,13 @@ public class ParticipantPageDialog extends SaveablePartDialog { * @param input the compare input to show in the dialog * @param participant the given participant */ + @Deprecated public ParticipantPageDialog(Shell shell, SaveablePartAdapter input, ISynchronizeParticipant participant) { super(shell, input); this.participant = participant; } + @Deprecated @Override protected Control createDialogArea(Composite parent2) { Composite parent = (Composite) super.createDialogArea(parent2); @@ -67,6 +69,7 @@ protected Control createDialogArea(Composite parent2) { return parent; } + @Deprecated @Override protected void buttonPressed(int buttonId) { if(buttonId == IDialogConstants.OK_ID && isRememberParticipant()) { @@ -97,6 +100,7 @@ private void rememberParticipant() { * * @return the participant showing in this dialog. */ + @Deprecated protected ISynchronizeParticipant getParticipant() { return participant; } @@ -109,6 +113,7 @@ protected ISynchronizeParticipant getParticipant() { * view should be presented to the user * @since 3.2 */ + @Deprecated protected boolean isOfferToRememberParticipant() { return true; } diff --git a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java index 9ad0603daff..9e6ef97bf71 100644 --- a/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java +++ b/team/bundles/org.eclipse.team.ui/src/org/eclipse/team/ui/synchronize/ParticipantPageSaveablePart.java @@ -87,12 +87,14 @@ public class ParticipantPageSaveablePart extends PageSaveablePart implements ICo * @param pageConfiguration the configuration that will be provided to the participant prior to creating the page * @param participant the participant whose page will be displayed in this part */ + @Deprecated public ParticipantPageSaveablePart(Shell shell, CompareConfiguration cc, ISynchronizePageConfiguration pageConfiguration, ISynchronizeParticipant participant) { super(shell,cc); this.participant = participant; this.pageConfiguration = pageConfiguration; } + @Deprecated @Override public void dispose() { if(titleImage != null) { @@ -108,6 +110,7 @@ public void dispose() { super.dispose(); } + @Deprecated @Override public Image getTitleImage() { if(titleImage == null) { @@ -116,11 +119,13 @@ public Image getTitleImage() { return titleImage; } + @Deprecated @Override public String getTitle() { return Utils.shortenText(SynchronizeView.MAX_NAME_LENGTH, participant.getName()); } + @Deprecated @Override public boolean isDirty() { if (participant instanceof ModelSynchronizeParticipant msp) { @@ -132,6 +137,7 @@ public boolean isDirty() { return super.isDirty(); } + @Deprecated @Override public void contentChanged(IContentChangeNotifier source) { try { @@ -145,6 +151,7 @@ public void contentChanged(IContentChangeNotifier source) { } } + @Deprecated @Override public void doSave(IProgressMonitor pm) { // TODO needs to work for models @@ -163,6 +170,7 @@ public void doSave(IProgressMonitor pm) { } } + @Deprecated @Override protected Control createPage(Composite parent, ToolBarManager toolBarManager) { listener = event -> { @@ -194,6 +202,7 @@ protected Control createPage(Composite parent, ToolBarManager toolBarManager) { return page.getControl(); } + @Deprecated @Override protected final ISelectionProvider getSelectionProvider() { return ((ISynchronizePage)page).getViewer(); @@ -234,6 +243,7 @@ private void initializeDiffViewer(Viewer viewer) { * {@inheritDoc} * @since 3.2 */ + @Deprecated @Override protected void prepareInput(final ICompareInput input, CompareConfiguration configuration, IProgressMonitor monitor) throws InvocationTargetException { monitor.beginTask(TeamUIMessages.SyncInfoCompareInput_3, 100); @@ -302,6 +312,7 @@ private static void commit(IProgressMonitor pm, DiffNode node) throws CoreExcept * * @return Returns the pageConfiguration. */ + @Deprecated public ISynchronizePageConfiguration getPageConfiguration() { return pageConfiguration; } @@ -311,6 +322,7 @@ public ISynchronizePageConfiguration getPageConfiguration() { * * @return Returns the participant. */ + @Deprecated public ISynchronizeParticipant getParticipant() { return participant; } @@ -319,6 +331,7 @@ public ISynchronizeParticipant getParticipant() { * {@inheritDoc} * @since 3.2 */ + @Deprecated @Override protected ICompareInput getCompareInput(ISelection selection) { ICompareInput compareInput = super.getCompareInput(selection); diff --git a/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF b/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF index 0c84b8bf90f..33ddc5aceee 100644 --- a/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.compare.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.compare.tests;singleton:=true -Bundle-Version: 3.8.800.qualifier +Bundle-Version: 3.8.900.qualifier Require-Bundle: org.eclipse.compare, org.eclipse.jface.text, org.eclipse.jface, @@ -16,9 +16,9 @@ Require-Bundle: org.eclipse.compare, org.eclipse.team.ui Import-Package: org.assertj.core.api, org.assertj.core.api.iterable, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-Activator: org.eclipse.compare.tests.CompareTestPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF b/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF index fa254724b70..323d078a0a8 100644 --- a/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.core.tests.net/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Net Tests Plug-in Bundle-SymbolicName: org.eclipse.core.tests.net -Bundle-Version: 1.6.400.qualifier +Bundle-Version: 1.6.500.qualifier Bundle-Vendor: Eclipse.org Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.core.net;bundle-version="[1.0.0,2.0.0)" Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir diff --git a/team/tests/org.eclipse.core.tests.net/pom.xml b/team/tests/org.eclipse.core.tests.net/pom.xml index f26bcba583a..a1a41798d6d 100644 --- a/team/tests/org.eclipse.core.tests.net/pom.xml +++ b/team/tests/org.eclipse.core.tests.net/pom.xml @@ -17,7 +17,7 @@ 4.38.0-SNAPSHOT org.eclipse.core.tests.net - 1.6.400-SNAPSHOT + 1.6.500-SNAPSHOT eclipse-test-plugin diff --git a/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF b/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF index ac47aefaab6..a191a8cd873 100644 --- a/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF +++ b/team/tests/org.eclipse.team.tests.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.team.tests.core; singleton:=true -Bundle-Version: 3.10.500.qualifier +Bundle-Version: 3.10.600.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.team.tests.core, @@ -27,10 +27,10 @@ Require-Bundle: org.eclipse.ui.ide;resolution:=optional, org.eclipse.core.filesystem, org.eclipse.compare.tests Import-Package: org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.extension, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.extension;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-ActivationPolicy: lazy Eclipse-BundleShape: dir Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/team/tests/org.eclipse.team.tests.core/pom.xml b/team/tests/org.eclipse.team.tests.core/pom.xml index 0ef6677001d..c66911365bc 100644 --- a/team/tests/org.eclipse.team.tests.core/pom.xml +++ b/team/tests/org.eclipse.team.tests.core/pom.xml @@ -17,7 +17,7 @@ 4.38.0-SNAPSHOT org.eclipse.team.tests.core - 3.10.500-SNAPSHOT + 3.10.600-SNAPSHOT eclipse-test-plugin diff --git a/terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt b/terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt new file mode 100644 index 00000000000..45a1d524bad --- /dev/null +++ b/terminal/bundles/org.eclipse.terminal.view.ui/forceQualifierUpdate.txt @@ -0,0 +1,2 @@ +# To force a version qualifier update add the bug here +https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/3412 \ No newline at end of file diff --git a/terminal/features/org.eclipse.terminal.feature/build.properties b/terminal/features/org.eclipse.terminal.feature/build.properties index b3a611b5c93..e2bd14c5f3e 100644 --- a/terminal/features/org.eclipse.terminal.feature/build.properties +++ b/terminal/features/org.eclipse.terminal.feature/build.properties @@ -1,2 +1,3 @@ bin.includes = feature.xml,\ + p2.inf,\ feature.properties diff --git a/terminal/features/org.eclipse.terminal.feature/p2.inf b/terminal/features/org.eclipse.terminal.feature/p2.inf new file mode 100644 index 00000000000..c8ab159caed --- /dev/null +++ b/terminal/features/org.eclipse.terminal.feature/p2.inf @@ -0,0 +1,6 @@ + +# The Eclipse Terminal feature replaces a whole set of features that the TM project +# used to provide. The granularity of the TM project is collapsed into a single +# feature in Eclipse Terminal. For ISVs that require additional granularity they +# are advised to provide their own features that lists their requirements +update.matchExp=providedCapabilities.exists(pc | pc.namespace == 'org.eclipse.equinox.p2.iu' && (pc.name == 'org.eclipse.terminal.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.connector.local.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.connector.ssh.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.connector.telnet.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.control.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.feature.feature.group' || pc.name == 'org.eclipse.tm.terminal.view.feature.feature.group')) diff --git a/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF b/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF index bdd9e0f6344..1b61ffdf8b2 100644 --- a/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF +++ b/terminal/tests/org.eclipse.terminal.test/META-INF/MANIFEST.MF @@ -21,5 +21,6 @@ Export-Package: org.eclipse.terminal.internal.connector;x-internal:=true, org.eclipse.terminal.model, org.eclipse.terminal.test Import-Package: org.junit.jupiter.api;version="[5.9.3,6.0.0)", - org.junit.jupiter.api.function;version="[5.9.3,6.0.0)" + org.junit.jupiter.api.function;version="[5.9.3,6.0.0)", + org.junit.platform.suite.api;version="[1.9.3,2.0.0)" Automatic-Module-Name: org.eclipse.terminal.test diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java index 9b9695cf1a4..cac790ea5fe 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/emulator/AllTestSuite.java @@ -12,27 +12,17 @@ *******************************************************************************/ package org.eclipse.terminal.internal.emulator; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Terminal emulator test cases. * Runs in emulator package to allow access to default visible items. */ -public class AllTestSuite extends TestCase { - public AllTestSuite() { - super(null); - } - - public AllTestSuite(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AllTestSuite.class.getName()); - suite.addTestSuite(VT100EmulatorBackendTest.class); - return suite; - } +@Suite +@SelectClasses({ // + VT100EmulatorBackendTest.class, // +}) +public class AllTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java index f2bf7ad9f51..47660269f0a 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/internal/model/AllTestSuite.java @@ -12,36 +12,26 @@ *******************************************************************************/ package org.eclipse.terminal.internal.model; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Internal Terminal Model test cases. * Runs in internal model package to allow access to default visible items. */ -public class AllTestSuite extends TestCase { - public AllTestSuite() { - super(null); - } - - public AllTestSuite(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AllTestSuite.class.getName()); - suite.addTestSuite(SnapshotChangesTest.class); - suite.addTestSuite(SynchronizedTerminalTextDataTest.class); - suite.addTestSuite(TerminalTextDataFastScrollTest.class); - suite.addTestSuite(TerminalTextDataFastScrollMaxHeightTest.class); - suite.addTestSuite(TerminalTextDataPerformanceTest.class); - suite.addTestSuite(TerminalTextDataSnapshotTest.class); - suite.addTestSuite(TerminalTextDataSnapshotWindowTest.class); - suite.addTestSuite(TerminalTextDataStoreTest.class); - suite.addTestSuite(TerminalTextDataTest.class); - suite.addTestSuite(TerminalTextDataWindowTest.class); - return suite; - } +@Suite +@SelectClasses({ // + SnapshotChangesTest.class, // + SynchronizedTerminalTextDataTest.class, // + TerminalTextDataFastScrollTest.class, // + TerminalTextDataFastScrollMaxHeightTest.class, // + TerminalTextDataPerformanceTest.class, // + TerminalTextDataSnapshotTest.class, // + TerminalTextDataSnapshotWindowTest.class, // + TerminalTextDataStoreTest.class, // + TerminalTextDataTest.class, // + TerminalTextDataWindowTest.class, // +}) +public class AllTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java index fa3b9b0a37c..d1c4b9e68d3 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/model/AllTestSuite.java @@ -12,29 +12,18 @@ *******************************************************************************/ package org.eclipse.terminal.model; -import junit.framework.JUnit4TestAdapter; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Public Terminal Model test cases. * Runs in internal model package to allow access to default visible items. */ -public class AllTestSuite extends TestCase { - public AllTestSuite() { - super(null); - } - - public AllTestSuite(String name) { - super(name); - } - - public static Test suite() { - TestSuite suite = new TestSuite(AllTestSuite.class.getName()); - suite.addTest(new JUnit4TestAdapter(TerminalColorUITest.class)); - suite.addTestSuite(StyleTest.class); - return suite; - } +@Suite +@SelectClasses({ // + TerminalColorUITest.class, // + StyleTest.class, // +}) +public class AllTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java index ec19cdae290..537449895c5 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedPluginTestSuite.java @@ -13,27 +13,17 @@ package org.eclipse.terminal.test; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Master Test Suite to run all Terminal plug-in tests. */ -public class AutomatedPluginTestSuite extends TestCase { - /** - * Call each AllTestSuite class from each of the test packages. - */ - public static Test suite() { - TestSuite suite = new TestSuite(AutomatedPluginTestSuite.class.getName()); - //These tests require Eclipse Platform to be up - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalConnectorPluginTest.class); - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalConnectorFactoryTest.class); - - //These tests must run as plain JUnit because they require access - //to "package" protected methods - //suite.addTest(AutomatedTestSuite.suite()); - return suite; - } +@Suite +@SelectClasses({ // + org.eclipse.terminal.internal.connector.TerminalConnectorPluginTest.class, // + org.eclipse.terminal.internal.connector.TerminalConnectorFactoryTest.class, // +}) +public class AutomatedPluginTestSuite { } diff --git a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java index e5f0ef9a8f7..d07b27e91f6 100644 --- a/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java +++ b/terminal/tests/org.eclipse.terminal.test/src/org/eclipse/terminal/test/AutomatedTestSuite.java @@ -12,35 +12,22 @@ *******************************************************************************/ package org.eclipse.terminal.test; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; /** * Master test suite to run all terminal unit tests. */ -public class AutomatedTestSuite extends TestCase { +@Suite +@SelectClasses({ // + org.eclipse.terminal.internal.emulator.AllTestSuite.class, // + org.eclipse.terminal.internal.model.AllTestSuite.class, // + org.eclipse.terminal.model.AllTestSuite.class, // + org.eclipse.terminal.internal.connector.TerminalConnectorTest.class, // + org.eclipse.terminal.internal.connector.TerminalToRemoteInjectionOutputStreamTest.class, // +}) +public class AutomatedTestSuite { public static final String PI_TERMINAL_TESTS = "org.eclipse.terminal.test"; //$NON-NLS-1$ - public AutomatedTestSuite() { - super(null); - } - - public AutomatedTestSuite(String name) { - super(name); - } - - /** - * Call each AllTestSuite class from each of the test packages. - */ - public static Test suite() { - TestSuite suite = new TestSuite(AutomatedTestSuite.class.getName()); - suite.addTest(org.eclipse.terminal.internal.emulator.AllTestSuite.suite()); - suite.addTest(org.eclipse.terminal.internal.model.AllTestSuite.suite()); - suite.addTest(org.eclipse.terminal.model.AllTestSuite.suite()); - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalConnectorTest.class); - suite.addTestSuite(org.eclipse.terminal.internal.connector.TerminalToRemoteInjectionOutputStreamTest.class); - return suite; - } } diff --git a/ua/org.eclipse.help.base/about.ini b/ua/org.eclipse.help.base/about.ini index 76a035608c3..ff2b3fa15cc 100644 --- a/ua/org.eclipse.help.base/about.ini +++ b/ua/org.eclipse.help.base/about.ini @@ -11,7 +11,7 @@ aboutText=%blurb # needed for primary features only # Property "featureImage" contains path to feature image (32x32) -featureImage=eclipse32.png +featureImage=eclipse32.svg # Property "aboutImage" contains path to product image (500x330 or 115x164) # needed for primary features only diff --git a/ua/org.eclipse.help.base/build.properties b/ua/org.eclipse.help.base/build.properties index b1323e48594..9a997796f13 100644 --- a/ua/org.eclipse.help.base/build.properties +++ b/ua/org.eclipse.help.base/build.properties @@ -24,9 +24,9 @@ bin.includes = doc/,\ about.ini,\ about.mappings,\ about.properties,\ - eclipse32.png,\ META-INF/,\ - ant_tasks/helpbase-ant.jar + ant_tasks/helpbase-ant.jar,\ + eclipse32.svg jars.compile.order = .,\ ant_tasks/helpbase-ant.jar diff --git a/ua/org.eclipse.help.base/eclipse32.png b/ua/org.eclipse.help.base/eclipse32.png deleted file mode 100644 index bf856800755..00000000000 Binary files a/ua/org.eclipse.help.base/eclipse32.png and /dev/null differ diff --git a/ua/org.eclipse.help.base/eclipse32.svg b/ua/org.eclipse.help.base/eclipse32.svg new file mode 100644 index 00000000000..4f0e95ebbf3 --- /dev/null +++ b/ua/org.eclipse.help.base/eclipse32.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF b/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF index 5e5dd4b19da..eff594da88c 100644 --- a/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.tips.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Tip of the Day Tests Bundle-SymbolicName: org.eclipse.tips.tests -Bundle-Version: 1.2.200.qualifier +Bundle-Version: 1.2.300.qualifier Bundle-Vendor: Eclipse Bundle-RequiredExecutionEnvironment: JavaSE-17 Require-Bundle: org.eclipse.tips.ide;bundle-version="0.1.0", @@ -15,6 +15,6 @@ Require-Bundle: org.eclipse.tips.ide;bundle-version="0.1.0", Automatic-Module-Name: org.eclipse.tips.tests Import-Package: com.google.gson;version="[2.8.6,3.0.0)", org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" diff --git a/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java b/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java index ceacbf9483b..d01ed7b58c1 100644 --- a/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java +++ b/ua/org.eclipse.tips.tests/src/org/eclipse/tips/core/TipImageURLTest.java @@ -25,7 +25,7 @@ public class TipImageURLTest { - private static final String URL = "http://remainsoftware.com/img.png"; + private static final String URL = "https://github.com/eclipse-platform/eclipse.platform/blob/master/ua/org.eclipse.tips.tests/icons/dummy.png"; @org.junit.jupiter.api.Test public void testTipImage() { diff --git a/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF b/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF index d9106e7f84e..dc2a34ad8af 100644 --- a/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ua.tests.doc/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.ua.tests.doc;singleton:=true -Bundle-Version: 1.3.100.qualifier +Bundle-Version: 1.3.200.qualifier Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.equinox.http.registry;bundle-version="1.0.200", @@ -16,8 +16,8 @@ Bundle-ActivationPolicy: lazy Import-Package: javax.servlet;version="3.1.0", javax.servlet.http;version="3.1.0", org.assertj.core.api, - org.junit.jupiter.api, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Export-Package: org.eclipse.ua.tests.doc, org.eclipse.ua.tests.doc.internal;x-internal:=true, org.eclipse.ua.tests.doc.internal.actions;x-internal:=true, diff --git a/ua/org.eclipse.ua.tests.doc/pom.xml b/ua/org.eclipse.ua.tests.doc/pom.xml index b2ae6efb1fc..cb182068da0 100644 --- a/ua/org.eclipse.ua.tests.doc/pom.xml +++ b/ua/org.eclipse.ua.tests.doc/pom.xml @@ -19,7 +19,7 @@ org.eclipse.platform org.eclipse.ua.tests.doc - 1.3.100-SNAPSHOT + 1.3.200-SNAPSHOT eclipse-test-plugin diff --git a/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF b/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF index e8cc761f27e..6764b8072ca 100644 --- a/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ua.tests/META-INF/MANIFEST.MF @@ -21,9 +21,9 @@ Import-Package: javax.servlet;version="3.1.0", org.apache.lucene.store;version="[10.0.0,11.0.0)", org.apache.lucene.util;version="[10.0.0,11.0.0)", org.assertj.core.api, - org.junit.jupiter.api, - org.junit.jupiter.api.function, - org.junit.platform.suite.api + org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" Bundle-RequiredExecutionEnvironment: JavaSE-21 Export-Package: org.eclipse.ua.tests, org.eclipse.ua.tests.browser.servlet, diff --git a/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF b/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF index 392efbc99d9..a36e35b45fd 100644 --- a/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF +++ b/ua/org.eclipse.ui.cheatsheets/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %PLUGIN_NAME Bundle-SymbolicName: org.eclipse.ui.cheatsheets; singleton:=true -Bundle-Version: 3.8.700.qualifier +Bundle-Version: 3.8.800.qualifier Bundle-Activator: org.eclipse.ui.internal.cheatsheets.CheatSheetPlugin Bundle-Vendor: %PROVIDER_NAME Bundle-Localization: plugin diff --git a/ua/org.eclipse.ui.cheatsheets/pom.xml b/ua/org.eclipse.ui.cheatsheets/pom.xml index 8608b9cad39..599ff528880 100644 --- a/ua/org.eclipse.ui.cheatsheets/pom.xml +++ b/ua/org.eclipse.ui.cheatsheets/pom.xml @@ -19,6 +19,6 @@ org.eclipse.platform org.eclipse.ui.cheatsheets - 3.8.700-SNAPSHOT + 3.8.800-SNAPSHOT eclipse-plugin diff --git a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java index ad0047882a1..e3218b4e4dc 100644 --- a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java +++ b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CompositeCheatSheetPage.java @@ -67,7 +67,6 @@ * A page which represents a composite cheat sheet */ -@SuppressWarnings("deprecation") // java.util.Observable since 9; public class CompositeCheatSheetPage extends Page implements ISelectionChangedListener, IMenuContributor { public static final String REVIEW_TAG = "__review__"; //$NON-NLS-1$ diff --git a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java index 3248e553511..2c794fdb104 100644 --- a/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java +++ b/ua/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/dialogs/CheatSheetCategoryBasedSelectionDialog.java @@ -363,7 +363,7 @@ private class BrowseListener implements SelectionListener { public void widgetSelected(SelectionEvent e) { // Launch a file dialog to select a cheatsheet file FileDialog fileDlg = new FileDialog(getShell()); - fileDlg.setFilterExtensions(new String[]{"*.xml"}); //$NON-NLS-1$ + fileDlg.setFilterExtensions("*.xml"); //$NON-NLS-1$ fileDlg.setText(Messages.SELECTION_DIALOG_FILEPICKER_TITLE); fileDlg.open(); String filename = fileDlg.getFileName(); diff --git a/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF b/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF index 01bac7f4a0d..3bf53c47b42 100644 --- a/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF +++ b/update/org.eclipse.update.configurator.tests/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.update.configurator.tests Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.update.configurator.tests;singleton:=true -Bundle-Version: 0.2.0.qualifier +Bundle-Version: 0.2.100.qualifier Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.update.configurator @@ -13,5 +13,5 @@ Bundle-Vendor: %providerName Export-Package: org.eclipse.update.configurator.tests, org.eclipse.update.internal.configurator.tests Eclipse-BundleShape: dir -Import-Package: org.junit.jupiter.api, - org.junit.platform.suite.api +Import-Package: org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java index ab903529948..bb23f728d48 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfiguratorUtils.java @@ -44,6 +44,7 @@ public class ConfiguratorUtils { * @return platform configuration used in current instance of platform * @since 3.0 */ + @Deprecated public static IPlatformConfiguration getCurrentPlatformConfiguration() { // acquire factory service first BundleContext context = ConfigurationActivator.getBundleContext(); @@ -69,6 +70,7 @@ public static IPlatformConfiguration getCurrentPlatformConfiguration() { * is specified, an empty configuration object is returned * @return platform configuration used in current instance of platform */ + @Deprecated public static IPlatformConfiguration getPlatformConfiguration(URL url) throws IOException { // acquire factory service first BundleContext context = ConfigurationActivator.getBundleContext(); @@ -95,6 +97,7 @@ public static IPlatformConfiguration getPlatformConfiguration(URL url) throws IO * @param loc location of the platform installation. Used to resolve entries in the save location * @return platform configuration used in current instance of platform */ + @Deprecated public static IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) throws IOException { // acquire factory service first BundleContext context = ConfigurationActivator.getBundleContext(); @@ -115,6 +118,7 @@ public static IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) /** * @return the URL of this eclipse installation */ + @Deprecated public static URL getInstallURL() { return Utils.getInstallURL(); } diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java index 4394c208840..0176d8c6368 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java @@ -44,6 +44,7 @@ public interface IPlatformConfiguration { * * @since 2.0 */ + @Deprecated public interface ISiteEntry { /** @@ -52,6 +53,7 @@ public interface ISiteEntry { * @return site url * @since 2.0 */ + @Deprecated public URL getURL(); /** @@ -60,6 +62,7 @@ public interface ISiteEntry { * @return site policy * @since 2.0 */ + @Deprecated public ISitePolicy getSitePolicy(); /** @@ -68,6 +71,7 @@ public interface ISiteEntry { * @param policy site policy * @since 2.0 */ + @Deprecated public void setSitePolicy(ISitePolicy policy); /** @@ -78,6 +82,7 @@ public interface ISiteEntry { * A feature entry is returned as a path relative to the site URL * @since 2.0 */ + @Deprecated public String[] getFeatures(); /** @@ -90,6 +95,7 @@ public interface ISiteEntry { * A plug-in entry is returned as a path relative to the site URL * * @since 2.0 */ + @Deprecated public String[] getPlugins(); /** @@ -100,6 +106,7 @@ public interface ISiteEntry { * @return site change stamp * @since 2.0 */ + @Deprecated public long getChangeStamp(); /** @@ -132,6 +139,7 @@ public interface ISiteEntry { * @return true if site can be updated, false otherwise * @since 2.0 */ + @Deprecated public boolean isUpdateable(); /** @@ -142,6 +150,7 @@ public interface ISiteEntry { * @return true if the site is linked, false otherwise * @since 2.0 */ + @Deprecated public boolean isNativelyLinked(); } @@ -167,6 +176,7 @@ public interface ISiteEntry { * * @since 2.0 */ + @Deprecated public interface ISitePolicy { /** @@ -178,6 +188,7 @@ public interface ISitePolicy { * policy type is interpreted as path entries to included plugin.xml * or fragment.xml relative to the site URL */ + @Deprecated public static final int USER_INCLUDE = 0; /** @@ -185,6 +196,7 @@ public interface ISitePolicy { * policy type is interpreted as path entries to excluded plugin.xml * or fragment.xml relative to the site URL */ + @Deprecated public static final int USER_EXCLUDE = 1; /** @@ -192,6 +204,7 @@ public interface ISitePolicy { * are contributed to the runtime. * @since 3.1 */ + @Deprecated public static final int MANAGED_ONLY = 2; /** @@ -200,6 +213,7 @@ public interface ISitePolicy { * @return policy type * @since 2.0 */ + @Deprecated public int getType(); /** @@ -208,6 +222,7 @@ public interface ISitePolicy { * @return the list as an array * @since 2.0 */ + @Deprecated public String[] getList(); /** @@ -220,6 +235,7 @@ public interface ISitePolicy { * @see #USER_EXCLUDE * @since 2.0 */ + @Deprecated public void setList(String[] list); } @@ -235,6 +251,7 @@ public interface ISitePolicy { * * @since 2.0 */ + @Deprecated public interface IFeatureEntry { /** @@ -242,6 +259,7 @@ public interface IFeatureEntry { * @return feature identifier * @since 2.0 */ + @Deprecated public String getFeatureIdentifier(); /** @@ -249,6 +267,7 @@ public interface IFeatureEntry { * @return feature version (as string), or null * @since 2.0 */ + @Deprecated public String getFeatureVersion(); /** @@ -263,6 +282,7 @@ public interface IFeatureEntry { * @return feature identifier (as string), or null * @since 2.1 */ + @Deprecated public String getFeaturePluginIdentifier(); /** @@ -277,6 +297,7 @@ public interface IFeatureEntry { * @return feature version (as string), or null * @since 2.0 */ + @Deprecated public String getFeaturePluginVersion(); /** @@ -285,6 +306,7 @@ public interface IFeatureEntry { * @return application identifier, or null * @since 2.0 */ + @Deprecated public String getFeatureApplication(); /** @@ -295,6 +317,7 @@ public interface IFeatureEntry { * @return array of URLs, or an empty array * @since 2.0 */ + @Deprecated public URL[] getFeatureRootURLs(); /** @@ -304,6 +327,7 @@ public interface IFeatureEntry { * false otherwise. * @since 2.0 */ + @Deprecated public boolean canBePrimary(); } @@ -315,6 +339,7 @@ public interface IFeatureEntry { * @return created site entry * @since 2.0 */ + @Deprecated public ISiteEntry createSiteEntry(URL url, ISitePolicy policy); /** @@ -327,6 +352,7 @@ public interface IFeatureEntry { * @return created site policy entry * @since 2.0 */ + @Deprecated public ISitePolicy createSitePolicy(int type, String[] list); /** @@ -348,6 +374,7 @@ public interface IFeatureEntry { * @return create feature entry * @since 2.0 */ + @Deprecated public IFeatureEntry createFeatureEntry(String id, String version, String pluginVersion, boolean primary, String application, URL[] root); /** @@ -371,6 +398,7 @@ public interface IFeatureEntry { * @return create feature entry * @since 2.1 */ + @Deprecated public IFeatureEntry createFeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root); /** @@ -380,6 +408,7 @@ public interface IFeatureEntry { * @param entry site entry * @since 2.0 */ + @Deprecated public void configureSite(ISiteEntry entry); /** @@ -392,6 +421,7 @@ public interface IFeatureEntry { * the same URL should be replaced (true) or not (false). * @since 2.0 */ + @Deprecated public void configureSite(ISiteEntry entry, boolean replace); /** @@ -401,6 +431,7 @@ public interface IFeatureEntry { * @param entry site entry * @since 2.0 */ + @Deprecated public void unconfigureSite(ISiteEntry entry); /** @@ -410,6 +441,7 @@ public interface IFeatureEntry { * configured * @since 2.0 */ + @Deprecated public ISiteEntry[] getConfiguredSites(); /** @@ -419,6 +451,7 @@ public interface IFeatureEntry { * @return matching site entry, or null if no match found * @since 2.0 */ + @Deprecated public ISiteEntry findConfiguredSite(URL url); /** @@ -428,6 +461,7 @@ public interface IFeatureEntry { * @param entry feature entry * @since 2.0 */ + @Deprecated public void configureFeatureEntry(IFeatureEntry entry); /** @@ -435,6 +469,7 @@ public interface IFeatureEntry { * @param entry feature entry * @since 2.0 */ + @Deprecated public void unconfigureFeatureEntry(IFeatureEntry entry); /** @@ -443,6 +478,7 @@ public interface IFeatureEntry { * are configured * @since 2.0 */ + @Deprecated public IFeatureEntry[] getConfiguredFeatureEntries(); /** @@ -451,6 +487,7 @@ public interface IFeatureEntry { * @return ferature entry, or null. * @since 2.0 */ + @Deprecated public IFeatureEntry findConfiguredFeatureEntry(String id); /** @@ -460,6 +497,7 @@ public interface IFeatureEntry { * configuration location could not be determined. * @since 2.0 */ + @Deprecated public URL getConfigurationLocation(); /** @@ -470,6 +508,7 @@ public interface IFeatureEntry { * @return configuration change stamp * @since 2.0 */ + @Deprecated public long getChangeStamp(); /** @@ -504,6 +543,7 @@ public interface IFeatureEntry { * @return primary feature identifier, or null if none configured * @since 2.0 */ + @Deprecated public String getPrimaryFeatureIdentifier(); /** @@ -513,6 +553,7 @@ public interface IFeatureEntry { * @return an array of plug-in path elements (full URL entries), or an empty array. * @since 2.0 */ + @Deprecated public URL[] getPluginPath(); /** @@ -549,6 +590,7 @@ public interface IFeatureEntry { * otherwise * @since 2.0 */ + @Deprecated public boolean isUpdateable(); /** @@ -561,6 +603,7 @@ public interface IFeatureEntry { * otherwise * @since 2.0 */ + @Deprecated public boolean isTransient(); /** @@ -574,6 +617,7 @@ public interface IFeatureEntry { * otherwise * @since 2.0 */ + @Deprecated public void isTransient(boolean value); /** @@ -582,12 +626,14 @@ public interface IFeatureEntry { * configuration state, and updates the lists of available plug-ins. * @since 2.0 */ + @Deprecated public void refresh(); /** * Called to save the configuration information * @since 2.0 */ + @Deprecated public void save() throws IOException; /** @@ -597,6 +643,7 @@ public interface IFeatureEntry { * @param url save location. * @since 2.0 */ + @Deprecated public void save(URL url) throws IOException; } diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java index 179470f659a..39ab8372fa0 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java @@ -34,6 +34,7 @@ public interface IPlatformConfigurationFactory { * * @return platform configuration used in current instance of platform */ + @Deprecated public IPlatformConfiguration getCurrentPlatformConfiguration(); /** * Returns a platform configuration object, optionally initialized with previously saved @@ -43,6 +44,7 @@ public interface IPlatformConfigurationFactory { * is specified, an empty configuration object is returned * @return platform configuration used in current instance of platform */ + @Deprecated public IPlatformConfiguration getPlatformConfiguration(URL url) throws IOException; /** @@ -55,5 +57,6 @@ public interface IPlatformConfigurationFactory { * location * @return platform configuration used in current instance of platform */ + @Deprecated public IPlatformConfiguration getPlatformConfiguration(URL url, URL loc) throws IOException; }