Java tutorial
/******************************************************************************* * Copyright (c) 2017 Red Hat Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.docker.launcher; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICMultiConfigDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting; import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher; import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; import org.eclipse.cdt.internal.docker.launcher.ContainerPropertyVolumesModel.MountType; import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IMultiConfiguration; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.core.Configuration; import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector; import org.eclipse.cdt.managedbuilder.ui.properties.AbstractCBuildPropertyTab; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.beans.IBeanValueProperty; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.map.IObservableMap; import org.eclipse.core.databinding.property.Properties; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; import org.eclipse.jface.databinding.viewers.ViewerSupport; import org.eclipse.jface.databinding.viewers.ViewersObservables; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.linuxtools.docker.core.DockerConnectionManager; import org.eclipse.linuxtools.docker.core.IDockerConnection; import org.eclipse.linuxtools.docker.core.IDockerConnectionManagerListener; import org.eclipse.linuxtools.docker.core.IDockerImage; import org.eclipse.linuxtools.docker.core.IDockerImageListener; import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; @SuppressWarnings("restriction") public class ContainerPropertyTab extends AbstractCBuildPropertyTab implements IDockerConnectionManagerListener, IDockerImageListener { public final static String VOLUME_SEPARATOR = "|"; //$NON-NLS-1$ private final static String GNU_ELF_PARSER_ID = "org.eclipse.cdt.core.GNU_ELF"; //$NON-NLS-1$ private final static String ELF_PARSER_ID = "org.eclipse.cdt.core.ELF"; //$NON-NLS-1$ private static final String RUN_IN_CONFIGURE_LAUNCHER = "org.eclipse.cdt.autotools.core.property.launchAutotoolsInContainer"; //$NON-NLS-1$ private Combo imageCombo; private Combo connectionSelector; private Button enableButton; private Button launchAutotoolsButton; private Button addButton; private IDockerConnection connection; private IDockerConnection[] connections; private IDockerImageListener containerTab; private boolean isAutotoolsProject; private String connectionName; private String connectionUri = ""; //$NON-NLS-1$ private boolean initialEnabled; private boolean initialAutotoolsLaunchEnabled; private String initialConnection; private String initialImageId; private String initialVolumes; private String initialSelectedVolumes; private boolean multiChange; private List<IDockerImage> displayedImages = new ArrayList<>(); private IConfiguration iCfg; private ICConfigurationDescription iCfgd; private final DataBindingContext dbc = new DataBindingContext(); private final ContainerPropertyVolumesModel model; private ModifyListener connectionModifyListener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { int index = connectionSelector.getSelectionIndex(); if (index < 0) { connection = null; connectionName = ""; return; } if (connection != null) connection.removeImageListener(containerTab); connection = connections[index]; connectionUri = connection.getUri(); if (!connectionName.equals(connection.getName())) { imageCombo.setText(""); initialImageId = null; refreshImages(); setVolumeControlsEnabled(new Button[] { addButton }, false); } connectionName = connection.getName(); setConnection(connectionUri); model.setConnection(connection); } }; public ContainerPropertyTab() { this.containerTab = this; this.model = new ContainerPropertyVolumesModel((IDockerConnection) null); } @Override public void createControls(Composite parent) { super.createControls(parent); usercomp.setLayout(new GridLayout(5, false)); usercomp.setFont(parent.getFont()); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 1; usercomp.setLayoutData(gd); enableButton = new Button(usercomp, SWT.CHECK); enableButton.setText(Messages.ContainerPropertyTab_Enable_Msg); iCfg = getCfg(); iCfgd = getResDesc().getConfiguration(); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 5; enableButton.setLayoutData(gd); Label connectionSelectorLabel = new Label(usercomp, SWT.NULL); connectionSelectorLabel.setText(Messages.ContainerTab_Connection_Selector_Label); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 1; gd.grabExcessHorizontalSpace = false; connectionSelectorLabel.setLayoutData(gd); connectionSelector = new Combo(usercomp, SWT.BORDER | SWT.READ_ONLY); initializeConnectionSelector(); connectionSelector.addModifyListener(connectionModifyListener); // Following is a kludge so that on Linux the Combo is read-only but // has a white background. connectionSelector.addVerifyListener(new VerifyListener() { @Override public void verifyText(VerifyEvent e) { e.doit = false; } }); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 3; gd.grabExcessHorizontalSpace = true; connectionSelector.setLayoutData(gd); Label label1 = new Label(usercomp, SWT.NULL); gd = new GridData(); gd.horizontalSpan = 1; gd.grabExcessHorizontalSpace = false; label1.setLayoutData(gd); Label imageSelectorLabel = new Label(usercomp, SWT.NULL); imageSelectorLabel.setText(Messages.ContainerTab_Image_Selector_Label); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 1; connectionSelectorLabel.setLayoutData(gd); imageCombo = new Combo(usercomp, SWT.DROP_DOWN); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 3; gd.grabExcessHorizontalSpace = true; imageCombo.setLayoutData(gd); Label label2 = new Label(usercomp, SWT.NULL); gd = new GridData(); gd.horizontalSpan = 1; gd.grabExcessHorizontalSpace = false; label2.setLayoutData(gd); initializeImageCombo(); imageCombo.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { setImageId(imageCombo.getText()); model.setSelectedImage(displayedImages.get(imageCombo.getSelectionIndex())); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }); createVolumeSettingsContainer(usercomp); try { IProject project = iCfgd.getProjectDescription().getProject(); IProjectNature nature = project.getNature("org.eclipse.cdt.autotools.core.autotoolsNatureV2"); //$NON-NLS-1$ isAutotoolsProject = (nature != null); if (isAutotoolsProject) { launchAutotoolsButton = new Button(usercomp, SWT.CHECK); launchAutotoolsButton.setText(Messages.ContainerPropertyTab_Run_Autotools_In_Container_Msg); launchAutotoolsButton .setToolTipText(Messages.ContainerPropertyTab_Run_Autotools_In_Container_Tooltip); gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 5; launchAutotoolsButton.setLayoutData(gd); initializeLaunchAutotoolsButton(); launchAutotoolsButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { setLaunchAutotoolsEnablement(launchAutotoolsButton.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { // ignore } }); } } catch (CoreException e) { DockerLaunchUIPlugin.log(e); } initializeEnablementButton(); enableButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { setControlsEnabled(enableButton.getSelection()); setEnablement(enableButton.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { // ignore } }); } private void createVolumeSettingsContainer(final Composite container) { final Label volumesLabel = new Label(container, SWT.NONE); volumesLabel.setText(WizardMessages.getString("ImageRunResourceVolVarPage.dataVolumesLabel")); //$NON-NLS-1$ GridDataFactory.fillDefaults().grab(false, false).applyTo(volumesLabel); final CheckboxTableViewer dataVolumesTableViewer = createVolumesTable(container); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).hint(400, 200) .applyTo(dataVolumesTableViewer.getTable()); // buttons final Composite buttonsContainers = new Composite(container, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(false, false).applyTo(buttonsContainers); GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).spacing(SWT.DEFAULT, 0) .applyTo(buttonsContainers); addButton = new Button(buttonsContainers, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).applyTo(addButton); addButton.setText(WizardMessages.getString("ImageRunResourceVolVarPage.addButton")); //$NON-NLS-1$ addButton.addSelectionListener(onAddDataVolume(dataVolumesTableViewer)); if (imageCombo.getText() != null && !imageCombo.getText().equals("")) { setVolumeControlsEnabled(new Button[] { addButton }, true); } final Button editButton = new Button(buttonsContainers, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).applyTo(editButton); editButton.setText(WizardMessages.getString("ImageRunResourceVolVarPage.editButton")); //$NON-NLS-1$ editButton.addSelectionListener(onEditDataVolume(dataVolumesTableViewer)); editButton.setEnabled(false); final Button removeButton = new Button(buttonsContainers, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).applyTo(removeButton); removeButton.setText(WizardMessages.getString("ImageRunResourceVolVarPage.removeButton")); //$NON-NLS-1$ removeButton.addSelectionListener(onRemoveDataVolumes(dataVolumesTableViewer)); removeButton.setEnabled(false); // update table content when selected image changes bind(dataVolumesTableViewer, model.getDataVolumes(), BeanProperties.values(DataVolumeModel.class, DataVolumeModel.CONTAINER_PATH, DataVolumeModel.MOUNT, DataVolumeModel.READ_ONLY_VOLUME)); dbc.bindSet(ViewersObservables.observeCheckedElements(dataVolumesTableViewer, DataVolumeModel.class), BeanProperties.set(ContainerPropertyVolumesModel.SELECTED_DATA_VOLUMES).observe(model)); // disable the edit and removeButton if the table is empty dataVolumesTableViewer.addSelectionChangedListener(onSelectionChanged(editButton, removeButton)); initializeVolumesTable(); } /** * Same as * {@link ViewerSupport#bind(StructuredViewer, IObservableList, org.eclipse.core.databinding.property.value.IValueProperty[]) * but with a custom LabelProvider, DataVolumesLabelProvider * * @param viewer * @param input * @param labelProperties */ private void bind(final StructuredViewer viewer, final IObservableList input, final IBeanValueProperty[] labelProperties) { final ObservableListContentProvider contentProvider = new ObservableListContentProvider(); if (viewer.getInput() != null) { viewer.setInput(null); } viewer.setContentProvider(contentProvider); viewer.setLabelProvider(new DataVolumesLabelProvider( Properties.observeEach(contentProvider.getKnownElements(), labelProperties))); if (input != null) { viewer.setInput(input); } } private ISelectionChangedListener onSelectionChanged(final Button... targetButtons) { return e -> { if (e.getSelection().isEmpty()) { setVolumeControlsEnabled(targetButtons, false); } else { setVolumeControlsEnabled(targetButtons, true); } }; } private static void setVolumeControlsEnabled(final Control[] controls, final boolean enabled) { for (Control control : controls) { if (control != null) { control.setEnabled(enabled); } } } private SelectionListener onAddDataVolume(final CheckboxTableViewer dataVolumesTableViewer) { return SelectionListener.widgetSelectedAdapter(e -> { final ContainerDataVolumeDialog dialog = new ContainerDataVolumeDialog( Display.getDefault().getActiveShell(), model.getConnection()); dialog.create(); if (dialog.open() == IDialogConstants.OK_ID) { final DataVolumeModel dataVolume = dialog.getDataVolume(); dataVolume.setSelected(true); model.getDataVolumes().add(dataVolume); model.getSelectedDataVolumes().add(dataVolume); dataVolumesTableViewer.setChecked(dataVolume, true); setVolumes(); } }); } private SelectionListener onEditDataVolume(final CheckboxTableViewer dataVolumesTableViewer) { return SelectionListener.widgetSelectedAdapter(e -> { final IStructuredSelection selection = (IStructuredSelection) dataVolumesTableViewer.getSelection(); if (selection.isEmpty()) { return; } final DataVolumeModel selectedDataVolume = (DataVolumeModel) selection.getFirstElement(); final ContainerDataVolumeDialog dialog = new ContainerDataVolumeDialog( Display.getDefault().getActiveShell(), model.getConnection(), selectedDataVolume); dialog.create(); if (dialog.open() == IDialogConstants.OK_ID) { final DataVolumeModel dialogDataVolume = dialog.getDataVolume(); selectedDataVolume.setContainerMount(dialogDataVolume.getContainerMount()); selectedDataVolume.setMountType(dialogDataVolume.getMountType()); selectedDataVolume.setHostPathMount(dialogDataVolume.getHostPathMount()); selectedDataVolume.setContainerMount(dialogDataVolume.getContainerMount()); selectedDataVolume.setReadOnly(dialogDataVolume.isReadOnly()); model.getSelectedDataVolumes().add(selectedDataVolume); dataVolumesTableViewer.setChecked(selectedDataVolume, true); setVolumes(); } }); } private SelectionListener onRemoveDataVolumes(final TableViewer dataVolumesTableViewer) { return SelectionListener.widgetSelectedAdapter(e -> { final IStructuredSelection selection = dataVolumesTableViewer.getStructuredSelection(); for (@SuppressWarnings("unchecked") Iterator<DataVolumeModel> iterator = selection.iterator(); iterator.hasNext();) { final DataVolumeModel volume = iterator.next(); model.removeDataVolume(volume); model.getSelectedDataVolumes().remove(volume); } setVolumes(); }); } private CheckboxTableViewer createVolumesTable(final Composite container) { final Table table = new Table(container, SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL); final CheckboxTableViewer tableViewer = new CheckboxTableViewer(table); table.setHeaderVisible(true); table.setLinesVisible(true); dbc.bindSet(ViewersObservables.observeCheckedElements(tableViewer, DataVolumeModel.class), BeanProperties.set(ContainerPropertyVolumesModel.SELECTED_DATA_VOLUMES).observe(model)); addTableViewerColumn(tableViewer, WizardMessages.getString("ImageRunResourceVolVarPage.containerPathColumn"), //$NON-NLS-1$ 180); addTableViewerColumn(tableViewer, WizardMessages.getString("ImageRunResourceVolVarPage.mountColumn"), //$NON-NLS-1$ 180); addTableViewerColumn(tableViewer, WizardMessages.getString("ImageRunResourceVolVarPage.readonlyColumn"), //$NON-NLS-1$ 60); return tableViewer; } private TableViewerColumn addTableViewerColumn(final TableViewer tableViewer, final String title, final int width) { final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); final TableColumn column = viewerColumn.getColumn(); if (title != null) { column.setText(title); } column.setWidth(width); return viewerColumn; } private static final class DataVolumesLabelProvider extends ObservableMapLabelProvider { private Image CONTAINER_IMAGE = SWTImagesFactory.DESC_CONTAINER.createImage(); private Image FOLDER_CLOSED_IMAGE = SWTImagesFactory.DESC_FOLDER_CLOSED.createImage(); private Image FILE_IMAGE = SWTImagesFactory.DESC_FILE.createImage(); public DataVolumesLabelProvider(final IObservableMap[] attributeMaps) { super(attributeMaps); } @Override public void dispose() { CONTAINER_IMAGE.dispose(); FOLDER_CLOSED_IMAGE.dispose(); FILE_IMAGE.dispose(); super.dispose(); } @Override public Image getColumnImage(Object element, int columnIndex) { final DataVolumeModel dataVolume = ((DataVolumeModel) element); if (dataVolume.getMountType() != null && columnIndex == 1) { switch (dataVolume.getMountType()) { case CONTAINER: return CONTAINER_IMAGE; case HOST_FILE_SYSTEM: final File hostFile = new File(dataVolume.getMount()); if (!hostFile.exists() || hostFile.isDirectory()) { return FOLDER_CLOSED_IMAGE; } else { return FILE_IMAGE; } default: return null; } } return null; } @Override public String getColumnText(Object element, int columnIndex) { final DataVolumeModel dataVolume = ((DataVolumeModel) element); switch (columnIndex) { case 0: return dataVolume.getContainerPath(); case 1: return dataVolume.getMount(); case 2: if (dataVolume.getMountType() != MountType.HOST_FILE_SYSTEM) { return null; } else if (dataVolume.isReadOnly()) { return WizardMessages.getString("ImageRunResourceVolVarPage.true"); //$NON-NLS-1$ } return WizardMessages.getString("ImageRunResourceVolVarPage.false"); //$NON-NLS-1$ default: return null; } } } private void setVolumes() { StringBuffer buffer = new StringBuffer(); String separator = ""; //$NON-NLS-1$ for (DataVolumeModel volume : model.getDataVolumes()) { buffer.append(separator); buffer.append(volume.toString()); separator = VOLUME_SEPARATOR; } StringBuffer selectedBuffer = new StringBuffer(); separator = ""; //$NON-NLS-1$ for (DataVolumeModel volume : model.getSelectedDataVolumes()) { selectedBuffer.append(separator); selectedBuffer.append(volume.toString()); separator = VOLUME_SEPARATOR; } if (iCfg instanceof IMultiConfiguration) { IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg).getItems(); for (int i = 0; i < cfs.length; i++) { IConfiguration cfg = cfs[i]; IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.VOLUMES_ID, buffer.toString()); p.setProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID, selectedBuffer.toString()); } } else { IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.VOLUMES_ID, buffer.toString()); p.setProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID, selectedBuffer.toString()); } } private void setEnablement(boolean enabled) { if (iCfg instanceof IMultiConfiguration) { IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg).getItems(); for (int i = 0; i < cfs.length; i++) { IConfiguration cfg = cfs[i]; IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, Boolean.toString(enableButton.getSelection())); } } else { IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, Boolean.toString(enableButton.getSelection())); } // if enabled, make sure we have ELF binary parsers specified if (enabled) { String[] ids = CoreModelUtil.getBinaryParserIds(page.getCfgsEditable()); List<String> idList = new ArrayList<>(Arrays.asList(ids)); if (!idList.contains(GNU_ELF_PARSER_ID)) { idList.add(GNU_ELF_PARSER_ID); } if (!idList.contains(ELF_PARSER_ID)) { idList.add(ELF_PARSER_ID); } CoreModelUtil.setBinaryParserIds(page.getCfgsEditable(), idList.toArray(new String[0])); } } private void setLaunchAutotoolsEnablement(boolean enabled) { if (iCfg instanceof IMultiConfiguration) { IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg).getItems(); for (int i = 0; i < cfs.length; i++) { IConfiguration cfg = cfs[i]; IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); p.setProperty(RUN_IN_CONFIGURE_LAUNCHER, Boolean.toString(launchAutotoolsButton.getSelection())); } } else { IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); p.setProperty(RUN_IN_CONFIGURE_LAUNCHER, Boolean.toString(launchAutotoolsButton.getSelection())); } } private void setImageId(String imageId) { if (iCfg instanceof IMultiConfiguration) { IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg).getItems(); for (int i = 0; i < cfs.length; i++) { IConfiguration cfg = cfs[i]; IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.IMAGE_ID, imageId); } } else { IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.IMAGE_ID, imageId); } } private void setConnection(String uri) { if (iCfg instanceof IMultiConfiguration) { IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg).getItems(); for (int i = 0; i < cfs.length; i++) { IConfiguration cfg = cfs[i]; IOptionalBuildProperties p = cfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.CONNECTION_ID, uri); } } else { IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); p.setProperty(ContainerCommandLauncher.CONNECTION_ID, uri); } } private void setControlsEnabled(boolean enabled) { imageCombo.setEnabled(enabled); connectionSelector.setEnabled(enabled); if (isAutotoolsProject) { launchAutotoolsButton.setEnabled(enabled); } setVolumeControlsEnabled(new Button[] { addButton }, enabled); } private void initializeEnablementButton() { initialEnabled = false; IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String savedEnabled = properties.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); if (savedEnabled != null) { initialEnabled = Boolean.parseBoolean(savedEnabled); } enableButton.setSelection(initialEnabled); setControlsEnabled(initialEnabled); } private void initializeLaunchAutotoolsButton() { initialEnabled = false; IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String savedEnabled = properties.getProperty(RUN_IN_CONFIGURE_LAUNCHER); if (savedEnabled != null) { initialAutotoolsLaunchEnabled = Boolean.parseBoolean(savedEnabled); } launchAutotoolsButton.setSelection(initialAutotoolsLaunchEnabled); } private void initializeConnectionSelector() { int defaultIndex = -1; initialConnection = null; IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String id = properties.getProperty(ContainerCommandLauncher.CONNECTION_ID); if (id != null) { initialConnection = id; } connections = DockerConnectionManager.getInstance().getConnections(); if (connections.length == 0) { // setErrorMessage(Messages.ContainerTab_Error_No_Connections); return; } String[] connectionNames = new String[connections.length]; for (int i = 0; i < connections.length; ++i) { connectionNames[i] = connections[i].getName(); if (connections[i].getUri().equals(initialConnection)) defaultIndex = i; } if (defaultIndex < 0) { initialEnabled = false; defaultIndex = 0; } connectionSelector.setItems(connectionNames); if (connections.length > 0) { connectionSelector.select(defaultIndex); connection = connections[defaultIndex]; connectionName = connection.getName(); connectionUri = connection.getUri(); initialConnection = connectionUri; model.setConnection(connection); } } private void refreshImages() { if (connection != null) { java.util.List<IDockerImage> images = connection.getImages(); if (images == null || images.size() == 0) { // setsetErrorMessage(Messages.ContainerTab_Error_No_Images); return; } connection.removeImageListener(containerTab); ArrayList<String> imageNames = new ArrayList<String>(); displayedImages = new ArrayList<>(); for (IDockerImage image : images) { java.util.List<String> tags = image.repoTags(); if (tags != null) { for (String tag : tags) { if (!tag.equals("<none>:<none>")) { //$NON-NLS-1$ imageNames.add(tag); displayedImages.add(image); } } } } imageCombo.setItems(imageNames.toArray(new String[0])); if (initialImageId != null) { int index = imageCombo.indexOf(initialImageId); if (index > -1) { imageCombo.select(index); model.setSelectedImage(displayedImages.get(index)); setVolumeControlsEnabled(new Button[] { addButton }, true); } else { } } connection.addImageListener(containerTab); } } private void initializeImageCombo() { initialImageId = null; IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); String id = properties.getProperty(ContainerCommandLauncher.IMAGE_ID); if (id != null) { initialImageId = id; } refreshImages(); } private void initializeVolumesTable() { model.clearDataVolumes(); int imageSelectionIndex = imageCombo.getSelectionIndex(); if (imageSelectionIndex >= 0 && imageSelectionIndex < displayedImages.size()) { model.setSelectedImage(displayedImages.get(imageSelectionIndex)); } IOptionalBuildProperties properties = iCfg.getOptionalBuildProperties(); initialVolumes = properties.getProperty(ContainerCommandLauncher.VOLUMES_ID); Map<String, DataVolumeModel> volumeMap = parseVolumes(initialVolumes); initialSelectedVolumes = properties.getProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID); Map<String, DataVolumeModel> selectedVolumeMap = parseVolumes(initialSelectedVolumes); Set<DataVolumeModel> selectedVolumes = new HashSet<>(); for (DataVolumeModel dvm : selectedVolumeMap.values()) { // we need selected volumes to be volumes that are in the volumes // collection, so just replace them in the volumes Map so they will // be // the same objects volumeMap.put(dvm.getContainerPath(), dvm); selectedVolumes.add(dvm); } model.setDataVolumes(volumeMap.values()); model.setSelectedDataVolumes(selectedVolumes); } private Map<String, DataVolumeModel> parseVolumes(String volumesString) { Map<String, DataVolumeModel> volumeMap = new HashMap<>(); if (volumesString != null && !volumesString.equals("")) { //$NON-NLS-1$ String[] volumes = volumesString.split("[" + VOLUME_SEPARATOR + "]"); //$NON-NLS-1$ //$NON-NLS-2$ for (String volume : volumes) { if (volume != null && !volume.equals("")) { //$NON-NLS-1$ DataVolumeModel dataVolume = DataVolumeModel.parseString(volume); volumeMap.put(dataVolume.getContainerPath(), dataVolume); } } } return volumeMap; } @Override protected void performApply(ICResourceDescription src, ICResourceDescription dst) { setVolumes(); boolean needToRecalculate = false; ICConfigurationDescription defaultCfg = null; if (page.isMultiCfg()) { ICMultiConfigDescription mc1 = (ICMultiConfigDescription) src.getConfiguration(); ICMultiConfigDescription mc2 = (ICMultiConfigDescription) dst.getConfiguration(); ICConfigurationDescription[] cds1 = (ICConfigurationDescription[]) mc1.getItems(); ICConfigurationDescription[] cds2 = (ICConfigurationDescription[]) mc2.getItems(); defaultCfg = cds1[0]; for (int i = 0; i < cds1.length; i++) needToRecalculate |= applyToCfg(cds1[i], cds2[i]); } else { defaultCfg = src.getConfiguration(); needToRecalculate = applyToCfg(src.getConfiguration(), dst.getConfiguration()); } if (needToRecalculate) { recalculateSpecs(defaultCfg, true); } } private boolean applyToCfg(ICConfigurationDescription c1, ICConfigurationDescription c2) { Configuration cfg01 = (Configuration) getCfg(c1); Configuration cfg02 = (Configuration) getCfg(c2); IOptionalBuildProperties prop1 = cfg01.getOptionalBuildProperties(); IOptionalBuildProperties prop2 = cfg02.getOptionalBuildProperties(); boolean needToRecalculate = false; ICTargetPlatformSetting tps = c1.getTargetPlatformSetting(); String[] pids = tps.getBinaryParserIds(); ICTargetPlatformSetting tps2 = c2.getTargetPlatformSetting(); tps2.setBinaryParserIds(pids); String enablementProperty = prop1.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); String enablementProperty2 = prop2.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED); if (enablementProperty != null && !enablementProperty.equals(enablementProperty2)) { needToRecalculate = true; } prop2.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, enablementProperty); String connectionProperty = prop1.getProperty(ContainerCommandLauncher.CONNECTION_ID); String connectionProperty2 = prop2.getProperty(ContainerCommandLauncher.CONNECTION_ID); if (connectionProperty != null && !connectionProperty.equals(connectionProperty2)) { needToRecalculate = true; } prop2.setProperty(ContainerCommandLauncher.CONNECTION_ID, connectionProperty); String imageProperty = prop1.getProperty(ContainerCommandLauncher.IMAGE_ID); String imageProperty2 = prop2.getProperty(ContainerCommandLauncher.IMAGE_ID); if (imageProperty != null && !imageProperty.equals(imageProperty2)) { needToRecalculate = true; } prop2.setProperty(ContainerCommandLauncher.IMAGE_ID, imageProperty); String volumesProperty = prop1.getProperty(ContainerCommandLauncher.VOLUMES_ID); prop2.setProperty(ContainerCommandLauncher.VOLUMES_ID, volumesProperty); String selectedVolumesProperty = prop1.getProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID); prop2.setProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID, selectedVolumesProperty); return needToRecalculate; } protected void recalculateSpecs(ICConfigurationDescription cfgd, boolean performingApply) { IConfiguration cfg = getCfg(cfgd); IOptionalBuildProperties properties = cfg.getOptionalBuildProperties(); initialEnabled = Boolean .parseBoolean(properties.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED)); initialConnection = properties.getProperty(ContainerCommandLauncher.CONNECTION_ID); initialImageId = properties.getProperty(ContainerCommandLauncher.IMAGE_ID); initialVolumes = properties.getProperty(ContainerCommandLauncher.VOLUMES_ID); initialSelectedVolumes = properties.getProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID); initialAutotoolsLaunchEnabled = Boolean.parseBoolean(properties.getProperty(RUN_IN_CONFIGURE_LAUNCHER)); List<ILanguageSettingsProvider> providers = ((ILanguageSettingsProvidersKeeper) cfgd) .getLanguageSettingProviders(); for (ILanguageSettingsProvider provider : providers) { if (provider instanceof GCCBuiltinSpecsDetector) { GCCBuiltinSpecsDetector d = (GCCBuiltinSpecsDetector) provider; // force recalculation of gcc include path d.clear(); if (performingApply) { d.handleEvent(null); } // final IProject project = getProject(); // CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(project)); } } } @Override protected void performOK() { boolean needToRecalculate = false; setVolumes(); if (iCfg instanceof IMultiConfiguration) { needToRecalculate = multiChange; } else { IOptionalBuildProperties p = iCfg.getOptionalBuildProperties(); if (initialEnabled != Boolean .parseBoolean(p.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED))) { needToRecalculate = true; } else if (initialEnabled == true) { if (!initialConnection.equals(p.getProperty(ContainerCommandLauncher.CONNECTION_ID)) || !initialImageId.equals(p.getProperty(ContainerCommandLauncher.IMAGE_ID))) { needToRecalculate = true; } } } if (needToRecalculate) { recalculateSpecs(ManagedBuildManager.getDescriptionForConfiguration(iCfg), false); } } @Override protected void performDefaults() { if (iCfg instanceof IMultiConfiguration) { IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg).getItems(); for (int i = 0; i < cfs.length; i++) { IOptionalBuildProperties props = cfs[i].getOptionalBuildProperties(); props.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, Boolean.toString(false)); if (connections.length > 0) { props.setProperty(ContainerCommandLauncher.CONNECTION_ID, connections[0].getUri()); } else { props.setProperty(ContainerCommandLauncher.CONNECTION_ID, null); } props.setProperty(ContainerCommandLauncher.IMAGE_ID, null); props.setProperty(ContainerCommandLauncher.VOLUMES_ID, null); props.setProperty(ContainerCommandLauncher.SELECTED_VOLUMES_ID, null); } } else { IOptionalBuildProperties props = iCfg.getOptionalBuildProperties(); props.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED, Boolean.toString(false)); if (connections.length > 0) { props.setProperty(ContainerCommandLauncher.CONNECTION_ID, connections[0].getUri()); } else { props.setProperty(ContainerCommandLauncher.CONNECTION_ID, null); } props.setProperty(ContainerCommandLauncher.IMAGE_ID, null); } initialEnabled = false; initialConnection = null; initialImageId = null; initialVolumes = null; initialSelectedVolumes = null; if (connections.length > 0) { connectionSelector.select(0); } imageCombo.setText(""); //$NON-NLS-1$ model.setDataVolumes(null); model.setSelectedDataVolumes(null); enableButton.setSelection(false); setControlsEnabled(false); } @Override public void updateData(ICResourceDescription cfgd) { if (cfgd == null) return; iCfg = getCfg(cfgd.getConfiguration()); iCfgd = cfgd.getConfiguration(); multiChange = false; initializeConnectionSelector(); initializeImageCombo(); initializeEnablementButton(); initializeVolumesTable(); } @Override protected void updateButtons() { // TODO Auto-generated method stub } @Override public void changeEvent(IDockerConnection changedConnection, int type) { String currUri = null; int currIndex = 0; connections = DockerConnectionManager.getInstance().getConnections(); if (connection != null) { currUri = connection.getUri(); currIndex = connectionSelector.getSelectionIndex(); } String[] connectionNames = new String[connections.length]; int index = 0; for (int i = 0; i < connections.length; ++i) { connectionNames[i] = connections[i].getName(); if (connections[i].getUri().equals(currUri)) index = i; } if (type == IDockerConnectionManagerListener.RENAME_EVENT) { index = currIndex; // no change in connection displayed } connectionSelector.removeModifyListener(connectionModifyListener); connectionSelector.setItems(connectionNames); if (connectionNames.length > 0) { connectionSelector.setText(connectionNames[index]); connection = connections[index]; model.setConnection(connection); connectionUri = connection.getUri(); } else { connection = null; model.setConnection(null); model.setSelectedImage(null); connectionUri = ""; connectionSelector.setText(""); } connectionSelector.addModifyListener(connectionModifyListener); } @Override public void listChanged(IDockerConnection c, java.util.List<IDockerImage> list) { final IDockerImage[] finalList = list.toArray(new IDockerImage[0]); if (c.getName().equals(connection.getName())) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { connection.removeImageListener(containerTab); ArrayList<String> imageNames = new ArrayList<String>(); displayedImages = new ArrayList<>(); for (IDockerImage image : finalList) { java.util.List<String> tags = image.repoTags(); if (tags != null) { for (String tag : tags) { imageNames.add(tag); displayedImages.add(image); } } } if (!imageCombo.isDisposed()) imageCombo.setItems(imageNames.toArray(new String[0])); connection.addImageListener(containerTab); } }); } } }