| /******************************************************************************* |
| * Copyright (c) 2007, 2017 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| * Lars Vogel <Lars.Vogel@vogella.com> - Bug 490755 |
| * Lucas Bullen <lbullen@redhat.com> & Ian Pun <ipun@redhat.com> - Bug 518652 |
| * Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes |
| *******************************************************************************/ |
| package org.eclipse.debug.internal.ui.importexport.launchconfigurations; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationType; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; |
| import org.eclipse.debug.internal.core.LaunchConfiguration; |
| import org.eclipse.debug.internal.ui.DebugUIPlugin; |
| import org.eclipse.debug.internal.ui.IDebugHelpContextIds; |
| import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; |
| import org.eclipse.debug.internal.ui.SWTFactory; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchCategoryFilter; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.CheckboxTreeViewer; |
| import org.eclipse.jface.viewers.ICheckStateListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.DirectoryDialog; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.model.WorkbenchViewerComparator; |
| import org.eclipse.ui.progress.UIJob; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| /** |
| * This calls provides the one and only wizard page to the |
| * export launch configurations wizard. |
| * @since 3.4.0 |
| */ |
| public class ExportLaunchConfigurationsWizardPage extends WizardPage { |
| |
| /** |
| * The content provider for the tree viewer |
| * @since 3.4.0 |
| */ |
| class ConfigContentProvider implements ITreeContentProvider { |
| |
| ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager(); |
| |
| @Override |
| public Object[] getChildren(Object parentElement) { |
| if(parentElement instanceof ILaunchConfigurationType) { |
| try { |
| return lm.getLaunchConfigurations((ILaunchConfigurationType) parentElement, ILaunchConfiguration.CONFIGURATION | ILaunchConfiguration.PROTOTYPE); |
| } |
| catch (Exception e) { |
| DebugUIPlugin.logErrorMessage(e.getMessage()); |
| } |
| } |
| return null; |
| } |
| @Override |
| public Object getParent(Object element) { |
| if(element instanceof ILaunchConfiguration) { |
| try { |
| return ((ILaunchConfiguration)element).getType(); |
| } catch (CoreException e) { |
| return null; |
| } |
| } |
| return null; |
| } |
| @Override |
| public boolean hasChildren(Object element) { |
| return element instanceof ILaunchConfigurationType; |
| } |
| @Override |
| public Object[] getElements(Object inputElement) { |
| return lm.getLaunchConfigurationTypes(); |
| } |
| } |
| private String OVERWRITE = "overwrite"; //$NON-NLS-1$ |
| private String OLD_PATH = "oldpath"; //$NON-NLS-1$ |
| private CheckboxTreeViewer fViewer = null; |
| private Text fFilePath = null; |
| private Button fOverwrite = null; |
| private ConfigContentProvider fContentProvider = null; |
| private IStructuredSelection selectedElements; |
| /** |
| * Constructor |
| */ |
| protected ExportLaunchConfigurationsWizardPage() { |
| super(WizardMessages.ExportLaunchConfigurationsWizard_0); |
| setTitle(WizardMessages.ExportLaunchConfigurationsWizard_0); |
| } |
| |
| protected ExportLaunchConfigurationsWizardPage(IStructuredSelection selection) { |
| this(); |
| selectedElements = selection; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) |
| */ |
| @Override |
| public void createControl(Composite parent) { |
| Composite comp = SWTFactory.createComposite(parent, 2, 1, GridData.FILL_BOTH); |
| //add the check table |
| createViewer(comp); |
| //add the file path and browse button |
| createFilePath(comp); |
| //add the overwrite option |
| fOverwrite = SWTFactory.createCheckButton(comp, WizardMessages.ExportLaunchConfigurationsWizardPage_1, null, getDialogSettings().getBoolean(OVERWRITE), 2); |
| setControl(comp); |
| PlatformUI .getWorkbench().getHelpSystem().setHelp(comp, IDebugHelpContextIds.EXPORT_LAUNCH_CONFIGURATIONS_PAGE); |
| setMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_7); |
| setPageComplete(isComplete()); |
| } |
| |
| /** |
| * Creates the check table viewer portion of the control |
| * @param parent the parent to add the check table viewer to |
| */ |
| protected void createViewer(Composite parent) { |
| SWTFactory.createWrapLabel(parent, WizardMessages.ExportLaunchConfigurationsWizardPage_3, 2); |
| Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.CHECK); |
| GridData gd = new GridData(GridData.FILL_BOTH); |
| gd.horizontalSpan = 2; |
| tree.setLayoutData(gd); |
| fViewer = new CheckboxTreeViewer(tree); |
| fViewer.setLabelProvider(DebugUITools.newDebugModelPresentation()); |
| fViewer.setComparator(new WorkbenchViewerComparator()); |
| fContentProvider = new ConfigContentProvider(); |
| fViewer.setContentProvider(fContentProvider); |
| fViewer.setInput(DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationTypes()); |
| //we don't want to see builders.... |
| fViewer.addFilter(new LaunchCategoryFilter(IInternalDebugUIConstants.ID_EXTERNAL_TOOL_BUILDER_LAUNCH_CATEGORY)); |
| //need to force load the children so that select all works initially |
| fViewer.expandAll(); |
| fViewer.collapseAll(); |
| if (selectedElements != null) { |
| Object[] checkedElements = selectedElements.toArray(); |
| fViewer.setCheckedElements(checkedElements); |
| fViewer.setExpandedElements(checkedElements); |
| for (Object element : checkedElements) { |
| updateCheckedState(element); |
| } |
| } |
| fViewer.addCheckStateListener(new ICheckStateListener() { |
| @Override |
| public void checkStateChanged(CheckStateChangedEvent event) { |
| updateCheckedState(event.getElement()); |
| setPageComplete(isComplete()); |
| } |
| }); |
| Composite buttoncomp = SWTFactory.createComposite(parent, parent.getFont(), 2, 2, GridData.FILL_HORIZONTAL, 0, 0); |
| Button button = SWTFactory.createPushButton(buttoncomp, WizardMessages.ExportLaunchConfigurationsWizardPage_8, null); |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| Object[] items = fContentProvider.getElements(fViewer.getInput()); |
| for (int i = 0; i < items.length; i++) { |
| fViewer.setSubtreeChecked(items[i], true); |
| } |
| setPageComplete(isComplete()); |
| } |
| }); |
| button = SWTFactory.createPushButton(buttoncomp, WizardMessages.ExportLaunchConfigurationsWizardPage_9, null); |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| Object[] items = fContentProvider.getElements(fViewer.getInput()); |
| for (int i = 0; i < items.length; i++) { |
| fViewer.setSubtreeChecked(items[i], false); |
| } |
| setPageComplete(isComplete()); |
| } |
| }); |
| } |
| |
| /** |
| * Updates the checked state of child launch configurations if the parent type is checked |
| * @param item |
| */ |
| protected void updateCheckedState(Object element) { |
| boolean state = fViewer.getChecked(element); |
| if(element instanceof ILaunchConfigurationType) { |
| Object[] items = ((ConfigContentProvider)fViewer.getContentProvider()).getChildren(element); |
| for(int i = 0; i < items.length; i++) { |
| fViewer.setChecked(items[i], state); |
| } |
| fViewer.setGrayed(element, false); |
| } |
| else if(element instanceof ILaunchConfiguration) { |
| ConfigContentProvider ccp = (ConfigContentProvider) fViewer.getContentProvider(); |
| Object parent = ccp.getParent(element); |
| Object[] items = ccp.getChildren(parent); |
| boolean checked = true; |
| boolean onechecked = false; |
| for(int i = 0; i < items.length; i++) { |
| state = fViewer.getChecked(items[i]); |
| checked &= state; |
| if(state) { |
| onechecked = true; |
| } |
| } |
| fViewer.setGrayed(parent, onechecked & !checked); |
| fViewer.setChecked(parent, checked | onechecked); |
| } |
| } |
| |
| /** |
| * Creates the controls for the file path selection area of the page |
| * @param parent |
| */ |
| protected void createFilePath(Composite parent) { |
| Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 3, 2, GridData.FILL_HORIZONTAL, 0, 10); |
| SWTFactory.createLabel(comp, WizardMessages.ExportLaunchConfigurationsWizardPage_4, 1); |
| fFilePath = SWTFactory.createText(comp, SWT.SINGLE | SWT.BORDER, 1); |
| String opath = getDialogSettings().get(OLD_PATH); |
| fFilePath.setText((opath == null ? IInternalDebugCoreConstants.EMPTY_STRING : opath)); |
| fFilePath.addModifyListener(new ModifyListener() { |
| @Override |
| public void modifyText(ModifyEvent e) { |
| setPageComplete(isComplete()); |
| } |
| }); |
| Button button = SWTFactory.createPushButton(comp, WizardMessages.ExportLaunchConfigurationsWizardPage_0, null, GridData.END); |
| button.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| DirectoryDialog dd = new DirectoryDialog(getContainer().getShell(), SWT.SHEET); |
| dd.setText(WizardMessages.ExportLaunchConfigurationsWizard_0); |
| String file = dd.open(); |
| if(file != null) { |
| IPath path = new Path(file); |
| if (path != null) { |
| fFilePath.setText(path.toString()); |
| setPageComplete(isComplete()); |
| } |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Returns if the page is complete |
| * @return true if the page is complete and can be 'finished', false otherwise |
| */ |
| protected boolean isComplete() { |
| Object[] elements = fViewer.getCheckedElements(); |
| boolean oneconfig = false; |
| for(int i = 0; i < elements.length; i++) { |
| if(elements[i] instanceof ILaunchConfiguration) { |
| oneconfig = true; |
| break; |
| } |
| } |
| if(elements.length < 1 || !oneconfig) { |
| setErrorMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_5); |
| return false; |
| } |
| String path = fFilePath.getText().trim(); |
| if(path.equals(IInternalDebugCoreConstants.EMPTY_STRING)) { |
| setErrorMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_6); |
| return false; |
| } |
| if ((new File(path)).isFile()) { |
| setErrorMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_2); |
| return false; |
| } |
| setErrorMessage(null); |
| setMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_7); |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.wizard.WizardPage#getImage() |
| */ |
| @Override |
| public Image getImage() { |
| return DebugUITools.getImage(IInternalDebugUIConstants.IMG_WIZBAN_EXPORT_CONFIGS); |
| } |
| |
| /** |
| * This method performs the work of the page |
| * @return if the export job was successful or not |
| */ |
| public boolean finish() { |
| final String dpath = fFilePath.getText().trim(); |
| IDialogSettings settings = getDialogSettings(); |
| settings.put(OVERWRITE, fOverwrite.getSelection()); |
| settings.put(OLD_PATH, dpath); |
| final Object[] configs = fViewer.getCheckedElements(); |
| final boolean overwrite = fOverwrite.getSelection(); |
| UIJob exportjob = new UIJob(getContainer().getShell().getDisplay(), WizardMessages.ExportLaunchConfigurationsWizard_0) { |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| IProgressMonitor progressMonitor = monitor != null ? monitor : new NullProgressMonitor(); |
| IPath destpath = new Path(dpath); |
| File destfolder = destpath.toFile(); |
| if(!destfolder.exists()) { |
| destfolder.mkdirs(); |
| } |
| progressMonitor.beginTask(WizardMessages.ExportLaunchConfigurationsWizardPage_10, configs.length); |
| try { |
| List<IStatus> errors = null; |
| IFileStore file = null; |
| File newfile = null; |
| boolean owall = false, nowall = false; |
| MessageDialog dialog = null; |
| for(int i = 0; i < configs.length; i++) { |
| if (progressMonitor.isCanceled()) { |
| return Status.CANCEL_STATUS; |
| } |
| if(configs[i] instanceof ILaunchConfiguration) { |
| try { |
| LaunchConfiguration launchConfig = (LaunchConfiguration) configs[i]; |
| file = launchConfig.getFileStore(); |
| if (file == null) { |
| if (errors == null) { |
| errors = new ArrayList<>(configs.length); |
| } |
| errors.add(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), MessageFormat.format(WizardMessages.ExportLaunchConfigurationsWizardPage_19, new Object[] { launchConfig.getName() }), null)); |
| } else { |
| newfile = new File(destpath.append(file.getName()).toOSString()); |
| if(newfile.exists() & !overwrite) { |
| if(nowall) { |
| continue; |
| } |
| dialog = new MessageDialog(DebugUIPlugin.getShell(), WizardMessages.ExportLaunchConfigurationsWizardPage_11, null, MessageFormat.format(WizardMessages.ExportLaunchConfigurationsWizardPage_12, new Object[] { file.getName() }), MessageDialog.QUESTION, new String[] { |
| WizardMessages.ExportLaunchConfigurationsWizardPage_13, |
| WizardMessages.ExportLaunchConfigurationsWizardPage_14, |
| WizardMessages.ExportLaunchConfigurationsWizardPage_15, |
| WizardMessages.ExportLaunchConfigurationsWizardPage_16, |
| WizardMessages.ExportLaunchConfigurationsWizardPage_17 }, 0); |
| if(!owall) { |
| int ret = dialog.open(); |
| switch(ret) { |
| case 0: { |
| copyFile(file, newfile); |
| break; |
| } |
| case 1: { |
| owall = true; |
| copyFile(file, newfile); |
| break; |
| } |
| case 3: { |
| nowall = true; |
| break; |
| } |
| case 4: { |
| progressMonitor.setCanceled(true); |
| break; |
| } |
| default: |
| break; |
| } |
| } |
| else if(!nowall) { |
| copyFile(file, newfile); |
| } |
| } |
| else { |
| copyFile(file, newfile); |
| } |
| } |
| } |
| catch (IOException e ) { |
| if (errors == null) { |
| errors = new ArrayList<>(configs.length); |
| } |
| errors.add(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), |
| e.getMessage(), e)); |
| } |
| catch (CoreException e) { |
| if (errors == null) { |
| errors = new ArrayList<>(configs.length); |
| } |
| errors.add(e.getStatus()); |
| } |
| } |
| if (!progressMonitor.isCanceled()) { |
| progressMonitor.worked(1); |
| } |
| } |
| if (errors == null || errors.isEmpty()) { |
| return Status.OK_STATUS; |
| } else { |
| if (errors.size() == 1) { |
| return errors.get(0); |
| } else { |
| return new MultiStatus(DebugUIPlugin.getUniqueIdentifier(), 0, |
| errors.toArray(new IStatus[errors.size()]), |
| WizardMessages.ExportLaunchConfigurationsWizardPage_18, null); |
| } |
| } |
| } |
| finally { |
| progressMonitor.done(); |
| } |
| } |
| }; |
| exportjob.schedule(); |
| return true; |
| } |
| |
| /** |
| * Copies a file from one location to another |
| * @param in the file to copy |
| * @param out the file to be copied out to |
| * @throws Exception |
| * @since 3.5 |
| */ |
| protected void copyFile(IFileStore in, File out) throws CoreException, IOException { |
| try (BufferedInputStream is = new BufferedInputStream(in.openInputStream(EFS.NONE, null)); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(out))) { |
| byte[] buf = new byte[1024]; |
| int i = 0; |
| while ((i = is.read(buf)) != -1) { |
| os.write(buf, 0, i); |
| } |
| } |
| } |
| } |