Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorustieber2011-04-27 06:39:14 +0000
committerustieber2011-04-27 06:39:14 +0000
commit2870751f2f0226fe1168988ffde72879b3a2d25b (patch)
tree67082a95ba5b97c69b52a4ac8970ff8ff052412f
parent008598c053a2dae230987eccab80ad86e1e41331 (diff)
downloadorg.eclipse.tcf-2870751f2f0226fe1168988ffde72879b3a2d25b.tar.gz
org.eclipse.tcf-2870751f2f0226fe1168988ffde72879b3a2d25b.tar.xz
org.eclipse.tcf-2870751f2f0226fe1168988ffde72879b3a2d25b.zip
Add initial Target Explorer contribution
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF13
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/build.properties5
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/plugin.properties12
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/activator/CoreBundleActivator.java55
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/AbstractExtensionPointManager.java170
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtension.java125
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtensionProxy.java156
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.java35
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.properties8
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/.options1
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/META-INF/MANIFEST.MF15
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/build.properties6
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.properties12
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.xml10
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/Tcf.java290
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/activator/CoreBundleActivator.java60
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/IChannelManager.java56
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/ChannelManager.java150
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/Startup.java82
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/interfaces/IChannelOpenListener.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelListener.java93
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelOpenListener.java63
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.java77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.properties9
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/utils/LogUtils.java43
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/META-INF/MANIFEST.MF21
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/build.properties6
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/folder.gifbin0 -> 216 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdrive.gifbin0 -> 336 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdriveopen.gifbin0 -> 339 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.properties16
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.xml66
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/activator/UIPlugin.java124
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeContentProvider.java411
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeControl.java128
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeLabelProvider.java175
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeNode.java86
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerComparator.java68
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerSorter.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/dialogs/FSOpenFileDialog.java198
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/explorer/FSExplorerEditorPage.java141
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/help/IContextHelpIds.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.java79
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.properties12
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/registries/InternalImageRegistry.java83
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/META-INF/MANIFEST.MF23
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/build.properties6
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.properties12
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.xml23
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/Scanner.java151
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/ScannerRunnable.java180
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java56
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IModelListener.java42
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IScanner.java49
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/ILocatorModel.java116
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModel.java288
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java79
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelLookupService.java34
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelRefreshService.java23
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelService.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelUpdateService.java47
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/MyPropertyTester.java84
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.java72
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.properties4
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/preferences/PreferencesInitializer.java43
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ChannelStateChangeListener.java75
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/LocatorListener.java98
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ModelAdapter.java39
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/LocatorModel.java333
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/PeerModel.java398
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/AbstractLocatorModelService.java40
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelLookupService.java68
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java100
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelUpdateService.java107
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/utils/IPAddressUtil.java403
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/META-INF/MANIFEST.MF20
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/build.properties7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/dtool16/newconnection_wiz.gifbin0 -> 202 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/etool16/newconnection_wiz.gifbin0 -> 328 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/rootNode_obj.gifbin0 -> 1001 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/target.gifbin0 -> 567 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/gold_ovr.gifbin0 -> 854 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/green_ovr.gifbin0 -> 854 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/grey_ovr.gifbin0 -> 854 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/redX_ovr.gifbin0 -> 854 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/red_ovr.gifbin0 -> 854 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.properties27
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.xml137
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/activator/UIPlugin.java124
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/dialogs/AddPeerDialog.java267
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/editor/pages/NodePropertiesEditorPage.java169
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/AddPeerCommandHandler.java107
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/RefreshCommandHandler.java65
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/help/IContextHelpIds.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/model/Model.java80
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ContentProviderDelegate.java104
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProvider.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProviderDelegate.java147
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ModelListener.java85
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/Sorter.java205
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java116
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.java97
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.properties30
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/registries/InternalImageRegistry.java88
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesContentProvider.java160
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesLabelProvider.java111
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesViewerComparator.java65
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/META-INF/MANIFEST.MF18
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/build.properties7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/editor.gifbin0 -> 940 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/prop_ps.gifbin0 -> 343 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/targets_view.gifbin0 -> 940 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.properties35
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.xml152
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPageBindings.exsd163
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPages.exsd147
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/activator/UIPlugin.java103
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/editor/AbstractEditorPage.java73
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IEditorPage.java20
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IRoot.java19
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IUIConstants.java26
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/ImageConsts.java32
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/View.java75
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/Editor.java211
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/EditorInput.java169
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/expressions/EditorPropertyTester.java35
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBinding.java94
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBindingExtensionPointManager.java180
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageExtensionPointManager.java102
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.properties6
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/targets/handler/PropertiesCommandHandler.java73
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/perspective/PerspectiveFactory.java67
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/.project28
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/.settings/org.eclipse.jdt.core.prefs77
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/META-INF/MANIFEST.MF24
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/build.properties5
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/plugin.properties12
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/AbstractViewerComparator.java105
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/WorkbenchPartControl.java127
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/activator/UIPlugin.java64
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/dialogs/CustomTrayDialog.java180
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/forms/CustomFormToolkit.java393
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageDescriptor.java176
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageRegistry.java218
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.java42
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.properties15
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nodes/PendingOperation.java45
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableNode.java39
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableViewerComparator.java135
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/properties/NodePropertiesTableControl.java417
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/AbstractTreeControl.java307
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/TreeViewerComparator.java178
176 files changed, 13753 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/.classpath b/target_explorer/plugins/org.eclipse.tm.te.core/.classpath
new file mode 100644
index 000000000..2d1a4302f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/.project b/target_explorer/plugins/org.eclipse.tm.te.core/.project
new file mode 100644
index 000000000..2c25cc880
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..af7055514
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Wed Apr 27 07:52:47 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..3db9197af
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.core.activator.CoreBundleActivator
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.core.extensions;version="1.0.0",
+ org.eclipse.tm.te.core.nls;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/build.properties b/target_explorer/plugins/org.eclipse.tm.te.core/build.properties
new file mode 100644
index 000000000..f4ae97015
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.core/plugin.properties
new file mode 100644
index 000000000..de370b5c7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/plugin.properties
@@ -0,0 +1,12 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer, Core
+providerName = Eclipse.org
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/activator/CoreBundleActivator.java
new file mode 100644
index 000000000..28f1d1c6a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/activator/CoreBundleActivator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.core.activator;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class CoreBundleActivator implements BundleActivator {
+ // The bundle context
+ private static BundleContext context;
+
+ /**
+ * Returns the bundle context
+ *
+ * @return the bundle context
+ */
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getContext() != null && getContext().getBundle() != null) {
+ return getContext().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = bundleContext;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/AbstractExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/AbstractExtensionPointManager.java
new file mode 100644
index 000000000..9f2940382
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/AbstractExtensionPointManager.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.core.extensions;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+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.tm.te.core.activator.CoreBundleActivator;
+import org.eclipse.tm.te.core.nls.Messages;
+
+/**
+ * Target Explorer: Abstract extension point manager implementation.
+ */
+public abstract class AbstractExtensionPointManager<V> {
+ // Flag to mark the extension point manager initialized (extensions loaded).
+ private boolean fInitialized = false;
+ // The map of loaded extension listed by their unique ids
+ private Map<String, ExecutableExtensionProxy<V>> fExtensions = new LinkedHashMap<String, ExecutableExtensionProxy<V>>();
+
+ /**
+ * Constructor.
+ */
+ public AbstractExtensionPointManager() {
+ }
+
+ /**
+ * Returns if or if not the extension point manager got initialized already.
+ * <p>
+ * Initialized means that the manager read the extensions for the managed extension point.
+ *
+ * @return <code>True</code> if already initialized, <code>false</code> otherwise.
+ */
+ protected boolean isInitialized() {
+ return fInitialized;
+ }
+
+ /**
+ * Sets if or if not the extension point manager is initialized.
+ * <p>
+ * Initialized means that the manager has read the extensions for the managed extension point.
+ *
+ * @return <code>True</code> to set the extension point manager is initialized, <code>false</code> otherwise.
+ */
+ protected void setInitialized(boolean initialized) {
+ fInitialized = initialized;
+ }
+
+ /**
+ * Returns the map of managed extensions. If not loaded before,
+ * this methods trigger the loading of the extensions to the managed
+ * extension point.
+ *
+ * @return The map of extensions.
+ */
+ protected Map<String, ExecutableExtensionProxy<V>> getExtensions() {
+ // Load and store the extensions thread-safe!
+ synchronized (fExtensions) {
+ if (!isInitialized()) { loadExtensions(); setInitialized(true); }
+ }
+ return fExtensions;
+ }
+
+ /**
+ * Returns the extension point id to read. The method
+ * must return never <code>null</code>.
+ *
+ * @return The extension point id.
+ */
+ protected abstract String getExtensionPointId();
+
+ /**
+ * Returns the configuration element name. The method
+ * must return never <code>null</code>.
+ *
+ * @return The configuration element name.
+ */
+ protected abstract String getConfigurationElementName();
+
+ /**
+ * Creates the extension proxy instance.
+ *
+ * @param element The configuration element of the extension. Must be not <code>null</code>.
+ * @return The extension proxy instance.
+ *
+ * @throws CoreException If the extension proxy instantiation failed.
+ */
+ protected ExecutableExtensionProxy<V> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+ assert element != null;
+ return new ExecutableExtensionProxy<V>(element);
+ }
+
+ /**
+ * Store the given extension to the given extensions store. Checks if an extension with the same id does exist
+ * already and throws an exception in this case.
+ *
+ * @param extensions The extensions store. Must not be <code>null</code>.
+ * @param candidate The extension. Must not be <code>null</code>.
+ * @param element The configuration element. Must not be <code>null</code>.
+ *
+ * @throws CoreException In case a extension with the same id as the given extension already exist.
+ */
+ protected void doStoreExtensionTo(Map<String, ExecutableExtensionProxy<V>> extensions, ExecutableExtensionProxy<V> candidate, IConfigurationElement element) throws CoreException {
+ assert extensions != null && candidate != null && element != null;
+
+ // If no extension with this id had been registered before, register now.
+ if (!fExtensions.containsKey(candidate.getId())) {
+ fExtensions.put(candidate.getId(), candidate);
+ }
+ else {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_duplicateExtension, candidate.getId(), element.getContributor().getName()),
+ null));
+ }
+ }
+
+ /**
+ * Loads the extensions for the managed extension point.
+ */
+ protected void loadExtensions() {
+ // If already initialized, this method will do nothing.
+ if (isInitialized()) return;
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint point = registry.getExtensionPoint(getExtensionPointId());
+ if (point != null) {
+ IExtension[] extensions = point.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if (getConfigurationElementName().equals(element.getName())) {
+ try {
+ ExecutableExtensionProxy<V> candidate = doCreateExtensionProxy(element);
+ if (candidate.getId() != null) {
+ doStoreExtensionTo(fExtensions, candidate, element);
+ } else {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", element.getAttribute("label")), //$NON-NLS-1$ //$NON-NLS-2$
+ null));
+ }
+ } catch (CoreException e) {
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()), e));
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtension.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtension.java
new file mode 100644
index 000000000..eb08c9f45
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtension.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.core.extensions;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.te.core.activator.CoreBundleActivator;
+import org.eclipse.tm.te.core.nls.Messages;
+
+
+
+/**
+ * Target Explorer: Executable extension implementation.
+ */
+public class ExecutableExtension extends PlatformObject {
+ private String fId;
+ private String fLabel;
+ private String fDescription;
+
+ /**
+ * Constructor.
+ */
+ public ExecutableExtension() {
+ super();
+ fId = null;
+ fLabel = ""; //$NON-NLS-1$
+ fDescription = ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Clone the initialization data to the given executable extension instance.
+ *
+ * @param other The destination executable extension instance. Must not be <code>null</code>.
+ */
+ public void cloneInitializationData(ExecutableExtension other) {
+ assert other != null;
+ other.fId = fId;
+ other.fLabel = fLabel;
+ other.fDescription = fDescription;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ if (config != null) {
+ // Initialize the id field by reading the <id> extension attribute.
+ // Throws an exception if the id is empty or null.
+ fId = config.getAttribute("id"); //$NON-NLS-1$
+ if (fId == null || fId.trim().length() == 0) {
+ throw createMissingMandatoryAttributeException("id", config.getContributor().getName()); //$NON-NLS-1$
+ }
+
+ // Initialize the label field by reading the <label> extension attribute if present.
+ fLabel = config.getAttribute("label"); //$NON-NLS-1$
+ if (fLabel == null || fLabel.trim().length() == 0) fLabel = ""; //$NON-NLS-1$
+
+ // Initialize the description field by reading the "<description>" extension child element if present.
+ IConfigurationElement[] children = config.getChildren("description"); //$NON-NLS-1$
+ // Only one description element is allow. All other will be ignored
+ if (children.length > 0) {
+ IConfigurationElement description = children[0];
+ String value = description.getValue();
+ fDescription = value != null ? value.trim() : ""; //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Creates a new {@link CoreException} to be thrown if a mandatory extension attribute
+ * is missing.
+ *
+ * @param attributeName The attribute name. Must be not <code>null</code>.
+ * @param extensionId The extension id. Must be not <code>null</code>.
+ *
+ * @return The {@link CoreException} instance.
+ */
+ protected CoreException createMissingMandatoryAttributeException(String attributeName, String extensionId) {
+ assert attributeName != null && extensionId != null;
+ return new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, attributeName, extensionId),
+ null));
+ }
+
+ /**
+ * Returns the unique id of the extension. The returned
+ * id must be never <code>null</code> or an empty string.
+ *
+ * @return The unique id.
+ */
+ public String getId() {
+ return fId;
+ }
+
+ /**
+ * Returns the label of the extension.
+ *
+ * @return The label or an empty string.
+ */
+ public String getLabel() {
+ return fLabel != null ? fLabel : ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the description of the extension.
+ *
+ * @return The description or an empty string.
+ */
+ public String getDescription() {
+ return fDescription != null ? fDescription : ""; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtensionProxy.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtensionProxy.java
new file mode 100644
index 000000000..68e5cb135
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/extensions/ExecutableExtensionProxy.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.core.extensions;
+
+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.tm.te.core.activator.CoreBundleActivator;
+import org.eclipse.tm.te.core.nls.Messages;
+
+
+/**
+ * Target Explorer: Executable extension proxy implementation.
+ */
+public class ExecutableExtensionProxy<V> {
+ // The extension instance. Created on first access
+ private V fInstance;
+ // The configuration element
+ private final IConfigurationElement fElement;
+ // The unique id of the extension.
+ private String fId;
+
+ /**
+ * Constructor.
+ *
+ * @param element The configuration element. Must not be <code>null</code>.
+ * @throws CoreException In case the configuration element attribute <i>id</i> is <code>null</code> or empty.
+ */
+ public ExecutableExtensionProxy(IConfigurationElement element) throws CoreException {
+ assert element != null;
+ fElement = element;
+
+ // Extract the extension attributes
+ fId = element.getAttribute("id"); //$NON-NLS-1$
+ if (fId == null || fId.trim().length() == 0) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", element.getContributor().getName()), //$NON-NLS-1$
+ null));
+ }
+
+ fInstance = null;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id The id for this instance.
+ * @param instance The instance to add to proxy.
+ */
+ public ExecutableExtensionProxy(String id, V instance) {
+ assert id!= null && instance != null;
+ fId = id;
+ fInstance = instance;
+ fElement = null;
+ }
+
+ /**
+ * Returns the extensions unique id.
+ *
+ * @return The unique id.
+ */
+ public String getId() {
+ return fId;
+ }
+
+ /**
+ * Returns the configuration element for this extension.
+ *
+ * @return The configuration element.
+ */
+ public IConfigurationElement getConfigurationElement() {
+ return fElement;
+ }
+
+ /**
+ * Reset the extension instance to <code>null</code> and force the
+ * creation of a new extension instance on the next {@link #getInstance()}
+ * method invocation.
+ *
+ * @return The current extension instance or <code>null</code> if none.
+ */
+ public V reset() {
+ V oldExtension = fInstance;
+ fInstance = null;
+ return oldExtension;
+ }
+
+ /**
+ * Returns the extension class instance. The contributing
+ * plug-in will be activated if not yet activated anyway.
+ *
+ * @return The extension class instance or <code>null</code> if the instantiation fails.
+ */
+ public V getInstance() {
+ if (fInstance == null) fInstance = newInstance();
+ return fInstance;
+ }
+
+ /**
+ * Returns always a new extension class instance which is different
+ * to what {@link #getInstance()} would return.
+ *
+ * @return A new extension class instance or <code>null</code> if the instantiation fails.
+ */
+ @SuppressWarnings("unchecked")
+ public V newInstance() {
+ IConfigurationElement element = getConfigurationElement();
+ assert element != null;
+ // The "class" to load can be specified either as attribute or as child element
+ if (element != null && (element.getAttribute("class") != null || element.getChildren("class").length > 0)) { //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ return (V)element.createExecutableExtension("class"); //$NON-NLS-1$
+ } catch (Exception e) {
+ // Possible exceptions: CoreException, ClassCastException.
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()), e));
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ // Proxie's are equal if they have encapsulate an element
+ // with the same unique id
+ if (obj instanceof ExecutableExtensionProxy<?>) {
+ return getId().equals(((ExecutableExtensionProxy<?>)obj).getId());
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ // The hash code of a proxy is the one from the id
+ return getId().hashCode();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.java
new file mode 100644
index 000000000..f7488e2c3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.core.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer Core plugin externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.core.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String Extension_error_missingRequiredAttribute;
+ public static String Extension_error_duplicateExtension;
+ public static String Extension_error_invalidExtensionPoint;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.properties
new file mode 100644
index 000000000..0c0a2348a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.core/src/org/eclipse/tm/te/core/nls/Messages.properties
@@ -0,0 +1,8 @@
+#
+# org.eclipse.tm.te.core
+# Externalized Strings.
+#
+
+Extension_error_missingRequiredAttribute=Required attribute "{0}" missing for extension "{1}"!
+Extension_error_duplicateExtension=Duplicate extension with id ''{0}''. Ignoring duplicated contribution from contributor ''{1}''!
+Extension_error_invalidExtensionPoint=Failed to instantiate the executable extension from extension point ''{0}''.
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.classpath b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.options b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.options
new file mode 100644
index 000000000..70df03d93
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.options
@@ -0,0 +1 @@
+org.eclipse.tm.te.tcf.core/debug/channels = false
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.project b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.project
new file mode 100644
index 000000000..30df93801
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.tcf.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..d59c65841
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Thu Mar 17 14:57:00 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..3c9be0a22
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.tcf.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.tcf.core.activator.CoreBundleActivator
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.tm.tcf.core;bundle-version="0.3.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.tcf.core;version="1.0.0",
+ org.eclipse.tm.te.tcf.core.interfaces;version="1.0.0",
+ org.eclipse.tm.te.tcf.core.interfaces.listeners;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/build.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/build.properties
new file mode 100644
index 000000000..30b2fc40b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.properties
new file mode 100644
index 000000000..62ae97a5d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.properties
@@ -0,0 +1,12 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer, Common TCF Extensions
+providerName = Eclipse.org
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.xml
new file mode 100644
index 000000000..7d5c60d61
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/plugin.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- TCF framework startup participant -->
+ <extension point="org.eclipse.tm.tcf.startup">
+ <class name="org.eclipse.tm.te.tcf.core.internal.Startup"/>
+ </extension>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/Tcf.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/Tcf.java
new file mode 100644
index 000000000..a89f0de62
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/Tcf.java
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.protocol.Protocol.ChannelOpenListener;
+import org.eclipse.tm.te.tcf.core.interfaces.IChannelManager;
+import org.eclipse.tm.te.tcf.core.interfaces.listeners.IChannelStateChangeListener;
+import org.eclipse.tm.te.tcf.core.interfaces.listeners.IProtocolStateChangeListener;
+import org.eclipse.tm.te.tcf.core.internal.ChannelManager;
+import org.eclipse.tm.te.tcf.core.internal.Startup;
+import org.eclipse.tm.te.tcf.core.internal.interfaces.IChannelOpenListener;
+import org.eclipse.tm.te.tcf.core.internal.listener.InternalChannelOpenListener;
+
+
+/**
+ * The main entry point to access the TCF framework extensions.
+ */
+public final class Tcf {
+ /* default */ IChannelManager fChannelManager;
+
+ /* default */ ChannelOpenListener fChannelOpenListener;
+
+ /* default */ final List<IProtocolStateChangeListener> fProtocolStateChangeListeners = new ArrayList<IProtocolStateChangeListener>();
+ /* default */ final List<IChannelStateChangeListener> fChannelStateChangeListeners = new ArrayList<IChannelStateChangeListener>();
+
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static Tcf fInstance = new Tcf();
+ }
+
+ /**
+ * Constructor.
+ */
+ /* default */ Tcf() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance.
+ */
+ /* default */ static Tcf getInstance() {
+ return LazyInstance.fInstance;
+ }
+
+ /**
+ * Executes the given runnable within the TCF protocol dispatch thread.
+ * <p>
+ * <b>Note:</b> Code which is executed in the TCF protocol dispatch thread
+ * cannot use any blocking API!
+ *
+ * @param runnable The runnable. Must be not <code>null</code>.
+ */
+ private static final void runSafe(Runnable runnable) {
+ assert runnable != null;
+
+ if (Protocol.isDispatchThread()) {
+ runnable.run();
+ } else {
+ Protocol.invokeAndWait(runnable);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified once the TCF framework state changes.
+ *
+ * @param listener The listener. Must be not <code>null</code>.
+ */
+ public static final void addProtocolStateChangeListener(IProtocolStateChangeListener listener) {
+ assert Protocol.isDispatchThread() && listener != null;
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ if (!tcf.fProtocolStateChangeListeners.contains(listener)) {
+ tcf.fProtocolStateChangeListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified protocol state change listener.
+ *
+ * @param listener The listener. Must be not <code>null</code>.
+ */
+ public static final void removeProtocolStateChangeListener(IProtocolStateChangeListener listener) {
+ assert Protocol.isDispatchThread() && listener != null;
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ tcf.fProtocolStateChangeListeners.remove(listener);
+ }
+
+ /**
+ * Adds a listener that will be notified once the TCF framework state changes.
+ *
+ * @param listener The listener. Must be not <code>null</code>.
+ */
+ public static final void addChannelStateChangeListener(IChannelStateChangeListener listener) {
+ assert Protocol.isDispatchThread() && listener != null;
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ if (!tcf.fChannelStateChangeListeners.contains(listener)) {
+ tcf.fChannelStateChangeListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified protocol state change listener.
+ *
+ * @param listener The listener. Must be not <code>null</code>.
+ */
+ public static final void removeChannelStateChangeListener(IChannelStateChangeListener listener) {
+ assert Protocol.isDispatchThread() && listener != null;
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ tcf.fChannelStateChangeListeners.remove(listener);
+ }
+
+ /**
+ * Fires the channel state change listeners.
+ *
+ * @param channel The channel which changed state. Must be not <code>null</code>.
+ * @param state The new state.
+ */
+ public static final void fireChannelStateChangeListeners(final IChannel channel, final int state) {
+ assert channel != null;
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ final IChannelStateChangeListener[] listeners = tcf.fChannelStateChangeListeners.toArray(new IChannelStateChangeListener[tcf.fChannelStateChangeListeners.size()]);
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IChannelStateChangeListener listener : listeners) {
+ listener.stateChanged(channel, state);
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns if or if not the TCF framework is up and running.
+ *
+ * @return <code>True</code> if the framework is up and running, <code>false</code> otherwise.
+ */
+ public static final boolean isRunning() {
+ return Startup.isStarted();
+ }
+
+ /**
+ * Startup TCF related services and listeners once the core
+ * TCF framework starts up.
+ * <p>
+ * <b>Note:</b> The method is expected to be called within the TCF protocol dispatch thread.
+ *
+ * @see Startup#setStarted(boolean)
+ */
+ public static void start() {
+ assert Protocol.isDispatchThread();
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ // Create and register the global channel open listener
+ if (tcf.fChannelOpenListener == null) {
+ tcf.fChannelOpenListener = new InternalChannelOpenListener();
+ Protocol.addChannelOpenListener(tcf.fChannelOpenListener);
+ }
+
+ // Signal to interested listeners that we've started up
+ final IProtocolStateChangeListener[] listeners = tcf.fProtocolStateChangeListeners.toArray(new IProtocolStateChangeListener[tcf.fProtocolStateChangeListeners.size()]);
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IProtocolStateChangeListener listener : listeners) {
+ listener.stateChanged(true);
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Shutdown TCF related services and listeners once the core
+ * TCF framework shuts down.
+ * <p>
+ * <b>Note:</b> The method is expected to be called within the TCF protocol dispatch thread.
+ *
+ * @see Startup#setStarted(boolean)
+ */
+ public static void stop() {
+ assert Protocol.isDispatchThread();
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ // Unregister the channel open listener of created
+ if (tcf.fChannelOpenListener != null) {
+ Protocol.removeChannelOpenListener(tcf.fChannelOpenListener);
+ tcf.fChannelOpenListener = null;
+ }
+
+ // Signal to interested listeners that we've just went down
+ final IProtocolStateChangeListener[] listeners = tcf.fProtocolStateChangeListeners.toArray(new IProtocolStateChangeListener[tcf.fProtocolStateChangeListeners.size()]);
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IProtocolStateChangeListener listener : listeners) {
+ listener.stateChanged(false);
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns the channel manager instance.
+ * <p>
+ * <b>Note:</b> The method will create the channel manager instance on
+ * first invocation.
+ *
+ * @return The channel manager instance.
+ */
+ public static IChannelManager getChannelManager() {
+ final Tcf tcf = getInstance();
+ assert tcf != null;
+
+ runSafe(new Runnable() {
+ public void run() {
+ assert Protocol.isDispatchThread();
+
+ if (tcf.fChannelManager == null) {
+ // We have to create the channel manager
+ tcf.fChannelManager = new ChannelManager();
+ }
+ }
+ });
+
+ return tcf.fChannelManager;
+ }
+
+ /**
+ * Returns an object which is an instance of the given class associated with the given object.
+ * Returns <code>null</code> if no such object can be found.
+ *
+ * @param adapter The type of adapter to look up
+ * @return An object castable to the given adapter type, or <code>null</code>
+ * if the given adaptable object does not have an available adapter of the given type
+ *
+ * @see IAdapterManager#getAdapter(Object, Class)
+ */
+ public static Object getAdapter(Class<?> adapter) {
+ assert adapter != null;
+
+ Tcf tcf = getInstance();
+ assert tcf != null;
+
+ if (IChannelManager.class.equals(adapter)) {
+ return tcf.fChannelManager;
+ }
+ if (IChannelOpenListener.class.equals(adapter)) {
+ return tcf.fChannelOpenListener;
+ }
+
+ return Platform.getAdapterManager().getAdapter(tcf, adapter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/activator/CoreBundleActivator.java
new file mode 100644
index 000000000..cd6b211d4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/activator/CoreBundleActivator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.activator;
+
+import org.eclipse.tm.te.tcf.core.internal.Startup;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class CoreBundleActivator implements BundleActivator {
+ // The bundle context
+ private static BundleContext context;
+
+ /**
+ * Returns the bundle context
+ *
+ * @return the bundle context
+ */
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getContext() != null && getContext().getBundle() != null) {
+ return getContext().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = bundleContext;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = null;
+
+ // Mark the core framework as not started anymore
+ Startup.setStarted(false);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/IChannelManager.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/IChannelManager.java
new file mode 100644
index 000000000..2a52c50f7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/IChannelManager.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.interfaces;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+
+/**
+ * TCF channel manager public API declaration.
+ */
+public interface IChannelManager extends IAdaptable {
+
+ /**
+ * 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, <code>null</code> if succeeded.
+ * @param channel The channel object or <code>null</code>.
+ */
+ void doneOpenChannel(Throwable error, IChannel channel);
+ }
+
+ /**
+ * Opens a new channel to communicate with the given peer.
+ * <p>
+ * The method can be called from any thread context.
+ *
+ * @param peer The peer. Must be not <code>null</code>.
+ * @param done The client callback. Must be not <code>null</code>.
+ */
+ public void openChannel(IPeer peer, DoneOpenChannel done);
+
+ /**
+ * Opens a new channel to communicate with the peer described by the
+ * given peer attributes.
+ * <p>
+ * The method can be called from any thread context.
+ *
+ * @param peerAttributes The peer attributes. Must be not <code>null</code>.
+ * @param done The client callback. Must be not <code>null</code>.
+ */
+ public void openChannel(Map<String, String> peerAttributes, DoneOpenChannel done);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java
new file mode 100644
index 000000000..c6dfd3379
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.interfaces.listeners;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+
+/**
+ * Interface for clients to implement that wishes to listen
+ * channel state changes, like opening and closing of a channel.
+ */
+public interface IChannelStateChangeListener {
+
+ /**
+ * Invoked if the channel state has changed.
+ *
+ * @param channel The channel which changed state.
+ * @param state The new state.
+ */
+ public void stateChanged(IChannel channel, int state);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java
new file mode 100644
index 000000000..99a2efc3a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.interfaces.listeners;
+
+/**
+ * Interface for clients to implement that wishes to listen
+ * for the TCF protocol framework to come up and shutdown.
+ */
+public interface IProtocolStateChangeListener {
+
+ /**
+ * Invoked if the TCF framework comes up, <i>state == true</i>, or
+ * if it shuts down, <i>state == false</i>.
+ *
+ * @param state The current TCF framework state.
+ */
+ public void stateChanged(boolean state);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/ChannelManager.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/ChannelManager.java
new file mode 100644
index 000000000..9170cb29f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/ChannelManager.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.tcf.core.AbstractPeer;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.core.interfaces.IChannelManager;
+
+
+/**
+ * TCF channel manager implementation.
+ */
+public final class ChannelManager extends PlatformObject implements IChannelManager {
+
+ /**
+ * Constructor.
+ */
+ public ChannelManager() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.core.interfaces.IChannelManager#openChannel(org.eclipse.tm.tcf.protocol.IPeer, org.eclipse.tm.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)
+ */
+ public void openChannel(final IPeer peer, final DoneOpenChannel done) {
+ if (Protocol.isDispatchThread()) {
+ internalOpenChannel(peer, done);
+ } else {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ internalOpenChannel(peer, done);
+ }
+ });
+ }
+ }
+
+ /**
+ * Internal implementation of {@link #openChannel(IPeer, org.eclipse.tm.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)}.
+ * <p>
+ * Method must be called within the TCF dispatch thread.
+ *
+ * @param peer The peer. Must be not <code>null</code>.
+ * @param done The client callback. Must be not <code>null</code>.
+ */
+ /* default */ void internalOpenChannel(final IPeer peer, final DoneOpenChannel done) {
+ assert peer != null;
+ assert done != null;
+ assert Protocol.isDispatchThread();
+
+ // Open the channel
+ final IChannel channel = peer.openChannel();
+ // Register the channel listener
+ if (channel != null) {
+ channel.addChannelListener(new IChannel.IChannelListener() {
+
+ public void onChannelOpened() {
+ // Remove ourself as listener from the channel
+ channel.removeChannelListener(this);
+ // Channel opening succeeded
+ done.doneOpenChannel(null, channel);
+ }
+
+ public void onChannelClosed(Throwable error) {
+ // Remove ourself as listener from the channel
+ channel.removeChannelListener(this);
+ // Channel opening failed
+ done.doneOpenChannel(error, channel);
+ }
+
+ 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$
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.core.interfaces.IChannelManager#openChannel(java.util.Map, org.eclipse.tm.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)
+ */
+ public void openChannel(final Map<String, String> peerAttributes, final DoneOpenChannel done) {
+ if (Protocol.isDispatchThread()) {
+ internalOpenChannel(peerAttributes, done);
+ } else {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ internalOpenChannel(peerAttributes, done);
+ }
+ });
+ }
+ }
+
+ /**
+ * Internal implementation of {@link #openChannel(Map, org.eclipse.tm.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)}.
+ * <p>
+ * Method must be called within the TCF dispatch thread.
+ *
+ * @param peerAttributes The peer attributes. Must be not <code>null</code>.
+ * @param done The client callback. Must be not <code>null</code>.
+ */
+ /* default */ void internalOpenChannel(final Map<String, String> peerAttributes, final DoneOpenChannel done) {
+ assert peerAttributes != null;
+ assert done != null;
+ assert Protocol.isDispatchThread();
+ internalOpenChannel(getOrCreatePeerInstance(peerAttributes), done);
+ }
+
+ /**
+ * Tries to find an existing peer instance or create an new {@link IPeer}
+ * instance if not found.
+ * <p>
+ * <b>Note:</b> This method must be invoked at the TCF dispatch thread.
+ *
+ * @param peerAttributes The peer attributes. Must be not <code>null</code>.
+ * @return The peer instance.
+ */
+ private IPeer getOrCreatePeerInstance(final Map<String, String> peerAttributes) {
+ assert peerAttributes != null;
+ assert Protocol.isDispatchThread();
+
+ // Get the peer id from the properties
+ String peerId = peerAttributes.get(IPeer.ATTR_ID);
+ assert peerId != null;
+
+ // Look the peer via the Locator Service.
+ IPeer peer = Protocol.getLocator().getPeers().get(peerId);
+ // If not peer could be found, create a new one
+ if (peer == null) {
+ peer = new AbstractPeer(peerAttributes);
+ }
+
+ // Return the peer instance
+ return peer;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/Startup.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/Startup.java
new file mode 100644
index 000000000..4fd135b58
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/Startup.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.core.activator.CoreBundleActivator;
+
+
+/**
+ * Calls loaded by the TCF core framework when the framework is fired up. The static
+ * constructor of the class will trigger whatever is necessary in this case.
+ * <p>
+ * <b>Note:</b> This will effectively trigger {@link CoreBundleActivator#start(org.osgi.framework.BundleContext)}
+ * to be called.
+ */
+public class Startup {
+ // Atomic boolean to store the started state of the TCF core framework
+ /* default */ final static AtomicBoolean STARTED = new AtomicBoolean(false);
+
+ static {
+ // We might get here on shutdown as well, and if TCF has not
+ // been loaded, than we will run into an NPE. Lets double check.
+ if (Protocol.getEventQueue() != null) {
+ // Initialize the framework status by scheduling a simple
+ // runnable to execute and be invoked once the framework
+ // is fully up and usable.
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ // Core framework is scheduling the runnables, means it is started.
+ setStarted(true);
+ }
+ });
+ }
+ }
+
+ /**
+ * Set the core framework started state to the given state.
+ *
+ * @param started <code>True</code> when the framework is started, <code>false</code> otherwise.
+ */
+ public static final void setStarted(boolean started) {
+ STARTED.set(started);
+
+ // Start/Stop should be called in the TCF protocol dispatch thread
+ if (Protocol.getEventQueue() != null) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ // Catch IllegalStateException: TCF event dispatcher has shut down
+ try {
+ if (STARTED.get()) Tcf.start(); else Tcf.stop();
+ } catch (IllegalStateException e) {
+ if (!STARTED.get() && "TCF event dispatcher has shut down".equals(e.getLocalizedMessage())) { //$NON-NLS-1$
+ // ignore the exception on shutdown
+ } else {
+ // re-throw in any other case
+ throw e;
+ }
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns if or if not the core framework has been started.
+ *
+ * @return <code>True</code> when the framework is started, <code>false</code> otherwise.
+ */
+ public static final boolean isStarted() {
+ return STARTED.get();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/interfaces/IChannelOpenListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/interfaces/IChannelOpenListener.java
new file mode 100644
index 000000000..3a0273cac
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/interfaces/IChannelOpenListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal.interfaces;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.Protocol.ChannelOpenListener;
+
+/**
+ * Enhanced channel open listener interface for internal use.
+ */
+public interface IChannelOpenListener extends ChannelOpenListener {
+
+ /**
+ * Stores the given channel listener to the internal map. The map
+ * key is the given channel. If the given channel listener is <code>null</code>,
+ * the channel is removed from the internal map.
+ *
+ * @param channel The channel. Must be not <code>null</code>.
+ * @param listener The channel listener or <code>null</code>.
+ */
+ public void setChannelListener(IChannel channel, IChannel.IChannelListener listener);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelListener.java
new file mode 100644
index 000000000..2b533fb84
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelListener.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal.listener;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.core.internal.interfaces.IChannelOpenListener;
+import org.eclipse.tm.te.tcf.core.internal.nls.Messages;
+import org.eclipse.tm.te.tcf.core.internal.utils.LogUtils;
+
+
+/**
+ * Internal channel listener. Attached to a TCF channel for tracing purpose.
+ */
+public class InternalChannelListener implements IChannel.IChannelListener {
+ // The reference to the channel
+ private final IChannel fChannel;
+
+ /**
+ * Constructor.
+ *
+ * @param channel The channel. Must be not <code>null</code>.
+ */
+ public InternalChannelListener(IChannel channel) {
+ assert channel != null;
+ fChannel = channel;
+ }
+
+ /**
+ * Return the associated channel.
+ *
+ * @return The channel instance.
+ */
+ protected final IChannel getChannel() {
+ return fChannel;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.IChannel.IChannelListener#congestionLevel(int)
+ */
+ public void congestionLevel(int level) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable)
+ */
+ public void onChannelClosed(Throwable error) {
+ // Detach the listeners cleanly
+ detachListeners(getChannel());
+
+ // Construct the cause message
+ String cause = ""; //$NON-NLS-1$
+ if (error != null) {
+ cause = NLS.bind(Messages.InternalChannelListener_onChannelClosed_cause, error.getLocalizedMessage());
+ }
+
+ // Trace the channel closing
+ LogUtils.logMessageForChannel(getChannel(), NLS.bind(Messages.InternalChannelListener_onChannelClosed_message, cause), "debug/channels", this); //$NON-NLS-1$
+
+ // Fire the property change event for the channel
+ Tcf.fireChannelStateChangeListeners(getChannel(), IChannel.STATE_CLOSED);
+ }
+
+ /**
+ * Detach all registered listeners from the given channel.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ */
+ protected void detachListeners(IChannel channel) {
+ assert channel != null;
+
+ // Cleanly remove all listeners from the channel
+ channel.removeChannelListener(this);
+
+ // And remove the listener references from the global channel open listener
+ IChannelOpenListener openListener = (IChannelOpenListener)Tcf.getAdapter(IChannelOpenListener.class);
+ if (openListener != null) openListener.setChannelListener(channel, null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.IChannel.IChannelListener#onChannelOpened()
+ */
+ public void onChannelOpened() {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelOpenListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelOpenListener.java
new file mode 100644
index 000000000..70fd1367a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/listener/InternalChannelOpenListener.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal.listener;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IChannel.IChannelListener;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.core.internal.interfaces.IChannelOpenListener;
+import org.eclipse.tm.te.tcf.core.internal.nls.Messages;
+import org.eclipse.tm.te.tcf.core.internal.utils.LogUtils;
+
+
+/**
+ * Internal channel open listener taking care of logging and caching.
+ */
+public class InternalChannelOpenListener implements IChannelOpenListener {
+ // Static map containing the channel listeners per channel. Access to the
+ // map should happen from the TCF protocol dispatch thread only.
+ private final Map<IChannel, IChannel.IChannelListener> fChannelListeners = new HashMap<IChannel, IChannel.IChannelListener>();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.Protocol.ChannelOpenListener#onChannelOpen(org.eclipse.tm.tcf.protocol.IChannel)
+ */
+ public void onChannelOpen(IChannel channel) {
+ assert channel != null && Protocol.isDispatchThread();
+
+ // Trace the channel opening
+ LogUtils.logMessageForChannel(channel, Messages.InternalChannelOpenListener_onChannelOpen_message, "debug/channels", this); //$NON-NLS-1$
+
+ // As the channel has just opened, there should be no channel listener, but better be safe and check.
+ IChannel.IChannelListener channelListener = fChannelListeners.remove(channel);
+ if (channelListener != null) channel.removeChannelListener(channelListener);
+ // Create a new channel listener instance
+ channelListener = new InternalChannelListener(channel);
+ // Add the channel listener to the global map
+ setChannelListener(channel, channelListener);
+ // Attach channel listener to the channel
+ channel.addChannelListener(channelListener);
+
+ // Fire the property change event for the channel
+ Tcf.fireChannelStateChangeListeners(channel, IChannel.STATE_OPEN);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.core.internal.interfaces.IChannelOpenListener#setChannelListener(org.eclipse.tm.tcf.protocol.IChannel, org.eclipse.tm.tcf.protocol.IChannel.IChannelListener)
+ */
+ public void setChannelListener(IChannel channel, IChannelListener listener) {
+ assert channel != null;
+ if (listener != null) fChannelListeners.put(channel, listener);
+ else fChannelListeners.remove(channel);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.java
new file mode 100644
index 000000000..9bb3b6f87
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal.nls;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.tcf.core.internal.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Returns if or if not this NLS manager contains a constant for
+ * the given externalized strings key.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise.
+ */
+ public static boolean hasString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return field != null;
+ } catch (NoSuchFieldException e) { /* ignored on purpose */ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings
+ * key or <code>null</code> if the key does not exist.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ if (field != null) {
+ return (String)field.get(null);
+ }
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+
+ return null;
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String InternalChannelOpenListener_onChannelOpen_message;
+
+ public static String InternalChannelListener_onChannelClosed_message;
+ public static String InternalChannelListener_onChannelClosed_cause;
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.properties
new file mode 100644
index 000000000..5c3039f1a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/nls/Messages.properties
@@ -0,0 +1,9 @@
+#
+# org.eclipse.tm.te.tcf.core
+# Externalized Strings.
+#
+
+InternalChannelOpenListener_onChannelOpen_message=Channel opened.
+
+InternalChannelListener_onChannelClosed_message=Channel closed. {0}
+InternalChannelListener_onChannelClosed_cause=; Possibly caused by: {0}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/utils/LogUtils.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/utils/LogUtils.java
new file mode 100644
index 000000000..0db70c280
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.core/src/org/eclipse/tm/te/tcf/core/internal/utils/LogUtils.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.core.internal.utils;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.te.tcf.core.activator.CoreBundleActivator;
+
+
+/**
+ * Logging utilities helper implementations.
+ */
+public final class LogUtils {
+
+ /**
+ * Log the given message for the given channel.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ * @param message The message to log. Must not be <code>null</code>.
+ * @param slotId The Eclipse debug slot id which must be enabled to log the message. Must not be <code>null</code>.
+ * @param clazz The invoking class or <code>null</code>.
+ */
+ public static void logMessageForChannel(IChannel channel, String message, String slotId, Object clazz) {
+ assert channel != null && message != null && slotId != null;
+
+ // Trace the message
+ String fullMessage = channel.toString() + ": " + message; //$NON-NLS-1$
+
+ if (Boolean.parseBoolean(Platform.getDebugOption(CoreBundleActivator.getUniqueIdentifier() + "/" + slotId))) { //$NON-NLS-1$
+ IStatus status = new Status(IStatus.INFO, CoreBundleActivator.getUniqueIdentifier(), fullMessage.trim());
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.classpath b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.project b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.project
new file mode 100644
index 000000000..c565bd013
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.tcf.filesystem</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..3de8327ea
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Wed Apr 06 15:35:33 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..ed3a1d414
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.tcf.filesystem;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.tcf.filesystem.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.ui;bundle-version="3.6.2",
+ org.eclipse.ui.forms;bundle-version="3.5.2",
+ org.eclipse.ui.navigator;bundle-version="3.5.0",
+ org.eclipse.tm.tcf.core;bundle-version="0.3.0",
+ org.eclipse.tm.te.tcf.core;bundle-version="1.0.0",
+ org.eclipse.tm.te.ui;bundle-version="1.0.0",
+ org.eclipse.tm.te.ui.views;bundle-version="1.0.0",
+ org.eclipse.tm.te.tcf.locator;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.tcf.filesystem.controls;version="1.0.0",
+ org.eclipse.tm.te.tcf.filesystem.dialogs;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/build.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/build.properties
new file mode 100644
index 000000000..30b2fc40b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/folder.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/folder.gif
new file mode 100644
index 000000000..5ae555a34
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/folder.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdrive.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdrive.gif
new file mode 100644
index 000000000..fd426343b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdrive.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdriveopen.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdriveopen.gif
new file mode 100644
index 000000000..2171f7c38
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/icons/obj16/rootdriveopen.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.properties
new file mode 100644
index 000000000..1cb3db872
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.properties
@@ -0,0 +1,16 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer, TCF File System Extensions
+providerName = Eclipse.org
+
+# ***** Editor Pages *****
+
+FSExplorerEditorPage.name=File System
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.xml
new file mode 100644
index 000000000..5ab14daa3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/plugin.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- Common navigator contributions -->
+ <extension point="org.eclipse.ui.navigator.viewer">
+ <viewerContentBinding viewerId="org.eclipse.tm.te.ui.views.TargetExplorer">
+ <includes>
+ <contentExtension
+ isRoot="false"
+ pattern="org.eclipse.tm.te.datasource.tcf.filesystem"/>
+ </includes>
+ </viewerContentBinding>
+ </extension>
+
+ <extension point="org.eclipse.ui.navigator.navigatorContent">
+ <navigatorContent
+ activeByDefault="true"
+ contentProvider="org.eclipse.tm.te.tcf.filesystem.controls.FSTreeContentProvider"
+ icon="icons/obj16/rootdrive.gif"
+ id="org.eclipse.tm.te.datasource.tcf.filesystem"
+ labelProvider="org.eclipse.tm.te.tcf.filesystem.controls.FSTreeLabelProvider"
+ name="Target File System (TCF)"
+ priority="normal">
+ <triggerPoints>
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ <test property="org.eclipse.tm.te.tcf.locator.hasRemoteService" value="FileSystem"/>
+ </triggerPoints>
+ <possibleChildren>
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ <instanceof value="org.eclipse.tm.te.tcf.filesystem.controls.FSTreeNode"/>
+ </possibleChildren>
+ <commonSorter
+ class="org.eclipse.tm.te.tcf.filesystem.controls.FSTreeViewerSorter"
+ id="org.eclipse.tm.te.tcf.filesystem.navigator.sorter">
+ </commonSorter>
+ </navigatorContent>
+ </extension>
+
+<!-- Target Explorer Details Editor page contributions -->
+ <extension point="org.eclipse.tm.te.ui.views.editorPages">
+ <editorPage
+ class="org.eclipse.tm.te.tcf.filesystem.internal.explorer.FSExplorerEditorPage"
+ name="%FSExplorerEditorPage.name"
+ id="org.eclipse.tm.te.tcf.filesystem.FSExplorerEditorPage">
+ </editorPage>
+ </extension>
+
+<!-- Target Explorer Details Editor page binding contributions -->
+ <extension point="org.eclipse.tm.te.ui.views.editorPageBindings">
+ <editorPageBinding
+ id="org.eclipse.tm.te.tcf.filesystem.binding.FSExplorerEditorPage"
+ pageId="org.eclipse.tm.te.tcf.filesystem.FSExplorerEditorPage">
+ <enablement>
+ <with variable="activeEditorInput">
+ <and>
+ <adapt type="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel">
+ <test property="org.eclipse.tm.te.tcf.locator.hasRemoteService" value="FileSystem"/>
+ </adapt>
+ </and>
+ </with>
+ </enablement>
+ </editorPageBinding>
+ </extension>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/activator/UIPlugin.java
new file mode 100644
index 000000000..d62ab5ff2
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/activator/UIPlugin.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.activator;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.te.tcf.filesystem.internal.registries.InternalImageRegistry;
+import org.eclipse.tm.te.ui.images.AbstractImageDescriptor;
+import org.eclipse.tm.te.ui.images.AbstractImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+ // The shared instance
+ private static UIPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry registry) {
+ if (registry instanceof InternalImageRegistry) {
+ ((InternalImageRegistry)registry).initialize();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#createImageRegistry()
+ */
+ @Override
+ protected ImageRegistry createImageRegistry() {
+ return new InternalImageRegistry(this);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>Image</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getImage(String key) {
+ return getDefault().getImageRegistry().get(key);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>ImageDescriptor</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>ImageDescriptor</code> object instance or <code>null</code>.
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ return getDefault().getImageRegistry().getDescriptor(key);
+ }
+
+ /**
+ * Loads the image given by the specified image descriptor from the image
+ * registry. If the image has been loaded ones before already, the cached
+ * <code>Image</code> object instance is returned. Otherwise, the <code>
+ * Image</code> object instance will be created and cached before returned.
+ *
+ * @param descriptor The image descriptor.
+ * @return The corresponding <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getSharedImage(AbstractImageDescriptor descriptor) {
+ return ((AbstractImageRegistry)getDefault().getImageRegistry()).getSharedImage(descriptor);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeContentProvider.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeContentProvider.java
new file mode 100644
index 000000000..c8c2eaa47
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeContentProvider.java
@@ -0,0 +1,411 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.controls;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IFileSystem;
+import org.eclipse.tm.tcf.services.IFileSystem.DirEntry;
+import org.eclipse.tm.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tm.tcf.services.IFileSystem.IFileHandle;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.core.interfaces.IChannelManager;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.ui.nodes.PendingOperation;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * Target Explorer: File system tree content provider implementation.
+ */
+public class FSTreeContentProvider implements ITreeContentProvider {
+ /**
+ * Static reference to the return value representing no elements.
+ */
+ protected final static Object[] NO_ELEMENTS = new Object[0];
+
+ /**
+ * Static reference to the return value representing a pending child query.
+ */
+ protected final static Object[] PENDING = new Object[] { new PendingOperation() };
+
+
+ /* default */ IPeerModel fPeerNode = null;
+ private FSTreeNode fRootNode = null;
+
+ private IChannel fChannel = null;
+ private IFileSystem fService = null;
+
+ /* default */ Viewer fViewer = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ fViewer = viewer;
+ if (oldInput != null && newInput == null) {
+ closeOpenChannel();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ closeOpenChannel();
+ }
+
+ /**
+ * Close the open communication channel and set back the node references.
+ */
+ protected void closeOpenChannel() {
+ if (fChannel != null) {
+ final IChannel finChannel = fChannel;
+ if (Protocol.isDispatchThread()) {
+ finChannel.close();
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ finChannel.close();
+ }
+ });
+ }
+ fChannel = null;
+ fService = null;
+ }
+
+ fPeerNode = null;
+ fRootNode = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ if (element instanceof FSTreeNode) {
+ return ((FSTreeNode)element).parent;
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ assert parentElement != null;
+
+ Object[] children = NO_ELEMENTS;
+
+ // For the file system, we need the peer node
+ if (parentElement instanceof IPeerModel) {
+ // Is it the same peer node we have seen before?
+ if (fPeerNode == null || fPeerNode != null && !fPeerNode.equals(parentElement)) {
+ // Remember the peer node
+ fPeerNode = (IPeerModel)parentElement;
+
+ // If we still have a channel open, for now, we just close the old channel
+ if (fChannel != null) {
+ final IChannel finChannel = fChannel;
+ if (Protocol.isDispatchThread()) {
+ finChannel.close();
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ finChannel.close();
+ }
+ });
+ }
+ fChannel = null;
+ }
+
+ IPeer peer = fPeerNode.getPeer();
+ final int[] state = new int[1];
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ state[0] = fPeerNode.getIntProperty(IPeerModelProperties.PROP_STATE);
+ }
+ });
+ if (peer != null && IPeerModelProperties.STATE_ERROR != state[0] && IPeerModelProperties.STATE_NOT_REACHABLE != state[0]) {
+ children = PENDING;
+
+ Tcf.getChannelManager().openChannel(peer, new IChannelManager.DoneOpenChannel() {
+ @SuppressWarnings("synthetic-access")
+ public void doneOpenChannel(Throwable error, IChannel channel) {
+ assert Protocol.isDispatchThread();
+
+ if (channel != null) {
+ fChannel = channel;
+
+ fService = fChannel.getRemoteService(IFileSystem.class);
+ if (fService != null) {
+ fRootNode = new FSTreeNode();
+ fRootNode.type = "FSRootNode"; //$NON-NLS-1$
+ fRootNode.childrenQueried = false;
+ fRootNode.childrenQueryRunning = true;
+
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ fService.roots(new IFileSystem.DoneRoots() {
+ public void doneRoots(IToken token, FileSystemException error, DirEntry[] entries) {
+
+ if (fRootNode != null && error == null) {
+
+ for (DirEntry entry : entries) {
+ FSTreeNode node = createNodeFromDirEntry(entry, true);
+ if (node != null) {
+ node.parent = fRootNode;
+ fRootNode.children.add(node);
+ }
+ }
+
+ // Reset the children query markers
+ fRootNode.childrenQueryRunning = false;
+ fRootNode.childrenQueried = true;
+ }
+
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (fViewer != null) fViewer.refresh();
+ }
+ });
+ }
+ });
+ }
+ });
+
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (fViewer != null) fViewer.refresh();
+ }
+ });
+ } else {
+ // TCF file system service is not available, close the just opened channel
+ closeOpenChannel();
+ }
+
+ }
+ }
+ });
+ }
+ } else if (fRootNode != null && fRootNode.childrenQueried) {
+ children = fRootNode.children.toArray();
+ }
+ } else if (parentElement instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)parentElement;
+ // Get possible children
+ children = node.children.toArray();
+ // No children -> check for "childrenQueried" property. If false, trigger the query.
+ if (children.length == 0 && !node.childrenQueried && node.type.endsWith("DirNode")) { //$NON-NLS-1$
+ children = PENDING;
+
+ if (!node.childrenQueryRunning) {
+ final FSTreeNode parentNode = node;
+
+ final String absName = getEntryAbsoluteName(node);
+ if (absName != null && fService != null) {
+ parentNode.childrenQueryRunning = true;
+
+ Protocol.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ fService.opendir(absName, new IFileSystem.DoneOpen() {
+
+ public void doneOpen(IToken token, FileSystemException error, final IFileHandle handle) {
+
+ if (error == null && fService != null) {
+ // Read the directory content until finished
+ readdir(fService, handle, parentNode);
+ } else {
+ // In case of an error, we are done here
+ parentNode.childrenQueryRunning = false;
+ parentNode.childrenQueried = true;
+ }
+ }
+ });
+ }
+ });
+ }
+ }
+
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (fViewer != null) fViewer.refresh();
+ }
+ });
+ }
+ }
+
+ return children;
+ }
+
+ /**
+ * Reads the content of a directory until the file system service signals EOF.
+ *
+ * @param service The file system service. Must be not <code>null</code>.
+ * @param handle The directory handle. Must be not <code>null</code>.
+ * @param parentNode The parent node receiving the entries. Must be not <code>null</code>.
+ * @param mode The notification mode to set to the parent node once done.
+ */
+ protected void readdir(final IFileSystem service, final IFileHandle handle, final FSTreeNode parentNode) {
+ assert service != null && handle != null && parentNode != null;
+
+ Protocol.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ fService.readdir(handle, new IFileSystem.DoneReadDir() {
+
+ public void doneReadDir(IToken token, FileSystemException error, DirEntry[] entries, boolean eof) {
+ if (fService != null) {
+ // Close the handle if EOF is signaled or an error occurred.
+ if (eof) {
+ fService.close(handle, new IFileSystem.DoneClose() {
+ public void doneClose(IToken token, FileSystemException error) {
+ }
+ });
+ }
+
+ // Process the returned data
+ if (error == null && entries != null && entries.length > 0) {
+ for (DirEntry entry : entries) {
+ FSTreeNode node = createNodeFromDirEntry(entry, false);
+ if (node != null) {
+ node.parent = parentNode;
+ parentNode.children.add(node);
+ }
+ }
+ }
+
+ if (eof) {
+ // Reset the children query markers
+ parentNode.childrenQueryRunning = false;
+ parentNode.childrenQueried = true;
+ } else {
+ // And invoke ourself again
+ readdir(service, handle, parentNode);
+ }
+ }
+
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (fViewer instanceof StructuredViewer) ((StructuredViewer)fViewer).refresh(parentNode);
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+
+
+ /**
+ * Creates a tree node from the given directory entry.
+ *
+ * @param entry The directory entry. Must be not <code>null</code>.
+ *
+ * @return The tree node.
+ */
+ protected FSTreeNode createNodeFromDirEntry(DirEntry entry, boolean entryIsRootNode) {
+ assert entry != null;
+
+ FSTreeNode node = null;
+
+ IFileSystem.FileAttrs attrs = entry.attrs;
+
+ if (attrs == null || attrs != null && attrs.isDirectory()) {
+ node = new FSTreeNode();
+ node.childrenQueried = false;
+ node.childrenQueryRunning = false;
+ node.attr = attrs;
+ node.name = entry.filename;
+ node.type = entryIsRootNode ? "FSRootDirNode" : "FSDirNode"; //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (attrs.isFile()) {
+ node = new FSTreeNode();
+ node.childrenQueried = false;
+ node.childrenQueryRunning = false;
+ node.attr = attrs;
+ node.name = entry.filename;
+ node.type = "FSFileNode"; //$NON-NLS-1$
+ }
+
+ return node;
+ }
+
+ /**
+ * Returns the absolute name for the given node.
+ *
+ * @param node The node. Must be not <code>null</code>.
+ * @return The absolute name.
+ */
+ public static String getEntryAbsoluteName(FSTreeNode node) {
+ assert node != null;
+
+ StringBuilder path = new StringBuilder();
+
+ // We have to walk upwards the hierarchy until the root node is found
+ FSTreeNode parent = node.parent;
+ while (parent != null && parent.type != null && parent.type.startsWith("FS")) { //$NON-NLS-1$
+ if ("FSRootNode".equals(parent.type)) { //$NON-NLS-1$
+ // We are done if reaching the root node
+ break;
+ }
+
+ if (path.length() == 0) path.append(parent.name.replaceAll("\\\\", "/")); //$NON-NLS-1$ //$NON-NLS-2$
+ else {
+ String name = parent.name.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!name.endsWith("/")) name = name + "/"; //$NON-NLS-1$ //$NON-NLS-2$
+ path.insert(0, name);
+ }
+
+ parent = parent.parent;
+ }
+
+ if (path.length() > 0 && path.charAt(path.length() - 1) != '/') {
+ path.append("/"); //$NON-NLS-1$
+ }
+ path.append(node.name);
+
+ return path.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ assert element != null;
+
+ boolean hasChildren = false;
+
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)element;
+ if (node.type != null && node.type.endsWith("DirNode")) { //$NON-NLS-1$
+ if (!node.childrenQueried || node.childrenQueryRunning) {
+ hasChildren = true;
+ } else if (node.childrenQueried) {
+ hasChildren = node.children.size() > 0;
+ }
+ }
+ }
+
+ return hasChildren;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeControl.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeControl.java
new file mode 100644
index 000000000..1277bec96
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeControl.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.controls;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.tm.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tm.te.ui.interfaces.IUIConstants;
+import org.eclipse.tm.te.ui.trees.AbstractTreeControl;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+/**
+ * Target Explorer: File system browser control.
+ */
+public class FSTreeControl extends AbstractTreeControl {
+
+ /**
+ * Constructor.
+ */
+ public FSTreeControl() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPart The parent workbench part this control is embedded in or <code>null</code>.
+ */
+ public FSTreeControl(IWorkbenchPart parentPart) {
+ super(parentPart);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#configureTreeViewer(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected void configureTreeViewer(TreeViewer viewer) {
+ super.configureTreeViewer(viewer);
+
+ Tree tree = viewer.getTree();
+ if (hasColumns()) {
+ TreeColumn column = new TreeColumn(tree, SWT.LEFT);
+ column.setText(Messages.FSTreeControl_column_name_label);
+ column.setWidth(300);
+
+ column = new TreeColumn(tree, SWT.RIGHT);
+ column.setText(Messages.FSTreeControl_column_size_label);
+ column.setWidth(100);
+
+ column = new TreeColumn(tree, SWT.RIGHT);
+ column.setText(Messages.FSTreeControl_column_modified_label);
+ column.setWidth(200);
+ }
+ tree.setHeaderVisible(hasColumns());
+ }
+
+ /**
+ * Returns if or if not to show the tree columns.
+ *
+ * @return <code>True</code> to show the tree columns, <code>false</code> otherwise.
+ */
+ protected boolean hasColumns() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#doCreateTreeViewerContentProvider(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected ITreeContentProvider doCreateTreeViewerContentProvider(TreeViewer viewer) {
+ return new FSTreeContentProvider();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#doCreateTreeViewerLabelProvider(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected ILabelProvider doCreateTreeViewerLabelProvider(TreeViewer viewer) {
+ return new FSTreeLabelProvider(viewer);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#doCreateTreeViewerSelectionChangedListener(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected ISelectionChangedListener doCreateTreeViewerSelectionChangedListener(TreeViewer viewer) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#doCreateTreeViewerComparator(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected ViewerComparator doCreateTreeViewerComparator(TreeViewer viewer) {
+ return new FSTreeViewerComparator(viewer, (ILabelProvider)viewer.getLabelProvider());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#getAutoExpandLevel()
+ */
+ @Override
+ protected int getAutoExpandLevel() {
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#getContextMenuId()
+ */
+ @Override
+ protected String getContextMenuId() {
+ return IUIConstants.ID_CONTROL_MENUS_BASE + ".menu.fs"; //$NON-NLS-1$;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeLabelProvider.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeLabelProvider.java
new file mode 100644
index 000000000..4c4843fc8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeLabelProvider.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.controls;
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tm.te.tcf.filesystem.internal.registries.InternalImageRegistry;
+import org.eclipse.tm.te.ui.nodes.PendingOperation;
+import org.eclipse.tm.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+
+/**
+ * Target Explorer: File system tree control label provider implementation.
+ */
+public class FSTreeLabelProvider extends LabelProvider implements ITableLabelProvider {
+ private IEditorRegistry fEditorRegistry = null;
+
+ private static final SimpleDateFormat DATE_MODIFIED_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm"); //$NON-NLS-1$
+ private static final DecimalFormat SIZE_FORMAT = new DecimalFormat();
+
+ // Reference to the parent tree viewer
+ private TreeViewer fParentViewer;
+
+ /**
+ * Constructor.
+ */
+ public FSTreeLabelProvider() {
+ this(null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The tree viewer or <code>null</code>.
+ */
+ public FSTreeLabelProvider(TreeViewer viewer) {
+ super();
+ fParentViewer = viewer;
+ }
+
+ /**
+ * Returns the parent tree viewer instance.
+ *
+ * @return The parent tree viewer or <code>null</code>.
+ */
+ public final TreeViewer getParentViewer() {
+ if (fParentViewer == null) {
+ if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
+ && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IViewPart part = page.findView(IUIConstants.ID_EXPLORER);
+ if (part instanceof CommonNavigator) {
+ fParentViewer = ((CommonNavigator)part).getCommonViewer();
+ }
+ }
+ }
+ return fParentViewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof FSTreeNode) {
+ return ((FSTreeNode)element).name;
+ }
+ return super.getText(element);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Image getImage(Object element) {
+ if (element != null) {
+ boolean isExpanded = getParentViewer().getExpandedState(element);
+
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)element;
+ if ("FSRootDirNode".equals(node.type)) {//$NON-NLS-1$
+ return isExpanded ? UIPlugin.getImage(InternalImageRegistry.OBJ_RootDriveOpen) : UIPlugin.getImage(InternalImageRegistry.OBJ_RootDrive);
+ } else if ("FSDirNode".equals(node.type)) { //$NON-NLS-1$
+ return isExpanded ? PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER) : UIPlugin.getImage(InternalImageRegistry.OBJ_Folder);
+ } else if ("FSFileNode".equals(node.type)) { //$NON-NLS-1$
+ String key = node.name;
+ Image image = UIPlugin.getImage(key);
+ if (image == null) {
+
+ ImageDescriptor descriptor = getEditorRegistry().getImageDescriptor(key);
+ if (descriptor == null) descriptor = getEditorRegistry().getSystemExternalEditorImageDescriptor(key);
+ if (descriptor != null) UIPlugin.getDefault().getImageRegistry().put(key, descriptor);
+ image = UIPlugin.getImage(key);
+ }
+ return image;
+ }
+ }
+ }
+
+ return super.getImage(element);
+ }
+
+ private IEditorRegistry getEditorRegistry() {
+ if (fEditorRegistry == null) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null) fEditorRegistry = workbench.getEditorRegistry();
+ }
+ return fEditorRegistry;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+ */
+ public Image getColumnImage(Object element, int columnIndex) {
+ if (columnIndex == 0) return getImage(element);
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+ */
+ public String getColumnText(Object element, int columnIndex) {
+ if (columnIndex == 0) return getText(element);
+
+ if (element instanceof PendingOperation) return ""; //$NON-NLS-1$
+
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)element;
+ if (node.type != null && node.type.startsWith("FS")) { //$NON-NLS-1$
+ boolean isDirNode = node.type.endsWith("DirNode"); //$NON-NLS-1$
+ switch (columnIndex) {
+ case 1:
+ // Directory nodes does not have a size
+ if (!isDirNode) {
+ if (node.attr != null) {
+ return SIZE_FORMAT.format(node.attr.size / 1024) + " KB"; //$NON-NLS-1$
+ }
+ }
+ break;
+ case 2:
+ if (node.attr != null) {
+ return DATE_MODIFIED_FORMAT.format(new Date(node.attr.mtime));
+ }
+ break;
+ }
+
+ }
+ }
+
+ return ""; //$NON-NLS-1$
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeNode.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeNode.java
new file mode 100644
index 000000000..07bc2b842
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeNode.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.controls;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.tcf.services.IFileSystem;
+
+/**
+ * Target Explorer: Representation of a file system tree node.
+ */
+public final class FSTreeNode extends PlatformObject {
+ private final UUID fUniqueId = UUID.randomUUID();
+
+ /**
+ * The tree node name.
+ */
+ public String name = null;
+
+ /**
+ * The tree node type.
+ */
+ public String type = null;
+
+ /**
+ * The tree node file system attributes
+ */
+ public IFileSystem.FileAttrs attr = null;
+
+ /**
+ * The tree node parent.
+ */
+ public FSTreeNode parent = null;
+
+ /**
+ * The tree node children.
+ */
+ public List<FSTreeNode> children = new ArrayList<FSTreeNode>();
+
+ /**
+ * Flag to mark once the children of the node got queried
+ */
+ public boolean childrenQueried = false;
+
+ /**
+ * Flag to mark once the children query is running
+ */
+ public boolean childrenQueryRunning = false;
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public final int hashCode() {
+ return fUniqueId.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public final boolean equals(Object obj) {
+ if (obj instanceof FSTreeNode) {
+ return fUniqueId.equals(((FSTreeNode)obj).fUniqueId);
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return name != null ? name : super.toString();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerComparator.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerComparator.java
new file mode 100644
index 000000000..071574c4a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerComparator.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.controls;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tm.te.ui.trees.TreeViewerComparator;
+
+
+/**
+ * Target Explorer: File system tree control viewer comparator implementation.
+ */
+public class FSTreeViewerComparator extends TreeViewerComparator {
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The parent viewer. Must be not <code>null</code>.
+ * @param labelProvider The label provider. Must be not <code>null</code>.
+ */
+ public FSTreeViewerComparator(Viewer viewer, ILabelProvider labelProvider) {
+ super(viewer, labelProvider);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.trees.TreeViewerComparator#doCompare(java.lang.Object, java.lang.Object, java.lang.String, int, int)
+ */
+ @Override
+ protected int doCompare(Object node1, Object node2, String sortColumn, int index, int inverter) {
+ if (node1 instanceof FSTreeNode && node2 instanceof FSTreeNode) {
+ // Get the type labels
+ String t1 = ((FSTreeNode)node1).type;
+ String t2 = ((FSTreeNode)node2).type;
+
+ // Group directories and files always together before sorting by name
+ if (("FSRootDirNode".equals(t1) || "FSDirNode".equals(t1)) //$NON-NLS-1$ //$NON-NLS-2$
+ && !("FSRootDirNode".equals(t2) || "FSDirNode".equals(t2))) { //$NON-NLS-1$ //$NON-NLS-2$
+ return -1 * inverter;
+ }
+
+ if (("FSRootDirNode".equals(t2) || "FSDirNode".equals(t2)) //$NON-NLS-1$ //$NON-NLS-2$
+ && !("FSRootDirNode".equals(t1) || "FSDirNode".equals(t1))) { //$NON-NLS-1$ //$NON-NLS-2$
+ return 1 * inverter;
+ }
+
+ // If the nodes are of the same type and one entry starts
+ // with a '.', it comes before the one without a '.'
+ if (t1 != null && t2 != null && t1.equals(t2)) {
+ String n1 = doGetText(node1, index);
+ String n2 = doGetText(node2, index);
+ if (n1 != null && n2 != null) {
+ if (n1.startsWith(".") && !n2.startsWith(".")) return -1 * inverter; //$NON-NLS-1$ //$NON-NLS-2$
+ if (!n1.startsWith(".") && n2.startsWith(".")) return 1 * inverter; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ }
+
+ return super.doCompare(node1, node2, sortColumn, index, inverter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerSorter.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerSorter.java
new file mode 100644
index 000000000..24715fc77
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/controls/FSTreeViewerSorter.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.controls;
+
+import org.eclipse.jface.viewers.TreePathViewerSorter;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Target Explorer: File system tree control viewer sorter implementation.
+ */
+public class FSTreeViewerSorter extends TreePathViewerSorter {
+ private final FSTreeLabelProvider fLabelProvider = new FSTreeLabelProvider();
+ private final FSTreeViewerComparator fComparator;
+
+ /**
+ * Constructor.
+ */
+ public FSTreeViewerSorter() {
+ fComparator = new FSTreeViewerComparator(fLabelProvider.getParentViewer(), fLabelProvider);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ return fComparator.compare(viewer, e1, e2);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/dialogs/FSOpenFileDialog.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/dialogs/FSOpenFileDialog.java
new file mode 100644
index 000000000..d587963a6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/dialogs/FSOpenFileDialog.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.dialogs;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.te.tcf.filesystem.controls.FSTreeControl;
+import org.eclipse.tm.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tm.te.ui.dialogs.CustomTrayDialog;
+import org.eclipse.tm.te.ui.forms.CustomFormToolkit;
+import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.editor.IFormPage;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * Target Explorer: File system open file dialog.
+ */
+public class FSOpenFileDialog extends CustomTrayDialog {
+ // Reference to the subcontrol
+ private final FSTreeControl fControl;
+ // Reference to the current selection within the file system tree
+ private ISelection fSelection;
+
+ protected class FSOpenFileTreeControl extends FSTreeControl {
+
+ /**
+ * Constructor.
+ */
+ public FSOpenFileTreeControl() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPage The parent form page this control is embedded in or
+ * <code>null</code> if the control is not embedded within
+ * a form page.
+ */
+ public FSOpenFileTreeControl(FormPage parentPage) {
+ super(parentPage);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.tcf.ui.internal.controls.trees.fs.FSTreeControl#hasColumns()
+ */
+ @Override
+ protected boolean hasColumns() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.tcf.ui.internal.controls.trees.fs.FSTreeControl#doCreateTreeViewerSelectionChangedListener(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ protected ISelectionChangedListener doCreateTreeViewerSelectionChangedListener(TreeViewer viewer) {
+ return new FSOpenFileTreeControlSelectionChangedListener();
+ }
+ }
+
+ protected class FSOpenFileTreeControlSelectionChangedListener implements ISelectionChangedListener{
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ @SuppressWarnings("synthetic-access")
+ public void selectionChanged(SelectionChangedEvent event) {
+ fSelection = event.getSelection();
+ updateButtons();
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param shell The parent shell or <code>null</code>.
+ */
+ public FSOpenFileDialog(Shell shell) {
+ this(shell, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param shell The parent shell or <code>null</code>.
+ * @param contextHelpId The dialog context help id or <code>null</code>.
+ */
+ public FSOpenFileDialog(Shell shell, String contextHelpId) {
+ this(null, shell, contextHelpId);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPage The parent form page this control is embedded in or
+ * <code>null</code> if the control is not embedded within
+ * a form page.
+ * @param shell The parent shell or <code>null</code>.
+ * @param contextHelpId The dialog context help id or <code>null</code>.
+ */
+ public FSOpenFileDialog(FormPage parentPage, Shell shell, String contextHelpId) {
+ super(shell, contextHelpId);
+
+ fControl = new FSOpenFileTreeControl(parentPage);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#isResizable()
+ */
+ @Override
+ protected boolean isResizable() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.common.ui.dialogs.WRUnifiedTrayDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+
+ setDialogTitle(Messages.FSOpenFileDialog_title);
+
+ Composite panel = new Composite(composite, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0; layout.marginHeight = 0;
+ panel.setLayout(layout);
+ GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ layoutData.heightHint = convertHeightInCharsToPixels(25);
+ layoutData.widthHint = convertWidthInCharsToPixels(50);
+ panel.setLayoutData(layoutData);
+
+ CustomFormToolkit toolkit = null;
+ if (fControl.getParentPart() instanceof IFormPage && ((IFormPage)fControl.getParentPart()).getManagedForm() != null) {
+ toolkit = new CustomFormToolkit(((IFormPage)fControl.getParentPart()).getManagedForm().getToolkit());
+ }
+ if (toolkit == null) toolkit = new CustomFormToolkit(new FormToolkit(getShell().getDisplay()));
+
+ fControl.setupFormPanel(panel, toolkit);
+
+ return composite;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.common.ui.dialogs.WRUnifiedTrayDialog#close()
+ */
+ @Override
+ public boolean close() {
+ if (fControl != null) {
+ fControl.dispose();
+ }
+
+ return super.close();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createButtonBar(Composite parent) {
+ Control control = super.createButtonBar(parent);
+ updateButtons();
+ return control;
+ }
+
+ /**
+ * Update the button enablement.
+ */
+ protected void updateButtons() {
+ Button okButton = getButton(IDialogConstants.OK_ID);
+ if (okButton != null) okButton.setEnabled(fSelection != null && !fSelection.isEmpty());
+ }
+
+ /**
+ * Returns the current file system control selection.
+ * @return
+ */
+ public ISelection getSelection() {
+ return fSelection;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/explorer/FSExplorerEditorPage.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/explorer/FSExplorerEditorPage.java
new file mode 100644
index 000000000..f3e361f11
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/explorer/FSExplorerEditorPage.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.internal.explorer;
+
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tm.te.tcf.filesystem.controls.FSTreeControl;
+import org.eclipse.tm.te.tcf.filesystem.internal.help.IContextHelpIds;
+import org.eclipse.tm.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tm.te.ui.forms.CustomFormToolkit;
+import org.eclipse.tm.te.ui.views.editor.AbstractEditorPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+
+
+/**
+ * Target Explorer: File system editor page implementation.
+ *
+ * @author uwe.stieber@windriver.com
+ */
+public class FSExplorerEditorPage extends AbstractEditorPage {
+ // The references to the pages subcontrol's (needed for disposal)
+ private FSTreeControl fFileSystemControl;
+
+ // Reference to the form toolkit instance
+ private CustomFormToolkit fToolkit = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (fFileSystemControl != null) { fFileSystemControl.dispose(); fFileSystemControl = null; }
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
+ */
+ @Override
+ protected void createFormContent(IManagedForm managedForm) {
+ // Configure the managed form
+ configureManagedForm(managedForm);
+
+ // Get the form body
+ Composite body = managedForm.getForm().getBody();
+
+ // Create the toolkit instance
+ fToolkit = new CustomFormToolkit(managedForm.getToolkit());
+
+ // Do create the content of the form now
+ doCreateFormContent(body, fToolkit);
+
+ // Re-arrange the controls
+ managedForm.reflow(true);
+ }
+
+ /**
+ * Configure the managed form to be ready for usage.
+ *
+ * @param managedForm The managed form. Must be not <code>null</code>.
+ */
+ protected void configureManagedForm(IManagedForm managedForm) {
+ assert managedForm != null;
+
+ // Configure main layout
+ Composite body = managedForm.getForm().getBody();
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 2; layout.marginWidth = 0;
+ body.setLayout(layout);
+ body.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+
+ // Set context help id
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(managedForm.getForm(), IContextHelpIds.FS_EXPLORER_EDITOR_PAGE);
+ }
+
+ /**
+ * Do create the managed form content.
+ *
+ * @param parent The parent composite. Must be not <code>null</code>
+ * @param toolkit The {@link CustomFormToolkit} instance. Must be not <code>null</code>.
+ */
+ protected void doCreateFormContent(Composite parent, CustomFormToolkit toolkit) {
+ assert parent != null && toolkit != null;
+
+ Section section = toolkit.getFormToolkit().createSection(parent, ExpandableComposite.TITLE_BAR);
+ String title = Messages.FSExplorerTreeControl_section_title;
+ // Stretch to a length of 40 characters to make sure the title can be changed
+ // to hold and show text up to this length
+ while (title.length() < 40) {
+ title += " "; //$NON-NLS-1$
+ }
+ // Set the title to the section
+ section.setText(title);
+ section.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // Create the client area
+ Composite client = toolkit.getFormToolkit().createComposite(section);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0; layout.marginHeight = 0;
+ client.setLayout(layout);
+ section.setClient(client);
+
+ // Setup the file system tree control
+ fFileSystemControl = doCreateFileSystemTreeControl();
+ assert fFileSystemControl != null;
+ fFileSystemControl.setupFormPanel((Composite)section.getClient(), toolkit);
+
+ // Set the initial input
+ fFileSystemControl.getViewer().setInput(getEditorInputNode());
+ }
+
+ /**
+ * Creates and returns a file system tree control.
+ *
+ * @return The new file system tree control.
+ */
+ protected FSTreeControl doCreateFileSystemTreeControl() {
+ return new FSTreeControl(this);
+ }
+
+ /**
+ * Returns the associated file system tree control.
+ *
+ * @return The associated file system tree control or <code>null</code>.
+ */
+ protected final FSTreeControl getFileSystemTreeControl() {
+ return fFileSystemControl;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/help/IContextHelpIds.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/help/IContextHelpIds.java
new file mode 100644
index 000000000..be7f94bb4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/help/IContextHelpIds.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.internal.help;
+
+import org.eclipse.tm.te.tcf.filesystem.activator.UIPlugin;
+
+/**
+ * Plugin context help id definitions.
+ */
+public interface IContextHelpIds {
+
+ /**
+ * Target Explorer file system UI plug-in common context help id prefix.
+ */
+ public final static String PREFIX = UIPlugin.getUniqueIdentifier() + "."; //$NON-NLS-1$
+
+ /**
+ /**
+ * Target Explorer details editor page: File system explorer
+ */
+ public final static String FS_EXPLORER_EDITOR_PAGE = PREFIX + "FSExplorerEditorPage"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.java
new file mode 100644
index 000000000..956484609
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.internal.nls;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer: File System plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.tcf.filesystem.internal.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Returns if or if not this NLS manager contains a constant for
+ * the given externalized strings key.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise.
+ */
+ public static boolean hasString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return field != null;
+ } catch (NoSuchFieldException e) { /* ignored on purpose */ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings
+ * key or <code>null</code> if the key does not exist.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ if (field != null) {
+ return (String)field.get(null);
+ }
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+
+ return null;
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String FSExplorerTreeControl_section_title;
+
+ public static String FSTreeControl_column_name_label;
+ public static String FSTreeControl_column_size_label;
+ public static String FSTreeControl_column_modified_label;
+
+ public static String FSOpenFileDialog_title;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.properties
new file mode 100644
index 000000000..7531e40ce
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/nls/Messages.properties
@@ -0,0 +1,12 @@
+#
+# org.eclipse.tm.te.tcf.filesystem
+# Externalized Strings.
+#
+
+FSExplorerTreeControl_section_title=Exploring File System
+
+FSTreeControl_column_name_label=Name
+FSTreeControl_column_size_label=Size
+FSTreeControl_column_modified_label=Date Modified
+
+FSOpenFileDialog_title=Select Process Image
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/registries/InternalImageRegistry.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/registries/InternalImageRegistry.java
new file mode 100644
index 000000000..0ea23ad5b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.filesystem/src/org/eclipse/tm/te/tcf/filesystem/internal/registries/InternalImageRegistry.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.filesystem.internal.registries;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.tm.te.ui.images.AbstractImageRegistry;
+
+
+/**
+ * Target Explorer: File System UI Plug-in image registry.
+ */
+public class InternalImageRegistry extends AbstractImageRegistry {
+ private static List<Object[]> fStore = new ArrayList<Object[]>();
+
+ // declare all keys down here
+ public static final String OBJ_RootDrive = declareLocalImage("obj16", "rootdrive.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ public static final String OBJ_RootDriveOpen = declareLocalImage("obj16", "rootdriveopen.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ public static final String OBJ_Folder = declareLocalImage("obj16", "folder.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // external eclipse icons not reachable using ISharedImages
+
+ /**
+ * Constructor.
+ *
+ * @param plugin The plugin descriptor the image registry is created for.
+ */
+ public InternalImageRegistry(Plugin plugin) {
+ super(plugin);
+ }
+
+ /**
+ * Initialize image registry with all keys known yet.
+ */
+ public void initialize() {
+ for (Iterator<Object[]> iter = fStore.iterator(); iter.hasNext();) {
+ Object[] element = iter.next();
+ if (element.length == 3) {
+ localImage((String)element[0], (String)element[1], (String)element[2]);
+ }
+ else if (element.length > 3){
+ externalImage((String)element[0], (String)element[1], (String[])element[2], (String)element[3]);
+ }
+ }
+ }
+
+ /**
+ * Declare a locally stored image to the image registry.
+ */
+ static String declareLocalImage(String dir, String name) {
+ List<Object> registryObject = new ArrayList<Object>();
+ registryObject.add(dir);
+ registryObject.add(name);
+ String key = name + "_" + registryObject.hashCode(); //$NON-NLS-1$
+ registryObject.add(0, key);
+ fStore.add(registryObject.toArray());
+ return key;
+ }
+
+ /**
+ * Declare a externally stored image to the image registry.
+ */
+ static String declareExternalImage(String plugin, String[] dirs, String name) {
+ List<Object> registryObject = new ArrayList<Object>();
+ registryObject.add(plugin);
+ registryObject.add(dirs);
+ registryObject.add(name);
+ String key = name + "_" + registryObject.hashCode(); //$NON-NLS-1$
+ registryObject.add(0, key);
+ fStore.add(registryObject.toArray());
+ return key;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.classpath b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.project b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.project
new file mode 100644
index 000000000..1588cf8cc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.tcf.locator</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..4b09f4879
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Wed Apr 06 16:34:47 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..0b6fddbed
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.tcf.locator; singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.tcf.locator.activator.CoreBundleActivator
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.core.expressions;bundle-version="3.4.200",
+ org.eclipse.tm.tcf.core;bundle-version="0.3.0",
+ org.eclipse.tm.te.tcf.core;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.tcf.locator;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.interfaces;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.interfaces.nodes;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.interfaces.preferences;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.interfaces.services;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.listener;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.nodes;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.services;version="1.0.0",
+ org.eclipse.tm.te.tcf.locator.utils;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/build.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/build.properties
new file mode 100644
index 000000000..30b2fc40b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.properties
new file mode 100644
index 000000000..b6f6fe9dd
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.properties
@@ -0,0 +1,12 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer, TCF Locator Extensions
+providerName = Eclipse.org
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.xml
new file mode 100644
index 000000000..b748d8e90
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/plugin.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- Preference contributions -->
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.tm.te.tcf.locator.internal.preferences.PreferencesInitializer">
+ </initializer>
+ </extension>
+
+<!-- Eclipse core expressions property tester -->
+ <extension point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.tm.te.tcf.locator.internal.MyPropertyTester"
+ id="org.eclipse.tm.te.tcf.locator.LocatorModelPropertyTester"
+ namespace="org.eclipse.tm.te.tcf.locator"
+ properties="name,hasLocalService,hasRemoteService"
+ type="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel">
+ </propertyTester>
+ </extension>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/Scanner.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/Scanner.java
new file mode 100644
index 000000000..9466baa0c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/Scanner.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.IScanner;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+
+
+/**
+ * Locator model scanner implementation.
+ */
+public class Scanner extends Job implements IScanner {
+ // Reference to the parent model instance.
+ private final ILocatorModel fParentModel;
+
+ // Reference to the scanner configuration
+ private final Map<String, Object> fConfiguration = new HashMap<String, Object>();
+
+ // Flag to mark if the scanner is terminated
+ private AtomicBoolean fTerminated = new AtomicBoolean(false);
+
+ /**
+ * Constructor.
+ *
+ * @param parentModel The parent model instance. Must be not <code>null</code>.
+ */
+ public Scanner(ILocatorModel parentModel) {
+ super(Scanner.class.getName());
+ assert parentModel != null;
+ fParentModel = parentModel;
+ }
+
+ /**
+ * Returns the parent model instance.
+ *
+ * @return The parent model instance.
+ */
+ protected ILocatorModel getParentModel() {
+ return fParentModel;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#setConfiguration(java.util.Map)
+ */
+ public void setConfiguration(Map<String, Object> configuration) {
+ assert configuration != null;
+ fConfiguration.clear();
+ fConfiguration.putAll(configuration);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#getConfiguration()
+ */
+ public Map<String, Object> getConfiguration() {
+ return fConfiguration;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ if (monitor == null) monitor = new NullProgressMonitor();
+
+ // Get the current list of peers known to the parent model
+ IPeerModel[] peers = getParentModel().getPeers();
+ // Do we have something to scan at all
+ if (peers.length > 0) {
+ // The first runnable is setting the thread which will finish
+ // the job at the end
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ Scanner.this.setThread(Thread.currentThread());
+ }
+ });
+ // Loop the nodes and try to get an channel
+ for (IPeerModel peer : peers) {
+ // Check for the progress monitor getting canceled
+ if (monitor.isCanceled() || isTerminated()) break;
+ // Create the scanner runnable
+ Runnable runnable = new ScannerRunnable(this, peer);
+ // Submit for execution
+ Protocol.invokeLater(runnable);
+ }
+ // The last runnable will terminate the job as soon all
+ // scanner runnable's are processed and will reschedule the job
+ final IStatus result = monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ Scanner.this.done(result);
+
+ Long delay = (Long)getConfiguration().get(IScanner.PROP_SCHEDULE);
+ if (delay != null) {
+ Scanner.this.schedule(delay.longValue());
+ }
+ }
+ });
+ }
+
+ return peers.length > 0 ? ASYNC_FINISH : Status.OK_STATUS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#terminate()
+ */
+ public void terminate() {
+ fTerminated.set(true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#isTerminated()
+ */
+ public final boolean isTerminated() {
+ return fTerminated.get();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#shouldRun()
+ */
+ @Override
+ public boolean shouldRun() {
+ return Platform.isRunning() && !getParentModel().isDisposed() && !isTerminated();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#shouldSchedule()
+ */
+ @Override
+ public boolean shouldSchedule() {
+ return Platform.isRunning() && !getParentModel().isDisposed() && !isTerminated();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/ScannerRunnable.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/ScannerRunnable.java
new file mode 100644
index 000000000..286d878d4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/ScannerRunnable.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator;
+
+import java.net.SocketTimeoutException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.core.ChannelTCP;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.te.tcf.locator.interfaces.IScanner;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelUpdateService;
+import org.eclipse.tm.te.tcf.locator.nodes.PeerModel;
+
+
+/**
+ * Scanner runnable to be executed for each peer to probe within the
+ * TCF event dispatch thread.
+ */
+public class ScannerRunnable implements Runnable, IChannel.IChannelListener {
+ /**
+ * The default socket connect timeout in milliseconds.
+ */
+ private static final int DEFAULT_SOCKET_CONNECT_TIMEOUT = 10000;
+
+ // Reference to the parent model scanner
+ private final IScanner fParentScanner;
+ // Reference to the peer model node to update
+ private final IPeerModel fPeerNode;
+ // Reference to the channel
+ private IChannel fChannel = null;
+
+ /**
+ * Constructor.
+ *
+ * @param scanner The parent model scanner or <code>null</code> if the runnable is constructed from outside a scanner.
+ * @param peerNode The peer model instance. Must be not <code>null</code>.
+ */
+ public ScannerRunnable(IScanner scanner, IPeerModel peerNode) {
+ super();
+
+ fParentScanner = scanner;
+
+ assert peerNode != null;
+ fPeerNode = peerNode;
+ }
+
+ /**
+ * Returns the parent scanner instance.
+ *
+ * @return The parent scanner instance or <code>null</code>.
+ */
+ protected final IScanner getParentScanner() {
+ return fParentScanner;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ if (fPeerNode != null && fPeerNode.getPeer() != null) {
+ // Open the channel
+ fChannel = fPeerNode.getPeer().openChannel();
+ // Configure the connect timeout
+ if (fChannel instanceof ChannelTCP) {
+ int timeout = fPeerNode.getIntProperty(IPeerModelProperties.PROP_CONNECT_TIMEOUT);
+ if (timeout == -1) timeout = DEFAULT_SOCKET_CONNECT_TIMEOUT;
+ ((ChannelTCP)fChannel).setConnectTimeout(timeout);
+ }
+ // Add ourself as channel listener
+ fChannel.addChannelListener(this);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.IChannel.IChannelListener#onChannelOpened()
+ */
+ public void onChannelOpened() {
+ // Peer is reachable
+ if (fChannel != null) {
+ // Remove ourself as channel listener
+ fChannel.removeChannelListener(this);
+ }
+
+ // Set the peer state property
+ if (fPeerNode != null) {
+ int counter = fPeerNode.getIntProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER);
+ fPeerNode.setProperty(IPeerModelProperties.PROP_STATE, counter > 0 ? IPeerModelProperties.STATE_CONNECTED : IPeerModelProperties.STATE_REACHABLE);
+ fPeerNode.setProperty(IPeerModelProperties.PROP_LAST_SCANNER_ERROR, null);
+ }
+
+ if (fChannel != null && fChannel.getState() == IChannel.STATE_OPEN) {
+ // Get the parent model from the model mode
+ final ILocatorModel model = (ILocatorModel)fPeerNode.getAdapter(ILocatorModel.class);
+ if (model != null) {
+ // Get the local service
+ Collection<String> localServices = new ArrayList<String>(fChannel.getLocalServices());
+ // Get the remote services
+ Collection<String> remoteServices = new ArrayList<String>(fChannel.getRemoteServices());
+
+ // Get the update service
+ ILocatorModelUpdateService updateService = model.getService(ILocatorModelUpdateService.class);
+ if (updateService != null) {
+ // Update the services nodes
+ updateService.updatePeerServices(fPeerNode, localServices, remoteServices);
+ }
+
+ // Use the open channel to ask the remote peer what other
+ // peers it knows
+ ILocator locator = fChannel.getRemoteService(ILocator.class);
+ if (locator != null) {
+ final Map<String, IPeer> peers = locator.getPeers();
+ if (peers != null && !peers.isEmpty()) {
+ // Execute asynchronously within the TCF dispatch thread
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (String peerId : peers.keySet()) {
+ // Try to find an existing peer node first
+ IPeerModel peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(peerId);
+ if (peerNode == null) peerNode = new PeerModel(model, peers.get(peerId));
+ // Add the peer node to model
+ model.getService(ILocatorModelUpdateService.class).add(peerNode);
+ // And schedule for immediate status update
+ Runnable runnable = new ScannerRunnable(getParentScanner(), peerNode);
+ Protocol.invokeLater(runnable);
+ }
+ }
+ });
+ }
+ }
+ }
+
+ // And close the channel
+ fChannel.close();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable)
+ */
+ public void onChannelClosed(Throwable error) {
+ // Peer is not reachable
+
+ if (fChannel != null) {
+ // Remove ourself as channel listener
+ fChannel.removeChannelListener(this);
+ }
+
+ // Set the peer state property, if the scanner the runnable
+ // has been scheduled from is still active.
+ if (fPeerNode != null && (fParentScanner == null || fParentScanner != null && !fParentScanner.isTerminated())) {
+ fPeerNode.setProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, null);
+ fPeerNode.setProperty(IPeerModelProperties.PROP_STATE,
+ error instanceof SocketTimeoutException ? IPeerModelProperties.STATE_NOT_REACHABLE : IPeerModelProperties.STATE_ERROR);
+ fPeerNode.setProperty(IPeerModelProperties.PROP_LAST_SCANNER_ERROR, error instanceof SocketTimeoutException ? null : error);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.protocol.IChannel.IChannelListener#congestionLevel(int)
+ */
+ public void congestionLevel(int level) {
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java
new file mode 100644
index 000000000..d6426c304
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/activator/CoreBundleActivator.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.activator;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class CoreBundleActivator implements BundleActivator {
+ // The bundle context
+ private static BundleContext context;
+
+ /**
+ * Returns the bundle context
+ *
+ * @return the bundle context
+ */
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getContext() != null && getContext().getBundle() != null) {
+ return getContext().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IModelListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IModelListener.java
new file mode 100644
index 000000000..32ebc923d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IModelListener.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces;
+
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+
+/**
+ * Interface for clients to implement that wishes to listen
+ * to changes to the locator model.
+ */
+public interface IModelListener {
+
+ /**
+ * Invoked if a peer is added or removed to/from the locator model.
+ *
+ * @param model The changed locator model.
+ */
+ public void locatorModelChanged(ILocatorModel model);
+
+ /**
+ * Invoked if the locator model is disposed.
+ *
+ * @param model The disposed locator model.
+ */
+ public void locatorModelDisposed(ILocatorModel model);
+
+ /**
+ * Invoked if the peer model properties have changed.
+ *
+ * @param model The parent locator model.
+ * @param peer The changed peer model.
+ */
+ public void peerModelChanged(ILocatorModel model, IPeerModel peer);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IScanner.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IScanner.java
new file mode 100644
index 000000000..4499f107f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/IScanner.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces;
+
+import java.util.Map;
+
+/**
+ * Locator model scanner.
+ */
+public interface IScanner {
+
+ /**
+ * Scanner configuration property: The time in millisecond between the scanner runs.
+ */
+ public static String PROP_SCHEDULE = "schedule"; //$NON-NLS-1$
+
+ /**
+ * Set or modify the current scanner configuration.
+ *
+ * @param configuration The new scanner configuration. Must be not <code>null</code>.
+ */
+ public void setConfiguration(Map<String, Object> configuration);
+
+ /**
+ * Returns the current scanner configuration.
+ *
+ * @return The current scanner configuration.
+ */
+ public Map<String, Object> getConfiguration();
+
+ /**
+ * Terminate the scanner.
+ */
+ public void terminate();
+
+ /**
+ * Returns if or if not the discovery model scanner has been terminated.
+ *
+ * @return <code>True</code> if the discovery model scanner is terminated, <code>false</code> if still active.
+ */
+ public boolean isTerminated();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/ILocatorModel.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/ILocatorModel.java
new file mode 100644
index 000000000..eef07852d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/ILocatorModel.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.nodes;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.te.tcf.locator.interfaces.IModelListener;
+import org.eclipse.tm.te.tcf.locator.interfaces.IScanner;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelService;
+
+
+/**
+ * The locator model is an extension to the TCF locator service. The
+ * model allows to store additional properties for each peer, keep
+ * track of peers from different origins.
+ * <p>
+ * <b>Note:</b> Updates to the locator model, and the locator model
+ * children needs to be performed in the TCF dispatch thread. The
+ * locator model and all child model nodes do assert this core
+ * assumption. To maintain consistency, and to avoid any performance
+ * overhead for thread synchronization, the model read access must
+ * happen in the TCF dispatch thread as well.
+ *
+ * @see ILocator
+ */
+public interface ILocatorModel extends IAdaptable {
+
+ /**
+ * Adds the specified listener to the list of model listener.
+ * If the same listener has been added before, the listener will
+ * not be added again.
+ *
+ * @param listener The listener. Must be not <code>null</code>.
+ */
+ public void addListener(IModelListener listener);
+
+ /**
+ * Removes the specified listener from the list of model listener.
+ *
+ * @param listener The listener. Must be not <code>null</code>.
+ */
+ public void removeListener(IModelListener listener);
+
+ /**
+ * Returns the list of registered model listeners.
+ *
+ * @return The list of registered model listeners or an empty list.
+ */
+ public IModelListener[] getListener();
+
+ /**
+ * Dispose the locator model instance.
+ */
+ public void dispose();
+
+ /**
+ * Returns if or if not the locator model instance is disposed.
+ *
+ * @return <code>True</code> if the locator model instance is disposed, <code>false/code> otherwise.
+ */
+ public boolean isDisposed();
+
+ /**
+ * Returns the list of known peers.
+ *
+ * @return The list of known peers or an empty list.
+ */
+ public IPeerModel[] getPeers();
+
+ /**
+ * Returns the scanner instance being associated with the
+ * locator model.
+ *
+ * @return The scanner instance.
+ */
+ public IScanner getScanner();
+
+ /**
+ * Starts the scanner.
+ *
+ * @param delay The delay in millisecond before the scanning starts.
+ * @param schedule The time in millisecond between the scanner runs.
+ */
+ public void startScanner(long delay, long schedule);
+
+ /**
+ * Stops the scanner.
+ */
+ public void stopScanner();
+
+ /**
+ * Returns the locator model service, implementing at least the specified
+ * service interface.
+ *
+ * @param serviceInterface The service interface class. Must be not <code>null</code>.
+ * @return The service instance implementing the specified service interface, or <code>null</code>.
+ */
+ public <V extends ILocatorModelService> V getService(Class<V> serviceInterface);
+
+ /**
+ * Validate the given peer model if or if not it can be added
+ * to the locator model as new peer node.
+ *
+ * @param node The peer model. Must be not <code>null</code>.
+ * @return The peer node if it allowed add it to the model, or <code>null</code> if not.
+ */
+ public IPeerModel validatePeerNodeForAdd(IPeerModel node);
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModel.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModel.java
new file mode 100644
index 000000000..a1569db6b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModel.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.nodes;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tm.tcf.protocol.IPeer;
+
+/**
+ * The peer model is an extension to the TCF target/host
+ * representation, implementing the {@link IPeer} interface.
+ * The peer model provides an offline cache for a peers known list
+ * of local and remote services and is the merge point of peer
+ * attributes from custom data storages.
+ * <p>
+ * <b>Note:</b> The {@link #getProperty(String)} method provides access
+ * both the native peer attributes and to the custom attributes. Alternatively,
+ * the native peer attributes can be access via <i><code>getPeer().getAttributes()</code></i>.
+ * <p>
+ * <b>Note:</b> Read and write access to the peer model must happen within
+ * the TCF dispatch thread.
+ */
+public interface IPeerModel extends IAdaptable {
+
+ /**
+ * Returns the parent locator model instance.
+ *
+ * @return The parent locator model instance.
+ */
+ public ILocatorModel getModel();
+
+ /**
+ * Returns the native {@link IPeer} object.
+ *
+ * @return The native {@link IPeer} instance.
+ */
+ public IPeer getPeer();
+
+ /**
+ * Set the properties from the given map. Calling this method
+ * will overwrite all previous set properties.
+ *
+ * @param properties The map of properties to set. Must be not <code>null</code>.
+ */
+ public void setProperties(Map<String, Object> properties);
+
+ /**
+ * Stores the property under the given property key using the given property value.
+ * If the current property value is equal to the given property value, no store
+ * operation will be executed. If the property value is not <code>null</code> and
+ * is different from the current property value, the new value will be written to
+ * the property store and a property change event is fired. If the property value
+ * is <code>null</code>, the property key and the currently stored value are removed
+ * from the property store.
+ *
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ */
+ public boolean setProperty(String key, Object value);
+
+ /**
+ * Stores the property under the given property key using the given long
+ * property value. The given long value is transformed to an <code>Long</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, long value);
+
+ /**
+ * Stores the property under the given property key using the given integer
+ * property value. The given integer value is transformed to an <code>Integer</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, int value);
+
+ /**
+ * Stores the property under the given property key using the given boolean
+ * property value. The given boolean value is transformed to an <code>Boolean</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, boolean value);
+
+ /**
+ * Stores the property under the given property key using the given float
+ * property value. The given float value is transformed to an <code>Float</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, float value);
+
+ /**
+ * Stores the property under the given property key using the given double
+ * property value. The given double value is transformed to an <code>Double</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, double value);
+
+ /**
+ * Return all properties. The result map is read-only.
+ *
+ * @return A map containing all properties.
+ */
+ public Map<String, Object> getProperties();
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * does not exist, <code>null</code> is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value or <code>null</code>.
+ */
+ public Object getProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.String</code>, the property value casted to
+ * <code>java.lang.String</code> is returned. In all other cases, <code>null</code>
+ * is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value casted <code>java.lang.String</code> or <code>null</code>.
+ */
+ public String getStringProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Long</code>, the property value converted
+ * to an long value is returned. In all other cases, <code>-1</code> is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value converted to a long value or <code>-1</code>.
+ */
+ public long getLongProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Integer</code>, the property value converted
+ * to an integer value is returned. In all other cases, <code>-1</code> is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value converted to an integer value or <code>-1</code>.
+ */
+ public int getIntProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Boolean</code>, the property value converted
+ * to an boolean value is returned. In all other cases, <code>false</code> is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value converted to an boolean value or <code>false</code>.
+ */
+ public boolean getBooleanProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Float</code>, the property value converted
+ * to an float value is returned. In all other cases, <code>Float.NaN</code> is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value converted to a float value or <code>Float.NaN</code>.
+ */
+ public float getFloatProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Double</code>, the property value converted
+ * to an double value is returned. In all other cases, <code>Double.NaN</code> is returned.
+ *
+ * @param key The property key. Must be not <code>null</code>!
+ * @return The stored property value converted to a double value or <code>Double.NaN</code>.
+ */
+ public double getDoubleProperty(String key);
+
+ /**
+ * Remove all properties from the properties store. The method does not fire any
+ * properties changed event.
+ */
+ public void clearProperties();
+
+ /**
+ * Test if the property value stored under the given property is equal ignoring the case to the given
+ * expected string value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property string value.
+ * @return <code>true</code> if the expected string value is equal ignoring the case to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isPropertyIgnoreCase(String key, String value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, Object value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, long value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, int value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, boolean value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, float value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must be not <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, double value);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java
new file mode 100644
index 000000000..f54cd80ec
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/nodes/IPeerModelProperties.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.nodes;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+
+/**
+ * Default set of custom peer properties.
+ */
+public interface IPeerModelProperties {
+
+ /**
+ * Property: The peer instance. Object stored here must be
+ * castable to {@link IPeer}.
+ */
+ public static final String PROP_INSTANCE = "instance"; //$NON-NLS-1$
+
+ /**
+ * Property: The list of known local service names.
+ */
+ public static final String PROP_LOCAL_SERVICES = "services.local"; //$NON-NLS-1$
+
+ /**
+ * Property: The list of known remote service names.
+ */
+ public static final String PROP_REMOTE_SERVICES = "services.remote"; //$NON-NLS-1$
+
+ /**
+ * Property: The peer state.
+ */
+ public static String PROP_STATE = "state"; //$NON-NLS-1$
+
+ /**
+ * Peer state: Not determined yet (unknown).
+ */
+ public static int STATE_UNKNOWN = -1;
+
+ /**
+ * Peer state: Peer is reachable, no active communication channel is open.
+ */
+ public static int STATE_REACHABLE = 0;
+
+ /**
+ * Peer state: Peer is reachable and an active communication channel is opened.
+ */
+ public static int STATE_CONNECTED = 1;
+
+ /**
+ * Peer state: Peer is not reachable. Connection attempt timed out.
+ */
+ public static int STATE_NOT_REACHABLE = 2;
+
+ /**
+ * Peer state: Peer is not reachable. Connection attempt terminated with error.
+ */
+ public static int STATE_ERROR = 3;
+
+ /**
+ * Property: The peer connect timeout (for socket based transports)
+ */
+ public static String PROP_CONNECT_TIMEOUT = "connectTimeout"; //$NON-NLS-1$
+
+ /**
+ * Property: Reference counter tracking the active channels for this peer.
+ */
+ public static String PROP_CHANNEL_REF_COUNTER = "channelRefCounter.silent"; //$NON-NLS-1$
+
+ /**
+ * Property: The last error the scanner encounter trying to open a channel to this peer.
+ */
+ public static String PROP_LAST_SCANNER_ERROR = "lastScannerError"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java
new file mode 100644
index 000000000..d4a5e24c8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/preferences/IPreferenceKeys.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.preferences;
+
+/**
+ * The locator model bundle preference key identifiers..
+ */
+public interface IPreferenceKeys {
+ /**
+ * Common prefix for all core preference keys
+ */
+ public final String PREFIX = "tcf.locator.core."; //$NON-NLS-1$
+
+ /**
+ * If set to <code>true</code>, peers having the same agent id are filtered.
+ */
+ public final String PREF_FILTER_BY_AGENT_ID = PREFIX + "model.filter.agentid"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelLookupService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelLookupService.java
new file mode 100644
index 000000000..29216f813
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelLookupService.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.services;
+
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+
+/**
+ * The service to lookup/search in the parent locator model.
+ */
+public interface ILocatorModelLookupService extends ILocatorModelService {
+
+ /**
+ * Lookup the peer model for the given peer id.
+ *
+ * @param id The peer id. Must be not <code>null</code>.
+ * @return The peer model instance, or <code>null</code> if the peer model cannot be found.
+ */
+ public IPeerModel lkupPeerModelById(String id);
+
+ /**
+ * Lookup the peer model for the given peer id.
+ *
+ * @param agentId The agent id. Must be not <code>null</code>.
+ * @return The peer model instance, or <code>null</code> if the peer model cannot be found.
+ */
+ public IPeerModel lkupPeerModelByAgentId(String agentId);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelRefreshService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelRefreshService.java
new file mode 100644
index 000000000..9f430206f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelRefreshService.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.services;
+
+/**
+ * The service to refresh the parent locator model from remote.
+ */
+public interface ILocatorModelRefreshService extends ILocatorModelService {
+
+ /**
+ * Refreshes the list of known peers from the local locator service
+ * and update the locator model.
+ */
+ public void refresh();
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelService.java
new file mode 100644
index 000000000..d82da4f01
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelService.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.services;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+
+
+/**
+ * Common parent interface for locator model services.
+ */
+public interface ILocatorModelService extends IAdaptable {
+
+ /**
+ * Returns the parent locator model.
+ *
+ * @return The parent locator model.
+ */
+ public ILocatorModel getLocatorModel();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelUpdateService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelUpdateService.java
new file mode 100644
index 000000000..c1df5932d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/interfaces/services/ILocatorModelUpdateService.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.interfaces.services;
+
+import java.util.Collection;
+
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+
+
+/**
+ * The service to update the properties of given locator model nodes.
+ */
+public interface ILocatorModelUpdateService extends ILocatorModelService {
+
+ /**
+ * Adds the given peer to the list of know peers. A previous
+ * mapping to a peer model with the same id as the given
+ * peer model is overwritten.
+ *
+ * @param peer The peer model object. Must be not <code>null</code>.
+ */
+ public void add(IPeerModel peer);
+
+ /**
+ * Removes the given peer from the list of known peers.
+ *
+ * @param peer The peer model object. Must be not <code>null</code.
+ */
+ public void remove(IPeerModel peer);
+
+ /**
+ * Update the service nodes of the given peer node with the new set of
+ * local and/or remote services.
+ *
+ * @param peerNode The peer model instance. Must be not <code>null</code>.
+ * @param localServices The list of local service names or <code>null</code>.
+ * @param remoteServices The list of remote service names or <code>null</code>.
+ */
+ public void updatePeerServices(IPeerModel peerNode, Collection<String> localServices, Collection<String> remoteServices);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/MyPropertyTester.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/MyPropertyTester.java
new file mode 100644
index 000000000..0869d4c13
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/MyPropertyTester.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.internal;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+
+
+
+/**
+ * Locator model property tester.
+ *
+ * @author uwe.stieber@windriver.com
+ */
+public class MyPropertyTester extends PropertyTester {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
+ // The receiver is expected to be a peer model node
+ if (receiver instanceof IPeerModel) {
+ final Boolean[] result = new Boolean[1];
+ if (Protocol.isDispatchThread()) {
+ result[0] = Boolean.valueOf(testPeerModel((IPeerModel)receiver, property, args, expectedValue));
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ result[0] = Boolean.valueOf(testPeerModel((IPeerModel)receiver, property, args, expectedValue));
+ }
+ });
+ }
+ if (result[0] != null) return result[0].booleanValue();
+ }
+ return false;
+ }
+
+ /**
+ * Test the specific peer model node properties.
+ *
+ * @param node The model node. Must not be <code>null</code>.
+ * @param property The property to test.
+ * @param args The property arguments.
+ * @param expectedValue The expected value.
+ *
+ * @return <code>True</code> if the property to test has the expected value, <code>false</code> otherwise.
+ */
+ protected boolean testPeerModel(IPeerModel node, String property, Object[] args, Object expectedValue) {
+ assert Protocol.isDispatchThread() && node != null;
+
+ if ("name".equals(property)) { //$NON-NLS-1$
+ if (node.getPeer().getName() != null && node.getPeer().getName().equals(expectedValue)) {
+ return true;
+ }
+ }
+
+ if ("hasLocalService".equals(property) || "hasRemoteService".equals(property)) { //$NON-NLS-1$ //$NON-NLS-2$
+ String services = null;
+
+ if ("hasLocalService".equals(property)) services = node.getStringProperty(IPeerModelProperties.PROP_LOCAL_SERVICES); //$NON-NLS-1$
+ if ("hasRemoteService".equals(property)) services = node.getStringProperty(IPeerModelProperties.PROP_REMOTE_SERVICES); //$NON-NLS-1$
+
+ if (services != null) {
+ // Lookup each service individually to avoid "accidental" matching
+ for (String service : services.split(",")) { //$NON-NLS-1$
+ if (service != null && service.trim().equals(expectedValue)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.java
new file mode 100644
index 000000000..71a99e328
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.internal.nls;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer TCF Locator plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.tcf.locator.internal.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Returns if or if not this NLS manager contains a constant for
+ * the given externalized strings key.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise.
+ */
+ public static boolean hasString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return field != null;
+ } catch (NoSuchFieldException e) { /* ignored on purpose */ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings
+ * key or <code>null</code> if the key does not exist.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ if (field != null) {
+ return (String)field.get(null);
+ }
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+
+ return null;
+ }
+
+ // **** Declare externalized string id's down here *****
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.properties
new file mode 100644
index 000000000..5f3b5dc7e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/nls/Messages.properties
@@ -0,0 +1,4 @@
+#
+# org.eclipse.tm.te.tcf.locator
+# Externalized Strings.
+#
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/preferences/PreferencesInitializer.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/preferences/PreferencesInitializer.java
new file mode 100644
index 000000000..c0312f5ec
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/internal/preferences/PreferencesInitializer.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.tm.te.tcf.locator.activator.CoreBundleActivator;
+import org.eclipse.tm.te.tcf.locator.interfaces.preferences.IPreferenceKeys;
+
+
+/**
+ * The locator model bundle preference initializer.
+ */
+public class PreferencesInitializer extends AbstractPreferenceInitializer {
+
+ /**
+ * Constructor.
+ */
+ public PreferencesInitializer() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ @Override
+ public void initializeDefaultPreferences() {
+ // Get the bundles preferences manager
+ IEclipsePreferences prefs = new DefaultScope().getNode(CoreBundleActivator.getUniqueIdentifier());
+ if (prefs != null) {
+ // Filtered by agent id: default on
+ prefs.putBoolean(IPreferenceKeys.PREF_FILTER_BY_AGENT_ID, true);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ChannelStateChangeListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ChannelStateChangeListener.java
new file mode 100644
index 000000000..99353b7d6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ChannelStateChangeListener.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.listener;
+
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.core.interfaces.listeners.IChannelStateChangeListener;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+
+
+/**
+ * Channel state change listener implementation.
+ */
+public class ChannelStateChangeListener implements IChannelStateChangeListener {
+ // Reference to the parent model
+ private final ILocatorModel fModel;
+
+ /**
+ * Constructor.
+ *
+ * @param model The parent locator model. Must be not <code>null</code>.
+ */
+ public ChannelStateChangeListener(ILocatorModel model) {
+ assert model != null;
+ fModel = model;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.tcf.core.interfaces.listeners.IChannelStateChangeListener#stateChanged(org.eclipse.tm.tcf.protocol.IChannel, int)
+ */
+ public void stateChanged(IChannel channel, int state) {
+ assert Protocol.isDispatchThread() && channel != null;
+
+ switch (state) {
+ case IChannel.STATE_OPEN:
+ IPeer peer = channel.getRemotePeer();
+ // Find the corresponding model node
+ IPeerModel node = fModel.getService(ILocatorModelLookupService.class).lkupPeerModelById(peer.getID());
+ if (node != null) {
+ // Increase the channel reference counter by 1
+ int counter = node.getIntProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER);
+ if (counter < 0) counter = 0;
+ counter++;
+ node.setProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, counter);
+ if (counter > 0) node.setProperty(IPeerModelProperties.PROP_STATE, IPeerModelProperties.STATE_CONNECTED);
+ }
+ break;
+ case IChannel.STATE_CLOSED:
+ peer = channel.getRemotePeer();
+ // Find the corresponding model node
+ node = fModel.getService(ILocatorModelLookupService.class).lkupPeerModelById(peer.getID());
+ if (node != null) {
+ // Decrease the channel reference counter by 1
+ int counter = node.getIntProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER);
+ counter--;
+ if (counter < 0) counter = 0;
+ node.setProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, counter);
+ if (counter == 0) node.setProperty(IPeerModelProperties.PROP_STATE, IPeerModelProperties.STATE_REACHABLE);
+ }
+ break;
+ }
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/LocatorListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/LocatorListener.java
new file mode 100644
index 000000000..bdf0605ef
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/LocatorListener.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.listener;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.te.tcf.locator.ScannerRunnable;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelUpdateService;
+import org.eclipse.tm.te.tcf.locator.nodes.PeerModel;
+
+
+/**
+ * Locator listener implementation.
+ */
+public class LocatorListener implements ILocator.LocatorListener {
+ // Reference to the parent model
+ private final ILocatorModel fModel;
+
+ /**
+ * Constructor.
+ *
+ * @param model The parent locator model. Must be not <code>null</code>.
+ */
+ public LocatorListener(ILocatorModel model) {
+ super();
+
+ assert model != null;
+ fModel = model;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.services.ILocator.LocatorListener#peerAdded(org.eclipse.tm.tcf.protocol.IPeer)
+ */
+ public void peerAdded(IPeer peer) {
+ if (fModel != null && peer != null) {
+ // find the corresponding model node to remove (expected to be null)
+ IPeerModel peerNode = fModel.getService(ILocatorModelLookupService.class).lkupPeerModelById(peer.getID());
+ // If found, remove the old node
+ if (peerNode != null) fModel.getService(ILocatorModelUpdateService.class).remove(peerNode);
+ // Create a new peer node instance
+ peerNode = new PeerModel(fModel, peer);
+ // Validate the peer node before adding
+ if (peerNode != null) peerNode = fModel.validatePeerNodeForAdd(peerNode);
+ // Add the peer node to the model
+ if (peerNode != null) {
+ fModel.getService(ILocatorModelUpdateService.class).add(peerNode);
+ // And schedule for immediate status update
+ Runnable runnable = new ScannerRunnable(fModel.getScanner(), peerNode);
+ Protocol.invokeLater(runnable);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.services.ILocator.LocatorListener#peerChanged(org.eclipse.tm.tcf.protocol.IPeer)
+ */
+ public void peerChanged(IPeer peer) {
+ if (fModel != null && peer != null) {
+ // find the corresponding model node to remove
+ IPeerModel peerNode = fModel.getService(ILocatorModelLookupService.class).lkupPeerModelById(peer.getID());
+ // Update the peer instance
+ if (peerNode != null) peerNode.setProperty(IPeerModelProperties.PROP_INSTANCE, peer);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.services.ILocator.LocatorListener#peerRemoved(java.lang.String)
+ */
+ public void peerRemoved(String id) {
+ if (fModel != null && id != null) {
+ // find the corresponding model node to remove
+ IPeerModel peerNode = fModel.getService(ILocatorModelLookupService.class).lkupPeerModelById(id);
+ if (peerNode != null) {
+ // Remove from the model
+ fModel.getService(ILocatorModelUpdateService.class).remove(peerNode);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.tcf.services.ILocator.LocatorListener#peerHeartBeat(java.lang.String)
+ */
+ public void peerHeartBeat(String id) {
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ModelAdapter.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ModelAdapter.java
new file mode 100644
index 000000000..e68c020df
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/listener/ModelAdapter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.listener;
+
+import org.eclipse.tm.te.tcf.locator.interfaces.IModelListener;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+
+/**
+ * Default model listener implementation.
+ */
+public class ModelAdapter implements IModelListener {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IModelListener#locatorModelChanged(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel)
+ */
+ public void locatorModelChanged(ILocatorModel model) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IModelListener#locatorModelDisposed(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel)
+ */
+ public void locatorModelDisposed(ILocatorModel model) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IModelListener#peerModelChanged(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel, org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel)
+ */
+ public void peerModelChanged(ILocatorModel model, IPeerModel peer) {
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/LocatorModel.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/LocatorModel.java
new file mode 100644
index 000000000..6b2965ece
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/LocatorModel.java
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.nodes;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.core.interfaces.listeners.IChannelStateChangeListener;
+import org.eclipse.tm.te.tcf.locator.Scanner;
+import org.eclipse.tm.te.tcf.locator.activator.CoreBundleActivator;
+import org.eclipse.tm.te.tcf.locator.interfaces.IModelListener;
+import org.eclipse.tm.te.tcf.locator.interfaces.IScanner;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.preferences.IPreferenceKeys;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelRefreshService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelUpdateService;
+import org.eclipse.tm.te.tcf.locator.listener.ChannelStateChangeListener;
+import org.eclipse.tm.te.tcf.locator.listener.LocatorListener;
+import org.eclipse.tm.te.tcf.locator.services.LocatorModelLookupService;
+import org.eclipse.tm.te.tcf.locator.services.LocatorModelRefreshService;
+import org.eclipse.tm.te.tcf.locator.services.LocatorModelUpdateService;
+import org.eclipse.tm.te.tcf.locator.utils.IPAddressUtil;
+
+
+/**
+ * Default locator model implementation.
+ */
+public class LocatorModel extends PlatformObject implements ILocatorModel {
+ // Flag to mark the model disposed
+ private boolean fDisposed;
+
+ // The list of known peers
+ private final Map<String, IPeerModel> fPeers = new HashMap<String, IPeerModel>();
+
+ // Reference to the scanner
+ private IScanner fScanner = null;
+
+ // Reference to the model locator listener
+ private ILocator.LocatorListener fLocatorListener = null;
+ // Reference to the model channel state change listener
+ private IChannelStateChangeListener fChannelStateChangeListener = null;
+
+ // The list of registered model listeners
+ private final List<IModelListener> fModelListener = new ArrayList<IModelListener>();
+
+ // Reference to the refresh service
+ private final ILocatorModelRefreshService fRefreshService = new LocatorModelRefreshService(this);
+ // Reference to the lookup service
+ private final ILocatorModelLookupService fLookupService = new LocatorModelLookupService(this);
+ // Reference to the update service
+ private final ILocatorModelUpdateService fUpdateService = new LocatorModelUpdateService(this);
+
+ /**
+ * Constructor.
+ */
+ public LocatorModel() {
+ super();
+ fDisposed = false;
+
+ fChannelStateChangeListener = new ChannelStateChangeListener(this);
+ Tcf.addChannelStateChangeListener(fChannelStateChangeListener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#addListener(org.eclipse.tm.te.tcf.locator.core.interfaces.IModelListener)
+ */
+ public void addListener(IModelListener listener) {
+ assert Protocol.isDispatchThread() && listener != null;
+ if (!fModelListener.contains(listener)) fModelListener.add(listener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#removeListener(org.eclipse.tm.te.tcf.locator.core.interfaces.IModelListener)
+ */
+ public void removeListener(IModelListener listener) {
+ assert Protocol.isDispatchThread() && listener != null;
+ fModelListener.remove(listener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel#getListener()
+ */
+ public IModelListener[] getListener() {
+ return fModelListener.toArray(new IModelListener[fModelListener.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#dispose()
+ */
+ public void dispose() {
+ assert Protocol.isDispatchThread();
+
+ // If already disposed, we are done immediately
+ if (fDisposed) return;
+
+ fDisposed = true;
+
+ final IModelListener[] listeners = getListener();
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IModelListener listener : listeners) {
+ listener.locatorModelDisposed(LocatorModel.this);
+ }
+ }
+ });
+ }
+ fModelListener.clear();
+
+ if (fLocatorListener != null) {
+ Protocol.getLocator().removeListener(fLocatorListener);
+ fLocatorListener = null;
+ }
+
+ if (fChannelStateChangeListener != null) {
+ Tcf.removeChannelStateChangeListener(fChannelStateChangeListener);
+ fChannelStateChangeListener = null;
+ }
+
+ if (fScanner != null) {
+ stopScanner();
+ fScanner = null;
+ }
+
+ fPeers.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#isDisposed()
+ */
+ public boolean isDisposed() {
+ return fDisposed;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#getPeers()
+ */
+ public IPeerModel[] getPeers() {
+ return fPeers.values().toArray(new IPeerModel[fPeers.values().size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (adapter.isAssignableFrom(ILocator.LocatorListener.class)) {
+ return fLocatorListener;
+ }
+ if (adapter.isAssignableFrom(IScanner.class)) {
+ return fScanner;
+ }
+ if (adapter.isAssignableFrom(ILocatorModelRefreshService.class)) {
+ return fRefreshService;
+ }
+ if (adapter.isAssignableFrom(ILocatorModelLookupService.class)) {
+ return fLookupService;
+ }
+ if (adapter.isAssignableFrom(ILocatorModelUpdateService.class)) {
+ return fUpdateService;
+ }
+ if (adapter.isAssignableFrom(Map.class)) {
+ return fPeers;
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#getService(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public <V extends ILocatorModelService> V getService(Class<V> serviceInterface) {
+ assert serviceInterface != null;
+ return (V)getAdapter(serviceInterface);
+ }
+
+ /**
+ * Check if the locator listener has been created and registered
+ * to the global locator service.
+ * <p>
+ * <b>Note:</b> This method is not intended to be call from clients.
+ */
+ public void checkLocatorListener() {
+ assert Protocol.isDispatchThread();
+ assert Protocol.getLocator() != null;
+
+ if (fLocatorListener == null) {
+ fLocatorListener = doCreateLocatorListener(this);
+ Protocol.getLocator().addListener(fLocatorListener);
+ }
+ }
+
+ /**
+ * Creates the locator listener instance.
+ *
+ * @param model The parent model. Must be not <code>null</code>.
+ * @return The locator listener instance.
+ */
+ protected ILocator.LocatorListener doCreateLocatorListener(ILocatorModel model) {
+ assert model != null;
+ return new LocatorListener(model);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#getScanner()
+ */
+ public IScanner getScanner() {
+ if (fScanner == null) fScanner = new Scanner(this);
+ return fScanner;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#startScanner(long, long)
+ */
+ public void startScanner(long delay, long schedule) {
+ IScanner scanner = getScanner();
+
+ if (scanner != null) {
+ // Pass on the schedule parameter
+ Map<String, Object> config = new HashMap<String, Object>(scanner.getConfiguration());
+ config.put(IScanner.PROP_SCHEDULE, Long.valueOf(schedule));
+ scanner.setConfiguration(config);
+ }
+
+ // The default scanner implementation is a job.
+ // -> schedule here if it is a job
+ if (scanner instanceof Job) {
+ Job job = (Job)scanner;
+ job.setSystem(true);
+ job.setPriority(Job.DECORATE);
+ job.schedule(delay);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#stopScanner()
+ */
+ public void stopScanner() {
+ if (fScanner != null) {
+ // Terminate the scanner
+ fScanner.terminate();
+ // Reset the scanner reference
+ fScanner = null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel#validatePeerNodeForAdd(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel)
+ */
+ public IPeerModel validatePeerNodeForAdd(IPeerModel node) {
+ assert Protocol.isDispatchThread() && node != null;
+
+ // Get the peer from the peer node
+ IPeer peer = node.getPeer();
+
+ IPeerModel result = node;
+
+ // Check on the filtered by preference settings what to do
+ boolean isFilterByAgentId = Platform.getPreferencesService().getBoolean(CoreBundleActivator.getUniqueIdentifier(),
+ IPreferenceKeys.PREF_FILTER_BY_AGENT_ID,
+ false, null);
+ if (isFilterByAgentId) {
+ // Peers are filtered by agent id. Don't add the peer node
+ // if we have another peer node already having the same agent id
+ String agentId = peer.getAgentID();
+ IPeerModel previousNode = agentId != null ? getService(ILocatorModelLookupService.class).lkupPeerModelByAgentId(agentId) : null;
+ if (previousNode != null) {
+ // Get the peer for the previous node
+ IPeer previousPeer = previousNode.getPeer();
+ if (previousPeer != null) {
+ // We prefer to use the peer node for the canonical IP address before
+ // the loop back address before any other address.
+ String loopback = IPAddressUtil.getInstance().getIPv4LoopbackAddress();
+ String canonical = IPAddressUtil.getInstance().getCanonicalAddress();
+
+ boolean fireListener = false;
+
+ String peerIP = peer.getAttributes().get(IPeer.ATTR_IP_HOST);
+ String previousPeerIP = previousPeer.getAttributes().get(IPeer.ATTR_IP_HOST);
+ if (canonical != null && canonical.equals(peerIP) && !canonical.equals(previousPeerIP)) {
+ // Remove the old node and replace it with the new new
+ fPeers.remove(previousNode.getPeer().getID());
+ fireListener = true;
+ } else if (loopback != null && loopback.equals(peerIP) && !loopback.equals(previousPeerIP)
+ && (canonical == null || canonical != null && !canonical.equals(previousPeerIP))) {
+ // Remove the old node and replace it with the new new
+ fPeers.remove(previousNode.getPeer().getID());
+ fireListener = true;
+ } else {
+ // Drop the current node
+ result = null;
+ }
+
+ if (fireListener) {
+ final IModelListener[] listeners = getListener();
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IModelListener listener : listeners) {
+ listener.locatorModelChanged(LocatorModel.this);
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/PeerModel.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/PeerModel.java
new file mode 100644
index 000000000..50ac619b1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/nodes/PeerModel.java
@@ -0,0 +1,398 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.nodes;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.IModelListener;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+
+
+/**
+ * Default peer model implementation.
+ */
+public class PeerModel extends PlatformObject implements IPeerModel {
+ // Reference to the parent locator model
+ private final ILocatorModel fParentModel;
+
+ /**
+ * The custom properties map. The keys are always strings, the value might be any object.
+ */
+ private Map<String, Object> fProperties = new LinkedHashMap<String, Object>();
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent locator model. Must be not <code>null</code>.
+ */
+ public PeerModel(ILocatorModel parent) {
+ this(parent, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent locator model. Must be not <code>null</code>.
+ * @param peer The peer or <code>null</code>.
+ */
+ public PeerModel(ILocatorModel parent, IPeer peer) {
+ super();
+
+ assert parent != null;
+ fParentModel = parent;
+
+ setProperty(IPeerModelProperties.PROP_INSTANCE, peer);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getModel()
+ */
+ public ILocatorModel getModel() {
+ return (ILocatorModel)getAdapter(ILocatorModel.class);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getPeer()
+ */
+ public IPeer getPeer() {
+ return (IPeer)getAdapter(IPeer.class);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings({ "rawtypes" })
+ @Override
+ public Object getAdapter(final Class adapter) {
+ // NOTE: The getAdapter(...) method can be invoked from many place and
+ // many threads where we cannot control the calls. Therefore, this
+ // method is the only one which is allowed to call from any thread.
+ final Object[] object = new Object[1];
+ if (Protocol.isDispatchThread()) {
+ object[0] = doGetAdapter(adapter);
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ object[0] = doGetAdapter(adapter);
+ }
+ });
+ }
+ return object[0] != null ? object[0] : super.getAdapter(adapter);
+ }
+
+ /**
+ * Returns an object which is an instance of the given class associated with this object.
+ * Returns <code>null</code> if no such object can be found.
+ * <p>
+ * This method must be called within the TCF dispatch thread!
+ *
+ * @param adapter The adapter class to look up.
+ * @return The adapter or <code>null</code>.
+ */
+ protected Object doGetAdapter(Class<?> adapter) {
+ assert Protocol.isDispatchThread();
+
+ if (adapter.isAssignableFrom(ILocatorModel.class)) {
+ return fParentModel;
+ }
+
+ Object peer = getProperty(IPeerModelProperties.PROP_INSTANCE);
+ if (peer != null && adapter.isAssignableFrom(peer.getClass())) {
+ return peer;
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getProperties()
+ */
+ public Map<String, Object> getProperties() {
+ assert Protocol.isDispatchThread();
+ return Collections.unmodifiableMap(new HashMap<String, Object>(fProperties));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getProperty(java.lang.String)
+ */
+ public Object getProperty(String key) {
+ assert Protocol.isDispatchThread();
+
+ if (!fProperties.containsKey(key)
+ && getPeer() != null && getPeer().getAttributes().containsKey(key)) {
+ return getPeer().getAttributes().get(key);
+ }
+
+ return fProperties.get(key);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getBooleanProperty(java.lang.String)
+ */
+ public final boolean getBooleanProperty(String key) {
+ Object value = getProperty(key);
+ if (value instanceof Boolean) {
+ return ((Boolean)value).booleanValue();
+ }
+ if (value instanceof String) {
+ String val = ((String)value).trim();
+ return "TRUE".equalsIgnoreCase(val) || "1".equals(val) || "Y".equalsIgnoreCase(val) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "JA".equalsIgnoreCase(val) || "YES".equalsIgnoreCase(val); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getLongProperty(java.lang.String)
+ */
+ public final long getLongProperty(String key) {
+ Object value = getProperty(key);
+ if (value instanceof Long) {
+ return ((Long)value).longValue();
+ }
+ else if (value instanceof Integer) {
+ return ((Integer)value).intValue();
+ }
+ else if (value != null) {
+ try {
+ return Long.decode(value.toString()).longValue();
+ }
+ catch (Exception e) {}
+ }
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getIntProperty(java.lang.String)
+ */
+ public final int getIntProperty(String key) {
+ Object value = getProperty(key);
+ try {
+ return value instanceof Integer ? ((Integer)value).intValue() :
+ (value != null ? Integer.decode(value.toString()).intValue() : -1);
+ }
+ catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getStringProperty(java.lang.String)
+ */
+ public final String getStringProperty(String key) {
+ Object value = getProperty(key);
+ return value instanceof String ? (String)value :
+ (value != null ? value.toString() : null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getFloatProperty(java.lang.String)
+ */
+ public final float getFloatProperty(String key) {
+ Object value = getProperty(key);
+ try {
+ return value instanceof Float ? ((Float)value).floatValue() :
+ (value != null ? Float.parseFloat(value.toString()) : Float.NaN);
+ }
+ catch (Exception e) {
+ return Float.NaN;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#getDoubleProperty(java.lang.String)
+ */
+ public final double getDoubleProperty(String key) {
+ Object value = getProperty(key);
+ try {
+ return value instanceof Double ? ((Double)value).doubleValue() :
+ (value != null ? Double.parseDouble(value.toString()) : Double.NaN);
+ }
+ catch (Exception e) {
+ return Double.NaN;
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperties(java.util.Map)
+ */
+ public final void setProperties(Map<String, Object> properties) {
+ assert Protocol.isDispatchThread() && properties != null;
+
+ fProperties.clear();
+ fProperties.putAll(properties);
+
+ final IModelListener[] listeners = fParentModel.getListener();
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ for (IModelListener listener : listeners) {
+ listener.peerModelChanged(fParentModel, PeerModel.this);
+ }
+ }
+ });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperty(java.lang.String, boolean)
+ */
+ public final boolean setProperty(String key, boolean value) {
+ boolean oldValue = getBooleanProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Boolean.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperty(java.lang.String, long)
+ */
+ public final boolean setProperty(String key, long value) {
+ long oldValue = getLongProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Long.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperty(java.lang.String, int)
+ */
+ public final boolean setProperty(String key, int value) {
+ int oldValue = getIntProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Integer.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperty(java.lang.String, float)
+ */
+ public final boolean setProperty(String key, float value) {
+ float oldValue = getFloatProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Float.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperty(java.lang.String, double)
+ */
+ public final boolean setProperty(String key, double value) {
+ double oldValue = getDoubleProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Double.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#setProperty(java.lang.String, java.lang.Object)
+ */
+ public boolean setProperty(String key, Object value) {
+ assert Protocol.isDispatchThread();
+
+ Object oldValue = fProperties.get(key);
+ if ((oldValue == null && value != null) || (oldValue != null && !oldValue.equals(value))) {
+ if (value != null) {
+ fProperties.put(key, value);
+ } else {
+ fProperties.remove(key);
+ }
+
+ final IModelListener[] listeners = fParentModel.getListener();
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ for (IModelListener listener : listeners) {
+ listener.peerModelChanged(fParentModel, PeerModel.this);
+ }
+ }
+ });
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#clearProperties()
+ */
+ public final void clearProperties() {
+ assert Protocol.isDispatchThread();
+ fProperties.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isProperty(java.lang.String, long)
+ */
+ public final boolean isProperty(String key, long value) {
+ return getLongProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isProperty(java.lang.String, boolean)
+ */
+ public final boolean isProperty(String key, boolean value) {
+ return getBooleanProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isProperty(java.lang.String, int)
+ */
+ public final boolean isProperty(String key, int value) {
+ return getIntProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isProperty(java.lang.String, float)
+ */
+ public final boolean isProperty(String key, float value) {
+ return getFloatProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isProperty(java.lang.String, double)
+ */
+ public final boolean isProperty(String key, double value) {
+ return getDoubleProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isPropertyIgnoreCase(java.lang.String, java.lang.String)
+ */
+ public final boolean isPropertyIgnoreCase(String key, String value) {
+ String property = getStringProperty(key);
+ return (property == null && value == null) || (property != null && property.equalsIgnoreCase(value));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel#isProperty(java.lang.String, java.lang.Object)
+ */
+ public final boolean isProperty(String key, Object value) {
+ Object property = getProperty(key);
+ return (property == null && value == null) || (property != null && property.equals(value));
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/AbstractLocatorModelService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/AbstractLocatorModelService.java
new file mode 100644
index 000000000..34d36b732
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/AbstractLocatorModelService.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.services;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelService;
+
+
+/**
+ * Abstract locator model service base implementation.
+ */
+public abstract class AbstractLocatorModelService extends PlatformObject implements ILocatorModelService {
+ // Reference to the parent locator model
+ private final ILocatorModel fLocatorModel;
+
+ /**
+ * Constructor.
+ *
+ * @param parentModel The parent locator model instance. Must be not <code>null</code>.
+ */
+ public AbstractLocatorModelService(ILocatorModel parentModel) {
+ assert parentModel != null;
+ fLocatorModel = parentModel;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelService#getLocatorModel()
+ */
+ public final ILocatorModel getLocatorModel() {
+ return fLocatorModel;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelLookupService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelLookupService.java
new file mode 100644
index 000000000..c744fe1bf
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelLookupService.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.services;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+
+
+/**
+ * Default locator model lookup service implementation.
+ */
+public class LocatorModelLookupService extends AbstractLocatorModelService implements ILocatorModelLookupService {
+
+ /**
+ * Constructor.
+ *
+ * @param parentModel The parent locator model instance. Must be not <code>null</code>.
+ */
+ public LocatorModelLookupService(ILocatorModel parentModel) {
+ super(parentModel);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.services.ILocatorModelLookupService#lkupPeerModelById(java.lang.String)
+ */
+ public IPeerModel lkupPeerModelById(String id) {
+ assert Protocol.isDispatchThread() && id != null;
+
+ IPeerModel node = null;
+ for (IPeerModel candidate : getLocatorModel().getPeers()) {
+ IPeer peer = candidate.getPeer();
+ if (id.equals(peer.getID())) {
+ node = candidate;
+ break;
+ }
+ }
+
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.services.ILocatorModelLookupService#lkupPeerModelByAgentId(java.lang.String)
+ */
+ public IPeerModel lkupPeerModelByAgentId(String agentId) {
+ assert Protocol.isDispatchThread() && agentId != null;
+
+ IPeerModel node = null;
+ for (IPeerModel candidate : getLocatorModel().getPeers()) {
+ IPeer peer = candidate.getPeer();
+ if (agentId.equals(peer.getAgentID())) {
+ node = candidate;
+ break;
+ }
+ }
+
+ return node;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java
new file mode 100644
index 000000000..dd2455d22
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelRefreshService.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.services;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.locator.ScannerRunnable;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelRefreshService;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelUpdateService;
+import org.eclipse.tm.te.tcf.locator.nodes.LocatorModel;
+import org.eclipse.tm.te.tcf.locator.nodes.PeerModel;
+
+
+/**
+ * Default locator model refresh service implementation.
+ */
+public class LocatorModelRefreshService extends AbstractLocatorModelService implements ILocatorModelRefreshService {
+
+ /**
+ * Constructor.
+ *
+ * @param parentModel The parent locator model instance. Must be not <code>null</code>.
+ */
+ public LocatorModelRefreshService(ILocatorModel parentModel) {
+ super(parentModel);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.services.ILocatorModelRefreshService#refresh()
+ */
+ public void refresh() {
+ assert Protocol.isDispatchThread();
+
+ // Get the parent locator model
+ ILocatorModel model = getLocatorModel();
+
+ // If the parent model is already disposed, the service will drop out immediately
+ if (model.isDisposed()) return;
+
+ // If the TCF framework isn't initialized yet, the service will drop out immediately
+ if (!Tcf.isRunning()) return;
+
+ // Get the list of old children (update node instances where possible)
+ final List<IPeerModel> oldChildren = new ArrayList<IPeerModel>(Arrays.asList(model.getPeers()));
+
+ // Get the locator service
+ ILocator locatorService = Protocol.getLocator();
+ if (locatorService != null) {
+ // Check for the locator listener to be created and registered
+ if (model instanceof LocatorModel) ((LocatorModel)model).checkLocatorListener();
+ // Get the map of peers known to the locator service.
+ Map<String, IPeer> peers = locatorService.getPeers();
+ for (String peerId : peers.keySet()) {
+ // Get the peer instance for the current peer id
+ IPeer peer = peers.get(peerId);
+ // Try to find an existing peer node first
+ IPeerModel peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(peerId);
+ // And create a new one if we cannot find it
+ if (peerNode == null) peerNode = new PeerModel(model, peer);
+ else oldChildren.remove(peerNode);
+ // Validate the peer node before adding
+ if (peerNode != null) peerNode = model.validatePeerNodeForAdd(peerNode);
+ if (peerNode != null) {
+ // Add the peer node to model
+ model.getService(ILocatorModelUpdateService.class).add(peerNode);
+ // And schedule for immediate status update
+ Runnable runnable = new ScannerRunnable(model.getScanner(), peerNode);
+ Protocol.invokeLater(runnable);
+ }
+ }
+ }
+
+ // If there are remaining old children, remove them from the model (non-recursive)
+ for (IPeerModel oldChild : oldChildren) model.getService(ILocatorModelUpdateService.class).remove(oldChild);
+
+ // Create and fire the notification event if non null
+// if (dirty) {
+// IWRNotificationEvent event = model.getFactory().newPropertyChangeEvent(model, IContainerModelNode.PROPERTY_CHANGED, null, null);
+// if (event != null) WRNotificationManager.getInstance().fireEvent(event);
+// }
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelUpdateService.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelUpdateService.java
new file mode 100644
index 000000000..0ad455429
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/services/LocatorModelUpdateService.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.services;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.IModelListener;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelUpdateService;
+
+
+/**
+ * Default locator model update service implementation.
+ */
+public class LocatorModelUpdateService extends AbstractLocatorModelService implements ILocatorModelUpdateService {
+
+ /**
+ * Constructor.
+ *
+ * @param parentModel The parent locator model instance. Must be not <code>null</code>.
+ */
+ public LocatorModelUpdateService(ILocatorModel parentModel) {
+ super(parentModel);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.services.ILocatorModelUpdateService#add(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel)
+ */
+ public void add(IPeerModel peer) {
+ assert Protocol.isDispatchThread() && peer != null;
+
+ @SuppressWarnings("unchecked")
+ Map<String, IPeerModel> peers = (Map<String, IPeerModel>)getLocatorModel().getAdapter(Map.class);
+ assert peers != null;
+ peers.put(peer.getPeer().getID(), peer);
+
+ final IModelListener[] listeners = getLocatorModel().getListener();
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IModelListener listener : listeners) {
+ listener.locatorModelChanged(getLocatorModel());
+ }
+ }
+ });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.services.ILocatorModelUpdateService#remove(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel)
+ */
+ public void remove(IPeerModel peer) {
+ assert Protocol.isDispatchThread() && peer != null;
+
+ @SuppressWarnings("unchecked")
+ Map<String, IPeerModel> peers = (Map<String, IPeerModel>)getLocatorModel().getAdapter(Map.class);
+ assert peers != null;
+ peers.remove(peer.getPeer().getID());
+
+ final IModelListener[] listeners = getLocatorModel().getListener();
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ for (IModelListener listener : listeners) {
+ listener.locatorModelChanged(getLocatorModel());
+ }
+ }
+ });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.interfaces.services.ILocatorModelUpdateService#updatePeerServices(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel, java.util.Collection, java.util.Collection)
+ */
+ public void updatePeerServices(IPeerModel peerNode, Collection<String> localServices, Collection<String> remoteServices) {
+ assert Protocol.isDispatchThread() && peerNode != null;
+
+ peerNode.setProperty(IPeerModelProperties.PROP_LOCAL_SERVICES, localServices != null ? makeString(localServices) : null);
+ peerNode.setProperty(IPeerModelProperties.PROP_REMOTE_SERVICES, remoteServices != null ? makeString(remoteServices) : null);
+ }
+
+ /**
+ * Transform the given collection into a plain string.
+ *
+ * @param collection The collection. Must be not <code>null</code>.
+ * @return The plain string.
+ */
+ protected String makeString(Collection<String> collection) {
+ assert collection != null;
+
+ String buffer = collection.toString();
+ buffer = buffer.replaceAll("\\[", "").replaceAll("\\]", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ return buffer.trim();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/utils/IPAddressUtil.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/utils/IPAddressUtil.java
new file mode 100644
index 000000000..53bfcb748
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.locator/src/org/eclipse/tm/te/tcf/locator/utils/IPAddressUtil.java
@@ -0,0 +1,403 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.locator.utils;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * The IP address utility provides a safe method to get all local IP addresses,
+ * check if any given address refers to the local host, and compare IP addresses.
+ */
+public class IPAddressUtil {
+
+ /**
+ * Constants for address types. They are sorted by "quality", i.e. the higher the total value of all flags is, the
+ * "better" or "more canonical" an address is assumed to be. Any "global" address type is better than all other
+ * addresses; among address types, the canonical name is better than the address which is better than a plain name;
+ * IPv4 is better than IPv6.
+ */
+ public final static int HOSTMAP_IPV6 = 0x01;
+ public final static int HOSTMAP_IPV4 = 0x02;
+
+ public final static int HOSTMAP_NAME = 0x04;
+ public final static int HOSTMAP_ADDR = 0x08;
+ public final static int HOSTMAP_CANONICALNAME = 0x10;
+ public final static int HOSTMAP_CANONICALADDR = 0x20;
+
+ public final static int HOSTMAP_MULTICAST = 0x40;
+ public final static int HOSTMAP_LOOPBACK = 0x80;
+ public final static int HOSTMAP_LINKLOCAL = 0x100;
+ public final static int HOSTMAP_SITELOCAL = 0x200;
+ public final static int HOSTMAP_GLOBAL = 0x400;
+
+ // shortcuts
+ public final static int HOSTMAP_ANY_UNICAST = HOSTMAP_LOOPBACK | HOSTMAP_LINKLOCAL | HOSTMAP_SITELOCAL | HOSTMAP_GLOBAL;
+
+ private final Map<String, Integer> fLocalHostAddresses = new HashMap<String, Integer>();
+ private final Set<String> fNonLocalHostAddresses = new HashSet<String>();
+ private String fCanonicalAddress = null;
+
+ IPAddressUtil() {
+ initializeHostCache();
+ }
+
+ private synchronized void initializeHostCache() {
+ // first, add the known interfaces. This is the only safe method to get
+ // the _real_ IP addresses, and get _all_ of them.
+ addLocalAddressesByInterface();
+ try {
+ // Add what Java thinks is the local host.
+ InetAddress localHostJava = InetAddress.getLocalHost();
+ // Do _not_ add the address that Java thinks the local host has,
+ // since it may be wrong! This is due to the method Java uses:
+ // it takes the host _name_ and does a reverse name lookup
+ // to get the address. This may be _wrong_ in case the DNS server
+ // points to a different (or outdated) address for the name.
+ // In reality, _only_ the addresses given by our own interfaces
+ // are correct! (As obtained by addLocalAddressesByInterface()).
+ // addLocalAddress(localHostJava);
+
+ // Add what Java thinks is the local host name.
+ // The local host name correct in the sense that it is configured
+ // locally and thus known locally. Note that in case of DNS inconsistency,
+ // DNS servers will return a _different_ address for the name than the
+ // local one, in this case the host name will be added as non-local.
+ addHostName(localHostJava.getHostName());
+ } catch (UnknownHostException e) {
+ /* no error */
+ }
+ // finally, add the "localhost" special host name since it might not be covered
+ // by the methods above (we cannot get all names for a given address, only the other way round).
+ addHostName("localhost"); //$NON-NLS-1$
+ // and initialize the "canonical hostname" cache.
+ getCanonicalAddress();
+ }
+
+ /**
+ * Iterate over local interfaces and add IP-addresses. This is the only safe method to get all local IP-addresses,
+ * since InetAddr.getAllByName() may fail to get the local IP address in case the local hostname is configured to be
+ * resolved to the loopback adapter (in this case, only the loopback adapter's address is returned). When this
+ * method has run, we know that we have all IP addresses of this machine. We can not know all the names of this
+ * machine since there s no method to query all name servers for all addresses. Therefore, new names may be added
+ * later by @see addHostName(String).
+ */
+ private synchronized void addLocalAddressesByInterface() {
+ Enumeration<NetworkInterface> interfaces = null;
+ try {
+ interfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e) {
+ /* no error, try other method */
+ }
+ while (interfaces != null && interfaces.hasMoreElements()) {
+ NetworkInterface iface = interfaces.nextElement();
+ Enumeration<InetAddress> addresses = iface.getInetAddresses();
+ while (addresses.hasMoreElements()) {
+ InetAddress addr = addresses.nextElement();
+ addLocalAddress(addr);
+ }
+ }
+ }
+
+ private synchronized void addLocalAddress(InetAddress addr) {
+ int addrtype;
+ if (addr.isLoopbackAddress()) {
+ addrtype = HOSTMAP_LOOPBACK;
+ } else if (addr.isLinkLocalAddress()) {
+ addrtype = HOSTMAP_LINKLOCAL;
+ } else if (addr.isSiteLocalAddress()) {
+ addrtype = HOSTMAP_SITELOCAL;
+ } else if (addr.isMulticastAddress()) {
+ addrtype = HOSTMAP_MULTICAST;
+ } else {
+ addrtype = HOSTMAP_GLOBAL;
+ }
+ if (addr.getAddress().length == 4) {
+ addrtype |= HOSTMAP_IPV4;
+ } else {
+ addrtype |= HOSTMAP_IPV6;
+ }
+ String addrAsString = addr.getHostAddress();
+ fLocalHostAddresses.put(addrAsString, new Integer(addrtype | HOSTMAP_ADDR));
+ if (0 == (addrtype & (HOSTMAP_LINKLOCAL | HOSTMAP_SITELOCAL | HOSTMAP_MULTICAST))) {
+ // Don't do DNS Reverse Loopkup's for non-routable addresses.
+ // They won't be known to the Name Server anyway, and they
+ // make startup _much_ slower.
+ String addrAsNameCan = addr.getCanonicalHostName().toLowerCase();
+ // query the name after the canonical name, it will re-use
+ // cached canonical name (if the name was not explicitly set)
+ String addrAsName = addr.getHostName().toLowerCase();
+ if (!addrAsNameCan.equals(addrAsString)) {
+ // We must check if we really got a name, since InetAddress.getHostName()
+ // returns the original address in case it thinks the name is spoofed!
+ if (0 == (addrtype & HOSTMAP_LOOPBACK)) {
+ // Not loopback --> found a Canonical Name.
+ fLocalHostAddresses.put(addrAsNameCan, new Integer(addrtype | HOSTMAP_NAME | HOSTMAP_CANONICALNAME));
+ // override the address as canonical-address
+ fLocalHostAddresses.put(addrAsString, new Integer(addrtype | HOSTMAP_ADDR | HOSTMAP_CANONICALADDR));
+ } else {
+ // Loopback --> add the found name as non-canonical.
+ fLocalHostAddresses.put(addrAsNameCan, new Integer(addrtype | HOSTMAP_NAME));
+ }
+ }
+ if (!addrAsName.equals(addrAsString) && !addrAsName.equals(addrAsNameCan)) {
+ // don't override the canonical name by the name.
+ fLocalHostAddresses.put(addrAsName, new Integer(addrtype | HOSTMAP_NAME));
+ }
+ }
+ }
+
+ private synchronized boolean addHostAddress(InetAddress addr, String hostName) {
+ if (addr == null) {
+ // Address for host name could not be resolved --> add to non-local-addresses
+ fNonLocalHostAddresses.add(hostName);
+ return false;
+ }
+
+ // Get the host address
+ String hostAddr = addr.getHostAddress();
+
+ // Newly discovered loopback addresses are added
+ // to the local host address list first
+ if (!fLocalHostAddresses.containsKey(hostAddr) && addr.isLoopbackAddress()) {
+ addLocalAddress(addr);
+ }
+
+ Integer entryType = fLocalHostAddresses.get(hostAddr);
+ if (entryType != null) {
+ // found a new name for a known local address ?
+ if (!fLocalHostAddresses.containsKey(hostName)) {
+ int addrtype = entryType.intValue() & (~(HOSTMAP_ADDR | HOSTMAP_CANONICALADDR));
+ fLocalHostAddresses.put(hostName, new Integer(addrtype | HOSTMAP_NAME));
+ }
+ return true;
+ }
+
+ fNonLocalHostAddresses.add(hostName);
+ fNonLocalHostAddresses.add(hostAddr);
+ return false;
+ }
+
+ /**
+ * Add a host name to internal caching tables.
+ *
+ * @param hostName String host name or address as String
+ * @return <code>true</code> if the added Host was considered "local", false otherwise.
+ */
+ public boolean addHostName(String hostName) {
+ hostName = hostName.toLowerCase();
+ try {
+ // Only take the first address: in case of multiple addresses
+ // on the remote host, some of them could be on different
+ // subnetworks and thus be non-local although they match one
+ // of our local addresses!
+ //
+ // Make sure that the name service resolving (probably time-consuming!)
+ // is outside our synchronized block.
+ InetAddress addr = InetAddress.getByName(hostName);
+ return addHostAddress(addr, hostName);
+ } catch (UnknownHostException e) {
+ /* got an illegal name --> add as non-local. */
+ return addHostAddress(null, hostName);
+ }
+ }
+
+ /**
+ * Return a list of hostnames or addresses for the local host. In case loopback addresses were asked for, these will
+ * appear first in the list. Example: String[] addresses =
+ * getLocalHostAddresses(HOSTMAP_ADDR|HOSTMAP_LOOPBACK|HOSTMAP_IPV4);
+ *
+ * @param typesToGet an integer bitmask of the types to get, uses the HOSTMAP constants declared in this class:
+ * HOSTMAP_NAME - get hostnames HOSTMAP_ADDR - get IP-addresses HOSTMAP_CANONICALNAME - get the
+ * "canonical" hostnames for each interface HOSTMAP_CANONICALADDR - get the "canonical" addresses for each
+ * interface HOSTMAP_LOOPBACK - get names/addresses for the loopback interface HOSTMAP_LINKLOCAL - get
+ * names/addresses for link-local non-routable interfaces HOSTMAP_SITELOCAL - get names/addresses for
+ * site-local non-routable interfaces HOSTMAP_MULTICAST - get multicast names/addresses HOSTMAP_GLOBAL -
+ * get names/addresses that are globally valid HOSTMAP_ANY_UNICAST - get names/addresses for any local
+ * non-unicast address HOSTMAP_IPV4 - get IPv4 names/addresses HOSTMAP_IPV6 - get IPv6 names/addresses
+ * @return String[] array of IP-addresses in String representation.
+ */
+ public synchronized String[] getLocalHostAddresses(int typesToGet) {
+ if ((typesToGet & HOSTMAP_ADDR) != 0) {
+ typesToGet |= HOSTMAP_CANONICALADDR; // plain address query includes the canonical address
+ }
+ if ((typesToGet & HOSTMAP_NAME) != 0) {
+ typesToGet |= HOSTMAP_CANONICALNAME; // plain name query includes the canonical name
+ }
+ List<String> addresses = new ArrayList<String>(fLocalHostAddresses.size());
+ Iterator<Entry<String, Integer>> it = fLocalHostAddresses.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, Integer> entry = it.next();
+ int addrtype = entry.getValue().intValue();
+ if ((addrtype & typesToGet) == addrtype) {
+ if ((addrtype & HOSTMAP_LOOPBACK) != 0) {
+ addresses.add(0, entry.getKey()); // add loopback addresses first
+ } else {
+ addresses.add(entry.getKey());
+ }
+ }
+ }
+ return addresses.toArray(new String[addresses.size()]);
+ }
+
+ /**
+ * Returns an IPv4 address to safely connect to the local host. This method works around limitations in the Java
+ * library's provisions for obtaining the local host address: - InetAddress.getByName("localhost") might be IPv6,
+ * and it might be mapped to a non-local host by the name service - InetAddress.getByName(null) might fail due to
+ * disabled loopback adapter (ifconfig lo down) - InetAddress.getLocalHost() returns non-loopback-address which is
+ * not optimal (slower than loopback, may disappear when removing a network cable or disconnecting from dial-up
+ * network connection) Therefore, the method below relies on information obtained from Enumeration
+ * NetworkInterface.getNetworkInterfaces() to know if an address is local.
+ *
+ * @return String representation of IPv4 address referring to the local host, or <code>null</code> if no address is
+ * found that allows to connect to the local host via IPv4.
+ */
+ public synchronized String getIPv4LoopbackAddress() {
+ // first, try the official IPv4 loopback address as per Internet RFC.
+ // This can fail only in case of disabled loopback adapter ("ifconfig lo down").
+ // Should perhaps be removed here in order to allow configuring preferred
+ // localhost connection from the outside.
+ if (isLocalHost("127.0.0.1")) { //$NON-NLS-1$
+ return "127.0.0.1"; //$NON-NLS-1$
+ }
+ // next, check if "localhost" is configured as an IPv4 address:
+ // if yes, it can be used directly. This allows to configure
+ // the preferred method for local host connections from the outside.
+ Integer key = fLocalHostAddresses.get("localhost"); //$NON-NLS-1$
+ if (key != null && (key.intValue() & HOSTMAP_IPV4) != 0) { return "localhost"; //$NON-NLS-1$
+ }
+ // finally ("localhost" mis-configured), obtain an address from NetworkInterfaces.
+ // loopback addresses are sorted first, so they are preferred
+ int typemask = HOSTMAP_ADDR | HOSTMAP_IPV4 | HOSTMAP_ANY_UNICAST;
+ String[] candidates = getLocalHostAddresses(typemask);
+ if (candidates.length == 0) {
+ // re-initialize the cache, perhaps some interfaces were brought up
+ // in the meantime (e.g. hot-plug network cards)
+ addLocalAddressesByInterface();
+ candidates = getLocalHostAddresses(typemask);
+ }
+ return candidates.length > 0 ? candidates[0] : null;
+ }
+
+ /**
+ * Returns the canonical name or address of this host. A "best effort" is made to return the address that is assumed
+ * to be "most canonical". A global IP address is considered better than a host name, since name service
+ * configuration might not be global.
+ *
+ * @return String IP address of the local host as it should be reachable from the outside.
+ */
+ public synchronized String getCanonicalAddress() {
+ if (fCanonicalAddress == null) {
+ Iterator<Entry<String, Integer>> it = fLocalHostAddresses.entrySet().iterator();
+ String bestAddress = null;
+ int bestAddrType = 0;
+ while (it.hasNext()) {
+ Entry<String, Integer> curEntry = it.next();
+ int curAddrType = curEntry.getValue().intValue();
+ if (curAddrType > bestAddrType) {
+ bestAddress = curEntry.getKey();
+ bestAddrType = curAddrType;
+ }
+ }
+ // fCanonicalAddress = InetAddress.getByName(bestAddress);
+ fCanonicalAddress = bestAddress;
+ }
+ return fCanonicalAddress;
+ }
+
+ /**
+ * Returns a list of host names that are considered "most canonical" on this host. The names are guaranteed to refer
+ * to global IP addresses of this machine. The list may be empty if no proper name is configured.
+ *
+ * @return String[] host names, may be empty
+ */
+ public synchronized String[] getCanonicalHostNames() {
+ int typeMask = IPAddressUtil.HOSTMAP_CANONICALNAME | IPAddressUtil.HOSTMAP_GLOBAL | IPAddressUtil.HOSTMAP_IPV4;
+ String canonicalNames[] = IPAddressUtil.getInstance().getLocalHostAddresses(typeMask);
+ if (canonicalNames.length == 0) {
+ typeMask |= IPAddressUtil.HOSTMAP_NAME;
+ canonicalNames = IPAddressUtil.getInstance().getLocalHostAddresses(typeMask);
+ }
+ return canonicalNames;
+ }
+
+ /**
+ * Find out if the given host name is the local host.
+ *
+ * @param host String hostname or IP address
+ * @return <code>true</code> if the given host refers to the local host.
+ */
+ public boolean isLocalHost(String host) {
+ if (host == null) { return false; }
+ String hostLower = host.toLowerCase();
+ // Don't trim, perhaps it is possible to have addresses ended by space
+ // hostLower = hostLower.trim();
+ synchronized (this) {
+ if (fLocalHostAddresses.containsKey(hostLower)) {
+ return true;
+ } else if (fNonLocalHostAddresses.contains(hostLower)) { return false; }
+ }
+ // Make sure that the name service lookup (probably time consuming!)
+ // is outside the synchronized block.
+ return addHostName(hostLower);
+ }
+
+ /**
+ * Find out if two IP Addresses refer to the same host.
+ *
+ * @param h1 host name or IP address
+ * @param h2 host name or IP address
+ * @return
+ */
+ public boolean isSameHost(String h1, String h2) {
+ if (h1 == null) {
+ return (h2 == null);
+ } else if (h2 == null) { return false; }
+ h1 = h1.trim();
+ h2 = h2.trim();
+ if (h1.equalsIgnoreCase(h2)) { return true; }
+ // The local host can be referred to by several methods...
+ if (isLocalHost(h1) && isLocalHost(h2)) { return true; }
+ // Compare IP-addresses? How to know if two hosts are the same?
+ // Only the first IP-Address we get should be checked. But what if
+ // h1 and h2 are different IP-Addresses referring to the same host?
+ // The check would be complex and probably slow since name service
+ // must be invoked. So we do not do it for now.
+ return false;
+ }
+
+ // Initialize-On-Demand Holder Class idiom:
+ // Lazy initialization and thread-safe single instance.
+ // See http://www-106.ibm.com/developerworks/java/library/j-jtp03304/
+ private static class LazyHolder {
+ public static IPAddressUtil instance = new IPAddressUtil();
+ }
+
+ /**
+ * Return the singleton instance.
+ */
+ public static IPAddressUtil getInstance() {
+ // LazyRegistryHolder class will be loaded in thread-safe manner
+ // the first time it is used.
+ return LazyHolder.instance;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.classpath b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.project b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.project
new file mode 100644
index 000000000..0a613f685
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.tcf.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..39179c161
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Mon Nov 29 11:56:48 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..04b46de06
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.tcf.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.tcf.ui.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.ui;bundle-version="3.6.2",
+ org.eclipse.ui.forms;bundle-version="3.5.2",
+ org.eclipse.ui.navigator;bundle-version="3.5.0",
+ org.eclipse.tm.tcf.core;bundle-version="0.3.0",
+ org.eclipse.tm.te.ui;bundle-version="1.0.0",
+ org.eclipse.tm.te.ui.views;bundle-version="1.0.0",
+ org.eclipse.tm.te.tcf.core;bundle-version="1.0.0",
+ org.eclipse.tm.te.tcf.locator;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.tcf.ui.tables;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/build.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/build.properties
new file mode 100644
index 000000000..d24082bdb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml,\
+ icons/
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/dtool16/newconnection_wiz.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/dtool16/newconnection_wiz.gif
new file mode 100644
index 000000000..5d9eae9e5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/dtool16/newconnection_wiz.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/etool16/newconnection_wiz.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/etool16/newconnection_wiz.gif
new file mode 100644
index 000000000..9f2b4acc7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/etool16/newconnection_wiz.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/rootNode_obj.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/rootNode_obj.gif
new file mode 100644
index 000000000..f1bf387e1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/rootNode_obj.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/target.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/target.gif
new file mode 100644
index 000000000..e9df7b871
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/obj16/target.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/gold_ovr.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/gold_ovr.gif
new file mode 100644
index 000000000..a05073c2f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/gold_ovr.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/green_ovr.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/green_ovr.gif
new file mode 100644
index 000000000..35ed218ad
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/green_ovr.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/grey_ovr.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/grey_ovr.gif
new file mode 100644
index 000000000..3f5fb9f6f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/grey_ovr.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/redX_ovr.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/redX_ovr.gif
new file mode 100644
index 000000000..8fa687bb2
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/redX_ovr.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/red_ovr.gif b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/red_ovr.gif
new file mode 100644
index 000000000..ea5aaa545
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/icons/ovr16/red_ovr.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.properties
new file mode 100644
index 000000000..910ffda8c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.properties
@@ -0,0 +1,27 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer, TCF UI Plug-in
+providerName = Eclipse.org
+
+# ***** Editor Pages *****
+
+NodePropertiesEditorPage.name=General
+
+# ***** Command Contributions *****
+TcfDataSource.command.category.name=Target Explorer Commands (TCF)
+
+TcfDataSource.command.refresh.name=Refresh Command
+TcfDataSource.command.refresh.label=Re&fresh
+TcfDataSource.command.refresh.tooltip=Refresh
+
+TcfDataSource.command.addPeer.name=Add New Peer Command
+TcfDataSource.command.addPeer.label=&New Peer...
+TcfDataSource.command.addPeer.tooltip=Adds a new peer to the discovery view.
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.xml
new file mode 100644
index 000000000..aee18917d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/plugin.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- Common navigator contributions -->
+ <extension point="org.eclipse.ui.navigator.viewer">
+ <viewerContentBinding viewerId="org.eclipse.tm.te.ui.views.TargetExplorer">
+ <includes>
+ <contentExtension
+ isRoot="true"
+ pattern="org.eclipse.tm.te.datasource.tcf"/>
+ </includes>
+ </viewerContentBinding>
+ </extension>
+
+ <extension point="org.eclipse.ui.navigator.navigatorContent">
+ <navigatorContent
+ activeByDefault="true"
+ contentProvider="org.eclipse.tm.te.tcf.ui.internal.navigator.ContentProviderDelegate"
+ icon="icons/obj16/rootNode_obj.gif"
+ id="org.eclipse.tm.te.datasource.tcf"
+ labelProvider="org.eclipse.tm.te.tcf.ui.internal.navigator.LabelProvider"
+ name="Dynamic Target Discovery (TCF)"
+ priority="normal">
+ <triggerPoints>
+ <instanceof value="org.eclipse.tm.te.ui.views.interfaces.IRoot"/>
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel"/>
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ </triggerPoints>
+ <commonSorter
+ class="org.eclipse.tm.te.tcf.ui.internal.navigator.Sorter"
+ id="org.eclipse.tm.te.tcf.ui.navigator.sorter"/>
+ </navigatorContent>
+ </extension>
+
+<!-- Target Explorer Details Editor page contributions -->
+ <extension point="org.eclipse.tm.te.ui.views.editorPages">
+ <editorPage
+ class="org.eclipse.tm.te.tcf.ui.internal.editor.pages.NodePropertiesEditorPage"
+ name="%NodePropertiesEditorPage.name"
+ id="org.eclipse.tm.te.tcf.ui.NodePropertiesEditorPage">
+ </editorPage>
+ </extension>
+
+<!-- Target Explorer Details Editor page binding contributions -->
+ <extension point="org.eclipse.tm.te.ui.views.editorPageBindings">
+ <editorPageBinding
+ id="org.eclipse.tm.te.tcf.ui.binding.NodePropertiesEditorPage"
+ pageId="org.eclipse.tm.te.tcf.ui.NodePropertiesEditorPage"
+ insertBefore="first">
+ <enablement>
+ <with variable="activeEditorInput">
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ </with>
+ </enablement>
+ </editorPageBinding>
+ </extension>
+
+<!-- Target Explorer menu contributions -->
+ <extension point="org.eclipse.ui.menus">
+ <menuContribution locationURI="popup:org.eclipse.tm.te.ui.views.TargetExplorer#Popup?after=group.new">
+ <command
+ commandId="org.eclipse.tm.te.tcf.ui.command.addPeer"
+ disabledIcon="icons/dtool16/newconnection_wiz.gif"
+ helpContextId="org.eclipse.tm.te.tcf.ui.command_AddPeer"
+ icon="icons/etool16/newconnection_wiz.gif"
+ id="org.eclipse.tm.te.tcf.ui.commands.addPeer"
+ label="%TcfDataSource.command.addPeer.label"
+ style="push"
+ tooltip="%TcfDataSource.command.addPeer.tooltip">
+ <visibleWhen checkEnabled="false">
+ <with variable="selection">
+ <count value="1"/>
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+
+ <menuContribution locationURI="popup:org.eclipse.tm.te.ui.views.TargetExplorer#Popup?after=group.refresh">
+ <command
+ commandId="org.eclipse.tm.te.tcf.ui.command.refresh"
+ disabledIcon="platform:/plugin/org.eclipse.ui.ide/icons/full/dlcl16/refresh_nav.gif"
+ helpContextId="org.eclipse.tm.te.tcf.ui.command_Refresh"
+ icon="platform:/plugin/org.eclipse.ui.ide/icons/full/elcl16/refresh_nav.gif"
+ id="org.eclipse.tm.te.tcf.ui.commands.refresh"
+ label="%TcfDataSource.command.refresh.label"
+ style="push"
+ tooltip="%TcfDataSource.command.refresh.tooltip">
+ <visibleWhen checkEnabled="false">
+ <with variable="selection">
+ <count value="1"/>
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator name="operationsGroupMarker" visible="true"/>
+ </menuContribution>
+ </extension>
+
+<!-- TCF data source command contributions -->
+ <extension point="org.eclipse.ui.commands">
+ <category
+ id="org.eclipse.tm.te.tcf.ui.commands.category"
+ name="%TcfDataSource.command.category.name">
+ </category>
+ <command
+ categoryId="org.eclipse.tm.te.tcf.ui.commands.category"
+ helpContextId="org.eclipse.tm.te.tcf.ui.command_Refresh"
+ id="org.eclipse.tm.te.tcf.ui.command.refresh"
+ name="%TcfDataSource.command.refresh.name">
+ </command>
+ <command
+ categoryId="org.eclipse.tm.te.tcf.ui.commands.category"
+ helpContextId="org.eclipse.tm.te.tcf.ui.command_AddPeer"
+ id="org.eclipse.tm.te.tcf.ui.command.addPeer"
+ name="%TcfDataSource.command.addPeer.name">
+ </command>
+ </extension>
+
+<!-- TCF data source handler contributions -->
+ <extension point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.tm.te.tcf.ui.internal.handler.RefreshCommandHandler"
+ commandId="org.eclipse.tm.te.tcf.ui.command.refresh">
+ </handler>
+
+ <handler
+ class="org.eclipse.tm.te.tcf.ui.internal.handler.AddPeerCommandHandler"
+ commandId="org.eclipse.tm.te.tcf.ui.command.addPeer">
+ </handler>
+ </extension>
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/activator/UIPlugin.java
new file mode 100644
index 000000000..751715329
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/activator/UIPlugin.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.activator;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.te.tcf.ui.internal.registries.InternalImageRegistry;
+import org.eclipse.tm.te.ui.images.AbstractImageDescriptor;
+import org.eclipse.tm.te.ui.images.AbstractImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+ // The shared instance
+ private static UIPlugin plugin;
+
+ /**
+ * Constructor.
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry registry) {
+ if (registry instanceof InternalImageRegistry) {
+ ((InternalImageRegistry)registry).initialize();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#createImageRegistry()
+ */
+ @Override
+ protected ImageRegistry createImageRegistry() {
+ return new InternalImageRegistry(this);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>Image</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getImage(String key) {
+ return getDefault().getImageRegistry().get(key);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>ImageDescriptor</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>ImageDescriptor</code> object instance or <code>null</code>.
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ return getDefault().getImageRegistry().getDescriptor(key);
+ }
+
+ /**
+ * Loads the image given by the specified image descriptor from the image
+ * registry. If the image has been loaded ones before already, the cached
+ * <code>Image</code> object instance is returned. Otherwise, the <code>
+ * Image</code> object instance will be created and cached before returned.
+ *
+ * @param descriptor The image descriptor.
+ * @return The corresponding <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getSharedImage(AbstractImageDescriptor descriptor) {
+ return ((AbstractImageRegistry)getDefault().getImageRegistry()).getSharedImage(descriptor);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/dialogs/AddPeerDialog.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/dialogs/AddPeerDialog.java
new file mode 100644
index 000000000..ab8446780
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/dialogs/AddPeerDialog.java
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.dialogs;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.te.tcf.ui.internal.help.IContextHelpIds;
+import org.eclipse.tm.te.tcf.ui.internal.nls.Messages;
+import org.eclipse.tm.te.ui.dialogs.CustomTrayDialog;
+
+
+/**
+ * Target Explorer: Add peer dialog implementation.
+ */
+public class AddPeerDialog extends CustomTrayDialog {
+ private Combo fTransportTypeControl;
+ private Text fAddressControl;
+ private Text fPortControl;
+ private Text fPeerIdControl;
+ private Text fPeerNameControl;
+
+ private Map<String, String> fPeerAttributes = null;
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent shell used to view the dialog.
+ */
+ public AddPeerDialog(Shell parent) {
+ this(parent, IContextHelpIds.ADD_PEER_DIALOG);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent shell used to view the dialog.
+ * @param contextHelpId The dialog context help id or <code>null</code>.
+ */
+ public AddPeerDialog(Shell parent, String contextHelpId) {
+ super(parent, contextHelpId);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.target.ui.dialogs.WRUnifiedTitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+
+ configureTitles();
+
+ Composite panel = new Composite(composite, SWT.NONE);
+ panel.setLayout(new GridLayout(2, false));
+ panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // Add the controls
+ Label label = new Label(panel, SWT.NONE);
+ label.setText(Messages.TransportTypeControl_label);
+
+ fTransportTypeControl = new Combo(panel, SWT.READ_ONLY);
+ fTransportTypeControl.setItems(new String[] { "TCP" }); //$NON-NLS-1$
+ fTransportTypeControl.select(0);
+ fTransportTypeControl.setEnabled(false);
+ fTransportTypeControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ label = new Label(panel, SWT.NONE);
+ label.setText(Messages.AgentHostControl_label);
+
+ fAddressControl = new Text(panel, SWT.SINGLE | SWT.BORDER);
+ fAddressControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fAddressControl.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updatePeerId();
+ }
+ });
+
+ label = new Label(panel, SWT.NONE);
+ label.setText(Messages.AgentPortControl_label);
+
+ fPortControl = new Text(panel, SWT.SINGLE | SWT.BORDER);
+ fPortControl.setText("1534"); //$NON-NLS-1$
+ fPortControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fPortControl.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updatePeerId();
+ }
+ });
+
+ label = new Label(panel, SWT.NONE);
+ label.setText(Messages.PeerIdControl_label);
+
+ fPeerIdControl = new Text(panel, SWT.SINGLE | SWT.BORDER);
+ fPeerIdControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ label = new Label(panel, SWT.NONE);
+ label.setText(Messages.PeerNameControl_label);
+
+ fPeerNameControl = new Text(panel, SWT.SINGLE | SWT.BORDER);
+ fPeerNameControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Setup the control content
+ setupContent();
+
+ // Adjust the font
+ applyDialogFont(composite);
+
+ return composite;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createButtonBar(Composite parent) {
+ Control control = super.createButtonBar(parent);
+ validateDialog();
+ return control;
+ }
+
+ /**
+ * Configure the dialog title and the title area content. The method
+ * is called from {@link #createDialogArea(Composite)}.
+ */
+ protected void configureTitles() {
+ setDialogTitle(Messages.AddPeerDialog_title);
+ }
+
+ /**
+ * Setup the control content.
+ */
+ protected void setupContent() {
+ restoreWidgetValues();
+ updatePeerId();
+ }
+
+ /**
+ * Update peer id control.
+ */
+ protected void updatePeerId() {
+ String address = fAddressControl.getText();
+ String port = fPortControl.getText();
+ String type = fTransportTypeControl.getText();
+
+ if (!"".equals(address) && !"".equals(port)) { //$NON-NLS-1$ //$NON-NLS-2$
+ fPeerIdControl.setText(type + ":" //$NON-NLS-1$
+ + address + ":" //$NON-NLS-1$
+ + port);
+ } else {
+ fPeerIdControl.setText(""); //$NON-NLS-1$
+ }
+
+ validateDialog();
+ }
+
+ /**
+ * Validates the dialog.
+ */
+ protected void validateDialog() {
+ boolean valid = true;
+
+ if ("".equals(fAddressControl.getText()) || "".equals(fPortControl)) { //$NON-NLS-1$ //$NON-NLS-2$
+ valid = false;
+ }
+
+ if (getButton(IDialogConstants.OK_ID) != null)
+ getButton(IDialogConstants.OK_ID).setEnabled(valid);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
+ */
+ @Override
+ protected void cancelPressed() {
+ // Dispose the peer attributes
+ fPeerAttributes = null;
+
+ super.cancelPressed();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.target.ui.dialogs.WRUnifiedTitleAreaDialog#okPressed()
+ */
+ @Override
+ protected void okPressed() {
+ saveWidgetValues();
+
+ // Create a new peer attributes map
+ fPeerAttributes = new HashMap<String, String>();
+ // Update with the current control content
+ updatePeerAttributes(fPeerAttributes);
+
+ super.okPressed();
+ }
+
+ /**
+ * Updates the given attributes map with the current control content.
+ */
+ protected void updatePeerAttributes(Map<String, String> peerAttributes) {
+ assert peerAttributes != null;
+
+ peerAttributes.put(IPeer.ATTR_IP_HOST, fAddressControl.getText());
+ peerAttributes.put(IPeer.ATTR_IP_PORT, fPortControl.getText());
+ peerAttributes.put(IPeer.ATTR_ID, fPeerIdControl.getText());
+ peerAttributes.put(IPeer.ATTR_NAME, fPeerNameControl.getText());
+ peerAttributes.put(IPeer.ATTR_TRANSPORT_NAME, fTransportTypeControl.getText());
+ }
+
+ /**
+ * Returns the peer attributes.
+ *
+ * @return The peer attributes or <code>null</code> if canceled.
+ */
+ public final Map<String, String> getPeerAttributes() {
+ return fPeerAttributes;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.target.ui.dialogs.WRUnifiedTitleAreaDialog#saveWidgetValues()
+ */
+ protected void saveWidgetValues() {
+ IDialogSettings settings = getDialogSettings();
+ if (settings != null) {
+ // The transport type control is not saved
+ settings.put(IPeer.ATTR_IP_HOST, fAddressControl.getText());
+ settings.put(IPeer.ATTR_IP_PORT, fPortControl.getText());
+ settings.put(IPeer.ATTR_ID, fPeerIdControl.getText());
+ settings.put(IPeer.ATTR_NAME, fPeerNameControl.getText());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.target.ui.dialogs.WRUnifiedTitleAreaDialog#restoreWidgetValues()
+ */
+ protected void restoreWidgetValues() {
+ IDialogSettings settings = getDialogSettings();
+ if (settings != null) {
+ // The transport type control is not restored
+ if (settings.get(IPeer.ATTR_IP_HOST) != null) fAddressControl.setText(settings.get(IPeer.ATTR_IP_HOST));
+ if (settings.get(IPeer.ATTR_IP_PORT) != null) fPortControl.setText(settings.get(IPeer.ATTR_IP_PORT));
+ if (settings.get(IPeer.ATTR_ID) != null) fPeerIdControl.setText(settings.get(IPeer.ATTR_ID));
+ if (settings.get(IPeer.ATTR_NAME) != null) fPeerNameControl.setText(settings.get(IPeer.ATTR_NAME));
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/editor/pages/NodePropertiesEditorPage.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/editor/pages/NodePropertiesEditorPage.java
new file mode 100644
index 000000000..3dac76862
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/editor/pages/NodePropertiesEditorPage.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.editor.pages;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tm.te.tcf.ui.internal.help.IContextHelpIds;
+import org.eclipse.tm.te.tcf.ui.tables.NodePropertiesContentProvider;
+import org.eclipse.tm.te.tcf.ui.tables.NodePropertiesLabelProvider;
+import org.eclipse.tm.te.tcf.ui.tables.NodePropertiesViewerComparator;
+import org.eclipse.tm.te.ui.forms.CustomFormToolkit;
+import org.eclipse.tm.te.ui.nls.Messages;
+import org.eclipse.tm.te.ui.tables.properties.NodePropertiesTableControl;
+import org.eclipse.tm.te.ui.views.editor.AbstractEditorPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+
+
+/**
+ * Target Explorer: TCF node properties details editor page implementation.
+ */
+public class NodePropertiesEditorPage extends AbstractEditorPage {
+ // The references to the pages subcontrol's (needed for disposal)
+ private NodePropertiesTableControl fNodePropertiesTableControl;
+
+ // Reference to the form toolkit instance
+ private CustomFormToolkit fToolkit = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (fNodePropertiesTableControl != null) { fNodePropertiesTableControl.dispose(); fNodePropertiesTableControl = null; }
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
+ */
+ @Override
+ protected void createFormContent(IManagedForm managedForm) {
+ // Configure the managed form
+ configureManagedForm(managedForm);
+
+ // Get the form body
+ Composite body = managedForm.getForm().getBody();
+
+ // Create the toolkit instance
+ fToolkit = new CustomFormToolkit(managedForm.getToolkit());
+
+ // Do create the content of the form now
+ doCreateFormContent(body, fToolkit);
+
+ // Re-arrange the controls
+ managedForm.reflow(true);
+ }
+
+ /**
+ * Configure the managed form to be ready for usage.
+ *
+ * @param managedForm The managed form. Must be not <code>null</code>.
+ */
+ protected void configureManagedForm(IManagedForm managedForm) {
+ assert managedForm != null;
+
+ // Configure main layout
+ Composite body = managedForm.getForm().getBody();
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 2; layout.marginWidth = 0;
+ body.setLayout(layout);
+ body.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+
+ // Set context help id
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(managedForm.getForm(), IContextHelpIds.NODE_PROPERTIES_EDITOR_PAGE);
+ }
+
+ /**
+ * Do create the managed form content.
+ *
+ * @param parent The parent composite. Must be not <code>null</code>
+ * @param toolkit The {@link CustomFormToolkit} instance. Must be not <code>null</code>.
+ */
+ protected void doCreateFormContent(Composite parent, CustomFormToolkit toolkit) {
+ assert parent != null && toolkit != null;
+
+ Section section = toolkit.getFormToolkit().createSection(parent, ExpandableComposite.TITLE_BAR);
+ String title = NLS.bind(Messages.NodePropertiesTableControl_section_title, Messages.NodePropertiesTableControl_section_title_noSelection);
+ // Stretch to a length of 40 characters to make sure the title can be changed
+ // to hold and show text up to this length
+ while (title.length() < 40) {
+ title += " "; //$NON-NLS-1$
+ }
+ // Set the title to the section
+ section.setText(title);
+ section.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // Create the client area
+ Composite client = toolkit.getFormToolkit().createComposite(section);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0; layout.marginHeight = 0;
+ client.setLayout(layout);
+ section.setClient(client);
+
+ // Setup the node properties table control
+ fNodePropertiesTableControl = doCreateNodePropertiesTableControl();
+ assert fNodePropertiesTableControl != null;
+ fNodePropertiesTableControl.setupFormPanel((Composite)section.getClient(), toolkit);
+
+ // Set the initial input
+ fNodePropertiesTableControl.getViewer().setInput(getEditorInputNode());
+ }
+
+ /**
+ * Creates and returns a new node properties table control.
+ *
+ * @return The new node properties table control.
+ */
+ protected NodePropertiesTableControl doCreateNodePropertiesTableControl() {
+ return new NodePropertiesTableControl(this) {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.tables.NodePropertiesTableControl#doCreateTableViewerContentProvider(org.eclipse.jface.viewers.TableViewer)
+ */
+ @Override
+ protected IStructuredContentProvider doCreateTableViewerContentProvider(TableViewer viewer) {
+ return new NodePropertiesContentProvider(true);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.tables.properties.NodePropertiesTableControl#doCreateTableViewerLabelProvider(org.eclipse.jface.viewers.TableViewer)
+ */
+ @Override
+ protected ITableLabelProvider doCreateTableViewerLabelProvider(TableViewer viewer) {
+ return new NodePropertiesLabelProvider(viewer);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.tables.NodePropertiesTableControl#doCreateTableViewerComparator(org.eclipse.jface.viewers.TableViewer)
+ */
+ @Override
+ protected ViewerComparator doCreateTableViewerComparator(TableViewer viewer) {
+ return new NodePropertiesViewerComparator(viewer, (ITableLabelProvider)viewer.getLabelProvider());
+ }
+ };
+ }
+
+ /**
+ * Returns the associated node properties table control.
+ *
+ * @return The associated node properties table control or <code>null</code>.
+ */
+ protected final NodePropertiesTableControl getNodePropertiesTableControl() {
+ return fNodePropertiesTableControl;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/AddPeerCommandHandler.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/AddPeerCommandHandler.java
new file mode 100644
index 000000000..de0f820d9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/AddPeerCommandHandler.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.handler;
+
+import java.util.Map;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.core.interfaces.IChannelManager;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+import org.eclipse.tm.te.tcf.ui.internal.dialogs.AddPeerDialog;
+import org.eclipse.tm.te.tcf.ui.internal.model.Model;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+/**
+ * Target Explorer: Adds a new peer to the TCF locator model.
+ */
+public class AddPeerCommandHandler extends AbstractHandler {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // Get the shell
+ Shell shell = HandlerUtil.getActiveShell(event);
+ // Open the dialog
+ AddPeerDialog dialog = new AddPeerDialog(shell);
+ if (dialog.open() == Window.OK) {
+ // Get the new peer attributes
+ final Map<String, String> peerAttributes = dialog.getPeerAttributes();
+ if (peerAttributes != null) {
+ // Try to connect to the peer
+ IChannel channel = null;
+ try {
+ IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
+ IEditorPart editorPart = activePart != null ? (IEditorPart)activePart.getAdapter(IEditorPart.class) : null;
+ final ISelectionProvider selectionProvider = editorPart != null ? editorPart.getEditorSite().getSelectionProvider() : null;
+
+ Tcf.getChannelManager().openChannel(peerAttributes, new IChannelManager.DoneOpenChannel() {
+ public void doneOpenChannel(Throwable error, IChannel channel) {
+ if (error == null) {
+ IPeer peer = channel.getRemotePeer();
+ if (selectionProvider != null && peer != null) {
+ // OK, we have the peer instance now, for the rest,
+ // we need the locator model
+ ILocatorModel model = Model.getModel();
+ if (model != null) {
+ final IPeerModel peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(peer.getID());
+ if (peerNode != null) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ selectionProvider.setSelection(new StructuredSelection(peerNode));
+ }
+ });
+ }
+ }
+ }
+ }
+
+ channel.close();
+ }
+ });
+ } catch (Exception e) {
+ } finally {
+ // Close the channel again
+ if (channel != null) {
+ final IChannel finChannel = channel;
+ if (Protocol.isDispatchThread()) {
+ finChannel.close();
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ finChannel.close();
+ }
+ });
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/RefreshCommandHandler.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/RefreshCommandHandler.java
new file mode 100644
index 000000000..5c6e804a7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/handler/RefreshCommandHandler.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.handler;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelRefreshService;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+/**
+ * Target Explorer: TCF refresh command handler.
+ */
+public class RefreshCommandHandler extends AbstractHandler {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ List<ILocatorModel> refreshedModels = new ArrayList<ILocatorModel>();
+ Iterator<?> iterator = ((IStructuredSelection)selection).iterator();
+ while (iterator.hasNext()) {
+ Object element = iterator.next();
+ if (element instanceof IAdaptable) {
+ final ILocatorModel model = (ILocatorModel)((IAdaptable)element).getAdapter(ILocatorModel.class);
+ if (model != null && !refreshedModels.contains(model)) {
+ if (Protocol.isDispatchThread()) {
+ model.getService(ILocatorModelRefreshService.class).refresh();
+ } else {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ model.getService(ILocatorModelRefreshService.class).refresh();
+ }
+ });
+ }
+ refreshedModels.add(model);
+ }
+ }
+ }
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/help/IContextHelpIds.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/help/IContextHelpIds.java
new file mode 100644
index 000000000..6497cb459
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/help/IContextHelpIds.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.help;
+
+import org.eclipse.tm.te.tcf.ui.activator.UIPlugin;
+
+/**
+ * Target Explorer: Context help id definitions.
+ */
+public interface IContextHelpIds {
+
+ /**
+ * TCF data source UI plug-in common context help id prefix.
+ */
+ public final static String PREFIX = UIPlugin.getUniqueIdentifier() + "."; //$NON-NLS-1$
+
+ /**
+ * Add new peer dialog.
+ */
+ public final static String ADD_PEER_DIALOG = PREFIX + "AddPeerDialog"; //$NON-NLS-1$
+
+ /**
+ * Target Explorer details editor page: Node properties
+ */
+ public final static String NODE_PROPERTIES_EDITOR_PAGE = PREFIX + "NodePropertiesEditorPage"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/model/Model.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/model/Model.java
new file mode 100644
index 000000000..2171b623e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/model/Model.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.model;
+
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.nodes.LocatorModel;
+import org.eclipse.tm.te.tcf.ui.internal.navigator.ModelListener;
+
+
+/**
+ * Target Explorer: Helper class to instantiate and initialize the TCF locator model.
+ */
+public final class Model {
+ // Reference to the locator model
+ /* default */ static ILocatorModel fLocatorModel;
+
+ /**
+ * Returns the locator model. If not yet initialized,
+ * initialize the locator model.
+ *
+ * @return The locator model.
+ */
+ public static ILocatorModel getModel() {
+ // Access to the locator model must happen in the TCF dispatch thread
+ if (fLocatorModel == null) {
+ if (Protocol.isDispatchThread()) {
+ initialize();
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ initialize();
+ }
+ });
+ }
+ }
+ return fLocatorModel;
+ }
+
+ /**
+ * Initialize the root node. Must be called within the TCF dispatch thread.
+ */
+ protected static void initialize() {
+ assert Protocol.isDispatchThread();
+
+ fLocatorModel = new LocatorModel();
+ // Register the model listener
+ fLocatorModel.addListener(new ModelListener(fLocatorModel));
+ // Start the scanner
+ fLocatorModel.startScanner(5000, 120000);
+ }
+
+ /**
+ * Dispose the root node.
+ */
+ public static void dispose() {
+ if (fLocatorModel == null) return;
+
+ // Access to the locator model must happen in the TCF dispatch thread
+ if (Protocol.isDispatchThread()) {
+ fLocatorModel.dispose();
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ fLocatorModel.dispose();
+ }
+ });
+ }
+
+ fLocatorModel = null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ContentProviderDelegate.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ContentProviderDelegate.java
new file mode 100644
index 000000000..ac3e4d11e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ContentProviderDelegate.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.navigator;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.core.Tcf;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.services.ILocatorModelRefreshService;
+import org.eclipse.tm.te.tcf.ui.internal.model.Model;
+import org.eclipse.tm.te.ui.views.interfaces.IRoot;
+
+
+/**
+ * Target Explorer: Content provider delegate implementation.
+ */
+public class ContentProviderDelegate implements ITreeContentProvider {
+ private final static Object[] NO_ELEMENTS = new Object[0];
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ Object[] children = NO_ELEMENTS;
+
+ // If the parent element is null or IRoot, than we assume
+ // the locator model as parent element.
+ if (parentElement == null || parentElement instanceof IRoot) {
+ parentElement = Model.getModel();
+ }
+ // If it is the locator model, get the peers
+ if (parentElement instanceof ILocatorModel) {
+ children = ((ILocatorModel)parentElement).getPeers();
+ }
+
+ return children;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ // If it is a peer model node, return the parent locator model
+ if (element instanceof IPeerModel) {
+ return ((IPeerModel)element).getModel();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ boolean hasChildren = false;
+
+ if (element instanceof ILocatorModel) {
+ hasChildren = ((ILocatorModel)element).getPeers().length > 0;
+ }
+
+ return hasChildren;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ Model.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof IRoot) {
+ final ILocatorModel model = Model.getModel();
+ // If the TCF framework is not running yet, run the refresh asynchronous
+ if (Tcf.isRunning() && Protocol.isDispatchThread()) {
+ model.getService(ILocatorModelRefreshService.class).refresh();
+ } else {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ model.getService(ILocatorModelRefreshService.class).refresh();
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProvider.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProvider.java
new file mode 100644
index 000000000..6dea9bcad
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProvider.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.navigator;
+
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+
+/**
+ * Target Explorer: Decorating label provider.
+ */
+public class LabelProvider extends DecoratingLabelProvider {
+ private final static LabelProviderDelegate DELEGATE = new LabelProviderDelegate();
+
+ /**
+ * Constructor.
+ */
+ public LabelProvider() {
+ super(DELEGATE, DELEGATE);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProviderDelegate.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProviderDelegate.java
new file mode 100644
index 000000000..2632f87b4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/LabelProviderDelegate.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.navigator;
+
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.ui.activator.UIPlugin;
+import org.eclipse.tm.te.tcf.ui.internal.navigator.images.PeerImageDescriptor;
+import org.eclipse.tm.te.tcf.ui.internal.registries.InternalImageRegistry;
+import org.eclipse.tm.te.ui.images.AbstractImageDescriptor;
+
+
+/**
+ * Target Explorer: Label provider delegate implementation.
+ */
+public class LabelProviderDelegate extends LabelProvider implements ILabelDecorator {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof IPeerModel) {
+ String label = null;
+
+ final IPeer peer = ((IPeerModel)element).getPeer();
+ final String[] peerName = new String[1];
+ if (Protocol.isDispatchThread()) {
+ peerName[0] = peer.getName();
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ peerName[0] = peer.getName();
+ }
+ });
+ }
+ label = peerName[0];
+
+ if (label != null && !"".equals(label.trim())) { //$NON-NLS-1$
+ return label;
+ }
+ }
+
+ return ""; //$NON-NLS-1$
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof IPeerModel) {
+ return UIPlugin.getImage(InternalImageRegistry.OBJ_Target);
+ }
+
+ return super.getImage(element);
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelDecorator#decorateImage(org.eclipse.swt.graphics.Image, java.lang.Object)
+ */
+ public Image decorateImage(Image image, Object element) {
+ Image decoratedImage = null;
+
+ if (image != null && element instanceof IPeerModel) {
+ AbstractImageDescriptor descriptor = new PeerImageDescriptor(UIPlugin.getDefault().getImageRegistry(),
+ image,
+ (IPeerModel)element);
+ decoratedImage = UIPlugin.getSharedImage(descriptor);
+ }
+
+ return decoratedImage;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelDecorator#decorateText(java.lang.String, java.lang.Object)
+ */
+ public String decorateText(String text, Object element) {
+ if (element instanceof IPeerModel) {
+ String label = text;
+
+ final IPeer peer = ((IPeerModel)element).getPeer();
+ final StringBuilder builder = new StringBuilder(label != null && !"".equals(label.trim()) ? label.trim() : "<noname>"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (Protocol.isDispatchThread()) {
+ doDecorateText(builder, peer);
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ doDecorateText(builder, peer);
+ }
+ });
+ }
+ label = builder.toString();
+
+ if (label != null && !"".equals(label.trim()) && !"<noname>".equals(label.trim())) { //$NON-NLS-1$ //$NON-NLS-2$
+ return label;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Decorate the text with some peer attributes.
+ * <p>
+ * <b>Note:</b> Must be called with the TCF event dispatch thread.
+ *
+ * @param builder The string builder to decorate. Must be not <code>null</code>.
+ * @param peer The peer. Must be not <code>null</code>.
+ */
+ /* default */ void doDecorateText(StringBuilder builder, IPeer peer) {
+ assert Protocol.isDispatchThread() && builder != null && peer != null;
+
+ String osName = peer.getOSName();
+
+ if (osName != null && !"".equals(osName.trim())) { //$NON-NLS-1$
+ builder.append(" [" + osName.trim() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ String ip = peer.getAttributes().get(IPeer.ATTR_IP_HOST);
+ String port = peer.getAttributes().get(IPeer.ATTR_IP_PORT);
+
+ if (ip != null && !"".equals(ip.trim())) { //$NON-NLS-1$
+ builder.append(" @ "); //$NON-NLS-1$
+ builder.append(ip.trim());
+
+ if (port != null && !"".equals(port.trim()) && !"1534".equals(port.trim())) { //$NON-NLS-1$ //$NON-NLS-2$
+ builder.append(":"); //$NON-NLS-1$
+ builder.append(port.trim());
+ }
+ }
+
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ModelListener.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ModelListener.java
new file mode 100644
index 000000000..feba68e58
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/ModelListener.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.navigator;
+
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.listener.ModelAdapter;
+import org.eclipse.tm.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+
+
+/**
+ * Target Exploer: TCF locator model listener implementation.
+ */
+public class ModelListener extends ModelAdapter {
+ private final ILocatorModel fParentModel;
+
+ /**
+ * Constructor.
+ *
+ */
+ public ModelListener(ILocatorModel parent) {
+ assert parent != null;
+ fParentModel = parent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.listener.ModelAdapter#locatorModelChanged(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel)
+ */
+ @Override
+ public void locatorModelChanged(final ILocatorModel model) {
+ if (fParentModel.equals(model)) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ CommonViewer viewer = getViewer();
+ if (viewer != null) viewer.refresh();
+ }
+ });
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.locator.core.listener.ModelAdapter#peerModelChanged(org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.ILocatorModel, org.eclipse.tm.te.tcf.locator.core.interfaces.nodes.IPeerModel)
+ */
+ @Override
+ public void peerModelChanged(final ILocatorModel model, final IPeerModel peer) {
+ if (fParentModel.equals(model)) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ CommonViewer viewer = getViewer();
+ if (viewer != null) viewer.refresh(peer);
+ }
+ });
+ }
+ }
+
+ /**
+ * Get the common viewer used by the Target Explorer view instance.
+ *
+ * @return The common viewer or <code>null</code>
+ */
+ protected CommonViewer getViewer() {
+ if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
+ && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IViewPart part = page.findView(IUIConstants.ID_EXPLORER);
+ if (part instanceof CommonNavigator) {
+ return ((CommonNavigator)part).getCommonViewer();
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/Sorter.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/Sorter.java
new file mode 100644
index 000000000..0c342c5ca
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/Sorter.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.navigator;
+
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TreePathViewerSorter;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * Target Explorer: Common sorter implementation.
+ */
+public class Sorter extends TreePathViewerSorter {
+ private final ILabelProvider fLabelProvider = new LabelProviderDelegate();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) {
+ return doCompare(e1, e2, doGetSortColumnLabel(viewer), doGetSortColumnIndex(viewer) , doDetermineInverter(viewer));
+ }
+ return super.compare(viewer, e1, e2);
+ }
+
+ /**
+ * Returns the text to compare for the given node and column index.
+ *
+ * @param node The node or <code>null</code>.
+ * @param index The column index or <code>-1</code>.
+ *
+ * @return The text for the given node and column index or <code>null</code>.
+ */
+ protected String doGetText(Object node, int index) {
+ if (node != null) {
+ return fLabelProvider.getText(node);
+ }
+ return null;
+ }
+
+ /**
+ * Return the label provider associated with the specified viewer.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return The label provider or <code>null</code>.
+ */
+ protected ILabelProvider doGetLabelProvider(Viewer viewer) {
+ if (viewer instanceof ContentViewer) {
+ IBaseLabelProvider candidate = ((ContentViewer)viewer).getLabelProvider();
+ if (candidate instanceof ILabelProvider) return (ILabelProvider)candidate;
+ }
+ return null;
+ }
+
+ /**
+ * Determine if or if not the sort direction needs to be inverted.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return <code>1</code> for original sort order, or <code>-1</code> for inverted sort order.
+ */
+ protected int doDetermineInverter(Viewer viewer) {
+ int inverter = 1;
+
+ // Viewer must be of type TreeViewer and the tree must not be disposed yet
+ if (viewer instanceof TreeViewer && ((TreeViewer)viewer).getTree() != null) {
+ Tree tree = ((TreeViewer)viewer).getTree();
+ if (!tree.isDisposed() && tree.getSortDirection() == SWT.DOWN) inverter = -1;
+ }
+
+ return inverter;
+ }
+
+ /**
+ * Return the label of the sort column of the given viewer.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return The label of the sort column or an empty string.
+ */
+ protected String doGetSortColumnLabel(Viewer viewer) {
+ // Viewer must be of type TreeViewer and the tree must not be disposed yet
+ if (viewer instanceof TreeViewer && ((TreeViewer)viewer).getTree() != null && !((TreeViewer)viewer).getTree().isDisposed()) {
+ Tree tree = ((TreeViewer)viewer).getTree();
+ return tree.getSortColumn() != null ? tree.getSortColumn().getText() : ""; //$NON-NLS-1$
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Return the index of the sort column of the given viewer.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return The index of the sort column or <code>-1</code>.
+ */
+ protected int doGetSortColumnIndex(Viewer viewer) {
+ if (viewer instanceof TreeViewer && ((TreeViewer)viewer).getTree() != null && !((TreeViewer)viewer).getTree().isDisposed()) {
+ Tree tree = ((TreeViewer)viewer).getTree();
+ return tree.getSortColumn() != null ? Arrays.asList(tree.getColumns()).indexOf(tree.getSortColumn()) : -1;
+ }
+ return -1;
+ }
+
+ /**
+ * Compare the given model nodes by the given sort column and inverter.
+ *
+ * @param node1 The first node or <code>null</code>.
+ * @param node2 The second node or <code>null</code>.
+ * @param sortColumn The sort column text or <code>null</code>.
+ * @param index The sort column index or <code>-1</code>.
+ * @param inverter The inverter.
+ *
+ * @return The compare result.
+ */
+ @SuppressWarnings("unchecked")
+ protected int doCompare(Object node1, Object node2, String sortColumn, int index, int inverter) {
+ if (node1 == null && node2 == null) return 0;
+ if (node1 != null && node2 == null) return 1;
+ if (node1 == null && node2 != null) return -1;
+
+ // Get the labels
+ String text1 = doGetText(node1, index);
+ String text2 = doGetText(node2, index);
+
+ // The tree sorts not strictly alphabetical. First comes entries starting with numbers,
+ // second entries starting with uppercase and than all the rest. Additional, if a label contains
+ // uppercase characters, it is sorted in before any labels being lowercase only.
+ if (text1.length() > 0 && text2.length() > 0) {
+ // Get the first characters of both
+ char c1 = text1.charAt(0);
+ char c2 = text2.charAt(0);
+
+ if (Character.isDigit(c1) || Character.isDigit(c2)) {
+ // Check on the differences. If both are digits, the standard compare will do it
+ if (Character.isDigit(c1) && !Character.isDigit(c2)) return -1 * inverter;
+ if (!Character.isDigit(c1) && Character.isDigit(c2)) return 1 * inverter;
+ }
+
+ if (Character.isUpperCase(c1) || Character.isUpperCase(c2)) {
+ // Check on the differences. If both are uppercase characters, the standard compare will do it
+ if (Character.isUpperCase(c1) && !Character.isUpperCase(c2)) return -1 * inverter;
+ if (!Character.isUpperCase(c1) && Character.isUpperCase(c2)) return 1 * inverter;
+ }
+
+ Matcher m1 = Pattern.compile("(\\D+)(\\d+)").matcher(text1); //$NON-NLS-1$
+ Matcher m2 = Pattern.compile("(\\D+)(\\d+)").matcher(text2); //$NON-NLS-1$
+ if (m1.matches() && m2.matches()) {
+ String p11 = m1.group(1);
+ String p12 = m1.group(2);
+
+ String p21 = m2.group(1);
+ String p22 = m2.group(2);
+
+ if (p11 != null && p11.equals(p21)) {
+ // Compare the second parts as number
+ try {
+ int result = 0;
+ long l1 = Long.parseLong(p12);
+ long l2 = Long.parseLong(p22);
+
+ if (l1 > l2) result = 1;
+ if (l1 < l2) result = -1;
+
+ return result;
+ } catch (NumberFormatException e) { /* ignored on purpose */ }
+ }
+ }
+
+ if (text1.matches(".*[A-Z]+.*") || text2.matches(".*[A-Z]+.*")) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (text1.matches(".*[A-Z]+.*") && !text2.matches(".*[A-Z]+.*")) return -1 * inverter; //$NON-NLS-1$ //$NON-NLS-2$
+ if (!text1.matches(".*[A-Z]+.*") && text2.matches(".*[A-Z]+.*")) return 1 * inverter; //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Additionally, it even depends on the position of the first uppercase
+ // character if both strings contains them :-(
+ int minLength = Math.min(text1.length(), text2.length());
+ for (int i = 0; i < minLength; i++) {
+ char ch1 = text1.charAt(i);
+ char ch2 = text2.charAt(i);
+
+ if (Character.isUpperCase(ch1) && !Character.isUpperCase(ch2)) return -1 * inverter;
+ if (!Character.isUpperCase(ch1) && Character.isUpperCase(ch2)) return 1 * inverter;
+ // If both are uppercase, we break the loop and compare as usual
+ if (Character.isUpperCase(ch1) && Character.isUpperCase(ch2)) break;
+ }
+ }
+ }
+
+ // Compare the text alphabetical
+ return getComparator().compare(text1, text2) * inverter;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java
new file mode 100644
index 000000000..7ecfe435a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/navigator/images/PeerImageDescriptor.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.navigator.images;
+
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.ui.internal.registries.InternalImageRegistry;
+import org.eclipse.tm.te.ui.images.AbstractImageDescriptor;
+
+
+/**
+ * Target Explorer: Peer model node image descriptor implementation.
+ */
+public class PeerImageDescriptor extends AbstractImageDescriptor {
+ // the base image to decorate with overlays
+ private Image fBaseImage;
+ // the image size
+ private Point fImageSize;
+
+ // Flags representing the object states to decorate
+ private int fState;
+
+ /**
+ * Constructor.
+ */
+ public PeerImageDescriptor(final ImageRegistry registry, final Image baseImage, final IPeerModel node) {
+ super(registry);
+
+ fBaseImage = baseImage;
+ fImageSize = new Point(fBaseImage.getImageData().width, fBaseImage.getImageData().height);
+
+ // Determine the current object state to decorate
+ if (Protocol.isDispatchThread()) {
+ initialize(node);
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ initialize(node);
+ }
+ });
+ }
+
+ // build up the key for the image registry
+ defineKey(fBaseImage.hashCode());
+ }
+
+ /**
+ * Initialize the image descriptor from the peer model.
+ *
+ * @param node The peer model. Must be not <code>null</code>.
+ */
+ protected void initialize(IPeerModel node) {
+ assert Protocol.isDispatchThread() && node != null;
+
+ fState = node.getIntProperty(IPeerModelProperties.PROP_STATE);
+ }
+
+ protected void defineKey(int hashCode) {
+ String key = "PMID:" + //$NON-NLS-1$
+ hashCode + ":" + //$NON-NLS-1$
+ fState;
+
+ setKey(key);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int)
+ */
+ @Override
+ protected void drawCompositeImage(int width, int height) {
+ drawCentered(fBaseImage, width, height);
+
+ if (fState == IPeerModelProperties.STATE_UNKNOWN) { /* unknown */
+ drawBottomRight(InternalImageRegistry.OVERLAY_Grey);
+ }
+ else if (fState == IPeerModelProperties.STATE_REACHABLE) { /* not connected, but reachable */
+ drawBottomRight(InternalImageRegistry.OVERLAY_Gold);
+ }
+ else if (fState == IPeerModelProperties.STATE_CONNECTED) { /* connected */
+ drawBottomRight(InternalImageRegistry.OVERLAY_Green);
+ }
+ else if (fState == IPeerModelProperties.STATE_NOT_REACHABLE) { /* not connected, not reachable */
+ drawBottomRight(InternalImageRegistry.OVERLAY_Red);
+ }
+ else if (fState == IPeerModelProperties.STATE_ERROR) { /* not connected, error */
+ drawBottomRight(InternalImageRegistry.OVERLAY_RedX);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.resource.CompositeImageDescriptor#getSize()
+ */
+ @Override
+ protected Point getSize() {
+ return fImageSize;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.ide.util.ui.AbstractImageDescriptor#getBaseImage()
+ */
+ @Override
+ protected Image getBaseImage() {
+ return fBaseImage;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.java
new file mode 100644
index 000000000..e7267fb35
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.nls;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer: TCF UI Plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.tcf.ui.internal.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Returns if or if not this NLS manager contains a constant for
+ * the given externalized strings key.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise.
+ */
+ public static boolean hasString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return field != null;
+ } catch (NoSuchFieldException e) { /* ignored on purpose */ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings
+ * key or <code>null</code> if the key does not exist.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ if (field != null) {
+ return (String)field.get(null);
+ }
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+
+ return null;
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String NodePropertiesContentProvider_peerNode_sectionTitle;
+
+ public static String NodePropertiesLabelProvider_state;
+ public static String NodePropertiesLabelProvider_state__1;
+ public static String NodePropertiesLabelProvider_state_0;
+ public static String NodePropertiesLabelProvider_state_1;
+ public static String NodePropertiesLabelProvider_state_2;
+ public static String NodePropertiesLabelProvider_state_3;
+
+ public static String NodePropertiesLabelProvider_lastScannerError;
+
+ public static String NodePropertiesLabelProvider_services_local;
+ public static String NodePropertiesLabelProvider_services_remote;
+
+ public static String AddPeerDialog_title;
+
+ public static String TransportTypeControl_label;
+
+ public static String AgentHostControl_label;
+
+ public static String AgentPortControl_label;
+
+ public static String PeerIdControl_label;
+
+ public static String PeerNameControl_label;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.properties
new file mode 100644
index 000000000..94fdbfa19
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/nls/Messages.properties
@@ -0,0 +1,30 @@
+#
+# org.eclipse.tm.te.tcf.ui
+# Externalized Strings.
+#
+
+NodePropertiesContentProvider_peerNode_sectionTitle=Peer
+
+NodePropertiesLabelProvider_state=Link State
+NodePropertiesLabelProvider_state__1=Unknown
+NodePropertiesLabelProvider_state_0=Reachable
+NodePropertiesLabelProvider_state_1=Communicating
+NodePropertiesLabelProvider_state_2=Not Reachable. Connection attempt timed out.
+NodePropertiesLabelProvider_state_3=Not Reachable. Connection attempt failed.
+
+NodePropertiesLabelProvider_lastScannerError=Communication failed. Possible cause:
+
+NodePropertiesLabelProvider_services_local=Local Services
+NodePropertiesLabelProvider_services_remote=Remote Services
+
+AddPeerDialog_title=Add New Peer
+
+TransportTypeControl_label=Type:
+
+AgentHostControl_label=Host:
+
+AgentPortControl_label=Port:
+
+PeerIdControl_label=ID:
+
+PeerNameControl_label=Name:
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/registries/InternalImageRegistry.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/registries/InternalImageRegistry.java
new file mode 100644
index 000000000..c5bae59a2
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/internal/registries/InternalImageRegistry.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.internal.registries;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.tm.te.ui.images.AbstractImageRegistry;
+
+
+/**
+ * Target Explorer: TCF UI plugin image registry.
+ */
+public class InternalImageRegistry extends AbstractImageRegistry {
+ private static List<Object[]> fStore = new ArrayList<Object[]>();
+
+ // declare all keys down here
+ public static final String OBJ_Target = declareLocalImage("obj16", "target.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Overlays
+ public final static String OVERLAY_Gold = declareLocalImage("ovr16", "gold_ovr.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ public final static String OVERLAY_Green = declareLocalImage("ovr16", "green_ovr.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ public final static String OVERLAY_Grey = declareLocalImage("ovr16", "grey_ovr.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ public final static String OVERLAY_Red = declareLocalImage("ovr16", "red_ovr.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+ public final static String OVERLAY_RedX = declareLocalImage("ovr16", "redX_ovr.gif"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // external eclipse icons not reachable using ISharedImages
+
+ /**
+ * Constructor.
+ *
+ * @param plugin The plugin descriptor the image registry is created for.
+ */
+ public InternalImageRegistry(Plugin plugin) {
+ super(plugin);
+ }
+
+ /**
+ * Initialize image registry with all keys known yet.
+ */
+ public void initialize() {
+ for (Iterator<Object[]> iter = fStore.iterator(); iter.hasNext();) {
+ Object[] element = iter.next();
+ if (element.length == 3) {
+ localImage((String)element[0], (String)element[1], (String)element[2]);
+ }
+ else if (element.length > 3){
+ externalImage((String)element[0], (String)element[1], (String[])element[2], (String)element[3]);
+ }
+ }
+ }
+
+ /**
+ * Declare a locally stored image to the image registry.
+ */
+ static String declareLocalImage(String dir, String name) {
+ List<Object> registryObject = new ArrayList<Object>();
+ registryObject.add(dir);
+ registryObject.add(name);
+ String key = name + "_" + registryObject.hashCode(); //$NON-NLS-1$
+ registryObject.add(0, key);
+ fStore.add(registryObject.toArray());
+ return key;
+ }
+
+ /**
+ * Declare a externally stored image to the image registry.
+ */
+ static String declareExternalImage(String plugin, String[] dirs, String name) {
+ List<Object> registryObject = new ArrayList<Object>();
+ registryObject.add(plugin);
+ registryObject.add(dirs);
+ registryObject.add(name);
+ String key = name + "_" + registryObject.hashCode(); //$NON-NLS-1$
+ registryObject.add(0, key);
+ fStore.add(registryObject.toArray());
+ return key;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesContentProvider.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesContentProvider.java
new file mode 100644
index 000000000..ae7d5d9c6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesContentProvider.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.tables;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.ui.internal.nls.Messages;
+import org.eclipse.tm.te.ui.tables.TableNode;
+import org.eclipse.ui.forms.widgets.Section;
+
+
+/**
+ * Target Explorer: TCF node properties table content provider implementation.
+ */
+public class NodePropertiesContentProvider implements IStructuredContentProvider {
+
+ /**
+ * The list of properties to filter out and not to show within the table.
+ */
+ 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,
+ "hasTabularProperties" //$NON-NLS-1$
+ };
+
+ // Flag to control if the content provide may update the parent section title
+ private final boolean fUpdateParentSectionTitle;
+
+ /**
+ * Constructor.
+ *
+ * @param updateParentSectionTitle Specify <code>true</code> to allow the content provider to update
+ * the parent section title, <code>false</code> if no title update is desired.
+ */
+ public NodePropertiesContentProvider(boolean updateParentSectionTitle) {
+ fUpdateParentSectionTitle = updateParentSectionTitle;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(final Object inputElement) {
+ List<TableNode> nodes = new ArrayList<TableNode>();
+
+ if (inputElement instanceof IPeerModel) {
+ TableNode lastErrorNode = null;
+
+ // Get all custom properties of the node
+ final Map<String, Object> properties = new HashMap<String, Object>();
+ // And get all native properties of the peer
+ if (Protocol.isDispatchThread()) {
+ properties.putAll(((IPeerModel)inputElement).getProperties());
+ properties.putAll(((IPeerModel)inputElement).getPeer().getAttributes());
+ } else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ properties.putAll(((IPeerModel)inputElement).getProperties());
+ properties.putAll(((IPeerModel)inputElement).getPeer().getAttributes());
+ }
+ });
+ }
+
+ 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$
+ // Create the properties node
+ TableNode propertiesNode = new TableNode(name, properties.get(name) != null ? properties.get(name).toString() : ""); //$NON-NLS-1$
+ if (!IPeerModelProperties.PROP_LAST_SCANNER_ERROR.equals(name)) nodes.add(propertiesNode);
+ else lastErrorNode = propertiesNode;
+ }
+
+ if (lastErrorNode != null) {
+ // Add an empty line before the error
+ TableNode propertiesNode = new TableNode("", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ nodes.add(propertiesNode);
+ nodes.add(lastErrorNode);
+ }
+ }
+
+ return nodes.toArray(new TableNode[nodes.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // Do nothing if we shall not update the section title
+ if (!fUpdateParentSectionTitle) return;
+
+ String sectionTitle = null;
+ Object element = null;
+
+ // If the input is a tree selection, extract the element from the tree path
+ if (newInput instanceof ITreeSelection && !((ITreeSelection)newInput).isEmpty()) {
+ // Cast to the correct type
+ ITreeSelection selection = (ITreeSelection)newInput;
+ // Get the selected tree pathes
+ TreePath[] pathes = selection.getPaths();
+ // If there are more than one elements selected, we care only about the first path
+ TreePath path = pathes.length > 0 ? pathes[0] : null;
+ // Get the last element within the tree path
+ element = path != null ? path.getLastSegment() : null;
+ }
+
+ // If the input is a peer model node, set it directly
+ if (newInput instanceof IPeerModel) element = newInput;
+
+ // Determine the section header text
+ if (element instanceof IPeerModel) {
+ sectionTitle = NLS.bind(org.eclipse.tm.te.ui.nls.Messages.NodePropertiesTableControl_section_title, Messages.NodePropertiesContentProvider_peerNode_sectionTitle);
+ }
+
+ // Set the standard (no selection) section title if none could be determined
+ if (sectionTitle == null || "".equals(sectionTitle.trim())) sectionTitle = org.eclipse.tm.te.ui.nls.Messages.NodePropertiesTableControl_section_title_noSelection; //$NON-NLS-1$
+ // Stretch to a length of 40 characters to make sure the title can be changed
+ // to hold and show text up to this length
+ while (sectionTitle.length() < 40) sectionTitle += " "; //$NON-NLS-1$
+
+ // Find the parent section the node properties tables is embedded in
+ Control control = viewer.getControl();
+ while (control != null && !control.isDisposed()) {
+ if (control instanceof Section) {
+ Section section = (Section)control;
+ // We cannot get access to the Label control used to set the text, so just catch the
+ // probably SWTException
+ try { section.setText(sectionTitle); } catch(SWTException e) { /* ignored on purpose */ }
+ break;
+ }
+ control = control.getParent();
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesLabelProvider.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesLabelProvider.java
new file mode 100644
index 000000000..c201c0f0c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesLabelProvider.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.tables;
+
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tm.te.tcf.ui.internal.nls.Messages;
+import org.eclipse.tm.te.ui.tables.TableNode;
+
+
+/**
+ * Target Explorer: TCF node properties table label provider implementation.
+ */
+public class NodePropertiesLabelProvider extends LabelProvider implements ITableLabelProvider, ITableColorProvider {
+ // Reference to the parent table viewer
+ private final TableViewer fParentViewer;
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The table viewer or <code>null</code>.
+ */
+ public NodePropertiesLabelProvider(TableViewer viewer) {
+ super();
+ fParentViewer = viewer;
+ }
+
+ /**
+ * Returns the parent table viewer instance.
+ *
+ * @return The parent table viewer or <code>null</code>.
+ */
+ protected final TableViewer getParentViewer() {
+ return fParentViewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.datasource.controls.tables.TableLabelProvider#getColumnText(org.eclipse.tm.te.tcf.core.runtime.model.interfaces.IModelNode, int)
+ */
+ public String getColumnText(Object element, int columnIndex) {
+ assert element != null;
+
+ String label = null;
+
+ if (element instanceof TableNode) {
+ switch (columnIndex) {
+ case 0:
+ label = ((TableNode)element).name;
+ break;
+ case 1:
+ label = ((TableNode)element).value;
+ break;
+ }
+
+ if (label != null) {
+ if (IPeerModelProperties.PROP_LAST_SCANNER_ERROR.equals(label)) {
+ label = Messages.NodePropertiesLabelProvider_lastScannerError;
+ } else if (IPeerModelProperties.PROP_STATE.equals(label)) {
+ label = Messages.NodePropertiesLabelProvider_state;
+ } else if (IPeerModelProperties.PROP_LOCAL_SERVICES.equals(label)) {
+ label = Messages.NodePropertiesLabelProvider_services_local;
+ } else if (IPeerModelProperties.PROP_REMOTE_SERVICES.equals(label)) {
+ label = Messages.NodePropertiesLabelProvider_services_remote;
+ } else if (columnIndex == 1 && IPeerModelProperties.PROP_STATE.equals(((TableNode)element).name)) {
+ label = Messages.getString("NodePropertiesLabelProvider_state_" + label.replace('-', '_')); //$NON-NLS-1$
+ }
+ }
+ }
+
+ return label;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+ */
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableColorProvider#getForeground(java.lang.Object, int)
+ */
+ public Color getForeground(Object element, int columnIndex) {
+ if (element instanceof TableNode && IPeerModelProperties.PROP_LAST_SCANNER_ERROR.equals(((TableNode)element).name)) {
+ return getParentViewer().getControl().getDisplay().getSystemColor(SWT.COLOR_RED);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableColorProvider#getBackground(java.lang.Object, int)
+ */
+ public Color getBackground(Object element, int columnIndex) {
+ return null;
+ }
+
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesViewerComparator.java b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesViewerComparator.java
new file mode 100644
index 000000000..157a0bc86
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.tcf.ui/src/org/eclipse/tm/te/tcf/ui/tables/NodePropertiesViewerComparator.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.tcf.ui.tables;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tm.te.tcf.ui.internal.nls.Messages;
+import org.eclipse.tm.te.ui.tables.TableViewerComparator;
+
+
+/**
+ * Target Explorer: TCF node properties table viewer comparator implementation.
+ */
+public class NodePropertiesViewerComparator extends TableViewerComparator {
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The parent viewer. Must be not <code>null</code>.
+ * @param labelProvider The table label provider. Must be not <code>null</code>.
+ */
+ public NodePropertiesViewerComparator(Viewer viewer, ITableLabelProvider labelProvider) {
+ super(viewer, labelProvider);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.tcf.vtl.ui.tables.TableViewerComparator#doCompare(java.lang.Object, java.lang.Object, java.lang.String, int, int)
+ */
+ @Override
+ protected int doCompare(Object node1, Object node2, String sortColumn, int index, int inverter) {
+ if (node1 != null && node2 != null && index == 0) {
+ String t1 = doGetText(node1, index);
+ String t2 = doGetText(node2, index);
+
+ // Special handling for empty text and last error text
+ if ("".equals(t1) || "".equals(t2) //$NON-NLS-1$ //$NON-NLS-2$
+ || Messages.NodePropertiesLabelProvider_lastScannerError.equals(t1)
+ || Messages.NodePropertiesLabelProvider_lastScannerError.equals(t2)) {
+ if (("".equals(t1) || Messages.NodePropertiesLabelProvider_lastScannerError.equals(t1)) //$NON-NLS-1$
+ && !("".equals(t2) || Messages.NodePropertiesLabelProvider_lastScannerError.equals(t2))) { //$NON-NLS-1$
+ return 1;
+ }
+ if (!("".equals(t1) || Messages.NodePropertiesLabelProvider_lastScannerError.equals(t1)) //$NON-NLS-1$
+ && ("".equals(t2) || Messages.NodePropertiesLabelProvider_lastScannerError.equals(t2))) { //$NON-NLS-1$
+ return -1;
+ }
+ if ("".equals(t1) && Messages.NodePropertiesLabelProvider_lastScannerError.equals(t2)) { //$NON-NLS-1$
+ return -1;
+ }
+ if ("".equals(t2) && Messages.NodePropertiesLabelProvider_lastScannerError.equals(t1)) { //$NON-NLS-1$
+ return 1;
+ }
+ }
+ }
+
+ return super.doCompare(node1, node2, sortColumn, index, inverter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/.classpath b/target_explorer/plugins/org.eclipse.tm.te.ui.views/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/.project b/target_explorer/plugins/org.eclipse.tm.te.ui.views/.project
new file mode 100644
index 000000000..22f8a6f02
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.ui.views</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.ui.views/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..16730451b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Wed Dec 15 14:57:08 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.ui.views/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..f54227fd2
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.ui.views;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.ui.views.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.core.expressions;bundle-version="3.4.200",
+ org.eclipse.ui;bundle-version="3.6.2",
+ org.eclipse.ui.forms;bundle-version="3.5.2",
+ org.eclipse.ui.navigator;bundle-version="3.5.0",
+ org.eclipse.tm.te.core;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.ui.views.editor;version="1.0.0",
+ org.eclipse.tm.te.ui.views.interfaces;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/build.properties b/target_explorer/plugins/org.eclipse.tm.te.ui.views/build.properties
new file mode 100644
index 000000000..d24082bdb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml,\
+ icons/
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/editor.gif b/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/editor.gif
new file mode 100644
index 000000000..9ca749bbd
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/editor.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/prop_ps.gif b/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/prop_ps.gif
new file mode 100644
index 000000000..d11c996e5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/prop_ps.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/targets_view.gif b/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/targets_view.gif
new file mode 100644
index 000000000..9ca749bbd
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/icons/eview16/targets_view.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.properties
new file mode 100644
index 000000000..3b97b3b7c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.properties
@@ -0,0 +1,35 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer View
+providerName = Eclipse.org
+
+# ***** Extension Points *****
+
+ExtensionPoint.editorPages.name=Target Explorer Details Editor Pages Extension Point
+ExtensionPoint.editorPageBindings.name=Target Explorer Details Editor Page Bindings Extension Point
+
+# ***** Perspective *****
+
+Perspective.name=Target Explorer
+
+# ***** Views *****
+
+ViewCategory.name=Target Explorer Views
+TargetExplorer.name=Target Explorer
+
+# ***** Editor *****
+
+Editor.name=Target Explorer Details Editor
+
+# ***** Command and menu contributions *****
+
+PropertiesAction.label=&Properties
+PropertiesAction.tooltip=Show Properties of Selection
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.xml b/target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.xml
new file mode 100644
index 000000000..81443abd3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/plugin.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension-point id="editorPageBindings" name="%ExtensionPoint.editorPageBindings.name" schema="schema/editorPageBindings.exsd"/>
+ <extension-point id="editorPages" name="%ExtensionPoint.editorPages.name" schema="schema/editorPages.exsd"/>
+
+<!-- Common Navigator contributions -->
+ <extension point="org.eclipse.ui.navigator.viewer">
+ <viewer
+ helpContext="org.eclipse.tm.te.ui.views.TargetExplorer"
+ viewerId="org.eclipse.tm.te.ui.views.TargetExplorer">
+ <popupMenu
+ id="org.eclipse.tm.te.ui.views.TargetExplorer#Popup"
+ allowsPlatformContributions="true">
+ <insertionPoint name="group.new" separator="true"/>
+ <insertionPoint name="group.goto"/>
+ <insertionPoint name="group.expandto" separator="true"/>
+ <insertionPoint name="group.expand"/>
+ <insertionPoint name="group.open" separator="true"/>
+ <insertionPoint name="group.openWith"/>
+ <insertionPoint name="group.connect" separator="true"/>
+ <insertionPoint name="group.symbols" separator="true"/>
+ <insertionPoint name="group.symbols.rd"/>
+ <insertionPoint name="group.symbols.loadunload"/>
+ <insertionPoint name="group.symbols.additions"/>
+ <insertionPoint name="group.launch" separator="true"/>
+ <insertionPoint name="group.launch.rundebug"/>
+ <insertionPoint name="group.launch.modes"/>
+ <insertionPoint name="group.launch.additions"/>
+ <insertionPoint name="group.show" separator="true"/>
+ <insertionPoint name="group.edit" separator="true"/>
+ <insertionPoint name="group.delete"/>
+ <insertionPoint name="group.build" separator="true"/>
+ <insertionPoint name="group.refresh" separator="true"/>
+ <insertionPoint name="group.reorganize"/>
+ <insertionPoint name="group.reorder"/>
+ <insertionPoint name="group.port"/>
+ <insertionPoint name="group.generate" separator="true"/>
+ <insertionPoint name="group.search" separator="true"/>
+ <insertionPoint name="group.connection" separator="true"/>
+ <insertionPoint name="group.operations" separator="true"/>
+ <insertionPoint name="group.analysis" separator="true"/>
+ <insertionPoint name="additions" separator="true"/>
+ <insertionPoint name="group.properties" separator="true"/>
+ </popupMenu>
+ <options>
+ <property
+ name="org.eclipse.ui.navigator.hideLinkWithEditorAction"
+ value="true">
+ </property>
+ </options>
+ </viewer>
+ </extension>
+
+<!-- View contributions -->
+ <extension point="org.eclipse.ui.views">
+ <category
+ id="org.eclipse.tm.te.ui.views.category"
+ name="%ViewCategory.name">
+ </category>
+ <view
+ category="org.eclipse.tm.te.ui.views.category"
+ class="org.eclipse.tm.te.ui.views.internal.View"
+ icon="icons/eview16/targets_view.gif"
+ id="org.eclipse.tm.te.ui.views.TargetExplorer"
+ name="%TargetExplorer.name"
+ restorable="true">
+ </view>
+ </extension>
+
+<!-- Target Explorer Perspective -->
+ <extension point="org.eclipse.ui.perspectives">
+ <perspective
+ class="org.eclipse.tm.te.ui.views.perspective.PerspectiveFactory"
+ icon="icons/eview16/editor.gif"
+ id="org.eclipse.tm.te.ui.perspective"
+ name="%Perspective.name">
+ </perspective>
+ </extension>
+
+<!-- Perspective contributions -->
+ <extension point="org.eclipse.ui.perspectiveExtensions">
+ <perspectiveExtension targetID="org.eclipse.tm.te.ui.perspective">
+ <!-- Run/Debug actions should be available -->
+ <actionSet id="org.eclipse.debug.ui.launchActionSet"/>
+ <!-- Register the view shortcuts -->
+ <viewShortcut id="org.eclipse.tm.te.ui.views.TargetExplorer"/>
+ </perspectiveExtension>
+ </extension>
+
+<!-- Editor contributions -->
+ <extension point="org.eclipse.ui.editors">
+ <editor
+ class="org.eclipse.tm.te.ui.views.internal.editor.Editor"
+ default="false"
+ icon="icons/eview16/prop_ps.gif"
+ id="org.eclipse.tm.te.ui.view.Editor"
+ name="%Editor.name">
+ </editor>
+ </extension>
+
+<!-- Target Explorer menu contributions -->
+ <extension point="org.eclipse.ui.menus">
+ <menuContribution locationURI="popup:org.eclipse.tm.te.ui.views.TargetExplorer#Popup?after=group.properties">
+ <command
+ commandId="org.eclipse.ui.file.properties"
+ helpContextId="org.eclipse.tm.te.ui.views.command_Properties"
+ id="properties"
+ label="%PropertiesAction.label"
+ tooltip="%PropertiesAction.tooltip">
+ <visibleWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate operator="and" ifEmpty="false">
+ <test property="org.eclipse.tm.te.ui.views.hasApplicableEditorBindings" value="true"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ </extension>
+
+<!-- Handler contributions -->
+ <extension point="org.eclipse.ui.handlers">
+ <handler
+ commandId="org.eclipse.ui.file.properties"
+ class="org.eclipse.tm.te.ui.views.internal.targets.handler.PropertiesCommandHandler">
+ <enabledWhen>
+ <with variable="selection">
+ <count value="1"/>
+ </with>
+ </enabledWhen>
+ <activeWhen>
+ <with variable="activePartId">
+ <equals value="org.eclipse.tm.te.ui.views.TargetExplorer"/>
+ </with>
+ </activeWhen>
+ </handler>
+ </extension>
+
+<!-- Eclipse core expressions property tester -->
+ <extension point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.tm.te.ui.views.internal.expressions.EditorPropertyTester"
+ id="org.eclipse.tm.te.ui.views.EditorPropertyTester"
+ namespace="org.eclipse.tm.te.ui.views"
+ properties="hasApplicableEditorBindings"
+ type="java.lang.Object">
+ </propertyTester>
+ </extension>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPageBindings.exsd b/target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPageBindings.exsd
new file mode 100644
index 000000000..a7bc73d8f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPageBindings.exsd
@@ -0,0 +1,163 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.te.ui.views" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tm.te.ui.views" id="editorPageBindings" name="Target Explorer Editor Page Bindings Extension Point"/>
+ </appinfo>
+ <documentation>
+ This extension point is used to declare the Target Explorer editor page bindings.
+&lt;p&gt;
+&lt;b&gt;Note:&lt;/b&gt; For the enablement expression evaluation, note that the default variable and the &quot;activeEditorInput&quot; variable are the same and non-iterable.
+ </documentation>
+ </annotation>
+
+ <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="editorPageBinding" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="editorPageBinding">
+ <annotation>
+ <documentation>
+ Declares a Target Explorer editor page binding.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="enablement" minOccurs="0" maxOccurs="1"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id of the editor page binding contribution.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pageId" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id of the referenced editor page.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.tm.te.ui.views.editorPages/editorPage/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="insertBefore">
+ <annotation>
+ <documentation>
+ The id of the page this page shall be inserted before, or &quot;first&quot; to insert it at the beginning of the stack. If &quot;insertBefore&quot; is specified non-empty, it will eclipse the &quot;insertAfter&quot; attribute. If neither &quot;insertBefore&quot; or &quot;insertAfter&quot; is specified, the page will be inserted at the end of the stack.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.tm.te.ui.views.editorPages/editorPage/@id"/>
+ </appinfo>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="first">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ <attribute name="insertAfter">
+ <annotation>
+ <documentation>
+ The id of the page this page shall be inserted after, or &quot;last&quot; to insert it at the end of the stack. If &quot;insertBefore&quot; is specified non-empty, it will eclipse the &quot;insertAfter&quot; attribute. If neither &quot;insertBefore&quot; or &quot;insertAfter&quot; is specified, the page will be inserted at the end of the stack.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.te.ui.views.editorPages/editorPage/@id"/>
+ </appinfo>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="last">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Target Explorer 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;pre&gt;
+ &lt;extension point=&quot;org.eclipse.tm.te.ui.views.editorPageBindings&quot;&gt;
+ &lt;editorPageBinding
+ id=&quot;org.eclipse.tm.te.tcf.binding.TcfPeerPropertiesPage&quot;
+ pageId=&quot;org.eclipse.tm.te.tcf.ui.TcfPeerPropertiesPage&quot;&gt;
+ &lt;enablement&gt;
+ &lt;with variable=&quot;activeEditorInput&quot;&gt;
+ ...
+ &lt;/with&gt;
+ &lt;/enablement&gt;
+ &lt;/editorPageBinding&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ 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.
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPages.exsd b/target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPages.exsd
new file mode 100644
index 000000000..6c76732ae
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/schema/editorPages.exsd
@@ -0,0 +1,147 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.te.ui.views" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tm.te.ui.views" id="editorPages" name="Target Explorer Editor Pages Extension Point"/>
+ </appinfo>
+ <documentation>
+ This extension point is used to allow the contribution of new Target Explorer editor pages.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="editorPage" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="editorPage">
+ <annotation>
+ <documentation>
+ Declares a Target Explorer editor page contribution.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique editor page id.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ A translatable name that will be used in the UI for this editor page.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;org.eclipse.tm.te.ui.views.interfaces.IEditorPage&lt;/code&gt; or extends &lt;code&gt;org.eclipse.tm.te.ui.views.editor.AbstractEditorPage&lt;/code&gt;.
+&lt;p&gt;
+The editor page implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.tm.te.views.editor.AbstractEditorPage:org.eclipse.tm.te.ui.views.interfaces.IEditorPage"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ A relative name of the icon that will be used for the editor page.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Target Explorer 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;pre&gt;
+ &lt;extension point=&quot;org.eclipse.tm.te.ui.views.editorPages&quot;&gt;
+ &lt;editorPage
+ class=&quot;org.eclipse.tm.te.tcf.ui.internal.TcfPeerPropertiesPage&quot;
+ id=&quot;org.eclipse.tm.te.tcf.ui.TcfPeerPropertiesPage&quot;
+ label=&quot;TCF Peer Properties Editor Page&quot;&gt;
+ &lt;/editorPage&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ Plug-ins that want to extend this extension point, the referenced class must implement &lt;samp&gt;org.eclipse.tm.te.ui.views.interfaces.IEditorPage&lt;/samp&gt; interface.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ 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.
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/activator/UIPlugin.java
new file mode 100644
index 000000000..dd9063d2b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/activator/UIPlugin.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.activator;
+
+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.tm.te.ui.views.interfaces.ImageConsts;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+
+ // The shared instance
+ private static UIPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry registry) {
+ URL url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_EDITOR + "prop_ps.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.IMAGE_EDITOR, ImageDescriptor.createFromURL(url));
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>Image</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getImage(String key) {
+ return getDefault().getImageRegistry().get(key);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>ImageDescriptor</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>ImageDescriptor</code> object instance or <code>null</code>.
+ */
+ public static ImageDescriptor getImageDescriptor(String key) {
+ return getDefault().getImageRegistry().getDescriptor(key);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/editor/AbstractEditorPage.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/editor/AbstractEditorPage.java
new file mode 100644
index 000000000..b0771e58c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/editor/AbstractEditorPage.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.editor;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.te.core.nls.Messages;
+import org.eclipse.tm.te.ui.views.activator.UIPlugin;
+import org.eclipse.tm.te.ui.views.interfaces.IEditorPage;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.forms.editor.FormPage;
+
+
+/**
+ * Target Explorer: Abstract details editor page implementation.
+ */
+public abstract class AbstractEditorPage extends FormPage implements IEditorPage {
+ // The unique page id
+ private String fId;
+
+ /**
+ * Constructor.
+ */
+ public AbstractEditorPage() {
+ super("", ""); // //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) {
+ super.setInitializationData(config, propertyName, data);
+
+ if (config != null) {
+ // Initialize the id field by reading the <id> extension attribute.
+ // Throws an exception if the id is empty or null.
+ fId = config.getAttribute("id"); //$NON-NLS-1$
+ if (fId == null || fId.trim().length() == 0) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", config.getContributor().getName())); //$NON-NLS-1$
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#getId()
+ */
+ @Override
+ public String getId() {
+ return fId;
+ }
+
+ /**
+ * Returns the node associated with the current editor input.
+ *
+ * @return The node or <code>null</code>.
+ */
+ public Object getEditorInputNode() {
+ IEditorInput input = getEditorInput();
+ return input != null ? input.getAdapter(Object.class) : null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IEditorPage.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IEditorPage.java
new file mode 100644
index 000000000..21ef97c9c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IEditorPage.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.interfaces;
+
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.ui.forms.editor.IFormPage;
+
+/**
+ * Target Explorer: Details editor page public interface.
+ */
+public interface IEditorPage extends IFormPage, IExecutableExtension {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IRoot.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IRoot.java
new file mode 100644
index 000000000..de53c26af
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IRoot.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.interfaces;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * Target Explorer root node.
+ */
+public interface IRoot extends IAdaptable {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IUIConstants.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IUIConstants.java
new file mode 100644
index 000000000..e10db0787
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/IUIConstants.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.interfaces;
+
+/**
+ * Target Explorer UI constants.
+ */
+public interface IUIConstants {
+
+ /**
+ * The target explorer view id.
+ */
+ public static final String ID_EXPLORER = "org.eclipse.tm.te.ui.views.TargetExplorer"; //$NON-NLS-1$
+
+ /**
+ * The target explorer editor id.
+ */
+ public static final String ID_EDITOR = "org.eclipse.tm.te.ui.view.Editor"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/ImageConsts.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/ImageConsts.java
new file mode 100644
index 000000000..aba89ee72
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/interfaces/ImageConsts.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.interfaces;
+
+/**
+ * Target Explorer: Image registry constants.
+ */
+public interface ImageConsts {
+ /**
+ * The root directory where to load the images from, relative to
+ * the bundle directory.
+ */
+ public final static String IMAGE_DIR_ROOT = "icons/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load view related images from, relative to
+ * the image root directory.
+ */
+ public final static String IMAGE_DIR_EVIEW = "eview16/"; //$NON-NLS-1$
+
+ /**
+ * The key to access the Target Explorer editor image.
+ */
+ public static final String IMAGE_EDITOR = "TargetExplorerEditor"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/View.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/View.java
new file mode 100644
index 000000000..1d2775c40
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/View.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tm.te.ui.views.interfaces.IRoot;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+
+/**
+ * Target Explorer View implementation.
+ * <p>
+ * The view is based on the Eclipse Common Navigator framework.
+ */
+public class View extends CommonNavigator {
+ private final IRoot fRoot;
+
+ /**
+ * Target Explorer root node implementation
+ */
+ protected static class Root extends PlatformObject implements IRoot {
+ /**
+ * Constructor.
+ */
+ public Root() {
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ public View() {
+ fRoot = new Root();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#getInitialInput()
+ */
+ @Override
+ protected Object getInitialInput() {
+ return fRoot;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonNavigator#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+
+ if (getViewSite() != null && getViewSite().getActionBars() != null) {
+ IToolBarManager tbManager = getViewSite().getActionBars().getToolBarManager();
+ if (tbManager != null) {
+ tbManager.insertBefore("FRAME_ACTION_GROUP_ID", new GroupMarker("group.new")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.new", new Separator("group.connect")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.connect", new Separator("group.symbols.rd")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.symbols.rd", new GroupMarker("group.symbols")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.symbols", new Separator("group.refresh")); //$NON-NLS-1$ //$NON-NLS-2$
+ tbManager.appendToGroup("group.refresh", new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/Editor.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/Editor.java
new file mode 100644
index 000000000..8e646d785
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/Editor.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.editor;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.tm.te.ui.views.interfaces.IEditorPage;
+import org.eclipse.tm.te.ui.views.internal.extensions.EditorPageBinding;
+import org.eclipse.tm.te.ui.views.internal.extensions.EditorPageBindingExtensionPointManager;
+import org.eclipse.tm.te.ui.views.internal.extensions.EditorPageExtensionPointManager;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistable;
+import org.eclipse.ui.IPersistableEditor;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.IFormPage;
+
+
+/**
+ * Target Explorer: Details editor.
+ */
+public class Editor extends FormEditor implements IPersistableEditor {
+
+ // The reference to an memento to restore once the editor got activated
+ private IMemento fMementoToRestore;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
+ */
+ @Override
+ protected void addPages() {
+ // Read extension point and add the contributed pages.
+ IEditorInput input = getEditorInput();
+ // Get all applicable editor page bindings
+ EditorPageBinding[] bindings = EditorPageBindingExtensionPointManager.getInstance().getApplicableEditorPageBindings(input);
+ for (EditorPageBinding binding : bindings) {
+ String pageId = binding.getPageId();
+ if (pageId != null) {
+ // Get the corresponding editor page instance
+ IEditorPage page = EditorPageExtensionPointManager.getInstance().getEditorPage(pageId, true);
+ if (page != null) {
+ try {
+ // Associate this editor with the page instance.
+ // This is typically done in the constructor, but we are
+ // utilizing a default constructor to instantiate the page.
+ page.initialize(this);
+
+ // Read in the "insertBefore" and "insertAfter" properties of the binding
+ String insertBefore = binding.getInsertBefore().trim();
+ String insertAfter = binding.getInsertAfter().trim();
+
+ // insertBefore will eclipse insertAfter is both is specified.
+ if (!"".equals(insertBefore)) { //$NON-NLS-1$
+ // If it is "first", we insert the page at index 0
+ if ("first".equalsIgnoreCase(insertBefore)) { //$NON-NLS-1$
+ addPage(0, page);
+ } else {
+ // Find the index of the page we shall insert this page before
+ int index = getIndexOf(insertBefore);
+ if (index != -1) addPage(index, page);
+ else addPage(page);
+ }
+ } else if (!"".equals(insertAfter) && !"last".equalsIgnoreCase(insertAfter)) { //$NON-NLS-1$ //$NON-NLS-2$
+ // Find the index of the page we shall insert this page after
+ int index = getIndexOf(insertAfter);
+ if (index != -1 && index + 1 < pages.size()) addPage(index + 1, page);
+ else addPage(page);
+ } else {
+ // And add the page to the editor as last page.
+ addPage(page);
+ }
+ } catch (PartInitException e) { /* ignored on purpose */ }
+ }
+ }
+ }
+
+ if (fMementoToRestore != null) {
+ // Loop over all registered pages and pass on the editor specific memento
+ // to the pages which implements IPersistableEditor as well
+ for (Object page : pages) {
+ if (page instanceof IPersistableEditor) {
+ ((IPersistableEditor)page).restoreState(fMementoToRestore);
+ }
+ }
+ fMementoToRestore = null;
+ }
+ }
+
+ /**
+ * Returns the index of the page with the given id.
+ *
+ * @param pageId The page id. Must be not <code>null</code>.
+ * @return The page index or <code>-1</code> if not found.
+ */
+ private int getIndexOf(String pageId) {
+ assert pageId != null;
+ for (int i = 0; i < pages.size(); i++) {
+ Object page = pages.get(i);
+ if (page instanceof IFormPage) {
+ IFormPage fpage = (IFormPage)page;
+ if (fpage.getId().equals(pageId))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.editor.FormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+ super.init(site, input);
+
+ // Update the part name
+ if (!"".equals(input.getName())) setPartName(input.getName()); //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSaveAs()
+ */
+ @Override
+ public void doSaveAs() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableEditor#restoreState(org.eclipse.ui.IMemento)
+ */
+ public void restoreState(IMemento memento) {
+ // Get the editor specific memento
+ fMementoToRestore = internalGetMemento(memento);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ public void saveState(IMemento memento) {
+ // Get the editor specific memento
+ memento = internalGetMemento(memento);
+ // Loop over all registered pages and pass on the editor specific memento
+ // to the pages which implements IPersistable as well
+ for (Object page : pages) {
+ if (page instanceof IPersistable) {
+ ((IPersistable)page).saveState(memento);
+ }
+ }
+ }
+
+ /**
+ * Internal helper method accessing our editor local child memento
+ * from the given parent memento.
+ */
+ private IMemento internalGetMemento(IMemento memento) {
+ // Assume the editor memento to be the same as the parent memento
+ IMemento editorMemento = memento;
+
+ // If the parent memento is not null, create a child within the parent
+ if (memento != null) {
+ editorMemento = memento.getChild(Editor.class.getName());
+ if (editorMemento == null) {
+ editorMemento = memento.createChild(Editor.class.getName());
+ }
+ } else {
+ // The parent memento is null. Create a new internal instance
+ // of a XMLMemento. This case is happening if the user switches
+ // to another perspective an the view becomes visible by this switch.
+ editorMemento = XMLMemento.createWriteRoot(Editor.class.getName());
+ }
+
+ return editorMemento;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.MultiPageEditorPart#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Object getAdapter(Class adapter) {
+ // We pass on the adapt request to the currently active page
+ Object adapterInstance = getActivePageInstance() != null ? getActivePageInstance().getAdapter(adapter) : null;
+ if (adapterInstance == null) {
+ // If failed to adapt via the currently active page, pass on to the super implementation
+ adapterInstance = super.getAdapter(adapter);
+ }
+ return adapterInstance;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/EditorInput.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/EditorInput.java
new file mode 100644
index 000000000..85d37cd77
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/editor/EditorInput.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.editor;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.tm.te.ui.views.activator.UIPlugin;
+import org.eclipse.tm.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tm.te.ui.views.interfaces.ImageConsts;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.CommonViewer;
+
+
+/**
+ * Target Explorer: Details editor input implementation.
+ */
+public class EditorInput implements IEditorInput, IPersistableElement {
+ // The parent editor id
+ private final String fId;
+ // The editor input name, once determined
+ private String fName;
+ // The node (selection) the editor is showing
+ private final Object fNode;
+
+ /**
+ * Constructor.
+ *
+ * @param node The node (selection) the editor is showing. Must be not <code>null</code>.
+ */
+ public EditorInput(Object node) {
+ this(node, IUIConstants.ID_EDITOR);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param node The node (selection) the editor is showing. Must be not <code>null</code>.
+ * @param id The parent editor id or <code>null</code>
+ */
+ public EditorInput(Object node, String id) {
+ super();
+ fId = id;
+ assert node != null;
+ fNode = node;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (fNode != null && obj instanceof EditorInput) {
+ return fNode.equals(((EditorInput)obj).fNode)
+ && (fId != null ? fId.equals(((EditorInput)obj).fId) : ((EditorInput)obj).fId == null);
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return fNode != null ? fNode.hashCode() << 16 + (fId != null ? fId.hashCode() : 0) : super.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#exists()
+ */
+ public boolean exists() {
+ return fNode != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
+ */
+ public ImageDescriptor getImageDescriptor() {
+ return UIPlugin.getImageDescriptor(ImageConsts.IMAGE_EDITOR);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getName()
+ */
+ public String getName() {
+ if (fName == null && fNode != null) {
+ CommonViewer viewer = getViewer();
+ fName = viewer != null && viewer.getLabelProvider() instanceof ILabelProvider ? ((ILabelProvider)viewer.getLabelProvider()).getText(fNode) : fNode.toString();
+ }
+
+ return fName != null ? fName : ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Get the common viewer used by the Target Explorer view instance.
+ *
+ * @return The common viewer or <code>null</code>
+ */
+ protected CommonViewer getViewer() {
+ if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
+ && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IViewPart part = page.findView(IUIConstants.ID_EXPLORER);
+ if (part instanceof CommonNavigator) {
+ return ((CommonNavigator)part).getCommonViewer();
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getPersistable()
+ */
+ public IPersistableElement getPersistable() {
+ // We cannot persist this kind of editor input.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableElement#getFactoryId()
+ */
+ public String getFactoryId() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ public void saveState(IMemento memento) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getToolTipText()
+ */
+ public String getToolTipText() {
+ return getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Class adapter) {
+ if (IPersistableElement.class.isAssignableFrom(adapter)) {
+ return getPersistable();
+ }
+
+ // If the adapter can be applied to the node instance, return the node
+ Object adapted = Platform.getAdapterManager().getAdapter(fNode, adapter);
+ if (adapted != null) return adapted;
+
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/expressions/EditorPropertyTester.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/expressions/EditorPropertyTester.java
new file mode 100644
index 000000000..4e3897c27
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/expressions/EditorPropertyTester.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.expressions;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.tm.te.ui.views.internal.editor.EditorInput;
+import org.eclipse.tm.te.ui.views.internal.extensions.EditorPageBindingExtensionPointManager;
+import org.eclipse.ui.IEditorInput;
+
+
+/**
+ * Target Explorer: Details editor property tester implementation.
+ */
+public class EditorPropertyTester extends PropertyTester {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if ("hasApplicableEditorBindings".equals(property)) { //$NON-NLS-1$
+ // Create a fake editor input object
+ IEditorInput input = new EditorInput(receiver);
+ return expectedValue.equals(Boolean.valueOf(EditorPageBindingExtensionPointManager.getInstance().getApplicableEditorPageBindings(input).length > 0));
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBinding.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBinding.java
new file mode 100644
index 000000000..059912002
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBinding.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.extensions;
+
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.tm.te.core.extensions.ExecutableExtension;
+
+/**
+ * Target Explorer: Details editor page binding implementation.
+ */
+public class EditorPageBinding extends ExecutableExtension {
+ private String fPageId;
+ private String fInsertBefore;
+ private String fInsertAfter;
+ private Expression fExpression;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.ExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ super.setInitializationData(config, propertyName, data);
+
+ if (config != null) {
+ // Initialize the page id field by reading the <pageId> extension attribute.
+ // Throws an exception if the id is empty or null.
+ fPageId = config.getAttribute("pageId"); //$NON-NLS-1$
+ if (fPageId == null || fPageId.trim().length() == 0) {
+ throw createMissingMandatoryAttributeException("pageId", config.getContributor().getName()); //$NON-NLS-1$
+ }
+
+ // Initialize the insertBefore field by reading the <insertBefore> extension attribute if present.
+ fInsertBefore = config.getAttribute("insertBefore"); //$NON-NLS-1$
+ if (fInsertBefore == null || fInsertBefore.trim().length() == 0) fInsertBefore = ""; //$NON-NLS-1$
+
+ // Initialize the insertAfter field by reading the <insertAfter> extension attribute if present.
+ fInsertAfter = config.getAttribute("insertAfter"); //$NON-NLS-1$
+ if (fInsertAfter == null || fInsertAfter.trim().length() == 0) fInsertAfter = ""; //$NON-NLS-1$
+
+ IConfigurationElement[] children = config.getChildren();
+ if (children != null && children.length > 0) {
+ // Should only be one - enablement
+ fExpression = ExpressionConverter.getDefault().perform(children[0]);
+ }
+
+ }
+ }
+
+ /**
+ * Returns the editor page id which is associated with this binding.
+ *
+ * @return The editor page id.
+ */
+ public String getPageId() {
+ return fPageId;
+ }
+
+ /**
+ * Returns the enablement expression which is associated with this binding.
+ *
+ * @return The enablement expression or <code>null</code>.
+ */
+ public Expression getEnablement() {
+ return fExpression;
+ }
+
+ /**
+ * Returns the &quot;insertBefore&quot; property for this binding.
+ *
+ * @return The &quot;insertBefore&quot; property of an empty string.
+ */
+ public String getInsertBefore() {
+ return fInsertBefore;
+ }
+
+ /**
+ * Returns the &quot;insertAfter&quot; property for this binding.
+ *
+ * @return The &quot;insertAfter&quot; property of an empty string.
+ */
+ public String getInsertAfter() {
+ return fInsertAfter;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBindingExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBindingExtensionPointManager.java
new file mode 100644
index 000000000..e1451117f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageBindingExtensionPointManager.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.extensions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager;
+import org.eclipse.tm.te.core.extensions.ExecutableExtensionProxy;
+import org.eclipse.tm.te.ui.views.activator.UIPlugin;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.ISources;
+
+
+/**
+ * Target Explorer: Details editor page binding extension point manager implementation.
+ */
+public class EditorPageBindingExtensionPointManager extends AbstractExtensionPointManager<EditorPageBinding> {
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static EditorPageBindingExtensionPointManager fInstance = new EditorPageBindingExtensionPointManager();
+ }
+
+ /**
+ * Constructor.
+ */
+ EditorPageBindingExtensionPointManager() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance of the extension point manager.
+ */
+ public static EditorPageBindingExtensionPointManager getInstance() {
+ return LazyInstance.fInstance;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.AbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tm.te.ui.views.editorPageBindings"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.AbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "editorPageBinding"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.AbstractExtensionPointManager#doCreateExtensionProxy(org.eclipse.core.runtime.IConfigurationElement)
+ */
+ @Override
+ protected ExecutableExtensionProxy<EditorPageBinding> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+ return new ExecutableExtensionProxy<EditorPageBinding>(element) {
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.ExecutableExtensionProxy#newInstance()
+ */
+ @Override
+ public EditorPageBinding newInstance() {
+ EditorPageBinding instance = new EditorPageBinding();
+ if (instance != null) {
+ try {
+ instance.setInitializationData(getConfigurationElement(), null, null);
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ return instance;
+ }
+ };
+ }
+
+ /**
+ * Returns the applicable editor page bindings for the given data source model node..
+ *
+ * @param input The active editor input or <code>null</code>.
+ * @return The list of applicable editor page bindings or an empty array.
+ */
+ public EditorPageBinding[] getApplicableEditorPageBindings(IEditorInput input) {
+ List<EditorPageBinding> applicable = new ArrayList<EditorPageBinding>();
+
+ for (EditorPageBinding binding : getEditorPageBindings()) {
+ Expression enablement = binding.getEnablement();
+
+ // The page binding is applicable by default if no expression
+ // is specified.
+ boolean isApplicable = enablement == null;
+
+ if (enablement != null && input != null) {
+ // Extract the node from the editor input
+ Object node = input.getAdapter(Object.class);
+ if (node != null) {
+ // Set the default variable to the data source model node instance.
+ EvaluationContext context = new EvaluationContext(null, node);
+ // Set the "activeEditorInput" variable to the data source model node instance.
+ context.addVariable(ISources.ACTIVE_EDITOR_INPUT_NAME, node);
+ // Evaluate the expression
+ try {
+ isApplicable = enablement.evaluate(context).equals(EvaluationResult.TRUE);
+ } catch (CoreException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ e.getLocalizedMessage(), e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ } else {
+ // The enablement is false by definition if we cannot
+ // determine the data source model node.
+ isApplicable = false;
+ }
+ }
+
+ // Add the page if applicable
+ if (isApplicable) applicable.add(binding);
+ }
+
+ return applicable.toArray(new EditorPageBinding[applicable.size()]);
+ }
+
+ /**
+ * Returns the list of all contributed editor page bindings.
+ *
+ * @return The list of contributed editor page bindings, or an empty array.
+ */
+ public EditorPageBinding[] getEditorPageBindings() {
+ List<EditorPageBinding> contributions = new ArrayList<EditorPageBinding>();
+ Collection<ExecutableExtensionProxy<EditorPageBinding>> editorPageBindings = getExtensions().values();
+ for (ExecutableExtensionProxy<EditorPageBinding> editorPageBinding : editorPageBindings) {
+ EditorPageBinding instance = editorPageBinding.getInstance();
+ if (instance != null && !contributions.contains(instance)) {
+ contributions.add(instance);
+ }
+ }
+
+ return contributions.toArray(new EditorPageBinding[contributions.size()]);
+ }
+
+ /**
+ * Returns the editor page binding identified by its unique id. If no editor
+ * page binding with the specified id is registered, <code>null</code> is returned.
+ *
+ * @param id The unique id of the editor page binding or <code>null</code>
+ *
+ * @return The editor page instance or <code>null</code>.
+ */
+ public EditorPageBinding getEditorPageBinding(String id) {
+ EditorPageBinding contribution = null;
+ if (getExtensions().containsKey(id)) {
+ ExecutableExtensionProxy<EditorPageBinding> proxy = getExtensions().get(id);
+ // Get the extension instance
+ contribution = proxy.getInstance();
+ }
+
+ return contribution;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageExtensionPointManager.java
new file mode 100644
index 000000000..b36563b01
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/extensions/EditorPageExtensionPointManager.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.extensions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.tm.te.core.extensions.AbstractExtensionPointManager;
+import org.eclipse.tm.te.core.extensions.ExecutableExtensionProxy;
+import org.eclipse.tm.te.ui.views.interfaces.IEditorPage;
+
+
+/**
+ * Target Explorer: Details editor page extension point manager implementation.
+ */
+public class EditorPageExtensionPointManager extends AbstractExtensionPointManager<IEditorPage> {
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static EditorPageExtensionPointManager fInstance = new EditorPageExtensionPointManager();
+ }
+
+ /**
+ * Constructor.
+ */
+ EditorPageExtensionPointManager() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance of the extension point manager.
+ */
+ public static EditorPageExtensionPointManager getInstance() {
+ return LazyInstance.fInstance;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.AbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tm.te.ui.views.editorPages"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.views.internal.extensions.AbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "editorPage"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the list of all contributed editor pages.
+ *
+ * @param unique If <code>true</code>, the method returns new instances for each
+ * contributed editor page.
+ *
+ * @return The list of contributed editor pages, or an empty array.
+ */
+ public IEditorPage[] getEditorPages(boolean unique) {
+ List<IEditorPage> contributions = new ArrayList<IEditorPage>();
+ Collection<ExecutableExtensionProxy<IEditorPage>> editorPages = getExtensions().values();
+ for (ExecutableExtensionProxy<IEditorPage> editorPage : editorPages) {
+ IEditorPage instance = unique ? editorPage.newInstance() : editorPage.getInstance();
+ if (instance != null && !contributions.contains(instance)) {
+ contributions.add(instance);
+ }
+ }
+
+ return contributions.toArray(new IEditorPage[contributions.size()]);
+ }
+
+ /**
+ * Returns the editor page identified by its unique id. If no editor
+ * page with the specified id is registered, <code>null</code> is returned.
+ *
+ * @param id The unique id of the editor page or <code>null</code>
+ * @param unique If <code>true</code>, the method returns new instances of the editor page contribution.
+ *
+ * @return The editor page instance or <code>null</code>.
+ */
+ public IEditorPage getEditorPage(String id, boolean unique) {
+ IEditorPage contribution = null;
+ if (getExtensions().containsKey(id)) {
+ ExecutableExtensionProxy<IEditorPage> proxy = getExtensions().get(id);
+ // Get the extension instance
+ contribution = unique ? proxy.newInstance() : proxy.getInstance();
+ }
+
+ return contribution;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.java
new file mode 100644
index 000000000..5a0520bb9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer UI plugin externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.ui.views.internal.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String PropertiesCommandHandler_error_initPartFailed;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.properties
new file mode 100644
index 000000000..c88578ab4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/nls/Messages.properties
@@ -0,0 +1,6 @@
+#
+# org.eclipse.tm.te.ui.views
+# Externalized Strings.
+#
+
+PropertiesCommandHandler_error_initPartFailed=Failed to initialize the Target Explorer details editor.
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/targets/handler/PropertiesCommandHandler.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/targets/handler/PropertiesCommandHandler.java
new file mode 100644
index 000000000..ae76a2a03
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/internal/targets/handler/PropertiesCommandHandler.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.internal.targets.handler;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tm.te.ui.views.activator.UIPlugin;
+import org.eclipse.tm.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tm.te.ui.views.internal.editor.EditorInput;
+import org.eclipse.tm.te.ui.views.internal.nls.Messages;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+/**
+ * Target Explorer: Properties command handler implementation.
+ */
+public class PropertiesCommandHandler extends AbstractHandler {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // Get the active selection
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ Object element = ((IStructuredSelection)selection).getFirstElement();
+ if (element != null) {
+ // Get the currently active workbench window
+ IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+ if (window == null) window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ // Get the active page
+ IWorkbenchPage page = window.getActivePage();
+ // Create the editor input object
+ IEditorInput input = new EditorInput(element);
+ // Check for the Target Explorer editor already opened
+ IEditorReference[] references = page.findEditors(input, IUIConstants.ID_EDITOR, IWorkbenchPage.MATCH_INPUT);
+ if (references.length == 0) {
+ try {
+ // Opens the Target Explorer properties editor
+ page.openEditor(input, IUIConstants.ID_EDITOR);
+ } catch (PartInitException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ Messages.PropertiesCommandHandler_error_initPartFailed, e);
+ UIPlugin.getDefault().getLog().log(status);
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/perspective/PerspectiveFactory.java b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/perspective/PerspectiveFactory.java
new file mode 100644
index 000000000..8af6ac492
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui.views/src/org/eclipse/tm/te/ui/views/perspective/PerspectiveFactory.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.views.perspective;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.IPlaceholderFolderLayout;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Target Explorer: Perspective factory.
+ */
+public class PerspectiveFactory extends PlatformObject implements IPerspectiveFactory {
+ private final static String[] VIEWS_FOR_LEFT_AREA = new String[] {
+ "org.eclipse.tm.te.ui.views.TargetExplorer", //$NON-NLS-1$
+ "org.eclipse.ui.navigator.ProjectExplorer" //$NON-NLS-1$
+ };
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPerspectiveFactory#createInitialLayout(org.eclipse.ui.IPageLayout)
+ */
+ public void createInitialLayout(IPageLayout layout) {
+ // editor is placed for free
+ String editorArea = layout.getEditorArea();
+
+ boolean leftAreaActive = false;
+ for (String viewId : VIEWS_FOR_LEFT_AREA) {
+ leftAreaActive |= PlatformUI.getWorkbench().getViewRegistry().find(viewId) != null;
+ if (leftAreaActive) break;
+ }
+
+ if (leftAreaActive) {
+ // place resource navigator to the left of editor area
+ IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.3f, editorArea); //$NON-NLS-1$
+
+ for (String viewId : VIEWS_FOR_LEFT_AREA) {
+ if (PlatformUI.getWorkbench().getViewRegistry().find(viewId) != null) {
+ left.addView(viewId);
+ }
+ }
+ } else {
+ layout.createPlaceholderFolder("left", IPageLayout.LEFT, 0.3f, editorArea); //$NON-NLS-1$
+ }
+
+ // place console below the main editor
+ IFolderLayout lowerRight = layout.createFolder("lowerRight", IPageLayout.BOTTOM, 0.7f, editorArea); //$NON-NLS-1$
+ if (PlatformUI.getWorkbench().getViewRegistry().find("org.eclipse.pde.runtime.LogView") != null) //$NON-NLS-1$
+ lowerRight.addView("org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
+ if (PlatformUI.getWorkbench().getViewRegistry().find("org.eclipse.ui.views.TaskList") != null) //$NON-NLS-1$
+ lowerRight.addPlaceholder("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$
+
+ // place details view port to the right of editor area
+ IPlaceholderFolderLayout right = layout.createPlaceholderFolder("right", IPageLayout.RIGHT, 0.75f, editorArea); //$NON-NLS-1$
+ if (PlatformUI.getWorkbench().getViewRegistry().find(IPageLayout.ID_OUTLINE) != null)
+ right.addPlaceholder(IPageLayout.ID_OUTLINE);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/.classpath b/target_explorer/plugins/org.eclipse.tm.te.ui/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/.project b/target_explorer/plugins/org.eclipse.tm.te.ui/.project
new file mode 100644
index 000000000..3ce2b5292
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.te.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tm.te.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..441efa153
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Thu Aug 19 09:20:49 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tm.te.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..371798215
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.te.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tm.te.ui.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.core.expressions;bundle-version="3.4.200",
+ org.eclipse.ui;bundle-version="3.6.2",
+ org.eclipse.ui.forms;bundle-version="3.5.2"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tm.te.ui;version="1.0.0",
+ org.eclipse.tm.te.ui.dialogs;version="1.0.0",
+ org.eclipse.tm.te.ui.forms;version="1.0.0",
+ org.eclipse.tm.te.ui.images;version="1.0.0",
+ org.eclipse.tm.te.ui.interfaces;version="1.0.0",
+ org.eclipse.tm.te.ui.nls;version="1.0.0",
+ org.eclipse.tm.te.ui.nodes;version="1.0.0",
+ org.eclipse.tm.te.ui.tables;version="1.0.0",
+ org.eclipse.tm.te.ui.tables.properties;version="1.0.0",
+ org.eclipse.tm.te.ui.trees;version="1.0.0"
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/build.properties b/target_explorer/plugins/org.eclipse.tm.te.ui/build.properties
new file mode 100644
index 000000000..aa1a00826
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/plugin.properties b/target_explorer/plugins/org.eclipse.tm.te.ui/plugin.properties
new file mode 100644
index 000000000..9007e2197
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/plugin.properties
@@ -0,0 +1,12 @@
+##################################################################################
+# 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:
+# Uwe Stieber (Wind River) - initial API and implementation
+##################################################################################
+
+pluginName = Target Explorer, Common UI Controls and Helper
+providerName = Eclipse.org
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/AbstractViewerComparator.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/AbstractViewerComparator.java
new file mode 100644
index 000000000..4d4e1e9fe
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/AbstractViewerComparator.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * Target Explorer: Common viewer comparator implementation.
+ */
+public abstract class AbstractViewerComparator extends ViewerComparator {
+ // Reference to the viewer
+ private final Viewer fViewer;
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The parent viewer. Must be not <code>null</code>.
+ */
+ public AbstractViewerComparator(Viewer viewer) {
+ assert viewer != null;
+ fViewer = viewer;
+ }
+
+ /**
+ * Returns the parent viewer instance.
+ *
+ * @return The parent viewer instance.
+ */
+ protected final Viewer getParentViewer() {
+ return fViewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) {
+ return doCompare(e1, e2, doGetSortColumnLabel(viewer), doGetSortColumnIndex(viewer) , doDetermineInverter(viewer));
+ }
+ return super.compare(viewer, e1, e2);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Object o1, Object o2) {
+ return doCompare(o1, o2, null, -1, doDetermineInverter(getParentViewer()));
+ }
+
+ /**
+ * Compare the given nodes by the given sort column and inverter.
+ *
+ * @param node1 The first node or <code>null</code>.
+ * @param node2 The second node or <code>null</code>.
+ * @param sortColumn The sort column text or <code>null</code>.
+ * @param index The sort column index or <code>-1</code>.
+ * @param inverter The inverter.
+ *
+ * @return The compare result.
+ */
+ protected abstract int doCompare(Object node1, Object node2, String sortColumn, int index, int inverter);
+
+ /**
+ * Returns the text to compare for the given node and column index.
+ *
+ * @param node The node or <code>null</code>.
+ * @param index The column index or <code>-1</code>.
+ *
+ * @return The text for the given node and column index or <code>null</code>.
+ */
+ protected abstract String doGetText(Object node, int index);
+
+ /**
+ * Determine if or if not the sort direction needs to be inverted.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return <code>1</code> for original sort order, or <code>-1</code> for inverted sort order.
+ */
+ protected abstract int doDetermineInverter(Viewer viewer);
+
+ /**
+ * Return the label of the sort column of the given viewer.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return The label of the sort column or an empty string.
+ */
+ protected abstract String doGetSortColumnLabel(Viewer viewer);
+
+ /**
+ * Return the index of the sort column of the given viewer.
+ *
+ * @param viewer The viewer or <code>null</code>.
+ * @return The index of the sort column or <code>-1</code>.
+ */
+ protected abstract int doGetSortColumnIndex(Viewer viewer);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/WorkbenchPartControl.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/WorkbenchPartControl.java
new file mode 100644
index 000000000..6dab3be48
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/WorkbenchPartControl.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tm.te.ui.activator.UIPlugin;
+import org.eclipse.tm.te.ui.forms.CustomFormToolkit;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+/**
+ * Target Explorer: Common workbench part control implementation.
+ */
+public class WorkbenchPartControl extends PlatformObject {
+ /**
+ * Reference to the parent workbench part the control might be embedded in.
+ */
+ private final IWorkbenchPart fParentPart;
+
+ /**
+ * Reference to the form toolkit instance provided via {@link #setupFormPanel(Composite, CustomFormToolkit)}.
+ */
+ private CustomFormToolkit fFormToolkit = null;
+
+ /**
+ * Reference to the parent control.
+ */
+ private Composite fParentControl;
+
+ /**
+ * Constructor.
+ */
+ public WorkbenchPartControl() {
+ this(null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPart The parent workbench part this control is embedded in or <code>null</code>.
+ */
+ public WorkbenchPartControl(IWorkbenchPart parentPart) {
+ super();
+ fParentPart = parentPart;
+ }
+
+ /**
+ * Returns the parent workbench part the control might be embedded in.
+ *
+ * @return The parent workbench part or <code>null</code>.
+ */
+ public final IWorkbenchPart getParentPart() {
+ return fParentPart;
+ }
+
+ /**
+ * Returns if the <code>setupPanel(...)</code> method has been called at least once with
+ * a non-null parent control.
+ *
+ * @return <code>true</code> if the associated parent control is not <code>null</code>, <code>false</code> otherwise.
+ */
+ public final boolean isControlCreated() {
+ return (fParentControl != null);
+ }
+
+ /**
+ * Returns the parent control of the control.
+ *
+ * @return The parent control or <code>null</code>.
+ */
+ public final Composite getParentControl() {
+ return fParentControl;
+ }
+
+ /**
+ * Cleanup all resources the control might have been created.
+ */
+ public void dispose() {
+ fParentControl = null;
+ }
+
+ /**
+ * Creates the controls UI elements.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @param toolkit The {@link CustomFormToolkit} instance. Must be not <code>null</code>.
+ */
+ public void setupFormPanel(Composite parent, CustomFormToolkit toolkit) {
+ assert parent != null && toolkit != null;
+ fParentControl = parent;
+ fFormToolkit = toolkit;
+ }
+
+ /**
+ * Returns the associated form toolkit instance.
+ *
+ * @return The form toolkit instance or <code>null</code> if not initialized yet.
+ */
+ protected final CustomFormToolkit getFormToolkit() {
+ return fFormToolkit;
+ }
+
+ /**
+ * Returns the selection service of the workbench.
+ *
+ * @return The selection service or <code>null</code>.
+ */
+ protected final ISelectionService getSelectionService() {
+ ISelectionService selectionService = null;
+ // Check if plugin, workbench and active workbench window are still valid
+ if (UIPlugin.getDefault() != null && UIPlugin.getDefault().getWorkbench() != null
+ && UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow() != null) {
+ selectionService = UIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getSelectionService();
+ }
+ return selectionService;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/activator/UIPlugin.java
new file mode 100644
index 000000000..d8d6e1e1b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/activator/UIPlugin.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.activator;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin {
+ // The shared instance
+ private static UIPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/dialogs/CustomTrayDialog.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/dialogs/CustomTrayDialog.java
new file mode 100644
index 000000000..702bab109
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/dialogs/CustomTrayDialog.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.dialogs;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.te.ui.activator.UIPlugin;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * Target Explorer: Custom tray dialog implementation.
+ */
+public class CustomTrayDialog extends TrayDialog {
+ private String fContextHelpId = null;
+
+ // the dialog storage
+ private IDialogSettings fDialogSettings;
+
+ /**
+ * Constructor.
+ *
+ * @param shell The parent shell or <code>null</code>.
+ */
+ public CustomTrayDialog(Shell shell) {
+ this(shell, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param shell The parent shell or <code>null</code>.
+ * @param contextHelpId The dialog context help id or <code>null</code>.
+ */
+ public CustomTrayDialog(Shell shell, String contextHelpId) {
+ super(shell);
+ initializeDialogSettings();
+ setContextHelpId(contextHelpId);
+ }
+
+ /**
+ * Configure the dialogs context help id.
+ *
+ * @param contextHelpId The context help id or <code>null</code>.
+ */
+ protected void setContextHelpId(String contextHelpId) {
+ fContextHelpId = contextHelpId;
+ setHelpAvailable(fContextHelpId != null);
+ }
+
+ /**
+ * Initialize the dialog settings storage.
+ */
+ protected void initializeDialogSettings() {
+ IDialogSettings settings = doGetDialogSettingsToInitialize();
+ assert settings != null;
+ IDialogSettings section = settings.getSection(getDialogSettingsSectionName());
+ if (section == null) {
+ section = settings.addNewSection(getDialogSettingsSectionName());
+ }
+ setDialogSettings(section);
+ }
+
+ /**
+ * Returns the dialog settings container to use and to initialize. This
+ * method is called from <code>initializeDialogSettings</code> and allows
+ * overriding the dialog settings container without changing the dialog
+ * settings structure.
+ *
+ * @return The dialog settings container to use. Must be not <code>null</code>.
+ */
+ protected IDialogSettings doGetDialogSettingsToInitialize() {
+ return UIPlugin.getDefault().getDialogSettings();
+ }
+
+ /**
+ * Returns the section name to use for separating different persistent
+ * dialog settings from different dialogs.
+ *
+ * @return The section name used to store the persistent dialog settings within the plugins persistent
+ * dialog settings store.
+ */
+ public String getDialogSettingsSectionName() {
+ return "CustomTrayDialog"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the associated dialog settings storage.
+ *
+ * @return The dialog settings storage.
+ */
+ public IDialogSettings getDialogSettings() {
+ // The dialog settings may not been initialized here. Initialize first in this case
+ // to be sure that we do have always the correct dialog settings.
+ if (fDialogSettings == null) {
+ initializeDialogSettings();
+ }
+ return fDialogSettings;
+ }
+
+ /**
+ * Sets the associated dialog settings storage.
+ *
+ * @return The dialog settings storage.
+ */
+ public void setDialogSettings(IDialogSettings dialogSettings) {
+ fDialogSettings = dialogSettings;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ if (fContextHelpId != null) {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, fContextHelpId);
+ }
+
+ // Let the super implementation create the dialog area control
+ Control control = super.createDialogArea(parent);
+ // But fix the layout data for the top control
+ if (control instanceof Composite) {
+ configureDialogAreaControl((Composite)control);
+ }
+
+ return control;
+ }
+
+ /**
+ * Configure the dialog top control.
+ *
+ * @param composite The dialog top control. Must be not <code>null</code>.
+ */
+ protected void configureDialogAreaControl(Composite composite) {
+ assert composite != null;
+ Layout layout = composite.getLayout();
+ if (layout == null || layout instanceof GridLayout) {
+ composite.setLayout(new GridLayout());
+ }
+ }
+
+ /**
+ * Cleanup when dialog is closed.
+ */
+ protected void dispose() {
+ fDialogSettings = null;
+ }
+
+ /**
+ * Cleanup the Dialog and close it.
+ */
+ @Override
+ public boolean close() {
+ dispose();
+ return super.close();
+ }
+
+ /**
+ * Sets the title for this dialog.
+ *
+ * @param title The title.
+ */
+ public void setDialogTitle(String title) {
+ if (getShell() != null && !getShell().isDisposed()) {
+ getShell().setText(title);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/forms/CustomFormToolkit.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/forms/CustomFormToolkit.java
new file mode 100644
index 000000000..5cb96b578
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/forms/CustomFormToolkit.java
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.forms;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.events.IExpansionListener;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * Target Explorer: Custom form toolkit for using form elements within
+ * dialog and wizard pages, or other containers.
+ */
+public class CustomFormToolkit extends PlatformObject {
+ // The reference of the wrapped toolkit
+ private final FormToolkit fToolkit;
+
+ /**
+ * Constructor.
+ *
+ * @param toolkit The {@link FormToolkit} instance to wrap. Must not be <code>null</code>.
+ */
+ public CustomFormToolkit(FormToolkit toolkit) {
+ super();
+ assert toolkit != null;
+ fToolkit = toolkit;
+ }
+
+ /**
+ * Returns the wrapped {@link FormToolkit} instance.
+ *
+ * @return The wrapped {@link FormToolkit} instance.
+ */
+ public final FormToolkit getFormToolkit() {
+ return fToolkit;
+ }
+
+ /**
+ * Dispose the form toolkit wrapper.
+ */
+ public void dispose() {
+ fToolkit.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
+ */
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Class adapter) {
+ if (FormToolkit.class.isAssignableFrom(adapter))
+ return getFormToolkit();
+
+ return super.getAdapter(adapter);
+ }
+
+ /**
+ * Returns the number of pixels corresponding to the height of the given
+ * number of characters.
+ * <p>
+ * This methods uses the static {@link Dialog#convertHeightInCharsToPixels(org.eclipse.swt.graphics.FontMetrics, int)}
+ * method for calculation.
+ * <p>
+ * @param chars The number of characters
+ * @return The corresponding height in pixels
+ */
+ protected int convertHeightInCharsToPixels(Control control, int chars) {
+ int height = 0;
+ if (control != null && !control.isDisposed()) {
+ GC gc = new GC(control);
+ gc.setFont(JFaceResources.getDialogFont());
+ height = Dialog.convertHeightInCharsToPixels(gc.getFontMetrics(), chars);
+ gc.dispose();
+ }
+
+ return height;
+ }
+
+ /**
+ * Creates a new scrollable form container within the given parent. If
+ * <code>overwriteBackground</code> is set, the parent background color
+ * and background image is applied to the created scrollable form.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @param title The form title or <code>null</code> if none.
+ * @param overwriteBackground If <code>true</code>, the parent background color and image are applied to the scrollable form.
+ *
+ * @return The scrollable form instance.
+ */
+ public ScrolledForm createScrolledForm(Composite parent, String title, boolean overwriteBackground) {
+ assert parent != null;
+
+ // Create the scrolled form which is the scrollable container for the expandable composite
+ final ScrolledForm scrollableForm = getFormToolkit().createScrolledForm(parent);
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ scrollableForm.setBackground(parent.getBackground());
+ scrollableForm.setBackgroundImage(parent.getBackgroundImage());
+ }
+
+ // If a title is given, set and decorate the header
+ if (title != null && scrollableForm.getForm() != null) {
+ scrollableForm.getForm().setText(title);
+ getFormToolkit().decorateFormHeading(scrollableForm.getForm());
+ }
+
+ return scrollableForm;
+ }
+
+ /**
+ * Creates an expandable composite within the given parent scrollable form using the given title.
+ * If <code>overwriteBackground</code> is set, the parent background color and background image
+ * is applied to the created expandable composite.
+ *
+ * @param scrolledForm The parent scrolled form. Must not be <code>null</code>.
+ * @param title The expandable composite title. Must not be <code>null</code>.
+ * @param entriesToShow The number of entries to show within the expanded area. Must be greater than 0.
+ * @param expanded The initial expanded state of the expandable composite.
+ * @param overwriteBackground If <code>true</code>, the parent background color and image are applied to the expandable composite.
+ *
+ * @return The expandable composite.
+ */
+ public final ExpandableComposite createExpandableComposite(final ScrolledForm scrolledForm,
+ String title, final int entriesToShow,
+ boolean expanded, boolean overwriteBackground) {
+ assert scrolledForm != null && title != null && entriesToShow > 0;
+
+ // Create the expandable composite within the scrollable container
+ final ExpandableComposite expandable = getFormToolkit().createExpandableComposite(scrolledForm.getBody(), ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
+ expandable.setText(title);
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ expandable.setBackground(scrolledForm.getBackground());
+ expandable.setBackgroundImage(scrolledForm.getBackgroundImage());
+ }
+
+ expandable.setLayout(new GridLayout());
+ expandable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create an associate an expansion listener to the expandable form
+ expandable.addExpansionListener(new IExpansionListener() {
+ boolean notExpanded = true;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanged(org.eclipse.ui.forms.events.ExpansionEvent)
+ */
+ public void expansionStateChanged(ExpansionEvent e) {
+ // Always set the scrolled form to re-flow. Otherwise it wouldn't
+ // re-arrange the controls following this expandable composite on
+ // collapse.
+ scrolledForm.reflow(true);
+
+ // Get the shell from the scrolled form.
+ Shell shell = scrolledForm.getShell();
+ if (shell != null && !shell.isDisposed() && e.getState() && notExpanded) {
+ // And recalculate the bounds on expand
+ shell.setRedraw(false);
+ Rectangle shellBounds = shell.getBounds();
+
+ // Assume at minimum 4 controls within the expandable area.
+ shellBounds.height += convertHeightInCharsToPixels(expandable, Math.max(4, entriesToShow)) + IDialogConstants.VERTICAL_SPACING;
+
+ shell.setBounds(shellBounds);
+ shell.setRedraw(true);
+ notExpanded = false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanging(org.eclipse.ui.forms.events.ExpansionEvent)
+ */
+ public void expansionStateChanging(ExpansionEvent e) {
+ }
+ });
+
+ // Create the client area the caller can use as parent for the control
+ Composite client = getFormToolkit().createComposite(expandable);
+ client.setLayout(new GridLayout());
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ client.setBackground(scrolledForm.getBackground());
+ client.setBackgroundImage(scrolledForm.getBackgroundImage());
+ }
+
+ // Set the initial expansion state
+ expandable.setExpanded(expanded);
+ // And associated the client
+ expandable.setClient(client);
+
+ return expandable;
+ }
+
+ /**
+ * Creates an expandable section within the given parent scrollable form using the given title.
+ * If <code>overwriteBackground</code> is set, the parent background color and background image
+ * is applied to the created section.
+ *
+ * @param parent The parent scrolled form. Must not be <code>null</code>.
+ * @param title The expandable composite title. Must not be <code>null</code>.
+ * @param entriesToShow The number of entries to show within the expanded area. Must be greater than 0.
+ * @param expanded The initial expanded state of the section.
+ * @param overwriteBackground If <code>true</code>, the parent background color and image are applied to the section.
+ *
+ * @return The section.
+ */
+ public final Section createSection(final ScrolledForm scrolledForm,
+ String title, final int entriesToShow,
+ boolean expanded, boolean overwriteBackground) {
+ assert scrolledForm != null && title != null && entriesToShow > 0;
+
+ // Create the section within the scrollable container
+ final Section section = getFormToolkit().createSection(scrolledForm.getBody(), ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
+ section.setText(title);
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ section.setBackground(scrolledForm.getBackground());
+ section.setBackgroundImage(scrolledForm.getBackgroundImage());
+ }
+
+ section.setLayout(new GridLayout());
+ section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create an associate an expansion listener to the expandable form
+ section.addExpansionListener(new IExpansionListener() {
+ boolean notExpanded = true;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanged(org.eclipse.ui.forms.events.ExpansionEvent)
+ */
+ public void expansionStateChanged(ExpansionEvent e) {
+ // Always set the scrolled form to re-flow. Otherwise it wouldn't
+ // re-arrange the controls following this expandable composite on
+ // collapse.
+ scrolledForm.reflow(true);
+
+ // Get the shell from the scrolled form.
+ Shell shell = scrolledForm.getShell();
+ if (shell != null && !shell.isDisposed() && e.getState() && notExpanded) {
+ // And recalculate the bounds on expand
+ shell.setRedraw(false);
+ Rectangle shellBounds = shell.getBounds();
+
+ // Assume at minimum 4 controls within the expandable area.
+ shellBounds.height += convertHeightInCharsToPixels(section, Math.max(4, entriesToShow)) + IDialogConstants.VERTICAL_SPACING;
+
+ shell.setBounds(shellBounds);
+ shell.setRedraw(true);
+ notExpanded = false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanging(org.eclipse.ui.forms.events.ExpansionEvent)
+ */
+ public void expansionStateChanging(ExpansionEvent e) {
+ }
+ });
+
+ // Create the client area the caller can use as parent for the control
+ Composite client = getFormToolkit().createComposite(section);
+ client.setLayout(new GridLayout());
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ client.setBackground(scrolledForm.getBackground());
+ client.setBackgroundImage(scrolledForm.getBackgroundImage());
+ }
+
+ // Set the initial expansion state
+ section.setExpanded(expanded);
+ // And associated the client
+ section.setClient(client);
+
+ return section;
+ }
+
+ /**
+ * Creates an non-expandable section within the given parent scrollable form using the given title.
+ * If <code>overwriteBackground</code> is set, the parent background color and background image
+ * is applied to the created section.
+ *
+ * @param parent The parent scrolled form. Must not be <code>null</code>.
+ * @param title The expandable composite title. Must not be <code>null</code>.
+ * @param overwriteBackground If <code>true</code>, the parent background color and image are applied to the section.
+ *
+ * @return The section.
+ */
+ public final Section createSection(final ScrolledForm scrolledForm, String title, boolean overwriteBackground) {
+ assert scrolledForm != null && title != null;
+
+ // Create the section within the scrollable container
+ final Section section = getFormToolkit().createSection(scrolledForm.getBody(), ExpandableComposite.TITLE_BAR | ExpandableComposite.CLIENT_INDENT);
+ section.setText(title);
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ section.setBackground(scrolledForm.getBackground());
+ section.setBackgroundImage(scrolledForm.getBackgroundImage());
+ }
+
+ // Configure the layout
+ section.setLayout(new GridLayout());
+ section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create the client area the caller can use as parent for the control
+ Composite client = getFormToolkit().createComposite(section);
+ client.setLayout(new GridLayout());
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ client.setBackground(section.getBackground());
+ client.setBackgroundImage(section.getBackgroundImage());
+ }
+
+ // And associated the client
+ section.setClient(client);
+
+ return section;
+ }
+
+ /**
+ * Creates a composite with a highlighted note entry and a message text.
+ * This is designed to take up the full width of the page.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @param title The note title. Must not be <code>null</code>.
+ * @param message The note message Must not be <code>null</code>.
+ * @param widthHint The note message width hint in pixel or <code>SWT.DEFAULT</code>.
+ * @param overwriteBackground If <code>true</code>, the parent background color and image are applied to the note composite.
+ *
+ * @return The note composite.
+ */
+ public final Composite createNoteComposite(Composite parent, String title, String message, int widthHint, boolean overwriteBackground) {
+ assert parent != null && title != null && message != null;
+
+ Composite composite = getFormToolkit().createComposite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginHeight = 0; layout.marginWidth = 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ composite.setFont(parent.getFont());
+
+ Label noteLabel = getFormToolkit().createLabel(composite, title, SWT.BOLD);
+ noteLabel.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
+ noteLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+
+ Label messageLabel = getFormToolkit().createLabel(composite, message);
+ GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
+ layoutData.widthHint = widthHint;
+ messageLabel.setLayoutData(layoutData);
+ messageLabel.setFont(parent.getFont());
+
+ // Overwrite background color and image if requested
+ if (overwriteBackground) {
+ composite.setBackground(parent.getBackground());
+ composite.setBackgroundImage(parent.getBackgroundImage());
+
+ noteLabel.setBackground(parent.getBackground());
+ noteLabel.setBackgroundImage(parent.getBackgroundImage());
+
+ messageLabel.setBackground(parent.getBackground());
+ messageLabel.setBackgroundImage(parent.getBackgroundImage());
+ }
+
+ return composite;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageDescriptor.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageDescriptor.java
new file mode 100644
index 000000000..626617b0a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageDescriptor.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.images;
+
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Target Explorer: Image descriptor for creating overlays.
+ */
+public abstract class AbstractImageDescriptor extends CompositeImageDescriptor {
+
+ private String fKey;
+ private ImageRegistry fRegistry;
+
+ public AbstractImageDescriptor(ImageRegistry reg) {
+ fRegistry = reg;
+ }
+
+ protected void setKey(String key) {
+ fKey = key;
+ }
+
+ public String getKey() {
+ return fKey;
+ }
+
+ protected ImageRegistry getRegistry() {
+ return fRegistry;
+ }
+
+ protected void drawCentered(String key, int width, int height) {
+ drawCentered(fRegistry.get(key), width, height);
+ }
+
+ protected void drawCentered(Image image, int width, int height) {
+ if (image != null) {
+ ImageData imageData = image.getImageData();
+ if (imageData != null) {
+ int x = StrictMath.max(0, (width - imageData.width + 1) / 2);
+ int y = StrictMath.max(0, (height - imageData.height + 1) / 2);
+ drawImage(imageData, x, y);
+ }
+ }
+ }
+
+ protected void drawCenterRight(String key, int width, int height) {
+ Image baseImage = fRegistry.get(key);
+ if (baseImage != null) {
+ ImageData imageData = baseImage.getImageData();
+ if (imageData != null) {
+ int x = StrictMath.max(0, width - imageData.width);
+ int y = StrictMath.max(0, (height - imageData.height + 1) / 2);
+ drawImage(imageData, x, y);
+ }
+ }
+ }
+
+ protected void drawTopLeft(String key) {
+ Image baseImage = fRegistry.get(key);
+ if (baseImage != null) {
+ ImageData imageData = baseImage.getImageData();
+ if (imageData != null) {
+ drawImage(imageData, 0, 0);
+ }
+ }
+ }
+
+ protected void drawTopRight(String key, int width, int height) {
+ Image baseImage = fRegistry.get(key);
+ if (baseImage != null) {
+ ImageData imageData = baseImage.getImageData();
+ if (imageData != null) {
+ int x = StrictMath.max(0, width - imageData.width);
+ drawImage(imageData, x, 0);
+ }
+ }
+ }
+
+ protected void drawBottomCenter(String key, int width, int height) {
+ Image image = fRegistry.get(key);
+ if (image != null) {
+ ImageData imageData = image.getImageData();
+ if (imageData != null) {
+ int x = StrictMath.max(0, (width - imageData.width + 1) / 2);
+ int y = StrictMath.max(0, height - imageData.height);
+ drawImage(imageData, x, y);
+ }
+ }
+ }
+
+ protected void drawBottomLeft(String key) {
+ if (getSize() != null) {
+ Point size = getSize();
+ drawBottomLeft(key, size.x, size.y);
+ } else {
+ // the default eclipse style guide recommendation is 16x16
+ drawBottomLeft(key, 16, 16);
+ }
+ }
+
+ protected void drawBottomLeft(String key, int width, int height) {
+ Image image = fRegistry.get(key);
+ if (image != null) {
+ ImageData imageData = image.getImageData();
+ if (imageData != null) {
+ int y = StrictMath.max(0, height - imageData.height);
+ drawImage(imageData, 0, y);
+ }
+ }
+ }
+
+ protected void drawCenterLeft(String key, int width, int height) {
+ Image image = fRegistry.get(key);
+ if (image != null) {
+ ImageData imageData = image.getImageData();
+ if (imageData != null) {
+ int y = StrictMath.max(0, (height - imageData.height) / 2);
+ drawImage(imageData, 0, y);
+ }
+ }
+ }
+
+ protected void drawBottomRight(String key) {
+ if (getSize() != null) {
+ Point size = getSize();
+ drawBottomRight(key, size.x, size.y);
+ } else {
+ // the default eclipse style guide recommendation is 16x16
+ drawBottomRight(key, 16, 16);
+ }
+ }
+
+ protected void drawBottomRight(String key, int width, int height) {
+ Image image = fRegistry.get(key);
+ if (image != null) {
+ ImageData imageData = image.getImageData();
+ if (imageData != null) {
+ int x = StrictMath.max(0, width - imageData.width);
+ int y = StrictMath.max(0, height - imageData.height);
+ drawImage(imageData, x, y);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.resource.CompositeImageDescriptor#getTransparentPixel()
+ */
+ @Override
+ protected int getTransparentPixel() {
+ Image baseImage = getBaseImage();
+ if (baseImage != null && baseImage.getImageData() != null) {
+ return baseImage.getImageData().transparentPixel;
+ }
+ return super.getTransparentPixel();
+ }
+
+ /**
+ * Returns the base image used for the combined image description. This
+ * method is called from <code>getTransparentPixel()</code> to query the
+ * transparent color of the palette.
+ *
+ * @return The base image or <code>null</code> if none.
+ */
+ protected abstract Image getBaseImage();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageRegistry.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageRegistry.java
new file mode 100644
index 000000000..849b7d875
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/images/AbstractImageRegistry.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.images;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.te.ui.activator.UIPlugin;
+import org.eclipse.tm.te.ui.nls.Messages;
+import org.osgi.framework.Bundle;
+
+
+
+/**
+ * Target Explorer: Abstract image registry that allows for defining fallback paths for images.
+ */
+public abstract class AbstractImageRegistry extends ImageRegistry {
+ private List<ImageRegistry> fDelegates = new ArrayList<ImageRegistry>();
+ private Map<String,String> fPlugins = new HashMap<String,String>();
+ private Map<String,String[]> fLocations = new HashMap<String,String[]>();
+ private URL fBaseUrl;
+
+ protected AbstractImageRegistry(Plugin plugin) {
+ fBaseUrl = plugin.getBundle().getEntry("/"); //$NON-NLS-1$
+ }
+
+ /**
+ * Adds the given image registry as delegate. Delegates are queried if
+ * an image or image descriptor cannot be found locally. If the image
+ * registry delegate had been added before, the method will do nothing.
+ *
+ * @param registry The image registry. Must be not <code>null</code>.
+ */
+ protected final void addImageRegistryDelegate(ImageRegistry registry) {
+ assert registry != null;
+ if (!fDelegates.contains(registry)) fDelegates.add(registry);
+ }
+
+ /**
+ * Removes the given image registry from the list of delegates.
+ *
+ * @param registry The image registry. Must be not <code>null</code>.
+ */
+ protected final void removeImageRegistryDelegate(ImageRegistry registry) {
+ assert registry != null;
+ fDelegates.remove(registry);
+ }
+
+ /**
+ * Defines the key for a local image, that must be found below the icons directory
+ * in the plugin.
+ * @param key Key by which the image can be referred by.
+ * @param dir Directory relative to icons/
+ * @param name The name of the file defining the icon. The name will be used as
+ * key.
+ */
+ protected void localImage(String key, String dir, String name) {
+ if (dir== null || dir.equals(""))//$NON-NLS-1$
+ fLocations.put(key, new String[] {"icons/" + name}); //$NON-NLS-1$
+ else
+ fLocations.put(key, new String[] {"icons/" + dir + "/" + name}); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * Defines the key for a non-local image, that must be found below the icons directory
+ * of some plugin.
+ * @param key Key by which the image can be referred by.
+ * @param plugin The plugin id, where the icon is searched.
+ * @param dirs A couple of directories below icons/ in the plugin. If loading fails,
+ * the next dir will be taken as fallback.
+ * @param name The name of the file defining the icon. The name will be used as
+ * key.
+ */
+ protected void externalImage(String key, String plugin, String[] dirs, String name) {
+ if (plugin != null) {
+ fPlugins.put(key, plugin);
+ }
+ String[] locations = new String[dirs.length];
+ for (int i = 0; i < dirs.length; i++) {
+ String dir = dirs[i];
+ if (dir== null || dir.equals(""))//$NON-NLS-1$
+ locations[i] = "icons/" + name; //$NON-NLS-1$
+ else
+ locations[i] = "icons/" + dir + "/" + name; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ fLocations.put(key, locations);
+ }
+
+ final private Image internalDoGet(String key) {
+ // First query the parent (local) image registry if
+ // an image for the given key is registered.
+ Image i = super.get(key);
+ if (i != null) return i;
+
+ // If no image had been returned, try the delegates
+ for (ImageRegistry delegate : fDelegates) {
+ i = delegate.get(key);
+ if (i != null) break;
+ }
+
+ return i;
+ }
+
+ final private ImageDescriptor internalDoGetDescriptor(String key) {
+ // First query the parent (local) image registry if
+ // an image for the given key is registered.
+ ImageDescriptor d = super.getDescriptor(key);
+ if (d != null) return d;
+
+ // If no image had been returned, try the delegates
+ for (ImageRegistry delegate : fDelegates) {
+ d = delegate.getDescriptor(key);
+ if (d != null) break;
+ }
+
+ return d;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.resource.ImageRegistry#get(java.lang.String)
+ */
+ @Override
+ final public Image get(String key) {
+ Image i = internalDoGet(key);
+ if (i != null) {
+ return i;
+ }
+
+ ImageDescriptor d = createFileImageDescriptor(key);
+ if (d != null) {
+ put(key, d);
+ return internalDoGet(key);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.resource.ImageRegistry#getDescriptor(java.lang.String)
+ */
+ @Override
+ final public ImageDescriptor getDescriptor(String key) {
+ ImageDescriptor d = internalDoGetDescriptor(key);
+ if (d != null) {
+ return d;
+ }
+
+ d = createFileImageDescriptor(key);
+ if (d != null) {
+ put(key, d);
+ return d;
+ }
+ return null;
+ }
+
+ private ImageDescriptor createFileImageDescriptor(String key) {
+ URL url = fBaseUrl;
+ String pluginId = fPlugins.get(key);
+ if (pluginId != null) {
+ Bundle bundle= Platform.getBundle(pluginId);
+ if (bundle != null) {
+ url = bundle.getEntry("/"); //$NON-NLS-1$
+ }
+ }
+ String[] locations= fLocations.get(key);
+ if (locations != null) {
+ for (int i = 0; i < locations.length; i++) {
+ String loc = locations[i];
+ URL full;
+ try {
+ full = new URL(url, loc);
+ ImageDescriptor candidate = ImageDescriptor.createFromURL(full);
+ if (candidate != null && candidate.getImageData() != null) {
+ return candidate;
+ }
+ } catch (MalformedURLException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
+ Messages.AbstractImageRegistry_error_malformedImage, e);
+ UIPlugin.getDefault().getLog().log(status);
+ } catch (SWTException e) {
+ // try the next one.
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get a shared Image for a given descriptor
+ */
+ public Image getSharedImage(AbstractImageDescriptor d) {
+ String key = d.getKey();
+ Image shared = super.get(key);
+ if (shared != null) {
+ return shared;
+ }
+ put(key, d);
+ return super.get(key);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java
new file mode 100644
index 000000000..3ff613ac9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/interfaces/IUIConstants.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.interfaces;
+
+import org.eclipse.tm.te.ui.activator.UIPlugin;
+
+/**
+ * Target Explorer: Common UI constants.
+ *
+ * @author uwe.stieber@windriver.com
+ */
+public interface IUIConstants {
+
+ /**
+ * The Target Explorer common controls context menu id base part.
+ */
+ public static final String ID_CONTROL_MENUS_BASE = UIPlugin.getUniqueIdentifier() + ".controls"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.java
new file mode 100644
index 000000000..297235b6b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer: Common UI plugin externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.ui.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String AbstractImageRegistry_error_malformedImage;
+
+ public static String NodePropertiesTableControl_section_title;
+ public static String NodePropertiesTableControl_section_title_noSelection;
+ public static String NodePropertiesTableControl_column_name_label;
+ public static String NodePropertiesTableControl_column_value_label;
+
+ public static String PendingOperation_label;
+
+ public static String EditBrowseTextControl_button_label;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.properties
new file mode 100644
index 000000000..b943bab0c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nls/Messages.properties
@@ -0,0 +1,15 @@
+#
+# org.eclipse.tm.te.ui
+# Externalized Strings.
+#
+
+AbstractImageRegistry_error_malformedImage=Malformed Image
+
+NodePropertiesTableControl_section_title={0} Information
+NodePropertiesTableControl_section_title_noSelection=Node
+NodePropertiesTableControl_column_name_label=Property
+NodePropertiesTableControl_column_value_label=Value
+
+PendingOperation_label=Pending...
+
+EditBrowseTextControl_button_label=Browse...
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nodes/PendingOperation.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nodes/PendingOperation.java
new file mode 100644
index 000000000..1859001c6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/nodes/PendingOperation.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.nodes;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.te.ui.nls.Messages;
+
+
+/**
+ * Target Explorer: Pending operation data node.
+ */
+public class PendingOperation extends PlatformObject {
+
+ /**
+ * Returns the pending operation node name.
+ *
+ * @return The node name.
+ */
+ public final String getName() {
+ return Messages.PendingOperation_label;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public final int hashCode() {
+ return getName().hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public final String toString() {
+ return getName();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableNode.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableNode.java
new file mode 100644
index 000000000..e4daa98c9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableNode.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.tables;
+
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ * Target Explorer: Immutable representation of a table node.
+ */
+public final class TableNode extends PlatformObject {
+ /**
+ * The node name.
+ */
+ public final String name;
+
+ /**
+ * The node value.
+ */
+ public final String value;
+
+ /**
+ * Constructor.
+ *
+ * @param name The node name. Must be not <code>null</code>.
+ * @param value The node value. Must be not <code>null</code>.
+ */
+ public TableNode(String name, String value) {
+ assert name != null && value != null;
+ this.name = name;
+ this.value = value;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableViewerComparator.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableViewerComparator.java
new file mode 100644
index 000000000..c00691b66
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/TableViewerComparator.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.tables;
+
+import java.util.Arrays;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.tm.te.ui.AbstractViewerComparator;
+
+
+/**
+ * Target Explorer: Common table control viewer comparator implementation.
+ */
+public class TableViewerComparator extends AbstractViewerComparator {
+ private final ITableLabelProvider fLabelProvider;
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The parent viewer. Must be not <code>null</code>.
+ * @param labelProvider The table label provider. Must be not <code>null</code>.
+ */
+ public TableViewerComparator(Viewer viewer, ITableLabelProvider labelProvider) {
+ super(viewer);
+ assert labelProvider != null;
+ fLabelProvider = labelProvider;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doDetermineInverter(org.eclipse.jface.viewers.Viewer)
+ */
+ @Override
+ protected int doDetermineInverter(Viewer viewer) {
+ int inverter = 1;
+
+ // Viewer must be of type TableViewer and the table must not be disposed yet
+ if (viewer instanceof TableViewer && ((TableViewer)viewer).getTable() != null) {
+ Table table = ((TableViewer)viewer).getTable();
+ if (!table.isDisposed() && table.getSortDirection() == SWT.DOWN) inverter = -1;
+ }
+
+ return inverter;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doGetText(java.lang.Object, int)
+ */
+ @Override
+ protected String doGetText(Object node, int index) {
+ if (node != null && fLabelProvider != null) {
+ return index != -1 ? fLabelProvider.getColumnText(node, index) : ((ILabelProvider)fLabelProvider).getText(node);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doGetSortColumnLabel(org.eclipse.jface.viewers.Viewer)
+ */
+ @Override
+ protected String doGetSortColumnLabel(Viewer viewer) {
+ // Viewer must be of type TableViewer and the table must not be disposed yet
+ if (viewer instanceof TableViewer && ((TableViewer)viewer).getTable() != null && !((TableViewer)viewer).getTable().isDisposed()) {
+ Table table = ((TableViewer)viewer).getTable();
+ return table.getSortColumn() != null ? table.getSortColumn().getText() : ""; //$NON-NLS-1$
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doGetSortColumnIndex(org.eclipse.jface.viewers.Viewer)
+ */
+ @Override
+ protected int doGetSortColumnIndex(Viewer viewer) {
+ // Viewer must be of type TableViewer and the table must not be disposed yet
+ if (viewer instanceof TableViewer && ((TableViewer)viewer).getTable() != null && !((TableViewer)viewer).getTable().isDisposed()) {
+ Table table = ((TableViewer)viewer).getTable();
+ return table.getSortColumn() != null ? Arrays.asList(table.getColumns()).indexOf(table.getSortColumn()) : -1;
+ }
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doCompare(java.lang.Object, java.lang.Object, java.lang.String, int, int)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected int doCompare(Object node1, Object node2, String sortColumn, int index, int inverter) {
+ if (node1 == null && node2 == null) return 0;
+ if (node1 != null && node2 == null) return 1;
+ if (node1 == null && node2 != null) return -1;
+
+ // Get the labels
+ String text1 = doGetText(node1, index);
+ String text2 = doGetText(node2, index);
+
+ // If the text is matching ".*[0-9]+$" -> compare numerical instead of alphabetical
+ if (text1 != null && text1.matches(".*[0-9]+$") && text2 != null && text2.matches(".*[0-9]+$")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // Split numbers and text (note that this effectively removes the number ... splitted[1] == "").
+ String[] splitted1 = text1.split("[0-9]+$", 2); //$NON-NLS-1$
+ String[] splitted2 = text2.split("[0-9]+$", 2); //$NON-NLS-1$
+
+ // Get the parts to match alphabetical
+ String alpha1 = splitted1[0];
+ String alpha2 = splitted2[0];
+
+ // The numerical parts is what remains if we strip the alpha parts from the original text
+ String num1 = text1.replace(alpha1, ""); //$NON-NLS-1$
+ String num2 = text2.replace(alpha2, ""); //$NON-NLS-1$
+
+ // Compare the alpha parts
+ int result = getComparator().compare(alpha1, alpha2) * inverter;
+ // Only if the alpha parts are equal, compare the numerical parts too
+ if (result == 0) {
+ result = Integer.decode(num1).compareTo(Integer.decode(num2)) * inverter;
+ }
+
+ return result;
+ }
+
+ // Compare the text alphabetical
+ return getComparator().compare(text1, text2) * inverter;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/properties/NodePropertiesTableControl.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/properties/NodePropertiesTableControl.java
new file mode 100644
index 000000000..4fe2f3d68
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/tables/properties/NodePropertiesTableControl.java
@@ -0,0 +1,417 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.tables.properties;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.tm.te.ui.WorkbenchPartControl;
+import org.eclipse.tm.te.ui.forms.CustomFormToolkit;
+import org.eclipse.tm.te.ui.interfaces.IUIConstants;
+import org.eclipse.tm.te.ui.nls.Messages;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.forms.widgets.Section;
+
+
+/**
+ * Target Explorer: Abstract node properties table control implementation.
+ */
+public abstract class NodePropertiesTableControl extends WorkbenchPartControl {
+ // Reference to the table viewer
+ private TableViewer fViewer;
+ // Reference to the selection changed listener
+ private ISelectionChangedListener fEditorSelectionChangedListener;
+
+ // We remember the sorting order (ascending vs. descending) for each
+ // column separately. That way we can come up with the sort order switching
+ // correctly if the user changes from one column to the next. If set
+ // to Boolean.FALSE, the sort order for the column is descending (default)
+ private final Map<TableColumn, Boolean> fColumnSortOrder = new LinkedHashMap<TableColumn, Boolean>();
+
+ /**
+ * Default node properties table control selection changed listener implementation.
+ * The selection changed listener is registered to the editor tree control.
+ */
+ protected class NodePropertiesTableControlSelectionChangedListener implements ISelectionChangedListener {
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (getViewer() != null) {
+ getViewer().setInput(event.getSelection());
+ }
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPart The parent workbench part this control is embedded in or <code>null</code>.
+ */
+ public NodePropertiesTableControl(IWorkbenchPart parentPart) {
+ super(parentPart);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.WorkbenchPartControl#dispose()
+ */
+ @Override
+ public void dispose() {
+ // Dispose the editor tree control selection changed listener
+ if (fEditorSelectionChangedListener != null) {
+ ISelectionProvider selectionProvider = (ISelectionProvider)getParentPart().getAdapter(ISelectionProvider.class);
+ if (selectionProvider != null) {
+ selectionProvider.removeSelectionChangedListener(fEditorSelectionChangedListener);
+ fEditorSelectionChangedListener = null;
+ }
+ }
+
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.WorkbenchPartControl#setupFormPanel(org.eclipse.swt.widgets.Composite, org.eclipse.tm.te.ui.forms.CustomFormToolkit)
+ */
+ @Override
+ public void setupFormPanel(Composite parent, CustomFormToolkit toolkit) {
+ super.setupFormPanel(parent, toolkit);
+
+ // Create the table viewer
+ fViewer = doCreateTableViewer(parent);
+ // Configure the table viewer
+ configureTableViewer(fViewer);
+ // Configure the table
+ configureTable(fViewer.getTable(), fViewer.getComparator() != null);
+
+ // Register the control as selection listener to the editor control
+ ISelectionProvider selectionProvider = getParentPart() != null ? (ISelectionProvider)getParentPart().getAdapter(ISelectionProvider.class) : null;
+ if (selectionProvider != null) {
+ // Create the selection changed listener instance
+ fEditorSelectionChangedListener = doCreateEditorSelectionChangedListener();
+ selectionProvider.addSelectionChangedListener(fEditorSelectionChangedListener);
+ }
+
+ // Prepare popup menu and toolbar
+ createContributionItems(fViewer);
+
+ // Set the current selection as input
+ fViewer.setInput(selectionProvider != null ? selectionProvider.getSelection() : null);
+ }
+
+ /**
+ * Creates a new editor tree control selection changed listener instance.
+ *
+ * @return The editor tree control selection changed listener instance.
+ */
+ protected ISelectionChangedListener doCreateEditorSelectionChangedListener() {
+ return new NodePropertiesTableControlSelectionChangedListener();
+ }
+
+ /**
+ * Creates the table viewer instance.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @return The table viewer.
+ */
+ protected TableViewer doCreateTableViewer(Composite parent) {
+ assert parent != null;
+
+ TableViewer tableViewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER);
+
+ return tableViewer;
+ }
+
+ /**
+ * Configure the table Viewer.
+ *
+ * @param tableViewer The table viewer. Must not be <code>null</code>.
+ */
+ protected void configureTableViewer(TableViewer tableViewer) {
+ assert tableViewer != null;
+
+ tableViewer.setLabelProvider(doCreateTableViewerLabelProvider(tableViewer));
+ tableViewer.setContentProvider(doCreateTableViewerContentProvider(tableViewer));
+ tableViewer.setComparator(doCreateTableViewerComparator(tableViewer));
+ }
+
+ /**
+ * Creates the table viewer label provider instance.
+ *
+ * @param viewer The table viewer. Must be not <code>null</code>.
+ * @return The table viewer label provider instance.
+ */
+ protected abstract ITableLabelProvider doCreateTableViewerLabelProvider(TableViewer viewer);
+
+ /**
+ * Creates the table viewer content provider instance.
+ *
+ * @param viewer The table viewer. Must be not <code>null</code>.
+ * @return The table viewer content provider instance.
+ */
+ protected abstract IStructuredContentProvider doCreateTableViewerContentProvider(TableViewer viewer);
+
+ /**
+ * Creates the table viewer comparator instance.
+ *
+ * @param viewer The table viewer. Must be not <code>null</code>.
+ * @return The table viewer comparator instance or <code>null</code> to turn of sorting.
+ */
+ protected ViewerComparator doCreateTableViewerComparator(TableViewer viewer) {
+ return null;
+ }
+
+ /**
+ * Configure the table.
+ *
+ * @param table The table. Must not be <code>null</code>.
+ * @param sorted Specify <code>true</code> if the table shall support sorting, <code>false</code> otherwise.
+ */
+ protected void configureTable(Table table, boolean sorted) {
+ assert table != null;
+
+ // Create and configure the table columns
+ createTableColumns(table, sorted);
+
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ }
+
+ /**
+ * Create the table columns.
+ *
+ * @param table The table. Must not be <code>null</code>.
+ * @param sorted Specify <code>true</code> if the table shall support sorting, <code>false</code> otherwise.
+ */
+ protected void createTableColumns(final Table table, boolean sorted) {
+ assert table != null;
+
+ TableColumn sortColumn = null;
+
+ TableColumn column = new TableColumn(table, SWT.LEFT);
+ column.setText(Messages.NodePropertiesTableControl_column_name_label);
+ fColumnSortOrder.put(column, Boolean.TRUE);
+ if (sorted) column.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget instanceof TableColumn) {
+ switchSortColumn(table, (TableColumn)e.widget);
+ }
+ }
+ });
+ // The property name is the default sorting column
+ sortColumn = column;
+
+ column = new TableColumn(table, SWT.LEFT);
+ column.setText(Messages.NodePropertiesTableControl_column_value_label);
+ fColumnSortOrder.put(column, Boolean.FALSE);
+ if (sorted) column.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget instanceof TableColumn) {
+ switchSortColumn(table, (TableColumn)e.widget);
+ }
+ }
+ });
+
+ TableLayout tableLayout = new TableLayout();
+ tableLayout.addColumnData(new ColumnWeightData(30));
+ tableLayout.addColumnData(new ColumnWeightData(70));
+ table.setLayout(tableLayout);
+
+ GridData layoutData = new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_BEGINNING);
+ table.setLayoutData(layoutData);
+
+ if (sorted) {
+ // set the default sort column
+ table.setSortColumn(sortColumn);
+ table.setSortDirection(fColumnSortOrder.get(sortColumn).booleanValue() ? SWT.UP : SWT.DOWN);
+ }
+ }
+
+ /**
+ * Switches the sort order for the given column and set the
+ * new sort order and sort column to the given table.
+ *
+ * @param table The table.
+ * @param column The table column
+ */
+ protected final void switchSortColumn(Table table, TableColumn column) {
+ if (table == null || table.isDisposed() || column == null || column.isDisposed()) {
+ return;
+ }
+ // Get the current sorting order for the given column
+ boolean newSortOrder = !fColumnSortOrder.get(column).booleanValue();
+ // Set sort column and sort direction
+ table.setSortColumn(column);
+ table.setSortDirection(newSortOrder ? SWT.UP : SWT.DOWN);
+ // And update the remembered sort order in the map
+ fColumnSortOrder.put(column, Boolean.valueOf(newSortOrder));
+
+ getViewer().refresh();
+ }
+
+ /**
+ * Create the context menu and toolbar groups.
+ *
+ * @param viewer The table viewer. Must not be <code>null</code>.
+ */
+ protected void createContributionItems(TableViewer viewer) {
+ assert viewer != null;
+
+ // Create the menu manager
+ MenuManager manager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ // Attach the menu listener
+ manager.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+ // All items are removed when menu is closing
+ manager.setRemoveAllWhenShown(true);
+ // Associated with the tree
+ viewer.getTable().setMenu(manager.createContextMenu(viewer.getTable()));
+
+ // Register the context menu at the parent workbench part site.
+ if (getParentPart() != null && getParentPart().getSite() != null && getContextMenuId() != null) {
+ IWorkbenchPartSite site = getParentPart().getSite();
+ site.registerContextMenu(getContextMenuId(), manager, viewer);
+ }
+
+ // The toolbar is a bit more complicated as we want to have the
+ // toolbar placed within the section title.
+ createToolbarContributionItem(viewer);
+ }
+
+ /**
+ * Returns the controls context menu id.
+ *
+ * @return The context menu id or <code>null</code>.
+ */
+ protected String getContextMenuId() {
+ return IUIConstants.ID_CONTROL_MENUS_BASE + ".menu.propertiesTable"; //$NON-NLS-1$
+ }
+
+ /**
+ * Creates the toolbar within the section parent of the given filtered tree.
+ *
+ * @param viewer The table viewer. Must not be <code>null</code>.
+ */
+ protected void createToolbarContributionItem(TableViewer viewer) {
+ assert viewer != null;
+
+ // Determine the section parent from the filtered tree
+ Composite parent = viewer.getTable().getParent();
+ while (parent != null && !(parent instanceof Section)) {
+ parent = parent.getParent();
+ }
+
+ // We are done here if we cannot find a section parent or the parent is disposed
+ if (parent == null || parent.isDisposed()) {
+ return;
+ }
+
+ // Create the toolbar control
+ ToolBar toolbar = new ToolBar(parent, SWT.FLAT | SWT.HORIZONTAL | SWT.RIGHT);
+
+ // The cursor within the toolbar shall change to an hand
+ final Cursor handCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+ toolbar.setCursor(handCursor);
+ // Cursor needs to be explicitly disposed
+ toolbar.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ if ((handCursor != null) && (handCursor.isDisposed() == false)) {
+ handCursor.dispose();
+ }
+ }
+ });
+
+ // If the parent composite is a forms section, set the toolbar
+ // as text client to the section header
+ if (parent instanceof Section) {
+ Section section = (Section)parent;
+ // Set the toolbar as text client
+ section.setTextClient(toolbar);
+ }
+
+ // create the toolbar items
+ createToolBarItems(toolbar);
+ }
+
+ /**
+ * Create the toolbar items to be added to the toolbar. Override
+ * to add the wanted toolbar items.
+ * <p>
+ * <b>Note:</b> The toolbar items are added from left to right.
+ *
+ * @param toolbar The toolbar to add the toolbar items too. Must not be <code>null</code>.
+ */
+ protected void createToolBarItems(ToolBar toolbar) {
+ assert toolbar != null;
+ }
+
+ /**
+ * Returns the viewer instance.
+ *
+ * @return The viewer instance or <code>null</code>.
+ */
+ public Viewer getViewer() {
+ return fViewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Object getAdapter(Class adapter) {
+ if (Viewer.class.isAssignableFrom(adapter)) {
+ // We have to double check if our real viewer is assignable to
+ // the requested Viewer class.
+ Viewer viewer = getViewer();
+ if (!adapter.isAssignableFrom(viewer.getClass())) {
+ viewer = null;
+ }
+ return viewer;
+ } else if (ISelectionListener.class.isAssignableFrom(adapter)) {
+ return fEditorSelectionChangedListener;
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/AbstractTreeControl.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/AbstractTreeControl.java
new file mode 100644
index 000000000..e4ae46050
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/AbstractTreeControl.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.trees;
+
+
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.tm.te.ui.WorkbenchPartControl;
+import org.eclipse.tm.te.ui.forms.CustomFormToolkit;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.forms.widgets.Section;
+
+
+/**
+ * Target Explorer: Abstract tree control implementation.
+ */
+public abstract class AbstractTreeControl extends WorkbenchPartControl {
+ // Reference to the tree viewer instance
+ private TreeViewer fViewer;
+ // Reference to the selection changed listener
+ private ISelectionChangedListener fSelectionChangedListener;
+
+ /**
+ * Constructor.
+ */
+ public AbstractTreeControl() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPart The parent workbench part this control is embedded in or <code>null</code>.
+ */
+ public AbstractTreeControl(IWorkbenchPart parentPart) {
+ super(parentPart);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.WorkbenchPartControl#dispose()
+ */
+ @Override
+ public void dispose() {
+ // Unregister the selection changed listener
+ if (fSelectionChangedListener != null) {
+ if (getViewer() != null) {
+ getViewer().removeSelectionChangedListener(fSelectionChangedListener);
+ }
+ fSelectionChangedListener = null;
+ }
+
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.WorkbenchPartControl#setupFormPanel(org.eclipse.swt.widgets.Composite, org.eclipse.tm.te.ui.forms.CustomFormToolkit)
+ */
+ @Override
+ public void setupFormPanel(Composite parent, CustomFormToolkit toolkit) {
+ super.setupFormPanel(parent, toolkit);
+
+ // Create the tree viewer
+ fViewer = doCreateTreeViewer(parent);
+ // And configure the tree viewer
+ configureTreeViewer(fViewer);
+
+ // Prepare popup menu and toolbar
+ createContributionItems(fViewer);
+ }
+
+ /**
+ * Creates the tree viewer instance.
+ *
+ * @param parent The parent composite. Must be not <code>null</code>.
+ * @return The tree viewer.
+ */
+ protected TreeViewer doCreateTreeViewer(Composite parent) {
+ assert parent != null;
+ return new TreeViewer(parent, SWT.FULL_SELECTION | SWT.SINGLE);
+ }
+
+ /**
+ * Configure the tree viewer.
+ *
+ * @param viewer The tree viewer. Must be not <code>null</code>.
+ */
+ protected void configureTreeViewer(TreeViewer viewer) {
+ assert viewer != null;
+
+ viewer.setAutoExpandLevel(getAutoExpandLevel());
+
+ viewer.setLabelProvider(doCreateTreeViewerLabelProvider(viewer));
+ viewer.setContentProvider(doCreateTreeViewerContentProvider(viewer));
+ viewer.setComparator(doCreateTreeViewerComparator(viewer));
+
+ viewer.getTree().setLayoutData(doCreateTreeViewerLayoutData(viewer));
+
+ // Attach the selection changed listener
+ fSelectionChangedListener = doCreateTreeViewerSelectionChangedListener(viewer);
+ if (fSelectionChangedListener != null) {
+ viewer.addSelectionChangedListener(fSelectionChangedListener);
+ }
+ }
+
+ /**
+ * Returns the number of levels to auto expand.
+ * If the method returns <code>0</code>, no auto expansion will happen
+ *
+ * @return The number of levels to auto expand or <code>0</code>.
+ */
+ protected int getAutoExpandLevel() {
+ return 2;
+ }
+
+ /**
+ * Creates the tree viewer layout data instance.
+ *
+ * @param viewer The tree viewer. Must be not <code>null</code>.
+ * @return The tree viewer layout data instance.
+ */
+ protected Object doCreateTreeViewerLayoutData(TreeViewer viewer) {
+ return new GridData(GridData.FILL_BOTH);
+ }
+
+ /**
+ * Creates the tree viewer label provider instance.
+ *
+ * @param viewer The tree viewer. Must be not <code>null</code>.
+ * @return The tree viewer label provider instance.
+ */
+ protected abstract ILabelProvider doCreateTreeViewerLabelProvider(TreeViewer viewer);
+
+ /**
+ * Creates the tree viewer content provider instance.
+ *
+ * @param viewer The tree viewer. Must be not <code>null</code>.
+ * @return The tree viewer content provider instance.
+ */
+ protected abstract ITreeContentProvider doCreateTreeViewerContentProvider(TreeViewer viewer);
+
+ /**
+ * Creates the tree viewer comparator instance.
+ *
+ * @param viewer The tree viewer. Must be not <code>null</code>.
+ * @return The tree viewer comparator instance or <code>null</code> to turn of sorting.
+ */
+ protected ViewerComparator doCreateTreeViewerComparator(TreeViewer viewer) {
+ assert viewer != null;
+ return null;
+ }
+
+ /**
+ * Creates a new selection changed listener instance.
+ *
+ * @param viewer The tree viewer. Must be not <code>null</code>.
+ * @return The selection changed listener instance.
+ */
+ protected abstract ISelectionChangedListener doCreateTreeViewerSelectionChangedListener(TreeViewer viewer);
+
+ /**
+ * Create the context menu and toolbar groups.
+ *
+ * @param viewer The tree viewer instance. Must not be <code>null</code>.
+ */
+ protected void createContributionItems(TreeViewer viewer) {
+ assert viewer != null;
+
+ // Create the menu manager
+ MenuManager manager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ // Attach the menu listener
+ manager.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ }
+ });
+ // All items are removed when menu is closing
+ manager.setRemoveAllWhenShown(true);
+ // Associated with the tree
+ viewer.getTree().setMenu(manager.createContextMenu(viewer.getTree()));
+
+ // Register the context menu at the parent workbench part site.
+ if (getParentPart() != null && getParentPart().getSite() != null && getContextMenuId() != null) {
+ getParentPart().getSite().registerContextMenu(getContextMenuId(), manager, viewer);
+ }
+
+ // The toolbar is a bit more complicated as we want to have the
+ // toolbar placed within the section title.
+ createToolbarContributionItem(viewer);
+ }
+
+ /**
+ * Returns the context menu id.
+ *
+ * @return The context menu id.
+ */
+ protected abstract String getContextMenuId();
+
+ /**
+ * Creates the toolbar within the section parent of the given tree viewer.
+ *
+ * @param viewer The tree viewer instance. Must not be <code>null</code>.
+ */
+ protected void createToolbarContributionItem(TreeViewer viewer) {
+ assert viewer != null;
+
+ // Determine the section parent from the tree viewer
+ Composite parent = viewer.getTree().getParent();
+ while (parent != null && !(parent instanceof Section)) {
+ parent = parent.getParent();
+ }
+
+ // We are done here if we cannot find a section parent or the parent is disposed
+ if (parent == null || parent.isDisposed()) {
+ return;
+ }
+
+ // Create the toolbar control
+ ToolBar toolbar = new ToolBar(parent, SWT.FLAT | SWT.HORIZONTAL | SWT.RIGHT);
+
+ // The cursor within the toolbar shall change to an hand
+ final Cursor handCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
+ toolbar.setCursor(handCursor);
+ // Cursor needs to be explicitly disposed
+ toolbar.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ if ((handCursor != null) && (handCursor.isDisposed() == false)) {
+ handCursor.dispose();
+ }
+ }
+ });
+
+ // If the parent composite is a forms section, set the toolbar
+ // as text client to the section header
+ if (parent instanceof Section) {
+ Section section = (Section)parent;
+ // Set the toolbar as text client
+ section.setTextClient(toolbar);
+ }
+
+ // create the toolbar items
+ createToolBarItems(toolbar);
+ }
+
+ /**
+ * Create the toolbar items to be added to the toolbar. Override
+ * to add the wanted toolbar items.
+ * <p>
+ * <b>Note:</b> The toolbar items are added from left to right.
+ *
+ * @param toolbar The toolbar to add the toolbar items too. Must not be <code>null</code>.
+ */
+ protected void createToolBarItems(ToolBar toolbar) {
+ assert toolbar != null;
+ }
+
+ /**
+ * Returns the viewer instance.
+ *
+ * @return The viewer instance or <code>null</code>.
+ */
+ public Viewer getViewer() {
+ return fViewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Object getAdapter(Class adapter) {
+ if (Viewer.class.isAssignableFrom(adapter)) {
+ // We have to double check if our real viewer is assignable to
+ // the requested Viewer class.
+ Viewer viewer = getViewer();
+ if (!adapter.isAssignableFrom(viewer.getClass())) {
+ viewer = null;
+ }
+ return viewer;
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/TreeViewerComparator.java b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/TreeViewerComparator.java
new file mode 100644
index 000000000..b24a4b2af
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.ui/src/org/eclipse/tm/te/ui/trees/TreeViewerComparator.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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:
+ * Uwe Stieber (Wind River) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.te.ui.trees;
+
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.tm.te.ui.AbstractViewerComparator;
+
+
+/**
+ * Target Explorer: Common tree control viewer comparator implementation.
+ */
+public class TreeViewerComparator extends AbstractViewerComparator {
+ private final ILabelProvider fLabelProvider;
+
+ /**
+ * Constructor.
+ *
+ * @param viewer The parent viewer. Must be not <code>null</code>.
+ * @param labelProvider The label provider. Must be not <code>null</code>.
+ */
+ public TreeViewerComparator(Viewer viewer, ILabelProvider labelProvider) {
+ super(viewer);
+ assert labelProvider != null;
+ fLabelProvider = labelProvider;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doDetermineInverter(org.eclipse.jface.viewers.Viewer)
+ */
+ @Override
+ protected int doDetermineInverter(Viewer viewer) {
+ int inverter = 1;
+
+ // Viewer must be of type TreeViewer and the tree must not be disposed yet
+ if (viewer instanceof TreeViewer && ((TreeViewer)viewer).getTree() != null) {
+ Tree tree = ((TreeViewer)viewer).getTree();
+ if (!tree.isDisposed() && tree.getSortDirection() == SWT.DOWN) inverter = -1;
+ }
+
+ return inverter;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doGetText(java.lang.Object, int)
+ */
+ @Override
+ protected String doGetText(Object node, int index) {
+ if (node != null && fLabelProvider != null) {
+ return fLabelProvider.getText(node);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doGetSortColumnLabel(org.eclipse.jface.viewers.Viewer)
+ */
+ @Override
+ protected String doGetSortColumnLabel(Viewer viewer) {
+ // Viewer must be of type TreeViewer and the tree must not be disposed yet
+ if (viewer instanceof TreeViewer && ((TreeViewer)viewer).getTree() != null && !((TreeViewer)viewer).getTree().isDisposed()) {
+ Tree tree = ((TreeViewer)viewer).getTree();
+ return tree.getSortColumn() != null ? tree.getSortColumn().getText() : ""; //$NON-NLS-1$
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doGetSortColumnIndex(org.eclipse.jface.viewers.Viewer)
+ */
+ @Override
+ protected int doGetSortColumnIndex(Viewer viewer) {
+ if (viewer instanceof TreeViewer && ((TreeViewer)viewer).getTree() != null && !((TreeViewer)viewer).getTree().isDisposed()) {
+ Tree tree = ((TreeViewer)viewer).getTree();
+ return tree.getSortColumn() != null ? Arrays.asList(tree.getColumns()).indexOf(tree.getSortColumn()) : -1;
+ }
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.ui.controls.AbstractViewerComparator#doCompare(java.lang.Object, java.lang.Object, java.lang.String, int, int)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ protected int doCompare(Object node1, Object node2, String sortColumn, int index, int inverter) {
+ if (node1 == null && node2 == null) return 0;
+ if (node1 != null && node2 == null) return 1;
+ if (node1 == null && node2 != null) return -1;
+
+ // Get the labels
+ String text1 = doGetText(node1, index);
+ String text2 = doGetText(node2, index);
+
+ // Normalize labels
+ if (text1 == null) text1 = ""; //$NON-NLS-1$
+ if (text2 == null) text2 = ""; //$NON-NLS-1$
+
+ // The tree sorts not strictly alphabetical. First comes entries starting with numbers,
+ // second entries starting with uppercase and than all the rest. Additional, if a label contains
+ // uppercase characters, it is sorted in before any labels being lowercase only.
+ if (text1.length() > 0 && text2.length() > 0) {
+ // Get the first characters of both
+ char c1 = text1.charAt(0);
+ char c2 = text2.charAt(0);
+
+ if (Character.isDigit(c1) || Character.isDigit(c2)) {
+ // Check on the differences. If both are digits, the standard compare will do it
+ if (Character.isDigit(c1) && !Character.isDigit(c2)) return -1 * inverter;
+ if (!Character.isDigit(c1) && Character.isDigit(c2)) return 1 * inverter;
+ }
+
+ if (Character.isUpperCase(c1) || Character.isUpperCase(c2)) {
+ // Check on the differences. If both are uppercase characters, the standard compare will do it
+ if (Character.isUpperCase(c1) && !Character.isUpperCase(c2)) return -1 * inverter;
+ if (!Character.isUpperCase(c1) && Character.isUpperCase(c2)) return 1 * inverter;
+ }
+
+ Matcher m1 = Pattern.compile("(\\D+)(\\d+)").matcher(text1); //$NON-NLS-1$
+ Matcher m2 = Pattern.compile("(\\D+)(\\d+)").matcher(text2); //$NON-NLS-1$
+ if (m1.matches() && m2.matches()) {
+ String p11 = m1.group(1);
+ String p12 = m1.group(2);
+
+ String p21 = m2.group(1);
+ String p22 = m2.group(2);
+
+ if (p11 != null && p11.equals(p21)) {
+ // Compare the second parts as number
+ try {
+ int result = 0;
+ long l1 = Long.parseLong(p12);
+ long l2 = Long.parseLong(p22);
+
+ if (l1 > l2) result = 1;
+ if (l1 < l2) result = -1;
+
+ return result;
+ } catch (NumberFormatException e) { /* ignored on purpose */ }
+ }
+ }
+
+ if (text1.matches(".*[A-Z]+.*") || text2.matches(".*[A-Z]+.*")) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (text1.matches(".*[A-Z]+.*") && !text2.matches(".*[A-Z]+.*")) return -1 * inverter; //$NON-NLS-1$ //$NON-NLS-2$
+ if (!text1.matches(".*[A-Z]+.*") && text2.matches(".*[A-Z]+.*")) return 1 * inverter; //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Additionally, it even depends on the position of the first uppercase
+ // character if both strings contains them :-(
+ int minLength = Math.min(text1.length(), text2.length());
+ for (int i = 0; i < minLength; i++) {
+ char ch1 = text1.charAt(i);
+ char ch2 = text2.charAt(i);
+
+ if (Character.isUpperCase(ch1) && !Character.isUpperCase(ch2)) return -1 * inverter;
+ if (!Character.isUpperCase(ch1) && Character.isUpperCase(ch2)) return 1 * inverter;
+ // If both are uppercase, we break the loop and compare as usual
+ if (Character.isUpperCase(ch1) && Character.isUpperCase(ch2)) break;
+ }
+ }
+ }
+
+ // Compare the text alphabetical
+ return getComparator().compare(text1, text2) * inverter;
+ }
+}

Back to the top