From 35d8960b85caf925f0b7175801e8e925b5561d1f Mon Sep 17 00:00:00 2001 From: Alexander Fedorov Date: Sat, 1 Feb 2025 08:54:45 +0300 Subject: [PATCH] [eclipse-platform#1668] simplify work with launch attributes * identify launch attribute * connect it with preference metadata (to supply defaults/label/description) * read attribute from configuration * write attribute to configuration working copy * demonstrate usage for ExternalTools --- .../ui/launchConfigurations/AntMainTab.java | 72 +++++++----------- .../META-INF/MANIFEST.MF | 2 +- .../internal/IExternalToolConstants.java | 16 +++- .../ExternalToolsProgramMessages.java | 12 ++- .../ExternalToolsProgramMessages.properties | 8 +- .../LaunchAttributeArguments.java | 36 +++++++++ .../LaunchAttributeLocation.java | 36 +++++++++ .../LaunchAttributeWorkingDirectory.java | 36 +++++++++ .../META-INF/MANIFEST.MF | 2 +- .../core/LauchAttributeIdentityRecord.java | 34 +++++++++ .../debug/core/LaunchAttributeDefined.java | 49 ++++++++++++ .../debug/core/LaunchAttributeIdentity.java | 31 ++++++++ .../debug/core/LaunchAttributeProbe.java | 56 ++++++++++++++ .../debug/core/LaunchAttributeRead.java | 71 +++++++++++++++++ .../debug/core/LaunchAttributeWrite.java | 69 +++++++++++++++++ ...ernalToolsLaunchConfigurationMessages.java | 5 +- ...oolsLaunchConfigurationMessages.properties | 5 +- .../ExternalToolsMainTab.java | 76 ++++++++----------- 18 files changed, 514 insertions(+), 102 deletions(-) create mode 100644 debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeArguments.java create mode 100644 debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeLocation.java create mode 100644 debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeWorkingDirectory.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LauchAttributeIdentityRecord.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeDefined.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeIdentity.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeProbe.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeRead.java create mode 100644 debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeWrite.java diff --git a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntMainTab.java b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntMainTab.java index 95bac0f450a..13b80a7deff 100644 --- a/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntMainTab.java +++ b/ant/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntMainTab.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 @@ -10,24 +10,26 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 *******************************************************************************/ package org.eclipse.ant.internal.ui.launchConfigurations; +import java.util.Optional; + import org.eclipse.ant.internal.core.IAntCoreConstants; import org.eclipse.ant.internal.ui.AntUIPlugin; import org.eclipse.ant.internal.ui.AntUtil; import org.eclipse.ant.internal.ui.IAntUIConstants; import org.eclipse.ant.internal.ui.IAntUIHelpContextIds; import org.eclipse.ant.launching.IAntLaunchConstants; -import org.eclipse.core.externaltools.internal.IExternalToolConstants; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.LaunchAttributeProbe; import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jface.dialogs.Dialog; @@ -45,44 +47,27 @@ public class AntMainTab extends ExternalToolsMainTab { - private String fCurrentLocation = null; + private Optional fCurrentLocation; private Button fSetInputHandlerButton; private IFile fNewFile; @Override public void initializeFrom(ILaunchConfiguration configuration) { super.initializeFrom(configuration); - try { - fCurrentLocation = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); - } - catch (CoreException e) { - // do nothing - } + fCurrentLocation = new LaunchAttributeProbe<>(configuration, locationAttribute).get(); updateCheckButtons(configuration); } @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { super.performApply(configuration); - try { - // has the location changed - String newLocation = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); - if (newLocation != null) { - if (!newLocation.equals(fCurrentLocation)) { - updateTargetsTab(); - fCurrentLocation = newLocation; - updateProjectName(configuration); - } - } else if (fCurrentLocation != null) { - updateTargetsTab(); - fCurrentLocation = newLocation; - updateProjectName(configuration); - } - } - catch (CoreException e) { - // do nothing + // has the location changed + Optional newLocation = new LaunchAttributeProbe<>(configuration, locationAttribute).get(); + if (!newLocation.equals(fCurrentLocation)) { + updateTargetsTab(); + fCurrentLocation = newLocation; + updateProjectName(configuration); } - setMappedResources(configuration); setAttribute(IAntUIConstants.SET_INPUTHANDLER, configuration, fSetInputHandlerButton.getSelection(), true); } @@ -110,26 +95,21 @@ private void updateProjectName(ILaunchConfigurationWorkingCopy configuration) { } private IFile getIFile(ILaunchConfigurationWorkingCopy configuration) { - IFile file = null; if (fNewFile != null) { - file = fNewFile; + IFile file = fNewFile; fNewFile = null; - } else { - IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); - try { - String location = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null); - if (location != null) { - String expandedLocation = manager.performStringSubstitution(location); - if (expandedLocation != null) { - file = AntUtil.getFileForLocation(expandedLocation, null); - } - } - } - catch (CoreException e) { - // do nothing - } + return file; + } + return new LaunchAttributeProbe<>(configuration, locationAttribute).get().flatMap(this::resolve).map(exp -> AntUtil.getFileForLocation(exp, null)).orElse(null); + } + + private Optional resolve(String location) { + try { + return Optional.of(VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(location)); + } + catch (CoreException e) { + return Optional.empty(); } - return file; } @Override @@ -153,7 +133,7 @@ public void createControl(Composite parent) { /** * Creates the controls needed to edit the set input handler attribute of an Ant build - * + * * @param parent * the composite to create the controls in */ diff --git a/debug/org.eclipse.core.externaltools/META-INF/MANIFEST.MF b/debug/org.eclipse.core.externaltools/META-INF/MANIFEST.MF index 169587e22ed..2be9d48ae29 100644 --- a/debug/org.eclipse.core.externaltools/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.core.externaltools/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.core.externaltools;singleton:=true -Bundle-Version: 1.3.400.qualifier +Bundle-Version: 1.3.500.qualifier Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.debug.core;bundle-version="[3.9.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.2.800,4.0.0)" diff --git a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/IExternalToolConstants.java b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/IExternalToolConstants.java index 86cad5dce44..ca7c5902ba8 100644 --- a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/IExternalToolConstants.java +++ b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/IExternalToolConstants.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 @@ -11,9 +11,14 @@ * Contributors: * IBM Corporation - initial API and implementation * dakshinamurthy.karra@gmail.com - bug 165371 + * Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 *******************************************************************************/ package org.eclipse.core.externaltools.internal; + +import org.eclipse.debug.core.LauchAttributeIdentityRecord; +import org.eclipse.debug.core.LaunchAttributeIdentity; + /** * Defines the constants available for client use. *

@@ -221,4 +226,13 @@ public interface IExternalToolConstants { * true. */ String ATTR_INCLUDE_REFERENCED_PROJECTS = UI_PLUGIN_ID + ".ATTR_INCLUDE_REFERENCED_PROJECTS"; //$NON-NLS-1$ + + interface LaunchAttributes { + + LaunchAttributeIdentity location = new LauchAttributeIdentityRecord(ATTR_LOCATION); + LaunchAttributeIdentity workingDirectory = new LauchAttributeIdentityRecord(ATTR_WORKING_DIRECTORY); + LaunchAttributeIdentity arguments = new LauchAttributeIdentityRecord(ATTR_TOOL_ARGUMENTS); + + } + } diff --git a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.java b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.java index b733eb9ed02..2eb524a11ca 100644 --- a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.java +++ b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 *******************************************************************************/ package org.eclipse.core.externaltools.internal.launchConfigurations; @@ -29,6 +30,15 @@ public class ExternalToolsProgramMessages extends NLS { public static String ExternalToolsUtil_invalidLocation__0_; public static String ExternalToolsUtil_invalidDirectory__0_; + + public static String LaunchAttributeArguments_name; + + + public static String LaunchAttributeLocation_name; + + + public static String LaunchAttributeWorkingDirectory_name; + static { // load message values from bundle file NLS.initializeMessages(BUNDLE_NAME, ExternalToolsProgramMessages.class); diff --git a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.properties b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.properties index 7d91899381d..545627fe950 100644 --- a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.properties +++ b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ExternalToolsProgramMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2009 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 @@ -10,6 +10,7 @@ # # Contributors: # IBM Corporation - initial API and implementation +# Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 ############################################################################### BackgroundResourceRefresher_0=Refreshing resources... @@ -20,4 +21,7 @@ ProgramLaunchDelegate_5=[pid: {0}] ExternalToolsUtil_Location_not_specified_by__0__1=Location not specified by {0} ExternalToolsUtil_invalidLocation__0_ = The file does not exist for the external tool named {0}. -ExternalToolsUtil_invalidDirectory__0_ = The working directory {0} does not exist for the external tool named {1}. \ No newline at end of file +ExternalToolsUtil_invalidDirectory__0_ = The working directory {0} does not exist for the external tool named {1}. +LaunchAttributeArguments_name=Arguments +LaunchAttributeLocation_name=Location +LaunchAttributeWorkingDirectory_name=Working Directory diff --git a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeArguments.java b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeArguments.java new file mode 100644 index 00000000000..a1e2fd56aca --- /dev/null +++ b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeArguments.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.externaltools.internal.launchConfigurations; + +import org.eclipse.core.externaltools.internal.IExternalToolConstants; +import org.eclipse.core.runtime.preferences.PreferenceMetadata; +import org.eclipse.debug.core.LaunchAttributeDefined; +import org.eclipse.debug.core.LaunchAttributeIdentity; + +public final class LaunchAttributeArguments implements LaunchAttributeDefined { + + @Override + public LaunchAttributeIdentity identity() { + return IExternalToolConstants.LaunchAttributes.arguments; + } + + @Override + public PreferenceMetadata metadata() { + return new PreferenceMetadata<>(String.class, // + identity().id(), + null, // unspecified by default + ExternalToolsProgramMessages.LaunchAttributeArguments_name); + } + +} diff --git a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeLocation.java b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeLocation.java new file mode 100644 index 00000000000..e7532e47b5a --- /dev/null +++ b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeLocation.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.externaltools.internal.launchConfigurations; + +import org.eclipse.core.externaltools.internal.IExternalToolConstants; +import org.eclipse.core.runtime.preferences.PreferenceMetadata; +import org.eclipse.debug.core.LaunchAttributeDefined; +import org.eclipse.debug.core.LaunchAttributeIdentity; + +public final class LaunchAttributeLocation implements LaunchAttributeDefined { + + @Override + public LaunchAttributeIdentity identity() { + return IExternalToolConstants.LaunchAttributes.location; + } + + @Override + public PreferenceMetadata metadata() { + return new PreferenceMetadata<>(String.class, // + identity().id(), + null, // unspecified by default + ExternalToolsProgramMessages.LaunchAttributeLocation_name); + } + +} diff --git a/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeWorkingDirectory.java b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeWorkingDirectory.java new file mode 100644 index 00000000000..6071e508e89 --- /dev/null +++ b/debug/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/LaunchAttributeWorkingDirectory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.externaltools.internal.launchConfigurations; + +import org.eclipse.core.externaltools.internal.IExternalToolConstants; +import org.eclipse.core.runtime.preferences.PreferenceMetadata; +import org.eclipse.debug.core.LaunchAttributeDefined; +import org.eclipse.debug.core.LaunchAttributeIdentity; + +public final class LaunchAttributeWorkingDirectory implements LaunchAttributeDefined { + + @Override + public LaunchAttributeIdentity identity() { + return IExternalToolConstants.LaunchAttributes.workingDirectory; + } + + @Override + public PreferenceMetadata metadata() { + return new PreferenceMetadata<>(String.class, // + identity().id(), + null, // unspecified by default + ExternalToolsProgramMessages.LaunchAttributeWorkingDirectory_name); + } + +} diff --git a/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF index cdd768c6fb7..ccc9689c272 100644 --- a/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.debug.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.debug.core; singleton:=true -Bundle-Version: 3.22.100.qualifier +Bundle-Version: 3.23.0.qualifier Bundle-Activator: org.eclipse.debug.core.DebugPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LauchAttributeIdentityRecord.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LauchAttributeIdentityRecord.java new file mode 100644 index 00000000000..a1a08e342fa --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LauchAttributeIdentityRecord.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2024, 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.core; + +/** + * Default implementation for {@link LaunchAttributeIdentity} + * + * @since 3.23 + */ +public record LauchAttributeIdentityRecord(String id) implements LaunchAttributeIdentity { + + /** + * Convenience way to compose full qualified name for launch attribute + * + * @param qualifier usually corresponds to Bundle-Symbolic-Name + * @param key short key to name this very attribute in the scope of + * qualifier + */ + public LauchAttributeIdentityRecord(String qualifier, String key) { + this(qualifier + "." + key); //$NON-NLS-1$ + } + +} diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeDefined.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeDefined.java new file mode 100644 index 00000000000..6804b89e85e --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeDefined.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2024, 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.core; + +import org.eclipse.core.runtime.preferences.PreferenceMetadata; + +/** + * + * The definition of {@link ILaunchConfiguration} attribute convenience to: + *

    + *
  • {@link ILaunchConfiguration#getAttribute(String, String)} and similar + * operations
  • + *
  • {@link ILaunchConfigurationWorkingCopy#setAttribute(String, String)} and + * similar operations
  • + *
  • Connecting {@link ILaunchConfiguration} attributes with preferences
  • + *
  • Representing {@link ILaunchConfiguration} attributes in UI
  • + *
+ * + * @see LaunchAttributeRead + * @see LaunchAttributeWrite + * + * @since 3.23 + */ +public interface LaunchAttributeDefined { + + /** + * + * @return identity for defined attribute + */ + LaunchAttributeIdentity identity(); + + /** + * + * @return preference metadata for defined attribute + */ + PreferenceMetadata metadata(); + +} diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeIdentity.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeIdentity.java new file mode 100644 index 00000000000..a24b64108c9 --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeIdentity.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2024, 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.core; + +/** + * Identifies an attribute in {@link ILaunchConfiguration} + * + * @since 3.23 + */ +public interface LaunchAttributeIdentity { + + /** + * String id of {@link ILaunchConfiguration} attribute for "low-level" + * operations + * + * @return id of attribute + */ + String id(); + +} diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeProbe.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeProbe.java new file mode 100644 index 00000000000..b507b3cdf86 --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeProbe.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2024, 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.core; + +import java.util.Optional; +import java.util.function.Supplier; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; + +/** + * + * "Probes" the value of launch configuration {@link String} attribute.
+ * Returns {@link Optional} in case of read failure of null value + * to let caller decide how to proceed + * + * @since 3.23 + */ +public final class LaunchAttributeProbe implements Supplier> { + + private final LaunchAttributeRead read; + + public LaunchAttributeProbe(ILaunchConfiguration config, String identifier, Class type, Supplier value) { + read = new LaunchAttributeRead<>(config, identifier, type, value); + } + + public LaunchAttributeProbe(ILaunchConfiguration config, LaunchAttributeDefined attribute) { + read = new LaunchAttributeRead<>(config, attribute); + } + + /** + * @return {@link Optional#empty()} in case of read failure or + * null result + */ + @Override + public Optional get() { + try { + return Optional.ofNullable(read.get()); + } catch (CoreException e) { + Platform.getLog(getClass()).log(e.getStatus()); + return Optional.empty(); + } + } + +} diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeRead.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeRead.java new file mode 100644 index 00000000000..8201c9f82ba --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeRead.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2024, 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.core; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Supplier; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Status; + +/** + * + * Reads the value of launch attribute + * + * @since 3.23 + */ +public final class LaunchAttributeRead { + + private final ILaunchConfiguration configuration; + private final String id; + private final Class type; + private final Supplier value; + + public LaunchAttributeRead(ILaunchConfiguration configuration, LaunchAttributeDefined defined) { + this(configuration, defined.identity().id(), defined.metadata().valueClass(), defined.metadata()::defaultValue); + } + + public LaunchAttributeRead(ILaunchConfiguration configuration, String id, Class type, Supplier value) { + this.configuration = Objects.requireNonNull(configuration); + this.id = Objects.requireNonNull(id); + this.type = Objects.requireNonNull(type); + this.value = Objects.requireNonNull(value); + } + + public V get() throws CoreException { + if (String.class.equals(type)) { + return type.cast(configuration.getAttribute(id, String.class.cast(value.get()))); + } + if (Boolean.class.equals(type)) { + return type.cast(configuration.getAttribute(id, Boolean.class.cast(value.get()))); + } + if (Integer.class.equals(type)) { + return type.cast(configuration.getAttribute(id, Integer.class.cast(value.get()))); + } + if (List.class.equals(type)) { + return type.cast(configuration.getAttribute(id, List.class.cast(value.get()))); + } + if (Map.class.equals(type)) { + return type.cast(configuration.getAttribute(id, Map.class.cast(value.get()))); + } + if (Set.class.equals(type)) { + return type.cast(configuration.getAttribute(id, Set.class.cast(value.get()))); + } + throw new CoreException(Status.error(id, new ClassCastException())); + } + +} diff --git a/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeWrite.java b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeWrite.java new file mode 100644 index 00000000000..82ecd46caa8 --- /dev/null +++ b/debug/org.eclipse.debug.core/core/org/eclipse/debug/core/LaunchAttributeWrite.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2024, 2025 ArSysOp. + * + * 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: + * Alexander Fedorov (ArSysOp) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.debug.core; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * + * Writes the value of launch attribute. Useful in conjunction with UI. + * + * @since 3.23 + */ +public final class LaunchAttributeWrite implements Consumer { + + private final String id; + private final Class type; + private final Supplier value; + + public LaunchAttributeWrite(LaunchAttributeDefined defined) { + this(defined.identity().id(), defined.metadata().valueClass(), defined.metadata()::defaultValue); + } + + public LaunchAttributeWrite(LaunchAttributeDefined defined, Supplier value) { + this(defined.identity().id(), defined.metadata().valueClass(), value); + } + + public LaunchAttributeWrite(String id, Class type, Supplier value) { + this.id = Objects.requireNonNull(id); + this.type = Objects.requireNonNull(type); + this.value = Objects.requireNonNull(value); + } + + @Override + public void accept(ILaunchConfigurationWorkingCopy working) { + if (String.class.equals(type)) { + working.setAttribute(id, String.class.cast(value.get())); + } else if (Integer.class.equals(type)) { + working.setAttribute(id, Integer.class.cast(value.get()).intValue()); + } else if (Boolean.class.equals(type)) { + working.setAttribute(id, Boolean.class.cast(value.get()).booleanValue()); + } else if (List.class.equals(type)) { + working.setAttribute(id, List.class.cast(value.get())); + } else if (Map.class.equals(type)) { + working.setAttribute(id, Map.class.cast(value.get())); + } else if (Set.class.equals(type)) { + working.setAttribute(id, Set.class.cast(value.get())); + } else { + working.setAttribute(id, value.get()); + } + } + +} diff --git a/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.java b/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.java index e1237be4220..4a7b2c001e0 100644 --- a/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.java +++ b/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 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 @@ -11,6 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation * dakshinamurthy.karra@gmail.com - bug 165371 + * Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 *******************************************************************************/ package org.eclipse.ui.externaltools.internal.launchConfigurations; @@ -25,7 +26,6 @@ public class ExternalToolsLaunchConfigurationMessages extends NLS { public static String ExternalToolsMainTab_Working__Directory__5; public static String ExternalToolsMainTab_Browse_Wor_kspace____6; public static String ExternalToolsMainTab_Browse_F_ile_System____7; - public static String ExternalToolsMainTab_Error_reading_configuration_10; public static String ExternalToolsMainTab__Main_17; public static String ExternalToolsMainTab_External_tool_location_cannot_be_empty_18; public static String ExternalToolsMainTab_External_tool_location_does_not_exist_19; @@ -36,7 +36,6 @@ public class ExternalToolsLaunchConfigurationMessages extends NLS { public static String ExternalToolsMainTab__Arguments___1; public static String ExternalToolsMainTab_Varia_bles____2; public static String ExternalToolsMainTab_3; - public static String ExternalToolsMainTab_Error_reading_configuration_7; public static String ExternalToolsMainTab_Not_a_directory; public static String ExternalToolsMainTab_30; public static String ExternalToolsMainTab_31; diff --git a/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.properties b/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.properties index be127c1207f..7b2aea9425e 100644 --- a/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.properties +++ b/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsLaunchConfigurationMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2010 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 @@ -11,6 +11,7 @@ # Contributors: # IBM Corporation - initial API and implementation # dakshinamurthy.karra@gmail.com - bug 165371 +# Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 ############################################################################### ExternalToolsMainTab__Location___2=&Location: @@ -19,7 +20,6 @@ ExternalToolsMainTab_Brows_e_File_System____4=Brows&e File System... ExternalToolsMainTab_Working__Directory__5=Working &Directory: ExternalToolsMainTab_Browse_Wor_kspace____6=Browse Wor&kspace... ExternalToolsMainTab_Browse_F_ile_System____7=Browse File Syste&m... -ExternalToolsMainTab_Error_reading_configuration_10=Error reading configuration ExternalToolsMainTab__Main_17=Main ExternalToolsMainTab_External_tool_location_cannot_be_empty_18=External tool location cannot be empty ExternalToolsMainTab_External_tool_location_does_not_exist_19=External tool location does not exist @@ -30,7 +30,6 @@ ExternalToolsMainTab_23=Select a working directory: ExternalToolsMainTab__Arguments___1=&Arguments: ExternalToolsMainTab_Varia_bles____2=Variable&s... ExternalToolsMainTab_3=Note: Enclose an argument containing spaces using double-quotes (\"). -ExternalToolsMainTab_Error_reading_configuration_7=Error reading configuration ExternalToolsMainTab_Not_a_directory=The specified location is not a directory ExternalToolsMainTab_30=Please specify the location of the external tool you would like to configure. ExternalToolsMainTab_31=Var&iables... diff --git a/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsMainTab.java b/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsMainTab.java index b6cadb9a189..52079c41e8d 100644 --- a/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsMainTab.java +++ b/debug/org.eclipse.ui.externaltools/External Tools Base/org/eclipse/ui/externaltools/internal/launchConfigurations/ExternalToolsMainTab.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 @@ -10,13 +10,19 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Alexander Fedorov (ArSysOp) - https://github.com/eclipse-platform/eclipse.platform/issues/1668 *******************************************************************************/ package org.eclipse.ui.externaltools.internal.launchConfigurations; import java.io.File; +import java.util.Optional; +import java.util.function.Predicate; import org.eclipse.core.externaltools.internal.IExternalToolConstants; +import org.eclipse.core.externaltools.internal.launchConfigurations.LaunchAttributeArguments; +import org.eclipse.core.externaltools.internal.launchConfigurations.LaunchAttributeLocation; +import org.eclipse.core.externaltools.internal.launchConfigurations.LaunchAttributeWorkingDirectory; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -25,6 +31,9 @@ import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.LaunchAttributeDefined; +import org.eclipse.debug.core.LaunchAttributeProbe; +import org.eclipse.debug.core.LaunchAttributeWrite; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.debug.ui.StringVariableSelectionDialog; import org.eclipse.jface.dialogs.Dialog; @@ -50,7 +59,6 @@ import org.eclipse.ui.dialogs.ContainerSelectionDialog; import org.eclipse.ui.dialogs.ResourceSelectionDialog; import org.eclipse.ui.externaltools.internal.model.ExternalToolsImages; -import org.eclipse.ui.externaltools.internal.model.ExternalToolsPlugin; /** * The external tools main tab allows the user to configure primary attributes @@ -60,6 +68,10 @@ public abstract class ExternalToolsMainTab extends AbstractLaunchConfigurationTab { public final static String FIRST_EDIT = "editedByExternalToolsMainTab"; //$NON-NLS-1$ + protected final LaunchAttributeDefined workingDirectoryAttribute = new LaunchAttributeWorkingDirectory(); + protected final LaunchAttributeDefined locationAttribute = new LaunchAttributeLocation(); + protected final LaunchAttributeDefined argumentsAttribute = new LaunchAttributeArguments(); + protected Text locationField; protected Text workDirectoryField; protected Button fileLocationButton; @@ -312,13 +324,7 @@ public void initializeFrom(ILaunchConfiguration configuration) { * configuration. */ protected void updateWorkingDirectory(ILaunchConfiguration configuration) { - String workingDir= IExternalToolConstants.EMPTY_STRING; - try { - workingDir= configuration.getAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY, IExternalToolConstants.EMPTY_STRING); - } catch (CoreException ce) { - ExternalToolsPlugin.getDefault().log(ExternalToolsLaunchConfigurationMessages.ExternalToolsMainTab_Error_reading_configuration_10, ce); - } - workDirectoryField.setText(workingDir); + updateTextField(workDirectoryField, workingDirectoryAttribute, configuration); } /** @@ -326,13 +332,7 @@ protected void updateWorkingDirectory(ILaunchConfiguration configuration) { * configuration. */ protected void updateLocation(ILaunchConfiguration configuration) { - String location= IExternalToolConstants.EMPTY_STRING; - try { - location= configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, IExternalToolConstants.EMPTY_STRING); - } catch (CoreException ce) { - ExternalToolsPlugin.getDefault().log(ExternalToolsLaunchConfigurationMessages.ExternalToolsMainTab_Error_reading_configuration_10, ce); - } - locationField.setText(location); + updateTextField(locationField, locationAttribute, configuration); } /** @@ -340,43 +340,31 @@ protected void updateLocation(ILaunchConfiguration configuration) { * configuration. */ protected void updateArgument(ILaunchConfiguration configuration) { - String arguments= IExternalToolConstants.EMPTY_STRING; - try { - arguments= configuration.getAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, IExternalToolConstants.EMPTY_STRING); - } catch (CoreException ce) { - ExternalToolsPlugin.getDefault().log(ExternalToolsLaunchConfigurationMessages.ExternalToolsMainTab_Error_reading_configuration_7, ce); - } - argumentField.setText(arguments); + updateTextField(argumentField, argumentsAttribute, configuration); + } + + private void updateTextField(Text text, LaunchAttributeDefined defined, ILaunchConfiguration configuration) { + text.setText(new LaunchAttributeProbe<>(configuration, defined).get().orElse(IExternalToolConstants.EMPTY_STRING)); } @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { - String location= locationField.getText().trim(); - if (location.length() == 0) { - configuration.setAttribute(IExternalToolConstants.ATTR_LOCATION, (String)null); - } else { - configuration.setAttribute(IExternalToolConstants.ATTR_LOCATION, location); - } - - String workingDirectory= workDirectoryField.getText().trim(); - if (workingDirectory.length() == 0) { - configuration.setAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY, (String)null); - } else { - configuration.setAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY, workingDirectory); - } - - String arguments= argumentField.getText().trim(); - if (arguments.length() == 0) { - configuration.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, (String)null); - } else { - configuration.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, arguments); - } - + applyText(locationField, locationAttribute); + applyText(workDirectoryField, workingDirectoryAttribute); + applyText(argumentField, argumentsAttribute); if(userEdited) { configuration.setAttribute(FIRST_EDIT, (String)null); } } + private void applyText(Text text, LaunchAttributeDefined defined) { + new LaunchAttributeWrite<>(defined, () -> nullIfEmpty(text)); + } + + private String nullIfEmpty(Text text) { + return Optional.of(text.getText().trim()).filter(Predicate.not(String::isEmpty)).orElse(null); + } + @Override public String getName() { return ExternalToolsLaunchConfigurationMessages.ExternalToolsMainTab__Main_17;