| /*=============================================================================# |
| # Copyright (c) 2015, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.docmlet.base.ui.processing.operations; |
| |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.Nullable_String_TYPE; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.observable.Realm; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.databinding.observable.value.WritableValue; |
| import org.eclipse.core.databinding.validation.IValidator; |
| import org.eclipse.core.databinding.validation.ValidationStatus; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationListener; |
| import org.eclipse.debug.core.ILaunchConfigurationType; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.jface.databinding.viewers.typed.ViewerProperties; |
| import org.eclipse.jface.viewers.ArrayContentProvider; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.databinding.core.conversion.ClassTypedConverter; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtils; |
| import org.eclipse.statet.ecommons.ui.util.UIAccess; |
| |
| import org.eclipse.statet.docmlet.base.ui.DocmlBaseUI; |
| import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingConfigStepTab; |
| import org.eclipse.statet.docmlet.base.ui.processing.DocProcessingOperationSettings; |
| import org.eclipse.statet.internal.docmlet.base.ui.processing.Messages; |
| |
| |
| @NonNullByDefault |
| public abstract class AbstractLaunchConfigOperationSettings extends DocProcessingOperationSettings { |
| |
| |
| @SuppressWarnings("null") |
| private static final Class<@Nullable ILaunchConfiguration> Nullable_LaunchConfiguration_TYPE= ILaunchConfiguration.class; |
| |
| |
| private final String launchConfigTypeId; |
| |
| private final String launchConfigNameAttrName; |
| |
| private ILaunchManager launchManager; |
| private ILaunchConfigurationType launchConfigType; |
| private ILaunchConfigurationListener launchConfigListener; |
| private List<ILaunchConfiguration> availablelaunchConfigs; |
| |
| private IObservableValue<@Nullable String> launchConfigNameValue; |
| |
| private TableViewer launchConfigViewer; |
| private Button launchConfigNewControl; |
| |
| |
| public AbstractLaunchConfigOperationSettings(final String launchConfigTypeId) { |
| this.launchConfigTypeId= launchConfigTypeId; |
| |
| this.launchConfigNameAttrName= getId() + '/' + AbstractLaunchConfigOperation.LAUNCH_CONFIG_NAME_ATTR_KEY; |
| } |
| |
| |
| @Override |
| public String getInfo() { |
| final String label= getLabel(); |
| final String name= this.launchConfigNameValue.getValue(); |
| return label + ": " + ((name != null) ? limitInfo(name) : "?"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| @Override |
| protected void init(final DocProcessingConfigStepTab tab) { |
| super.init(tab); |
| |
| final Realm realm= getRealm(); |
| this.launchConfigNameValue= new WritableValue<>(realm, null, String.class); |
| |
| this.launchManager= DebugPlugin.getDefault().getLaunchManager(); |
| final ILaunchConfigurationType launchConfigType= this.launchManager.getLaunchConfigurationType(this.launchConfigTypeId); |
| if (launchConfigType == null) { |
| throw new RuntimeException("Launch configuration type is missing: id= " + this.launchConfigTypeId); //$NON-NLS-1$ |
| } |
| this.launchConfigType= launchConfigType; |
| this.launchConfigListener= new ILaunchConfigurationListener() { |
| @Override |
| public void launchConfigurationAdded(final ILaunchConfiguration configuration) { |
| updateAvailableConfigs(); |
| } |
| @Override |
| public void launchConfigurationChanged(final ILaunchConfiguration configuration) { |
| updateAvailableConfigs(); |
| } |
| @Override |
| public void launchConfigurationRemoved(final ILaunchConfiguration configuration) { |
| updateAvailableConfigs(); |
| } |
| }; |
| this.launchManager.addLaunchConfigurationListener(this.launchConfigListener); |
| updateAvailableConfigs(); |
| } |
| |
| @Override |
| protected void dispose() { |
| if (this.launchManager != null) { |
| this.launchManager.removeLaunchConfigurationListener(this.launchConfigListener); |
| } |
| |
| super.dispose(); |
| } |
| |
| @Override |
| protected Composite createControl(final Composite parent) { |
| final Composite composite= super.createControl(parent); |
| composite.setLayout(LayoutUtils.newCompositeGrid(2)); |
| |
| { final Label label= new Label(composite, SWT.NONE); |
| label.setText(Messages.ProcessingOperation_RunLaunchConfigSettings_List_label); |
| label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); |
| } |
| |
| { final TableViewer viewer= new TableViewer(composite, |
| SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); |
| |
| viewer.setLabelProvider(DebugUITools.newDebugModelPresentation()); |
| viewer.setContentProvider(new ArrayContentProvider()); |
| viewer.setInput(new Object()); |
| |
| final GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); |
| gd.heightHint= LayoutUtils.hintHeight(viewer.getTable(), 5); |
| viewer.getControl().setLayoutData(gd); |
| this.launchConfigViewer= viewer; |
| } |
| { final Button button= new Button(composite, SWT.PUSH); |
| |
| button.setText(Messages.ProcessingOperation_RunLaunchConfigSettings_New_label); |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(final SelectionEvent e) { |
| createNewLaunchConfig(); |
| } |
| |
| }); |
| |
| final GridData gd= new GridData(SWT.FILL, SWT.TOP, false, false); |
| gd.widthHint= LayoutUtils.hintWidth(button); |
| button.setLayoutData(gd); |
| this.launchConfigNewControl= button; |
| } |
| return composite; |
| } |
| |
| @Override |
| protected void addBindings(final DataBindingContext dbc) { |
| dbc.bindValue( |
| ViewerProperties.singleSelection(ILaunchConfiguration.class) |
| .observe(this.launchConfigViewer), |
| this.launchConfigNameValue, |
| new UpdateValueStrategy<@Nullable ILaunchConfiguration, @Nullable String>() |
| .setAfterGetValidator(new IValidator<@Nullable ILaunchConfiguration>() { |
| @Override |
| public IStatus validate(final @Nullable ILaunchConfiguration value) { |
| if (value == null) { |
| return ValidationStatus.error(NLS.bind( |
| Messages.ProcessingOperation_RunLaunchConfigSettings_error_NoConfigSelected_message, |
| getLabel() )); |
| } |
| return ValidationStatus.ok(); |
| } |
| }) |
| .setConverter(ClassTypedConverter.create(Nullable_LaunchConfiguration_TYPE, Nullable_String_TYPE, |
| (final @Nullable ILaunchConfiguration fromObject) -> |
| (fromObject != null) ? fromObject.getName() : null )), |
| new UpdateValueStrategy<@Nullable String, @Nullable ILaunchConfiguration>() |
| .setConverter(ClassTypedConverter.create(Nullable_String_TYPE, Nullable_LaunchConfiguration_TYPE, |
| this::findLaunchConfig ))); |
| } |
| |
| private @Nullable ILaunchConfiguration findLaunchConfig(final @Nullable String name) { |
| if (name != null) { |
| for (final ILaunchConfiguration config : this.availablelaunchConfigs) { |
| if (config.getName().equals(name)) { |
| return config; |
| } |
| } |
| } |
| return null; |
| } |
| |
| private void updateAvailableConfigs() { |
| try { |
| final ILaunchConfiguration[] allConfigs= this.launchManager.getLaunchConfigurations( |
| this.launchConfigType ); |
| final ArrayList<ILaunchConfiguration> filteredConfigs= new ArrayList<>(allConfigs.length); |
| for (final ILaunchConfiguration config : allConfigs) { |
| if (includeLaunchConfig(config)) { |
| filteredConfigs.add(config); |
| } |
| } |
| this.availablelaunchConfigs= filteredConfigs; |
| if (UIAccess.isOkToUse(this.launchConfigViewer)) { |
| this.launchConfigViewer.setInput(this.availablelaunchConfigs); |
| } |
| } |
| catch (final CoreException e) { |
| StatusManager.getManager().handle(new Status(IStatus.ERROR, DocmlBaseUI.BUNDLE_ID, 0, |
| NLS.bind("An error occurred while updating list of launch configurations for ''{0}''.", |
| getLabel() ), |
| e )); |
| } |
| } |
| |
| protected boolean includeLaunchConfig(final ILaunchConfiguration config) { |
| return true; |
| } |
| |
| protected void createNewLaunchConfig() { |
| try { |
| final String name= getLaunchConfigurationDialog().generateName(getNewLaunchConfigName()); |
| |
| final ILaunchConfigurationWorkingCopy newConfig= this.launchConfigType.newInstance(null, name); |
| |
| initializeNewLaunchConfig(newConfig); |
| |
| this.launchConfigNameValue.setValue(name); |
| |
| newConfig.doSave(); |
| } |
| catch (final CoreException e) { |
| StatusManager.getManager().handle(new Status(IStatus.ERROR, DocmlBaseUI.BUNDLE_ID, 0, |
| NLS.bind(Messages.ProcessingOperation_RunLaunchConfigSettings_error_NewConfigFailed_message, |
| getLabel() ), |
| e ), StatusManager.LOG | StatusManager.SHOW); |
| } |
| } |
| |
| protected @Nullable String getNewLaunchConfigName() { |
| return null; |
| } |
| |
| protected void initializeNewLaunchConfig(final ILaunchConfigurationWorkingCopy config) { |
| } |
| |
| @Override |
| protected void load(final Map<String, String> config) { |
| final String name= config.get(this.launchConfigNameAttrName); |
| this.launchConfigNameValue.setValue(name); |
| } |
| |
| @Override |
| protected void save(final Map<String, String> config) { |
| final String name= this.launchConfigNameValue.getValue(); |
| set(config, this.launchConfigNameAttrName, name); |
| } |
| |
| } |