diff options
author | Jeff Johnston | 2016-11-26 18:06:50 +0000 |
---|---|---|
committer | Jeff Johnston | 2016-11-29 00:59:50 +0000 |
commit | aad5e04522369411e91699392899d94e3789afda (patch) | |
tree | 291931ac581124fe3f59a397c0fb128406f41e39 | |
parent | 5a9eee6db475b7f2006c51fe311b61cbc990b636 (diff) | |
download | org.eclipse.linuxtools-aad5e04522369411e91699392899d94e3789afda.tar.gz org.eclipse.linuxtools-aad5e04522369411e91699392899d94e3789afda.tar.xz org.eclipse.linuxtools-aad5e04522369411e91699392899d94e3789afda.zip |
Bug 508233 - Fix copy from container
- add support to ContainerCopyFromPage when the container is stopped
to just add a text widget for specifying container directories
- fix CheckboxTreeAndListGroup to access children when new tree
entries show up (get children's children, then check the new
elements for white and gray listing
- also add new logic for finding the white list items which will
return a directory when the user has clicked the entire directory
- fix the logic in CopyFromContainerCommandHandler for reading
the tar file to handle directory (make directories and read
next entry, but read tar file for file entries)
- also switch to use org.apache.commons.compress for
TarArchiveInputStream
- add check for container being stopped to ContainerCopyFrom wizard
Change-Id: I9c616f62713977c609f12ff05f1976e00236fdc8
Reviewed-on: https://git.eclipse.org/r/85823
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
(cherry picked from commit 8b29f797012784dc8ad76031322a7e5f9c1fd21e)
Reviewed-on: https://git.eclipse.org/r/85904
7 files changed, 183 insertions, 65 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF b/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF index dbb3b1940f..91a1cd842c 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF +++ b/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF @@ -29,7 +29,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.e4.ui.model.workbench;bundle-version="1.2.0", org.eclipse.tm.terminal.view.ui;bundle-version="4.1.0", org.eclipse.tm.terminal.view.core;bundle-version="4.0.0", - com.ibm.icu + com.ibm.icu, + org.apache.commons.compress;bundle-version="1.6.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml index caaf5c2b05..c352c1ac0a 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml +++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml @@ -682,18 +682,11 @@ <instanceof value="org.eclipse.linuxtools.docker.core.IDockerContainer"> </instanceof> - <or> - <test - forcePluginActivation="true" - property="org.eclipse.linuxtools.docker.propertytesters.container.isStopped" - value="false"> - </test> - <test - forcePluginActivation="true" - property="org.eclipse.linuxtools.docker.propertytesters.container.isUnknown" - value="true"> - </test> - </or> + <test + forcePluginActivation="true" + property="org.eclipse.linuxtools.docker.propertytesters.container.isUnknown" + value="false"> + </test> </and> </iterate> </with> diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/CheckboxTreeAndListGroup.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/CheckboxTreeAndListGroup.java index 2c1991c1bb..f4ce27287e 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/CheckboxTreeAndListGroup.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/CheckboxTreeAndListGroup.java @@ -11,6 +11,7 @@ package org.eclipse.linuxtools.internal.docker.ui; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -202,6 +203,11 @@ public class CheckboxTreeAndListGroup extends EventManager implements treeViewer.setChecked(currentElement, checked); treeViewer.setGrayed(currentElement, checked && !whiteCheckedTreeItems.contains(currentElement)); + // New - if in white list, make sure all descendent elements are + // checked + if (whiteCheckedTreeItems.contains(currentElement)) { + setTreeChecked(currentElement, true); + } } } @@ -390,6 +396,55 @@ public class CheckboxTreeAndListGroup extends EventManager implements } /** + * Returns a list of all of the items that are white checked. Any folders + * that are white checked are added and then any files from white checked + * folders are added. + * + * @return the list of all of the items that are white checked + */ + public Iterator getAllWhiteCheckedItems() { + List result = new ArrayList(); + // Iterate through the children of the root as the root is not in the + // store + Object[] children = treeContentProvider.getChildren(root); + for (int i = 0; i < children.length; ++i) { + findAllWhiteCheckedItems(children[i], result); + } + return result.iterator(); + } + + /** + * Find all of the white checked children of the treeElement and add them to + * the collection. If the element itself is white select add it. If not then + * add any selected list elements and recurse down to the children. + * + * @param treeElement + * java.lang.Object + * @param result + * java.util.Collection + */ + @SuppressWarnings("unchecked") + private void findAllWhiteCheckedItems(Object treeElement, + Collection result) { + if (whiteCheckedTreeItems.contains(treeElement)) { + result.add(treeElement); + } else { + Collection listChildren = (Collection) checkedStateStore + .get(treeElement); + // if it is not in the store then it and it's children are not + // interesting + if (listChildren == null) { + return; + } + result.addAll(listChildren); + Object[] children = treeContentProvider.getChildren(treeElement); + for (int i = 0; i < children.length; ++i) { + findAllWhiteCheckedItems(children[i], result); + } + } + } + + /** * Answer a collection of all of the checked elements in the tree portion of * self * @@ -744,11 +799,11 @@ public class CheckboxTreeAndListGroup extends EventManager implements // already been realized then this won't be necessary if (!expandedTreeNodes.contains(item)) { expandedTreeNodes.add(item); - checkNewTreeElements(dynamicTreeContentProvider.getChildren(item)); - Object[] children = treeContentProvider.getElements(item); + Object[] children = treeContentProvider.getChildren(item); for (int i = 0; i < children.length; ++i) { dynamicTreeContentProvider.getElements(children[i]); } + checkNewTreeElements(dynamicTreeContentProvider.getChildren(item)); } } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java index 0161625439..ae71f8c892 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java @@ -15,6 +15,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.List; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.runtime.IPath; @@ -31,9 +33,6 @@ import org.eclipse.linuxtools.docker.ui.Activator; import org.eclipse.linuxtools.docker.ui.wizards.ImageSearch; import org.eclipse.linuxtools.internal.docker.core.ContainerFileProxy; import org.eclipse.linuxtools.internal.docker.core.DockerConnection; -import org.eclipse.linuxtools.internal.docker.ui.TarEntry; -import org.eclipse.linuxtools.internal.docker.ui.TarException; -import org.eclipse.linuxtools.internal.docker.ui.TarInputStream; import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerCopyFrom; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPart; @@ -110,31 +109,38 @@ public class CopyFromContainerCommandHandler extends AbstractHandler { COPY_FROM_CONTAINER_JOB_SUBTASK, proxy.getFullPath())); monitor.worked(1); - TarInputStream k = new TarInputStream( + TarArchiveInputStream k = new TarArchiveInputStream( ((DockerConnection) connection) .copyContainer(container.id(), proxy.getLink())); - TarEntry te = k.getNextEntry(); - long size = te.getSize(); - IPath path = new Path(target); - path = path.append(proxy.getName()); - File f = new File(path.toOSString()); - f.createNewFile(); - FileOutputStream os = new FileOutputStream(f); - if (size > 4096) - size = 4096; - byte[] barray = new byte[(int) size]; - while (k.read(barray) > 0) { - if (monitor.isCanceled()) { - monitor.done(); - k.close(); - os.close(); - return Status.CANCEL_STATUS; + TarArchiveEntry te = null; + while ((te = k.getNextTarEntry()) != null) { + long size = te.getSize(); + IPath path = new Path(target); + path = path.append(te.getName()); + File f = new File(path.toOSString()); + if (te.isDirectory()) { + f.mkdir(); + continue; + } else { + f.createNewFile(); } - os.write(barray); + FileOutputStream os = new FileOutputStream(f); + if (size > 4096) + size = 4096; + byte[] barray = new byte[(int) size]; + while (k.read(barray) > -1) { + if (monitor.isCanceled()) { + monitor.done(); + k.close(); + os.close(); + return Status.CANCEL_STATUS; + } + os.write(barray); + } + os.close(); } k.close(); - os.close(); } catch (final DockerException e) { Display.getDefault() .syncExec(() -> MessageDialog.openError( @@ -151,7 +157,7 @@ public class CopyFromContainerCommandHandler extends AbstractHandler { } } catch (InterruptedException e) { // do nothing - } catch (TarException | IOException e) { + } catch (IOException e) { Activator.log(e); } finally { monitor.done(); diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFrom.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFrom.java index b52d1d168f..698652da86 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFrom.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFrom.java @@ -17,6 +17,7 @@ import java.util.List; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.wizard.Wizard; +import org.eclipse.linuxtools.docker.core.EnumDockerStatus; import org.eclipse.linuxtools.docker.core.IDockerConnection; import org.eclipse.linuxtools.docker.core.IDockerContainer; import org.eclipse.linuxtools.docker.ui.Activator; @@ -64,8 +65,11 @@ public class ContainerCopyFrom extends Wizard { e.printStackTrace(); } + boolean isRunning = EnumDockerStatus.fromStatusMessage( + container.status()) == EnumDockerStatus.RUNNING; + mainPage = new ContainerCopyFromPage(sfo.getResult(), provider, - container.name()); + container.name(), isRunning); addPage(mainPage); } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFromPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFromPage.java index 27b4a64485..ae6172e3f1 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFromPage.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCopyFromPage.java @@ -11,6 +11,7 @@ package org.eclipse.linuxtools.internal.docker.ui.wizards; import java.io.File; +import java.util.ArrayList; import java.util.Iterator; import org.eclipse.jface.layout.GridDataFactory; @@ -19,6 +20,7 @@ import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.linuxtools.docker.ui.Activator; +import org.eclipse.linuxtools.internal.docker.core.ContainerFileProxy; import org.eclipse.linuxtools.internal.docker.ui.CheckboxTreeAndListGroup; import org.eclipse.linuxtools.internal.docker.ui.MinimizedFileSystemElement; import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory; @@ -64,7 +66,10 @@ public class ContainerCopyFromPage extends WizardPage { private final static String DESC = "ContainerCopyFrom.desc"; //$NON-NLS-1$ private static final String TARGET_LABEL = "ContainerCopyFrom.target.label"; //$NON-NLS-1$ private static final String TARGET_TOOLTIP = "ContainerCopyFrom.target.tooltip"; //$NON-NLS-1$ + private static final String SOURCE_LABEL = "ContainerCopyFrom.source.label"; //$NON-NLS-1$ + private static final String SOURCE_TOOLTIP = "ContainerCopyFrom.source.tooltip"; //$NON-NLS-1$ private static final String NO_TARGET_SPECIFIED = "ContainerCopyFrom.notarget.error"; //$NON-NLS-1$ + private static final String NO_SOURCE_SPECIFIED = "ContainerCopyFrom.nosource.error"; //$NON-NLS-1$ private static final String BROWSE_LABEL = "ContainerCopyFrom.browse.label"; //$NON-NLS-1$ // the root file representative to populate the viewer with @@ -72,10 +77,13 @@ public class ContainerCopyFromPage extends WizardPage { private IImportStructureProvider structureProvider; + private boolean isRunning; + // the visual selection widget group CheckboxTreeAndListGroup selectionGroup; private Text targetText; + private Text sourceText; private Button browseButton; private String target; @@ -98,7 +106,8 @@ public class ContainerCopyFromPage extends WizardPage { * - name of container */ public ContainerCopyFromPage(FileSystemElement fileSystemElement, - IImportStructureProvider structureProvider, String containerName) { + IImportStructureProvider structureProvider, String containerName, + boolean isRunning) { super(WizardMessages.getString(NAME)); setDescription(WizardMessages.getFormattedString(DESC, containerName)); @@ -106,6 +115,7 @@ public class ContainerCopyFromPage extends WizardPage { setImageDescriptor(SWTImagesFactory.DESC_WIZARD); root = fileSystemElement; this.structureProvider = structureProvider; + this.isRunning = isRunning; } @@ -119,13 +129,22 @@ public class ContainerCopyFromPage extends WizardPage { /* * Get an iterator for the selected items to copy */ - @SuppressWarnings("rawtypes") + @SuppressWarnings({ "rawtypes", "unchecked" }) public Iterator getValueIterator() { - // TODO: look at also returning all checked table items and - // remove files from that directory to shorten the - // time taken to copy (i.e. copy the whole directory - // at once). - return selectionGroup.getAllCheckedListItems(); + if (isRunning) { + return selectionGroup.getAllWhiteCheckedItems(); + } else { + // We need to fake a collection of MinimizedFileSystemElement with + // one element. + ArrayList out = new ArrayList(); + String sourceName = sourceText.getText(); + MinimizedFileSystemElement element = new MinimizedFileSystemElement( + sourceName, null, false); + element.setFileSystemObject( + new ContainerFileProxy(sourceName, "", false)); //$NON-NLS-1$ + out.add(element); + return out.iterator(); + } } private ModifyListener Listener = e -> validate(); @@ -146,8 +165,21 @@ public class ContainerCopyFromPage extends WizardPage { } } - if (selectionGroup.getCheckedElementCount() == 0) - complete = false; + if (!error) { + if (isRunning) { + if (selectionGroup.getCheckedElementCount() == 0) { + error = true; + setErrorMessage( + WizardMessages.getString(NO_SOURCE_SPECIFIED)); + } + } else { + if (sourceText.getText().length() == 0) { + error = true; + setErrorMessage( + WizardMessages.getString(NO_SOURCE_SPECIFIED)); + } + } + } if (!error) { target = targetText.getText(); @@ -192,31 +224,55 @@ public class ContainerCopyFromPage extends WizardPage { input.addChild(root); root.setParent(input); - Composite selectionComposite = new Composite(composite, SWT.NULL); - GridLayout selectionLayout = new GridLayout(); - selectionComposite.setLayout(selectionLayout); + Composite selectionComposite = null; + + if (isRunning) { + selectionComposite = new Composite(composite, SWT.NULL); + GridLayout selectionLayout = new GridLayout(); + selectionComposite.setLayout(selectionLayout); + + selectionGroup = new CheckboxTreeAndListGroup(selectionComposite, + input, getFolderProvider(), getDynamicFolderProvider(), + new WorkbenchLabelProvider(), getFileProvider(), + new WorkbenchLabelProvider(), SWT.NONE, + SIZING_SELECTION_WIDGET_WIDTH, // since this page has no + // other significantly-sized + SIZING_SELECTION_WIDGET_HEIGHT); // widgets we need to + // hardcode the combined + // widget's + // size, otherwise it will open too small + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(3, 1) + .grab(true, false).applyTo(selectionComposite); + } else { + Label sourceLabel = new Label(composite, SWT.NONE); + sourceLabel.setText(WizardMessages.getString(SOURCE_LABEL)); + + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) + .span(1, 1).grab(false, false).applyTo(sourceLabel); - selectionGroup = new CheckboxTreeAndListGroup(selectionComposite, input, - getFolderProvider(), getDynamicFolderProvider(), - new WorkbenchLabelProvider(), - getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE, - SIZING_SELECTION_WIDGET_WIDTH, // since this page has no other significantly-sized - SIZING_SELECTION_WIDGET_HEIGHT); // widgets we need to hardcode the combined widget's - // size, otherwise it will open too small + sourceText = new Text(composite, SWT.BORDER | SWT.SINGLE); + sourceText.addModifyListener(Listener); + sourceText.setToolTipText(WizardMessages.getString(SOURCE_TOOLTIP)); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(3, 1) - .grab(true, false).applyTo(selectionComposite); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1) + .grab(true, false).applyTo(sourceText); - WorkbenchViewerComparator comparator = new WorkbenchViewerComparator(); - selectionGroup.setTreeComparator(comparator); - selectionGroup.setListComparator(comparator); - selectionGroup.addCheckStateListener(CheckListener); + } + + if (isRunning) { + WorkbenchViewerComparator comparator = new WorkbenchViewerComparator(); + selectionGroup.setTreeComparator(comparator); + selectionGroup.setListComparator(comparator); + selectionGroup.addCheckStateListener(CheckListener); + } setControl(composite); validate(); setPageComplete(false); - selectionGroup.aboutToOpen(); + if (isRunning) { + selectionGroup.aboutToOpen(); + } } private SelectionListener onBrowseSelect() { diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties index 9143275867..08bb8f4a32 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties @@ -169,7 +169,10 @@ ContainerCopyFrom.title=Copy From Container ContainerCopyFrom.name=Copy From Container ContainerCopyFrom.target.label=Host Directory ContainerCopyFrom.target.tooltip=Specify a directory on host to copy files to +ContainerCopyFrom.source.label=Container Path +ContainerCopyFrom.source.tooltip=Specify a path in Container to copy file(s) from ContainerCopyFrom.notarget.error=A valid host directory must be specified +ContainerCopyFrom.nosource.error=At least one Container path must be specified ContainerCopyFrom.browse.label=Browse... ImageName.toolTip=Enter name for image (either REPOSITORY or REPOSITORY:TAG) |