From 3dcc9f514f1a79d197ed1f0083299cd9a83aaad9 Mon Sep 17 00:00:00 2001 From: William Chen Date: Thu, 24 Nov 2011 15:57:21 +0800 Subject: Target Explorer: Revision based on the feedbacks for bug #361324. --- .../org.eclipse.tcf.te.tcf.filesystem/plugin.xml | 163 ++++++++++++++--- .../tcf/te/tcf/filesystem/activator/UIPlugin.java | 2 - .../filesystem/controls/FSCellConfigurator.java | 86 --------- .../filesystem/controls/FSTreeContentProvider.java | 2 - .../te/tcf/filesystem/controls/FSTreeControl.java | 6 +- .../filesystem/controls/FSTreeLabelProvider.java | 2 - .../controls/FSViewerCellEditorFactory.java | 143 +++++++++++++++ .../dialogs/FSFolderSelectionDialog.java | 5 +- .../internal/adapters/NodeStateFilter.java | 2 - .../internal/celleditor/FSCellListener.java | 3 +- .../internal/celleditor/FSCellModifier.java | 3 +- .../internal/celleditor/FSCellValidator.java | 3 +- .../internal/compare/LocalFileSaveable.java | 9 +- .../internal/compare/MergeEditorInput.java | 9 +- .../filesystem/internal/compare/MergeInput.java | 9 +- .../internal/dnd/FSDragAdapterAssistant.java | 3 +- .../internal/dnd/FSDragSourceListener.java | 3 +- .../internal/dnd/FSDropAdapterAssistant.java | 99 +++++++---- .../internal/dnd/FSDropTargetListener.java | 60 +++++-- .../filesystem/internal/handlers/CacheManager.java | 11 +- .../internal/handlers/ClipboardPropertyTester.java | 39 ++-- .../internal/handlers/CopyFilesHandler.java | 3 +- .../filesystem/internal/handlers/CutDecorator.java | 3 +- .../internal/handlers/CutFilesHandler.java | 3 +- .../internal/handlers/CutImageDescriptor.java | 3 +- .../internal/handlers/DeleteFilesHandler.java | 3 +- .../EditorActivationEventPropertyTester.java | 42 +++++ .../handlers/FSTreeNodePropertyTester.java | 24 +-- .../internal/handlers/MoveFilesHandler.java | 3 +- .../internal/handlers/PasteFilesHandler.java | 61 ++++--- .../internal/handlers/PersistenceManager.java | 2 - .../internal/handlers/RefreshDirectoryHandler.java | 42 +++++ .../internal/handlers/RenameFilesHandler.java | 3 +- .../filesystem/internal/handlers/StateManager.java | 2 - .../filesystem/internal/handlers/UserManager.java | 2 - .../te/tcf/filesystem/internal/nls/Messages.java | 3 - .../filesystem/internal/nls/Messages.properties | 3 - .../internal/operations/FSClipboard.java | 16 +- .../tcf/filesystem/internal/operations/FSCopy.java | 122 +++++++------ .../filesystem/internal/operations/FSDelete.java | 92 +++++----- .../tcf/filesystem/internal/operations/FSMove.java | 111 ++++++------ .../internal/operations/FSOperation.java | 47 ++--- .../filesystem/internal/operations/FSRefresh.java | 145 +++++++++++++++ .../filesystem/internal/operations/FSRename.java | 14 +- .../preferences/PreferencesInitializer.java | 2 - .../preferences/TargetExplorerPreferencePage.java | 2 - .../tcf/te/tcf/filesystem/model/FSTreeNode.java | 2 - .../org.eclipse.tcf.te.ui.views/plugin.properties | 2 + .../plugins/org.eclipse.tcf.te.ui.views/plugin.xml | 2 +- .../schema/cellEditors.exsd | 197 +++++++++++++++++++++ .../schema/configurators.exsd | 135 -------------- .../views/interfaces/IViewerCellEditorFactory.java | 58 ++++++ .../ui/views/interfaces/IViewerConfigurator.java | 28 --- .../org/eclipse/tcf/te/ui/views/internal/View.java | 9 +- .../tcf/te/ui/views/internal/ViewViewer.java | 3 +- .../ui/views/internal/ViewViewerConfigurator.java | 87 --------- .../ViewViewerEditorActivationStrategy.java | 156 ++++++++++++++++ 57 files changed, 1340 insertions(+), 754 deletions(-) delete mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSViewerCellEditorFactory.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/EditorActivationEventPropertyTester.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RefreshDirectoryHandler.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/cellEditors.exsd delete mode 100644 target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerCellEditorFactory.java delete mode 100644 target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java delete mode 100644 target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerEditorActivationStrategy.java diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml index c5d83aeb5..46316ccc5 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml @@ -314,7 +314,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type="org.eclipse.jface.viewers.IStructuredSelection"> + + @@ -1420,26 +1477,17 @@ + value="+"> - - - - - - + + - - @@ -1557,6 +1605,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1634,11 +1731,31 @@ - + - - - + + + + + + + + + + + + + + + + + + diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java index 0c74b43e3..195381904 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java @@ -8,8 +8,6 @@ * Wind River Systems - initial API and implementation * William Chen (Wind River) - [345387] Open the remote files with a proper editor * William Chen (Wind River) - [345552] Edit the remote files with a proper editor - * William Chen (Wind River) - [361324] Add more file operations in the file system - * system of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.activator; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java deleted file mode 100644 index 27bca50e2..000000000 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Wind River Systems, 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: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. - *******************************************************************************/ -package org.eclipse.tcf.te.tcf.filesystem.controls; - -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnViewerEditor; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; -import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.TreeViewerEditor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellListener; -import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellModifier; -import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellValidator; -import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RenameFilesHandler; -import org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator; -import org.eclipse.ui.navigator.CommonViewer; - -/** - * FSCellConfigurator implements IViewerConfigurator to configure the - * editor for renaming in the file system tree of Target Explorer. - */ -public class FSCellConfigurator implements IViewerConfigurator { - /* - * (non-Javadoc) - * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator#configure(org.eclipse.ui.navigator.CommonViewer) - */ - @Override - public void configure(final CommonViewer viewer) { - addEditingSupport(viewer); - } - - /** - * Add the editing support for the specified tree viewer with those editing assistants which - * have the specified viewId. - * - * @param viewer The tree viewer to which the editing support is added. - */ - static void addEditingSupport(final TreeViewer viewer) { - // Define an editor activation strategy for the common viewer so as to be invoked only programmatically. - ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(viewer) { - @Override - protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { - // Activated only when a single node is selected and invoked programmatically. - boolean singleSelect = ((IStructuredSelection) viewer.getSelection()).size() == 1; - return singleSelect && (event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC); - } - }; - TreeViewerEditor.create(viewer, null, activationStrategy, ColumnViewerEditor.DEFAULT); - - // Set the column properties, the cell editor, and the modifier. - viewer.setColumnProperties(new String[] { FSCellModifier.PROPERTY_NAME }); - TextCellEditor cellEditor = new TextCellEditor((Composite) viewer.getControl(), SWT.BORDER); - cellEditor.setValidator(new FSCellValidator(viewer)); - cellEditor.addListener(new FSCellListener(cellEditor)); - viewer.setCellEditors(new CellEditor[] { cellEditor }); - viewer.setCellModifier(new FSCellModifier()); - - // Trace the currently focused tree viewer. - Control control = viewer.getControl(); - control.addFocusListener(new FocusListener() { - @Override - public void focusGained(FocusEvent e) { - RenameFilesHandler.setCurrentViewer(viewer); - } - - @Override - public void focusLost(FocusEvent e) { - } - }); - } -} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java index 04ae0cef2..2dcb2c04e 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java @@ -6,8 +6,6 @@ * * Contributors: * Wind River Systems - initial API and implementation - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.controls; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java index cf81f63c4..fe3599c68 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java @@ -7,8 +7,6 @@ * Contributors: * Wind River Systems - initial API and implementation * William Chen (Wind River) - [345384] Provide property pages for remote file system nodes - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.controls; @@ -108,12 +106,12 @@ public class FSTreeControl extends AbstractTreeControl implements ISelectionChan tree.setHeaderVisible(hasColumns()); viewer.addDoubleClickListener(this); //Add DnD support. - int operations = DND.DROP_MOVE; + int operations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; Transfer[] transferTypes = {LocalSelectionTransfer.getTransfer()}; viewer.addDragSupport(operations, transferTypes, new FSDragSourceListener(viewer)); viewer.addDropSupport(operations, transferTypes, new FSDropTargetListener(viewer)); // Add editing support to rename files/folders. - FSCellConfigurator.addEditingSupport(viewer); + new FSViewerCellEditorFactory().addEditingSupport(viewer); } /** diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java index dd934bc1b..3686fae8c 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java @@ -6,8 +6,6 @@ * * Contributors: * Wind River Systems - initial API and implementation - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.controls; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSViewerCellEditorFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSViewerCellEditorFactory.java new file mode 100644 index 000000000..26200d203 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSViewerCellEditorFactory.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.filesystem.controls; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellListener; +import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellModifier; +import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellValidator; +import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RenameFilesHandler; +import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; +import org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory; + +/** + * FSViewerCellEditorFactory implements IViewerCellEditorFactory to add + * cell editors to Target Explorer for renaming files or folders in the file system tree viewer. + */ +public class FSViewerCellEditorFactory implements IViewerCellEditorFactory, FocusListener { + // The column properties used for cell editing. + private static String[] COLUMN_PROPERTIES = { FSCellModifier.PROPERTY_NAME }; + // The tree viewer to add cell editing. + private TreeViewer viewer; + // The cell editors used to rename a file/folder. + private CellEditor[] cellEditors; + // The cell modifier used to modify a file/folder's name. + private ICellModifier cellModifer; + + /** + * Create an instance. + */ + public FSViewerCellEditorFactory() { + } + + /** + * Add the editing support for the specified tree viewer using the cell editing configuration + * from this factory. + * + * @param viewer The tree viewer to which the editing support is added. + */ + public void addEditingSupport(final TreeViewer viewer) { + // Initialize the tree viewer. + init(viewer); + // Define an editor activation strategy for the common viewer so as to be invoked only programmatically. + ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(viewer) { + @Override + protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { + // Activated only when a single FSTreeNode is selected and invoked programmatically. + IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); + boolean singleSelect = selection.size() == 1; + if(singleSelect && event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC){ + Object object = selection.getFirstElement(); + return object instanceof FSTreeNode; + } + return false; + } + }; + TreeViewerEditor.create(viewer, null, activationStrategy, ColumnViewerEditor.DEFAULT); + + // Set the column properties, the cell editor, and the modifier. + viewer.setColumnProperties(getColumnProperties()); + viewer.setCellEditors(getCellEditors()); + viewer.setCellModifier(getCellModifier()); + } + + /* + * (non-Javadoc) + * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#init(org.eclipse.jface.viewers.TreeViewer) + */ + @Override + public void init(TreeViewer aViewer) { + viewer = aViewer; + TextCellEditor cellEditor = new TextCellEditor(aViewer.getTree(), SWT.BORDER); + cellEditor.setValidator(new FSCellValidator(aViewer)); + cellEditor.addListener(new FSCellListener(cellEditor)); + cellEditors = new CellEditor[] { cellEditor }; + cellModifer = new FSCellModifier(); + Tree tree = aViewer.getTree(); + tree.addFocusListener(this); + } + + /* + * (non-Javadoc) + * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#getCellEditors() + */ + @Override + public CellEditor[] getCellEditors() { + return cellEditors; + } + + /* + * (non-Javadoc) + * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#getCellModifier() + */ + @Override + public ICellModifier getCellModifier() { + return cellModifer; + } + + /* + * (non-Javadoc) + * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#getColumnProperties() + */ + @Override + public String[] getColumnProperties() { + return COLUMN_PROPERTIES; + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) + */ + @Override + public void focusGained(FocusEvent e) { + // Set the currently focused viewer. + RenameFilesHandler.setCurrentViewer(viewer); + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) + */ + @Override + public void focusLost(FocusEvent e) { + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java index 9f9ca52df..b891e9a16 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.dialogs; @@ -146,6 +145,8 @@ public class FSFolderSelectionDialog extends ElementTreeSelectionDialog { return error; } } + if(!target.isWritable()) + return error; return new Status(IStatus.OK, pluginId, null); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java index d7c38a760..e1580da64 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java @@ -7,8 +7,6 @@ * Contributors: * Wind River Systems - initial API and implementation * William Chen (Wind River)- [345552] Edit the remote files with a proper editor - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.adapters; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java index 1cbc83dd0..3d40a3d55 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.celleditor; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java index ead56eb8a..3a8c56b0d 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.celleditor; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java index a12db0f47..85239a15d 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.celleditor; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/LocalFileSaveable.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/LocalFileSaveable.java index d45b7936d..a84edc021 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/LocalFileSaveable.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/LocalFileSaveable.java @@ -20,7 +20,6 @@ import org.eclipse.compare.contentmergeviewer.ContentMergeViewer; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; @@ -29,6 +28,7 @@ import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.util.SafeRunnable; import org.eclipse.swt.graphics.Image; import org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener; import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CacheManager; @@ -462,17 +462,12 @@ public class LocalFileSaveable extends Saveable implements Object[] allListeners = listeners.getListeners(); for (int i = 0; i < allListeners.length; i++) { final Object object = allListeners[i]; - SafeRunner.run(new ISafeRunnable() { + SafeRunner.run(new SafeRunnable() { @Override public void run() throws Exception { ((IPropertyListener) object).propertyChanged( LocalFileSaveable.this, property); } - - @Override - public void handleException(Throwable exception) { - // handled by platform - } }); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java index bd2ca22ab..afc35afb3 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java @@ -20,10 +20,10 @@ import org.eclipse.compare.structuremergeviewer.ICompareInput; import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.Viewer; import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.TextProcessor; @@ -254,16 +254,11 @@ public class MergeEditorInput extends CompareEditorInput implements Object[] allListeners = inputChangeListeners.getListeners(); for (int i = 0; i < allListeners.length; i++) { final ICompareInputChangeListener listener = (ICompareInputChangeListener) allListeners[i]; - SafeRunner.run(new ISafeRunnable() { + SafeRunner.run(new SafeRunnable() { @Override public void run() throws Exception { listener.compareInputChanged(getCompareResult()); } - - @Override - public void handleException(Throwable exception) { - // Logged by the safe runner - } }); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java index 12647fd7b..2f599257f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java @@ -15,9 +15,9 @@ import org.eclipse.compare.structuremergeviewer.Differencer; import org.eclipse.compare.structuremergeviewer.ICompareInput; import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener; import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; import org.eclipse.swt.graphics.Image; import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; @@ -69,16 +69,11 @@ public class MergeInput implements ICompareInput { Object[] _listeners = listeners.getListeners(); for (int i = 0; i < _listeners.length; i++) { final ICompareInputChangeListener listener = (ICompareInputChangeListener) _listeners[i]; - SafeRunner.run(new ISafeRunnable() { + SafeRunner.run(new SafeRunnable() { @Override public void run() throws Exception { listener.compareInputChanged(MergeInput.this); } - - @Override - public void handleException(Throwable exception) { - // Logged by the safe runner - } }); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java index 5cd526589..b49810965 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.dnd; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java index f14644612..3a6a6d578 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.dnd; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java index 702aba18d..e46483e48 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.dnd; @@ -19,9 +18,9 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TransferData; -import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; -import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; +import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSCopy; import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove; +import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; import org.eclipse.ui.navigator.CommonDropAdapter; import org.eclipse.ui.navigator.CommonDropAdapterAssistant; @@ -42,10 +41,32 @@ public class FSDropAdapterAssistant extends CommonDropAdapterAssistant { */ @Override public IStatus validateDrop(Object target, int operation, TransferData transferType) { - if (validateDropping(target, operation, transferType)) { - return Status.OK_STATUS; + LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer(); + if (transfer.isSupportedType(transferType) && target instanceof FSTreeNode) { + FSTreeNode hovered = (FSTreeNode) target; + IStructuredSelection selection = (IStructuredSelection) transfer.getSelection(); + List nodes = selection.toList(); + boolean moving = (operation & DND.DROP_MOVE) != 0; + boolean copying = (operation & DND.DROP_COPY) != 0; + if (hovered.isDirectory() && hovered.isWritable() && (moving || copying)) { + FSTreeNode head = nodes.get(0); + String hid = head.peerNode.getPeer().getID(); + String tid = hovered.peerNode.getPeer().getID(); + if (hid.equals(tid)) { + for (FSTreeNode node : nodes) { + if (moving && node == hovered || node.isAncestorOf(hovered)) { + return Status.CANCEL_STATUS; + } + } + return Status.OK_STATUS; + } + } + else if (hovered.isFile() && copying) { + hovered = hovered.parent; + return validateDrop(hovered, operation, transferType); + } } - return new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), Messages.FSTreeNodeDropAdapterAssistant_DragError); + return Status.CANCEL_STATUS; } /* @@ -55,43 +76,43 @@ public class FSDropAdapterAssistant extends CommonDropAdapterAssistant { @Override public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget) { Object data = aDropTargetEvent.data; - FSTreeNode dest = (FSTreeNode) aTarget; + int operations = aDropAdapter.getCurrentOperation(); IStructuredSelection selection = (IStructuredSelection) data; List nodes = selection.toList(); - FSMove move = new FSMove(nodes, dest); - return move.doit() ? Status.OK_STATUS : new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), Messages.FSTreeNodeDropAdapterAssistant_MoveFailure); + FSOperation operation = null; + if ((operations & DND.DROP_MOVE) != 0) { + FSTreeNode dest = (FSTreeNode) aTarget; + operation = new FSMove(nodes, dest); + } + else if ((operations & DND.DROP_COPY) != 0) { + FSTreeNode hovered = (FSTreeNode) aTarget; + FSTreeNode dest = getCopyDestination(hovered, nodes); + operation = new FSCopy(nodes, dest); + } + return (operation != null && operation.doit()) ? Status.OK_STATUS : Status.CANCEL_STATUS; } - - /** - * Validates dropping on the given object. - * - * @param target the object that the mouse is currently hovering over, or - * null if the mouse is hovering over empty space - * @param operation the current drag operation (copy, move, etc.) - * @param transferType the current transfer type - * @return true if the drop is valid, and false - * otherwise - */ - private boolean validateDropping(Object target, int operation, TransferData transferType) { - LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer(); - if (target != null && transfer.isSupportedType(transferType) && operation == DND.DROP_MOVE && target instanceof FSTreeNode) { - FSTreeNode hovered = (FSTreeNode) target; - if (hovered.isDirectory()) { - IStructuredSelection selection = (IStructuredSelection) transfer.getSelection(); - List nodes = selection.toList(); - FSTreeNode head = nodes.get(0); - String hid = head.peerNode.getPeer().getID(); - String tid = hovered.peerNode.getPeer().getID(); - if (hid.equals(tid)) { - for (FSTreeNode node : nodes) { - if (node == hovered || node.isAncestorOf(hovered)) { - return false; - } - } - return true; + + /** + * Return an appropriate destination directory for copying according to + * the specified hovered node. If the hovered node is a file, then return + * its parent directory. If the hovered node is a directory, then return its + * self if it is not a node being copied. Return its parent directory if it is + * a node being copied. + * @param hovered + * @param nodes + * @return + */ + private FSTreeNode getCopyDestination(FSTreeNode hovered, List nodes) { + if (hovered.isFile()) { + return hovered.parent; + } + else if (hovered.isDirectory()) { + for (FSTreeNode node : nodes) { + if (node == hovered) { + return hovered.parent; } } } - return false; + return hovered; } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java index 5e6136879..c9d1b685c 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.dnd; @@ -18,7 +17,9 @@ import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerDropAdapter; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.TransferData; +import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSCopy; import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove; +import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; /** @@ -41,23 +42,29 @@ public class FSDropTargetListener extends ViewerDropAdapter { @Override public boolean validateDrop(Object target, int operation, TransferData transferType) { LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer(); - if (target != null && transfer.isSupportedType(transferType) && operation == DND.DROP_MOVE && target instanceof FSTreeNode) { + if (transfer.isSupportedType(transferType) && target instanceof FSTreeNode) { FSTreeNode hovered = (FSTreeNode) target; - if (hovered.isDirectory()) { - IStructuredSelection selection = (IStructuredSelection) transfer.getSelection(); - List nodes = selection.toList(); + IStructuredSelection selection = (IStructuredSelection) transfer.getSelection(); + List nodes = selection.toList(); + boolean moving = (operation & DND.DROP_MOVE) != 0; + boolean copying = (operation & DND.DROP_COPY) != 0; + if (hovered.isDirectory() && hovered.isWritable() && (moving || copying)) { FSTreeNode head = nodes.get(0); String hid = head.peerNode.getPeer().getID(); String tid = hovered.peerNode.getPeer().getID(); if (hid.equals(tid)) { for (FSTreeNode node : nodes) { - if (node == hovered || node.isAncestorOf(hovered)) { + if (moving && node == hovered || node.isAncestorOf(hovered)) { return false; } } return true; } } + else if (hovered.isFile() && copying) { + hovered = hovered.parent; + return validateDrop(hovered, operation, transferType); + } } return false; } @@ -69,10 +76,43 @@ public class FSDropTargetListener extends ViewerDropAdapter { @Override public boolean performDrop(Object data) { Object aTarget = getCurrentTarget(); - FSTreeNode dest = (FSTreeNode) aTarget; + int operations = getCurrentOperation(); IStructuredSelection selection = (IStructuredSelection) data; List nodes = selection.toList(); - FSMove move = new FSMove(nodes, dest); - return move.doit(); + FSOperation operation = null; + if ((operations & DND.DROP_MOVE) != 0) { + FSTreeNode dest = (FSTreeNode) aTarget; + operation = new FSMove(nodes, dest); + } + else if ((operations & DND.DROP_COPY) != 0) { + FSTreeNode hovered = (FSTreeNode) aTarget; + FSTreeNode dest = getCopyDestination(hovered, nodes); + operation = new FSCopy(nodes, dest); + } + return (operation != null && operation.doit()) ; + } + + /** + * Return an appropriate destination directory for copying according to + * the specified hovered node. If the hovered node is a file, then return + * its parent directory. If the hovered node is a directory, then return its + * self if it is not a node being copied. Return its parent directory if it is + * a node being copied. + * @param hovered + * @param nodes + * @return + */ + private FSTreeNode getCopyDestination(FSTreeNode hovered, List nodes) { + if (hovered.isFile()) { + return hovered.parent; + } + else if (hovered.isDirectory()) { + for (FSTreeNode node : nodes) { + if (node == hovered) { + return hovered.parent; + } + } + } + return hovered; } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java index 9fbab82fa..48a75bac5 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java @@ -8,8 +8,6 @@ * Wind River Systems - initial API and implementation * William Chen (Wind River)- [345387] Open the remote files with a proper editor * William Chen (Wind River)- [345552] Edit the remote files with a proper editor - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; @@ -27,11 +25,11 @@ import java.text.DecimalFormat; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.util.SafeRunnable; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; @@ -384,12 +382,7 @@ public class CacheManager { if(!monitor.isCanceled()){ // Once upload is successful, synchronize the modified time. final FSTreeNode node = nodes[i]; - SafeRunner.run(new ISafeRunnable() { - @Override - public void handleException(Throwable exception) { - // Just ignore it. - } - + SafeRunner.run(new SafeRunnable() { @Override public void run() throws Exception { StateManager.getInstance().updateState(node); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java index 389d3bfec..c37e75a06 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java @@ -5,18 +5,17 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; -import java.net.URL; import java.util.List; import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard; -import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; /** * Provide a tester to test if the paste operation is enabled. @@ -35,29 +34,33 @@ public class ClipboardPropertyTester extends PropertyTester { */ @Override public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + Assert.isTrue(receiver instanceof IStructuredSelection); if (property.equals("canPaste")) { //$NON-NLS-1$ FSClipboard cb = UIPlugin.getDefault().getClipboard(); if (!cb.isEmpty()) { + List nodes = cb.getTreeNodes(); int operation = cb.getOperation(); - List urls = cb.getFiles(); - for (URL url : urls) { - FSTreeNode node = FSModel.getInstance().getTreeNode(url); - if (node != null) { - if (operation == FSClipboard.COPY) { - // If it is not a windows node and it is not readable, - // then it cannot be moved. - if (!node.isWindowsNode() && !node.isReadable()) return false; - } - else if (operation == FSClipboard.CUT) { - // If it is a windows node and is read only, or it is not - // a windows node and is not writable, then it cannot be moved. - if (node.isWindowsNode() && node.isReadOnly() || !node.isWindowsNode() && !node.isWritable()) { + boolean moving = operation == FSClipboard.CUT; + boolean copying = operation == FSClipboard.COPY; + List selection = ((IStructuredSelection) receiver).toList(); + FSTreeNode hovered = null; + for (FSTreeNode node : selection) { + if (hovered == null) hovered = node.parent; + else if (hovered != node.parent) return false; + } + if (hovered.isDirectory() && hovered.isWritable() && (moving || copying)) { + FSTreeNode head = nodes.get(0); + String hid = head.peerNode.getPeer().getID(); + String tid = hovered.peerNode.getPeer().getID(); + if (hid.equals(tid)) { + for (FSTreeNode node : nodes) { + if (moving && node.parent == hovered || node.isAncestorOf(hovered)) { return false; } } + return true; } } - return true; } } return false; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java index bb70e169f..23a7c21e3 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java index 7063fce46..327b03f59 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java index 4c22b616f..d82deed03 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java index f4410831e..12da3c772 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java index e5283de7e..7e9a57155 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/EditorActivationEventPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/EditorActivationEventPropertyTester.java new file mode 100644 index 000000000..f450dfb1e --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/EditorActivationEventPropertyTester.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; + +/** + * The property tester of a ColumnViewerEditorActivationEvent. + * The properties include "isEditorActivation" which calculates + * if the event will trigger a cell editing action. + */ +public class EditorActivationEventPropertyTester extends PropertyTester { + + /** + * Create an instance. + */ + public EditorActivationEventPropertyTester() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object) + */ + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + Assert.isTrue(receiver instanceof ColumnViewerEditorActivationEvent); + ColumnViewerEditorActivationEvent event = (ColumnViewerEditorActivationEvent) receiver; + if (property.equals("isEditorActivation")) { //$NON-NLS-1$ + return event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC; + } + return false; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java index c915a6c1d..eb63143a6 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java @@ -9,21 +9,14 @@ * William Chen (Wind River) - [345387]Open the remote files with a proper editor * William Chen (Wind River) - [352302]Opening a file in an editor depending on * the client's permissions. - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; import java.io.File; -import java.net.URL; -import java.util.List; import org.eclipse.core.expressions.PropertyTester; import org.eclipse.core.runtime.Assert; -import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; -import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard; import org.eclipse.tcf.te.tcf.filesystem.model.CacheState; -import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; /** @@ -33,8 +26,7 @@ import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; * it is writable, "isExecutable" if it is executable, "isRoot" if it is a * root directory, "isWindows" if it is a windows file node, "isReadOnly" * if it is read only, "isHidden" if it is hidden, "getCacheState" to - * get a node's state, and "isSamePeer" to test if the selected folder is - * from the same peer with the files in the clip board. + * get a node's state. */ public class FSTreeNodePropertyTester extends PropertyTester { @@ -71,20 +63,6 @@ public class FSTreeNodePropertyTester extends PropertyTester { return false; CacheState state = StateManager.getInstance().getCacheState(node); return state.name().equals(expectedValue); - } else if (property.equals("isSamePeer")) { //$NON-NLS-1$ - String id = node.peerNode.getPeer().getID(); - FSClipboard cb = UIPlugin.getDefault().getClipboard(); - if (!cb.isEmpty()) { - List urls = cb.getFiles(); - for (URL url : urls) { - FSTreeNode clipped = FSModel.getInstance().getTreeNode(url); - String cid = clipped.peerNode.getPeer().getID(); - if(!id.equals(cid)){ - return false; - } - } - return true; - } } return false; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java index f4b452fbe..b5e394335 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java index f48ec1b65..6b577eefd 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java @@ -5,13 +5,10 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; -import java.net.URL; -import java.util.ArrayList; import java.util.List; import org.eclipse.core.commands.AbstractHandler; @@ -23,9 +20,9 @@ import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard; import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSCopy; import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove; import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation; -import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; import org.eclipse.ui.handlers.HandlerUtil; + /** * The handler that pastes the files or folders in the clip board. */ @@ -33,35 +30,53 @@ public class PasteFilesHandler extends AbstractHandler { /* * (non-Javadoc) - * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent) + * @see + * org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { FSClipboard cb = UIPlugin.getDefault().getClipboard(); if (!cb.isEmpty()) { // Get the files/folders from the clip board. - List nodes = new ArrayList(); - List files = cb.getFiles(); - for (URL file : files) { - FSTreeNode node = FSModel.getInstance().getTreeNode(file); - nodes.add(node); - } - // Get the destination folder. + int operations = cb.getOperation(); IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event); - FSTreeNode dest = (FSTreeNode) selection.getFirstElement(); - int operation = cb.getOperation(); - FSOperation fsop; - if (operation == FSClipboard.COPY) { - // Copy action. - fsop = new FSCopy(nodes, dest); + List nodes = cb.getTreeNodes(); + FSOperation operation = null; + if (operations == FSClipboard.CUT) { + FSTreeNode dest = (FSTreeNode) selection.getFirstElement(); + operation = new FSMove(nodes, dest); } - else { - // Cut action. - fsop = new FSMove(nodes, dest); + else if (operations == FSClipboard.COPY) { + FSTreeNode hovered = (FSTreeNode) selection.getFirstElement(); + FSTreeNode dest = getCopyDestination(hovered, nodes); + operation = new FSCopy(nodes, dest); } - fsop.doit(); + if (operation != null) operation.doit(); } return null; } + /** + * Return an appropriate destination directory for copying according to + * the specified hovered node. If the hovered node is a file, then return + * its parent directory. If the hovered node is a directory, then return its + * self if it is not a node being copied. Return its parent directory if it is + * a node being copied. + * @param hovered + * @param nodes + * @return + */ + private FSTreeNode getCopyDestination(FSTreeNode hovered, List nodes) { + if (hovered.isFile()) { + return hovered.parent; + } + else if (hovered.isDirectory()) { + for (FSTreeNode node : nodes) { + if (node == hovered) { + return hovered.parent; + } + } + } + return hovered; + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java index fa9015259..4f3f1a371 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java @@ -7,8 +7,6 @@ * Contributors: * William Chen (Wind River) [360494]Provide an "Open With" action in the pop * up menu of file system nodes of Target Explorer. - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RefreshDirectoryHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RefreshDirectoryHandler.java new file mode 100644 index 000000000..82a0d96d8 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RefreshDirectoryHandler.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSRefresh; +import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * The handler that refreshes the directory and its children recursively + * in the file system tree. + */ +public class RefreshDirectoryHandler extends AbstractHandler { + + /* + * (non-Javadoc) + * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent) + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event); + Assert.isTrue(selection.size() == 1); + FSTreeNode node = (FSTreeNode) selection.getFirstElement(); + if(node.childrenQueried) { + FSRefresh refresh = new FSRefresh(node); + refresh.doit(); + } + return null; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java index a4b9d1368..9e416d26f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java index ede34d842..ba6a4f4ce 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java @@ -7,8 +7,6 @@ * Contributors: * Wind River Systems - initial API and implementation * William Chen (Wind River)- [345552] Edit the remote files with a proper editor - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java index c57926f84..88b082394 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java @@ -7,8 +7,6 @@ * Contributors: * Wind River Systems - initial API and implementation * William Chen (Wind River)- [345552] Edit the remote files with a proper editor - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.handlers; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java index 6965b4306..cde34aea0 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java @@ -158,9 +158,6 @@ public class Messages extends NLS { public static String FSTreeControl_column_size_label; public static String FSTreeControl_column_modified_label; - public static String FSTreeNodeDropAdapterAssistant_DragError; - public static String FSTreeNodeDropAdapterAssistant_MoveFailure; - public static String FSTreeNodeDropAdapterAssistant_NoFileSelected; public static String FSOpenFileDialog_title; public static String FSOperation_CopyNOfFile; public static String FSOperation_CopyOfFile; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties index 2a90699db..e8051f3dc 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties @@ -10,9 +10,6 @@ FSFolderSelectionDialog_MoveDialogTitle=Move Files and Folders FSTreeControl_column_name_label=Name FSTreeControl_column_size_label=Size FSTreeControl_column_modified_label=Date Modified -FSTreeNodeDropAdapterAssistant_DragError=Cannot drag to itself you its ancestor\! -FSTreeNodeDropAdapterAssistant_MoveFailure=Moving failed\! -FSTreeNodeDropAdapterAssistant_NoFileSelected=No file is selected yet\! FSOpenFileDialog_title=Select Process Image FSOperation_CopyNOfFile=Copy ({0}) of {1} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java index 4f36d32e6..922addd39 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java @@ -5,14 +5,17 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.operations; import java.net.URL; +import java.util.ArrayList; import java.util.List; +import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; +import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; + /** * The clip board to which copy or cut files/folders. */ @@ -87,4 +90,13 @@ public class FSClipboard { operation = NONE; this.files = null; } + + public List getTreeNodes() { + List nodes = new ArrayList(); + for (URL file : files) { + FSTreeNode node = FSModel.getInstance().getTreeNode(file); + nodes.add(node); + } + return nodes; + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java index 7f2b5df13..94793d607 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.operations; @@ -143,30 +142,46 @@ public class FSCopy extends FSOperation { * @throws InterruptedException The exception thrown when the operation is canceled. */ private void copyFolder(IProgressMonitor monitor, IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException { - if (!monitor.isCanceled()) { - FSTreeNode copy = findChild(service, dest, node.name); - if (copy == null || confirmReplace(node)) { - if (copy == null) { - // If no existing directory with the same name, create it. - copy = (FSTreeNode) node.clone(); - addChild(service, dest, copy); - mkdir(service, copy); - } - List children = new ArrayList(getChildren(node, service)); - if (!children.isEmpty()) { - for (FSTreeNode child : children) { - // Iterate and copy its children nodes. - copyNode(monitor, service, child, copy); - } - } - } - monitor.worked(1); + if (monitor.isCanceled()) throw new InterruptedException(); + FSTreeNode copy = findChild(service, dest, node.name); + if (copy == null) { + // If no existing directory with the same name, create it. + copy = (FSTreeNode) node.clone(); + addChild(service, dest, copy); + mkdir(service, copy); + copyChildren(monitor, service, node, copy); + } + else if (node == copy) { + copy = createCopyDestination(service, node, dest); + mkdir(service, copy); + copyChildren(monitor, service, node, copy); } - else { - throw new InterruptedException(); + else if (confirmReplace(node)) { + copyChildren(monitor, service, node, copy); } + monitor.worked(1); } + /** + * Copy the children of the node to the destination folder. + * + * @param monitor The monitor to report the progress. + * @param service The file system service to do the remote copying. + * @param node The folder node to be copied. + * @param dest The destination folder. + * @throws TCFFileSystemException The exception thrown during copying + * @throws InterruptedException The exception thrown when the operation is canceled. + */ + private void copyChildren(IProgressMonitor monitor, IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException { + List children = new ArrayList(getChildren(node, service)); + if (!children.isEmpty()) { + for (FSTreeNode child : children) { + // Iterate and copy its children nodes. + copyNode(monitor, service, child, dest); + } + } + } + /** * Copy the file represented by the specified node to the destination folder. * @@ -178,43 +193,38 @@ public class FSCopy extends FSOperation { * @throws InterruptedException The exception thrown when the operation is canceled. */ private void copyFile(IProgressMonitor monitor, IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException { - if (!monitor.isCanceled()) { - monitor.subTask(NLS.bind(Messages.FSCopy_Copying, node.name)); - // Create the copy target file - final FSTreeNode copy = createCopyFile(service, node, dest); - String src_path = node.getLocation(true); - String dst_path = copy.getLocation(true); - final TCFFileSystemException[] errors = new TCFFileSystemException[1]; - final Rendezvous rendezvous = new Rendezvous(); - // Get the options of copy permission and ownership. - boolean copyPermission = PersistenceManager.getInstance().isCopyPermission(); - boolean copyOwnership = PersistenceManager.getInstance().isCopyOwnership(); - service.copy(src_path, dst_path, copyPermission, copyOwnership, new DoneCopy() { - @Override - public void doneCopy(IToken token, FileSystemException error) { - if (error != null) { - String message = NLS.bind(Messages.FSCopy_CannotCopyFile, copy.name, error); - errors[0] = new TCFFileSystemException(message, error); - } - rendezvous.arrive(); + if (monitor.isCanceled()) throw new InterruptedException(); + monitor.subTask(NLS.bind(Messages.FSCopy_Copying, node.name)); + // Create the copy target file + final FSTreeNode copy = createCopyDestination(service, node, dest); + String src_path = node.getLocation(true); + String dst_path = copy.getLocation(true); + final TCFFileSystemException[] errors = new TCFFileSystemException[1]; + final Rendezvous rendezvous = new Rendezvous(); + // Get the options of copy permission and ownership. + boolean copyPermission = PersistenceManager.getInstance().isCopyPermission(); + boolean copyOwnership = PersistenceManager.getInstance().isCopyOwnership(); + service.copy(src_path, dst_path, copyPermission, copyOwnership, new DoneCopy() { + @Override + public void doneCopy(IToken token, FileSystemException error) { + if (error != null) { + String message = NLS.bind(Messages.FSCopy_CannotCopyFile, copy.name, error); + errors[0] = new TCFFileSystemException(message, error); } - }); - try { - rendezvous.waiting(5000L); + rendezvous.arrive(); } - catch (InterruptedException e) { - String message = NLS.bind(Messages.FSCopy_CannotCopyFile, node.name, Messages.FSOperation_TimedOutWhenOpening); - errors[0] = new TCFFileSystemException(message); - } - if (errors[0] != null) { - removeChild(service, dest, copy); - throw errors[0]; - } - monitor.worked(1); + }); + try { + rendezvous.waiting(5000L); + } + catch (InterruptedException e) { + String message = NLS.bind(Messages.FSCopy_CannotCopyFile, node.name, Messages.FSOperation_TimedOutWhenOpening); + errors[0] = new TCFFileSystemException(message); } - else { - // Canceled. - throw new InterruptedException(); + if (errors[0] != null) { + removeChild(service, dest, copy); + throw errors[0]; } + monitor.worked(1); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java index 2642dbcc0..eb598f426 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.operations; @@ -15,14 +14,19 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.util.SafeRunnable; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.protocol.IToken; +import org.eclipse.tcf.services.IFileSystem; +import org.eclipse.tcf.services.IFileSystem.DoneRemove; +import org.eclipse.tcf.services.IFileSystem.FileSystemException; import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; @@ -33,11 +37,6 @@ import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; -import org.eclipse.tcf.protocol.IChannel; -import org.eclipse.tcf.protocol.IToken; -import org.eclipse.tcf.services.IFileSystem; -import org.eclipse.tcf.services.IFileSystem.DoneRemove; -import org.eclipse.tcf.services.IFileSystem.FileSystemException; import org.eclipse.ui.PlatformUI; /** @@ -148,12 +147,10 @@ public class FSDelete extends FSOperation { remove(monitor, child, service); } } - if (!monitor.isCanceled()) { - monitor.subTask(NLS.bind(Messages.FSDelete_RemovingFileFolder, node.name)); - removeFolder(service, node); - monitor.worked(1); - } - else throw new InterruptedException(); + if (monitor.isCanceled()) throw new InterruptedException(); + monitor.subTask(NLS.bind(Messages.FSDelete_RemovingFileFolder, node.name)); + removeFolder(service, node); + monitor.worked(1); } /** @@ -204,47 +201,42 @@ public class FSDelete extends FSOperation { * @throws InterruptedException Thrown when the operation is canceled. */ private void removeFile(IProgressMonitor monitor, final FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException { - if (!monitor.isCanceled()) { - monitor.subTask(NLS.bind(Messages.FSDelete_RemovingFileFolder, node.name)); - // If the file is read only on windows or not writable on unix, then make it deletable. - if (node.isWindowsNode() && node.isReadOnly() || !node.isWindowsNode() && !node.isWritable()) { - if (!yes2All) { - int result = confirmDelete(node); - if (result == 1) { - yes2All = true; - } - else if (result == 2) { - monitor.worked(1); - return; - } - else if (result == 3) { - // Cancel the whole operation - throw new InterruptedException(); - } + if (monitor.isCanceled()) throw new InterruptedException(); + monitor.subTask(NLS.bind(Messages.FSDelete_RemovingFileFolder, node.name)); + // If the file is read only on windows or not writable on unix, then make it deletable. + if (node.isWindowsNode() && node.isReadOnly() || !node.isWindowsNode() && !node.isWritable()) { + if (!yes2All) { + int result = confirmDelete(node); + if (result == 1) { + yes2All = true; } - final FSTreeNode clone = (FSTreeNode) node.clone(); - if (node.isWindowsNode()) { - clone.setReadOnly(false); + else if (result == 2) { + monitor.worked(1); + return; } - else { - clone.setWritable(true); + else if (result == 3) { + // Cancel the whole operation + monitor.setCanceled(true); + throw new InterruptedException(); } - // Make the file writable. - SafeRunner.run(new ISafeRunnable() { - @Override - public void handleException(Throwable exception) { - } - - @Override - public void run() throws Exception { - StateManager.getInstance().setFileAttrs(node, clone.attr); - } - }); } - removeFile(node, service); - monitor.worked(1); + final FSTreeNode clone = (FSTreeNode) node.clone(); + if (node.isWindowsNode()) { + clone.setReadOnly(false); + } + else { + clone.setWritable(true); + } + // Make the file writable. + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + StateManager.getInstance().setFileAttrs(node, clone.attr); + } + }); } - else throw new InterruptedException(); + removeFile(node, service); + monitor.worked(1); } /** diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java index b4f4b34f6..bda749f9c 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.operations; @@ -124,70 +123,66 @@ public class FSMove extends FSOperation { * @throws InterruptedException Thrown when the operation is canceled. */ void moveNode(IProgressMonitor monitor, IFileSystem service, final FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException { - if (!monitor.isCanceled()) { - monitor.subTask(NLS.bind(Messages.FSMove_Moving, node.name)); - FSTreeNode copy = findChild(service, dest, node.name); - if (copy == null || !copy.equals(node) && confirmReplace(node)) { - if (copy != null && copy.isDirectory() && node.isDirectory()) { - List children = new ArrayList(getChildren(node, service)); - for (FSTreeNode child : children) { - moveNode(monitor, service, child, copy); - } - removeFolder(node, service); - monitor.worked(1); + if (monitor.isCanceled()) throw new InterruptedException(); + monitor.subTask(NLS.bind(Messages.FSMove_Moving, node.name)); + FSTreeNode copy = findChild(service, dest, node.name); + if (copy == null || !copy.equals(node) && confirmReplace(node)) { + if (copy != null && copy.isDirectory() && node.isDirectory()) { + List children = new ArrayList(getChildren(node, service)); + for (FSTreeNode child : children) { + moveNode(monitor, service, child, copy); } - else if (copy != null && copy.isFile() && node.isDirectory()) { - String error = NLS.bind(Messages.FSMove_FileExistsError, copy.name); - throw new TCFFileSystemException(error); + removeFolder(node, service); + monitor.worked(1); + } + else if (copy != null && copy.isFile() && node.isDirectory()) { + String error = NLS.bind(Messages.FSMove_FileExistsError, copy.name); + throw new TCFFileSystemException(error); + } + else if (copy != null && copy.isDirectory() && node.isFile()) { + String error = NLS.bind(Messages.FSMove_FolderExistsError, copy.name); + throw new TCFFileSystemException(error); + } + else { + if (copy != null && copy.isFile() && node.isFile()) { + removeFile(copy, service); } - else if (copy != null && copy.isDirectory() && node.isFile()) { - String error = NLS.bind(Messages.FSMove_FolderExistsError, copy.name); - throw new TCFFileSystemException(error); + else if (copy == null) { + copy = (FSTreeNode) node.clone(); } - else { - if (copy != null && copy.isFile() && node.isFile()) { - removeFile(copy, service); - } - else if (copy == null) { - copy = (FSTreeNode) node.clone(); - } - addChild(service, dest, copy); - String dst_path = copy.getLocation(true); - String src_path = node.getLocation(true); - final FSTreeNode copyNode = copy; - final TCFFileSystemException[] errors = new TCFFileSystemException[1]; - final Rendezvous rendezvous = new Rendezvous(); - service.rename(src_path, dst_path, new DoneRename() { - @Override - public void doneRename(IToken token, FileSystemException error) { - if (error != null) { - String message = NLS.bind(Messages.FSMove_CannotMove, node.name, error); - errors[0] = new TCFFileSystemException(message, error); - } - else { - cleanUpNode(node, copyNode); - } - rendezvous.arrive(); + addChild(service, dest, copy); + String dst_path = copy.getLocation(true); + String src_path = node.getLocation(true); + final FSTreeNode copyNode = copy; + final TCFFileSystemException[] errors = new TCFFileSystemException[1]; + final Rendezvous rendezvous = new Rendezvous(); + service.rename(src_path, dst_path, new DoneRename() { + @Override + public void doneRename(IToken token, FileSystemException error) { + if (error != null) { + String message = NLS.bind(Messages.FSMove_CannotMove, node.name, error); + errors[0] = new TCFFileSystemException(message, error); } - }); - try { - rendezvous.waiting(5000L); - } - catch (InterruptedException e) { - String message = NLS.bind(Messages.FSMove_CannotMove, node.name, Messages.FSOperation_TimedOutWhenOpening); - errors[0] = new TCFFileSystemException(message); - } - if (errors[0] != null) { - removeChild(service, dest, copy); - throw errors[0]; + else { + cleanUpNode(node, copyNode); + } + rendezvous.arrive(); } - monitor.worked(1); + }); + try { + rendezvous.waiting(5000L); + } + catch (InterruptedException e) { + String message = NLS.bind(Messages.FSMove_CannotMove, node.name, Messages.FSOperation_TimedOutWhenOpening); + errors[0] = new TCFFileSystemException(message); } + if (errors[0] != null) { + removeChild(service, dest, copy); + throw errors[0]; + } + monitor.worked(1); } } - else { - throw new InterruptedException(); - } } /** diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java index 73e401427..89df3f59f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.operations; @@ -16,23 +15,13 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; -import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts; -import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFChannelException; -import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; -import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CacheManager; -import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager; -import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; -import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; -import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; -import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.IToken; @@ -47,6 +36,16 @@ import org.eclipse.tcf.services.IFileSystem.FileSystemException; import org.eclipse.tcf.services.IFileSystem.IFileHandle; import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel; +import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; +import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts; +import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFChannelException; +import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; +import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CacheManager; +import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager; +import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; +import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; +import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; +import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; @@ -121,15 +120,18 @@ public abstract class FSOperation { /** * Close the editor that opens the specified file. + *

+ * Note: The method must be called within the UI thread. * * @param file The file that is opened. */ protected void closeEditor(final File file) { + Assert.isNotNull(Display.findDisplay(Thread.currentThread())); final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IEditorReference[] refs = page.getEditorReferences(); for (IEditorReference ref : refs) { final IEditorReference editorRef = ref; - SafeRunner.run(new ISafeRunnable() { + SafeRunner.run(new SafeRunnable() { @Override public void run() throws Exception { IEditorInput input = editorRef.getEditorInput(); @@ -142,11 +144,6 @@ public abstract class FSOperation { } } } - - @Override - public void handleException(Throwable exception) { - // Logged by safe runner. - } }); } } @@ -157,9 +154,15 @@ public abstract class FSOperation { * @param node the file node that is to be cleaned. */ protected void cleanUpFile(FSTreeNode node) { - File file = CacheManager.getInstance().getCacheFile(node); + final File file = CacheManager.getInstance().getCacheFile(node); if (file.exists()) { - closeEditor(file); + Display display = PlatformUI.getWorkbench().getDisplay(); + display.asyncExec(new Runnable(){ + @Override + public void run() { + closeEditor(file); + } + }); file.delete(); } PersistenceManager.getInstance().removeBaseTimestamp(node.getLocationURL()); @@ -438,7 +441,7 @@ public abstract class FSOperation { * @return The new target node with the new name following the rule. * @throws TCFFileSystemException Thrown during children querying. */ - protected FSTreeNode createCopyFile(IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException { + protected FSTreeNode createCopyDestination(IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException { FSTreeNode copy = (FSTreeNode) node.clone(); String name = node.name; FSTreeNode possibleChild = findChild(service, dest, name); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java new file mode 100644 index 000000000..27320cc09 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.filesystem.internal.operations; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; +import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; +import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; +import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; +import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; +import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.services.IFileSystem; +import org.eclipse.ui.PlatformUI; + +/** + * FSRefresh refreshes a specified tree node and its children and grand children recursively. + */ +public class FSRefresh extends FSOperation { + /** + * The root node to be refreshed. + */ + private FSTreeNode node; + + /** + * Create an FSRefresh to refresh the specified node and its descendants. + * + * @param node The root node to be refreshed. + */ + public FSRefresh(FSTreeNode node) { + this.node = node; + } + + /* + * (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation#doit() + */ + @Override + public boolean doit() { + if (node.childrenQueried) { + IChannel channel = null; + try { + channel = openChannel(node.peerNode.getPeer()); + if (channel != null) { + IFileSystem service = channel.getRemoteService(IFileSystem.class); + if (service != null) { + refresh(node, service); + } + else { + String message = NLS.bind(Messages.FSOperation_NoFileSystemError, node.peerNode.getPeer().getID()); + throw new TCFFileSystemException(message); + } + } + } + catch (TCFException e) { + // Display the error reported during moving. + Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + MessageDialog.openError(parent, Messages.FSMove_MoveFileFolderTitle, e.getLocalizedMessage()); + return false; + } + finally { + if (channel != null) channel.close(); + // Refresh the file system tree. + FSModel.getInstance().fireNodeStateChanged(node); + } + } + return true; + } + + /** + * Refresh the specified node and its children recursively using the file system service. + * + * @param node The node to be refreshed. + * @param service The file system service. + * @throws TCFFileSystemException Thrown during refreshing. + */ + private void refresh(final FSTreeNode node, final IFileSystem service) throws TCFFileSystemException { + if (node.isDirectory() && node.childrenQueried) { + updateChildren(node, service); + List children = new ArrayList(getCurrentChildren(node)); + for (FSTreeNode child : children) { + refresh(child, service); + } + } + } + + + /** + * Update the children of the specified folder node using the file system service. + * + * @param node The folder node. + * @param service The file system service. + * @throws TCFFileSystemException Thrown during querying the children nodes. + */ + private void updateChildren(final FSTreeNode node, final IFileSystem service) throws TCFFileSystemException { + List current = getCurrentChildren(node); + List latest = queryChildren(node, service); + List newNodes = diff(latest, new ArrayList(current)); + List deleted = diff(new ArrayList(current), latest); + for (FSTreeNode aNode : deleted) { + current.remove(aNode); + } + for (FSTreeNode aNode : newNodes) { + aNode.parent = node; + aNode.peerNode = node.peerNode; + current.add(aNode); + FSModel.getInstance().addNode(aNode); + } + } + + /** + * Find those nodes which are in aList yet not in bList and return them as a list. + * + * @param aList + * @param bList + * @return the difference list. + */ + private List diff(List aList, List bList) { + List newList = new ArrayList(); + for (FSTreeNode aNode : aList) { + boolean found = false; + for (FSTreeNode bNode : bList) { + if (aNode.name.equals(bNode.name)) { + found = true; + break; + } + } + if (!found) { + newList.add(aNode); + } + } + return newList; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java index e2298fc5b..8b7800d6f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java @@ -5,8 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. + * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.operations; @@ -14,6 +13,7 @@ import java.io.File; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; @@ -105,10 +105,16 @@ public class FSRename extends FSOperation { errors[0] = new TCFFileSystemException(message, error); } else { - File file = CacheManager.getInstance().getCacheFile(node); + final File file = CacheManager.getInstance().getCacheFile(node); if (file.exists()) { if (node.isFile()) { - closeEditor(file); + Display display = PlatformUI.getWorkbench().getDisplay(); + display.asyncExec(new Runnable(){ + @Override + public void run() { + closeEditor(file); + } + }); PersistenceManager.getInstance().removeBaseTimestamp(node.getLocationURL()); } file.delete(); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java index 5bbba2255..0762d14c1 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java @@ -6,8 +6,6 @@ * * Contributors: * Wind River Systems - initial API and implementation - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.preferences; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java index 2300f6450..4c1ce8ead 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java @@ -7,8 +7,6 @@ * Contributors: * Wind River Systems - initial API and implementation * William Chen (Wind River)- [345552] Edit the remote files with a proper editor - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.internal.preferences; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java index a696e8c15..8db221fbf 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java @@ -9,8 +9,6 @@ * William Chen (Wind River) - [345384] Provide property pages for remote file system nodes * William Chen (Wind River) - [352302]Opening a file in an editor depending on * the client's permissions. - * William Chen (Wind River) - [361324] Add more file operations in the file system - * of Target Explorer. *******************************************************************************/ package org.eclipse.tcf.te.tcf.filesystem.model; diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.properties b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.properties index cd9aa991c..0d81187d4 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.properties @@ -47,3 +47,5 @@ Command.open.name=Open PropertiesAction.label=P&roperties PropertiesAction.tooltip=Show Properties of Selection + +ExtensionPoint.cellEditors.name = Common Viewer Cell Editors \ No newline at end of file diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml index 8c219402e..867d7ca3b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml @@ -3,7 +3,7 @@ - + diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/cellEditors.exsd b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/cellEditors.exsd new file mode 100644 index 000000000..badb525e9 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/cellEditors.exsd @@ -0,0 +1,197 @@ + + + + + + + + + This extension point is used to declare the cell editor factories in Target Explorer view. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares a cell editor factory for Target Explorer view. + + + + + + + + + + The id of the common viewer that this cell editor factory contributes to. If the viewer is in a common navigator then the id must match the navigator's id defined in its <b>org.eclipse.ui.views</b> extension. + + + + + + + + + + The class that implements <code>org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory</code>. +<p> +The cell editor factory implementation class must be specified either by the "editorFactory" attribute! + + + + + + + + + + + + + The <b>activation</b> expression defines the event that triggers the cell editing and the elements selected when the cell editor is about to be activated. + + + + + + + + + + + + + + + + + + + + + + + + + + + Target Explorer 1.0.0 + + + + + + + + + <pre> + <extension + point="org.eclipse.tcf.te.ui.views.cellEditors"> + <cellEditor + editorFactory="org.eclipse.tcf.te.tcf.filesystem.controls.FSViewerCellEditorFactory" + viewerId="org.eclipse.tcf.te.ui.views.TargetExplorer"> + <activation> + <and> + <with + variable="selection"> + <count + value="1"> + </count> + <iterate> + <instanceof + value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode"> + </instanceof> + </iterate> + </with> + <with + variable="event"> + <test + property="org.eclipse.tcf.te.tcf.filesystem.propertytester.event.isEditorActivation"> + </test> + </with> + </and> + </activation> + </cellEditor> + </extension> +</pre> + + + + + + + + + Plug-ins that want to extend this extension point, the referenced class must implement <samp>org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory</samp> interface. +<p> +In the "activation" element, the evaluation context has two variables: "selection" and "event". +"selection" stores the currently selected elements in the viewer. "event" is the event that +triggers cell editing, an instance of <code>org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent</code>. +See <code>org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy</code> for more information. + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + Copyright (c) 2011 Wind River Systems, 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. + + + + diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd deleted file mode 100644 index a9a8e14a4..000000000 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - <p> -This extension point is used to declare Target Explorer Viewer Configurators. A Viewer Configurator is used to configure the common viewer of Target Explorer when it is created. Those who want to configure the common viewer after it is created should implement an instance of IViewerConfigurator and add a viewer configurator extension. -</p> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Declares a Target Explorer Viewer Configurator. - - - - - - - The id of the common viewer that this configurator contributes to. If the viewer is in a common navigator then the id must match the navigator's id defined in its <b>org.eclipse.ui.views</b> extension. - - - - - - - - - - The class that implements <code>org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator</code>. -<p> -The editor page implementation class must be specified either by the class attribute! - - - - - - - - - - - - - - - Target Explorer 1.0.0 - - - - - - - - - <pre> - <extension - point="org.eclipse.tcf.te.ui.views.configurators"> - <configurator - class="org.eclipse.tcf.te.tcf.filesystem.controls.FSCellConfigurator" - viewerId="org.eclipse.tcf.te.ui.views.TargetExplorer"> - </configurator> - </extension> -</pre> - - - - - - - - - Plug-ins that want to extend this extension point, the referenced class must implement <samp>org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator</samp> interface. - - - - - - - - - - Copyright (c) 2011 Wind River Systems, 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. - - - - diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerCellEditorFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerCellEditorFactory.java new file mode 100644 index 000000000..38dbc6617 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerCellEditorFactory.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.views.interfaces; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.jface.viewers.TreeViewer; + +/** + * An interface to provide the cell editing support for Target Explorer in an abstract way. + *

+ * This interface should be implemented by classes that wish to add cell editing support to Target + * Explorer when it is created. + */ +public interface IViewerCellEditorFactory { + /** + * Initialize this cell editor factory with the tree viewer that is used as the common viewer in + * Target Explorer. + * + * @param viewer The tree viewer in Target Explorer. + */ + void init(TreeViewer viewer); + + /** + * Returns the column properties of the viewer. The properties must correspond with the columns + * of the table control. They are used to identify the column in a cell modifier. + * + * @return the list of column properties + * @see org.eclipse.jface.viewers.ColumnViewer#getColumnProperties + * @see org.eclipse.jface.viewers.ColumnViewer#setColumnProperties + */ + String[] getColumnProperties(); + + /** + * Return the CellEditors for the viewer, or null if no cell editors are set. + * + * @return CellEditor[] + * @see org.eclipse.jface.viewers.ColumnViewer#getCellEditors + * @see org.eclipse.jface.viewers.ColumnViewer#setCellEditors + */ + CellEditor[] getCellEditors(); + + /** + * Returns the cell modifier of this viewer, or null if none has been set. + * + * @return the cell modifier, or null + * @see org.eclipse.jface.viewers.ColumnViewer#getCellModifier + * @see org.eclipse.jface.viewers.ColumnViewer#setCellModifier + */ + ICellModifier getCellModifier(); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java deleted file mode 100644 index 8c899be31..000000000 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Wind River Systems, 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: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. - *******************************************************************************/ -package org.eclipse.tcf.te.ui.views.interfaces; - -import org.eclipse.ui.navigator.CommonViewer; - -/** - * An interface to configure the common viewer of Target Explorer in an abstract way. - *

- * This interface should be implemented by classes that wish to configure the common viewer when - * Target Explorer is created. - */ -public interface IViewerConfigurator { - /** - * Configure the common viewer of Target Explorer. - * - * @param viewer The common viewer of Target Explorer. - */ - void configure(CommonViewer viewer); -} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java index fdfa3a5b1..b19f4eb96 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/View.java @@ -21,8 +21,11 @@ import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ColumnViewerEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeViewerEditor; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; @@ -146,7 +149,11 @@ public class View extends CommonNavigator { */ @Override protected CommonViewer createCommonViewerObject(Composite parent) { - return new ViewViewer(getViewSite().getId(), parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + ViewViewer viewer = new ViewViewer(getViewSite().getId(), parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + // Define an editor activation strategy for the common viewer so as to be invoked only programmatically. + ColumnViewerEditorActivationStrategy activationStrategy = new ViewViewerEditorActivationStrategy(getSite().getId(), viewer); + TreeViewerEditor.create(viewer, null, activationStrategy, ColumnViewerEditor.DEFAULT); + return viewer; } /* (non-Javadoc) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java index 13d61a14d..a7bba6e63 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java @@ -11,8 +11,8 @@ package org.eclipse.tcf.te.ui.views.internal; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.widgets.Composite; -import org.eclipse.tcf.te.ui.views.events.ViewerContentChangeEvent; import org.eclipse.tcf.te.runtime.events.EventManager; +import org.eclipse.tcf.te.ui.views.events.ViewerContentChangeEvent; import org.eclipse.ui.navigator.CommonViewer; import org.eclipse.ui.navigator.CommonViewerSorter; @@ -35,7 +35,6 @@ public class ViewViewer extends CommonViewer { */ public ViewViewer(String viewerId, Composite parent, int style) { super(viewerId, parent, style); - new ViewViewerConfigurator(viewerId).configure(this); } /* (non-Javadoc) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java deleted file mode 100644 index 0255f5782..000000000 --- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Wind River Systems, 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: - * William Chen (Wind River) - [361324] Add more file operations in the file - * system of Target Explorer. - *******************************************************************************/ -package org.eclipse.tcf.te.ui.views.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.SafeRunner; -import org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator; -import org.eclipse.ui.navigator.CommonViewer; - -/** - * This viewer configurator reads the extensions from the extension point - * "org.eclipse.tcf.te.ui.views.configurators" and initialize the registered viewer - * configurators. - */ -public class ViewViewerConfigurator implements IViewerConfigurator { - private static final String EXTENSION_POINT_ID = "org.eclipse.tcf.te.ui.views.configurators"; //$NON-NLS-1$ - // The registered viewer configurators with the specified viewer id. - List configurators; - - /** - * Create an instance with the specified viewer id. - */ - public ViewViewerConfigurator(String viewerId) { - Assert.isTrue(viewerId != null); - configurators = Collections.synchronizedList(new ArrayList()); - IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(EXTENSION_POINT_ID); - IExtension[] extensions = extensionPoint.getExtensions(); - for (IExtension extension : extensions) { - IConfigurationElement[] elements = extension.getConfigurationElements(); - for (IConfigurationElement element : elements) { - String name = element.getName(); - String id = element.getAttribute("viewerId"); //$NON-NLS-1$ - if (name.equals("configurator") && viewerId.equals(id)) { //$NON-NLS-1$ - addConfigurator(element); - } - } - } - } - - /** - * Add the viewer configurator defined in the configuration element to the configurator list. - * - * @param element The configuration element that defines the viewer configurator. - */ - private void addConfigurator(final IConfigurationElement element) { - SafeRunner.run(new ISafeRunnable() { - @Override - public void handleException(Throwable exception) { - // Ignore it. - } - - @Override - public void run() throws Exception { - IViewerConfigurator configurator = (IViewerConfigurator) element.createExecutableExtension("class"); //$NON-NLS-1$ - configurators.add(configurator); - } - }); - } - - /* - * (non-Javadoc) - * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator#configure(org.eclipse.ui.navigator.CommonViewer) - */ - @Override - public void configure(CommonViewer viewer) { - for (IViewerConfigurator configurator : configurators) { - configurator.configure(viewer); - } - } -} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerEditorActivationStrategy.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerEditorActivationStrategy.java new file mode 100644 index 000000000..d8fc805cd --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerEditorActivationStrategy.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.views.internal; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.expressions.EvaluationContext; +import org.eclipse.core.expressions.EvaluationResult; +import org.eclipse.core.expressions.Expression; +import org.eclipse.core.expressions.ExpressionConverter; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory; + +/** + * ViewViewerEditorActivationStratgy is a subclass of + * ColumnViewerEditorActivationStrategy that parses the extensions of + * "org.eclipse.tcf.te.ui.views.cellEditors" for Target Explorer, creating a map of + * IViewerCellEditorFactory with the activation expressions. When requested to judge if + * a ColumnViewerEditorActivationEvent triggers the cell editing in method + * isEditorActivationEvent, it traverses the map and finds an appropriate cell editor + * factory by evaluating its activation expression. If such a factory is found, add the cell editing + * support to Target Explorer viewer with it and return true to activate the cell editing. If no + * such a factory is found, then return false to deactivate the cell editing. + */ +public class ViewViewerEditorActivationStrategy extends ColumnViewerEditorActivationStrategy { + // The extension point id. + private static final String EXTENSION_POINT_ID = "org.eclipse.tcf.te.ui.views.cellEditors"; //$NON-NLS-1$ + // The common viewer's id. + String viewerId; + // The common viewer to add editing support. + TreeViewer viewer; + // The registered cell editor factories map. + Map factories; + + /** + * Create an instance with the specified viewer id and the common viewer. + * + * @param viewerId + * @param viewer + */ + public ViewViewerEditorActivationStrategy(String viewerId, TreeViewer viewer) { + super(viewer); + Assert.isNotNull(viewerId); + this.viewerId = viewerId; + this.viewer = viewer; + loadFactories(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy#isEditorActivationEvent(org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent) + */ + @Override + protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { + IViewerCellEditorFactory factory = getFactory(event); + if (factory != null) { + // If an appropriate factory is found, initialize the cell editors. + viewer.setColumnProperties(factory.getColumnProperties()); + viewer.setCellEditors(factory.getCellEditors()); + viewer.setCellModifier(factory.getCellModifier()); + } + return factory != null; + } + + /** + * Get an appropriate cell editor factory based on the event and the current + * selection in the viewer. + * + * @param event the event triggering the action + * @return The cell editor factory is appropriate. + */ + private IViewerCellEditorFactory getFactory(ColumnViewerEditorActivationEvent event) { + // Prepare the evaluation context. + ISelection selection = viewer.getSelection(); + final EvaluationContext context = new EvaluationContext(null, selection); + context.addVariable("selection", selection); //$NON-NLS-1$ + context.addVariable("event", event); //$NON-NLS-1$ + final IViewerCellEditorFactory[] result = new IViewerCellEditorFactory[1]; + for (Expression expression : factories.keySet()) { + final Expression exp = expression; + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + EvaluationResult evaluate = exp.evaluate(context); + if (evaluate == EvaluationResult.TRUE) { + result[0] = factories.get(exp); + } + } + }); + if (result[0] != null) return result[0]; + } + return null; + } + + /** + * Load the currently registered cell editor factories. + */ + private void loadFactories() { + factories = Collections.synchronizedMap(new HashMap()); + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_POINT_ID); + IConfigurationElement[] configurations = extensionPoint.getConfigurationElements(); + for (IConfigurationElement configuration : configurations) { + String name = configuration.getName(); + if ("cellEditor".equals(name)) { //$NON-NLS-1$ + String viewerId = configuration.getAttribute("viewerId"); //$NON-NLS-1$ + if (this.viewerId.equals(viewerId)) { + addFactory(configuration); + } + } + } + } + + /** + * Create and add the cell editor factory that is defined in the configuration element + * into the map. + * @param configuration The configuration element that defines the cell editor factory. + */ + private void addFactory(final IConfigurationElement configuration) { + IConfigurationElement[] children = configuration.getChildren("activation"); //$NON-NLS-1$ + Assert.isTrue(children != null && children.length == 1); + children = children[0].getChildren(); + Assert.isTrue(children != null && children.length == 1); + final IConfigurationElement config = children[0]; + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + Expression expression = ExpressionConverter.getDefault().perform(config); + IViewerCellEditorFactory factory = (IViewerCellEditorFactory) configuration.createExecutableExtension("editorFactory"); //$NON-NLS-1$ + if (expression != null && factory != null) { + factory.init(viewer); + factories.put(expression, factory); + } + } + }); + } +} -- cgit v1.2.3 From d16633ddda860badbc9265ddfa71137dda800fe1 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Thu, 24 Nov 2011 10:29:43 +0100 Subject: Target Explorer: Improve persistable handling in ModelNodePersistableAdapter --- .../eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java | 8 ++++++++ .../src/org/eclipse/tcf/te/core/nls/Messages.java | 1 + .../src/org/eclipse/tcf/te/core/nls/Messages.properties | 1 + 3 files changed, 10 insertions(+) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java index decfde327..2f2d1d896 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java @@ -193,6 +193,14 @@ public class ModelNodePersistableAdapter implements IPersistable { IPersistable persistable = value instanceof IAdaptable ? (IPersistable)((IAdaptable)value).getAdapter(IPersistable.class) : null; if (persistable == null) persistable = (IPersistable)Platform.getAdapterManager().getAdapter(value, IPersistable.class); if (persistable != null) { + // Check if the persistable returns complete information to create the reference + if (persistable.getStorageID() == null) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "storageID")); //$NON-NLS-1$ + } + if (persistable.getURI(value) == null) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "uri")); //$NON-NLS-1$ + } + // Create a reference object Map reference = new HashMap(); reference.put("storageID", persistable.getStorageID()); //$NON-NLS-1$ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java index ab4825298..b5f669273 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java @@ -35,5 +35,6 @@ public class Messages extends NLS { public static String ConnectStrategyStepExecutor_error_stepFailed; public static String ConnectStrategyStepExecutor_stepFailed_debugInfo; + public static String ModelNodePersistableAdapter_export_invalidPersistable; public static String ModelNodePersistableAdapter_export_unknownType; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties index 292522277..2c5f058ee 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties @@ -18,4 +18,5 @@ Connect Strategy: {2}\n\ Connect Step: {3} ConnectStrategyStepExecutor_stepFailed_debugInfo=Debug info:\n{0} +ModelNodePersistableAdapter_export_invalidPersistable=Persistable for object type ''{0}'' provides incomplete information for property ''{1}''. ModelNodePersistableAdapter_export_unknownType=No strategy to persist an object of type ''{0}'', key = ''{1}''. -- cgit v1.2.3 From 32c5289b341814cba4a11fa17f6abdff7c12d0b2 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Thu, 24 Nov 2011 11:18:42 +0100 Subject: Target Explorer: Improve reference handling in ModelNodePersistableAdapter --- .../core/adapters/ModelNodePersistableAdapter.java | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java index 2f2d1d896..b1064bbe0 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java @@ -58,7 +58,7 @@ public class ModelNodePersistableAdapter implements IPersistable { IModelNode node = (IModelNode) data; if (node.getName() != null && !"".equals(node.getName().trim())) { //$NON-NLS-1$ // Get the node name and make it a valid file system name (no spaces etc). - IPath path = getRoot().append(makeValidFileSystemName(((IModelNode) data).getName().trim())); + IPath path = getRoot().append(makeValidFileSystemName(node.getName().trim())); if (!"ini".equals(path.getFileExtension())) path = path.addFileExtension("ini"); //$NON-NLS-1$ //$NON-NLS-2$ uri = path.toFile().toURI(); } @@ -67,6 +67,12 @@ public class ModelNodePersistableAdapter implements IPersistable { IPath path = new Path(node.getStringProperty("Path")); //$NON-NLS-1$ uri = path.toFile().toURI(); } + // Final fallback is to use the UUID + else if (node.getUUID() != null) { + IPath path = getRoot().append(makeValidFileSystemName(node.getUUID().toString().trim())); + if (!"ini".equals(path.getFileExtension())) path = path.addFileExtension("ini"); //$NON-NLS-1$ //$NON-NLS-2$ + uri = path.toFile().toURI(); + } } return uri; @@ -193,22 +199,25 @@ public class ModelNodePersistableAdapter implements IPersistable { IPersistable persistable = value instanceof IAdaptable ? (IPersistable)((IAdaptable)value).getAdapter(IPersistable.class) : null; if (persistable == null) persistable = (IPersistable)Platform.getAdapterManager().getAdapter(value, IPersistable.class); if (persistable != null) { + String storageID = persistable.getStorageID(); + URI uri = persistable.getURI(value); + // Check if the persistable returns complete information to create the reference - if (persistable.getStorageID() == null) { + if (storageID == null) { throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "storageID")); //$NON-NLS-1$ } - if (persistable.getURI(value) == null) { + if (uri == null) { throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "uri")); //$NON-NLS-1$ } // Create a reference object Map reference = new HashMap(); - reference.put("storageID", persistable.getStorageID()); //$NON-NLS-1$ - reference.put("uri", persistable.getURI(value).toString()); //$NON-NLS-1$ + reference.put("storageID", storageID); //$NON-NLS-1$ + reference.put("uri", uri.toString()); //$NON-NLS-1$ - IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(persistable.getStorageID(), false); + IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(storageID, false); if (delegate != null) { - delegate.write(persistable.getURI(value), persistable.exportFrom(value)); + delegate.write(uri, persistable.exportFrom(value)); dst.put(key, reference); continue; } -- cgit v1.2.3 From b6a18b4dc17dbfeb2cd526dd97d24c00e0a0d7ad Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Thu, 24 Nov 2011 18:47:09 +0100 Subject: Target Explorer: Add extensible model node factory and implement type correct data node recreation from the persistence storage --- .../core/adapters/ModelNodePersistableAdapter.java | 89 ++++++++- .../src/org/eclipse/tcf/te/core/nls/Messages.java | 2 + .../eclipse/tcf/te/core/nls/Messages.properties | 2 + .../META-INF/MANIFEST.MF | 3 + .../build.properties | 3 +- .../org.eclipse.tcf.te.runtime.model/plugin.xml | 6 + .../schema/factoryDelegates.exsd | 221 +++++++++++++++++++++ .../model/factory/AbstractFactoryDelegate.java | 21 ++ .../tcf/te/runtime/model/factory/Factory.java | 63 ++++++ .../runtime/model/interfaces/factory/IFactory.java | 28 +++ .../model/interfaces/factory/IFactoryDelegate.java | 28 +++ .../internal/factory/FactoryDelegateManager.java | 78 ++++++++ .../internal/factory/FactoryDelegateProxy.java | 107 ++++++++++ .../eclipse/tcf/te/runtime/model/nls/Messages.java | 2 + .../tcf/te/runtime/model/nls/Messages.properties | 2 + .../persistence/interfaces/IPersistable.java | 12 ++ .../PropertiesFilePersistenceDelegate.java | 3 +- .../internal/adapters/MapPersistableAdapter.java | 14 +- .../adapters/PeerModelPersistableAdapter.java | 14 +- 19 files changed, 691 insertions(+), 7 deletions(-) create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java index b1064bbe0..739a76a6f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java @@ -26,10 +26,13 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; import org.eclipse.tcf.te.core.activator.CoreBundleActivator; import org.eclipse.tcf.te.core.nls.Messages; +import org.eclipse.tcf.te.runtime.model.factory.Factory; +import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode; import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; import org.eclipse.tcf.te.runtime.persistence.PersistenceDelegateManager; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistenceDelegate; +import org.osgi.framework.Bundle; /** * Model node persistable adapter implementation. @@ -67,7 +70,7 @@ public class ModelNodePersistableAdapter implements IPersistable { IPath path = new Path(node.getStringProperty("Path")); //$NON-NLS-1$ uri = path.toFile().toURI(); } - // Final fallback is to use the UUID + // No name and no explicit path is set -> use the UUID else if (node.getUUID() != null) { IPath path = getRoot().append(makeValidFileSystemName(node.getUUID().toString().trim())); if (!"ini".equals(path.getFileExtension())) path = path.addFileExtension("ini"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -117,6 +120,20 @@ public class ModelNodePersistableAdapter implements IPersistable { return location; } + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#getInterfaceType(java.lang.Object) + */ + @SuppressWarnings("restriction") + @Override + public String getInterfaceTypeName(Object data) { + if (data instanceof IContainerModelNode) { + return org.eclipse.tcf.te.runtime.model.activator.CoreBundleActivator.getUniqueIdentifier() + ":" + IContainerModelNode.class.getName(); //$NON-NLS-1$ + } else if (data instanceof IModelNode) { + return org.eclipse.tcf.te.runtime.model.activator.CoreBundleActivator.getUniqueIdentifier() + ":" + IModelNode.class.getName(); //$NON-NLS-1$ + } + return null; + } + /* (non-Javadoc) * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object) */ @@ -201,6 +218,7 @@ public class ModelNodePersistableAdapter implements IPersistable { if (persistable != null) { String storageID = persistable.getStorageID(); URI uri = persistable.getURI(value); + String interfaceTypeName = persistable.getInterfaceTypeName(value); // Check if the persistable returns complete information to create the reference if (storageID == null) { @@ -209,16 +227,20 @@ public class ModelNodePersistableAdapter implements IPersistable { if (uri == null) { throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "uri")); //$NON-NLS-1$ } + if (interfaceTypeName == null) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "interfaceTypeName")); //$NON-NLS-1$ + } // Create a reference object Map reference = new HashMap(); reference.put("storageID", storageID); //$NON-NLS-1$ reference.put("uri", uri.toString()); //$NON-NLS-1$ + reference.put("interfaceType", interfaceTypeName); //$NON-NLS-1$ IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(storageID, false); if (delegate != null) { delegate.write(uri, persistable.exportFrom(value)); - dst.put(key, reference); + dst.put("reference:" + key, reference); //$NON-NLS-1$ continue; } } @@ -241,7 +263,68 @@ public class ModelNodePersistableAdapter implements IPersistable { if (data instanceof IModelNode) { IModelNode node = (IModelNode) data; for (String key : external.keySet()) { - node.setProperty(key, external.get(key)); + // Get the property value + Object value = external.get(key); + + // Check for reference objects + if (key.startsWith("reference:") && value instanceof Map) { //$NON-NLS-1$ + // Cut the "reference:" from the key + String newKey = key.substring(10); + + @SuppressWarnings("unchecked") + Map reference = (Map)value; + + // Get the storage id and the URI from the reference + String storageID = reference.get("storageID"); //$NON-NLS-1$ + String uri = reference.get("uri"); //$NON-NLS-1$ + String interfaceTypeName = reference.get("interfaceType"); //$NON-NLS-1$ + + // Check if the reference returns complete information to read the referenced storage + if (storageID == null) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "storageID")); //$NON-NLS-1$ + } + if (uri == null) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "uri")); //$NON-NLS-1$ + } + if (interfaceTypeName == null) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "interfaceType")); //$NON-NLS-1$ + } + + // Get the persistence delegate + IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(storageID, false); + if (delegate != null) { + Map referenceData = delegate.read(URI.create(uri)); + if (referenceData != null && !referenceData.isEmpty()) { + try { + // Now, we have to recreate the object + + // Separate the bundleId from the interface name + String[] pieces = interfaceTypeName.split(":", 2); //$NON-NLS-1$ + String bundleId = pieces.length > 1 ? pieces[0] : null; + if (pieces.length > 1) interfaceTypeName = pieces[1]; + + // Determine the bundle to use for loading the class + Bundle bundle = bundleId != null && !"".equals(bundleId.trim()) ? Platform.getBundle(bundleId.trim()) : CoreBundleActivator.getContext().getBundle(); //$NON-NLS-1$ + + Class interfaceType = (Class)bundle.loadClass(interfaceTypeName); + IModelNode referenceNode = Factory.getInstance().newInstance(interfaceType); + + IPersistable persistable = (IPersistable)referenceNode.getAdapter(IPersistable.class); + if (persistable == null) persistable = (IPersistable)Platform.getAdapterManager().getAdapter(referenceNode, IPersistable.class); + if (persistable != null) { + persistable.importTo(referenceNode, referenceData); + node.setProperty(newKey, referenceNode); + } + } catch (ClassNotFoundException e) { + throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_cannotLoadClass, interfaceTypeName), e); + } + } + } + } + // Not a reference object -> store the object as is to the node + else { + node.setProperty(key, value); + } } } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java index b5f669273..ae2936030 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java @@ -37,4 +37,6 @@ public class Messages extends NLS { public static String ModelNodePersistableAdapter_export_invalidPersistable; public static String ModelNodePersistableAdapter_export_unknownType; + public static String ModelNodePersistableAdapter_import_invalidReference; + public static String ModelNodePersistableAdapter_import_cannotLoadClass; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties index 2c5f058ee..f80734b73 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties @@ -20,3 +20,5 @@ ConnectStrategyStepExecutor_stepFailed_debugInfo=Debug info:\n{0} ModelNodePersistableAdapter_export_invalidPersistable=Persistable for object type ''{0}'' provides incomplete information for property ''{1}''. ModelNodePersistableAdapter_export_unknownType=No strategy to persist an object of type ''{0}'', key = ''{1}''. +ModelNodePersistableAdapter_import_invalidReference=Reference provides incomplete information for property ''{0}'' to restore the object. +ModelNodePersistableAdapter_import_cannotLoadClass=Cannot load class for name ''{0}'' diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF index 0018cebd8..b4025fdc1 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF @@ -12,5 +12,8 @@ Bundle-ActivationPolicy: lazy Bundle-Localization: plugin Export-Package: org.eclipse.tcf.te.runtime.model, org.eclipse.tcf.te.runtime.model.activator;x-internal:=true, + org.eclipse.tcf.te.runtime.model.factory, org.eclipse.tcf.te.runtime.model.interfaces, + org.eclipse.tcf.te.runtime.model.interfaces.factory, + org.eclipse.tcf.te.runtime.model.internal.factory;x-internal:=true, org.eclipse.tcf.te.runtime.model.nls;x-internal:=true diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties index f4ae97015..73a5119ed 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.properties + plugin.properties,\ + plugin.xml diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml new file mode 100644 index 000000000..34249eeb3 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd new file mode 100644 index 000000000..33854922f --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd @@ -0,0 +1,221 @@ + + + + + + + + + This extension point is used to contribute model node factory delegates. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares a model node factory delegate contribution. + + + + + + + + + + + The unique id of the model node factory delegate contribution. + + + + + + + The label representing the model node factory delegate. + + + + + + + The class that implements <code>org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate</code> or extends <code>org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate</code>. +<p> +The model node factory delegate implementation class must be specified either by the class attribute or the class child element! + + + + + + + + + + + + + Used when creating an <code>IExecutableExtension</code> with a named parameter, or more than one. + + + + + + + + + + The class that implements <code>org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate</code> or extends <code>org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate</code>. +<p> +The model node factory delegate implementation class must be specified either by the class attribute or the class child element! + + + + + + + + + + + + + A parameter for an <code>IExecutableExtension</code>. + + + + + + + <p>The parameter name.</p> + + + + + + + <p>The parameter value.</p> + + + + + + + + + + The node type interface implemented by nodes created by the factory delegate. + + + + + + + + + + + + + + + + + The unique id of the bundle which contains the class loader required to load the node type class. If not specified, the plugin's own class loader is used. + + + + + + + + + + + + Target Explorer 1.0.0 + + + + + + + + + This is an example of the extension point usage: +<p> +<pre><code> + <extension point="org.eclipse.tcf.te.runtime.model.factoryDelegates"> + <delegate + id="org.eclipse.tcf.te.runtime.model.factory.modelNode" + class="org.eclipse.tcf.te.runtime.model.internal.ModelNodeFactoryDelegate" + label="Model Node Factory Delegate"> + <nodeType class="org.eclipse.tcf.te.runtime.model.interfaces.IModelNode"/> + <nodeType class="org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode"/> + </delegate> + </extension> +</code></pre> + + + + + + + + + The provider of a model node factory delegate must implement <samp>org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate</samp>. + + + + + + + + + + Copyright (c) 2011 Wind River Systems, 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. + + + + diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java new file mode 100644 index 000000000..f2dc3d5ff --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.model.factory; + +import org.eclipse.tcf.te.runtime.extensions.ExecutableExtension; +import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate; + + +/** + * Abstract model node factory delegate implementation. + */ +public abstract class AbstractFactoryDelegate extends ExecutableExtension implements IFactoryDelegate { + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java new file mode 100644 index 000000000..b4c47aad7 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.model.factory; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; +import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactory; +import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate; +import org.eclipse.tcf.te.runtime.model.internal.factory.FactoryDelegateManager; + +/** + * Model node factory implementation. + */ +public final class Factory extends PlatformObject implements IFactory { + private final FactoryDelegateManager manager = new FactoryDelegateManager(); + + /* + * Thread save singleton instance creation. + */ + private static class LazyInstance { + public static Factory instance = new Factory(); + } + + /** + * Returns the singleton instance of the service manager. + */ + public static Factory getInstance() { + return LazyInstance.instance; + } + + /** + * Constructor. + */ + Factory() { + super(); + } + + /** + * Creates an new instance of the model node object implementing + * the specified node interface. + * + * @param nodeInterface The node interface to be implemented by the model node object to create. + * Must not be null. + * @return The model not object implementing the specified node interface or null. + */ + @Override + public V newInstance(Class nodeInterface) { + Assert.isNotNull(nodeInterface); + + // Determine the model node factory delegate to use + IFactoryDelegate delegate = manager.getFactoryDelegate(nodeInterface); + // Return the model node instance + return delegate != null ? (V)delegate.newInstance(nodeInterface) : null; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java new file mode 100644 index 000000000..0c1b5b407 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.model.interfaces.factory; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; + +/** + * Interface to be implemented by model node factories. + */ +public interface IFactory extends IAdaptable { + + /** + * Creates an new instance of an node object implementing the specified node interface. + * + * @param nodeInterface The node interface to be implemented by the node object to be created. + * Must not be null. + * @return The node object implementing the specified node interface or null. + */ + public V newInstance(Class nodeInterface); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java new file mode 100644 index 000000000..18cead26f --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.model.interfaces.factory; + +import org.eclipse.tcf.te.runtime.interfaces.extensions.IExecutableExtension; +import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; + +/** + * Interface to be implemented by model node factory delegates. + */ +public interface IFactoryDelegate extends IExecutableExtension { + + /** + * Returns a new instance of an node object implementing the given node interface. + * + * @param nodeInterface The node interface to be implemented by the node object to be created. + * Must not be null. + * @return The node object implementing the specified node interface or null. + */ + public V newInstance(Class nodeInterface); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java new file mode 100644 index 000000000..1e5e00354 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.model.internal.factory; + +import java.util.Collection; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager; +import org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy; +import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; +import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate; + + +/** + * Model node factory delegate extension point manager implementation. + */ +public class FactoryDelegateManager extends AbstractExtensionPointManager { + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getExtensionPointId() + */ + @Override + protected String getExtensionPointId() { + return "org.eclipse.tcf.te.runtime.model.factoryDelegates"; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getConfigurationElementName() + */ + @Override + protected String getConfigurationElementName() { + return "delegate"; //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#doCreateExtensionProxy(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected ExecutableExtensionProxy doCreateExtensionProxy(IConfigurationElement element) throws CoreException { + return new FactoryDelegateProxy(element); + } + + /** + * Returns the model node factory delegate for the given node type. + *

+ * Note: The first factory delegate declaring the given node type + * as supported will be returned. + * + * @param nodeType The node type. Must not be null. + * @return The model node factory delegate or null. + */ + public IFactoryDelegate getFactoryDelegate(Class nodeType) { + Assert.isNotNull(nodeType); + + IFactoryDelegate delegate = null; + + Collection> delegates = getExtensions().values(); + for (ExecutableExtensionProxy candidate : delegates) { + if (!(candidate instanceof FactoryDelegateProxy)) continue; + if (((FactoryDelegateProxy)candidate).getNodeTypes().contains(nodeType)) { + delegate = candidate.getInstance(); + break; + } + } + + return delegate; + } + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java new file mode 100644 index 000000000..05af0cc82 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.model.internal.factory; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator; +import org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy; +import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; +import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate; +import org.eclipse.tcf.te.runtime.model.nls.Messages; +import org.osgi.framework.Bundle; + +/** + * Model node factory delegate executable extension proxy implementation. + */ +public class FactoryDelegateProxy extends ExecutableExtensionProxy { + // The list of node types supported by the model node factory delegate + private final List> nodeTypes = new ArrayList>(); + // Flag to mark if the node types has been loaded + private boolean nodeTypesLoaded = false; + + /** + * Constructor. + * + * @param element The configuration element. Must not be null. + * @throws CoreException In case the configuration element attribute id is null or empty. + */ + public FactoryDelegateProxy(IConfigurationElement element) throws CoreException { + super(element); + } + + /** + * Constructor. + * + * @param id The id for this instance. + * @param instance The instance to add to proxy. + */ + public FactoryDelegateProxy(String id, IFactoryDelegate instance) { + super(id, instance); + } + + /** + * Returns the list of node types supported by the model node factory. + * + * @return The unmodifiable list of node types. + */ + public List> getNodeTypes() { + if (!nodeTypesLoaded) loadNodeTypes(); + return Collections.unmodifiableList(nodeTypes); + } + + /** + * Load the node types. + */ + protected void loadNodeTypes() { + IConfigurationElement element = getConfigurationElement(); + Assert.isNotNull(element); + + nodeTypes.clear(); + + IConfigurationElement[] nodeTypeElements = element.getChildren("nodeType"); //$NON-NLS-1$ + if (nodeTypeElements != null && nodeTypeElements.length > 0) { + for (IConfigurationElement nodeTypeElement : nodeTypeElements) { + try { + String type = nodeTypeElement.getAttribute("class"); //$NON-NLS-1$ + String bundleId = nodeTypeElement.getAttribute("bundleId"); //$NON-NLS-1$ + + // If a bundle id got specified, use the specified bundle to load the node type class + Bundle bundle = bundleId != null ? bundle = Platform.getBundle(bundleId) : null; + // If we don't have a bundle to load from yet, fallback to the declaring bundle + if (bundle == null) bundle = Platform.getBundle(element.getDeclaringExtension().getNamespaceIdentifier()); + // And finally, use our own bundle to load the class. + // This fallback is expected to never be used. + if (bundle == null) bundle = CoreBundleActivator.getContext().getBundle(); + + // Try to load the node type class now. + Class typeClass = (Class)(bundle != null ? bundle.loadClass(type) : Class.forName(type)); + this.nodeTypes.add(typeClass); + } + catch (Exception e) { + IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(), + NLS.bind(Messages.FactoryDelegateProxy_warning_failedToLoadNodeType, nodeTypeElement.getAttribute("class"), element.getDeclaringExtension().getUniqueIdentifier()), e); //$NON-NLS-1$ + Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status); + } + } + } + + nodeTypesLoaded = true; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java index eccd6a288..b739d0ce9 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java @@ -30,4 +30,6 @@ public class Messages extends NLS { // **** Declare externalized string id's down here ***** public static String PendingOperationModelNode_label; + + public static String FactoryDelegateProxy_warning_failedToLoadNodeType; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties index 9fa4cbffc..74497992b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties @@ -4,3 +4,5 @@ # PendingOperationModelNode_label=Pending... + +FactoryDelegateProxy_warning_failedToLoadNodeType=Cannot create node type ''{0}'' for model node factory delegate ''{1}''. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java index d93f862fd..17368c32a 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java @@ -40,6 +40,18 @@ public interface IPersistable { */ public URI getURI(Object data); + /** + * Returns the interface type name to use for recreating the object from the + * persisted object representation. + *

+ * Note: The returned string is expected in the format "<bundleId>:<full qualified interface type name>". + * If the bundle id is not present, it is very likely that the object recreation will fail with a {@link ClassNotFoundException}. + * + * @param data The data object. Must not be null. + * @return The interface type or null. + */ + public String getInterfaceTypeName(Object data); + /** * Exports the given data object to an external representation. *

diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java index d18465c6d..8522891c2 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java @@ -224,7 +224,8 @@ public class PropertiesFilePersistenceDelegate extends AbstractPersistenceDelega while (line != null) { Matcher matcher = SECTION.matcher(line); if (matcher.matches()) { - currentSection = matcher.group(1).toLowerCase(); + // Section names are case-sensitive too + currentSection = matcher.group(1); if (sections.get(currentSection) == null) { sections.put(currentSection, new HashMap()); } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java index e2695c393..d302d769f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java @@ -18,8 +18,8 @@ import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.tcf.protocol.IPeer; -import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable; +import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator; /** * Persistable implementation handling peer attributes. @@ -97,6 +97,18 @@ public class MapPersistableAdapter implements IPersistable { return location; } + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#getInterfaceType(java.lang.Object) + */ + @Override + public String getInterfaceTypeName(Object data) { + if (data instanceof Map) { + // No bundle id needed here, it's a POJO + return Map.class.getName(); + } + return null; + } + /* (non-Javadoc) * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object) */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java index fa7ee71ff..adce7db44 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java @@ -16,8 +16,9 @@ import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Path; import org.eclipse.tcf.protocol.Protocol; -import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable; +import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator; +import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; /** * Persistable implementation handling peer attributes. @@ -64,6 +65,17 @@ public class PeerModelPersistableAdapter implements IPersistable { return uri; } + /* (non-Javadoc) + * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#getInterfaceType(java.lang.Object) + */ + @Override + public String getInterfaceTypeName(Object data) { + if (data instanceof IPeerModel) { + return CoreBundleActivator.getUniqueIdentifier() + ":" + IPeerModel.class.getName(); //$NON-NLS-1$ + } + return null; + } + /* (non-Javadoc) * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object) */ -- cgit v1.2.3 From 49bb357df2dba58049c5c34a9984cef0c895171f Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Fri, 25 Nov 2011 09:30:42 +0100 Subject: Target Explorer: Store the full URI instead of just the path for restored static nodes --- .../core/adapters/ModelNodePersistableAdapter.java | 40 +++++++++++----- .../interfaces/IPersistableNodeProperties.java | 36 ++++++++++++++ .../te/tcf/locator/internal/MyPropertyTester.java | 4 +- .../adapters/PeerModelPersistableAdapter.java | 56 ++++++++++++++-------- .../services/LocatorModelRefreshService.java | 7 ++- .../ui/tables/NodePropertiesContentProvider.java | 6 +-- 6 files changed, 108 insertions(+), 41 deletions(-) create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistableNodeProperties.java diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java index 739a76a6f..e1c6f6b64 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java @@ -31,6 +31,7 @@ import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode; import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; import org.eclipse.tcf.te.runtime.persistence.PersistenceDelegateManager; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable; +import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistableNodeProperties; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistenceDelegate; import org.osgi.framework.Bundle; @@ -59,20 +60,32 @@ public class ModelNodePersistableAdapter implements IPersistable { // Only model nodes are supported if (data instanceof IModelNode) { IModelNode node = (IModelNode) data; - if (node.getName() != null && !"".equals(node.getName().trim())) { //$NON-NLS-1$ - // Get the node name and make it a valid file system name (no spaces etc). - IPath path = getRoot().append(makeValidFileSystemName(node.getName().trim())); - if (!"ini".equals(path.getFileExtension())) path = path.addFileExtension("ini"); //$NON-NLS-1$ //$NON-NLS-2$ - uri = path.toFile().toURI(); + + IPath path = null; + + // If the persistence node name is set, use it and ignore all other possibilities + String persistenceNodeName = node.getStringProperty(IPersistableNodeProperties.PROPERTY_NODE_NAME); + if (persistenceNodeName != null && !"".equals(node.getName().trim())) { //$NON-NLS-1$ + path = getRoot().append(makeValidFileSystemName(persistenceNodeName.trim())); } - // If the name is not set, check for "Path" - else if (node.getStringProperty("Path") != null && !"".equals(node.getStringProperty("Path").trim())) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - IPath path = new Path(node.getStringProperty("Path")); //$NON-NLS-1$ - uri = path.toFile().toURI(); + // If the persistence name not set, check for the node name + else if (node.getName() != null && !"".equals(node.getName().trim())) { //$NON-NLS-1$ + path = getRoot().append(makeValidFileSystemName(node.getName().trim())); + } + // If the name is not set, check for an URI + else if (node.getProperty(IPersistableNodeProperties.PROPERTY_URI) != null) { + Object candidate = node.getProperty(IPersistableNodeProperties.PROPERTY_URI); + if (candidate instanceof URI) uri = (URI)candidate; + else if (candidate instanceof String && !"".equals(((String)candidate).trim())) { //$NON-NLS-1$ + uri = URI.create(((String)candidate).trim()); + } } // No name and no explicit path is set -> use the UUID else if (node.getUUID() != null) { - IPath path = getRoot().append(makeValidFileSystemName(node.getUUID().toString().trim())); + path = getRoot().append(makeValidFileSystemName(node.getUUID().toString().trim())); + } + + if (path != null) { if (!"ini".equals(path.getFileExtension())) path = path.addFileExtension("ini"); //$NON-NLS-1$ //$NON-NLS-2$ uri = path.toFile().toURI(); } @@ -276,14 +289,14 @@ public class ModelNodePersistableAdapter implements IPersistable { // Get the storage id and the URI from the reference String storageID = reference.get("storageID"); //$NON-NLS-1$ - String uri = reference.get("uri"); //$NON-NLS-1$ + String uriString = reference.get("uri"); //$NON-NLS-1$ String interfaceTypeName = reference.get("interfaceType"); //$NON-NLS-1$ // Check if the reference returns complete information to read the referenced storage if (storageID == null) { throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "storageID")); //$NON-NLS-1$ } - if (uri == null) { + if (uriString == null) { throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "uri")); //$NON-NLS-1$ } if (interfaceTypeName == null) { @@ -293,7 +306,8 @@ public class ModelNodePersistableAdapter implements IPersistable { // Get the persistence delegate IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(storageID, false); if (delegate != null) { - Map referenceData = delegate.read(URI.create(uri)); + URI uri = URI.create(uriString); + Map referenceData = delegate.read(uri); if (referenceData != null && !referenceData.isEmpty()) { try { // Now, we have to recreate the object diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistableNodeProperties.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistableNodeProperties.java new file mode 100644 index 000000000..4c85529fe --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistableNodeProperties.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.runtime.persistence.interfaces; + +/** + * Persistable node property constants. + */ +public interface IPersistableNodeProperties { + + /** + * The URI of the node in a persistence storage. + *

+ * This property can be used by persistable implementations to store the URI to remember from + * where a node got restored or written to. + *

+ * The property itself is a transient property. + */ + public static final String PROPERTY_URI = "URI.transient"; //$NON-NLS-1$ + + /** + * The node name to use to store the node to the persistence storage. Typically prepended with + * segments describing the persistence storage hierarchy, like an absolute file path in case of + * a file system based persistence storage. + *

+ * The node name is free text, but all non-word characters are replaced by '_' before creating + * the persistence node. + */ + public static final String PROPERTY_NODE_NAME = "persistenceNodeName"; //$NON-NLS-1$ +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/MyPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/MyPropertyTester.java index b1ebe5ced..eacbb86a7 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/MyPropertyTester.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/MyPropertyTester.java @@ -82,8 +82,8 @@ public class MyPropertyTester extends PropertyTester { } if ("isStaticPeer".equals(property)) { //$NON-NLS-1$ - String path = node.getPeer().getAttributes().get("Path"); //$NON-NLS-1$ - boolean isStaticPeer = path != null && !"".equals(path.trim()); //$NON-NLS-1$ + String value = node.getPeer().getAttributes().get("static.transient"); //$NON-NLS-1$ + boolean isStaticPeer = value != null && Boolean.parseBoolean(value.trim()); if (expectedValue instanceof Boolean) return ((Boolean)expectedValue).booleanValue() == isStaticPeer; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java index adce7db44..0dd1ef35a 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java @@ -11,12 +11,14 @@ package org.eclipse.tcf.te.tcf.locator.internal.adapters; import java.io.IOException; import java.net.URI; +import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.Path; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable; +import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistableNodeProperties; import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; @@ -44,22 +46,21 @@ public class PeerModelPersistableAdapter implements IPersistable { // Only peer model objects are supported if (data instanceof IPeerModel) { - // Get the file path the peer model has been created from - final String[] path = new String[1]; - if (Protocol.isDispatchThread()) { - path[0] = ((IPeerModel)data).getPeer().getAttributes().get("Path"); //$NON-NLS-1$ - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - path[0] = ((IPeerModel)data).getPeer().getAttributes().get("Path"); //$NON-NLS-1$ + // Get the URI the peer model has been created from + final AtomicReference nodeURI = new AtomicReference(); + Runnable runnable = new Runnable() { + @Override + public void run() { + String value = ((IPeerModel)data).getPeer().getAttributes().get(IPersistableNodeProperties.PROPERTY_URI); + if (value != null && !"".equals(value.trim())) { //$NON-NLS-1$ + nodeURI.set(URI.create(value.trim())); } - }); - } + } + }; + if (Protocol.isDispatchThread()) runnable.run(); + else Protocol.invokeAndWait(runnable); - if (path[0] != null && !"".equals(path[0].trim())) { //$NON-NLS-1$ - uri = new Path(path[0].trim()).toFile().toURI(); - } + if (nodeURI.get() != null) uri = nodeURI.get(); } return uri; @@ -80,13 +81,27 @@ public class PeerModelPersistableAdapter implements IPersistable { * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object) */ @Override - public Map exportFrom(Object data) throws IOException { + public Map exportFrom(final Object data) throws IOException { Assert.isNotNull(data); - Map result = null; + final AtomicReference> attributes = new AtomicReference>(); // Only peer model objects are supported if (data instanceof IPeerModel) { + Runnable runnable = new Runnable() { + @Override + public void run() { + attributes.set(((IPeerModel)data).getPeer().getAttributes()); + } + }; + if (Protocol.isDispatchThread()) runnable.run(); + else Protocol.invokeAndWait(runnable); + } + + Map result = null; + if (attributes.get() != null) { + result = new HashMap(); + result.putAll(attributes.get()); } return result; @@ -96,13 +111,12 @@ public class PeerModelPersistableAdapter implements IPersistable { * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#importTo(java.lang.Object, java.util.Map) */ @Override - public void importTo(Object data, Map external) throws IOException { + public void importTo(final Object data, final Map external) throws IOException { Assert.isNotNull(data); Assert.isNotNull(external); - // Only peer model objects are supported - if (data instanceof IPeerModel) { - } + // A direct import of the attributes in a peer is not possible. + // A new peer with the new attributes needs to be created and set to the peer model. } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/services/LocatorModelRefreshService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/services/LocatorModelRefreshService.java index 4fb96826c..d644b69df 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/services/LocatorModelRefreshService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/services/LocatorModelRefreshService.java @@ -29,6 +29,8 @@ import org.eclipse.tcf.core.TransientPeer; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.ILocator; +import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistableNodeProperties; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.locator.ScannerRunnable; import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel; @@ -39,7 +41,6 @@ import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelRefreshSe import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelUpdateService; import org.eclipse.tcf.te.tcf.locator.nodes.LocatorModel; import org.eclipse.tcf.te.tcf.locator.nodes.PeerModel; -import org.eclipse.tcf.te.tcf.core.Tcf; /** @@ -172,7 +173,9 @@ public class LocatorModelRefreshService extends AbstractLocatorModelService impl } // Remember the file path within the properties - properties.setProperty("Path", candidate.getAbsolutePath()); //$NON-NLS-1$ + properties.setProperty(IPersistableNodeProperties.PROPERTY_URI, candidate.getAbsoluteFile().toURI().toString()); + // Mark the node as static peer model node + properties.setProperty("static.transient", "true"); //$NON-NLS-1$ //$NON-NLS-2$ // Validate the name attribute. If not set, set // it to the file name without the .ini extension. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/tables/NodePropertiesContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/tables/NodePropertiesContentProvider.java index be37140e5..5629da711 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/tables/NodePropertiesContentProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/tables/NodePropertiesContentProvider.java @@ -23,9 +23,9 @@ import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Control; import org.eclipse.tcf.protocol.Protocol; -import org.eclipse.tcf.te.tcf.ui.nls.Messages; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties; +import org.eclipse.tcf.te.tcf.ui.nls.Messages; import org.eclipse.tcf.te.ui.tables.properties.NodePropertiesTableTableNode; import org.eclipse.ui.forms.widgets.Section; @@ -41,7 +41,7 @@ public class NodePropertiesContentProvider implements IStructuredContentProvider protected final static String[] FILTERED_PROPERTIES = new String[] { "name", "typeLabel", //$NON-NLS-1$ //$NON-NLS-2$ "instance", "childrenQueried", //$NON-NLS-1$ //$NON-NLS-2$ - IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, "Path", //$NON-NLS-1$ + IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, "hasTabularProperties" //$NON-NLS-1$ }; @@ -93,7 +93,7 @@ public class NodePropertiesContentProvider implements IStructuredContentProvider for (String name : properties.keySet()) { // Check if the property is filtered - if (name.endsWith(".silent") || Arrays.asList(FILTERED_PROPERTIES).contains(name)) continue; //$NON-NLS-1$ + if (name.endsWith(".silent") || name.contains(".transient") || Arrays.asList(FILTERED_PROPERTIES).contains(name)) continue; //$NON-NLS-1$ //$NON-NLS-2$ // Create the properties node, if not one of the services nodes if (!IPeerModelProperties.PROP_LOCAL_SERVICES.equals(name) && !IPeerModelProperties.PROP_REMOTE_SERVICES.equals(name)) { NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode(name, properties.get(name) != null ? properties.get(name).toString() : ""); //$NON-NLS-1$ -- cgit v1.2.3 From 391a301f7750b43ae2fc6918eedc1c013b0e17bc Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Mon, 28 Nov 2011 10:12:08 +0100 Subject: Target Explorer: Extended TCF channel manager to allow sharing an active channel to reduce the number of open channels to the same peer --- .../plugins/org.eclipse.tcf.te.tcf.core/.options | 4 +- .../META-INF/MANIFEST.MF | 3 +- .../te/tcf/core/activator/CoreBundleActivator.java | 17 +- .../te/tcf/core/interfaces/IChannelManager.java | 51 +++- .../tcf/te/tcf/core/internal/ChannelManager.java | 282 ++++++++++++++++++--- .../internal/listener/InternalChannelListener.java | 3 +- .../listener/InternalChannelOpenListener.java | 3 +- .../tcf/te/tcf/core/internal/nls/Messages.java | 11 +- .../te/tcf/core/internal/nls/Messages.properties | 10 + .../te/tcf/core/internal/tracing/ITraceIds.java | 26 ++ .../filesystem/controls/FSTreeContentProvider.java | 23 +- .../filesystem/internal/handlers/StateManager.java | 14 +- .../filesystem/internal/handlers/UserManager.java | 29 +-- .../tcf/filesystem/internal/operations/FSCopy.java | 13 +- .../filesystem/internal/operations/FSDelete.java | 17 +- .../tcf/filesystem/internal/operations/FSMove.java | 19 +- .../internal/operations/FSOperation.java | 44 ++-- .../filesystem/internal/operations/FSRefresh.java | 19 +- .../filesystem/internal/operations/FSRename.java | 17 +- .../filesystem/internal/url/TcfURLConnection.java | 4 +- .../tcf/te/tcf/locator/nodes/PeerModel.java | 29 ++- .../processes/core/launcher/ProcessLauncher.java | 16 +- .../ui/controls/ProcessesTreeContentProvider.java | 26 +- .../handler/AbstractChannelCommandHandler.java | 37 +-- .../core/activator/CoreBundleActivator.java | 1 + .../terminals/core/launcher/TerminalsLauncher.java | 14 +- 26 files changed, 485 insertions(+), 247 deletions(-) create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/tracing/ITraceIds.java diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/.options b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/.options index 4367d1867..910e6f7d1 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/.options +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/.options @@ -1 +1,3 @@ -org.eclipse.tcf.te.tcf.core/debug/channels = false +org.eclipse.tcf.te.tcf.core/debugmode = 0 +org.eclipse.tcf.te.tcf.core/trace/channels = false +org.eclipse.tcf.te.tcf.core/trace/channelManager = false diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/META-INF/MANIFEST.MF index e5302f890..e14b41336 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/META-INF/MANIFEST.MF +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/META-INF/MANIFEST.MF @@ -6,7 +6,8 @@ Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.tcf.te.tcf.core.activator.CoreBundleActivator Bundle-Vendor: %providerName Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0", - org.eclipse.tcf.core;bundle-version="1.0.0" + org.eclipse.tcf.core;bundle-version="1.0.0", + org.eclipse.tcf.te.runtime;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java index e716a3b8d..e8ac5c042 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java @@ -9,6 +9,7 @@ *******************************************************************************/ package org.eclipse.tcf.te.tcf.core.activator; +import org.eclipse.tcf.te.runtime.tracing.TraceHandler; import org.eclipse.tcf.te.tcf.core.internal.Startup; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -20,6 +21,8 @@ import org.osgi.framework.BundleContext; public class CoreBundleActivator implements BundleActivator { // The bundle context private static BundleContext context; + // The trace handler instance + private static TraceHandler traceHandler; /** * Returns the bundle context @@ -40,6 +43,18 @@ public class CoreBundleActivator implements BundleActivator { return null; } + /** + * Returns the bundles trace handler. + * + * @return The bundles trace handler. + */ + public static TraceHandler getTraceHandler() { + if (traceHandler == null) { + traceHandler = new TraceHandler(getUniqueIdentifier()); + } + return traceHandler; + } + /* (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ @@ -54,9 +69,9 @@ public class CoreBundleActivator implements BundleActivator { @Override public void stop(BundleContext bundleContext) throws Exception { CoreBundleActivator.context = null; - // Mark the core framework as not started anymore Startup.setStarted(false); + traceHandler = null; } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java index b7d7aca1f..1b2d290e6 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java @@ -3,7 +3,7 @@ * 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: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -20,37 +20,60 @@ import org.eclipse.tcf.protocol.IPeer; */ public interface IChannelManager extends IAdaptable { - /** - * Client call back interface for openChannel(...). - */ + /** + * Client call back interface for openChannel(...). + */ interface DoneOpenChannel { - /** - * Called when the channel fully opened or failed to open. - * - * @param error The error description if operation failed, null if succeeded. - * @param channel The channel object or null. - */ + /** + * Called when the channel fully opened or failed to open. + * + * @param error The error description if operation failed, null if succeeded. + * @param channel The channel object or null. + */ void doneOpenChannel(Throwable error, IChannel channel); } /** * Opens a new channel to communicate with the given peer. *

+ * If forceNew is true, a new and not reference counted channel is + * opened and returned. The returned channel must be closed by the caller himself. The channel + * manager is not keeping track of non reference counted channels. + *

+ * Reference counted channels are cached by the channel manager and must be closed via {@link #closeChannel(IChannel)}. + *

* The method can be called from any thread context. * * @param peer The peer. Must not be null. * @param done The client callback. Must not be null. */ - public void openChannel(IPeer peer, DoneOpenChannel done); + public void openChannel(IPeer peer, boolean forceNew, DoneOpenChannel done); /** - * Opens a new channel to communicate with the peer described by the - * given peer attributes. + * Opens a new channel to communicate with the peer described by the given peer attributes. + *

+ * If forceNew is true, a new and not reference counted channel is + * opened and returned. The returned channel must be closed by the caller himself. The channel + * manager is not keeping track of non reference counted channels. + *

+ * Reference counted channels are cached by the channel manager and must be closed via {@link #closeChannel(IChannel)}. *

* The method can be called from any thread context. * * @param peerAttributes The peer attributes. Must not be null. * @param done The client callback. Must not be null. */ - public void openChannel(Map peerAttributes, DoneOpenChannel done); + public void openChannel(Map peerAttributes, boolean forceNew, DoneOpenChannel done); + + /** + * Closes the given channel. + *

+ * If the given channel is a reference counted channel, the channel will be closed if the reference counter + * reaches 0. For non reference counted channels, the channel is closed immediately. + *

+ * The method can be called from any thread context. + * + * @param channel The channel. Must not be null. + */ + public void closeChannel(IChannel channel); } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java index 1be6135fa..f587383fc 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java @@ -9,22 +9,85 @@ *******************************************************************************/ package org.eclipse.tcf.te.tcf.core.internal; +import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.osgi.util.NLS; import org.eclipse.tcf.core.AbstractPeer; import org.eclipse.tcf.core.TransientPeer; import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; +import org.eclipse.tcf.te.tcf.core.activator.CoreBundleActivator; import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; +import org.eclipse.tcf.te.tcf.core.internal.nls.Messages; +import org.eclipse.tcf.te.tcf.core.internal.tracing.ITraceIds; /** * TCF channel manager implementation. */ public final class ChannelManager extends PlatformObject implements IChannelManager { + // The map of reference counters per peer id + /* default */ final Map refCounters = new HashMap(); + // The map of channels per peer id + /* default */ final Map channels = new HashMap(); + + /** + * The channel monitor keeps watching the channel after it got successfully opened. + * If the channel is closing eventually, the channel monitor cleans out the reference + * counter and the channels map. + */ + private final class ChannelMonitor implements IChannel.IChannelListener { + // Reference to the monitored channel + private final IChannel channel; + // Reference to the peer id the channel got opened for + private final String id; + + /** + * Constructor. + * + * @param The peer id. Must not be null. + * @param The channel. Must not be null. + */ + public ChannelMonitor(String id, IChannel channel) { + Assert.isNotNull(id); + Assert.isNotNull(channel); + + this.id = id; + this.channel = channel; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelOpened() + */ + @Override + public void onChannelOpened() { + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable) + */ + @Override + public void onChannelClosed(Throwable error) { + // Remove ourself + channel.removeChannelListener(this); + // Clean the reference counter and the channel map + channels.remove(id); + refCounters.remove(id); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#congestionLevel(int) + */ + @Override + public void congestionLevel(int level) { + } + } /** * Constructor. @@ -34,17 +97,17 @@ public final class ChannelManager extends PlatformObject implements IChannelMana } /* (non-Javadoc) - * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#openChannel(org.eclipse.tcf.protocol.IPeer, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel) + * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#openChannel(org.eclipse.tcf.protocol.IPeer, boolean, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel) */ @Override - public void openChannel(final IPeer peer, final DoneOpenChannel done) { + public void openChannel(final IPeer peer, final boolean forceNew, final DoneOpenChannel done) { if (Protocol.isDispatchThread()) { - internalOpenChannel(peer, done); + internalOpenChannel(peer, forceNew, done); } else { Protocol.invokeLater(new Runnable() { @Override public void run() { - internalOpenChannel(peer, done); + internalOpenChannel(peer, forceNew, done); } }); } @@ -53,62 +116,133 @@ public final class ChannelManager extends PlatformObject implements IChannelMana /** * Internal implementation of {@link #openChannel(IPeer, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)}. *

+ * If forceNew is true, a new and not reference counted channel is opened and returned. The returned + * channel must be closed by the caller himself. The channel manager is not keeping track of non reference counted channels. + *

+ * Reference counted channels are cached by the channel manager and must be closed via ... . + *

* Method must be called within the TCF dispatch thread. * * @param peer The peer. Must not be null. + * @param forceNew Specify true to force opening a new channel, false otherwise. * @param done The client callback. Must not be null. */ - /* default */ void internalOpenChannel(final IPeer peer, final DoneOpenChannel done) { + /* default */ void internalOpenChannel(final IPeer peer, final boolean forceNew, final DoneOpenChannel done) { Assert.isNotNull(peer); Assert.isNotNull(done); - Assert.isTrue(Protocol.isDispatchThread()); + Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ - // Open the channel - final IChannel channel = peer.openChannel(); - // Register the channel listener - if (channel != null) { - channel.addChannelListener(new IChannel.IChannelListener() { + // The channel instance to return + IChannel channel = null; - @Override - public void onChannelOpened() { - // Remove ourself as listener from the channel - channel.removeChannelListener(this); - // Channel opening succeeded - done.doneOpenChannel(null, channel); - } + // Get the peer id + final String id = peer.getID(); - @Override - public void onChannelClosed(Throwable error) { - // Remove ourself as listener from the channel - channel.removeChannelListener(this); - // Channel opening failed - done.doneOpenChannel(error, channel); - } + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_message, id, Boolean.valueOf(forceNew)), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + + // Check if there is already a channel opened to this peer + channel = !forceNew ? channels.get(id) : null; + if (channel != null && (channel.getState() == IChannel.STATE_OPEN || channel.getState() == IChannel.STATE_OPENING)) { + // Increase the reference count + AtomicInteger counter = refCounters.get(id); + if (counter == null) { + counter = new AtomicInteger(0); + refCounters.put(id, counter); + } + counter.incrementAndGet(); + + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_reuse_message, id, counter.toString()), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + } else if (channel != null) { + // Channel is not in open state -> drop the instance + channel = null; + channels.remove(id); + refCounters.remove(id); + } + + // Opens a new channel if necessary + if (channel == null) { + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_new_message, id), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + + channel = peer.openChannel(); + + if (channel != null) { + if (!forceNew) channels.put(id, channel); + if (!forceNew) refCounters.put(id, new AtomicInteger(1)); + + // Register the channel listener + final IChannel finChannel = channel; + channel.addChannelListener(new IChannel.IChannelListener() { + + @Override + public void onChannelOpened() { + // Remove ourself as listener from the channel + finChannel.removeChannelListener(this); + // Register the channel monitor + finChannel.addChannelListener(new ChannelMonitor(id, finChannel)); + + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_success_message, id), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + + // Channel opening succeeded + done.doneOpenChannel(null, finChannel); + } + + @Override + public void onChannelClosed(Throwable error) { + // Remove ourself as listener from the channel + finChannel.removeChannelListener(this); + // Clean the reference counter and the channel map + channels.remove(id); + refCounters.remove(id); + + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_openChannel_failed_message, id, error), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + + // Channel opening failed + done.doneOpenChannel(error, finChannel); + } + + @Override + public void congestionLevel(int level) { + // ignored + } + }); + } else { + // Channel is null? Something went terrible wrong. + done.doneOpenChannel(new Exception("Unexpected null return value from IPeer#openChannel()!"), null); //$NON-NLS-1$ + } - @Override - public void congestionLevel(int level) { - // ignored - } - }); } else { - // Channel is null? Something went terrible wrong. - done.doneOpenChannel(new Exception("Unexpected null return value from IPeer#openChannel()!"), null); //$NON-NLS-1$ + done.doneOpenChannel(null, channel); } } /* (non-Javadoc) - * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#openChannel(java.util.Map, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel) + * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#openChannel(java.util.Map, boolean, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel) */ @Override - public void openChannel(final Map peerAttributes, final DoneOpenChannel done) { + public void openChannel(final Map peerAttributes, final boolean forceNew, final DoneOpenChannel done) { if (Protocol.isDispatchThread()) { - internalOpenChannel(peerAttributes, done); + internalOpenChannel(peerAttributes, forceNew, done); } else { Protocol.invokeLater(new Runnable() { @Override public void run() { - internalOpenChannel(peerAttributes, done); + internalOpenChannel(peerAttributes, forceNew, done); } }); } @@ -120,13 +254,14 @@ public final class ChannelManager extends PlatformObject implements IChannelMana * Method must be called within the TCF dispatch thread. * * @param peerAttributes The peer attributes. Must not be null. + * @param forceNew Specify true to force opening a new channel, false otherwise. * @param done The client callback. Must not be null. */ - /* default */ void internalOpenChannel(final Map peerAttributes, final DoneOpenChannel done) { + /* default */ void internalOpenChannel(final Map peerAttributes, final boolean forceNew, final DoneOpenChannel done) { Assert.isNotNull(peerAttributes); Assert.isNotNull(done); - Assert.isTrue(Protocol.isDispatchThread()); - internalOpenChannel(getOrCreatePeerInstance(peerAttributes), done); + Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ + internalOpenChannel(getOrCreatePeerInstance(peerAttributes), forceNew, done); } /** @@ -140,7 +275,7 @@ public final class ChannelManager extends PlatformObject implements IChannelMana */ private IPeer getOrCreatePeerInstance(final Map peerAttributes) { Assert.isNotNull(peerAttributes); - Assert.isTrue(Protocol.isDispatchThread()); + Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ // Get the peer id from the properties String peerId = peerAttributes.get(IPeer.ATTR_ID); @@ -154,9 +289,76 @@ public final class ChannelManager extends PlatformObject implements IChannelMana // If not peer could be found, create a new one if (peer == null) { peer = isTransient ? new TransientPeer(peerAttributes) : new AbstractPeer(peerAttributes); + + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_createPeer_new_message, peerId, Boolean.valueOf(isTransient)), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } } // Return the peer instance return peer; } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#closeChannel(org.eclipse.tcf.protocol.IChannel) + */ + @Override + public void closeChannel(final IChannel channel) { + if (Protocol.isDispatchThread()) { + internalCloseChannel(channel); + } else { + Protocol.invokeLater(new Runnable() { + @Override + public void run() { + internalCloseChannel(channel); + } + }); + } + } + + /** + * Closes the given channel. + *

+ * If the given channel is a reference counted channel, the channel will be closed if the reference counter + * reaches 0. For non reference counted channels, the channel is closed immediately. + *

+ * Note: This method must be invoked at the TCF dispatch thread. + * + * @param channel The channel. Must not be null. + */ + /* default */ void internalCloseChannel(IChannel channel) { + Assert.isNotNull(channel); + Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ + + // Get the id of the remote peer + String id = channel.getRemotePeer().getID(); + + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_closeChannel_message, id), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + + // Get the reference counter + AtomicInteger counter = refCounters.get(id); + + // If the counter is null or get 0 after the decrement, close the channel + if (counter == null || counter.decrementAndGet() == 0) { + channel.close(); + + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_closeChannel_closed_message, id), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + } else { + if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_CHANNEL_MANAGER)) { + CoreBundleActivator.getTraceHandler().trace(NLS.bind(Messages.ChannelManager_closeChannel_inuse_message, id, counter.toString()), + 0, ITraceIds.TRACE_CHANNEL_MANAGER, IStatus.INFO, this); + } + } + + // Clean the reference counter and the channel map + refCounters.remove(id); + channels.remove(id); + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java index 8f77376ad..a6858df6f 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java @@ -16,6 +16,7 @@ import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.core.internal.interfaces.IChannelOpenListener; import org.eclipse.tcf.te.tcf.core.internal.nls.Messages; +import org.eclipse.tcf.te.tcf.core.internal.tracing.ITraceIds; import org.eclipse.tcf.te.tcf.core.internal.utils.LogUtils; @@ -69,7 +70,7 @@ public class InternalChannelListener implements IChannel.IChannelListener { } // Trace the channel closing - LogUtils.logMessageForChannel(getChannel(), NLS.bind(Messages.InternalChannelListener_onChannelClosed_message, cause), "debug/channels", this); //$NON-NLS-1$ + LogUtils.logMessageForChannel(getChannel(), NLS.bind(Messages.InternalChannelListener_onChannelClosed_message, cause), ITraceIds.TRACE_CHANNELS, this); // Fire the property change event for the channel Tcf.fireChannelStateChangeListeners(getChannel(), IChannel.STATE_CLOSED); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java index 9d5e093c4..5a9930561 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java @@ -19,6 +19,7 @@ import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.core.internal.interfaces.IChannelOpenListener; import org.eclipse.tcf.te.tcf.core.internal.nls.Messages; +import org.eclipse.tcf.te.tcf.core.internal.tracing.ITraceIds; import org.eclipse.tcf.te.tcf.core.internal.utils.LogUtils; @@ -39,7 +40,7 @@ public class InternalChannelOpenListener implements IChannelOpenListener { Assert.isTrue(Protocol.isDispatchThread()); // Trace the channel opening - LogUtils.logMessageForChannel(channel, Messages.InternalChannelOpenListener_onChannelOpen_message, "debug/channels", this); //$NON-NLS-1$ + LogUtils.logMessageForChannel(channel, Messages.InternalChannelOpenListener_onChannelOpen_message, ITraceIds.TRACE_CHANNELS, this); // As the channel has just opened, there should be no channel listener, but better be safe and check. IChannel.IChannelListener channelListener = channelListeners.remove(channel); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java index a3e6ca469..5291bf610 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java @@ -3,7 +3,7 @@ * 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: * Wind River Systems - initial API and implementation *******************************************************************************/ @@ -74,4 +74,13 @@ public class Messages extends NLS { public static String InternalChannelListener_onChannelClosed_message; public static String InternalChannelListener_onChannelClosed_cause; + public static String ChannelManager_openChannel_message; + public static String ChannelManager_openChannel_reuse_message; + public static String ChannelManager_openChannel_new_message; + public static String ChannelManager_openChannel_success_message; + public static String ChannelManager_openChannel_failed_message; + public static String ChannelManager_createPeer_new_message; + public static String ChannelManager_closeChannel_message; + public static String ChannelManager_closeChannel_inuse_message; + public static String ChannelManager_closeChannel_closed_message; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties index 50c4de0de..074a24a6d 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties @@ -7,3 +7,13 @@ InternalChannelOpenListener_onChannelOpen_message=Channel opened. InternalChannelListener_onChannelClosed_message=Channel closed. {0} InternalChannelListener_onChannelClosed_cause=; Possibly caused by: {0} + +ChannelManager_openChannel_message=Request to open channel. Peer id = {0}, forceNew = {1} +ChannelManager_openChannel_reuse_message=Reusing already opened channel. Peer id = {0}, new reference count = {1} +ChannelManager_openChannel_new_message=Opening new channel. Peer id = {0} +ChannelManager_openChannel_success_message=Opening channel succeeded. Peer id = {0} +ChannelManager_openChannel_failed_message=Opening channel failed. Peer id = {0}, cause = {1} +ChannelManager_createPeer_new_message=New peer created. Peer id = {0}, isTransient = {1} +ChannelManager_closeChannel_message=Request to close channel. Peer id = {0} +ChannelManager_closeChannel_inuse_message=Channel not closed. Still in use. Peer id = {0}, new reference count = {1} +ChannelManager_closeChannel_closed_message=Closed channel. Peer id = {0} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/tracing/ITraceIds.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/tracing/ITraceIds.java new file mode 100644 index 000000000..9c77bccaf --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/tracing/ITraceIds.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.core.internal.tracing; + +/** + * TCF core plug-in trace slot identifiers. + */ +public interface ITraceIds { + + /** + * If activated, tracing information about channel open/close is printed out. + */ + public static String TRACE_CHANNELS = "trace/channels"; //$NON-NLS-1$ + + /** + * If activated, tracing information about the channel manager is printed out. + */ + public static String TRACE_CHANNEL_MANAGER = "trace/channelManager"; //$NON-NLS-1$ +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java index 2dcb2c04e..2968f27fd 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java @@ -28,11 +28,11 @@ import org.eclipse.tcf.services.IFileSystem; import org.eclipse.tcf.services.IFileSystem.DirEntry; import org.eclipse.tcf.services.IFileSystem.FileSystemException; import org.eclipse.tcf.services.IFileSystem.IFileHandle; +import org.eclipse.tcf.te.tcf.core.Tcf; +import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; import org.eclipse.tcf.te.tcf.filesystem.internal.events.INodeStateListener; import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; -import org.eclipse.tcf.te.tcf.core.Tcf; -import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties; import org.eclipse.tcf.te.ui.nls.Messages; @@ -80,18 +80,7 @@ public class FSTreeContentProvider implements ITreeContentProvider, INodeStateLi * Close the open communication channel. */ protected void closeOpenChannel(final IChannel channel) { - if (channel != null) { - if (Protocol.isDispatchThread()) { - channel.close(); - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - channel.close(); - } - }); - } - } + if (channel != null) Tcf.getChannelManager().closeChannel(channel); } /* (non-Javadoc) @@ -185,7 +174,7 @@ public class FSTreeContentProvider implements ITreeContentProvider, INodeStateLi children = candidates.toArray(); - Tcf.getChannelManager().openChannel(peer, new IChannelManager.DoneOpenChannel() { + Tcf.getChannelManager().openChannel(peer, false, new IChannelManager.DoneOpenChannel() { @Override public void doneOpenChannel(final Throwable error, final IChannel channel) { Assert.isTrue(Protocol.isDispatchThread()); @@ -308,7 +297,7 @@ public class FSTreeContentProvider implements ITreeContentProvider, INodeStateLi if (absName != null) { // Open a channel to the peer and query the children - Tcf.getChannelManager().openChannel(node.peerNode.getPeer(), new IChannelManager.DoneOpenChannel() { + Tcf.getChannelManager().openChannel(node.peerNode.getPeer(), false, new IChannelManager.DoneOpenChannel() { @Override public void doneOpenChannel(final Throwable error, final IChannel channel) { Assert.isTrue(Protocol.isDispatchThread()); @@ -368,7 +357,7 @@ public class FSTreeContentProvider implements ITreeContentProvider, INodeStateLi /** * Adapt the specified element to a IPeerModel. - * + * * @param element The element to be adapted. * @return The IPeerModel adapted. */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java index ba6a4f4ce..7ab4d5c4b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java @@ -22,6 +22,8 @@ import org.eclipse.tcf.services.IFileSystem.DoneSetStat; import org.eclipse.tcf.services.IFileSystem.DoneStat; import org.eclipse.tcf.services.IFileSystem.FileAttrs; import org.eclipse.tcf.services.IFileSystem.FileSystemException; +import org.eclipse.tcf.te.tcf.core.Tcf; +import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFChannelException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; @@ -30,8 +32,6 @@ import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; import org.eclipse.tcf.te.tcf.filesystem.model.CacheState; import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; -import org.eclipse.tcf.te.tcf.core.Tcf; -import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel; /** * This class provides several utility methods to get, update, commit @@ -125,8 +125,7 @@ public class StateManager { } } } finally { - if (channel != null) - channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); } } @@ -151,7 +150,7 @@ public class StateManager { /** * Set the file's attributes using the new attributes. - * + * * @param node The file's node. * @param attrs The new file attributes. * @throws TCFException @@ -193,8 +192,7 @@ public class StateManager { } } } finally { - if (channel != null) - channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); } } @@ -207,7 +205,7 @@ public class StateManager { final Rendezvous rendezvous = new Rendezvous(); final TCFChannelException[] errors = new TCFChannelException[1]; final IChannel[] channels = new IChannel[1]; - Tcf.getChannelManager().openChannel(peer, new DoneOpenChannel(){ + Tcf.getChannelManager().openChannel(peer, false, new DoneOpenChannel(){ @Override public void doneOpenChannel(Throwable error, IChannel channel) { if(error!=null){ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java index 88b082394..76ab4b451 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java @@ -21,14 +21,14 @@ import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.IFileSystem; import org.eclipse.tcf.services.IFileSystem.DoneUser; import org.eclipse.tcf.services.IFileSystem.FileSystemException; +import org.eclipse.tcf.te.tcf.core.Tcf; +import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel; import org.eclipse.tcf.te.tcf.filesystem.internal.UserAccount; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFChannelException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; -import org.eclipse.tcf.te.tcf.core.Tcf; -import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.ui.PlatformUI; @@ -107,20 +107,19 @@ public class UserManager { UserAccount account = getUserFromPeer(peerNode); if (account == null) { IChannel channel = null; - try{ - channel = openChannel(peerNode.getPeer()); - if (channel != null) { - account = getUserByChannel(channel); - if (account != null) - setUserToPeer(peerNode, account); + try { + channel = openChannel(peerNode.getPeer()); + if (channel != null) { + account = getUserByChannel(channel); + if (account != null) setUserToPeer(peerNode, account); + } } - }catch(TCFException e){ + catch (TCFException e) { Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); MessageDialog.openError(parent, Messages.UserManager_UserAccountTitle, e.getLocalizedMessage()); - }finally{ - if(channel!=null){ - channel.close(); - } + } + finally { + if (channel != null) Tcf.getChannelManager().closeChannel(channel); } } return account; @@ -135,7 +134,7 @@ public class UserManager { final Rendezvous rendezvous = new Rendezvous(); final TCFChannelException[] errors = new TCFChannelException[1]; final IChannel[] channels = new IChannel[1]; - Tcf.getChannelManager().openChannel(peer, new DoneOpenChannel(){ + Tcf.getChannelManager().openChannel(peer, false, new DoneOpenChannel(){ @Override public void doneOpenChannel(Throwable error, IChannel channel) { if(error!=null){ @@ -159,7 +158,7 @@ public class UserManager { } return channels[0]; } - + /** * Get the user account stored in the specified peer model using a key named * "user.account" defined by the constant USER_ACCOUNT_KEY. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java index 94793d607..1ec11170c 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java @@ -23,6 +23,7 @@ import org.eclipse.tcf.protocol.IToken; import org.eclipse.tcf.services.IFileSystem; import org.eclipse.tcf.services.IFileSystem.DoneCopy; import org.eclipse.tcf.services.IFileSystem.FileSystemException; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager; @@ -44,7 +45,7 @@ public class FSCopy extends FSOperation { /** * Create a copy operation using the specified nodes and destination folder. - * + * * @param nodes The file/folder nodes to be copied. * @param dest The destination folder to be copied to. */ @@ -89,7 +90,7 @@ public class FSCopy extends FSOperation { throw new InvocationTargetException(e); } finally { - if (channel != null) channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); // Refresh the file system tree. FSModel.getInstance().fireNodeStateChanged(null); monitor.done(); @@ -114,7 +115,7 @@ public class FSCopy extends FSOperation { /** * Copy the file/folder represented by the specified node to the destination folder. - * + * * @param monitor The monitor to report the progress. * @param service The file system service to do the remote copying. * @param node The file/folder node to be copied. @@ -133,7 +134,7 @@ public class FSCopy extends FSOperation { /** * Copy the folder represented by the specified node to the destination folder. - * + * * @param monitor The monitor to report the progress. * @param service The file system service to do the remote copying. * @param node The folder node to be copied. @@ -164,7 +165,7 @@ public class FSCopy extends FSOperation { /** * Copy the children of the node to the destination folder. - * + * * @param monitor The monitor to report the progress. * @param service The file system service to do the remote copying. * @param node The folder node to be copied. @@ -184,7 +185,7 @@ public class FSCopy extends FSOperation { /** * Copy the file represented by the specified node to the destination folder. - * + * * @param monitor The monitor to report the progress. * @param service The file system service to do the remote copying. * @param node The file node to be copied. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java index eb598f426..59905d3fc 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java @@ -27,6 +27,7 @@ import org.eclipse.tcf.protocol.IToken; import org.eclipse.tcf.services.IFileSystem; import org.eclipse.tcf.services.IFileSystem.DoneRemove; import org.eclipse.tcf.services.IFileSystem.FileSystemException; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; @@ -48,7 +49,7 @@ public class FSDelete extends FSOperation { /** * Create a delete operation using the specified nodes. - * + * * @param nodes The nodes to be deleted. */ public FSDelete(List nodes) { @@ -89,7 +90,7 @@ public class FSDelete extends FSOperation { throw new InvocationTargetException(e); } finally { - if (channel != null) channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); // Refresh the file system tree. FSModel.getInstance().fireNodeStateChanged(null); monitor.done(); @@ -114,7 +115,7 @@ public class FSDelete extends FSOperation { /** * Delete the file/folder node using the file system service. - * + * * @param monitor The monitor to report the progress. * @param node The file/folder node to be deleted. * @param service The file system service. @@ -132,7 +133,7 @@ public class FSDelete extends FSOperation { /** * Delete the folder node and its children using the file system service. - * + * * @param monitor The monitor to report the progress. * @param node The folder node to be deleted. * @param service The file system service. @@ -155,7 +156,7 @@ public class FSDelete extends FSOperation { /** * Delete the folder node using the file system service. - * + * * @param monitor The monitor to report the progress. * @param node The folder node to be deleted. * @param service The file system service. @@ -193,7 +194,7 @@ public class FSDelete extends FSOperation { /** * Delete the file node using the file system service. - * + * * @param monitor The monitor to report the progress. * @param node The file node to be deleted. * @param service The file system service. @@ -238,10 +239,10 @@ public class FSDelete extends FSOperation { removeFile(node, service); monitor.worked(1); } - + /** * Confirm deleting the read only file. - * + * * @param node The read only file node. * @return The confirming result, 0-yes, 1-yes to all, 2-no, 3-cancel. */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java index bda749f9c..b6bd5f01d 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java @@ -18,6 +18,12 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.protocol.IToken; +import org.eclipse.tcf.services.IFileSystem; +import org.eclipse.tcf.services.IFileSystem.DoneRename; +import org.eclipse.tcf.services.IFileSystem.FileSystemException; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; @@ -26,11 +32,6 @@ import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; -import org.eclipse.tcf.protocol.IChannel; -import org.eclipse.tcf.protocol.IToken; -import org.eclipse.tcf.services.IFileSystem; -import org.eclipse.tcf.services.IFileSystem.DoneRename; -import org.eclipse.tcf.services.IFileSystem.FileSystemException; import org.eclipse.ui.PlatformUI; /** @@ -44,7 +45,7 @@ public class FSMove extends FSOperation { /** * Create a move operation to move the specified nodes to the destination folder. - * + * * @param nodes The nodes to be moved. * @param dest the destination folder to move to. */ @@ -89,7 +90,7 @@ public class FSMove extends FSOperation { finally { // Clear the clip board. UIPlugin.getDefault().getClipboard().clear(); - if (channel != null) channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); // Refresh the file system tree. FSModel.getInstance().fireNodeStateChanged(null); monitor.done(); @@ -114,7 +115,7 @@ public class FSMove extends FSOperation { /** * Move the file/folder to the destination folder using the specified file system service. - * + * * @param monitor The monitor used to report the moving progress. * @param service The file system service used to move the remote files. * @param node The file/folder node to be moved. @@ -187,7 +188,7 @@ public class FSMove extends FSOperation { /** * Clean up the node after successful moving. - * + * * @param node The node being moved. * @param copyNode The target node that is moved to. */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java index 89df3f59f..bebedbf01 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java @@ -72,7 +72,7 @@ public abstract class FSOperation { * Get the top most nodes of the specified node list, removing those nodes whose ancestors are * one of the other nodes in the list. This method is used to remove those children or grand * children of the nodes that are cut, copied, moved or deleted. - * + * * @param nodes The original node list. * @return The top most nodes. */ @@ -88,7 +88,7 @@ public abstract class FSOperation { /** * If the target node has ancestor in the specified node list. - * + * * @param target The node to be tested. * @param nodes The node list to search in. * @return true if the target node has an ancestor in the node list. @@ -104,7 +104,7 @@ public abstract class FSOperation { /** * Clean up the folder node after moving, deleting or copying. - * + * * @param node the folder node that is to be cleaned. */ protected void cleanUpFolder(FSTreeNode node) { @@ -122,7 +122,7 @@ public abstract class FSOperation { * Close the editor that opens the specified file. *

* Note: The method must be called within the UI thread. - * + * * @param file The file that is opened. */ protected void closeEditor(final File file) { @@ -150,7 +150,7 @@ public abstract class FSOperation { /** * Clean up the file node after moving, deleting or copying. - * + * * @param node the file node that is to be cleaned. */ protected void cleanUpFile(FSTreeNode node) { @@ -174,14 +174,14 @@ public abstract class FSOperation { /** * Open a channel connected to the target represented by the peer. - * + * * @return The channel or null if the operation fails. */ protected IChannel openChannel(final IPeer peer) throws TCFChannelException { final Rendezvous rendezvous = new Rendezvous(); final TCFChannelException[] errors = new TCFChannelException[1]; final IChannel[] channels = new IChannel[1]; - Tcf.getChannelManager().openChannel(peer, new DoneOpenChannel() { + Tcf.getChannelManager().openChannel(peer, false, new DoneOpenChannel() { @Override public void doneOpenChannel(Throwable error, IChannel channel) { if (error != null) { @@ -210,7 +210,7 @@ public abstract class FSOperation { /** * Count the total nodes in the node list including their children and grand children * recursively. - * + * * @param service The file system service used to open those folders that are not expanded yet. * @param nodes The node list to be counted. * @return The count of the total nodes. @@ -233,7 +233,7 @@ public abstract class FSOperation { /** * Get the children of the specified folder node. If the folder node is not expanded, then * expanded using the specified file system service. - * + * * @param node The folder node. * @param service The file system service. * @return The children of the folder node. @@ -249,7 +249,7 @@ public abstract class FSOperation { /** * Get the current children of the specified folder node. - * + * * @param node The folder node. * @return The children of the folder node. */ @@ -271,7 +271,7 @@ public abstract class FSOperation { /** * Load the children of the specified folder node using the file system service. - * + * * @param node The folder node. * @param service The file system service. * @throws TCFFileSystemException Thrown during querying the children nodes. @@ -290,7 +290,7 @@ public abstract class FSOperation { /** * Query the children of the specified node using the file system service. - * + * * @param node The folder node. * @param service The file system service. * @return The children of the folder node. @@ -385,7 +385,7 @@ public abstract class FSOperation { /** * Remove the child from the children list of the specified folder. If the folder has not yet * expanded, then expand it. - * + * * @param service The file system service. * @param folder The folder node from which the node is going to be removed. * @param child The child node to be removed. @@ -416,7 +416,7 @@ public abstract class FSOperation { /** * Find the node with the name from the children list of the folder. - * + * * @param service The file system service. * @param folder The folder node. * @param name The target node's name. @@ -434,7 +434,7 @@ public abstract class FSOperation { /** * Create the name for the target file that is copied. If there exists a file with the same * name, then "Copy of xxxx" and "Copy (n) of xxxx" will be used as the target file name. - * + * * @param service File system service used to query the children nodes of the folder. * @param node The node whose target file is to be created. * @param dest The destination folder. @@ -461,7 +461,7 @@ public abstract class FSOperation { /** * Make a new directory with for the new node. - * + * * @param service The file system service. * @param node The directory node to be made. * @throws TCFFileSystemException Thrown during children querying. @@ -495,7 +495,7 @@ public abstract class FSOperation { /** * Confirm if the file/folder represented by the specified should be replaced. - * + * * @param node The file/folder node. * @return The confirming result. true yes, false no. * @throws InterruptedException Thrown when canceled. @@ -534,7 +534,7 @@ public abstract class FSOperation { /** * Add the specified child to the folder node's children list. - * + * * @param service The file system service. * @param folder The folder node. * @param child The child node to be added. @@ -567,7 +567,7 @@ public abstract class FSOperation { /** * Create an directory entry using the specified DirEntry which contains the directory * information. - * + * * @param entry The directory entry node. * @param entryIsRootNode If it is root node. * @return An FSTreeNode representing the folder. @@ -601,7 +601,7 @@ public abstract class FSOperation { /** * Remove the file. - * + * * @param node * @param service * @throws TCFFileSystemException @@ -638,7 +638,7 @@ public abstract class FSOperation { /** * Remove the folder. - * + * * @param node * @param service * @throws TCFFileSystemException @@ -675,7 +675,7 @@ public abstract class FSOperation { /** * Do the actual operation. - * + * * @return true if it is successful. */ public abstract boolean doit(); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java index 27320cc09..e5f660154 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRefresh.java @@ -15,13 +15,14 @@ import java.util.List; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.services.IFileSystem; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; -import org.eclipse.tcf.protocol.IChannel; -import org.eclipse.tcf.services.IFileSystem; import org.eclipse.ui.PlatformUI; /** @@ -35,7 +36,7 @@ public class FSRefresh extends FSOperation { /** * Create an FSRefresh to refresh the specified node and its descendants. - * + * * @param node The root node to be refreshed. */ public FSRefresh(FSTreeNode node) { @@ -70,7 +71,7 @@ public class FSRefresh extends FSOperation { return false; } finally { - if (channel != null) channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); // Refresh the file system tree. FSModel.getInstance().fireNodeStateChanged(node); } @@ -80,7 +81,7 @@ public class FSRefresh extends FSOperation { /** * Refresh the specified node and its children recursively using the file system service. - * + * * @param node The node to be refreshed. * @param service The file system service. * @throws TCFFileSystemException Thrown during refreshing. @@ -94,11 +95,11 @@ public class FSRefresh extends FSOperation { } } } - + /** * Update the children of the specified folder node using the file system service. - * + * * @param node The folder node. * @param service The file system service. * @throws TCFFileSystemException Thrown during querying the children nodes. @@ -121,7 +122,7 @@ public class FSRefresh extends FSOperation { /** * Find those nodes which are in aList yet not in bList and return them as a list. - * + * * @param aList * @param bList * @return the difference list. @@ -141,5 +142,5 @@ public class FSRefresh extends FSOperation { } } return newList; - } + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java index 8b7800d6f..887ba60f0 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java @@ -15,6 +15,12 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.tcf.protocol.IChannel; +import org.eclipse.tcf.protocol.IToken; +import org.eclipse.tcf.services.IFileSystem; +import org.eclipse.tcf.services.IFileSystem.DoneRename; +import org.eclipse.tcf.services.IFileSystem.FileSystemException; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException; import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException; import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CacheManager; @@ -23,11 +29,6 @@ import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages; import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous; import org.eclipse.tcf.te.tcf.filesystem.model.FSModel; import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode; -import org.eclipse.tcf.protocol.IChannel; -import org.eclipse.tcf.protocol.IToken; -import org.eclipse.tcf.services.IFileSystem; -import org.eclipse.tcf.services.IFileSystem.DoneRename; -import org.eclipse.tcf.services.IFileSystem.FileSystemException; import org.eclipse.ui.PlatformUI; /** * FSRename renames the specified file/folder to a @@ -42,7 +43,7 @@ public class FSRename extends FSOperation { /** * Create a rename operation that renames the node with the new name. - * + * * @param node The file/folder node to be renamed. * @param newName The new name of this node. */ @@ -77,7 +78,7 @@ public class FSRename extends FSOperation { MessageDialog.openError(parent, Messages.FSRename_RenameFileFolderTitle, e.getLocalizedMessage()); } finally { - if (channel != null) channel.close(); + if (channel != null) Tcf.getChannelManager().closeChannel(channel); FSModel.getInstance().fireNodeStateChanged(node); } return false; @@ -85,7 +86,7 @@ public class FSRename extends FSOperation { /** * Rename the node using the new name. - * + * * @param service File system service used to rename. * @throws TCFFileSystemException The exception thrown during renaming. */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java index 3b8b799e1..1842c78bc 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java @@ -144,7 +144,7 @@ public class TcfURLConnection extends URLConnection { final Rendezvous rendezvous = new Rendezvous(); final TCFChannelException[] errors = new TCFChannelException[1]; final IChannel[] channels = new IChannel[1]; - Tcf.getChannelManager().openChannel(peer, new DoneOpenChannel(){ + Tcf.getChannelManager().openChannel(peer, false, new DoneOpenChannel(){ @Override public void doneOpenChannel(Throwable error, IChannel channel) { if(error!=null){ @@ -289,7 +289,7 @@ public class TcfURLConnection extends URLConnection { } catch (InterruptedException e) { throw new IOException(Messages.TcfURLConnection_CloseFileTimeout); } - channel.close(); + Tcf.getChannelManager().closeChannel(channel); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java index 6b77020a4..7dd822b81 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java @@ -12,16 +12,17 @@ package org.eclipse.tcf.te.tcf.locator.nodes; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.Assert; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; +import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement; +import org.eclipse.tcf.te.runtime.properties.PropertiesContainer; import org.eclipse.tcf.te.tcf.locator.interfaces.IModelListener; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties; -import org.eclipse.tcf.te.runtime.interfaces.workingsets.IWorkingSetElement; -import org.eclipse.tcf.te.runtime.properties.PropertiesContainer; /** @@ -107,18 +108,18 @@ public class PeerModel extends PropertiesContainer implements IPeerModel, IWorki // NOTE: The getAdapter(...) method can be invoked from many place and // many threads where we cannot control the calls. Therefore, this // method is allowed be called from any thread. - final Object[] object = new Object[1]; - if (Protocol.isDispatchThread()) { - object[0] = doGetAdapter(adapter); - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - object[0] = doGetAdapter(adapter); - } - }); - } - return object[0] != null ? object[0] : super.getAdapter(adapter); + final AtomicReference object = new AtomicReference(); + Runnable runnable = new Runnable() { + @Override + public void run() { + object.set(doGetAdapter(adapter)); + } + }; + + if (Protocol.isDispatchThread()) runnable.run(); + else Protocol.invokeAndWait(runnable); + + return object.get() != null ? object.get() : super.getAdapter(adapter); } /** diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java index 6915106db..5844a23e8 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java @@ -43,12 +43,6 @@ import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.IProcesses; import org.eclipse.tcf.services.IProcesses.ProcessContext; import org.eclipse.tcf.services.IStreams; -import org.eclipse.tcf.te.tcf.processes.core.activator.CoreBundleActivator; -import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessContextAwareListener; -import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessLauncher; -import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessStreamsProxy; -import org.eclipse.tcf.te.tcf.processes.core.internal.tracing.ITraceIds; -import org.eclipse.tcf.te.tcf.processes.core.nls.Messages; import org.eclipse.tcf.te.core.async.AsyncCallbackCollector; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.runtime.events.DisposedEvent; @@ -64,6 +58,12 @@ import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; import org.eclipse.tcf.te.tcf.core.streams.StreamsDataProvider; import org.eclipse.tcf.te.tcf.core.streams.StreamsDataReceiver; +import org.eclipse.tcf.te.tcf.processes.core.activator.CoreBundleActivator; +import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessContextAwareListener; +import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessLauncher; +import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessStreamsProxy; +import org.eclipse.tcf.te.tcf.processes.core.internal.tracing.ITraceIds; +import org.eclipse.tcf.te.tcf.processes.core.nls.Messages; /** * Remote process launcher. @@ -144,7 +144,7 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher protected void internalDone(Object caller, IStatus status) { Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ // Close the channel as all disposal is done - if (finChannel != null) finChannel.close(); + if (finChannel != null) Tcf.getChannelManager().closeChannel(finChannel); } }, delegate); @@ -332,7 +332,7 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher this.properties = properties; // Open a channel to the given peer - Tcf.getChannelManager().openChannel(peer, new IChannelManager.DoneOpenChannel() { + Tcf.getChannelManager().openChannel(peer, false, new IChannelManager.DoneOpenChannel() { /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel#doneOpenChannel(java.lang.Throwable, org.eclipse.tcf.protocol.IChannel) */ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/controls/ProcessesTreeContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/controls/ProcessesTreeContentProvider.java index 7a271405a..1435ed47b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/controls/ProcessesTreeContentProvider.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/controls/ProcessesTreeContentProvider.java @@ -66,17 +66,7 @@ public class ProcessesTreeContentProvider implements ITreeContentProvider { */ protected void closeOpenChannel() { if (channel != null) { - final IChannel finChannel = channel; - if (Protocol.isDispatchThread()) { - finChannel.close(); - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - finChannel.close(); - } - }); - } + Tcf.getChannelManager().closeChannel(channel); channel = null; service = null; } @@ -122,17 +112,7 @@ public class ProcessesTreeContentProvider implements ITreeContentProvider { // If we still have a channel open, for now, we just close the old channel if (channel != null) { - final IChannel finChannel = channel; - if (Protocol.isDispatchThread()) { - finChannel.close(); - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - finChannel.close(); - } - }); - } + Tcf.getChannelManager().closeChannel(channel); channel = null; } @@ -151,7 +131,7 @@ public class ProcessesTreeContentProvider implements ITreeContentProvider { children = new Object[] { pendingNode }; - Tcf.getChannelManager().openChannel(peer, new IChannelManager.DoneOpenChannel() { + Tcf.getChannelManager().openChannel(peer, false, new IChannelManager.DoneOpenChannel() { @Override @SuppressWarnings("synthetic-access") public void doneOpenChannel(Throwable error, IChannel channel) { diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/internal/handler/AbstractChannelCommandHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/internal/handler/AbstractChannelCommandHandler.java index 6075fd5ca..09bc40785 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/internal/handler/AbstractChannelCommandHandler.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.ui/src/org/eclipse/tcf/te/tcf/processes/ui/internal/handler/AbstractChannelCommandHandler.java @@ -22,10 +22,6 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IPeer; -import org.eclipse.tcf.protocol.Protocol; -import org.eclipse.tcf.te.tcf.processes.ui.activator.UIPlugin; -import org.eclipse.tcf.te.tcf.processes.ui.internal.help.IContextHelpIds; -import org.eclipse.tcf.te.tcf.processes.ui.nls.Messages; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.properties.PropertiesContainer; import org.eclipse.tcf.te.runtime.statushandler.StatusHandlerManager; @@ -34,6 +30,9 @@ import org.eclipse.tcf.te.runtime.statushandler.interfaces.IStatusHandlerConstan import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; +import org.eclipse.tcf.te.tcf.processes.ui.activator.UIPlugin; +import org.eclipse.tcf.te.tcf.processes.ui.internal.help.IContextHelpIds; +import org.eclipse.tcf.te.tcf.processes.ui.nls.Messages; import org.eclipse.tcf.te.ui.swt.DisplayUtil; import org.eclipse.ui.handlers.HandlerUtil; @@ -63,7 +62,7 @@ public abstract class AbstractChannelCommandHandler extends AbstractHandler { // If the peer is available, we can open a channel to the remote peer if (peer != null) { // Get the channel - Tcf.getChannelManager().openChannel(peer, new IChannelManager.DoneOpenChannel() { + Tcf.getChannelManager().openChannel(peer, false, new IChannelManager.DoneOpenChannel() { @Override public void doneOpenChannel(final Throwable error, final IChannel channel) { if (error == null) { @@ -78,19 +77,7 @@ public abstract class AbstractChannelCommandHandler extends AbstractHandler { handleException(channel, new CoreException(status)); } else { // Close the channel - if (channel != null) { - final IChannel finChannel = channel; - if (Protocol.isDispatchThread()) { - finChannel.close(); - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - finChannel.close(); - } - }); - } - } + if (channel != null) Tcf.getChannelManager().closeChannel(channel); } } }); @@ -145,19 +132,7 @@ public abstract class AbstractChannelCommandHandler extends AbstractHandler { Assert.isNotNull(exception); // Close the backend channel - if (channel != null) { - final IChannel finChannel = channel; - if (Protocol.isDispatchThread()) { - finChannel.close(); - } else { - Protocol.invokeAndWait(new Runnable() { - @Override - public void run() { - finChannel.close(); - } - }); - } - } + if (channel != null) Tcf.getChannelManager().closeChannel(channel); // Get the status handler IStatusHandler[] handler = StatusHandlerManager.getInstance().getHandler(getClass()); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/activator/CoreBundleActivator.java index 3d5711ba7..359d80934 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/activator/CoreBundleActivator.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/activator/CoreBundleActivator.java @@ -67,5 +67,6 @@ public class CoreBundleActivator implements BundleActivator { @Override public void stop(BundleContext bundleContext) throws Exception { CoreBundleActivator.context = null; + traceHandler = null; } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/launcher/TerminalsLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/launcher/TerminalsLauncher.java index bed8c1f93..2f4e769ed 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/launcher/TerminalsLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.terminals.core/src/org/eclipse/tcf/te/tcf/terminals/core/launcher/TerminalsLauncher.java @@ -39,11 +39,6 @@ import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.IStreams; import org.eclipse.tcf.services.ITerminals; import org.eclipse.tcf.services.ITerminals.TerminalContext; -import org.eclipse.tcf.te.tcf.terminals.core.activator.CoreBundleActivator; -import org.eclipse.tcf.te.tcf.terminals.core.interfaces.launcher.ITerminalsContextAwareListener; -import org.eclipse.tcf.te.tcf.terminals.core.interfaces.launcher.ITerminalsLauncher; -import org.eclipse.tcf.te.tcf.terminals.core.internal.tracing.ITraceIds; -import org.eclipse.tcf.te.tcf.terminals.core.nls.Messages; import org.eclipse.tcf.te.core.async.AsyncCallbackCollector; import org.eclipse.tcf.te.runtime.callback.Callback; import org.eclipse.tcf.te.runtime.events.DisposedEvent; @@ -59,6 +54,11 @@ import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager; import org.eclipse.tcf.te.tcf.core.streams.StreamsDataProvider; import org.eclipse.tcf.te.tcf.core.streams.StreamsDataReceiver; +import org.eclipse.tcf.te.tcf.terminals.core.activator.CoreBundleActivator; +import org.eclipse.tcf.te.tcf.terminals.core.interfaces.launcher.ITerminalsContextAwareListener; +import org.eclipse.tcf.te.tcf.terminals.core.interfaces.launcher.ITerminalsLauncher; +import org.eclipse.tcf.te.tcf.terminals.core.internal.tracing.ITraceIds; +import org.eclipse.tcf.te.tcf.terminals.core.nls.Messages; /** * Remote terminals launcher. @@ -128,7 +128,7 @@ public class TerminalsLauncher extends PlatformObject implements ITerminalsLaunc protected void internalDone(Object caller, IStatus status) { Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ // Close the channel as all disposal is done - if (finChannel != null) finChannel.close(); + if (finChannel != null) Tcf.getChannelManager().closeChannel(finChannel); } }, delegate); @@ -256,7 +256,7 @@ public class TerminalsLauncher extends PlatformObject implements ITerminalsLaunc this.properties = properties; // Open a channel to the given peer - Tcf.getChannelManager().openChannel(peer, new IChannelManager.DoneOpenChannel() { + Tcf.getChannelManager().openChannel(peer, false, new IChannelManager.DoneOpenChannel() { /* (non-Javadoc) * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel#doneOpenChannel(java.lang.Throwable, org.eclipse.tcf.protocol.IChannel) */ -- cgit v1.2.3 From 98948fd216f307010a4167a5efb8efb39d3f62b9 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Mon, 28 Nov 2011 10:13:27 +0100 Subject: Target Explorer: Simplify peer node tree decoration --- .../tcf/ui/internal/navigator/images/PeerImageDescriptor.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java index df20b97e5..cbdc37fbd 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java @@ -14,9 +14,9 @@ import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.tcf.protocol.Protocol; -import org.eclipse.tcf.te.tcf.ui.internal.ImageConsts; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties; +import org.eclipse.tcf.te.tcf.ui.internal.ImageConsts; import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor; @@ -84,13 +84,7 @@ public class PeerImageDescriptor extends AbstractImageDescriptor { protected void drawCompositeImage(int width, int height) { drawCentered(baseImage, width, height); - if (state == IPeerModelProperties.STATE_UNKNOWN) { /* unknown */ - drawBottomRight(ImageConsts.GREY_OVR); - } - else if (state == IPeerModelProperties.STATE_REACHABLE) { /* not connected, but reachable */ - drawBottomRight(ImageConsts.GOLD_OVR); - } - else if (state == IPeerModelProperties.STATE_CONNECTED) { /* connected */ + if (state == IPeerModelProperties.STATE_CONNECTED) { /* connected */ drawBottomRight(ImageConsts.GREEN_OVR); } else if (state == IPeerModelProperties.STATE_NOT_REACHABLE) { /* not connected, not reachable */ -- cgit v1.2.3 From 58e864152fa713a0bcea66ae79fee5dd582a64e2 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Mon, 28 Nov 2011 11:06:15 +0100 Subject: Target Explorer: Attach workbench listener to assure clean closing of all channels on shutdown --- .../te/tcf/core/interfaces/IChannelManager.java | 7 +++++ .../tcf/te/tcf/core/internal/ChannelManager.java | 33 ++++++++++++++++++++++ .../eclipse/tcf/te/tcf/ui/activator/UIPlugin.java | 22 +++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java index 1b2d290e6..2dd3d6137 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java @@ -76,4 +76,11 @@ public interface IChannelManager extends IAdaptable { * @param channel The channel. Must not be null. */ public void closeChannel(IChannel channel); + + /** + * Close all open channel, no matter of the current reference count. + *

+ * The method can be called from any thread context. + */ + public void closeAll(); } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java index f587383fc..19616be62 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java @@ -361,4 +361,37 @@ public final class ChannelManager extends PlatformObject implements IChannelMana refCounters.remove(id); channels.remove(id); } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#closeAll() + */ + @Override + public void closeAll() { + if (Protocol.isDispatchThread()) { + internalCloseAll(); + } else { + Protocol.invokeLater(new Runnable() { + @Override + public void run() { + internalCloseAll(); + } + }); + } + } + + /** + * Close all open channel, no matter of the current reference count. + *

+ * Note: This method must be invoked at the TCF dispatch thread. + */ + /* default */ void internalCloseAll() { + Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ + + IChannel[] openChannels = channels.values().toArray(new IChannel[channels.values().size()]); + + refCounters.clear(); + channels.clear(); + + for (IChannel channel : openChannels) internalCloseChannel(channel); + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/activator/UIPlugin.java index a88d80cb4..5c4bc7e4a 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/activator/UIPlugin.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/activator/UIPlugin.java @@ -14,8 +14,12 @@ import java.net.URL; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.graphics.Image; +import org.eclipse.tcf.te.tcf.core.Tcf; import org.eclipse.tcf.te.tcf.ui.internal.ImageConsts; import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -26,6 +30,8 @@ import org.osgi.framework.BundleContext; public class UIPlugin extends AbstractUIPlugin { // The shared instance private static UIPlugin plugin; + // The workbench listener instance + private IWorkbenchListener listener; /** * Constructor. @@ -59,6 +65,21 @@ public class UIPlugin extends AbstractUIPlugin { public void start(BundleContext context) throws Exception { super.start(context); plugin = this; + + // Create and register the workbench listener instance + listener = new IWorkbenchListener() { + + @Override + public boolean preShutdown(IWorkbench workbench, boolean forced) { + Tcf.getChannelManager().closeAll(); + return true; + } + + @Override + public void postShutdown(IWorkbench workbench) { + } + }; + PlatformUI.getWorkbench().addWorkbenchListener(listener); } /* (non-Javadoc) @@ -67,6 +88,7 @@ public class UIPlugin extends AbstractUIPlugin { @Override public void stop(BundleContext context) throws Exception { plugin = null; + if (listener != null) { PlatformUI.getWorkbench().removeWorkbenchListener(listener); listener = null; } super.stop(context); } -- cgit v1.2.3