From 2f0f316cfbd3051ca93879f2c170cd2cc33d9c26 Mon Sep 17 00:00:00 2001 From: David Dykstal Date: Thu, 22 Mar 2007 14:52:36 +0000 Subject: [PATCH] initial population --- .../org.eclipse.rse.importexport/.classpath | 7 + .../org.eclipse.rse.importexport/.cvsignore | 1 + .../org.eclipse.rse.importexport/.project | 28 + .../META-INF/MANIFEST.MF | 11 + .../org.eclipse.rse.importexport/about.html | 30 + .../build.properties | 22 + .../icons/full/etool16/file_export.gif | Bin 0 -> 187 bytes .../icons/full/etool16/file_import.gif | Bin 0 -> 189 bytes .../plugin.properties | 46 + .../org.eclipse.rse.importexport/plugin.xml | 21 + .../IRemoteImportExportConstants.java | 37 + ...ortExportDescriptionFilesViewerFilter.java | 93 ++ .../RemoteImportExportProblemDialog.java | 141 ++ .../RemoteImportExportResources.java | 37 + .../RemoteImportExportResources.properties | 39 + .../RemoteImportExportRunnable.java | 42 + .../importexport/RemoteImportExportUtil.java | 142 ++ .../rse/files/importexport/files/Debug.java | 20 + .../importexport/files/FileSystemElement.java | 233 +++ .../files/FileSystemStructureProvider.java | 101 ++ .../files/IImportStructureProvider.java | 64 + .../IRemoteFileExportDescriptionReader.java | 25 + .../IRemoteFileExportDescriptionWriter.java | 25 + .../IRemoteFileImportDescriptionReader.java | 25 + .../IRemoteFileImportDescriptionWriter.java | 25 + .../files/MinimizedFileSystemElement.java | 99 ++ .../files/RemoteExportWizard.java | 128 ++ .../files/RemoteExportWizardPage1.java | 867 ++++++++++ .../importexport/files/RemoteExporter.java | 104 ++ .../files/RemoteFileExportActionDelegate.java | 157 ++ .../files/RemoteFileExportData.java | 173 ++ .../RemoteFileExportDescriptionReader.java | 202 +++ .../RemoteFileExportDescriptionWriter.java | 169 ++ ...teFileExportFromProjectActionDelegate.java | 31 + .../files/RemoteFileExportOperation.java | 536 +++++++ .../files/RemoteFileImportActionDelegate.java | 157 ++ .../files/RemoteFileImportData.java | 218 +++ .../RemoteFileImportDescriptionReader.java | 192 +++ .../RemoteFileImportDescriptionWriter.java | 171 ++ .../RemoteFileImportExportActionDelegate.java | 119 ++ .../files/RemoteFileImportOperation.java | 639 ++++++++ ...moteFileImportToProjectActionDelegate.java | 31 + ...oteFileOpenExportWizardActionDelegate.java | 82 + ...oteFileOpenImportWizardActionDelegate.java | 82 + .../files/RemoteFileOverwriteQuery.java | 94 ++ .../files/RemoteImportWizard.java | 119 ++ .../files/RemoteImportWizardPage1.java | 1365 ++++++++++++++++ .../files/TreeExpandDropListener.java | 89 ++ .../files/TreeScrollDropListener.java | 145 ++ .../files/importexport/files/UniFilePlus.java | 359 +++++ .../files/importexport/files/Utilities.java | 226 +++ .../RemoteImportExportPlugin.java | 64 + .../SystemImportExportResources.java | 89 ++ .../SystemImportExportResources.properties | 122 ++ .../org.eclipse.rse.useractions/.classpath | 7 + .../org.eclipse.rse.useractions/.cvsignore | 1 + .../org.eclipse.rse.useractions/.project | 28 + .../META-INF/MANIFEST.MF | 32 + .../org.eclipse.rse.useractions/about.html | 30 + .../build.properties | 17 + .../icons/full/obj16/compcmd_ibm_obj.gif | Bin 0 -> 596 bytes .../icons/full/obj16/compcmd_ibmuser_obj.gif | Bin 0 -> 587 bytes .../icons/full/obj16/compcmd_new_obj.gif | Bin 0 -> 597 bytes .../icons/full/obj16/compcmd_user_obj.gif | Bin 0 -> 563 bytes .../icons/full/obj16/user_action_ibm_obj.gif | Bin 0 -> 338 bytes .../full/obj16/user_action_ibm_user_obj.gif | Bin 0 -> 361 bytes .../icons/full/obj16/user_action_new_obj.gif | Bin 0 -> 370 bytes .../icons/full/obj16/user_action_obj.gif | Bin 0 -> 353 bytes .../full/obj16/user_type_ibm_new_obj.gif | Bin 0 -> 574 bytes .../icons/full/obj16/user_type_ibm_obj.gif | Bin 0 -> 341 bytes .../full/obj16/user_type_ibm_user_obj.gif | Bin 0 -> 577 bytes .../icons/full/obj16/user_type_new_obj.gif | Bin 0 -> 577 bytes .../icons/full/obj16/user_type_obj.gif | Bin 0 -> 341 bytes .../plugin.properties | 15 + .../org.eclipse.rse.useractions/plugin.xml | 32 + .../eclipse/rse/useractions/Activator.java | 63 + .../rse/useractions/UserActionsIcon.java | 116 ++ .../rse/useractions/UserActionsResources.java | 70 + .../UserActionsResources.properties | 85 + .../files/compile/LocalCompileManager.java | 46 + .../files/compile/LocalCompileProfile.java | 28 + .../compile/UniversalCompilableSource.java | 46 + .../compile/UniversalCompileManager.java | 64 + .../compile/UniversalCompileProfile.java | 44 + .../compile/UniversalCompileSubstList.java | 54 + .../compile/UniversalCompileSubstitutor.java | 218 +++ .../compile/UniversalIBMCompileCommand.java | 44 + .../compile/UniversalIBMCompileCommands.java | 65 + .../files/uda/UDActionSubsystemFiles.java | 783 +++++++++ .../uda/UDActionSubsystemLocalFiles.java | 114 ++ .../uda/UDActionSubsystemUniversalFiles.java | 113 ++ .../files/uda/UDSubstListCommonFiles.java | 59 + .../files/uda/UDSubstListFiles.java | 48 + .../files/uda/UDSubstListFolders.java | 41 + .../files/uda/UDTypesEditPaneFiles.java | 71 + .../files/uda/UDTypesEditorFiles.java | 567 +++++++ ...ystemCommandTextAdditionalGUIProvider.java | 32 + .../useractions/ui/ISystemSubstitutor.java | 32 + .../rse/useractions/ui/SystemCmdSubstVar.java | 77 + .../useractions/ui/SystemCmdSubstVarList.java | 292 ++++ .../ui/SystemCommandTextField.java | 287 ++++ .../ui/SystemCommandViewerConfiguration.java | 200 +++ .../ui/SystemEditCommandDialog.java | 141 ++ .../ui/SystemPromptCommandDialog.java | 222 +++ .../ISystemCompileCommandEditPaneHoster.java | 30 + ...ISystemCompileCommandEditPaneListener.java | 26 + .../ISystemCompileCommandSubstitutor.java | 26 + .../compile/ISystemCompileXMLConstants.java | 140 ++ .../compile/SystemCascadingCompileAction.java | 91 ++ .../ui/compile/SystemCompilableSource.java | 230 +++ .../ui/compile/SystemCompileAction.java | 194 +++ .../SystemCompileCascadeByProfileAction.java | 110 ++ .../ui/compile/SystemCompileCommand.java | 418 +++++ .../SystemCompileCommandActionCopy.java | 54 + .../SystemCompileCommandActionDelete.java | 54 + .../SystemCompileCommandActionMoveDown.java | 53 + .../SystemCompileCommandActionMoveUp.java | 53 + .../SystemCompileCommandActionPaste.java | 54 + ...emCompileCommandActionRestoreDefaults.java | 54 + .../SystemCompileCommandContentProvider.java | 45 + .../compile/SystemCompileCommandEditPane.java | 675 ++++++++ .../SystemCompileCommandLabelProvider.java | 49 + .../ui/compile/SystemCompileContributor.java | 136 ++ .../SystemCompileContributorManager.java | 70 + .../SystemCompileContributorReader.java | 51 + .../ui/compile/SystemCompileManager.java | 418 +++++ .../SystemCompileMultipleSelectAction.java | 159 ++ .../ui/compile/SystemCompileProfile.java | 617 +++++++ .../SystemCompileRemoteObjectMatcher.java | 189 +++ .../ui/compile/SystemCompileType.java | 348 ++++ .../compile/SystemDefaultCompileCommand.java | 214 +++ .../compile/SystemDefaultCompileCommands.java | 196 +++ .../SystemNewCompileSrcTypeDialog.java | 219 +++ .../SystemPromptCompileCommandDialog.java | 84 + .../SystemWorkWithCompileCommandsAction.java | 149 ++ .../SystemWorkWithCompileCommandsDialog.java | 1117 +++++++++++++ .../SystemTeamViewCompileCommandAdapter.java | 196 +++ .../SystemTeamViewCompileCommandNode.java | 105 ++ .../SystemTeamViewCompileTypeAdapter.java | 187 +++ .../SystemTeamViewCompileTypeNode.java | 137 ++ .../SystemTeamViewUserActionAdapter.java | 209 +++ ...temTeamViewCompileCommandPropertyPage.java | 186 +++ ...SystemTeamViewCompileTypePropertyPage.java | 87 + .../SystemTeamViewUserActionPropertyPage.java | 313 ++++ .../ui/uda/ISystemUDAConstants.java | 50 + .../ui/uda/ISystemUDAEditPaneHoster.java | 40 + .../ui/uda/ISystemUDSelectTypeListener.java | 32 + .../useractions/ui/uda/ISystemUDTreeView.java | 130 ++ .../ISystemUDTypeEditPaneTypesSelector.java | 108 ++ .../ui/uda/ISystemUDWorkWithDialog.java | 63 + .../uda/ISystemXMLElementWrapperFactory.java | 33 + .../ui/uda/SystemPromptUDADialog.java | 79 + .../ui/uda/SystemUDACascadeAction.java | 101 ++ .../uda/SystemUDACascadeByProfileAction.java | 76 + .../ui/uda/SystemUDAFileTypesForName.java | 29 + .../ui/uda/SystemUDAResolvedTypes.java | 131 ++ .../ui/uda/SystemUDAResources.java | 267 ++++ .../ui/uda/SystemUDAResources.properties | 438 +++++ .../uda/SystemUDARestoreDefaultsActions.java | 53 + .../ui/uda/SystemUDASubstVarListCommon.java | 46 + .../ui/uda/SystemUDActionEditPane.java | 1213 ++++++++++++++ .../ui/uda/SystemUDActionElement.java | 255 +++ .../ui/uda/SystemUDActionManager.java | 225 +++ .../ui/uda/SystemUDActionSubsystem.java | 1143 +++++++++++++ .../ui/uda/SystemUDActionTreeView.java | 88 + .../ui/uda/SystemUDAsBaseAction.java | 53 + .../ui/uda/SystemUDBaseManager.java | 1414 +++++++++++++++++ .../ui/uda/SystemUDBaseTreeView.java | 803 ++++++++++ .../SystemUDBaseTreeViewLabelProvider.java | 54 + .../ui/uda/SystemUDSelectTypesForm.java | 478 ++++++ .../ui/uda/SystemUDSimpleTypesListEditor.java | 192 +++ .../ui/uda/SystemUDTreeActionCopy.java | 52 + .../ui/uda/SystemUDTreeActionDelete.java | 52 + .../ui/uda/SystemUDTreeActionMoveDown.java | 51 + .../ui/uda/SystemUDTreeActionMoveUp.java | 51 + .../ui/uda/SystemUDTreeActionPaste.java | 52 + .../ui/uda/SystemUDTreeViewNewItem.java | 118 ++ .../ui/uda/SystemUDTypeEditPane.java | 527 ++++++ .../ui/uda/SystemUDTypeElement.java | 72 + .../ui/uda/SystemUDTypeManager.java | 321 ++++ .../ui/uda/SystemUDTypeTreeView.java | 121 ++ .../ui/uda/SystemUserActionExtension.java | 61 + .../uda/SystemUserActionExtensionManager.java | 103 ++ .../ui/uda/SystemWorkWithUDAsDialog.java | 453 ++++++ .../ui/uda/SystemWorkWithUDTypeDialog.java | 432 +++++ .../ui/uda/SystemXMLElementWrapper.java | 524 ++++++ .../SystemWorkWithFileTypesAction.java | 156 ++ .../uda/actions/SystemWorkWithUDAsAction.java | 170 ++ .../rse/useractions/ui/uda/util/MatchStr.java | 97 ++ .../ui/uda/util/UDAFileTypesForName.java | 29 + .../ui/uda/util/UDAResolvedTypes.java | 76 + 191 files changed, 31083 insertions(+) create mode 100644 rse/plugins/org.eclipse.rse.importexport/.classpath create mode 100644 rse/plugins/org.eclipse.rse.importexport/.cvsignore create mode 100644 rse/plugins/org.eclipse.rse.importexport/.project create mode 100644 rse/plugins/org.eclipse.rse.importexport/META-INF/MANIFEST.MF create mode 100644 rse/plugins/org.eclipse.rse.importexport/about.html create mode 100644 rse/plugins/org.eclipse.rse.importexport/build.properties create mode 100644 rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_export.gif create mode 100644 rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_import.gif create mode 100644 rse/plugins/org.eclipse.rse.importexport/plugin.properties create mode 100644 rse/plugins/org.eclipse.rse.importexport/plugin.xml create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/IRemoteImportExportConstants.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportDescriptionFilesViewerFilter.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportProblemDialog.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.properties create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportRunnable.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportUtil.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Debug.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemElement.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemStructureProvider.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IImportStructureProvider.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionReader.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionWriter.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionReader.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionWriter.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/MinimizedFileSystemElement.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizard.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizardPage1.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExporter.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportData.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionReader.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionWriter.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportFromProjectActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportOperation.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportData.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionReader.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionWriter.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportExportActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportOperation.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportToProjectActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenExportWizardActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenImportWizardActionDelegate.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOverwriteQuery.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizard.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizardPage1.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeExpandDropListener.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeScrollDropListener.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/UniFilePlus.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Utilities.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/RemoteImportExportPlugin.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.properties create mode 100644 rse/plugins/org.eclipse.rse.useractions/.classpath create mode 100644 rse/plugins/org.eclipse.rse.useractions/.cvsignore create mode 100644 rse/plugins/org.eclipse.rse.useractions/.project create mode 100644 rse/plugins/org.eclipse.rse.useractions/META-INF/MANIFEST.MF create mode 100644 rse/plugins/org.eclipse.rse.useractions/about.html create mode 100644 rse/plugins/org.eclipse.rse.useractions/build.properties create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibm_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibmuser_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_new_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_user_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_user_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_new_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_new_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_user_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_new_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_obj.gif create mode 100644 rse/plugins/org.eclipse.rse.useractions/plugin.properties create mode 100644 rse/plugins/org.eclipse.rse.useractions/plugin.xml create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/Activator.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsIcon.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.properties create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileProfile.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompilableSource.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileProfile.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstList.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstitutor.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommand.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommands.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemLocalFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemUniversalFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListCommonFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFolders.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditPaneFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditorFiles.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemCommandTextAdditionalGUIProvider.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemSubstitutor.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVar.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVarList.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandTextField.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandViewerConfiguration.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemEditCommandDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemPromptCommandDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneHoster.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneListener.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandSubstitutor.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileXMLConstants.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCascadingCompileAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompilableSource.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCascadeByProfileAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommand.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionCopy.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionDelete.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveDown.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveUp.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionPaste.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionRestoreDefaults.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandContentProvider.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandEditPane.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandLabelProvider.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributor.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorReader.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileMultipleSelectAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileProfile.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileRemoteObjectMatcher.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileType.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommand.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommands.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemNewCompileSrcTypeDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemPromptCompileCommandDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandAdapter.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandNode.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeAdapter.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeNode.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewUserActionAdapter.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileCommandPropertyPage.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileTypePropertyPage.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewUserActionPropertyPage.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAConstants.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAEditPaneHoster.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDSelectTypeListener.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTreeView.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTypeEditPaneTypesSelector.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDWorkWithDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemXMLElementWrapperFactory.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemPromptUDADialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeByProfileAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAFileTypesForName.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResolvedTypes.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.properties create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDARestoreDefaultsActions.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDASubstVarListCommon.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionEditPane.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionElement.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionSubsystem.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionTreeView.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAsBaseAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeView.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeViewLabelProvider.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSelectTypesForm.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSimpleTypesListEditor.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionCopy.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionDelete.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveDown.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveUp.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionPaste.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeViewNewItem.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeEditPane.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeElement.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeTreeView.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtension.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtensionManager.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDAsDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDTypeDialog.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemXMLElementWrapper.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithFileTypesAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithUDAsAction.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/MatchStr.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAFileTypesForName.java create mode 100644 rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAResolvedTypes.java diff --git a/rse/plugins/org.eclipse.rse.importexport/.classpath b/rse/plugins/org.eclipse.rse.importexport/.classpath new file mode 100644 index 00000000000..751c8f2e504 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.importexport/.cvsignore b/rse/plugins/org.eclipse.rse.importexport/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.rse.importexport/.project b/rse/plugins/org.eclipse.rse.importexport/.project new file mode 100644 index 00000000000..6f0a9641711 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.importexport + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.importexport/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.importexport/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..675f4b26521 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Importexport Plug-in +Bundle-SymbolicName: org.eclipse.rse.importexport; singleton:=true +Bundle-Version: 1.0.0 +Bundle-ClassPath: systemsImportExport.jar +Bundle-Activator: org.eclipse.rse.importexport.RemoteImportExportPlugin +Bundle-Localization: plugin +Export-Package: org.eclipse.rse.files.importexport,org.eclipse.rse.files.importexport.files,org.eclipse.rse.importexport +Require-Bundle: org.eclipse.core.runtime,org.eclipse.core.resources,org.eclipse.ui,org.eclipse.ui.ide,org.eclipse.ui.views,org.eclipse.rse.services,org.eclipse.rse.core,org.eclipse.rse.ui,org.eclipse.rse.subsystems.files.core,org.eclipse.rse.files.ui +Eclipse-LazyStart: true diff --git a/rse/plugins/org.eclipse.rse.importexport/about.html b/rse/plugins/org.eclipse.rse.importexport/about.html new file mode 100644 index 00000000000..e8ed9d8aad1 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/about.html @@ -0,0 +1,30 @@ + + + + +About + + +

About This Content

+ +

June 5, 2006

+

License

+

The Eclipse Foundation makes available all content in this plug-in ("Content"). +Unless otherwise indicated below, the Content is provided to you under the +terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content. +

+

+If you did not receive this Content directly from the Eclipse Foundation, +the Content is being redistributed by another party ("Redistributor") and different +terms and conditions may apply to your use of any object code in the Content. +Check the Redistributor’s license that was provided with the Content. +If no such license exists, contact the Redistributor. +Unless otherwise indicated below, the terms and conditions of the EPL still +apply to any source code in the Content and such source code may be obtained +at http://www.eclipse.org. +

+ + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.importexport/build.properties b/rse/plugins/org.eclipse.rse.importexport/build.properties new file mode 100644 index 00000000000..db91518b1d5 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/build.properties @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2000, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +source.systemsImportExport.jar = src/ +output.systemsImportExport.jar = bin/ +bin.includes = plugin.xml,\ + systemsImportExport.jar,\ + plugin.properties,\ + icons/,\ + about.html,\ + about.properties,\ + about.ini,\ + wsFeat.gif,\ + about.html,\ + META-INF/ diff --git a/rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_export.gif b/rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_export.gif new file mode 100644 index 0000000000000000000000000000000000000000..a13e02f6b22b610823113dbe1e6032535353d568 GIT binary patch literal 187 zcmZ?wbhEHb6krfwIKsftF?C&jSxat3dwR_z9i2ya zbspT-adLO}nZ4aNj`UsJ-*fwD-~a#r8HfXlKUo+V7=##fK*~XOGO$`KQ0Ys_oR_g` z-5X8=2W|~RNfosX3^lR}7D5XiHrOaJJ3a`1_0?s6OJjk>lDtJLx29@r*>u0af`!2v E0P)*B`2YX_ literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_import.gif b/rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_import.gif new file mode 100644 index 0000000000000000000000000000000000000000..5709c2ec8e1c4cf51bd079298273cc55f1e121c8 GIT binary patch literal 189 zcmZ?wbhEHb6krfwIKsftF?C&jSxat3dwR_z9i2ya zbspT-adLO}nZ4aNj`UsJ-*fwD-~a#r8HfXlKUo+V7=##fK*~XOGO$`LQ0Ys_oR_g` z-5U-A2W|~RNfosX3^lR}7D5XiHrOaJJ3a`1_0?tngI8`wTU6Mbw5t;&x!T{A>ToeK GSOWlC89ZqK literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.importexport/plugin.properties b/rse/plugins/org.eclipse.rse.importexport/plugin.properties new file mode 100644 index 00000000000..0e7dc532c16 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/plugin.properties @@ -0,0 +1,46 @@ +############################################################################### +# Copyright (c) 2000, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +# NLS_MESSAGEFORMAT_NONE +# NLS_ENCODING=UTF-8 + +# Plugin name +plugin.name = RSE Import/Export + +# Remote file import and export wizards +RemoteFileSystemExportWizard.label = Remote file system +RemoteFileSystemExportWizard.description = Export resources to a remote file system +RemoteFileSystemImportWizard.label = Remote file system +RemoteFileSystemImportWizard.description = Import resources from a remote file system + +# Remote file export action +RemoteFileExportAction.label = E&xport to Remote File System +RemoteFileExportAction.tooltip = Exports resources to a remote file system based on the selected export description file + +# Open remote file export wizard +OpenRemoteFileExport.label = Ope&n Remote File Exporter... +OpenRemoteFileExport.tooltip = Opens the remote file system export wizard based on the selected export description file + +# Remote file import action +RemoteFileImportAction.label = Import from Remote File System +RemoteFileImportAction.tooltip = Imports resources from a remote file system based on the selected import description file + +# Open remote file import wizard +OpenRemoteFileImport.label = Ope&n Remote File Importer... +OpenRemoteFileImport.tooltip = Opens the remote file system import wizard based on the selected import description file + +# Import to project +ImportToProject.label = Import To Project... +ImportToProject.tooltip = Import contents of selected folder to a project + +# Export from project +ExportFromProject.label = Export From Project... +ExportFromProject.tooltip = Export contents of project to the selected folder diff --git a/rse/plugins/org.eclipse.rse.importexport/plugin.xml b/rse/plugins/org.eclipse.rse.importexport/plugin.xml new file mode 100644 index 00000000000..0338b61d575 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/plugin.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/IRemoteImportExportConstants.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/IRemoteImportExportConstants.java new file mode 100644 index 00000000000..387031a769e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/IRemoteImportExportConstants.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport; + +/** + * Interface containing contstants required for import and export. + */ +public interface IRemoteImportExportConstants { + /** + * Remote file import description file extension, "rimpfd". + */ + public static final String REMOTE_FILE_IMPORT_DESCRIPTION_FILE_EXTENSION = "rimpfd"; //$NON-NLS-1$ + /** + * An array of import description file extensions. + */ + public static final String[] REMOTE_IMPORT_DESCRIPTION_FILE_EXTENSIONS = { REMOTE_FILE_IMPORT_DESCRIPTION_FILE_EXTENSION }; + /** + * Remote file export description file extension, "rexpfd". + */ + public static final String REMOTE_FILE_EXPORT_DESCRIPTION_FILE_EXTENSION = "rexpfd"; //$NON-NLS-1$ + /** + * Remote jar export description file extension, "rmtjardesc". + */ + public static final String REMOTE_JAR_EXPORT_DESCRIPTION_FILE_EXTENSION = "rmtjardesc"; //$NON-NLS-1$ + /** + * An array of export description file extensions. + */ + public static final String[] REMOTE_EXPORT_DESCRIPTION_FILE_EXTENSIONS = { REMOTE_FILE_EXPORT_DESCRIPTION_FILE_EXTENSION, REMOTE_JAR_EXPORT_DESCRIPTION_FILE_EXTENSION }; +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportDescriptionFilesViewerFilter.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportDescriptionFilesViewerFilter.java new file mode 100644 index 00000000000..0172902976c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportDescriptionFilesViewerFilter.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +/** + * This class defines a viewer filter that can be used with a selection dialog, e.g. ElementTreeSelectionDialog. + * The viewer filter only allows description files for import/export. Current known extensions are defined + * in class RemoteFileImportExportConstants. + */ +public class RemoteImportExportDescriptionFilesViewerFilter extends ViewerFilter { + /** + * Constant indicating descriptor files for both import and export should be allowed. + */ + public static final int IMPORT_EXPORT = 0; + /** + * Constant indicating that only descriptor files for imports should be allowed. + */ + public static final int IMPORT_ONLY = 1; + /** + * Constant indicating that only descriptor files for exports should be allowed. + */ + public static final int EXPORT_ONLY = 2; + private int mode; + + /** + * Constructor. + * @param mode the mode. One of IMPORT_EXPORT, IMPORT_ONLY, or EXPORT_ONLY. + */ + public RemoteImportExportDescriptionFilesViewerFilter(int mode) { + Assert.isLegal((mode == IMPORT_EXPORT) || (mode == IMPORT_ONLY) || (mode == EXPORT_ONLY)); + this.mode = mode; + } + + /** + * Allows containers and import/export description files. + * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (element instanceof IResource) { + IResource resource = (IResource) element; + if (resource.getType() == IResource.FILE) { + String extension = resource.getFileExtension(); + if (extension == null || extension.equals("")) { //$NON-NLS-1$ + return false; + } + switch (mode) { + case IMPORT_EXPORT: + return (contains(IRemoteImportExportConstants.REMOTE_IMPORT_DESCRIPTION_FILE_EXTENSIONS, extension) || contains( + IRemoteImportExportConstants.REMOTE_EXPORT_DESCRIPTION_FILE_EXTENSIONS, extension)); + case IMPORT_ONLY: + return contains(IRemoteImportExportConstants.REMOTE_IMPORT_DESCRIPTION_FILE_EXTENSIONS, extension); + case EXPORT_ONLY: + return contains(IRemoteImportExportConstants.REMOTE_EXPORT_DESCRIPTION_FILE_EXTENSIONS, extension); + // should never be here + default: + return false; + } + } else { + return true; + } + } else { + return false; + } + } + + /** + * Returns whether an extension exists in an array of extensions. + * @param extensions an array to extensions. + * @param extension the extension. + * @return true if the extension exists in the array of extensions, false otherwise. + */ + private boolean contains(String[] extensions, String extension) { + for (int i = 0; i < extensions.length; i++) { + if (extensions[i].equals(extension)) { + return true; + } + } + return false; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportProblemDialog.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportProblemDialog.java new file mode 100644 index 00000000000..3bbbc0a1972 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportProblemDialog.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Overrides ErrorDialog to provide a dialog with + * the image that corresponds to the IStatus. + * + * This behavior should be implemented in the ErrorDialog itself, + * see: 1GJU7TK: ITPUI:WINNT - DCR: ErrorDialog should not always show the error icon + * The class can be removed when the above PR is fixed + * + * @see org.eclipse.core.runtime.IStatus + */ +public class RemoteImportExportProblemDialog extends ErrorDialog { + private Image fImage; + + /** + * Creates a problem dialog. + * + * @param parent the shell under which to create this dialog + * @param title the title to use for this dialog, + * or null to indicate that the default title should be used + * @param message the message to show in this dialog, + * or null to indicate that the error's message should be shown + * as the primary message + * @param image the image to be used + * @param status the error to show to the user + * @param displayMask the mask to use to filter the displaying of child items, + * as per IStatus.matches + * @see org.eclipse.core.runtime.IStatus#matches + */ + protected RemoteImportExportProblemDialog(Shell parent, String title, String message, Image image, IStatus status, int displayMask) { + super(parent, title, message, status, displayMask); + fImage = image; + } + + /* + * Overrides method declared on Dialog. + */ + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + if (fImage == null) { + return composite; + } + // find the label that contains the image + Control[] kids = composite.getChildren(); + int childCount = kids.length; + Label label = null; + int i = 0; + while (i < childCount) { + if (kids[i] instanceof Label) { + label = (Label) kids[i]; + if (label.getImage() != null) { + break; + } + } + i++; + } + if (i < childCount && label != null) { + label.setImage(fImage); + } + applyDialogFont(composite); + return composite; + } + + /** + * Opens a warning dialog to display the given warning. Use this method if the + * warning object being displayed does not contain child items, or if you + * wish to display all such items without filtering. + * + * @param parent the parent shell of the dialog, or null if none + * @param title the title to use for this dialog, + * or null to indicate that the default title should be used + * @param message the message to show in this dialog, + * or null to indicate that the error's message should be shown + * as the primary message + * @param status the error to show to the user + * @return the code of the button that was pressed that resulted in this dialog + * closing. This will be Dialog.OK if the OK button was + * pressed, or Dialog.CANCEL if this dialog's close window + * decoration or the ESC key was used. + */ + public static int open(Shell parent, String title, String message, IStatus status) { + return open(parent, title, message, status, IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.ERROR); + } + + /** + * Opens a dialog to display either an error or warning dialog. Use this method if the + * status being displayed contains child items and you wish to + * specify a mask which will be used to filter the displaying of these + * children. The error dialog will only be displayed if there is at + * least one child status matching the mask. + * + * @param parent the parent shell of the dialog, or null if none + * @param title the title to use for this dialog, + * or null to indicate that the default title should be used + * @param message the message to show in this dialog, + * or null to indicate that the error's message should be shown + * as the primary message + * @param status the error to show to the user + * @param displayMask the mask to use to filter the displaying of child items, + * as per IStatus.matches + * @return the code of the button that was pressed that resulted in this dialog + * closing. This will be Dialog.OK if the OK button was + * pressed, or Dialog.CANCEL if this dialog's close window + * decoration or the ESC key was used. + * @see org.eclipse.core.runtime.IStatus#matches + */ + public static int open(Shell parent, String title, String message, IStatus status, int displayMask) { + Image image; + Display display = parent.getDisplay(); + if (status == null || status.matches(IStatus.ERROR)) { + image = display.getSystemImage(SWT.ICON_ERROR); + } else if (status.matches(IStatus.WARNING)) { + image = display.getSystemImage(SWT.ICON_WARNING); + } else { + image = display.getSystemImage(SWT.ICON_INFORMATION); + } + ErrorDialog dialog = new RemoteImportExportProblemDialog(parent, title, message, image, status, displayMask); + return dialog.open(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.java new file mode 100644 index 00000000000..2ecaf58fd4a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport; + +import org.eclipse.osgi.util.NLS; + +public class RemoteImportExportResources extends NLS { + private static String BUNDLE_NAME = "org.eclipse.rse.files.importexport.RemoteImportExportResources"; //$NON-NLS-1$ + public static String IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_TITLE; + public static String IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_MESSAGE; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_ABSOLUTE; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_EXISTING_CONTAINER; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_NO_CONTAINER; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_INVALID_EXTENSION; + public static String IMPORT_EXPORT_ERROR_CREATE_FILES_FAILED; + public static String IMPORT_EXPORT_ERROR_CREATE_FILE_FAILED; + public static String IMPORT_EXPORT_EXPORT_ACTION_DELEGATE_TITLE; + public static String IMPORT_EXPORT_IMPORT_ACTION_DELEGATE_TITLE; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_READ; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_CLOSE; + public static String WizardDataTransfer_existsQuestion; + public static String WizardDataTransfer_overwriteNameAndPathQuestion; + public static String WizardDataTransfer_exceptionMessage; + public static String Question; + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, RemoteImportExportResources.class); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.properties b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.properties new file mode 100644 index 00000000000..9b4734c15d6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportResources.properties @@ -0,0 +1,39 @@ +############################################################################### +# Copyright (c) 2000, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +# NLS_MESSAGEFORMAT_VAR +# NLS_ENCODING=UTF-8 + +# Description file messages +IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_TITLE = Save As +IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_MESSAGE = Select location and name for the description +IMPORT_EXPORT_ERROR_DESCRIPTION_ABSOLUTE = Description file path must be absolute (i.e. begins with /) +IMPORT_EXPORT_ERROR_DESCRIPTION_EXISTING_CONTAINER = The description file location must not be an existing container +IMPORT_EXPORT_ERROR_DESCRIPTION_NO_CONTAINER = Container for description file does not exist +IMPORT_EXPORT_ERROR_DESCRIPTION_INVALID_EXTENSION = Description file extension must be ''.{0}'' + +# Creation failure messages +IMPORT_EXPORT_ERROR_CREATE_FILES_FAILED = Creation of some files failed. See details for additional information. +IMPORT_EXPORT_ERROR_CREATE_FILE_FAILED = File creation failed. See details for additional information. + +# Description file error messages +IMPORT_EXPORT_ERROR_DESCRIPTION_READ = Error reading {0}: {1} +IMPORT_EXPORT_ERROR_DESCRIPTION_CLOSE = Error closing description reader for {0} + +# Action delegate +IMPORT_EXPORT_EXPORT_ACTION_DELEGATE_TITLE = Remote File Export +IMPORT_EXPORT_IMPORT_ACTION_DELEGATE_TITLE = Remote File Import + +#Generic messages +WizardDataTransfer_existsQuestion = ''{0}'' already exists. Would you like to overwrite it? +WizardDataTransfer_overwriteNameAndPathQuestion = Overwrite ''{0}'' in folder ''{1}''? +WizardDataTransfer_exceptionMessage = Error occurred during operation: {0} +Question = Question diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportRunnable.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportRunnable.java new file mode 100644 index 00000000000..9f5007d872c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportRunnable.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport; + +import org.eclipse.core.resources.IFile; + +/** + * A runnable class that exports from an export description file. Use this class + * to export in a non-UI thread, by using Display.syncExec() or Display.asyncExec(). + */ +public class RemoteImportExportRunnable implements Runnable { + // description file + private IFile file; + private boolean export; + + /** + * Constrcutor. + * @param descriptionFile the description file. + * @param export true to export, otherwise false. + */ + public RemoteImportExportRunnable(IFile descriptionFile, boolean export) { + this.file = descriptionFile; + this.export = export; + } + + /** + * @see java.lang.Runnable#run() + */ + public void run() { + if (export) { + RemoteImportExportUtil.getInstance().exportFromDescriptionFile(file); + } + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportUtil.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportUtil.java new file mode 100644 index 00000000000..c665e0666dc --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/RemoteImportExportUtil.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.files.importexport.files.RemoteFileExportActionDelegate; + +/** + * Utility class for import and export. A singleton class. + */ +public class RemoteImportExportUtil { + private static RemoteImportExportUtil instance; + + /** + * Dummy action. Does nothing. + */ + private class DummyAction extends Action { + /** + * Constructor. + */ + public DummyAction() { + super(); + } + } + + private RemoteImportExportUtil() { + } + + public static RemoteImportExportUtil getInstance() { + if (instance == null) { + instance = new RemoteImportExportUtil(); + } + return instance; + } + + /** + * Does an export from a description file. The given description file must exist. + * @param descriptionFile the export description file. + */ + public void exportFromDescriptionFile(IFile descriptionFile) { + Assert.isLegal((descriptionFile != null) && descriptionFile.exists()); + IFile file = descriptionFile; + String extension = file.getFileExtension(); + if (extension == null || extension.equals("")) { //$NON-NLS-1$ + return; + } + if (extension.equals(IRemoteImportExportConstants.REMOTE_FILE_EXPORT_DESCRIPTION_FILE_EXTENSION)) { + RemoteFileExportActionDelegate action = new RemoteFileExportActionDelegate(); + DummyAction dummy = new DummyAction(); + action.selectionChanged(dummy, new StructuredSelection(file)); + action.run(dummy); + } else if (extension.equals(IRemoteImportExportConstants.REMOTE_JAR_EXPORT_DESCRIPTION_FILE_EXTENSION)) { + // TODO + // CreateRemoteJarActionDelegate action = new CreateRemoteJarActionDelegate(); + // DummyAction dummy = new DummyAction(); + // action.selectionChanged(dummy, new StructuredSelection(file)); + // action.run(dummy); + } + } + + /** + * Helper method for case insensitive file systems. Returns + * an existing resource whose path differs only in case from + * the given path, or null if no such resource exists. + */ + public IResource findExistingResourceVariant(IPath target) { + IWorkspace workspace = SystemBasePlugin.getWorkspace(); + // check if local file system is case sensitive + boolean isCaseInsensitive = Platform.getOS().equals(Platform.OS_WIN32); + // if so, we don't need to go any further + if (!isCaseInsensitive) { + return null; + } + IWorkspaceRoot root = workspace.getRoot(); + IPath result = root.getFullPath(); + IContainer container = root; + int segmentCount = target.segmentCount(); + for (int i = 0; i < segmentCount; i++) { + IResource[] children = null; + if (i != 0) { + IResource resource = root.findMember(result); + if ((resource != null) && (resource instanceof IContainer)) { + container = (IContainer) resource; + } else { + return null; + } + } + try { + children = container.members(); + } catch (CoreException e) { + SystemBasePlugin.logError("Exception occured trying to get children of " + result, e); //$NON-NLS-1$ + } + String name = findVariant(target.segment(i), children); + if (name == null) { + return null; + } + result = result.append(name); + } + return root.findMember(result); + } + + /** + * Searches for a variant of the given target in the list, + * that differs only in case. Returns the variant from + * the list if one is found, otherwise returns null. + * @param target the name. + * @param list the list of resources that may have the variant + */ + private String findVariant(String target, IResource[] list) { + if (list == null) { + return null; + } + // go through list + for (int i = 0; i < list.length; i++) { + String name = list[i].getName(); + // see if there is a variant, and if so, return it + if (target.equalsIgnoreCase(name)) { + return name; + } + } + return null; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Debug.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Debug.java new file mode 100644 index 00000000000..481aa03946f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Debug.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +public class Debug { + //execution time switches + public static boolean debug = false; + + public static void out(String s) { + if (debug) System.out.println(s); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemElement.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemElement.java new file mode 100644 index 00000000000..9b231626fda --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemElement.java @@ -0,0 +1,233 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.model.WorkbenchAdapter; + +// Similar to org.eclipse.ui.dialogs.FileSystemElement +// Changes: added getName() method +/** + * Instances of this class represent files or file-like entities (eg.- zip + * file entries) on the local file system. They do not represent resources + * within the workbench. This distinction is made because the representation of + * a file system resource is significantly different from that of a workbench + * resource. + * + * If self represents a collection (eg.- file system directory, zip directory) + * then its icon will be the folderIcon static field. Otherwise (ie.- self + * represents a file system file) self's icon is stored in field "icon", and is + * determined by the extension of the file that self represents. + * + * This class is adaptable, and implements one adapter itself, namely the + * IWorkbenchAdapter adapter used for navigation and display in the workbench. + */ +public class FileSystemElement implements IAdaptable { + private String name; + private Object fileSystemObject; + /* Wait until a child is added to initialize the receiver's lists. + * Doing so minimizes the amount of memory that is allocated when + * a large directory structure is being processed. + */ + private AdaptableList folders = null; + private AdaptableList files = null; + private boolean isDirectory = false; + private FileSystemElement parent; + private final static AdaptableList EMPTY_LIST = new AdaptableList(0); + private WorkbenchAdapter workbenchAdapter = new WorkbenchAdapter() { + /** + * Answer the children property of this element + */ + public Object[] getChildren(Object o) { + return getFolders().getChildren(o); + } + + /** + * Returns the parent of this element + */ + public Object getParent(Object o) { + return parent; + } + + /** + * Returns an appropriate label for this file system element. + */ + public String getLabel(Object o) { + return name; + } + + /** + * Returns an image descriptor for this file system element + */ + public ImageDescriptor getImageDescriptor(Object object) { + if (isDirectory()) { + return PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER); + } else { + return PlatformUI.getWorkbench().getEditorRegistry().getImageDescriptor(name); + } + } + }; + + /** + * Creates a new FileSystemElement and initializes it + * and its parent if applicable. + * + * @param name java.lang.String + */ + public FileSystemElement(String name, FileSystemElement parent, boolean isDirectory) { + this.name = name; + this.parent = parent; + this.isDirectory = isDirectory; + if (parent != null) parent.addChild(this); + } + + /** + * Adds the passed child to this object's collection of children. + * + * @param child FileSystemElement + */ + public void addChild(FileSystemElement child) { + if (child.isDirectory()) { + if (folders == null) folders = new AdaptableList(1); + folders.add(child); + } else { + if (files == null) files = new AdaptableList(1); + files.add(child); + } + } + + /** + * Returns the adapter + */ + public Object getAdapter(Class adapter) { + if (adapter == IWorkbenchAdapter.class) { + return workbenchAdapter; + } + //defer to the platform + return Platform.getAdapterManager().getAdapter(this, adapter); + } + + /** + * Returns the extension of this element's filename. Returns + * The empty string if there is no extension. + */ + public String getFileNameExtension() { + int lastDot = name.lastIndexOf('.'); + return lastDot < 0 ? "" : name.substring(lastDot + 1); //$NON-NLS-1$ + } + + /** + * Answer the files property of this element. Answer an empty list if the + * files property is null. + * This method should not be used to add children + * to the receiver. Use addChild(FileSystemElement) instead. + */ + public AdaptableList getFiles() { + if (files == null) return EMPTY_LIST; + return files; + } + + /** + * Returns the file system object property of this element + * + * @return the file system object + */ + public Object getFileSystemObject() { + return fileSystemObject; + } + + /** + * Returns a list of the folders that are immediate children + * of this folder. Answer an empty list if the folders property is null. + * This method should not be used to add children + * to the receiver. Use addChild(FileSystemElement) instead. + */ + public AdaptableList getFolders() { + if (folders == null) return EMPTY_LIST; + return folders; + } + + /** + * Returns the name. + */ + public String getName() { + return name; + } + + /** + * Return the parent of this element. + * + * @return the parent file system element, or null if this is the root + */ + public FileSystemElement getParent() { + return this.parent; + } + + /** + * Returns true if this element represents a directory, and false + * otherwise. + */ + public boolean isDirectory() { + return isDirectory; + } + + /** + * Removes a sub-folder from this file system element. + */ + public void removeFolder(FileSystemElement child) { + if (folders == null) return; + folders.remove(child); + child.setParent(null); + } + + /** + * Set the file system object property of this element + * + * @param value the file system object + */ + public void setFileSystemObject(Object value) { + fileSystemObject = value; + } + + /** + * Sets the parent of this file system element. + */ + public void setParent(FileSystemElement element) { + parent = element; + } + + /** + * For debugging purposes only. + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + if (isDirectory()) { + buf.append("Folder(");//$NON-NLS-1$ + } else { + buf.append("File(");//$NON-NLS-1$ + } + buf.append(name).append(")");//$NON-NLS-1$ + if (!isDirectory()) { + return buf.toString(); + } + buf.append(" folders: ");//$NON-NLS-1$ + buf.append(folders); + buf.append(" files: ");//$NON-NLS-1$ + buf.append(files); + return buf.toString(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemStructureProvider.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemStructureProvider.java new file mode 100644 index 00000000000..b3423652469 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/FileSystemStructureProvider.java @@ -0,0 +1,101 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; + +// Similar to org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider +// Changes marked with "IFS:" comments. +/** + * This class provides information regarding the structure and + * content of specified file system File objects. + */ +public class FileSystemStructureProvider implements IImportStructureProvider { + /** + * Holds a singleton instance of this class. + */ + public final static FileSystemStructureProvider INSTANCE = new FileSystemStructureProvider(); + + /** + * Creates an instance of FileSystemStructureProvider. + */ + public FileSystemStructureProvider() { + super(); + } + + /* (non-Javadoc) + * Method declared on IImportStructureProvider + */ + public List getChildren(Object element) { + List result = new ArrayList(0); + try { + String[] children = ((File) element).list(); + int childrenLength = children == null ? 0 : children.length; + result = new ArrayList(childrenLength); + long start = System.currentTimeMillis(); + // String p=((UniFilePlus)element).getAbsolutePath()+"/"; //$NON-NLS-1$ + // IHost sysC=((UniFilePlus) element).remoteFile.getSystemConnection(); + IRemoteFile[] childIRemoteFiles = ((UniFilePlus) element).listIRemoteFiles(); + for (int i = 0; i < childrenLength; i++) + result.add(new UniFilePlus(childIRemoteFiles[i])); + Debug.out("Expanding [" + ((File) element).getPath() + "] took in (ms): " + (System.currentTimeMillis() - start)); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (Exception e) { + // Probably caused by IFS authority problem + // ignore for now + } + return result; + } + + /* (non-Javadoc) + * Method declared on IImportStructureProvider + */ + public InputStream getContents(Object element) { + try { + return new FileInputStream((File) element); + } catch (FileNotFoundException e) { + return null; + } + } + + /* (non-Javadoc) + * Method declared on IImportStructureProvider + */ + public String getFullPath(Object element) { + return ((File) element).getPath(); + } + + /* (non-Javadoc) + * Method declared on IImportStructureProvider + */ + public String getLabel(Object element) { + //Get the name - if it is empty then return the path as it is a file root + File file = (File) element; + String name = file.getName(); + if (name == null || name.length() == 0) + return file.getPath(); + else + return name; + } + + /* (non-Javadoc) + * Method declared on IImportStructureProvider + */ + public boolean isFolder(Object element) { + return ((File) element).isDirectory(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IImportStructureProvider.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IImportStructureProvider.java new file mode 100644 index 00000000000..5ff41d952a2 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IImportStructureProvider.java @@ -0,0 +1,64 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.InputStream; +import java.util.List; + +// Similar to org.eclipse.ui.wizards.datatransfer.IImportStructureProvider +// Basically unchanged. +/** + * Interface which can provide structure and content information + * for an element (for example, a file system element). + * Used by the import wizards to abstract the commonalities + * between importing from the file system and importing from an archive. + */ +public interface IImportStructureProvider { + /** + * Returns a collection with the children of the specified structured element. + */ + List getChildren(Object element); + + /** + * Returns the contents of the specified structured element, or + * null if there is a problem determining the element's + * contents. + * + * @param element a structured element + * @return the contents of the structured element, or null + */ + InputStream getContents(Object element); + + /** + * Returns the full path of the specified structured element. + * + * @param element a structured element + * @return the display label of the structured element + */ + String getFullPath(Object element); + + /** + * Returns the display label of the specified structured element. + * + * @param element a structured element + * @return the display label of the structured element + */ + String getLabel(Object element); + + /** + * Returns a boolean indicating whether the passed structured element represents + * a container element (as opposed to a leaf element). + * + * @return boolean + * @param element java.lang.Object + */ + boolean isFolder(Object element); +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionReader.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionReader.java new file mode 100644 index 00000000000..9a36adefc2b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionReader.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +/** + * An interface for remote file export description reader. + */ +public interface IRemoteFileExportDescriptionReader { + public void read(RemoteFileExportData exportData) throws CoreException; + + public void close() throws CoreException; + + public IStatus getStatus(); +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionWriter.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionWriter.java new file mode 100644 index 00000000000..c26959ed213 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileExportDescriptionWriter.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +/** + * An interface for remote file export description writer. + */ +public interface IRemoteFileExportDescriptionWriter { + public void write(RemoteFileExportData exportData) throws CoreException; + + public void close() throws CoreException; + + public IStatus getStatus(); +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionReader.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionReader.java new file mode 100644 index 00000000000..db25ac85bd6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionReader.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +/** + * An interface for remote file import description reader. + */ +public interface IRemoteFileImportDescriptionReader { + public void read(RemoteFileImportData importData) throws CoreException; + + public void close() throws CoreException; + + public IStatus getStatus(); +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionWriter.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionWriter.java new file mode 100644 index 00000000000..720ff03c908 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/IRemoteFileImportDescriptionWriter.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +/** + * An interface for remote file import description writer. + */ +public interface IRemoteFileImportDescriptionWriter { + public void write(RemoteFileImportData importData) throws CoreException; + + public void close() throws CoreException; + + public IStatus getStatus(); +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/MinimizedFileSystemElement.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/MinimizedFileSystemElement.java new file mode 100644 index 00000000000..86c28a2343e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/MinimizedFileSystemElement.java @@ -0,0 +1,99 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.ui.model.AdaptableList; + +// Similar to org.eclipse.ui.wizards.datatransfer.MinimizedFileSystemElement +// Changes marked with "IFS:" comments. +/** + * The MinimizedFileSystemElement is a FileSystemElement that knows + * if it has been populated or not. + */ +// IFS: made class public +public class MinimizedFileSystemElement extends FileSystemElement { + private boolean populated = false; + + /** + * Create a MinimizedFileSystemElement with the supplied name and parent. + * @param name the name of the file element this represents + * @param parent the containing parent + * @param isDirectory indicated if this could have children or not + */ + public MinimizedFileSystemElement(String name, FileSystemElement parent, boolean isDirectory) { + super(name, parent, isDirectory); + } + + /** + * Returns a list of the files that are immediate children. Use the supplied provider + * if it needs to be populated. + * of this folder. + */ + public AdaptableList getFiles(IImportStructureProvider provider) { + if (!populated) populate(provider); + return super.getFiles(); + } + + /** + * Returns a list of the folders that are immediate children. Use the supplied provider + * if it needs to be populated. + * of this folder. + */ + public AdaptableList getFolders(IImportStructureProvider provider) { + if (!populated) populate(provider); + return super.getFolders(); + } + + /** + * Return whether or not population has happened for the receiver. + */ + // IFS: made method public + public boolean isPopulated() { + return this.populated; + } + + /** + * Return whether or not population has not happened for the receiver. + */ + boolean notPopulated() { + return !this.populated; + } + + /** + * Populate the files and folders of the receiver using the suppliec structure provider. + * @param provider org.eclipse.ui.wizards.datatransfer.IImportStructureProvider + */ + private void populate(IImportStructureProvider provider) { + Object fileSystemObject = getFileSystemObject(); + List children = provider.getChildren(fileSystemObject); + if (children == null) children = new ArrayList(1); + Iterator childrenEnum = children.iterator(); + while (childrenEnum.hasNext()) { + Object child = childrenEnum.next(); + String elementLabel = provider.getLabel(child); + //Create one level below + MinimizedFileSystemElement result = new MinimizedFileSystemElement(elementLabel, this, provider.isFolder(child)); + result.setFileSystemObject(child); + } + setPopulated(); + } + + /** + * Set whether or not population has happened for the receiver to true. + */ + public void setPopulated() { + this.populated = true; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizard.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizard.java new file mode 100644 index 00000000000..834e0015d95 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizard.java @@ -0,0 +1,128 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.importexport.SystemImportExportResources; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.wizards.AbstractSystemWizard; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IExportWizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; + +/** + * Standard workbench wizard for exporting resources from the workspace + * to the local file system. + *

+ * This class may be instantiated and used without further configuration; + * this class is not intended to be subclassed. + *

+ *

+ * Example: + *

+ * IWizard wizard = new RemoteExportWizard();
+ * wizard.init(workbench, selection);
+ * WizardDialog dialog = new WizardDialog(shell, wizard);
+ * dialog.open();
+ * 
+ * During the call to open, the wizard dialog is presented to the + * user. When the user hits Finish, the user-selected workspace resources + * are exported to the user-specified location in the local file system, + * the dialog closes, and the call to open returns. + *

+ */ +public class RemoteExportWizard extends AbstractSystemWizard implements IExportWizard { + private IStructuredSelection selection; + private RemoteExportWizardPage1 mainPage; + private RemoteFileExportData exportData; + private boolean initializeFromExportData; + + /** + * Creates a wizard for exporting workspace resources to the local file system. + */ + public RemoteExportWizard() { + IDialogSettings workbenchSettings = RSEUIPlugin.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings.getSection("RemoteExportWizard"); //$NON-NLS-1$ + if (section == null) section = workbenchSettings.addNewSection("RemoteExportWizard"); //$NON-NLS-1$ + setDialogSettings(section); + } + + /* (non-Javadoc) + * Method declared on IWizard. + */ + public void addPages() { + mainPage = new RemoteExportWizardPage1(selection); + addPage(mainPage); + } + + /** + * Returns the image descriptor with the given relative path. + */ + private ImageDescriptor getImageDescriptor(String relativePath) { + String iconPath = "icons/full/"; //$NON-NLS-1$ + return RSEUIPlugin.getDefault().getPluginImage(iconPath + relativePath); + } + + /* (non-Javadoc) + * Method declared on IWorkbenchWizard. + */ + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + // make it the current selection by default but look it up otherwise + this.selection = currentSelection; + if (currentSelection.isEmpty() && workbench.getActiveWorkbenchWindow() != null) { + IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); + if (page != null) { + IEditorPart currentEditor = page.getActiveEditor(); + if (currentEditor != null) { + Object selectedResource = currentEditor.getEditorInput().getAdapter(IResource.class); + if (selectedResource != null) selection = new StructuredSelection(selectedResource); + } + } + } + setInitializeFromExportData(false); + setWindowTitle(SystemImportExportResources.RESID_FILEEXPORT_TITLE); + setDefaultPageImageDescriptor(getImageDescriptor("wizban/export_wiz.gif")); //$NON-NLS-1$ + setNeedsProgressMonitor(true); + } + + public void init(IWorkbench workbench, RemoteFileExportData exportData) { + this.selection = new StructuredSelection(exportData.getElements().toArray()); + this.exportData = exportData; + setInitializeFromExportData(true); + setWindowTitle(SystemImportExportResources.RESID_FILEEXPORT_TITLE); + setDefaultPageImageDescriptor(getImageDescriptor("wizban/export_wiz.gif")); //$NON-NLS-1$ + setNeedsProgressMonitor(true); + } + + protected void setInitializeFromExportData(boolean init) { + this.initializeFromExportData = init; + } + + public boolean getInitializeFromExportData() { + return initializeFromExportData; + } + + public RemoteFileExportData getExportData() { + return exportData; + } + + /** + * Method declared on IWizard. + */ + public boolean performFinish() { + return mainPage.finish(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizardPage1.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizardPage1.java new file mode 100644 index 00000000000..5b93f13b13c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExportWizardPage1.java @@ -0,0 +1,867 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.files.importexport.RemoteImportExportResources; +import org.eclipse.rse.files.importexport.RemoteImportExportUtil; +import org.eclipse.rse.files.ui.actions.SystemSelectRemoteFolderAction; +import org.eclipse.rse.importexport.SystemImportExportResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.rse.ui.messages.SystemMessageLine; +import org.eclipse.rse.ui.wizards.ISystemWizardPage; +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.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.dialogs.SaveAsDialog; +import org.eclipse.ui.dialogs.WizardExportResourcesPage; + +/** + * Page 1 of the base resource export-to-file-system Wizard + * + * 040510 AR Fix "Create folder" question. Previous fix changed the way we were + * asking user if they wanted target folder created, to use RSE + * widgets. But introduced error. + */ +class RemoteExportWizardPage1 extends WizardExportResourcesPage implements Listener, ISystemWizardPage { + private Object destinationFolder = null; + private String helpId; + private Composite parentComposite; + private SystemMessageLine msgLine; + private SystemMessage pendingMessage, pendingErrorMessage; + // widgets + private Combo destinationNameField; + private Button destinationBrowseButton; + protected Button overwriteExistingFilesCheckbox; + protected Button createDirectoryStructureButton; + protected Button createSelectionOnlyButton; + protected Button saveSettingsButton; + protected Label descFilePathLabel; + protected Text descFilePathField; + protected Button descFileBrowseButton; + // input object + protected Object inputObject = null; + // constants + private static final int MY_SIZING_TEXT_FIELD_WIDTH = 250; + // dialog store id constants + private static final String STORE_DESTINATION_NAMES_ID = "RemoteExportWizard.STORE_DESTINATION_NAMES_ID"; //$NON-NLS-1$ + private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "RemoteExportWizard.STORE_OVERWRITE_EXISTING_FILES_ID"; //$NON-NLS-1$ + private static final String STORE_CREATE_STRUCTURE_ID = "RemoteExportWizard.STORE_CREATE_STRUCTURE_ID"; //$NON-NLS-1$ + private static final String STORE_CREATE_DESCRIPTION_FILE_ID = "RemoteExportWizard.STORE_CREATE_DESCRIPTION_FILE_ID"; //$NON-NLS-1$ + private static final String STORE_DESCRIPTION_FILE_NAME_ID = "RemoteExportWizard.STORE_DESCRIPTION_FILE_NAME_ID"; //$NON-NLS-1$ + //messages + private static final SystemMessage DESTINATION_EMPTY_MESSAGE = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_DESTINATION_EMPTY); //UniversalSystemPlugin.getString("IFSexport.destinationEmpty"); + + /** + * Create an instance of this class + */ + protected RemoteExportWizardPage1(String name, IStructuredSelection selection) { + super(name, selection); + setInputObject(selection); + } + + /** + * Create an instance of this class + */ + public RemoteExportWizardPage1(IStructuredSelection selection) { + this("fileSystemExportPage1", selection); //$NON-NLS-1$ + setTitle(SystemImportExportResources.RESID_FILEEXPORT_PAGE1_TITLE); + setDescription(SystemImportExportResources.RESID_FILEEXPORT_PAGE1_DESCRIPTION); + } + + /** + * Add the passed value to self's destination widget's history + * + * @param value java.lang.String + */ + protected void addDestinationItem(String value) { + destinationNameField.add(value); + } + + /** (non-Javadoc) + * Method declared on IDialogPage. + */ + public void createControl(Composite parent) { + parentComposite = new Composite(parent, SWT.NONE); + parentComposite.setLayout(new GridLayout(1, false)); + parentComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + super.createControl(parentComposite); + msgLine = new SystemMessageLine(parentComposite); + msgLine.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + if (pendingMessage != null) setMessage(pendingMessage); + if (pendingErrorMessage != null) setErrorMessage(pendingErrorMessage); + giveFocusToDestination(); + SystemWidgetHelpers.setWizardPageMnemonics(parentComposite); + if (helpId != null) { + SystemWidgetHelpers.setHelp(parentComposite, helpId); + } else { + SystemWidgetHelpers.setHelp(parentComposite, RSEUIPlugin.HELPPREFIX + "import_context"); //$NON-NLS-1$ + } + setControl(parentComposite); + // super.createControl(parent); + // parentComposite = parent; + // giveFocusToDestination(); + // SystemWidgetHelpers.setHelp(getControl(), RSEUIPlugin.HELPPREFIX + "export_context"); + // Control c = getControl(); + // if (c instanceof Composite) + // { + // SystemWidgetHelpers.setWizardPageMnemonics((Composite)c); + // parentComposite = (Composite)c; + // if (helpId != null) + // SystemWidgetHelpers.setHelp(parentComposite, helpId); + // } + // else if (c instanceof Button) + // { + // Mnemonics ms = new Mnemonics(); + // ms.setMnemonic((Button)c); + // } + // configureMessageLine(); + } + + /** + * Create the export destination specification widgets + * + * @param parent org.eclipse.swt.widgets.Composite + */ + protected void createDestinationGroup(Composite parent) { + // destination specification group + Composite destinationSelectionGroup = SystemWidgetHelpers.createComposite(parent, 3); + ((GridData) destinationSelectionGroup.getLayoutData()).verticalAlignment = GridData.FILL; + destinationNameField = SystemWidgetHelpers.createLabeledReadonlyCombo(destinationSelectionGroup, null, SystemImportExportResources.RESID_FILEEXPORT_DESTINATION_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_DESTINATION_TOOLTIP); + ((GridData) destinationNameField.getLayoutData()).widthHint = MY_SIZING_TEXT_FIELD_WIDTH; + ((GridData) destinationNameField.getLayoutData()).grabExcessHorizontalSpace = true; + destinationNameField.addListener(SWT.Modify, this); + destinationNameField.addListener(SWT.Selection, this); + // destination browse button + destinationBrowseButton = SystemWidgetHelpers.createPushButton(destinationSelectionGroup, null, SystemImportExportResources.RESID_FILEEXPORT_DESTINATION_BROWSE_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_DESTINATION_BROWSE_TOOLTIP); + ((GridData) destinationBrowseButton.getLayoutData()).grabExcessHorizontalSpace = false; + destinationBrowseButton.addListener(SWT.Selection, this); + new Label(parent, SWT.NONE); // vertical spacer + } + + /** + * Create the export options specification widgets. + * @param optionsGroup the group into which the option buttons will be placed + */ + protected void createOptionsGroupButtons(Group optionsGroup) { + overwriteExistingFilesCheckbox = SystemWidgetHelpers.createCheckBox(optionsGroup, 1, null, SystemImportExportResources.RESID_FILEEXPORT_OPTION_OVERWRITE_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_OPTION_OVERWRITE_TOOLTIP); + createDirectoryStructureButton = SystemWidgetHelpers.createRadioButton(optionsGroup, null, SystemImportExportResources.RESID_FILEEXPORT_OPTION_CREATEALL_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_OPTION_CREATEALL_TOOLTIP); + createSelectionOnlyButton = SystemWidgetHelpers.createRadioButton(optionsGroup, null, SystemImportExportResources.RESID_FILEEXPORT_OPTION_CREATESEL_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_OPTION_CREATESEL_TOOLTIP); + createSelectionOnlyButton.setSelection(true); + Composite comp = SystemWidgetHelpers.createComposite(optionsGroup, 3); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + layout.marginWidth = 0; + comp.setLayout(layout); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + saveSettingsButton = SystemWidgetHelpers.createCheckBox(comp, 3, null, SystemImportExportResources.RESID_FILEEXPORT_OPTION_SETTINGS_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_OPTION_SETTINGS_TOOLTIP); + saveSettingsButton.addListener(SWT.Selection, this); + descFilePathLabel = new Label(comp, SWT.NONE); + descFilePathLabel.setText(SystemImportExportResources.RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_LABEL); + GridData data = new GridData(); + descFilePathLabel.setLayoutData(data); + descFilePathField = new Text(comp, SWT.SINGLE | SWT.BORDER); + descFilePathField.setToolTipText(SystemImportExportResources.RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP); + data = new GridData(); + data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_FILL; + data.grabExcessHorizontalSpace = true; + data.widthHint = convertWidthInCharsToPixels(80); + descFilePathField.setLayoutData(data); + descFilePathField.addListener(SWT.Modify, this); + descFileBrowseButton = SystemWidgetHelpers.createPushButton(comp, null, SystemImportExportResources.RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_BROWSE_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_BROWSE_TOOLTIP); + descFileBrowseButton.addListener(SWT.Selection, this); + } + + /** + * @see org.eclipse.ui.dialogs.WizardExportResourcesPage#setupBasedOnInitialSelections() + */ + protected void setupBasedOnInitialSelections() { + Object input = getInputObject(); + boolean allResource = true; + // ensure initial input, i.e. selection, comprises of IResources only + if ((input != null) && (input instanceof IStructuredSelection)) { + IStructuredSelection sel = (IStructuredSelection) input; + if (sel.size() > 0) { + Iterator z = sel.iterator(); + while (z.hasNext()) { + Object obj = z.next(); + if (!(obj instanceof IResource)) { + allResource = false; + break; + } + } + } else { + allResource = false; + } + } else { + allResource = false; + } + // if selections are all resources, call super method to setup + if (allResource) { + super.setupBasedOnInitialSelections(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.dialogs.WizardDataTransferPage#updateWidgetEnablements() + */ + protected void updateWidgetEnablements() { + boolean isSaveSettings = isSaveSettings(); + descFilePathLabel.setEnabled(isSaveSettings); + descFilePathField.setEnabled(isSaveSettings); + descFileBrowseButton.setEnabled(isSaveSettings); + } + + /** + * Attempts to ensure that the specified directory exists on the local file system. + * Answers a boolean indicating success. + * + * @return boolean + * @param directory java.io.File + */ + protected boolean ensureDirectoryExists(File directory) { + if (!directory.exists()) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_TARGET_EXISTS); + msg.makeSubstitution(directory.getAbsolutePath()); + SystemMessageDialog dlg = new SystemMessageDialog(getContainer().getShell(), msg); + if (!dlg.openQuestionNoException()) return false; + if (!directory.mkdirs()) { + msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_CREATE_FOLDER_FAILED); + msg.makeSubstitution(directory.getAbsolutePath()); + setErrorMessage(msg); + giveFocusToDestination(); + return false; + } + } + return true; + } + + /** + * If the target for export does not exist then attempt to create it. + * Answer a boolean indicating whether the target exists (ie.- if it + * either pre-existed or this method was able to create it) + * + * @return boolean + */ + protected boolean ensureTargetIsValid(File targetDirectory) { + if (targetDirectory.exists() && !targetDirectory.isDirectory()) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_SOURCE_IS_FILE); + msg.makeSubstitution(targetDirectory.getAbsolutePath()); + setErrorMessage(msg); + giveFocusToDestination(); + return false; + } + return ensureDirectoryExists(targetDirectory); + } + + /** + * Set up and execute the passed Operation. Answer a boolean indicating success. + * + * @return boolean + */ + protected boolean executeExportOperation(RemoteFileExportOperation op) { + try { + getContainer().run(true, true, op); + } catch (InterruptedException e) { + return false; + } catch (InvocationTargetException e) { // Display error dialog if exception is NullPointer, assume this means + // communication failure. See RemoteFileExportOperation.exportFile() + if (!NullPointerException.class.isInstance(e.getTargetException())) { + displayErrorDialog(e.getTargetException()); + return false; + } + } catch (Exception e) { + displayErrorDialog(e.getMessage()); + return false; + } + IStatus status = op.getStatus(); + if (!status.isOK()) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_FAILED); + msg.makeSubstitution(status); + SystemMessageDialog dlg = new SystemMessageDialog(getContainer().getShell(), msg); + dlg.openWithDetails(); + return false; + } + return true; + } + + /** + * The Finish button was pressed. Try to do the required work now and answer + * a boolean indicating success. If false is returned then the wizard will + * not close. + * + * @return boolean + */ + public boolean finish() { + clearMessage(); + clearErrorMessage(); + boolean ret = false; + setDestinationValue(destinationNameField.getText().trim()); + if (Utilities.isConnectionValid(destinationNameField.getText().trim(), getShell()) && isDestinationFolder()) { + if (!ensureTargetIsValid((File) destinationFolder)) return false; + List resourcesToExport = getWhiteCheckedResources(); + //Save dirty editors if possible but do not stop if not all are saved + saveDirtyEditors(); + // about to invoke the operation so save our state + saveWidgetValues(); + if (resourcesToExport.size() > 0) { + // export data + RemoteFileExportData data = new RemoteFileExportData(); + data.setElements(resourcesToExport); + data.setCreateDirectoryStructure(createDirectoryStructureButton.getSelection()); + data.setCreateSelectionOnly(createSelectionOnlyButton.getSelection()); + data.setOverWriteExistingFiles(overwriteExistingFilesCheckbox.getSelection()); + data.setSaveSettings(saveSettingsButton.getSelection()); + data.setDescriptionFilePath(getDescriptionLocation()); + data.setDestination(getDestinationValue()); + // execute export + ret = executeExportOperation(new RemoteFileExportOperation(data, this)); + return ret; + } + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_NONE_SELECTED); + setErrorMessage(msg); + return false; + } + return false; + } + + /** + * Gets the destination. + * @return the desstionation. + */ + protected String getDestinationValue() { + return destinationNameField.getText().trim(); + } + + /** + * Gets the description. + * @return the description. + */ + protected String getDescriptionLocation() { + return descFilePathField.getText().trim(); + } + + /** + * Returns whether the settings should be saved. + * @return whether settings should be saved. + */ + protected boolean isSaveSettings() { + return saveSettingsButton.getSelection(); + } + + /** + * Set the current input focus to self's destination entry field + */ + protected void giveFocusToDestination() { + destinationNameField.setFocus(); + } + + /** + * Open an appropriate destination browser so that the user can specify a source + * to import from + */ + protected void handleDestinationBrowseButtonPressed() { + SystemSelectRemoteFolderAction action = new SystemSelectRemoteFolderAction(this.getShell()); + action.setShowNewConnectionPrompt(true); + action.setShowPropertySheet(true, false); + action.run(); + IRemoteFile folder = action.getSelectedFolder(); + if (folder != null) { + destinationFolder = new UniFilePlus(folder); + setDestinationValue(Utilities.getAsString((UniFilePlus) destinationFolder)); + } + } + + /** + * Open an appropriate destination browser so that the user can specify a source + * to import from. + */ + protected void handleDescriptionFileBrowseButtonPressed() { + SaveAsDialog dialog = new SaveAsDialog(getContainer().getShell()); + dialog.create(); + dialog.getShell().setText(RemoteImportExportResources.IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_TITLE); + dialog.setMessage(RemoteImportExportResources.IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_MESSAGE); + dialog.setOriginalFile(createFileHandle(new Path(getDescriptionLocation()))); + if (dialog.open() == Window.OK) { + IPath path = dialog.getResult(); + path = path.removeFileExtension().addFileExtension(Utilities.EXPORT_DESCRIPTION_EXTENSION); + descFilePathField.setText(path.toString()); + } + } + + /** + * Creates a file resource handle for the file with the given workspace path. + * This method does not create the file resource; this is the responsibility + * of createFile. + * + * @param filePath the path of the file resource to create a handle for + * @return the new file resource handle + */ + protected IFile createFileHandle(IPath filePath) { + if (filePath.isValidPath(filePath.toString()) && filePath.segmentCount() >= 2) + return SystemBasePlugin.getWorkspace().getRoot().getFile(filePath); + else + return null; + } + + /** + * Handle all events and enablements for widgets in this page + * @param e Event + */ + public void handleEvent(Event e) { + Widget source = e.widget; + if (source == destinationBrowseButton) { + handleDestinationBrowseButtonPressed(); + } else if (source == descFileBrowseButton) { + handleDescriptionFileBrowseButtonPressed(); + } + updateWidgetEnablements(); + updatePageCompletion(); + } + + /** + * Hook method for saving widget values for restoration by the next instance + * of this class. + */ + protected void internalSaveWidgetValues() { + // update directory names history + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + String[] directoryNames = settings.getArray(STORE_DESTINATION_NAMES_ID); + if (directoryNames == null) directoryNames = new String[0]; + directoryNames = addToHistory(directoryNames, getDestinationValue()); + settings.put(STORE_DESTINATION_NAMES_ID, directoryNames); + // options + settings.put(STORE_OVERWRITE_EXISTING_FILES_ID, overwriteExistingFilesCheckbox.getSelection()); + settings.put(STORE_CREATE_STRUCTURE_ID, createDirectoryStructureButton.getSelection()); + settings.put(STORE_CREATE_DESCRIPTION_FILE_ID, isSaveSettings()); + settings.put(STORE_DESCRIPTION_FILE_NAME_ID, getDescriptionLocation()); + } + } + + /** + * Method will return boolean value, will issue error if destination is + * null + */ + protected boolean isDestinationFolder() { + boolean ret = destinationFolder != null; + if (!ret) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_IMPORT_EXPORT_UNABLE_TO_USE_CONNECTION); + SystemMessageDialog.show(getShell(), msg); + } + return ret; + } + + /** + * Hook method for restoring widget values to the values that they held + * last time this wizard was used to completion. + */ + protected void restoreWidgetValues() { + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + // destination chosen on previous export + String lastDestination = null; + String[] directoryNames = settings.getArray(STORE_DESTINATION_NAMES_ID); + if (directoryNames != null) { + for (int i = 0; i < directoryNames.length; i++) { + // because of the way we add destination items to history, the + // destination for the previous export would be first + if (i == 0) { + lastDestination = directoryNames[i]; + } + addDestinationItem(directoryNames[i]); + } + } + RemoteExportWizard parentWizard = (RemoteExportWizard) getWizard(); + boolean isInitializingFromExportData = parentWizard.getInitializeFromExportData(); + // options + // no export data to initialize from, so prefill from previous export + if (!isInitializingFromExportData) { + overwriteExistingFilesCheckbox.setSelection(settings.getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID)); + boolean createDirectories = settings.getBoolean(STORE_CREATE_STRUCTURE_ID); + createDirectoryStructureButton.setSelection(createDirectories); + createSelectionOnlyButton.setSelection(!createDirectories); + boolean saveSettings = settings.getBoolean(STORE_CREATE_DESCRIPTION_FILE_ID); + saveSettingsButton.setSelection(saveSettings); + String descFilePathStr = settings.get(STORE_DESCRIPTION_FILE_NAME_ID); + if (descFilePathStr == null) { + descFilePathStr = ""; //$NON-NLS-1$ + } + descFilePathField.setText(descFilePathStr); + // select previous export destination + if (lastDestination != null) { + setDestinationValue(lastDestination); + } + } + // initialize from export data + else { + RemoteFileExportData data = parentWizard.getExportData(); + overwriteExistingFilesCheckbox.setSelection(data.isOverWriteExistingFiles()); + createDirectoryStructureButton.setSelection(data.isCreateDirectoryStructure()); + createSelectionOnlyButton.setSelection(data.isCreateSelectionOnly()); + saveSettingsButton.setSelection(data.isSaveSettings()); + String descFilePathStr = data.getDescriptionFilePath(); + if (descFilePathStr == null) { + descFilePathStr = ""; //$NON-NLS-1$ + } + descFilePathField.setText(descFilePathStr); + String destinationPath = data.getDestination(); + if (destinationPath != null) { + setDestinationValue(destinationPath); + } + } + } + // check if there was an initial selection + // if it is a remote directory, then set the absolute path in the source name field + Object initSelection = getInputObject(); + if ((initSelection != null) && (initSelection instanceof IStructuredSelection)) { + IStructuredSelection sel = (IStructuredSelection) initSelection; + if (sel.size() == 1) { + Object theSel = sel.getFirstElement(); + if (theSel instanceof IRemoteFile) { + IRemoteFile file = (IRemoteFile) theSel; + // set source name if the input is a folder + if (file.isDirectory()) { + destinationFolder = new UniFilePlus(file); + setDestinationValue(Utilities.getAsString((UniFilePlus) destinationFolder)); + } + } + } + } + } + + /** + * Set the contents of the receivers destination specification widget to + * the passed value + * + */ + protected void setDestinationValue(String path) { + if (path.length() > 0) { + String[] currentItems = destinationNameField.getItems(); + int selectionIndex = -1; + for (int i = 0; i < currentItems.length && selectionIndex < 0; i++) { + if (currentItems[i].equals(path)) selectionIndex = i; + } + if (selectionIndex < 0) { + // need to add a new one. + int oldLength = currentItems.length; + String[] newItems = new String[oldLength + 1]; + System.arraycopy(currentItems, 0, newItems, 0, oldLength); + newItems[oldLength] = path; + destinationNameField.setItems(newItems); + selectionIndex = oldLength; + } else { + } + destinationNameField.select(selectionIndex); + } + destinationFolder = null; // clear destination + IHost conn = Utilities.parseForSystemConnection(path); + if (conn != null) { + IRemoteFile rf = Utilities.parseForIRemoteFile(path); + if (rf != null) destinationFolder = new UniFilePlus(rf); + } + } + + /** + * Answer a boolean indicating whether the receivers destination specification + * widgets currently all contain valid values. + */ + protected boolean validateDestinationGroup() { + String destinationValue = getDestinationValue(); + if (destinationValue.length() == 0) { + setMessage(DESTINATION_EMPTY_MESSAGE); + return false; + } + String conflictingContainer = getConflictingContainerNameFor(destinationValue); + if (conflictingContainer != null) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_DESTINATION_CONFLICTING); + msg.makeSubstitution(conflictingContainer); + setErrorMessage(msg); + giveFocusToDestination(); + return false; + } + return true; + } + + /** + * @see org.eclipse.ui.dialogs.WizardDataTransferPage#validateOptionsGroup() + */ + protected boolean validateOptionsGroup() { + if (isSaveSettings()) { + IPath location = new Path(getDescriptionLocation()); + // if location is empty, no error message, but it's not valid + if (location.toString().length() == 0) { + setErrorMessage((String) null); + return false; + } + // location must start with '/' + if (!location.toString().startsWith("/")) { //$NON-NLS-1$ + setErrorMessage(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_ABSOLUTE); + return false; + } + // find the resource, including a variant if any + IResource resource = findResource(location); + // if resource is not a file, it must be a container. So location is pointing to a container, which is an error + if (resource != null && resource.getType() != IResource.FILE) { + setErrorMessage(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_EXISTING_CONTAINER); + return false; + } + // get the resource (or any variant of it) after removing the last segment + // this gets the parent resource + resource = findResource(location.removeLastSegments(1)); + // if parent resource does not exist, or if it is a file, then it is not valid + if (resource == null || resource.getType() == IResource.FILE) { + setErrorMessage(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_NO_CONTAINER); + return false; + } + // get the file extension + String fileExtension = location.getFileExtension(); + // ensure that file extension is valid + if (fileExtension == null || !fileExtension.equals(Utilities.EXPORT_DESCRIPTION_EXTENSION)) { + setErrorMessage(MessageFormat.format(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_INVALID_EXTENSION, new Object[] { Utilities.EXPORT_DESCRIPTION_EXTENSION })); + return false; + } + } + return true; + } + + /** + * Returns the resource for the specified path. + * + * @param path the path for which the resource should be returned + * @return the resource specified by the path or null + */ + protected IResource findResource(IPath path) { + IWorkspace workspace = SystemBasePlugin.getWorkspace(); + // validate path + IStatus result = workspace.validatePath(path.toString(), IResource.ROOT | IResource.PROJECT | IResource.FOLDER | IResource.FILE); + // if path valid + if (result.isOK()) { + // get the workspace root + IWorkspaceRoot root = workspace.getRoot(); + // see if path exists. If it does, return the resource at the path + if (root.exists(path)) { + return root.findMember(path); + } + // see if a variant of the path exists + else { + // look for variant + IResource variant = RemoteImportExportUtil.getInstance().findExistingResourceVariant(path); + // if a variant does exist, return it + if (variant != null) { + return variant; + } + } + } + return null; + } + + /** + * Returns the name of a container with a location that encompasses targetDirectory. + * Returns null if there is no conflict. + * + * @param targetDirectory the path of the directory to check. + * @return the conflicting container name or null + */ + protected String getConflictingContainerNameFor(String targetDirectory) { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IPath testPath = new Path(targetDirectory); + if (root.getLocation().isPrefixOf(testPath)) return "workspace root"; //UniversalSystemPlugin.getString("IFSexport.rootName"); //$NON-NLS-1$ + IProject[] projects = root.getProjects(); + for (int i = 0; i < projects.length; i++) { + if (projects[i].getLocation().isPrefixOf(testPath)) return projects[i].getName(); + } + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#setInputObject(java.lang.Object) + */ + public void setInputObject(Object inputObject) { + this.inputObject = inputObject; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#getInputObject() + */ + public Object getInputObject() { + return inputObject; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#performFinish() + */ + public boolean performFinish() { + return finish(); + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#setHelp(java.lang.String) + */ + public void setHelp(String id) { + if (parentComposite != null) SystemWidgetHelpers.setHelp(parentComposite, helpId); + this.helpId = id; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#getHelpContextId() + */ + public String getHelpContextId() { + return helpId; + } + + /** + * ISystemMessageLine method.
+ * Clears the currently displayed error message and redisplayes + * the message which was active before the error message was set. + */ + public void clearErrorMessage() { + if (msgLine != null) + msgLine.clearErrorMessage(); + else + super.setErrorMessage(null); + } + + /** + * ISystemMessageLine method.
+ * Clears the currently displayed message. + */ + public void clearMessage() { + if (msgLine != null) + msgLine.clearMessage(); + else + super.setMessage(null); + } + + /** + * ISystemMessageLine method.
+ * Get the currently displayed error text. + * @return The error message. If no error message is displayed null is returned. + */ + public SystemMessage getSystemErrorMessage() { + if (msgLine != null) + return msgLine.getSystemErrorMessage(); + else + return null; + } + + /** + * ISystemMessageLine method.
+ * Display the given error message. A currently displayed message + * is saved and will be redisplayed when the error message is cleared. + */ + public void setErrorMessage(SystemMessage message) { + if (msgLine != null) { + if (message != null) + msgLine.setErrorMessage(message); + else + msgLine.clearErrorMessage(); + } else // not configured yet + { + pendingErrorMessage = message; + super.setErrorMessage(message.getLevelOneText()); + } + } + + /** + * ISystemMessageLine method.
+ * Convenience method to set an error message from an exception + */ + public void setErrorMessage(Throwable exc) { + if (msgLine != null) + msgLine.setErrorMessage(exc); + else { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_ERROR_UNEXPECTED); + msg.makeSubstitution(exc); + pendingErrorMessage = msg; + super.setErrorMessage(msg.getLevelOneText()); + } + } + + /** + * ISystemMessageLine method.
+ * Display the given error message. A currently displayed message + * is saved and will be redisplayed when the error message is cleared. + */ + public void setErrorMessage(String message) { + if (msgLine != null) msgLine.setErrorMessage(message); + // super.setErrorMessage(message); + // if (msgLine != null) + // ((SystemDialogPageMessageLine)msgLine).internalSetErrorMessage(message); + } + + /** + * ISystemMessageLine method.
+ * If the message line currently displays an error, + * the message is stored and will be shown after a call to clearErrorMessage + */ + public void setMessage(SystemMessage message) { + if (msgLine != null) + msgLine.setMessage(message); + else // not configured yet + { + pendingMessage = message; + super.setMessage(message.getLevelOneText()); + } + } + + /** + * ISystemMessageLine method.
+ * Set the non-error message text. If the message line currently displays an error, + * the message is stored and will be shown after a call to clearErrorMessage + */ + public void setMessage(String message) { + if (msgLine != null) msgLine.setMessage(message); + // super.setMessage(message); + // if (msgLine!=null) + // ((SystemDialogPageMessageLine)msgLine).internalSetMessage(message); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExporter.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExporter.java new file mode 100644 index 00000000000..8cc10996db0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteExporter.java @@ -0,0 +1,104 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.File; +import java.io.IOException; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.services.files.RemoteFileException; +import org.eclipse.rse.services.files.RemoteFileSecurityException; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; + +// Similar to org.eclipse.ui.wizards.datatransfer.FileSystemExporter +/** + * Helper class for exporting resources to the file system. + */ +class RemoteExporter { + private Object as400 = null; + + /** + * Create an instance of this class. Use this constructor if you wish to + * use an AS400 object */ + public RemoteExporter(IHost s) { + super(); + as400 = s; + } + + /** + * Create an instance of this class. + */ + public RemoteExporter() { + super(); + } + + /** + * Creates the specified file system directory at destinationPath. + * This creates a new file system directory. + */ + public void createFolder(IPath destinationPath) { + // IFS: use IFSJaveFile object if necessary + if (as400 != null) + new UniFilePlus(Utilities.getIRemoteFile((IHost) as400, destinationPath.toString())).mkdir(); + else + new File(destinationPath.toOSString()).mkdir(); + } + + /** + * Writes the passed resource to the specified location recursively + */ + public void write(IResource resource, IPath destinationPath) throws IOException, CoreException, RemoteFileSecurityException, RemoteFileException { + if (resource.getType() == IResource.FILE) + writeFile((IFile) resource, destinationPath); + else + writeChildren((IContainer) resource, destinationPath); + } + + /** + * Exports the passed container's children + */ + protected void writeChildren(IContainer folder, IPath destinationPath) throws IOException, CoreException, RemoteFileSecurityException, RemoteFileException { + if (folder.isAccessible()) { + IResource[] children = folder.members(); + for (int i = 0; i < children.length; i++) { + IResource child = children[i]; + writeResource(child, destinationPath.append(child.getName())); + } + } + } + + /** + * Writes the passed file resource to the specified destination on the remote + * file system + */ + protected void writeFile(IFile file, IPath destinationPath) throws IOException, CoreException, RemoteFileSecurityException, RemoteFileException { + IRemoteFileSubSystem rfss = RemoteFileUtility.getFileSubSystem((IHost) as400); + rfss.upload(file.getLocation().makeAbsolute().toOSString(), destinationPath.toString(), null); + } + + /** + * Writes the passed resource to the specified location recursively + */ + protected void writeResource(IResource resource, IPath destinationPath) throws IOException, CoreException, RemoteFileSecurityException, RemoteFileException { + if (resource.getType() == IResource.FILE) + writeFile((IFile) resource, destinationPath); + else { + createFolder(destinationPath); + writeChildren((IContainer) resource, destinationPath); + } + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportActionDelegate.java new file mode 100644 index 00000000000..87393c69f1a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportActionDelegate.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.files.importexport.RemoteImportExportProblemDialog; +import org.eclipse.rse.files.importexport.RemoteImportExportResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.ui.PlatformUI; + +/** + * This class is a remote file export action. + */ +public class RemoteFileExportActionDelegate extends RemoteFileImportExportActionDelegate { + /** + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + IFile[] descriptions = getDescriptionFiles(getSelection()); + MultiStatus mergedStatus; + int length = descriptions.length; + if (length < 1) { + return; + } + // create read multi status + String message; + if (length > 1) { + message = RemoteImportExportResources.IMPORT_EXPORT_ERROR_CREATE_FILES_FAILED; + } else { + message = RemoteImportExportResources.IMPORT_EXPORT_ERROR_CREATE_FILE_FAILED; + } + MultiStatus readStatus = new MultiStatus(RSEUIPlugin.getDefault().getSymbolicName(), 0, message, null); + RemoteFileExportData[] exportDatas = readExportDatas(descriptions, readStatus); + if (exportDatas.length > 0) { + IStatus status = export(exportDatas); + if (status == null) { + return; + } + if (readStatus.getSeverity() == IStatus.ERROR) { + message = readStatus.getMessage(); + } else { + message = status.getMessage(); + } + // create new status because we want another message - no API to set message + mergedStatus = new MultiStatus(RSEUIPlugin.getDefault().getSymbolicName(), status.getCode(), readStatus.getChildren(), message, null); + mergedStatus.merge(status); + } else { + mergedStatus = readStatus; + } + if (!mergedStatus.isOK()) { + RemoteImportExportProblemDialog.open(getShell(), RemoteImportExportResources.IMPORT_EXPORT_EXPORT_ACTION_DELEGATE_TITLE, null, mergedStatus); + } + } + + private RemoteFileExportData[] readExportDatas(IFile[] descriptions, MultiStatus readStatus) { + List exportDataList = new ArrayList(descriptions.length); + for (int i = 0; i < descriptions.length; i++) { + RemoteFileExportData exportData = readExportData(descriptions[i], readStatus); + if (exportData != null) { + exportDataList.add(exportData); + } + } + return (RemoteFileExportData[]) exportDataList.toArray(new RemoteFileExportData[exportDataList.size()]); + } + + /** + * Reads the file export data from a file. + */ + protected RemoteFileExportData readExportData(IFile description, MultiStatus readStatus) { + Assert.isLegal(description.isAccessible()); + Assert.isNotNull(description.getFileExtension()); + Assert.isLegal(description.getFileExtension().equals(Utilities.EXPORT_DESCRIPTION_EXTENSION)); + RemoteFileExportData exportData = new RemoteFileExportData(); + IRemoteFileExportDescriptionReader reader = null; + try { + reader = exportData.createExportDescriptionReader(description.getContents()); + // read export data + reader.read(exportData); + // do not save settings again + exportData.setSaveSettings(false); + } catch (CoreException ex) { + String message = MessageFormat.format(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_READ, new Object[] { description.getFullPath(), ex.getStatus().getMessage() }); + addToStatus(readStatus, message, ex); + return null; + } finally { + if (reader != null) { + readStatus.addAll(reader.getStatus()); + } + try { + if (reader != null) { + reader.close(); + } + } catch (CoreException ex) { + String message = MessageFormat.format(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_CLOSE, new Object[] { description.getFullPath() }); + addToStatus(readStatus, message, ex); + } + } + return exportData; + } + + private IStatus export(RemoteFileExportData[] exportDatas) { + IStatus status = null; + for (int i = 0; i < exportDatas.length; i++) { + RemoteFileExportOperation op = new RemoteFileExportOperation(exportDatas[i], new RemoteFileOverwriteQuery()); + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, op); + status = op.getStatus(); + } catch (InvocationTargetException e) { + SystemBasePlugin.logError("Error occured trying to export", e); //$NON-NLS-1$ + status = new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, "", e); //$NON-NLS-1$ + } catch (InterruptedException e) { + SystemBasePlugin.logError("Error occured trying to export", e); //$NON-NLS-1$ + status = new Status(IStatus.OK, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, "", e); //$NON-NLS-1$ + } + if (!status.isOK()) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_FAILED); + msg.makeSubstitution(status); + SystemMessageDialog dlg = new SystemMessageDialog(getShell(), msg); + dlg.openWithDetails(); + return null; + } + } + return null; + } + + protected void addToStatus(MultiStatus multiStatus, String defaultMessage, CoreException ex) { + IStatus status = ex.getStatus(); + String message = ex.getLocalizedMessage(); + if (message == null || message.length() < 1) { + status = new Status(status.getSeverity(), status.getPlugin(), status.getCode(), defaultMessage, ex); + } + multiStatus.add(status); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportData.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportData.java new file mode 100644 index 00000000000..b63ce692c73 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportData.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.rse.core.SystemBasePlugin; + +/** + * Holds data of what to export. + */ +public class RemoteFileExportData { + private String destination; + private boolean overWriteExistingFiles; + private boolean createDirectoryStructure; + private boolean createSelectionOnly; + private boolean saveSettings; + private String descriptionFilePath; + // export elements + private List elements; + + /** + * Constructor. + */ + public RemoteFileExportData() { + setDestination(null); + setOverWriteExistingFiles(false); + setCreateDirectoryStructure(false); + setCreateSelectionOnly(true); + setSaveSettings(false); + setDescriptionFilePath(null); + } + + /** + * @return Returns the descriptionFilePath. + */ + public String getDescriptionFilePath() { + return descriptionFilePath; + } + + /** + * Gets the description file as a workspace resource. + * @return a file representing the description file. + */ + public IFile getDescriptionFile() { + IPath path = new Path(getDescriptionFilePath()); + if (path.isValidPath(path.toString()) && path.segmentCount() >= 2) { + return SystemBasePlugin.getWorkspace().getRoot().getFile(path); + } else { + return null; + } + } + + /** + * @param descriptionFilePath The descriptionFilePath to set. + */ + public void setDescriptionFilePath(String descriptionFilePath) { + this.descriptionFilePath = descriptionFilePath; + } + + /** + * @return Returns the destination. + */ + public String getDestination() { + return destination; + } + + /** + * @param destination The destination to set. + */ + public void setDestination(String destination) { + this.destination = destination; + } + + /** + * Returns the elements to be exported. + * @return the elements. + */ + public List getElements() { + return elements; + } + + /** + * Sets the elements to export. + * @param elements the elements. + */ + public void setElements(List elements) { + this.elements = elements; + } + + /** + * @return Returns the overWriteExistingFiles. + */ + public boolean isOverWriteExistingFiles() { + return overWriteExistingFiles; + } + + /** + * @param overWriteExistingFiles The overWriteExistingFiles to set. + */ + public void setOverWriteExistingFiles(boolean overWriteExistingFiles) { + this.overWriteExistingFiles = overWriteExistingFiles; + } + + /** + * @return Returns the saveSettings. + */ + public boolean isSaveSettings() { + return saveSettings; + } + + /** + * @param saveSettings The saveSettings to set. + */ + public void setSaveSettings(boolean saveSettings) { + this.saveSettings = saveSettings; + } + + /** + * @return Returns the createDirectoryStructure. + */ + public boolean isCreateDirectoryStructure() { + return createDirectoryStructure; + } + + /** + * @param createDirectoryStructure The createDirectoryStructure to set. + */ + public void setCreateDirectoryStructure(boolean createDirectoryStructure) { + this.createDirectoryStructure = createDirectoryStructure; + } + + /** + * @return Returns the createSelectionOnly. + */ + public boolean isCreateSelectionOnly() { + return createSelectionOnly; + } + + /** + * @param createSelectionOnly The createSelectionOnly to set. + */ + public void setCreateSelectionOnly(boolean createSelectionOnly) { + this.createSelectionOnly = createSelectionOnly; + } + + /** + * Creates and returns an export description writer. + */ + public IRemoteFileExportDescriptionWriter createExportDescriptionWriter(OutputStream outputStream) { + return new RemoteFileExportDescriptionWriter(outputStream); + } + + /** + * Creates and returns an export description writer. + */ + public IRemoteFileExportDescriptionReader createExportDescriptionReader(InputStream inputStream) { + return new RemoteFileExportDescriptionReader(inputStream); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionReader.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionReader.java new file mode 100644 index 00000000000..4144523e62d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionReader.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Remote file export description reader. + */ +public class RemoteFileExportDescriptionReader implements IRemoteFileExportDescriptionReader { + protected InputStream fInputStream; + + /** + * Constructor. + */ + public RemoteFileExportDescriptionReader(InputStream inputStream) { + Assert.isNotNull(inputStream); + fInputStream = new BufferedInputStream(inputStream); + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileExportDescriptionReader#read(org.eclipse.rse.files.importexport.files.RemoteFileExportData) + */ + public void read(RemoteFileExportData exportData) throws CoreException { + try { + readXML(exportData); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } catch (SAXException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + + public RemoteFileExportData readXML(RemoteFileExportData exportData) throws IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + DocumentBuilder parser = null; + try { + parser = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new IOException(ex.getLocalizedMessage()); + } + Element xmlFileDesc = parser.parse(new InputSource(fInputStream)).getDocumentElement(); + if (!xmlFileDesc.getNodeName().equals(Utilities.EXPORT_DESCRIPTION_EXTENSION)) { + throw new IOException(); + } + NodeList topLevelElements = xmlFileDesc.getChildNodes(); + for (int i = 0; i < topLevelElements.getLength(); i++) { + Node node = topLevelElements.item(i); + if (node.getNodeType() != Node.ELEMENT_NODE) continue; + Element element = (Element) node; + xmlReadDestinationLocation(exportData, element); + xmlReadOptions(exportData, element); + xmlReadSelectedElements(exportData, element); + } + return exportData; + } + + private void xmlReadDestinationLocation(RemoteFileExportData exportData, Element element) { + if (element.getNodeName().equals("destination")) { //$NON-NLS-1$ + exportData.setDestination(element.getAttribute("path")); //$NON-NLS-1$ + } + } + + private void xmlReadOptions(RemoteFileExportData exportData, Element element) throws IOException { + if (element.getNodeName().equals("options")) { //$NON-NLS-1$ + exportData.setOverWriteExistingFiles(getBooleanAttribute(element, "overWriteExistingFiles")); //$NON-NLS-1$ + exportData.setCreateDirectoryStructure(getBooleanAttribute(element, "createDirectoryStructure")); //$NON-NLS-1$ + exportData.setCreateSelectionOnly(getBooleanAttribute(element, "createSelectedOnly")); //$NON-NLS-1$ + exportData.setSaveSettings(getBooleanAttribute(element, "saveSettings")); //$NON-NLS-1$ + exportData.setDescriptionFilePath(element.getAttribute("descriptionFilePath")); //$NON-NLS-1$ + } + } + + private void xmlReadSelectedElements(RemoteFileExportData exportData, Element element) throws IOException { + if (element.getNodeName().equals("selectedElements")) { //$NON-NLS-1$ + NodeList selectedElements = element.getChildNodes(); + List elementsToExport = new ArrayList(selectedElements.getLength()); + for (int j = 0; j < selectedElements.getLength(); j++) { + Node selectedNode = selectedElements.item(j); + if (selectedNode.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + Element selectedElement = (Element) selectedNode; + if (selectedElement.getNodeName().equals("file")) { //$NON-NLS-1$ + addFile(elementsToExport, selectedElement); + } else if (selectedElement.getNodeName().equals("folder")) { //$NON-NLS-1$ + addFolder(elementsToExport, selectedElement); + } else if (selectedElement.getNodeName().equals("project")) { //$NON-NLS-1$ + addProject(elementsToExport, selectedElement); + } + } + exportData.setElements(elementsToExport); + } + } + + private void addFile(List selectedElements, Element element) throws IOException { + IPath path = getPath(element); + if (path != null) { + IFile file = SystemBasePlugin.getWorkspace().getRoot().getFile(path); + if (file != null) { + selectedElements.add(file); + } + } + } + + private void addFolder(List selectedElements, Element element) throws IOException { + IPath path = getPath(element); + if (path != null) { + IFolder folder = SystemBasePlugin.getWorkspace().getRoot().getFolder(path); + if (folder != null) { + selectedElements.add(folder); + } + } + } + + private void addProject(List selectedElements, Element element) throws IOException { + String name = element.getAttribute("name"); //$NON-NLS-1$ + if (name.equals("")) { //$NON-NLS-1$ + throw new IOException(); + } + IProject project = SystemBasePlugin.getWorkspace().getRoot().getProject(name); + if (project != null) { + selectedElements.add(project); + } + } + + private IPath getPath(Element element) throws IOException { + String pathString = element.getAttribute("path"); //$NON-NLS-1$ + if (pathString.equals("")) { //$NON-NLS-1$ + throw new IOException(); + } + return new Path(element.getAttribute("path")); //$NON-NLS-1$ + } + + protected boolean getBooleanAttribute(Element element, String name) throws IOException { + String value = element.getAttribute(name); + if (value != null && value.equalsIgnoreCase("true")) { //$NON-NLS-1$ + return true; + } + if (value != null && value.equalsIgnoreCase("false")) { //$NON-NLS-1$ + return false; + } + throw new IOException(); + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileExportDescriptionReader#close() + */ + public void close() throws CoreException { + if (fInputStream != null) { + try { + fInputStream.close(); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileExportDescriptionReader#getStatus() + */ + public IStatus getStatus() { + return new Status(IStatus.OK, RSEUIPlugin.getDefault().getSymbolicName(), 0, "", null); //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionWriter.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionWriter.java new file mode 100644 index 00000000000..115c577e2e7 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportDescriptionWriter.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Remote file export description writer. + */ +public class RemoteFileExportDescriptionWriter implements IRemoteFileExportDescriptionWriter { + protected OutputStream fOutputStream; + + /** + * Constructor. + */ + public RemoteFileExportDescriptionWriter(OutputStream outputStream) { + Assert.isNotNull(outputStream); + fOutputStream = new BufferedOutputStream(outputStream); + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileExportDescriptionWriter#write(org.eclipse.rse.files.importexport.files.RemoteFileExportData) + */ + public void write(RemoteFileExportData exportData) throws CoreException { + try { + writeXML(exportData); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + + /** + * Writes a XML representation of file export data. + * @exception IOException if writing to the underlying stream fails. + */ + public void writeXML(RemoteFileExportData exportData) throws IOException { + Assert.isNotNull(exportData); + DocumentBuilder docBuilder = null; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + try { + docBuilder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new IOException(ex.getLocalizedMessage()); + } + Document document = docBuilder.newDocument(); + // create the document + Element xmlFileDesc = document.createElement(Utilities.EXPORT_DESCRIPTION_EXTENSION); + document.appendChild(xmlFileDesc); + xmlWriteDestinationLocation(exportData, document, xmlFileDesc); + xmlWriteOptions(exportData, document, xmlFileDesc); + xmlWriteSelectedElements(exportData, document, xmlFileDesc); + try { + // write the document to the stream + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$ + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(fOutputStream); + transformer.transform(source, result); + } catch (TransformerException e) { + throw new IOException(e.getLocalizedMessage()); + } + } + + private void xmlWriteDestinationLocation(RemoteFileExportData exportData, Document document, Element xmlFileDesc) throws DOMException { + Element destination = document.createElement("destination"); //$NON-NLS-1$ + xmlFileDesc.appendChild(destination); + destination.setAttribute("path", exportData.getDestination()); //$NON-NLS-1$ + } + + private void xmlWriteOptions(RemoteFileExportData exportData, Document document, Element xmlFileDesc) throws DOMException { + Element options = document.createElement("options"); //$NON-NLS-1$ + xmlFileDesc.appendChild(options); + options.setAttribute("overWriteExistingFiles", "" + exportData.isOverWriteExistingFiles()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("createDirectoryStructure", "" + exportData.isCreateDirectoryStructure()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("createSelectedOnly", "" + exportData.isCreateSelectionOnly()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("saveSettings", "" + exportData.isSaveSettings()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("descriptionFilePath", "" + exportData.getDescriptionFilePath()); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void xmlWriteSelectedElements(RemoteFileExportData exportData, Document document, Element xmlFileDesc) throws DOMException { + Element selectedElements = document.createElement("selectedElements"); //$NON-NLS-1$ + xmlFileDesc.appendChild(selectedElements); + List elements = exportData.getElements(); + Iterator iter = elements.iterator(); + while (iter.hasNext()) { + Object element = iter.next(); + if (element instanceof IResource) { + add((IResource) element, selectedElements, document); + } + } + } + + private void add(IResource resource, Element parent, Document document) { + Element element = null; + if (resource.getType() == IResource.PROJECT) { + element = document.createElement("project"); //$NON-NLS-1$ + parent.appendChild(element); + element.setAttribute("name", resource.getName()); //$NON-NLS-1$ + return; + } + if (resource.getType() == IResource.FILE) { + element = document.createElement("file"); //$NON-NLS-1$ + } else if (resource.getType() == IResource.FOLDER) { + element = document.createElement("folder"); //$NON-NLS-1$ + } + if (element != null) { + parent.appendChild(element); + element.setAttribute("path", resource.getFullPath().toString()); //$NON-NLS-1$ + } + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileExportDescriptionWriter#close() + */ + public void close() throws CoreException { + if (fOutputStream != null) { + try { + fOutputStream.close(); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileExportDescriptionWriter#getStatus() + */ + public IStatus getStatus() { + return new Status(IStatus.OK, RSEUIPlugin.getDefault().getSymbolicName(), 0, "", null); //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportFromProjectActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportFromProjectActionDelegate.java new file mode 100644 index 00000000000..6e08f1436b6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportFromProjectActionDelegate.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.wizard.WizardDialog; + +/** + * This class represents the action to bring up the remote file system export wizard + * and export the contents of a project or projects to a remote folder. + */ +public class RemoteFileExportFromProjectActionDelegate extends RemoteFileImportExportActionDelegate { + /** + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + RemoteExportWizard wizard = new RemoteExportWizard(); + wizard.init(getWorkbench(), getSelection()); + WizardDialog dialog = new WizardDialog(getShell(), wizard); + dialog.create(); + dialog.open(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportOperation.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportOperation.java new file mode 100644 index 00000000000..7a2663e4086 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileExportOperation.java @@ -0,0 +1,536 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.operation.ModalContext; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.files.importexport.RemoteImportExportUtil; +import org.eclipse.rse.files.ui.resources.SystemIFileProperties; +import org.eclipse.rse.importexport.SystemImportExportResources; +import org.eclipse.rse.services.files.RemoteFileIOException; +import org.eclipse.rse.services.files.RemoteFileSecurityException; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.IOverwriteQuery; + +/** + * Operation for exporting the contents of a resource to the local file system. + */ +class RemoteFileExportOperation implements IRunnableWithProgress { + private IHost conn; + private IPath path; + private IProgressMonitor monitor; + private RemoteExporter exporter; + private List resourcesToExport; + private IOverwriteQuery overwriteCallback; + private IResource resource; + private List errorTable = new ArrayList(1); + private RemoteFileExportData exportData; + private boolean saveSettings; + private String descriptionFilePath; + // the constants for the overwrite 3 state + private static final int OVERWRITE_NOT_SET = 0; + private static final int OVERWRITE_NONE = 1; + private static final int OVERWRITE_ALL = 2; + private int overwriteState = OVERWRITE_NOT_SET; + private boolean createLeadupStructure = true; + private boolean createContainerDirectories = true; + + /** + * Create an instance of this class. Use this constructor if you wish to + * export specific resources with a common parent resource (affects container + * directory creation). + */ + private RemoteFileExportOperation(IHost conn, IResource resource, List resources, String destinationPath, IOverwriteQuery overwriteImplementor) { + this.conn = conn; + this.resource = resource; + this.resourcesToExport = resources; + this.path = new Path(destinationPath); + this.overwriteCallback = overwriteImplementor; + this.exporter = new RemoteExporter(conn); + } + + public RemoteFileExportOperation(RemoteFileExportData data, IOverwriteQuery overwriteImplementor) { + this(Utilities.parseForSystemConnection(data.getDestination()), null, data.getElements(), Utilities.parseForPath(data.getDestination()), overwriteImplementor); + this.exportData = data; + this.saveSettings = data.isSaveSettings(); + this.descriptionFilePath = data.getDescriptionFilePath(); + setCreateLeadupStructure(data.isCreateDirectoryStructure()); + setOverwriteFiles(data.isOverWriteExistingFiles()); + } + + /** + * Add a new entry to the error table with the passed information + */ + protected void addError(String message, Throwable e) { + errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, e)); + } + + /** + * Answer the total number of file resources that exist at or below self in the + * resources hierarchy. + * + * @return int + * @param resource org.eclipse.core.resources.IResource + */ + protected int countChildrenOf(IResource resource) throws CoreException { + if (resource.getType() == IResource.FILE) return 1; + int count = 0; + if (resource.isAccessible()) { + IResource[] children = ((IContainer) resource).members(); + for (int i = 0; i < children.length; i++) + count += countChildrenOf(children[i]); + } + return count; + } + + /** + * Answer a boolean indicating the number of file resources that were + * specified for export + * + * @return int + */ + protected int countSelectedResources() throws CoreException { + int result = 0; + Iterator resources = resourcesToExport.iterator(); + while (resources.hasNext()) + result += countChildrenOf((IResource) resources.next()); + return result; + } + + /** + * Create the directories required for exporting the passed resource, + * based upon its container hierarchy + * + * @param resource org.eclipse.core.resources.IResource + */ + protected void createLeadupDirectoriesFor(IResource resource) { + IPath resourcePath = resource.getFullPath().removeLastSegments(1); + for (int i = 0; i < resourcePath.segmentCount(); i++) { + path = path.append(resourcePath.segment(i)); + exporter.createFolder(path); + } + } + + /** + * Recursively export the previously-specified resource + */ + protected void exportAllResources() throws InterruptedException { + if (resource.getType() == IResource.FILE) + exportFile((IFile) resource, path); + else { + try { + exportChildren(((IContainer) resource).members(), path); + } catch (CoreException e) { + // not safe to show a dialog + // should never happen because the file system export wizard ensures that the + // single resource chosen for export is both existent and accessible + errorTable.add(e); + } + } + } + + /** + * Export all of the resources contained in the passed collection + * + * @param children java.util.Enumeration + * @param currentPath IPath + */ + protected void exportChildren(IResource[] children, IPath currentPath) throws InterruptedException { + for (int i = 0; i < children.length; i++) { + IResource child = children[i]; + if (!child.isAccessible()) continue; + if (child.getType() == IResource.FILE) + exportFile((IFile) child, currentPath); + else { + IPath destination = currentPath.append(child.getName()); + try { + exporter.createFolder(destination); + } catch (Exception e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, new Object[] { destination, e.getLocalizedMessage() == null ? e.toString() : e.getMessage(), e }) + .toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + } + try { + exportChildren(((IContainer) child).members(), destination); + } catch (CoreException e) { + // not safe to show a dialog + // should never happen because: + // i. this method is called recursively iterating over the result of #members, + // which only answers existing children + // ii. there is an #isAccessible check done before #members is invoked + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, e.getMessage(), e)); + //errorTable.add(e.getStatus()); + } + } + } + } + + /** + * Export the passed file to the specified location + * + * @param file org.eclipse.core.resources.IFile + * @param location org.eclipse.core.runtime.IPath + */ + protected void exportFile(IFile file, IPath location) throws InterruptedException { + IPath fullPath = location.append(file.getName()); + String destination = fullPath.toString(); + // flag to indicate whether export is required + boolean exportRequired = false; + monitor.subTask(file.getFullPath().toString()); + String properPathString = fullPath.toOSString(); + File targetFile = null; + if (conn == null) { + targetFile = new File(properPathString); + } else { + try { + targetFile = new UniFilePlus(Utilities.getIRemoteFile(conn, fullPath.toString())); + } catch (NullPointerException e) { + // Assume that communication has failed. + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, + new Object[] { fullPath, RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_IMPORT_EXPORT_UNABLE_TO_USE_CONNECTION).getLevelOneText(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + throw e; + } + } + if (targetFile.exists()) { + exportRequired = isExportRequired(file, destination); + // if export is not required, no need to do anything + if (!exportRequired) { + return; + } + if (!targetFile.canWrite()) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_NOT_WRITABLE, targetFile.getAbsolutePath()).toString(); + errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, null)); + monitor.worked(1); + return; + } + if (overwriteState == OVERWRITE_NONE) { + return; + } else if (overwriteState != OVERWRITE_ALL) { + String overwriteAnswer = overwriteCallback.queryOverwrite(properPathString); + if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) { + throw new InterruptedException(); + } else if (overwriteAnswer.equals(IOverwriteQuery.NO)) { + monitor.worked(1); + return; + } else if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) { + monitor.worked(1); + overwriteState = OVERWRITE_NONE; + return; + } else if (overwriteAnswer.equals(IOverwriteQuery.ALL)) { + overwriteState = OVERWRITE_ALL; + } + } + } else if (!targetFile.exists()) { + // need to do an export if target file does not exist, even if the local + // file has not changed. This is for the scenario where a file may have been + // exported, and the server copy was later deleted. The next export should put + // the local copy back on the server, even if the local file was not changed. + exportRequired = true; + } + try { + exporter.write(file, fullPath); + // if there are no exceptions, we should be here and the export should have completed fine + // so we update the modification time at the time of export + SystemIFileProperties props = new SystemIFileProperties(file); + long modTime = file.getModificationStamp(); + props.setModificationStampAtExport(conn.getHostName(), destination, modTime); + } catch (IOException e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, new Object[] { fullPath, e.getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, e)); + } catch (CoreException e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, new Object[] { fullPath, e.getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, e)); + } catch (RemoteFileIOException e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, new Object[] { fullPath, e.getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + } catch (RemoteFileSecurityException e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, new Object[] { fullPath, e.getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + } catch (Exception e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_ERROR, new Object[] { fullPath, e.getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, e)); + } + monitor.worked(1); + ModalContext.checkCanceled(monitor); + } + + protected boolean isExportRequired(IFile file, String destinationPath) { + if (conn != null) { + // get the host name of the connection + String hostName = conn.getHostName(); + SystemIFileProperties props = new SystemIFileProperties(file); + // check if we have a modification time stored for the hostname/destination path combination + boolean hasModTime = props.hasModificationStampAtExport(hostName, destinationPath); + // if not, that means we are exporting for the first time + if (!hasModTime) { + return true; + } + // otherwise, check if the modification time stored is different to the modification time + // of the file + else { + long modTime = props.getModificationStampAtExport(hostName, destinationPath); + long currentModTime = file.getModificationStamp(); + // if the modification timestamps are different, then the file has changed + // since the last export to the destination, so we need export it again + if (modTime != currentModTime) { + return true; + } + // otherwise, do not export + else { + return false; + } + } + } + return true; + } + + /** + * Export the resources contained in the previously-defined + * resourcesToExport collection + */ + protected void exportSpecifiedResources() throws InterruptedException { + Iterator resources = resourcesToExport.iterator(); + IPath initPath = (IPath) path.clone(); + while (resources.hasNext()) { + IResource currentResource = (IResource) resources.next(); + if (!currentResource.isAccessible()) continue; + path = initPath; + if (resource == null) { + // No root resource specified and creation of containment directories + // is required. Create containers from depth 2 onwards (ie.- project's + // child inclusive) for each resource being exported. + if (createLeadupStructure) createLeadupDirectoriesFor(currentResource); + } else { + // Root resource specified. Must create containment directories + // from this point onwards for each resource being exported + IPath containersToCreate = currentResource.getFullPath().removeFirstSegments(resource.getFullPath().segmentCount()).removeLastSegments(1); + for (int i = 0; i < containersToCreate.segmentCount(); i++) { + path = path.append(containersToCreate.segment(i)); + exporter.createFolder(path); + } + } + if (currentResource.getType() == IResource.FILE) + exportFile((IFile) currentResource, path); + else { + if (createContainerDirectories) { + path = path.append(currentResource.getName()); + exporter.createFolder(path); + } + try { + exportChildren(((IContainer) currentResource).members(), path); + } catch (CoreException e) { + // should never happen because #isAccessible is called before #members is invoked, + // which implicitly does an existence check + errorTable.add(e.getStatus()); + } + } + } + } + + /** + * Returns the status of the export operation. + * If there were any errors, the result is a status object containing + * individual status objects for each error. + * If there were no errors, the result is a status object with error code OK. + * + * @return the status + */ + public IStatus getStatus() { + IStatus[] errors = new IStatus[errorTable.size()]; + errorTable.toArray(errors); + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_EXPORT_PROBLEMS).getLevelOneText(); + return new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, errors, msg, null); + } + + /** + * Answer a boolean indicating whether the passed child is a descendent + * of one or more members of the passed resources collection + * + * @return boolean + * @param resources java.util.List + * @param child org.eclipse.core.resources.IResource + */ + protected boolean isDescendent(List resources, IResource child) { + if (child.getType() == IResource.PROJECT) return false; + IResource parent = child.getParent(); + if (resources.contains(parent)) return true; + return isDescendent(resources, parent); + } + + /** + * Export the resources that were previously specified for export + * (or if a single resource was specified then export it recursively) + */ + public void run(IProgressMonitor monitor) throws InterruptedException { + this.monitor = monitor; + if (resource != null) { + if (createLeadupStructure) createLeadupDirectoriesFor(resource); + if (createContainerDirectories && resource.getType() != IResource.FILE) { // ensure it's a container + path = path.append(resource.getName()); + exporter.createFolder(path); + } + } + try { + int totalWork = IProgressMonitor.UNKNOWN; + try { + if (resourcesToExport == null) + totalWork = countChildrenOf(resource); + else + totalWork = countSelectedResources(); + } catch (CoreException e) { + // Should not happen + errorTable.add(e.getStatus()); + } + String taskMsg = SystemImportExportResources.RESID_FILEEXPORT_EXPORTING; + monitor.beginTask(taskMsg, totalWork); + if (resourcesToExport == null) { + exportAllResources(); + } else { + exportSpecifiedResources(); + } + if (saveSettings) { + try { + saveDescription(); + } catch (CoreException e) { + SystemBasePlugin.logError("Error occured trying to save description " + descriptionFilePath, e); //$NON-NLS-1$ + errorTable.add(e.getStatus()); + } catch (IOException e) { + SystemBasePlugin.logError("Error occured trying to save description " + descriptionFilePath, e); //$NON-NLS-1$ + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, e.getLocalizedMessage(), e)); + } + } + } finally { + monitor.done(); + } + } + + /** + * Saves a description file for the export. + * @throws CoreException if an unexpected exception occurs. + * @throws IOException if an I/O error occurs. + */ + protected void saveDescription() throws CoreException, IOException { + ByteArrayOutputStream objectStreamOutput = new ByteArrayOutputStream(); + IRemoteFileExportDescriptionWriter writer = exportData.createExportDescriptionWriter(objectStreamOutput); + ByteArrayInputStream fileInput = null; + try { + writer.write(exportData); + fileInput = new ByteArrayInputStream(objectStreamOutput.toByteArray()); + IFile descriptionFile = exportData.getDescriptionFile(); + // check if resource exists + if (descriptionFile.isAccessible()) { + descriptionFile.setContents(fileInput, true, true, null); + } + // if resource does not exist + else { + // now have to check if a variant of this file exists (i.e. whether a file exists + // that has the same path with a different case. For case insensitive file systems + // such as Windows, this is needed since we can't simply create a file with a different + // case. Note that isAccessible() above does not check for file paths with different case, + // so we have to check it explicitly). + IResource variant = RemoteImportExportUtil.getInstance().findExistingResourceVariant(descriptionFile.getFullPath()); + // if a variant was not found, create the new file + if (variant == null) { + // check if a variant of the parent exists + // we need to do this because at this point we know that the file path does not + // exist, and neither does its variant. However, it is possible that the parent path + // has a variant, in which case calling create on the description file with + // the path as it is given will fail. We need to get the variant path of the parent, + // append the name of the file to the variant path, and create a file with that path. + // get parent + IResource parent = descriptionFile.getParent(); + if (parent != null) { + // get parent path + IResource parentVariant = RemoteImportExportUtil.getInstance().findExistingResourceVariant(parent.getFullPath()); + // no parent variant (i.e. in a case sensitive file system) + if (parentVariant == null) { + descriptionFile.create(fileInput, true, null); + } + // parent variant found (might be same as original parent path) + else { + IPath newPath = parentVariant.getFullPath().append(descriptionFile.getName()); + IFile newDescriptionFile = SystemBasePlugin.getWorkspace().getRoot().getFile(newPath); + newDescriptionFile.create(fileInput, true, null); + } + } + } + // otherwise, simply set the contents of the variant file + else { + if (variant instanceof IFile) { + ((IFile) variant).setContents(fileInput, true, true, null); + } + } + } + } finally { + if (fileInput != null) { + fileInput.close(); + } + if (writer != null) { + writer.close(); + } + } + } + + /** + * Set this boolean indicating whether a directory should be created for + * Folder resources that are explicitly passed for export + * + * @param value boolean + */ + public void setCreateContainerDirectories(boolean value) { + createContainerDirectories = value; + } + + /** + * Set this boolean indicating whether each exported resource's complete path should + * include containment hierarchies as dictated by its parents + * + * @param value boolean + */ + public void setCreateLeadupStructure(boolean value) { + createLeadupStructure = value; + } + + /** + * Set this boolean indicating whether exported resources should automatically + * overwrite existing files when a conflict occurs + * + * @param value boolean + */ + public void setOverwriteFiles(boolean value) { + if (value) { + overwriteState = OVERWRITE_ALL; + } + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportActionDelegate.java new file mode 100644 index 00000000000..0eb70d5a3fa --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportActionDelegate.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.IAction; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.files.importexport.RemoteImportExportProblemDialog; +import org.eclipse.rse.files.importexport.RemoteImportExportResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.ui.PlatformUI; + +/** + * This class is a remote file import action. + */ +public class RemoteFileImportActionDelegate extends RemoteFileImportExportActionDelegate { + /** + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + IFile[] descriptions = getDescriptionFiles(getSelection()); + MultiStatus mergedStatus; + int length = descriptions.length; + if (length < 1) { + return; + } + // create read multi status + String message; + if (length > 1) { + message = RemoteImportExportResources.IMPORT_EXPORT_ERROR_CREATE_FILES_FAILED; + } else { + message = RemoteImportExportResources.IMPORT_EXPORT_ERROR_CREATE_FILE_FAILED; + } + MultiStatus readStatus = new MultiStatus(RSEUIPlugin.getDefault().getSymbolicName(), 0, message, null); + RemoteFileImportData[] importDatas = readImportDatas(descriptions, readStatus); + if (importDatas.length > 0) { + IStatus status = importFiles(importDatas); + if (status == null) { + return; + } + if (readStatus.getSeverity() == IStatus.ERROR) { + message = readStatus.getMessage(); + } else { + message = status.getMessage(); + } + // create new status because we want another message - no API to set message + mergedStatus = new MultiStatus(RSEUIPlugin.getDefault().getSymbolicName(), status.getCode(), readStatus.getChildren(), message, null); + mergedStatus.merge(status); + } else { + mergedStatus = readStatus; + } + if (!mergedStatus.isOK()) { + RemoteImportExportProblemDialog.open(getShell(), RemoteImportExportResources.IMPORT_EXPORT_IMPORT_ACTION_DELEGATE_TITLE, null, mergedStatus); + } + } + + private RemoteFileImportData[] readImportDatas(IFile[] descriptions, MultiStatus readStatus) { + List importDataList = new ArrayList(descriptions.length); + for (int i = 0; i < descriptions.length; i++) { + RemoteFileImportData importData = readImportData(descriptions[i], readStatus); + if (importData != null) { + importDataList.add(importData); + } + } + return (RemoteFileImportData[]) importDataList.toArray(new RemoteFileImportData[importDataList.size()]); + } + + /** + * Reads the file import data from a file. + */ + protected RemoteFileImportData readImportData(IFile description, MultiStatus readStatus) { + Assert.isLegal(description.isAccessible()); + Assert.isNotNull(description.getFileExtension()); + Assert.isLegal(description.getFileExtension().equals(Utilities.IMPORT_DESCRIPTION_EXTENSION)); + RemoteFileImportData importData = new RemoteFileImportData(); + IRemoteFileImportDescriptionReader reader = null; + try { + reader = importData.createImportDescriptionReader(description.getContents()); + // read export data + reader.read(importData); + // do not save settings again + importData.setSaveSettings(false); + } catch (CoreException ex) { + String message = MessageFormat.format(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_READ, new Object[] { description.getFullPath(), ex.getStatus().getMessage() }); + addToStatus(readStatus, message, ex); + return null; + } finally { + if (reader != null) { + readStatus.addAll(reader.getStatus()); + } + try { + if (reader != null) { + reader.close(); + } + } catch (CoreException ex) { + String message = MessageFormat.format(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_CLOSE, new Object[] { description.getFullPath() }); + addToStatus(readStatus, message, ex); + } + } + return importData; + } + + private IStatus importFiles(RemoteFileImportData[] importDatas) { + IStatus status = null; + for (int i = 0; i < importDatas.length; i++) { + RemoteFileImportOperation op = new RemoteFileImportOperation(importDatas[i], FileSystemStructureProvider.INSTANCE, new RemoteFileOverwriteQuery()); + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, op); + status = op.getStatus(); + } catch (InvocationTargetException e) { + SystemBasePlugin.logError("Error occured trying to import", e); //$NON-NLS-1$ + status = new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, "", e); //$NON-NLS-1$ + } catch (InterruptedException e) { + SystemBasePlugin.logError("Error occured trying to import", e); //$NON-NLS-1$ + status = new Status(IStatus.OK, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, "", e); //$NON-NLS-1$ + } + if (!status.isOK()) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_FAILED); + msg.makeSubstitution(status); + SystemMessageDialog dlg = new SystemMessageDialog(getShell(), msg); + dlg.openWithDetails(); + return null; + } + } + return null; + } + + protected void addToStatus(MultiStatus multiStatus, String defaultMessage, CoreException ex) { + IStatus status = ex.getStatus(); + String message = ex.getLocalizedMessage(); + if (message == null || message.length() < 1) { + status = new Status(status.getSeverity(), status.getPlugin(), status.getCode(), defaultMessage, ex); + } + multiStatus.add(status); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportData.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportData.java new file mode 100644 index 00000000000..db39e65240d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportData.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.rse.core.SystemBasePlugin; + +/** + * Holds data of what to import. + */ +public class RemoteFileImportData { + private IPath containerPath; + private Object source; + private boolean overWriteExistingFiles; + private boolean createDirectoryStructure; + private boolean createSelectionOnly; + private boolean saveSettings; + private String descriptionFilePath; + // import elements + private HashMap map; + private List elements; + + /** + * Constructor. + */ + public RemoteFileImportData() { + setContainerPath(null); + setSource(null); + setOverWriteExistingFiles(false); + setCreateDirectoryStructure(false); + setCreateSelectionOnly(true); + setSaveSettings(false); + setDescriptionFilePath(null); + } + + /** + * @return Returns the descriptionFilePath. + */ + public String getDescriptionFilePath() { + return descriptionFilePath; + } + + /** + * Gets the description file as a workspace resource. + * @return a file representing the description file. + */ + public IFile getDescriptionFile() { + IPath path = new Path(getDescriptionFilePath()); + if (path.isValidPath(path.toString()) && path.segmentCount() >= 2) { + return SystemBasePlugin.getWorkspace().getRoot().getFile(path); + } else { + return null; + } + } + + /** + * @param descriptionFilePath The descriptionFilePath to set. + */ + public void setDescriptionFilePath(String descriptionFilePath) { + this.descriptionFilePath = descriptionFilePath; + } + + /** + * @return returns container path. + */ + public IPath getContainerPath() { + return containerPath; + } + + /** + * @param containerPath the container path. + */ + public void setContainerPath(IPath containerPath) { + this.containerPath = containerPath; + } + + /** + * Gets the source. + * @return the source from which to import. + */ + public Object getSource() { + return source; + } + + /** + * Sets the source. + * @param source the source from which to import. + */ + public void setSource(Object source) { + this.source = source; + } + + /** + * Returns the elements to be imported. + * @return the elements. + */ + public List getElements() { + return elements; + } + + /** + * Sets the elements to imported. + * @param elements the elements. + */ + public void setElements(List elements) { + this.elements = elements; + } + + /** + * Add to the list of files to import. + * @param object the file object. + */ + public void addToList(UniFilePlus object) { + if (map == null) { + map = new HashMap(); + } + // add to map + map.put(object.getAbsolutePath(), object); + } + + /** + * Does the file exist. + * @param object the file object. + * @return true of the + */ + public boolean doesExist(UniFilePlus object) { + if (map.get(object.getAbsolutePath()) == null) { + return false; + } else { + return true; + } + } + + /** + * @return Returns the overWriteExistingFiles. + */ + public boolean isOverWriteExistingFiles() { + return overWriteExistingFiles; + } + + /** + * @param overWriteExistingFiles The overWriteExistingFiles to set. + */ + public void setOverWriteExistingFiles(boolean overWriteExistingFiles) { + this.overWriteExistingFiles = overWriteExistingFiles; + } + + /** + * @return Returns the saveSettings. + */ + public boolean isSaveSettings() { + return saveSettings; + } + + /** + * @param saveSettings The saveSettings to set. + */ + public void setSaveSettings(boolean saveSettings) { + this.saveSettings = saveSettings; + } + + /** + * @return Returns the createDirectoryStructure. + */ + public boolean isCreateDirectoryStructure() { + return createDirectoryStructure; + } + + /** + * @param createDirectoryStructure The createDirectoryStructure to set. + */ + public void setCreateDirectoryStructure(boolean createDirectoryStructure) { + this.createDirectoryStructure = createDirectoryStructure; + } + + /** + * @return Returns the createSelectionOnly. + */ + public boolean isCreateSelectionOnly() { + return createSelectionOnly; + } + + /** + * @param createSelectionOnly The createSelectionOnly to set. + */ + public void setCreateSelectionOnly(boolean createSelectionOnly) { + this.createSelectionOnly = createSelectionOnly; + } + + /** + * Creates and returns an import description writer. + */ + public IRemoteFileImportDescriptionWriter createImportDescriptionWriter(OutputStream outputStream) { + return new RemoteFileImportDescriptionWriter(outputStream); + } + + /** + * Creates and returns an import description writer. + */ + public IRemoteFileImportDescriptionReader createImportDescriptionReader(InputStream inputStream) { + return new RemoteFileImportDescriptionReader(inputStream); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionReader.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionReader.java new file mode 100644 index 00000000000..ca2c96f53cd --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionReader.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Remote file import description reader. + */ +public class RemoteFileImportDescriptionReader implements IRemoteFileImportDescriptionReader { + protected InputStream fInputStream; + protected IRemoteFileSubSystem subsystem; + + /** + * Constructor. + */ + public RemoteFileImportDescriptionReader(InputStream inputStream) { + Assert.isNotNull(inputStream); + fInputStream = new BufferedInputStream(inputStream); + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileImportDescriptionReader#read(org.eclipse.rse.files.importexport.files.RemoteFileImportData) + */ + public void read(RemoteFileImportData importData) throws CoreException { + try { + readXML(importData); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } catch (SAXException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + + public RemoteFileImportData readXML(RemoteFileImportData importData) throws IOException, SAXException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + DocumentBuilder parser = null; + try { + parser = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new IOException(ex.getLocalizedMessage()); + } + Element xmlFileDesc = parser.parse(new InputSource(fInputStream)).getDocumentElement(); + if (!xmlFileDesc.getNodeName().equals(Utilities.IMPORT_DESCRIPTION_EXTENSION)) { + throw new IOException(); + } + NodeList topLevelElements = xmlFileDesc.getChildNodes(); + for (int i = 0; i < topLevelElements.getLength(); i++) { + Node node = topLevelElements.item(i); + if (node.getNodeType() != Node.ELEMENT_NODE) continue; + Element element = (Element) node; + xmlReadDestinationLocation(importData, element); + xmlReadOptions(importData, element); + xmlReadSourceLocation(importData, element); + xmlReadSelectedElements(importData, element); + } + return importData; + } + + private void xmlReadDestinationLocation(RemoteFileImportData importData, Element element) { + if (element.getNodeName().equals("destination")) { //$NON-NLS-1$ + String destinationPath = element.getAttribute("path"); //$NON-NLS-1$ + importData.setContainerPath(new Path(destinationPath)); + } + } + + private void xmlReadOptions(RemoteFileImportData importData, Element element) throws IOException { + if (element.getNodeName().equals("options")) { //$NON-NLS-1$ + importData.setOverWriteExistingFiles(getBooleanAttribute(element, "overWriteExistingFiles")); //$NON-NLS-1$ + importData.setCreateDirectoryStructure(getBooleanAttribute(element, "createDirectoryStructure")); //$NON-NLS-1$ + importData.setCreateSelectionOnly(getBooleanAttribute(element, "createSelectedOnly")); //$NON-NLS-1$ + importData.setSaveSettings(getBooleanAttribute(element, "saveSettings")); //$NON-NLS-1$ + importData.setDescriptionFilePath(element.getAttribute("descriptionFilePath")); //$NON-NLS-1$ + } + } + + private void xmlReadSourceLocation(RemoteFileImportData importData, Element element) { + if (element.getNodeName().equals("source")) { //$NON-NLS-1$ + String sourceCanonicalPath = element.getAttribute("path"); //$NON-NLS-1$ + IRemoteFile remoteFile = Utilities.parseForIRemoteFile(sourceCanonicalPath); + UniFilePlus file = new UniFilePlus(remoteFile); + importData.setSource(file); + subsystem = remoteFile.getParentRemoteFileSubSystem(); + } + } + + private void xmlReadSelectedElements(RemoteFileImportData importData, Element element) throws IOException { + if (element.getNodeName().equals("selectedElements")) { //$NON-NLS-1$ + NodeList selectedElements = element.getChildNodes(); + List elementsToImport = new ArrayList(selectedElements.getLength()); + for (int j = 0; j < selectedElements.getLength(); j++) { + Node selectedNode = selectedElements.item(j); + if (selectedNode.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + Element selectedElement = (Element) selectedNode; + if (selectedElement.getNodeName().equals("file")) { //$NON-NLS-1$ + addResource(importData, elementsToImport, selectedElement); + } else if (selectedElement.getNodeName().equals("folder")) { //$NON-NLS-1$ + addResource(importData, elementsToImport, selectedElement); + } + } + importData.setElements(elementsToImport); + } + } + + private void addResource(RemoteFileImportData importData, List selectedElements, Element element) throws IOException { + String path = element.getAttribute("path"); //$NON-NLS-1$ + if (path != null && subsystem != null) { + IRemoteFile remoteFile = null; + try { + remoteFile = subsystem.getRemoteFileObject(path); + if (remoteFile != null && remoteFile.exists()) { + UniFilePlus file = new UniFilePlus(remoteFile); + selectedElements.add(file); + // add to list of import data + importData.addToList(file); + } + } catch (SystemMessageException e) { + SystemBasePlugin.logError("Error occured trying to retrieve file " + path, e); //$NON-NLS-1$ + } + } + } + + protected boolean getBooleanAttribute(Element element, String name) throws IOException { + String value = element.getAttribute(name); + if (value != null && value.equalsIgnoreCase("true")) { //$NON-NLS-1$ + return true; + } + if (value != null && value.equalsIgnoreCase("false")) { //$NON-NLS-1$ + return false; + } + throw new IOException(); + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileImportDescriptionReader#close() + */ + public void close() throws CoreException { + if (fInputStream != null) { + try { + fInputStream.close(); + subsystem = null; + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileImportDescriptionReader#getStatus() + */ + public IStatus getStatus() { + return new Status(IStatus.OK, RSEUIPlugin.getDefault().getSymbolicName(), 0, "", null); //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionWriter.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionWriter.java new file mode 100644 index 00000000000..daedbc4ae3a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportDescriptionWriter.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Remote file import description writer. + */ +public class RemoteFileImportDescriptionWriter implements IRemoteFileImportDescriptionWriter { + protected OutputStream fOutputStream; + + /** + * Constructor. + */ + public RemoteFileImportDescriptionWriter(OutputStream outputStream) { + Assert.isNotNull(outputStream); + fOutputStream = new BufferedOutputStream(outputStream); + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileImportDescriptionWriter#write(org.eclipse.rse.files.importexport.files.RemoteFileImportData) + */ + public void write(RemoteFileImportData importData) throws CoreException { + try { + writeXML(importData); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + + /** + * Writes a XML representation of file import data. + * @exception IOException if writing to the underlying stream fails. + */ + public void writeXML(RemoteFileImportData importData) throws IOException { + Assert.isNotNull(importData); + DocumentBuilder docBuilder = null; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + try { + docBuilder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new IOException(ex.getLocalizedMessage()); + } + Document document = docBuilder.newDocument(); + // create the document + Element xmlFileDesc = document.createElement(Utilities.IMPORT_DESCRIPTION_EXTENSION); + document.appendChild(xmlFileDesc); + xmlWriteDestinationLocation(importData, document, xmlFileDesc); + xmlWriteOptions(importData, document, xmlFileDesc); + xmlWriteSourceLocation(importData, document, xmlFileDesc); + xmlWriteSelectedElements(importData, document, xmlFileDesc); + try { + // write the document to the stream + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$ + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(fOutputStream); + transformer.transform(source, result); + } catch (TransformerException e) { + throw new IOException(e.getLocalizedMessage()); + } + } + + private void xmlWriteDestinationLocation(RemoteFileImportData importData, Document document, Element xmlFileDesc) throws DOMException { + Element destination = document.createElement("destination"); //$NON-NLS-1$ + xmlFileDesc.appendChild(destination); + destination.setAttribute("path", importData.getContainerPath().toString()); //$NON-NLS-1$ + } + + private void xmlWriteOptions(RemoteFileImportData importData, Document document, Element xmlFileDesc) throws DOMException { + Element options = document.createElement("options"); //$NON-NLS-1$ + xmlFileDesc.appendChild(options); + options.setAttribute("overWriteExistingFiles", "" + importData.isOverWriteExistingFiles()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("createDirectoryStructure", "" + importData.isCreateDirectoryStructure()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("createSelectedOnly", "" + importData.isCreateSelectionOnly()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("saveSettings", "" + importData.isSaveSettings()); //$NON-NLS-1$ //$NON-NLS-2$ + options.setAttribute("descriptionFilePath", "" + importData.getDescriptionFilePath()); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void xmlWriteSourceLocation(RemoteFileImportData importData, Document document, Element xmlFileDesc) throws DOMException { + Element source = document.createElement("source"); //$NON-NLS-1$ + xmlFileDesc.appendChild(source); + UniFilePlus sourceResource = (UniFilePlus) (importData.getSource()); + // save path along with profile and connection name + source.setAttribute("path", sourceResource.getCanonicalPath()); //$NON-NLS-1$ + } + + private void xmlWriteSelectedElements(RemoteFileImportData exportData, Document document, Element xmlFileDesc) throws DOMException { + Element selectedElements = document.createElement("selectedElements"); //$NON-NLS-1$ + xmlFileDesc.appendChild(selectedElements); + List elements = exportData.getElements(); + Iterator iter = elements.iterator(); + while (iter.hasNext()) { + Object element = iter.next(); + if (element instanceof UniFilePlus) { + add((UniFilePlus) element, selectedElements, document); + } + } + } + + private void add(UniFilePlus resource, Element parent, Document document) { + Element element = null; + if (resource.isFile()) { + element = document.createElement("file"); //$NON-NLS-1$ + } else if (resource.isDirectory()) { + element = document.createElement("folder"); //$NON-NLS-1$ + } + if (element != null) { + parent.appendChild(element); + element.setAttribute("path", resource.getAbsolutePath()); //$NON-NLS-1$ + } + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileImportDescriptionWriter#close() + */ + public void close() throws CoreException { + if (fOutputStream != null) { + try { + fOutputStream.close(); + } catch (IOException ex) { + String message = (ex.getLocalizedMessage() != null ? ex.getLocalizedMessage() : ""); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, message, ex)); + } + } + } + + /** + * @see org.eclipse.rse.files.importexport.files.IRemoteFileImportDescriptionWriter#getStatus() + */ + public IStatus getStatus() { + return new Status(IStatus.OK, RSEUIPlugin.getDefault().getSymbolicName(), 0, "", null); //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportExportActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportExportActionDelegate.java new file mode 100644 index 00000000000..c889fe264d0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportExportActionDelegate.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.util.Iterator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IActionDelegate; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; + +/** + * This class is the super class of file import/export action delegate. + */ +public abstract class RemoteFileImportExportActionDelegate implements IActionDelegate { + protected IStructuredSelection fSelection; + + /** + * Sets the selection. The selection is only set if given a structured selection, otherwise it is set to an + * empty structured selection. + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + if (selection instanceof IStructuredSelection) { + fSelection = (IStructuredSelection) selection; + } else { + fSelection = StructuredSelection.EMPTY; + } + } + + /** + * Returns the remote file in the selection. + * Use this method if this action allows only a single remote file selection. + * @return the single remote file. + */ + protected IRemoteFile getRemoteFile(IStructuredSelection selection) { + return (IRemoteFile) selection.getFirstElement(); + } + + /** + * Returns the remote files in the selection. + * Use this method if this action allows multiple remote file selection. + * @return an array of remote files. + */ + protected IRemoteFile[] getRemoteFiles(IStructuredSelection selection) { + IRemoteFile[] files = new IRemoteFile[selection.size()]; + Iterator iter = selection.iterator(); + int i = 0; + while (iter.hasNext()) { + files[i++] = (IRemoteFile) iter.next(); + } + return files; + } + + /** + * Returns the description file for the first description file in + * the selection. Use this method if this action allows only + * a single file selection. + * @return the single description file. + */ + protected IFile getDescriptionFile(IStructuredSelection selection) { + return (IFile) selection.getFirstElement(); + } + + /** + * Returns a description file for each description file in + * the selection. Use this method if this action allows multiple + * selection. + * @return an array of description files. + */ + protected IFile[] getDescriptionFiles(IStructuredSelection selection) { + IFile[] files = new IFile[selection.size()]; + Iterator iter = selection.iterator(); + int i = 0; + while (iter.hasNext()) { + files[i++] = (IFile) iter.next(); + } + return files; + } + + /** + * Returns the workbench. + * @return the workbench. + */ + protected IWorkbench getWorkbench() { + return PlatformUI.getWorkbench(); + } + + /** + * Returns the active shell. + * @return the active shell. + */ + protected Shell getShell() { + return Display.getDefault().getActiveShell(); + } + + /** + * Returns the selection. + * @return the selection. + */ + protected IStructuredSelection getSelection() { + return fSelection; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportOperation.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportOperation.java new file mode 100644 index 00000000000..489bd899af0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportOperation.java @@ -0,0 +1,639 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.files.importexport.RemoteImportExportUtil; +import org.eclipse.rse.importexport.SystemImportExportResources; +import org.eclipse.rse.services.files.RemoteFileIOException; +import org.eclipse.rse.services.files.RemoteFileSecurityException; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.ui.actions.WorkspaceModifyOperation; +import org.eclipse.ui.dialogs.ContainerGenerator; +import org.eclipse.ui.dialogs.IOverwriteQuery; + +// Similar to org.eclipse.ui.wizards.datatransfer.ImportOperation +/** + * An operation which does the actual work of copying objects from the local file + * system into the workspace. + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ */ +public class RemoteFileImportOperation extends WorkspaceModifyOperation { + private static final int POLICY_DEFAULT = 0; + private static final int POLICY_SKIP_CHILDREN = 1; + private static final int POLICY_FORCE_OVERWRITE = 2; + private Object source; + private IPath destinationPath; + private IContainer destinationContainer; + private List selectedFiles; + private IImportStructureProvider provider; + private IProgressMonitor monitor; + protected IOverwriteQuery overwriteCallback; + private List errorTable = new ArrayList(); + private boolean createContainerStructure = true; + private RemoteFileImportData importData; + private boolean saveSettings; + private String descriptionFilePath; + //The constants for the overwrite 3 state + private static final int OVERWRITE_NOT_SET = 0; + private static final int OVERWRITE_NONE = 1; + private static final int OVERWRITE_ALL = 2; + private int overwriteState = OVERWRITE_NOT_SET; + + /** + * Creates a new operation that recursively imports the entire contents of the + * specified root file system object. + *

+ * The source parameter represents the root file system object to + * import. All contents of this object are imported. Valid types for this parameter + * are determined by the supplied IImportStructureProvider. + *

+ *

+ * The provider parameter allows this operation to deal with the + * source object in an abstract way. This operation calls methods on the provider + * and the provider in turn calls specific methods on the source object. + *

+ *

+ * The default import behavior is to recreate the complete container structure + * for the contents of the root file system object in their destination. + * If setCreateContainerStructure is set to false then the container + * structure created is relative to the root file system object. + *

+ * + * @param containerPath the full path of the destination container within the + * workspace + * @param source the root file system object to import + * @param provider the file system structure provider to use + * @param overwriteImplementor the overwrite strategy to use + */ + public RemoteFileImportOperation(IPath containerPath, Object source, IImportStructureProvider provider, IOverwriteQuery overwriteImplementor) { + super(); + this.destinationPath = containerPath; + this.source = source; + this.provider = provider; + overwriteCallback = overwriteImplementor; + } + + /** + * Creates a new operation that imports specific file system objects. + * In this usage context, the specified source file system object is used by the + * operation solely to determine the destination container structure of the file system + * objects being imported. + *

+ * The source parameter represents the root file system object to + * import. Valid types for this parameter are determined by the supplied + * IImportStructureProvider. The contents of the source which + * are to be imported are specified in the filesToImport + * parameter. + *

+ *

+ * The provider parameter allows this operation to deal with the + * source object in an abstract way. This operation calls methods on the provider + * and the provider in turn calls specific methods on the source object. + *

+ *

+ * The filesToImport parameter specifies what contents of the root + * file system object are to be imported. + *

+ *

+ * The default import behavior is to recreate the complete container structure + * for the file system objects in their destination. If setCreateContainerStructure + * is set to false, then the container structure created for each of + * the file system objects is relative to the supplied root file system object. + *

+ * + * @param containerPath the full path of the destination container within the + * workspace + * @param source the root file system object to import from + * @param provider the file system structure provider to use + * @param overwriteImplementor the overwrite strategy to use + * @param filesToImport the list of file system objects to be imported + * (element type: Object) + */ + public RemoteFileImportOperation(IPath containerPath, Object source, IImportStructureProvider provider, IOverwriteQuery overwriteImplementor, List filesToImport) { + this(containerPath, source, provider, overwriteImplementor); + setFilesToImport(filesToImport); + } + + public RemoteFileImportOperation(RemoteFileImportData data, IImportStructureProvider provider, IOverwriteQuery overwriteImplementor) { + this(data.getContainerPath(), data.getSource(), provider, overwriteImplementor); + setFilesToImport(data.getElements()); + setOverwriteResources(data.isOverWriteExistingFiles()); + setCreateContainerStructure(data.isCreateDirectoryStructure()); + this.importData = data; + this.saveSettings = data.isSaveSettings(); + this.descriptionFilePath = data.getDescriptionFilePath(); + } + + /** + * Creates a new operation that imports specific file system objects. + *

+ * The provider parameter allows this operation to deal with the + * source object in an abstract way. This operation calls methods on the provider + * and the provider in turn calls specific methods on the source object. + *

+ *

+ * The filesToImport parameter specifies what file system objects + * are to be imported. + *

+ *

+ * The default import behavior is to recreate the complete container structure + * for the file system objects in their destination. If setCreateContainerStructure + * is set to false, then no container structure is created for each of + * the file system objects. + *

+ * + * @param containerPath the full path of the destination container within the + * workspace + * @param provider the file system structure provider to use + * @param overwriteImplementor the overwrite strategy to use + * @param filesToImport the list of file system objects to be imported + * (element type: Object) + */ + public RemoteFileImportOperation(IPath containerPath, IImportStructureProvider provider, IOverwriteQuery overwriteImplementor, List filesToImport) { + this(containerPath, null, provider, overwriteImplementor); + setFilesToImport(filesToImport); + } + + /** + * Creates the folders that appear in the specified resource path. + * These folders are created relative to the destination container. + * + * @param path the relative path of the resource + * @return the container resource coresponding to the given path + * @exception CoreException if this method failed + */ + IContainer createContainersFor(IPath path) throws CoreException { + IContainer currentFolder = destinationContainer; + int segmentCount = path.segmentCount(); + //No containers to create + if (segmentCount == 0) return currentFolder; + //Needs to be handles differently at the root + if (currentFolder.getType() == IResource.ROOT) return createFromRoot(path); + for (int i = 0; i < segmentCount; i++) { + currentFolder = currentFolder.getFolder(new Path(path.segment(i))); + if (!currentFolder.exists()) ((IFolder) currentFolder).create(false, true, null); + } + return currentFolder; + } + + /** + * Creates the folders that appear in the specified resource path + * assuming that the destinationContainer begins at the root. Do not create projects. + * + * @param path the relative path of the resource + * @return the container resource coresponding to the given path + * @exception CoreException if this method failed + */ + private IContainer createFromRoot(IPath path) throws CoreException { + int segmentCount = path.segmentCount(); + //Assume the project exists + IContainer currentFolder = ((IWorkspaceRoot) destinationContainer).getProject(path.segment(0)); + for (int i = 1; i < segmentCount; i++) { + currentFolder = currentFolder.getFolder(new Path(path.segment(i))); + if (!currentFolder.exists()) ((IFolder) currentFolder).create(false, true, null); + } + return currentFolder; + } + + /** + * Deletes the given resource. If the resource fails to be deleted, adds a + * status object to the list to be returned by getResult. + * + * @param resource the resource + */ + void deleteResource(IResource resource) { + try { + resource.delete(IResource.KEEP_HISTORY, null); + } catch (CoreException e) { + errorTable.add(e.getStatus()); + } + } + + /** + * Attempts to ensure that the given resource does not already exist in the + * workspace. The resource will be deleted if required, perhaps after asking + * the user's permission. + * + * @param targetResource the resource that should not exist + * @param policy determines how the resource is imported + * @return true if the resource does not exist, and + * false if it does exist + */ + boolean ensureTargetDoesNotExist(IResource targetResource, int policy) { + if (targetResource.exists()) { + //If force overwrite is on don't bother + if (policy != POLICY_FORCE_OVERWRITE) { + if (this.overwriteState == OVERWRITE_NOT_SET && !queryOverwrite(targetResource.getFullPath())) return false; + if (this.overwriteState == OVERWRITE_NONE) return false; + } + deleteResource(targetResource); + } + return true; + } + + /* (non-Javadoc) + * Method declared on WorkbenchModifyOperation. + * Imports the specified file system objects from the file system. + */ + protected void execute(IProgressMonitor progressMonitor) { + monitor = progressMonitor; + try { + if (selectedFiles == null) { + //Set the amount to 1000 as we have no idea of how long this will take + String taskMsg = SystemImportExportResources.RESID_FILEIMPORT_IMPORTING; + monitor.beginTask(taskMsg, 1000); + ContainerGenerator generator = new ContainerGenerator(destinationPath); + monitor.worked(50); + destinationContainer = generator.generateContainer(new SubProgressMonitor(monitor, 50)); + importRecursivelyFrom(source, POLICY_DEFAULT); + //Be sure it finishes + monitor.worked(90); + } else { + // Choose twice the selected files size to take folders into account + int creationCount = selectedFiles.size(); + String taskMsg = SystemImportExportResources.RESID_FILEIMPORT_IMPORTING; + monitor.beginTask(taskMsg, creationCount + 100); + ContainerGenerator generator = new ContainerGenerator(destinationPath); + monitor.worked(50); + destinationContainer = generator.generateContainer(new SubProgressMonitor(monitor, 50)); + importFileSystemObjects(selectedFiles); + } + if (saveSettings) { + try { + saveDescription(); + } catch (CoreException e) { + SystemBasePlugin.logError("Error occured trying to save description " + descriptionFilePath, e); //$NON-NLS-1$ + errorTable.add(e.getStatus()); + } catch (IOException e) { + SystemBasePlugin.logError("Error occured trying to save description " + descriptionFilePath, e); //$NON-NLS-1$ + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getSymbolicName(), 0, e.getLocalizedMessage(), e)); + } + } + } catch (CoreException e) { + errorTable.add(e.getStatus()); + } finally { + monitor.done(); + } + } + + /** + * Saves a description file for the export. + * @throws CoreException if an unexpected exception occurs. + * @throws IOException if an I/O error occurs. + */ + protected void saveDescription() throws CoreException, IOException { + ByteArrayOutputStream objectStreamOutput = new ByteArrayOutputStream(); + IRemoteFileImportDescriptionWriter writer = importData.createImportDescriptionWriter(objectStreamOutput); + ByteArrayInputStream fileInput = null; + try { + writer.write(importData); + fileInput = new ByteArrayInputStream(objectStreamOutput.toByteArray()); + IFile descriptionFile = importData.getDescriptionFile(); + // check if resource exists + if (descriptionFile.isAccessible()) { + descriptionFile.setContents(fileInput, true, true, null); + } + // if resource does not exist + else { + // now have to check if a variant of this file exists (i.e. whether a file exists + // that has the same path with a different case. For case insensitive file systems + // such as Windows, this is needed since we can't simply create a file with a different + // case. Note that isAccessible() above does not check for file paths with different case, + // so we have to check it explicitly). + IResource variant = RemoteImportExportUtil.getInstance().findExistingResourceVariant(descriptionFile.getFullPath()); + // if a variant was not found, create the new file + if (variant == null) { + // check if a variant of the parent exists + // we need to do this because at this point we know that the file path does not + // exist, and neither does its variant. However, it is possible that the parent path + // has a variant, in which case calling create on the description file with + // the path as it is given will fail. We need to get the variant path of the parent, + // append the name of the file to the variant path, and create a file with that path. + // get parent + IResource parent = descriptionFile.getParent(); + if (parent != null) { + // get parent path + IResource parentVariant = RemoteImportExportUtil.getInstance().findExistingResourceVariant(parent.getFullPath()); + // no parent variant (i.e. in a case sensitive file system) + if (parentVariant == null) { + descriptionFile.create(fileInput, true, null); + } + // parent variant found (might be same as original parent path) + else { + IPath newPath = parentVariant.getFullPath().append(descriptionFile.getName()); + IFile newDescriptionFile = SystemBasePlugin.getWorkspace().getRoot().getFile(newPath); + newDescriptionFile.create(fileInput, true, null); + } + } + } + // otherwise, simply set the contents of the variant file + else { + if (variant instanceof IFile) { + ((IFile) variant).setContents(fileInput, true, true, null); + } + } + } + } finally { + if (fileInput != null) { + fileInput.close(); + } + if (writer != null) { + writer.close(); + } + } + } + + /** + * Returns the container resource that the passed file system object should be + * imported into. + * + * @param fileSystemObject the file system object being imported + * @return the container resource that the passed file system object should be + * imported into + * @exception CoreException if this method failed + */ + IContainer getDestinationContainerFor(Object fileSystemObject) throws CoreException { + IPath pathname = new Path(provider.getFullPath(fileSystemObject)); + if (createContainerStructure) + return createContainersFor(pathname.removeLastSegments(1)); + else { + if (source == fileSystemObject) return null; + IPath sourcePath = new Path(provider.getFullPath(source)); + IPath destContainerPath = pathname.removeLastSegments(1); + IPath relativePath = destContainerPath.removeFirstSegments(sourcePath.segmentCount()).setDevice(null); + return createContainersFor(relativePath); + } + } + + /** + * Returns the status of the import operation. + * If there were any errors, the result is a status object containing + * individual status objects for each error. + * If there were no errors, the result is a status object with error code OK. + * + * @return the status + */ + public IStatus getStatus() { + IStatus[] errors = new IStatus[errorTable.size()]; + errorTable.toArray(errors); + // IFS: + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_PROBLEMS).getLevelOneText(); + return new MultiStatus(RSEUIPlugin.getDefault().getBundle().getSymbolicName(), IStatus.OK, errors, msg, null); + } + + /** + * Imports the specified file system object into the workspace. + * If the import fails, adds a status object to the list to be returned by + * getResult. + * + * @param fileObject the file system object to be imported + * @param policy determines how the file object is imported + */ + void importFile(Object fileObject, int policy) { + IContainer containerResource; + try { + containerResource = getDestinationContainerFor(fileObject); + } catch (CoreException e) { + IStatus coreStatus = e.getStatus(); + String newMessage = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_ERROR, new Object[] { fileObject, coreStatus.getMessage(), e }).toString(); + IStatus status = new Status(coreStatus.getSeverity(), coreStatus.getPlugin(), coreStatus.getCode(), newMessage, null); + errorTable.add(status); + return; + } + String fileObjectPath = provider.getFullPath(fileObject); + monitor.subTask(fileObjectPath); + IFile targetResource = containerResource.getFile(new Path(provider.getLabel(fileObject))); + monitor.worked(1); + // ensure that the source and target are not the same + IPath targetPath = targetResource.getLocation(); + // Use Files for comparison to avoid platform specific case issues + if (targetPath != null && (targetPath.toFile().equals(new File(fileObjectPath)))) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_SELF, fileObjectPath).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, null)); + return; + } + if (!ensureTargetDoesNotExist(targetResource, policy)) { + // Do not add an error status because the user + // has explicitely said no overwrite. Do not + // update the monitor as it was done in queryOverwrite. + return; + } + try { + IRemoteFileSubSystem rfss = RemoteFileUtility.getFileSubSystem(((UniFilePlus) fileObject).remoteFile.getSystemConnection()); + // 030820: added the following kludge to circumvent problem in + // artemis. (artemis 3 will fix this) + // TODO remove for 6.0 + String encoding = System.getProperty("file.encoding"); //$NON-NLS-1$ + if (encoding.startsWith("CP")) //$NON-NLS-1$ + { + encoding = "Cp" + encoding.substring(2); //$NON-NLS-1$ + } + rfss.download(((UniFilePlus) fileObject).remoteFile, targetResource, encoding, null); + try { + // refresh workspace with just added resource + targetResource.refreshLocal(IResource.DEPTH_ZERO, new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); + } catch (CoreException e) { + errorTable.add(e.getStatus()); + } + } catch (RemoteFileIOException e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_ERROR, new Object[] { fileObjectPath, e.getRemoteException().getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + return; + } catch (RemoteFileSecurityException e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_ERROR, new Object[] { fileObjectPath, e.getRemoteException().getLocalizedMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + return; + } catch (Exception e) { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_ERROR, new Object[] { fileObjectPath, e.getMessage() == null ? e.toString() : e.getMessage(), e }).toString(); + errorTable.add(new Status(IStatus.ERROR, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, e)); + return; + } + } + + /** + * Imports the specified file system objects into the workspace. + * If the import fails, adds a status object to the list to be returned by + * getStatus. + * + * @param filesToImport the list of file system objects to import + * (element type: Object) + * @exception OperationCanceledException if canceled + */ + void importFileSystemObjects(List filesToImport) { + Iterator filesEnum = filesToImport.iterator(); + while (filesEnum.hasNext()) { + Object fileSystemObject = filesEnum.next(); + if (source == null) { + // We just import what we are given into the destination + IPath sourcePath = new Path(provider.getFullPath(fileSystemObject)).removeLastSegments(1); + if (provider.isFolder(fileSystemObject) && sourcePath.isEmpty()) { + // If we don't have a parent then we have selected the + // file systems root. Roots can't copied (at least not + // under windows). + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_COPY_ROOT).toString(); + errorTable.add(new Status(IStatus.INFO, RSEUIPlugin.getDefault().getBundle().getSymbolicName(), 0, msg, null)); + continue; + } + source = sourcePath.toFile(); + } + importRecursivelyFrom(fileSystemObject, POLICY_DEFAULT); + } + } + + /** + * Imports the specified file system container object into the workspace. + * If the import fails, adds a status object to the list to be returned by + * getResult. + * + * @param fileObject the file system container object to be imported + * @param policy determines how the folder object and children are imported + * @return the policy to use to import the folder's children + */ + int importFolder(Object folderObject, int policy) { + IContainer containerResource; + try { + containerResource = getDestinationContainerFor(folderObject); + } catch (CoreException e) { + errorTable.add(e.getStatus()); + return policy; + } + if (containerResource == null) return policy; + monitor.subTask(provider.getFullPath(folderObject)); + IWorkspace workspace = destinationContainer.getWorkspace(); + IPath containerPath = containerResource.getFullPath(); + IPath resourcePath = containerPath.append(provider.getLabel(folderObject)); + // Do not attempt the import if the resource path is unchanged. This may happen + // when importing from a zip file. + if (resourcePath.equals(containerPath)) return policy; + if (workspace.getRoot().exists(resourcePath)) { + if (policy != POLICY_FORCE_OVERWRITE) { + if (this.overwriteState == OVERWRITE_NONE || !queryOverwrite(resourcePath)) // Do not add an error status because the user + // has explicitely said no overwrite. Do not + // update the monitor as it was done in queryOverwrite. + return POLICY_SKIP_CHILDREN; + } + return POLICY_FORCE_OVERWRITE; + } + try { + workspace.getRoot().getFolder(resourcePath).create(false, true, null); + } catch (CoreException e) { + errorTable.add(e.getStatus()); + } + return policy; + } + + /** + * Imports the specified file system object recursively into the workspace. + * If the import fails, adds a status object to the list to be returned by + * getStatus. + * + * @param fileSystemObject the file system object to be imported + * @param policy determines how the file system object and children are imported + * @exception OperationCanceledException if canceled + */ + void importRecursivelyFrom(Object fileSystemObject, int policy) { + if (monitor.isCanceled()) throw new OperationCanceledException(); + if (!provider.isFolder(fileSystemObject)) { + importFile(fileSystemObject, policy); + return; + } + int childPolicy = importFolder(fileSystemObject, policy); + if (childPolicy != POLICY_SKIP_CHILDREN) { + Iterator children = provider.getChildren(fileSystemObject).iterator(); + while (children.hasNext()) + importRecursivelyFrom(children.next(), childPolicy); + } + } + + /** + * Queries the user whether the resource with the specified path should be + * overwritten by a file system object that is being imported. + * + * @param path the workspace path of the resource that needs to be overwritten + * @return true to overwrite, false to not overwrite + * @exception OperationCanceledException if canceled + */ + boolean queryOverwrite(IPath resourcePath) throws OperationCanceledException { + String overwriteAnswer = overwriteCallback.queryOverwrite(resourcePath.makeRelative().toString()); + if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) //throw new OperationCanceledException(UniversalSystemPlugin.getString("customs.emptyString")); + throw new OperationCanceledException(""); //$NON-NLS-1$ + if (overwriteAnswer.equals(IOverwriteQuery.NO)) { + return false; + } + if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) { + this.overwriteState = OVERWRITE_NONE; + return false; + } + if (overwriteAnswer.equals(IOverwriteQuery.ALL)) this.overwriteState = OVERWRITE_ALL; + return true; + } + + /** + * Sets whether the containment structures that are implied from the full paths + * of file system objects being imported should be duplicated in the workbench. + * + * @param value true if containers should be created, and + * false otherwise + */ + public void setCreateContainerStructure(boolean value) { + createContainerStructure = value; + } + + /** + * Sets the file system objects to import. + * + * @param filesToImport the list of file system objects to be imported + * (element type: Object) + */ + public void setFilesToImport(List filesToImport) { + this.selectedFiles = filesToImport; + } + + /** + * Sets whether imported file system objects should automatically overwrite + * existing workbench resources when a conflict occurs. + * + * @param value true to automatically overwrite, and + * false otherwise + */ + public void setOverwriteResources(boolean value) { + if (value) this.overwriteState = OVERWRITE_ALL; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportToProjectActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportToProjectActionDelegate.java new file mode 100644 index 00000000000..e83df6afedd --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileImportToProjectActionDelegate.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.wizard.WizardDialog; + +/** + * This class represents the action to bring up the remote file system import wizard + * and import the contents of a remote folder to a project. + */ +public class RemoteFileImportToProjectActionDelegate extends RemoteFileImportExportActionDelegate { + /** + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + RemoteImportWizard wizard = new RemoteImportWizard(); + wizard.init(getWorkbench(), getSelection()); + WizardDialog dialog = new WizardDialog(getShell(), wizard); + dialog.create(); + dialog.open(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenExportWizardActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenExportWizardActionDelegate.java new file mode 100644 index 00000000000..d4c4b2a07d6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenExportWizardActionDelegate.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.IOException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.swt.widgets.Shell; +import org.xml.sax.SAXException; + +/** + * Opens the remote file system export wizard. + */ +public class RemoteFileOpenExportWizardActionDelegate extends RemoteFileImportExportActionDelegate { + /** + * Opens the remote file system export wizard. + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + Shell parent = getShell(); + RemoteFileExportData exportData = null; + IFile file = getDescriptionFile(getSelection()); + if (file == null) { + SystemBasePlugin.logError("No description file found"); //$NON-NLS-1$ + return; + } + try { + exportData = readRemoteFileExportData(file); + } catch (CoreException e) { + SystemBasePlugin.logError("Error occured trying to read description file" + file.getFullPath(), e); //$NON-NLS-1$ + return; + } catch (IOException e) { + SystemBasePlugin.logError("Error occured trying to read description file" + file.getFullPath(), e); //$NON-NLS-1$ + return; + } catch (SAXException e) { + SystemBasePlugin.logError("Error occured trying to read description file" + file.getFullPath(), e); //$NON-NLS-1$ + return; + } + if (exportData == null) { + SystemBasePlugin.logError("No export data"); //$NON-NLS-1$ + return; + } + RemoteExportWizard wizard = new RemoteExportWizard(); + wizard.init(getWorkbench(), exportData); + WizardDialog dialog = new WizardDialog(parent, wizard); + dialog.create(); + dialog.open(); + } + + /** + * Reads the remote file export data from a file. + */ + private RemoteFileExportData readRemoteFileExportData(IFile description) throws CoreException, IOException, SAXException { + Assert.isLegal(description.isAccessible()); + Assert.isNotNull(description.getFileExtension()); + Assert.isLegal(description.getFileExtension().equals(Utilities.EXPORT_DESCRIPTION_EXTENSION)); + RemoteFileExportData exportData = new RemoteFileExportData(); + IRemoteFileExportDescriptionReader reader = null; + try { + reader = exportData.createExportDescriptionReader(description.getContents()); + reader.read(exportData); + } finally { + if (reader != null) { + reader.close(); + } + } + return exportData; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenImportWizardActionDelegate.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenImportWizardActionDelegate.java new file mode 100644 index 00000000000..01511c3fe1f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOpenImportWizardActionDelegate.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.IOException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.swt.widgets.Shell; +import org.xml.sax.SAXException; + +/** + * Opens the remote file system export wizard. + */ +public class RemoteFileOpenImportWizardActionDelegate extends RemoteFileImportExportActionDelegate { + /** + * Opens the remote file system export wizard. + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + Shell parent = getShell(); + RemoteFileImportData importData = null; + IFile file = getDescriptionFile(getSelection()); + if (file == null) { + SystemBasePlugin.logError("No description file found"); //$NON-NLS-1$ + return; + } + try { + importData = readRemoteFileImportData(file); + } catch (CoreException e) { + SystemBasePlugin.logError("Error occured trying to read description file" + file.getFullPath(), e); //$NON-NLS-1$ + return; + } catch (IOException e) { + SystemBasePlugin.logError("Error occured trying to read description file" + file.getFullPath(), e); //$NON-NLS-1$ + return; + } catch (SAXException e) { + SystemBasePlugin.logError("Error occured trying to read description file" + file.getFullPath(), e); //$NON-NLS-1$ + return; + } + if (importData == null) { + SystemBasePlugin.logError("No export data"); //$NON-NLS-1$ + return; + } + RemoteImportWizard wizard = new RemoteImportWizard(); + wizard.init(getWorkbench(), importData); + WizardDialog dialog = new WizardDialog(parent, wizard); + dialog.create(); + dialog.open(); + } + + /** + * Reads the remote file export data from a file. + */ + private RemoteFileImportData readRemoteFileImportData(IFile description) throws CoreException, IOException, SAXException { + Assert.isLegal(description.isAccessible()); + Assert.isNotNull(description.getFileExtension()); + Assert.isLegal(description.getFileExtension().equals(Utilities.IMPORT_DESCRIPTION_EXTENSION)); + RemoteFileImportData importData = new RemoteFileImportData(); + IRemoteFileImportDescriptionReader reader = null; + try { + reader = importData.createImportDescriptionReader(description.getContents()); + reader.read(importData); + } finally { + if (reader != null) { + reader.close(); + } + } + return importData; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOverwriteQuery.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOverwriteQuery.java new file mode 100644 index 00000000000..a0be328d388 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteFileOverwriteQuery.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.text.MessageFormat; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.files.importexport.RemoteImportExportResources; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.IOverwriteQuery; + +/** + * This class is used to query whether the user wants to overwrite a file, overwrite all files, not overwrite a file, + * not overwrite any files, or cancel. + */ +public class RemoteFileOverwriteQuery implements IOverwriteQuery { + /** + * This runnable shows the overwrite query dialog and stores the result. + */ + private class RemoteFileOverwriteQueryRunnable implements Runnable { + private String pathString; + private String queryResponse; + + /** + * Constructor. + * @param pathString the path. + */ + private RemoteFileOverwriteQueryRunnable(String pathString) { + this.pathString = pathString; + } + + /** + * @see java.lang.Runnable#run() + */ + public void run() { + Path path = new Path(pathString); + String messageString; + //Break the message up if there is a file name and a directory + //and there are at least 2 segments. + if (path.getFileExtension() == null || path.segmentCount() < 2) { + //TODO internal class used + messageString = MessageFormat.format(RemoteImportExportResources.WizardDataTransfer_existsQuestion, new String[] { pathString }); + } else { + // TODO internal class used + messageString = MessageFormat.format(RemoteImportExportResources.WizardDataTransfer_overwriteNameAndPathQuestion, new String[] { path.lastSegment(), + path.removeLastSegments(1).toOSString() }); + } + Shell shell = SystemBasePlugin.getActiveWorkbenchShell(); + // TODO internal class used + MessageDialog dialog = new MessageDialog(shell, RemoteImportExportResources.Question, null, messageString, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, + IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.CANCEL_LABEL }, 0); + String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL }; + // open the dialog + dialog.open(); + if (dialog.getReturnCode() < 0) { + queryResponse = IOverwriteQuery.CANCEL; + } else { + queryResponse = response[dialog.getReturnCode()]; + } + } + + private String getQueryRresponse() { + return queryResponse; + } + } + + /** + * Constructor. + */ + public RemoteFileOverwriteQuery() { + super(); + } + + /** + * @see org.eclipse.ui.dialogs.IOverwriteQuery#queryOverwrite(java.lang.String) + */ + public String queryOverwrite(String pathString) { + RemoteFileOverwriteQueryRunnable runnable = new RemoteFileOverwriteQueryRunnable(pathString); + Display.getDefault().syncExec(runnable); + return runnable.getQueryRresponse(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizard.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizard.java new file mode 100644 index 00000000000..0dd99e5bc8c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizard.java @@ -0,0 +1,119 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.importexport.SystemImportExportResources; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.wizards.AbstractSystemWizard; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + +// Similar to org.eclipse.ui.wizards.datatransfer.FileSystemImportWizard +// Changes marked with "IFS:" comments. Also see use of RemoteImportExportPlugin +/** + * Standard workbench wizard for importing resources from the local file system + * into the workspace. + *

+ * This class may be instantiated and used without further configuration; + * this class is not intended to be subclassed. + *

+ *

+ * Example: + *

+ * IWizard wizard = new RemoteImportWizard();
+ * wizard.init(workbench, selection);
+ * WizardDialog dialog = new WizardDialog(shell, wizard);
+ * dialog.open();
+ * 
+ * During the call to open, the wizard dialog is presented to the + * user. When the user hits Finish, the user-selected files are imported + * into the workspace, the dialog closes, and the call to open + * returns. + *

+ */ +public class RemoteImportWizard extends AbstractSystemWizard implements IImportWizard { + private IWorkbench workbench; + private IStructuredSelection selection; + private RemoteImportWizardPage1 mainPage; + private RemoteFileImportData importData; + private boolean initializeFromExportData; + + /** + * Creates a wizard for importing resources into the workspace from + * the file system. + */ + public RemoteImportWizard() { + IDialogSettings workbenchSettings = RSEUIPlugin.getDefault().getDialogSettings(); + IDialogSettings section = workbenchSettings.getSection("RemoteImportWizard"); //$NON-NLS-1$ + if (section == null) section = workbenchSettings.addNewSection("RemoteImportWizard"); //$NON-NLS-1$ + setDialogSettings(section); + } + + /* (non-Javadoc) + * Method declared on IWizard. + */ + public void addPages() { + mainPage = new RemoteImportWizardPage1(workbench, selection); + addPage(mainPage); + } + + /** + * Returns the image descriptor with the given relative path. + */ + private ImageDescriptor getImageDescriptor(String relativePath) { + String iconPath = "icons/full/"; //$NON-NLS-1$ + return RSEUIPlugin.getDefault().getPluginImage(iconPath + relativePath); + } + + /* (non-Javadoc) + * Method declared on IWorkbenchWizard. + */ + public void init(IWorkbench workbench, IStructuredSelection currentSelection) { + this.workbench = workbench; + selection = currentSelection; + setWindowTitle(SystemImportExportResources.RESID_FILEIMPORT_TITLE); + setDefaultPageImageDescriptor(getImageDescriptor("wizban/import_wiz.gif")); //$NON-NLS-1$ + setNeedsProgressMonitor(true); + } + + public void init(IWorkbench workbench, RemoteFileImportData importData) { + this.workbench = workbench; + this.selection = new StructuredSelection(importData.getElements().toArray()); + this.importData = importData; + setInitializeFromImportData(true); + setWindowTitle(SystemImportExportResources.RESID_FILEIMPORT_TITLE); + setDefaultPageImageDescriptor(getImageDescriptor("wizban/import_wiz.gif")); //$NON-NLS-1$ + setNeedsProgressMonitor(true); + } + + protected void setInitializeFromImportData(boolean init) { + this.initializeFromExportData = init; + } + + public boolean getInitializeFromImportData() { + return initializeFromExportData; + } + + public RemoteFileImportData getImportData() { + return importData; + } + + /* (non-Javadoc) + * Method declared on IWizard. + */ + public boolean performFinish() { + return mainPage.finish(); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizardPage1.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizardPage1.java new file mode 100644 index 00000000000..8b9b4aeccf4 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/RemoteImportWizardPage1.java @@ -0,0 +1,1365 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.files.importexport.RemoteImportExportResources; +import org.eclipse.rse.files.importexport.RemoteImportExportUtil; +import org.eclipse.rse.files.ui.actions.SystemSelectRemoteFolderAction; +import org.eclipse.rse.importexport.SystemImportExportResources; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.rse.ui.messages.SystemMessageLine; +import org.eclipse.rse.ui.wizards.ISystemWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.dialogs.SaveAsDialog; +import org.eclipse.ui.dialogs.WizardResourceImportPage; +import org.eclipse.ui.internal.ide.dialogs.IElementFilter; +import org.eclipse.ui.model.WorkbenchContentProvider; + +/** + * Page 1 of the base resource import-from-file-system Wizard + */ +class RemoteImportWizardPage1 extends WizardResourceImportPage implements Listener, ISystemWizardPage { + private Object sourceDirectory = null; + private String helpId; + private Composite parentComposite; + private SystemMessageLine msgLine; + private SystemMessage pendingMessage, pendingErrorMessage; + private String pendingString, pendingErrorString; + protected Composite sourceComposite; + protected Combo sourceNameField; + protected Button overwriteExistingResourcesCheckbox; + protected Button createContainerStructureButton; + protected Button createOnlySelectedButton; + protected Button saveSettingsButton; + protected Label descFilePathLabel; + protected Text descFilePathField; + protected Button descFileBrowseButton; + protected Button sourceBrowseButton; + protected Button selectTypesButton; + protected Button selectAllButton; + protected Button deselectAllButton; + // a boolean to indicate if the user has typed anything + private boolean entryChanged = false; + // input object + protected Object inputObject = null; + // flag to indicate whether initial selection was used to set source field + protected boolean initSourceNameSet = false; + // dialog store id constants + private final static String STORE_SOURCE_NAMES_ID = "RemoteImportWizardPage1.STORE_SOURCE_NAMES_ID"; //$NON-NLS-1$ + private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID = "RemoteImportWizardPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID"; //$NON-NLS-1$ + private final static String STORE_CREATE_CONTAINER_STRUCTURE_ID = "RemoteImportWizardPage1.STORE_CREATE_CONTAINER_STRUCTURE_ID"; //$NON-NLS-1$ + private static final String STORE_CREATE_DESCRIPTION_FILE_ID = "RemoteImportWizardPage1.STORE_CREATE_DESCRIPTION_FILE_ID"; //$NON-NLS-1$ + private static final String STORE_DESCRIPTION_FILE_NAME_ID = "RemoteImportWizardPage1.STORE_DESCRIPTION_FILE_NAME_ID"; //$NON-NLS-1$ + // messages + protected static final SystemMessage SOURCE_EMPTY_MESSAGE = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_SOURCE_EMPTY); + + /** + * Creates an instance of this class + */ + protected RemoteImportWizardPage1(String name, IWorkbench aWorkbench, IStructuredSelection selection) { + super(name, selection); + setInputObject(selection); + } + + /** + * Creates an instance of this class + * + * @param aWorkbench IWorkbench + * @param selection IStructuredSelection + */ + public RemoteImportWizardPage1(IWorkbench aWorkbench, IStructuredSelection selection) { + this("fileSystemImportPage1", aWorkbench, selection); //$NON-NLS-1$ + setTitle(SystemImportExportResources.RESID_FILEIMPORT_PAGE1_TITLE); + setDescription(SystemImportExportResources.RESID_FILEIMPORT_PAGE1_DESCRIPTION); + } + + /** + * Creates a new button with the given id. + *

+ * The Dialog implementation of this framework method + * creates a standard push button, registers for selection events + * including button presses and registers + * default buttons with its shell. + * The button id is stored as the buttons client data. + * Note that the parent's layout is assumed to be a GridLayout and + * the number of columns in this layout is incremented. + * Subclasses may override. + *

+ * + * @param parent the parent composite + * @param id the id of the button (see + * IDialogConstants.*_ID constants + * for standard dialog button ids) + * @param label the label from the button + * @param defaultButton true if the button is to be the + * default button, and false otherwise + */ + protected Button createButton(Composite parent, int id, String label, boolean defaultButton) { + // increment the number of columns in the button bar + ((GridLayout) parent.getLayout()).numColumns++; + Button button = new Button(parent, SWT.PUSH); + GridData buttonData = new GridData(GridData.FILL_HORIZONTAL); + button.setLayoutData(buttonData); + button.setData(new Integer(id)); + button.setText(label); + if (defaultButton) { + Shell shell = parent.getShell(); + if (shell != null) { + shell.setDefaultButton(button); + } + button.setFocus(); + } + return button; + } + + /** + * Creates the buttons for selecting specific types or selecting all or none of the + * elements. + * + * @param parent the parent control + */ + protected final void createButtonsGroup(Composite parent) { + Composite buttonComposite = SystemWidgetHelpers.createComposite(parent, 3); + ((GridLayout) buttonComposite.getLayout()).makeColumnsEqualWidth = true; + selectTypesButton = SystemWidgetHelpers.createPushButton(buttonComposite, null, SystemImportExportResources.RESID_FILEIMPEXP_BUTTON_SELECTTYPES_LABEL, + SystemImportExportResources.RESID_FILEIMPEXP_BUTTON_SELECTTYPES_TOOLTIP); + selectAllButton = SystemWidgetHelpers.createPushButton(buttonComposite, null, SystemImportExportResources.RESID_FILEIMPEXP_BUTTON_SELECTALL_LABEL, + SystemImportExportResources.RESID_FILEIMPEXP_BUTTON_SELECTALL_TOOLTIP); + deselectAllButton = SystemWidgetHelpers.createPushButton(buttonComposite, null, SystemImportExportResources.RESID_FILEIMPEXP_BUTTON_DESELECTALL_LABEL, + SystemImportExportResources.RESID_FILEIMPEXP_BUTTON_DESELECTALL_TOOLTIP); + SelectionListener listener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleTypesEditButtonPressed(); + } + }; + selectTypesButton.addSelectionListener(listener); + listener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + setAllSelections(true); + } + }; + selectAllButton.addSelectionListener(listener); + listener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + setAllSelections(false); + } + }; + deselectAllButton.addSelectionListener(listener); + } + + /** (non-Javadoc) + * Method declared on IDialogPage. + */ + public void createControl(Composite parent) { + parentComposite = new Composite(parent, SWT.NONE); + parentComposite.setLayout(new GridLayout(1, false)); + parentComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + super.createControl(parentComposite); + msgLine = new SystemMessageLine(parentComposite); + msgLine.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + if (pendingMessage != null) { + setMessage(pendingMessage); + } + if (pendingErrorMessage != null) { + setErrorMessage(pendingErrorMessage); + } + if (pendingString != null) { + setMessage(pendingString); + } + if (pendingErrorString != null) { + setErrorMessage(pendingErrorString); + } + validateSourceGroup(); + // if source not set from remote file selection, set focus to source name field + if (!initSourceNameSet) { + sourceNameField.setFocus(); + } + // otherwise, set focus to selection group + else { + selectionGroup.setFocus(); + } + SystemWidgetHelpers.setWizardPageMnemonics(parentComposite); + if (helpId != null) { + SystemWidgetHelpers.setHelp(parentComposite, helpId); + } else { + SystemWidgetHelpers.setHelp(parentComposite, RSEUIPlugin.HELPPREFIX + "import_context"); //$NON-NLS-1$ + } + setControl(parentComposite); + // SystemWidgetHelpers.setHelp(getControl(), RSEUIPlugin.HELPPREFIX + "import_context"); + // Control c = getControl(); + // if (c instanceof Composite) + // { + // SystemWidgetHelpers.setWizardPageMnemonics((Composite)c); + // parentComposite = (Composite)c; + // if (helpId != null) + // SystemWidgetHelpers.setHelp(parentComposite, helpId); + // } + // else if (c instanceof Button) + // { + // Mnemonics ms = new Mnemonics(); + // ms.setMnemonic((Button)c); + // } + // configureMessageLine(); + } + + /** + * Create the import options specification widgets. + */ + protected void createOptionsGroupButtons(Group optionsGroup) { + overwriteExistingResourcesCheckbox = SystemWidgetHelpers.createCheckBox(optionsGroup, 1, null, SystemImportExportResources.RESID_FILEIMPORT_OPTION_OVERWRITE_LABEL, + SystemImportExportResources.RESID_FILEIMPORT_OPTION_OVERWRITE_TOOLTIP); + createContainerStructureButton = SystemWidgetHelpers.createRadioButton(optionsGroup, null, SystemImportExportResources.RESID_FILEIMPORT_OPTION_CREATEALL_LABEL, + SystemImportExportResources.RESID_FILEIMPORT_OPTION_CREATEALL_TOOLTIP); + createOnlySelectedButton = SystemWidgetHelpers.createRadioButton(optionsGroup, null, SystemImportExportResources.RESID_FILEIMPORT_OPTION_CREATESEL_LABEL, + SystemImportExportResources.RESID_FILEIMPORT_OPTION_CREATESEL_TOOLTIP); + createOnlySelectedButton.setSelection(true); + Composite comp = SystemWidgetHelpers.createComposite(optionsGroup, 3); + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + layout.marginWidth = 0; + comp.setLayout(layout); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + saveSettingsButton = SystemWidgetHelpers.createCheckBox(comp, 3, null, SystemImportExportResources.RESID_FILEIMPORT_OPTION_SETTINGS_LABEL, + SystemImportExportResources.RESID_FILEIMPORT_OPTION_SETTINGS_TOOLTIP); + saveSettingsButton.addListener(SWT.Selection, this); + descFilePathLabel = new Label(comp, SWT.NONE); + descFilePathLabel.setText(SystemImportExportResources.RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_LABEL); + GridData data = new GridData(); + descFilePathLabel.setLayoutData(data); + descFilePathField = new Text(comp, SWT.SINGLE | SWT.BORDER); + descFilePathField.setToolTipText(SystemImportExportResources.RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP); + data = new GridData(); + data.horizontalAlignment = GridData.HORIZONTAL_ALIGN_FILL; + data.grabExcessHorizontalSpace = true; + data.widthHint = convertWidthInCharsToPixels(60); + descFilePathField.setLayoutData(data); + descFilePathField.addListener(SWT.Modify, this); + descFileBrowseButton = SystemWidgetHelpers.createPushButton(comp, null, SystemImportExportResources.RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_BROWSE_LABEL, + SystemImportExportResources.RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_BROWSE_TOOLTIP); + descFileBrowseButton.addListener(SWT.Selection, this); + } + + /** + * Create the group for creating the root directory + */ + protected void createRootDirectoryGroup(Composite parent) { + Composite sourceContainerGroup = SystemWidgetHelpers.createComposite(parent, 3); + ((GridData) sourceContainerGroup.getLayoutData()).grabExcessHorizontalSpace = true; + sourceNameField = SystemWidgetHelpers.createLabeledReadonlyCombo(sourceContainerGroup, null, SystemImportExportResources.RESID_FILEIMPORT_SOURCE_LABEL, + SystemImportExportResources.RESID_FILEIMPORT_SOURCE_TOOLTIP); + ((GridData) sourceNameField.getLayoutData()).widthHint = SIZING_TEXT_FIELD_WIDTH; + ((GridData) sourceNameField.getLayoutData()).grabExcessHorizontalSpace = true; + sourceNameField.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateFromSourceField(); + } + }); + sourceNameField.addKeyListener(new KeyListener() { + /* + * @see KeyListener.keyPressed + */ + public void keyPressed(KeyEvent e) { + //If there has been a key pressed then mark as dirty + entryChanged = true; + } + + /* + * @see KeyListener.keyReleased + */ + public void keyReleased(KeyEvent e) { + } + }); + sourceNameField.addFocusListener(new FocusListener() { + /* + * @see FocusListener.focusGained(FocusEvent) + */ + public void focusGained(FocusEvent e) { + //Do nothing when getting focus + } + + /* + * @see FocusListener.focusLost(FocusEvent) + */ + public void focusLost(FocusEvent e) { + //Clear the flag to prevent constant update + if (entryChanged) { + entryChanged = false; + updateFromSourceField(); + } + } + }); + // source browse button + sourceBrowseButton = SystemWidgetHelpers.createPushButton(sourceContainerGroup, null, SystemImportExportResources.RESID_FILEEXPORT_DESTINATION_BROWSE_LABEL, + SystemImportExportResources.RESID_FILEEXPORT_DESTINATION_BROWSE_TOOLTIP); + ((GridData) sourceBrowseButton.getLayoutData()).grabExcessHorizontalSpace = false; + sourceBrowseButton.addListener(SWT.Selection, this); + } + + /** + * Update the receiver from the source name field. + */ + private void updateFromSourceField() { + setSourceName(sourceNameField.getText()); + //Update enablements when this is selected + updateWidgetEnablements(); + } + + /** + * Creates and returns a FileSystemElement if the specified + * file system object merits one. The criteria for this are: + * Also create the children. + */ + protected MinimizedFileSystemElement createRootElement(Object fileSystemObject, IImportStructureProvider provider) { + boolean isContainer = provider.isFolder(fileSystemObject); + String elementLabel = provider.getLabel(fileSystemObject); + // Use an empty label so that display of the element's full name + // doesn't include a confusing label + MinimizedFileSystemElement dummyParent = new MinimizedFileSystemElement("", null, true); //$NON-NLS-1$ + dummyParent.setPopulated(); + MinimizedFileSystemElement result = new MinimizedFileSystemElement(elementLabel, dummyParent, isContainer); + result.setFileSystemObject(fileSystemObject); + //Get the files for the element so as to build the first level + result.getFiles(provider); + return dummyParent; + } + + /** + * Create the import source specification widgets + */ + protected void createSourceGroup(Composite parent) { + sourceComposite = parent; + createRootDirectoryGroup(parent); + createFileSelectionGroup(parent); + createButtonsGroup(parent); + } + + /** + * Enable or disable the button group. + */ + protected void enableButtonGroup(boolean enable) { + selectTypesButton.setEnabled(enable); + selectAllButton.setEnabled(enable); + deselectAllButton.setEnabled(enable); + } + + /** + * Answer a boolean indicating whether the specified source currently exists + * and is valid + */ + protected boolean ensureSourceIsValid() { + if (((File) sourceDirectory).isDirectory()) return true; + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_FOLDER_IS_FILE); + msg.makeSubstitution(((File) sourceDirectory).getAbsolutePath()); + setErrorMessage(msg); + sourceNameField.setFocus(); + return false; + } + + /** + * Execute the passed import operation. Answer a boolean indicating success. + */ + protected boolean executeImportOperation(RemoteFileImportOperation op) { + try { + getContainer().run(true, true, op); + } catch (InterruptedException e) { + return false; + } catch (InvocationTargetException e) { + displayErrorDialog(e.getTargetException()); + return false; + } + IStatus status = op.getStatus(); + if (!status.isOK()) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_FAILED); + msg.makeSubstitution(status); + SystemMessageDialog dlg = new SystemMessageDialog(getContainer().getShell(), msg); + dlg.openWithDetails(); + return false; + } + return true; + } + + /** + * The Finish button was pressed. Try to do the required work now and answer + * a boolean indicating success. If false is returned then the wizard will + * not close. + * + * @return boolean + */ + public boolean finish() { + clearMessage(); + clearErrorMessage(); + Object file; + IHost conn; + String temp; + if (!ensureSourceIsValid()) return false; + saveWidgetValues(); + Iterator resourcesEnum = getSelectedResources().iterator(); + List fileSystemObjects = new ArrayList(); + conn = Utilities.parseForSystemConnection(sourceNameField.getText()); + while (resourcesEnum.hasNext()) { + Object fo = ((FileSystemElement) resourcesEnum.next()).getFileSystemObject(); + temp = ((File) fo).getAbsolutePath(); + if (UniFilePlus.class.isInstance(fo)) + file = fo; + else + file = new UniFilePlus(Utilities.getIRemoteFile(conn, temp)); + fileSystemObjects.add(file); + } + if (fileSystemObjects.size() > 0) { + RemoteFileImportData data = new RemoteFileImportData(); + data.setContainerPath(getContainerFullPath()); + data.setSource(getSourceDirectory()); + data.setElements(fileSystemObjects); + data.setOverWriteExistingFiles(overwriteExistingResourcesCheckbox.getSelection()); + data.setCreateDirectoryStructure(createContainerStructureButton.getSelection()); + data.setCreateSelectionOnly(createOnlySelectedButton.getSelection()); + data.setSaveSettings(saveSettingsButton.getSelection()); + data.setDescriptionFilePath(getDescriptionLocation()); + boolean ret = executeImportOperation(new RemoteFileImportOperation(data, FileSystemStructureProvider.INSTANCE, this)); + return ret; + } + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_NONE_SELECTED); + setErrorMessage(msg); + return false; + } + + /** + * Returns a content provider for FileSystemElements that returns + * only files as children. + */ + protected ITreeContentProvider getFileProvider() { + //IFS: add BusyIndicator + return new WorkbenchContentProvider() { + boolean busy = false; + + public Object[] getChildren(Object o) { + if (o instanceof MinimizedFileSystemElement && !busy) { + busy = true; + final MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; + final Object[] oa = new Object[1]; + BusyIndicator.showWhile(sourceComposite.getDisplay(), new Runnable() { + public void run() { + oa[0] = element.getFiles(FileSystemStructureProvider.INSTANCE).getChildren(element); + } + }); + busy = false; + return (Object[]) oa[0]; + } + return new Object[0]; + } + }; + } + + /** + * Answer the root FileSystemElement that represents the contents of + * the currently-specified source. If this FileSystemElement is not + * currently defined then create and return it. + */ + protected MinimizedFileSystemElement getFileSystemTree() { + File sourceDirectory = getSourceDirectory(); + if (sourceDirectory == null) return null; + return selectFiles(sourceDirectory, FileSystemStructureProvider.INSTANCE); + } + + /** + * Returns a content provider for FileSystemElements that returns + * only folders as children. + */ + protected ITreeContentProvider getFolderProvider() { + //IFS: add BusyIndicator + return new WorkbenchContentProvider() { + boolean busy = false; + + public Object[] getChildren(Object o) { + if (o instanceof MinimizedFileSystemElement && !busy) { + busy = true; + final MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; + final Object[] oa = new Object[1]; + BusyIndicator.showWhile(sourceComposite.getDisplay(), new Runnable() { + public void run() { + oa[0] = element.getFolders(FileSystemStructureProvider.INSTANCE).getChildren(element); + } + }); + busy = false; + return (Object[]) oa[0]; + } + return new Object[0]; + } + + public boolean hasChildren(Object o) { + if (o instanceof MinimizedFileSystemElement) { + MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; + if (element.isPopulated()) + return getChildren(element).length > 0; + else { + //If we have not populated then wait until asked + return true; + } + } + return false; + } + }; + } + + /** + * Returns this page's collection of currently-specified resources to be + * imported. This is the primary resource selection facility accessor for + * subclasses. + * + * Added here to allow access for inner classes. + * + * @return a collection of resources currently selected + * for export (element type: IResource) + */ + protected List getSelectedResources() { + return super.getSelectedResources(); + } + + /** + * Returns a File object representing the currently-named source directory iff + * it exists as a valid directory, or null otherwise. + */ + protected File getSourceDirectory() { + return getSourceDirectory(this.sourceNameField.getText()); + } + + /** + * Returns a File object representing the currently-named source directory iff + * it exists as a valid directory, or null otherwise. + * + * @param path a String not yet formatted for java.io.File compatability + */ + private File getSourceDirectory(String path) { + return (File) sourceDirectory; + } + + /** + * Answer the directory name specified as being the import source. + * Note that if it ends with a separator then the separator is first + * removed so that java treats it as a proper directory + */ + private String getSourceDirectoryName() { + return getSourceDirectoryName(this.sourceNameField.getText()); + } + + /** + * Answer the directory name specified as being the import source. + * Note that if it ends with a separator then the separator is first + * removed so that java treats it as a proper directory + */ + private String getSourceDirectoryName(String sourceName) { + IPath result = new Path(sourceName.trim()); + if (result.getDevice() != null && result.segmentCount() == 0) // something like "c:" + result = result.addTrailingSeparator(); + else + result = result.removeTrailingSeparator(); + //return result.toOSString(); + return result.toString(); + } + + /** + * Gets the description. + * @return the description. + */ + protected String getDescriptionLocation() { + return descFilePathField.getText().trim(); + } + + /** + * Returns whether the settings should be saved. + * @return whether settings should be saved. + */ + protected boolean isSaveSettings() { + // need this check + if (saveSettingsButton != null) { + return saveSettingsButton.getSelection(); + } else { + return false; + } + } + + /** + * Handle all events and enablements for widgets in this dialog + * + * @param event Event + */ + public void handleEvent(Event event) { + if (event.widget == sourceBrowseButton) { + handleSourceBrowseButtonPressed(); + } else if (event.widget == descFileBrowseButton) { + handleDescriptionFileBrowseButtonPressed(); + } + super.handleEvent(event); + } + + /** + * Open an appropriate source browser so that the user can specify a source + * to import from + */ + protected void handleSourceBrowseButtonPressed() { + SystemSelectRemoteFolderAction action = new SystemSelectRemoteFolderAction(this.getShell()); + action.setShowNewConnectionPrompt(true); + action.setShowPropertySheet(true, false); + action.run(); + IRemoteFile folder = action.getSelectedFolder(); + if (folder != null) { + clearErrorMessage(); + setSourceName(Utilities.getAsString(folder)); + selectionGroup.setFocus(); + } + } + + /** + * Open an appropriate destination browser so that the user can specify a source + * to import from. + */ + protected void handleDescriptionFileBrowseButtonPressed() { + SaveAsDialog dialog = new SaveAsDialog(getContainer().getShell()); + dialog.create(); + dialog.getShell().setText(RemoteImportExportResources.IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_TITLE); + dialog.setMessage(RemoteImportExportResources.IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_MESSAGE); + dialog.setOriginalFile(createFileHandle(new Path(getDescriptionLocation()))); + if (dialog.open() == Window.OK) { + IPath path = dialog.getResult(); + path = path.removeFileExtension().addFileExtension(Utilities.IMPORT_DESCRIPTION_EXTENSION); + descFilePathField.setText(path.toString()); + } + } + + /** + * Creates a file resource handle for the file with the given workspace path. + * This method does not create the file resource; this is the responsibility + * of createFile. + * + * @param filePath the path of the file resource to create a handle for + * @return the new file resource handle + */ + protected IFile createFileHandle(IPath filePath) { + if (filePath.isValidPath(filePath.toString()) && filePath.segmentCount() >= 2) + return SystemBasePlugin.getWorkspace().getRoot().getFile(filePath); + else + return null; + } + + /** + * Open a registered type selection dialog and note the selections + * in the receivers types-to-export field., + * Added here so that inner classes can have access + */ + protected void handleTypesEditButtonPressed() { + super.handleTypesEditButtonPressed(); + } + + /** + * Returns whether the extension provided is an extension that + * has been specified for import by the user. + * @param extension the resource extension. + * @return true if the resource name is suitable for import based upon its extension. + */ + protected boolean isImportableExtension(String extension) { + // i.e. - all extensions are acceptable + if (selectedTypes == null) { + return true; + } + Iterator z = selectedTypes.iterator(); + while (z.hasNext()) { + if (extension.equalsIgnoreCase((String) (z.next()))) { + return true; + } + } + return false; + } + + /** + * Is the element included in import data. + * @param element the file element. + * @return true if the element is included in the import data, false if not. + */ + protected boolean isIncludedInImportData(MinimizedFileSystemElement element) { + UniFilePlus file = (UniFilePlus) (element.getFileSystemObject()); + RemoteImportWizard parentWizard = (RemoteImportWizard) getWizard(); + RemoteFileImportData importData = parentWizard.getImportData(); + return importData.doesExist(file); + } + + /** + * Repopulate the view based on the currently entered directory. + */ + protected void resetSelection() { + MinimizedFileSystemElement currentRoot = getFileSystemTree(); + this.selectionGroup.setRoot(currentRoot); + } + + /** + * Use the dialog store to restore widget values to the values that they held + * last time this wizard was used to completion + */ + protected void restoreWidgetValues() { + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID); + if (sourceNames != null) { + // set filenames history + for (int i = 0; i < sourceNames.length; i++) { + sourceNameField.add(sourceNames[i]); + } + } + RemoteImportWizard parentWizard = (RemoteImportWizard) getWizard(); + boolean isInitializingFromImportData = parentWizard.getInitializeFromImportData(); + if (!isInitializingFromImportData) { + // radio buttons and checkboxes + overwriteExistingResourcesCheckbox.setSelection(settings.getBoolean(STORE_OVERWRITE_EXISTING_RESOURCES_ID)); + boolean createStructure = settings.getBoolean(STORE_CREATE_CONTAINER_STRUCTURE_ID); + createContainerStructureButton.setSelection(createStructure); + createOnlySelectedButton.setSelection(!createStructure); + boolean saveSettings = settings.getBoolean(STORE_CREATE_DESCRIPTION_FILE_ID); + saveSettingsButton.setSelection(saveSettings); + String descFilePathStr = settings.get(STORE_DESCRIPTION_FILE_NAME_ID); + if (descFilePathStr == null) { + descFilePathStr = ""; //$NON-NLS-1$ + } + descFilePathField.setText(descFilePathStr); + } else { + RemoteFileImportData importData = parentWizard.getImportData(); + // container path + String containerPath = importData.getContainerPath().toString(); + if (containerPath != null) { + setContainerFieldValue(containerPath); + } + // radio buttons and checkboxes + overwriteExistingResourcesCheckbox.setSelection(importData.isOverWriteExistingFiles()); + createContainerStructureButton.setSelection(importData.isCreateDirectoryStructure()); + createOnlySelectedButton.setSelection(importData.isCreateSelectionOnly()); + saveSettingsButton.setSelection(importData.isSaveSettings()); + String descFilePathStr = importData.getDescriptionFilePath(); + if (descFilePathStr == null) { + descFilePathStr = ""; //$NON-NLS-1$ + } + descFilePathField.setText(descFilePathStr); + UniFilePlus source = (UniFilePlus) (importData.getSource()); + if (source != null) { + setSourceName(source.getCanonicalPath()); + } + } + } + // check if there was an initial selection + // if it is a remote directory, then set the absolute path in the source name field + Object initSelection = getInputObject(); + if ((initSelection != null) && (initSelection instanceof IStructuredSelection)) { + IStructuredSelection sel = (IStructuredSelection) initSelection; + if (sel.size() == 1) { + Object theSel = sel.getFirstElement(); + if (theSel instanceof IRemoteFile) { + IRemoteFile file = (IRemoteFile) theSel; + // set source name if the input is a folder + if (file.isDirectory()) { + setSourceName(Utilities.getAsString(file)); + // indicate source name set initially from remote folder selection + initSourceNameSet = true; + } + } + } + } + } + + /** + * Since Finish was pressed, write widget values to the dialog store so that they + * will persist into the next invocation of this wizard page + */ + protected void saveWidgetValues() { + IDialogSettings settings = getDialogSettings(); + if (settings != null) { + // update source names history + String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID); + if (sourceNames == null) sourceNames = new String[0]; + sourceNames = addToHistory(sourceNames, getSourceDirectoryName()); + settings.put(STORE_SOURCE_NAMES_ID, sourceNames); + // radio buttons and checkboxes + settings.put(STORE_OVERWRITE_EXISTING_RESOURCES_ID, overwriteExistingResourcesCheckbox.getSelection()); + settings.put(STORE_CREATE_CONTAINER_STRUCTURE_ID, createContainerStructureButton.getSelection()); + settings.put(STORE_CREATE_DESCRIPTION_FILE_ID, isSaveSettings()); + settings.put(STORE_DESCRIPTION_FILE_NAME_ID, getDescriptionLocation()); + } + } + + /** + * Invokes a file selection operation using the specified file system and + * structure provider. If the user specifies files to be imported then + * this selection is cached for later retrieval and is returned. + */ + protected MinimizedFileSystemElement selectFiles(final Object rootFileSystemObject, final IImportStructureProvider structureProvider) { + final MinimizedFileSystemElement[] results = new MinimizedFileSystemElement[1]; + BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { + public void run() { + //Create the root element from the supplied file system object + results[0] = createRootElement(rootFileSystemObject, structureProvider); + } + }); + return results[0]; + } + + /** + * Set all of the selections in the selection group to value. Implemented here + * to provide access for inner classes. + * @param value boolean + */ + protected void setAllSelections(boolean value) { + super.setAllSelections(value); + } + + /** + * Sets the source name of the import to be the supplied path. + * Adds the name of the path to the list of items in the + * source combo and selects it. + * + * @param path the path to be added + */ + protected void setSourceName(String path) { + if (path.length() > 0) { + // Clear selection in case this method is Excepted. + sourceDirectory = null; + sourceNameField.setText(""); //$NON-NLS-1$ + resetSelection(); + String[] currentItems = this.sourceNameField.getItems(); + int selectionIndex = -1; + for (int i = 0; i < currentItems.length && selectionIndex < 0; i++) { + if (currentItems[i].equals(path)) selectionIndex = i; + } + if (selectionIndex < 0) { // New one from Browse + int oldLength = currentItems.length; + String[] newItems = new String[oldLength + 1]; + System.arraycopy(currentItems, 0, newItems, 0, oldLength); + newItems[oldLength] = path; + this.sourceNameField.setItems(newItems); + selectionIndex = oldLength; + } + if (Utilities.isConnectionValid(path, getShell())) + // At time of writing no exceptions were expected from this code! + // if one is received, issue it. + try { + sourceDirectory = null; + IHost as400Conn = Utilities.parseForSystemConnection(path); + if (as400Conn != null) { + IRemoteFile rf = Utilities.parseForIRemoteFile(path); + if (rf != null && rf.exists()) sourceDirectory = new UniFilePlus(rf); + sourceNameField.select(selectionIndex); + } + resetSelection(); + } catch (Exception e) { + Utilities.error(e); + } + } + } + + /** + * Update the tree to only select those elements that match the selected types + */ + protected void setupSelectionsBasedOnSelectedTypes() { + ProgressMonitorDialog dialog = new ProgressMonitorDialog(getContainer().getShell()); + final Map selectionMap = new Hashtable(); + final IElementFilter filter = new IElementFilter() { + public void filterElements(Collection files, IProgressMonitor monitor) throws InterruptedException { + if (files == null) { + throw new InterruptedException(); + } + Iterator filesList = files.iterator(); + while (filesList.hasNext()) { + if (monitor.isCanceled()) throw new InterruptedException(); + checkFile(filesList.next()); + } + } + + public void filterElements(Object[] files, IProgressMonitor monitor) throws InterruptedException { + if (files == null) { + throw new InterruptedException(); + } + for (int i = 0; i < files.length; i++) { + if (monitor.isCanceled()) throw new InterruptedException(); + checkFile(files[i]); + } + } + + private void checkFile(Object fileElement) { + MinimizedFileSystemElement file = (MinimizedFileSystemElement) fileElement; + if (isImportableExtension(file.getFileNameExtension())) { + List elements = new ArrayList(); + FileSystemElement parent = file.getParent(); + if (selectionMap.containsKey(parent)) elements = (List) selectionMap.get(parent); + elements.add(file); + selectionMap.put(parent, elements); + } + } + }; + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(final IProgressMonitor monitor) throws InterruptedException { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_FILTERING).getLevelOneText(); + monitor.beginTask(msg, IProgressMonitor.UNKNOWN); + getSelectedResources(filter, monitor); + } + }; + try { + // have to set fork to false to avoid InvocationTargetException !! + dialog.run(false, true, runnable); + } catch (InvocationTargetException exception) { + //Couldn't start. Do nothing. + return; + } catch (InterruptedException exception) { + //Got interrupted. Do nothing. + return; + } + // make sure that all paint operations caused by closing the progress + // dialog get flushed, otherwise extra pixels will remain on the screen until + // updateSelections is completed + getShell().update(); + // The updateSelections method accesses SWT widgets so cannot be executed + // as part of the above progress dialog operation since the operation forks + // a new process. + updateSelections(selectionMap); + } + + /** + * Update the tree to only select those elements that are in the import data. + */ + protected void setupSelectionsBasedOnImportData() { + ProgressMonitorDialog dialog = new ProgressMonitorDialog(getContainer().getShell()); + final Map selectionMap = new Hashtable(); + final IElementFilter filter = new IElementFilter() { + public void filterElements(Collection files, IProgressMonitor monitor) throws InterruptedException { + if (files == null) { + throw new InterruptedException(); + } + Iterator filesList = files.iterator(); + while (filesList.hasNext()) { + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + checkFile(filesList.next()); + } + } + + public void filterElements(Object[] files, IProgressMonitor monitor) throws InterruptedException { + if (files == null) { + throw new InterruptedException(); + } + for (int i = 0; i < files.length; i++) { + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + checkFile(files[i]); + } + } + + private void checkFile(Object fileElement) { + MinimizedFileSystemElement file = (MinimizedFileSystemElement) fileElement; + if (isIncludedInImportData(file)) { + List elements = new ArrayList(); + FileSystemElement parent = file.getParent(); + if (selectionMap.containsKey(parent)) { + elements = (List) (selectionMap.get(parent)); + } + elements.add(file); + selectionMap.put(parent, elements); + } + } + }; + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(final IProgressMonitor monitor) throws InterruptedException { + String msg = RSEUIPlugin.getPluginMessage(ISystemMessages.FILEMSG_IMPORT_FILTERING).getLevelOneText(); + monitor.beginTask(msg, IProgressMonitor.UNKNOWN); + getSelectedResources(filter, monitor); + } + }; + try { + // have to set fork to false to avoid InvocationTargetException !! + dialog.run(false, true, runnable); + } catch (InvocationTargetException exception) { + //Couldn't start. Do nothing. + return; + } catch (InterruptedException exception) { + //Got interrupted. Do nothing. + return; + } + // make sure that all paint operations caused by closing the progress + // dialog get flushed, otherwise extra pixels will remain on the screen until + // updateSelections is completed + getShell().update(); + // The updateSelections method accesses SWT widgets so cannot be executed + // as part of the above progress dialog operation since the operation forks + // a new process. + updateSelections(selectionMap); + } + + /* (non-Javadoc) + * Method declared on IDialogPage. Set the selection up when it becomes visible. + */ + public void setVisible(boolean visible) { + super.setVisible(visible); + resetSelection(); + // importing from remote folder selection + if (initSourceNameSet) { + setAllSelections(true); + selectionGroup.setFocus(); + } + RemoteImportWizard parentWizard = (RemoteImportWizard) getWizard(); + boolean isInitializingFromImportData = parentWizard.getInitializeFromImportData(); + // initializing from import data + if (isInitializingFromImportData) { + setAllSelections(true); + setupSelectionsBasedOnImportData(); + } + } + + /** + * Update the selections with those in map . Implemented here to give inner class + * visibility + * @param map Map - key tree elements, values Lists of list elements + */ + protected void updateSelections(Map map) { + super.updateSelections(map); + } + + /** + * Check if widgets are enabled or disabled by a change in the dialog. + * Provided here to give access to inner classes. + */ + protected void updateWidgetEnablements() { + // need this check because handleEvent(), which calls this, is called when restoring container + if (saveSettingsButton != null && descFilePathLabel != null && descFilePathField != null && descFileBrowseButton != null) { + boolean isSaveSettings = isSaveSettings(); + descFilePathLabel.setEnabled(isSaveSettings); + descFilePathField.setEnabled(isSaveSettings); + descFileBrowseButton.setEnabled(isSaveSettings); + } + // this calls to determine whether page can be completed + super.updateWidgetEnablements(); + } + + /** + * Answer a boolean indicating whether self's source specification + * widgets currently all contain valid values. + */ + protected boolean validateSourceGroup() { + File sourceDirectory = getSourceDirectory(); + if (sourceDirectory == null) { + setMessage(SOURCE_EMPTY_MESSAGE); + enableButtonGroup(false); + return false; + } + if (sourceConflictsWithDestination(new Path(sourceDirectory.getPath()))) { + setErrorMessage(getSourceConflictMessage()); + enableButtonGroup(false); + return false; + } + enableButtonGroup(true); + return true; + } + + /** + * @see org.eclipse.ui.dialogs.WizardDataTransferPage#validateOptionsGroup() + */ + protected boolean validateOptionsGroup() { + if (isSaveSettings()) { + IPath location = new Path(getDescriptionLocation()); + // if location is empty, no error message, but it's not valid + if (location.toString().length() == 0) { + setErrorMessage((String) null); + return false; + } + // location must start with '/' + if (!location.toString().startsWith("/")) { //$NON-NLS-1$ + setErrorMessage(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_ABSOLUTE); + return false; + } + // find the resource, including a variant if any + IResource resource = findResource(location); + // if resource is not a file, it must be a container. So location is pointing to a container, which is an error + if (resource != null && resource.getType() != IResource.FILE) { + setErrorMessage(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_EXISTING_CONTAINER); + return false; + } + // get the resource (or any variant of it) after removing the last segment + // this gets the parent resource + resource = findResource(location.removeLastSegments(1)); + // if parent resource does not exist, or if it is a file, then it is not valid + if (resource == null || resource.getType() == IResource.FILE) { + setErrorMessage(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_NO_CONTAINER); + return false; + } + // get the file extension + String fileExtension = location.getFileExtension(); + // ensure that file extension is valid + if (fileExtension == null || !fileExtension.equals(Utilities.IMPORT_DESCRIPTION_EXTENSION)) { + setErrorMessage(MessageFormat.format(RemoteImportExportResources.IMPORT_EXPORT_ERROR_DESCRIPTION_INVALID_EXTENSION, new Object[] { Utilities.IMPORT_DESCRIPTION_EXTENSION })); + return false; + } + } + return true; + } + + /** + * Returns the resource for the specified path. + * + * @param path the path for which the resource should be returned + * @return the resource specified by the path or null + */ + protected IResource findResource(IPath path) { + IWorkspace workspace = SystemBasePlugin.getWorkspace(); + // validate path + IStatus result = workspace.validatePath(path.toString(), IResource.ROOT | IResource.PROJECT | IResource.FOLDER | IResource.FILE); + // if path valid + if (result.isOK()) { + // get the workspace root + IWorkspaceRoot root = workspace.getRoot(); + // see if path exists. If it does, return the resource at the path + if (root.exists(path)) { + return root.findMember(path); + } + // see if a variant of the path exists + else { + // look for variant + IResource variant = RemoteImportExportUtil.getInstance().findExistingResourceVariant(path); + // if a variant does exist, return it + if (variant != null) { + return variant; + } + } + } + return null; + } + + /** + * Returns whether the source location conflicts + * with the destination resource. This will occur if + * the source is already under the destination. + * + * @param sourcePath the path to check + * @return true if there is a conflict, false if not + */ + protected boolean sourceConflictsWithDestination(IPath sourcePath) { + IContainer container = getSpecifiedContainer(); + if (container == null) + return false; + else + return getSpecifiedContainer().getLocation().isPrefixOf(sourcePath); + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#setInputObject(java.lang.Object) + */ + public void setInputObject(Object inputObject) { + this.inputObject = inputObject; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#getInputObject() + */ + public Object getInputObject() { + return inputObject; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#performFinish() + */ + public boolean performFinish() { + return finish(); + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#setHelp(java.lang.String) + */ + public void setHelp(String id) { + if (parentComposite != null) SystemWidgetHelpers.setHelp(parentComposite, helpId); + this.helpId = id; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.wizards.ISystemWizardPage#getHelpContextId() + */ + public String getHelpContextId() { + return helpId; + } + + // ---------------- + // INTERNAL METHODS + // ---------------- + /** + * Internal method
+ * Configure the message line + */ + // private void configureMessageLine() + // { + // msgLine = SystemDialogPageMessageLine.createWizardMsgLine(this); + // if (msgLine!=null) + // { + // if (pendingMessage!=null) + // setMessage(pendingMessage); + // if (pendingErrorMessage!=null) + // setErrorMessage(pendingErrorMessage); + // } + // } + // ----------------------------- + // ISystemMessageLine methods... + // ----------------------------- + /** + * ISystemMessageLine method.
+ * Clears the currently displayed error message and redisplayes + * the message which was active before the error message was set. + */ + public void clearErrorMessage() { + if (msgLine != null) msgLine.clearErrorMessage(); + } + + /** + * ISystemMessageLine method.
+ * Clears the currently displayed message. + */ + public void clearMessage() { + if (msgLine != null) msgLine.clearMessage(); + } + + /** + * ISystemMessageLine method.
+ * Get the currently displayed error text. + * @return The error message. If no error message is displayed null is returned. + */ + public SystemMessage getSystemErrorMessage() { + if (msgLine != null) + return msgLine.getSystemErrorMessage(); + else + return null; + } + + /** + * ISystemMessageLine method.
+ * Display the given error message. A currently displayed message + * is saved and will be redisplayed when the error message is cleared. + */ + public void setErrorMessage(SystemMessage message) { + if (msgLine != null) { + if (message != null) { + msgLine.setErrorMessage(message); + } else { + msgLine.clearErrorMessage(); + } + } else { // not configured yet + pendingErrorMessage = message; + } + } + + /** + * ISystemMessageLine method.
+ * Convenience method to set an error message from an exception + */ + public void setErrorMessage(Throwable exc) { + if (msgLine != null) + msgLine.setErrorMessage(exc); + else { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_ERROR_UNEXPECTED); + msg.makeSubstitution(exc); + pendingErrorMessage = msg; + } + } + + /** + * ISystemMessageLine method.
+ * Display the given error message. A currently displayed message + * is saved and will be redisplayed when the error message is cleared. + */ + public void setErrorMessage(String message) { + if (msgLine != null) { + if (message != null) { + msgLine.setErrorMessage(message); + } else { + msgLine.clearErrorMessage(); + } + } else { // not configured yet + pendingErrorString = message; + } + } + + /** + * ISystemMessageLine method.
+ * If the message line currently displays an error, + * the message is stored and will be shown after a call to clearErrorMessage + */ + public void setMessage(SystemMessage message) { + if (msgLine != null) { + msgLine.setMessage(message); + } else { // not configured yet + pendingMessage = message; + } + } + + /** + * ISystemMessageLine method.
+ * Set the non-error message text. If the message line currently displays an error, + * the message is stored and will be shown after a call to clearErrorMessage + */ + public void setMessage(String message) { + if (msgLine != null) { + msgLine.setMessage(message); + } else { // not configured yet + pendingString = message; + } + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeExpandDropListener.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeExpandDropListener.java new file mode 100644 index 00000000000..1e97b72de58 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeExpandDropListener.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +/** + * TreeExpandDropListener provides automatic expansion for Trees during drag and drop + * operations. + *

+ * If the pointer hovers for a time over an item in the Tree that has not yet been + * expanded, the item is expanded automatically. This behaviour is consistent with + * that of popular GUI systems. + *

+ * To use it send addDropListener(new TreeExpandDropListener(tree)) to the DropTarget + * object attached to the Tree. + *

+ */ +public class TreeExpandDropListener extends DropTargetAdapter { + public static final long DEFAULT_EXPAND_DELAY = 1000; // millis + private long hoverThreshhold = DEFAULT_EXPAND_DELAY; + private long hoverBegin = 0; + private TreeItem hoverItem = null; + private Tree tree; + + /** + * Constructs a Tree expanding Drop Listener + * + * @param tree the Tree that the DropTarget is attached to + */ + public TreeExpandDropListener(final Tree tree) { + this.tree = tree; + } + + /** + * Handles dragEnter events. + * This is an implementation detail. + */ + public void dragEnter(DropTargetEvent event) { + hoverItem = null; + } + + /** + * Handles dragOver events. + * This is an implementation detail. + */ + public void dragOver(DropTargetEvent event) { + Point point = tree.toControl(new Point(event.x, event.y)); + // Get the item directly under the point + TreeItem item = tree.getItem(point); + if (item != hoverItem) { + // We just started hovering, remember this item + if ((item != null) && (!item.getExpanded())) { + hoverBegin = System.currentTimeMillis(); + hoverItem = item; + } else { + hoverItem = null; + } + } else if (hoverItem != null) { + // We've been hovering for a while, expand if our timer elapsed + long hoverCurrent = System.currentTimeMillis(); + if (hoverCurrent - hoverBegin >= hoverThreshhold) { + // Fake as if the user expanded the item manually + Event hoverEvent = new Event(); + hoverEvent.x = event.x; + hoverEvent.y = event.y; + hoverEvent.item = hoverItem; + hoverEvent.time = (int) hoverCurrent; + hoverItem.setExpanded(true); + hoverItem = null; + tree.notifyListeners(SWT.Expand, hoverEvent); + } + } + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeScrollDropListener.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeScrollDropListener.java new file mode 100644 index 00000000000..ef640864048 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/TreeScrollDropListener.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +/** + * TreeScrollDropListener provides automatic scrolling for Trees during drag and drop + * operations. + *

+ * If the pointer drags over an item in the Tree near its upper or + * lower edges, the Tree will scroll so as to make previous or successive items visible + * onscreen. This behaviour is consistent with that of popular GUI systems. + *

+ * To use it send addDropListener(new TreeScrollDropListener(tree)) to the DropTarget + * object attached to the Tree. + *

+ */ +public class TreeScrollDropListener extends DropTargetAdapter { + private Tree tree; + + /** + * Constructs a Tree scrolling Drop Listener + * + * @param tree the Tree that the DropTarget is attached to + */ + public TreeScrollDropListener(final Tree tree) { + this.tree = tree; + } + + /** + * Handles dragOver events. + * This is an implementation detail. + */ + public void dragOver(DropTargetEvent event) { + Point point = tree.toControl(new Point(event.x, event.y)); + // Get the item directly under the point + TreeItem item = tree.getItem(point); + if (item == null) return; + // Determine scroll direction according to whether we're nearer the top, middle, or bottom + Rectangle clientArea = tree.getClientArea(); + int scrollRegionSize = Math.min(clientArea.height / 3, 24); // cut region into 3 parts + if (scrollRegionSize < 8) return; // don't scroll if the control is too small to make sense + TreeItem showItem = item; + for (;;) { + if (point.y < clientArea.y + scrollRegionSize) { + // in upper region + showItem = getPreviousVisibleItem(tree, showItem); + } else if (point.y > clientArea.height + clientArea.y - scrollRegionSize) { + // in lower region + showItem = getNextVisibleItem(tree, showItem, false); + } else { + // in middle region + break; + } + // Show the item (causes a scroll if it is outside of the visible region) + if (showItem == null) break; + tree.showItem(showItem); + // Test that we actually scrolled, if we didn't try again with the next item + if (item != tree.getItem(point)) break; + } + } + + /** + * Given a TreeItem, locates its last (lowest) visible item + *

+ * Note that the item may not be actually rendered onscreen though it would be + * visible were the control scrolled appropriately. + *

+ * + * @param item the TreeItem whose last visible child is to be found + * @return the last visible child, or item if no visible children. + */ + private TreeItem getLastVisibleChild(TreeItem item) { + if (!item.getExpanded()) return item; + TreeItem[] items = item.getItems(); + if (items == null || items.length == 0) return item; + return getLastVisibleChild(items[items.length - 1]); + } + + /** + * Given a TreeItem, locates the following (below the specified item) visible TreeItem in a tree. + *

+ * Note that the item may not be actually rendered onscreen though it would be + * visible were the control scrolled appropriately. + *

+ * + * @param tree the Tree containing the items + * @param item the TreeItem whose next visible neighbour is to be found + * @return the next visible item, or null if none. + */ + private TreeItem getNextVisibleItem(Tree tree, TreeItem item, boolean ignoreChildren) { + TreeItem parent = item.getParentItem(); + TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); + if (items != null) { + for (int i = 0; i < items.length; ++i) { + if (items[i] == item) { + if (!ignoreChildren && items[i].getExpanded()) { + TreeItem[] children = items[i].getItems(); + if (children != null && children.length > 0) return children[0]; + } + if (i + 1 < items.length) return items[i + 1]; + break; + } + } + if (parent != null) return getNextVisibleItem(tree, parent, true); + } + return null; + } + + /** + * Given a TreeItem, locates the previous (above the specified item) visible TreeItem in a tree. + *

+ * Note that the item may not be actually rendered onscreen though it would be + * visible were the control scrolled appropriately. + *

+ * + * @param tree the Tree containing the items + * @param item the TreeItem whose previous visible neighbour is to be found + * @return the previous visible item, or null if none. + */ + private TreeItem getPreviousVisibleItem(Tree tree, TreeItem item) { + TreeItem parent = item.getParentItem(); + TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); + if (items != null) { + for (int i = items.length - 1; i > 0; --i) { + if (items[i] == item) return getLastVisibleChild(items[i - 1]); + } + } + return parent; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/UniFilePlus.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/UniFilePlus.java new file mode 100644 index 00000000000..87f39da7786 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/UniFilePlus.java @@ -0,0 +1,359 @@ +package org.eclipse.rse.files.importexport.files; + +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Vector; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.services.files.RemoteFileException; +import org.eclipse.rse.services.files.RemoteFileSecurityException; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; + +public class UniFilePlus extends File { + /** + * + */ + private static final long serialVersionUID = -1717648997950319457L; + public IRemoteFile remoteFile = null; + + /** + * Constructor. There is only one way to construct this object, + * and that is by giving an IRemoteFile object. All java.io.File + * methods are intercepted and delegated to this contained object. + */ + public UniFilePlus(IRemoteFile remoteFile) { + super(remoteFile.getAbsolutePath()); + this.remoteFile = remoteFile; + } + + public boolean canRead() { + return remoteFile.canRead(); + } + + public boolean canWrite() { + return remoteFile.canWrite(); + } + + public int compareTo(File pathname) { + if (pathname instanceof UniFilePlus) return remoteFile.compareTo(pathname); + return super.compareTo(pathname); + } + + /* + public int compareTo(Object o) + { + return remoteFile.compareTo(o); + } + */ + public boolean createNewFile() throws IOException { + IRemoteFile newFile = null; + try { + newFile = remoteFile.getParentRemoteFileSubSystem().createFile(remoteFile); + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if (e != null) { + if (e instanceof SecurityException) + throw (SecurityException) e; + else if (e instanceof IOException) throw (IOException) e; + } + if (exc instanceof RemoteFileSecurityException) + throw new SecurityException(exc.getMessage()); + else + throw new IOException(exc.getMessage()); + } + if (newFile != null) { + remoteFile = newFile; + return true; + } else + return false; + } + + public boolean delete() { + boolean ok = true; + try { + ok = remoteFile.getParentRemoteFileSubSystem().delete(remoteFile, null); + //hmm, should we set remoteFile to null? + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if ((e != null) && (e instanceof SecurityException)) throw (SecurityException) e; + throw new SecurityException(exc.getMessage()); + } + return ok; + } + + /** + * NOT SUPPORTED! + */ + public void deleteOnExit() { + } + + public boolean equals(Object obj) { + return remoteFile.equals(obj); + } + + public boolean exists() { + return remoteFile.exists(); + } + + public File getAbsoluteFile() { + return this; // Remote File objects are always absolute! + } + + public String getAbsolutePath() { + return remoteFile.getAbsolutePath(); + } + + public File getCanonicalFile() { + // hmm, maybe we should equal getAbsolutePathPlusConnection as canonical! + return this; + } + + public String getCanonicalPath() { + return remoteFile.getAbsolutePathPlusConnection(); + } + + public String getName() { + return remoteFile.getName(); + } + + public String getParent() { + return remoteFile.getParentPath(); + } + + public File getParentFile() { + IRemoteFile parent = remoteFile.getParentRemoteFile(); + if (parent != null) { + return new File(parent.getAbsolutePath()); + //return parent.getFileWrapper(); + } else + return null; + } + + public String getPath() { + return remoteFile.getAbsolutePath(); + } + + public int hashCode() { + return remoteFile.getAbsolutePathPlusConnection().hashCode(); + } + + public boolean isAbsolute() { + return true; + } + + public boolean isDirectory() { + return remoteFile.isDirectory(); + } + + public boolean isFile() { + return remoteFile.isFile(); + } + + public boolean isHidden() { + return remoteFile.isHidden(); + } + + public long lastModified() { + return remoteFile.getLastModified(); + } + + public long length() { + return remoteFile.getLength(); + } + + /** + * Returns an array of remote files that are children of this folder. + * This will be an null if there is an error or if the target object + * is not a folder. + * @return the array of IRemoteFiles. + */ + public IRemoteFile[] listIRemoteFiles() { + IRemoteFile[] result = null; + try { + result = remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(remoteFile, getNullMonitor()); + } catch (SystemMessageException e) { + SystemBasePlugin.logError("unexpected exception", e); //$NON-NLS-1$ + } + return result; + } + + public String[] list() { + IRemoteFile[] files = null; + try { + files = remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(remoteFile, getNullMonitor()); + } catch (SystemMessageException e) { + SystemBasePlugin.logError("unexpected exception", e); //$NON-NLS-1$ + } + if (files != null) { + String[] fileNames = new String[files.length]; + for (int idx = 0; idx < files.length; idx++) + fileNames[idx] = files[idx].getName(); + return fileNames; + } else + return null; + } + + public String[] list(FilenameFilter filter) { + IRemoteFile[] files = null; + try { + files = remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(remoteFile, getNullMonitor()); + } catch (SystemMessageException e) { + SystemBasePlugin.logError("unexpected exception", e); //$NON-NLS-1$ + } + if (files != null) { + Vector v = new Vector(); + String fileName = null; + for (int idx = 0; idx < files.length; idx++) { + fileName = files[idx].getName(); + if ((fileName != null) && (filter.accept(this, fileName))) v.addElement(fileName); + } + String[] fileNames = new String[v.size()]; + for (int idx = 0; idx < v.size(); idx++) + fileNames[idx] = (String) v.elementAt(idx); + return fileNames; + } else + return null; + } + + public File[] listFiles(FileFilter filter) { + IRemoteFile[] files = null; + try { + files = remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(remoteFile, getNullMonitor()); + } catch (SystemMessageException e) { + SystemBasePlugin.logError("unexpected exception", e); //$NON-NLS-1$ + } + if (files != null) { + Vector v = new Vector(); + for (int idx = 0; idx < files.length; idx++) { + //fileName = files[idx].getName(); + File fileObj = new File(files[idx].getAbsolutePath()); + if (filter.accept(fileObj)) v.addElement(fileObj); + } + File[] fileObjs = new File[v.size()]; + for (int idx = 0; idx < v.size(); idx++) + fileObjs[idx] = (File) v.elementAt(idx); + return fileObjs; + } else + return null; + } + + public File[] listFiles(FilenameFilter filter) { + IRemoteFile[] files = null; + try { + files = remoteFile.getParentRemoteFileSubSystem().listFoldersAndFiles(remoteFile, getNullMonitor()); + } catch (SystemMessageException e) { + SystemBasePlugin.logError("unexpected exception", e); //$NON-NLS-1$ + } + if (files != null) { + Vector v = new Vector(); + String fileName = null; + for (int idx = 0; idx < files.length; idx++) { + fileName = files[idx].getName(); + if ((fileName != null) && (filter.accept(this, fileName))) v.addElement(files[idx]); + } + File[] fileObjs = new File[v.size()]; + for (int idx = 0; idx < v.size(); idx++) { + fileObjs[idx] = new File(((IRemoteFile) v.elementAt(idx)).getAbsolutePath()); + } + return fileObjs; + } else + return null; + } + + public boolean mkdir() { + IRemoteFile dir = null; + try { + if (!remoteFile.exists()) dir = remoteFile.getParentRemoteFileSubSystem().createFolder(remoteFile); + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if ((e != null) && (e instanceof SecurityException)) throw (SecurityException) e; + throw new SecurityException(exc.getMessage()); + } + if (dir != null) remoteFile = dir; + return (dir != null); + } + + public boolean mkdirs() { + IRemoteFile dir = null; + try { + if (!remoteFile.exists()) dir = remoteFile.getParentRemoteFileSubSystem().createFolder(remoteFile); + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if ((e != null) && (e instanceof SecurityException)) throw (SecurityException) e; + throw new SecurityException(exc.getMessage()); + } + if (dir != null) remoteFile = dir; + return (dir != null); + } + + public boolean renameTo(File dest) { + boolean ok = false; + try { + ok = remoteFile.getParentRemoteFileSubSystem().rename(remoteFile, dest.getName()); + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if ((e != null) && (e instanceof SecurityException)) throw (SecurityException) e; + throw new SecurityException(exc.getMessage()); + } + return ok; + } + + public boolean setLastModified(long time) { + boolean ok = false; + if (time < 0) throw new IllegalArgumentException(); + try { + IProgressMonitor monitor = new NullProgressMonitor(); + ok = remoteFile.getParentRemoteFileSubSystem().setLastModified(monitor, remoteFile, time); + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if ((e != null) && (e instanceof SecurityException)) throw (SecurityException) e; + throw new SecurityException(exc.getMessage()); + } + return ok; + } + + public boolean setReadOnly() { + boolean ok = false; + try { + ok = remoteFile.getParentRemoteFileSubSystem().setReadOnly(new NullProgressMonitor(), remoteFile, true); + } catch (RemoteFileException exc) { + Exception e = exc.getRemoteException(); + if ((e != null) && (e instanceof SecurityException)) throw (SecurityException) e; + throw new SecurityException(exc.getMessage()); + } + return ok; + } + + public String toString() { + return getPath(); + } + + public URL toURL() throws MalformedURLException { + String urlName = "file://" + remoteFile.getAbsolutePathPlusConnection().replace('\\', '/'); //$NON-NLS-1$ + if (remoteFile.isDirectory() && !urlName.endsWith("/")) //$NON-NLS-1$ + urlName = urlName + '/'; + return new URL(urlName); + } + + private IProgressMonitor getNullMonitor() { + IProgressMonitor result = new NullProgressMonitor(); + return result; + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Utilities.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Utilities.java new file mode 100644 index 00000000000..ae75ea04c65 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/files/importexport/files/Utilities.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.files.importexport.files; + +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.files.importexport.IRemoteImportExportConstants; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.swt.widgets.Shell; + +/** + * Contains several helper methods. + * A lot of these should really be provided by comm. layer, but for + * many reasons they were not. oh well .... + */ +public class Utilities implements IRemoteImportExportConstants { + public static final String IMPORT_DESCRIPTION_EXTENSION = REMOTE_FILE_IMPORT_DESCRIPTION_FILE_EXTENSION; + public static final String EXPORT_DESCRIPTION_EXTENSION = REMOTE_FILE_EXPORT_DESCRIPTION_FILE_EXTENSION; + + /** + * Use this method to get IRemoteFile object from SystemConnection, and path + * + */ + public static IRemoteFile getIRemoteFile(IHost c, String path) { + IRemoteFile ret = null; + if (c != null) { + try { + IRemoteFileSubSystem ss = RemoteFileUtility.getFileSubSystem(c); + ret = ss.getRemoteFileObject(path); + } catch (SystemMessageException e) { + // get RemoteFileObject has been changed to raise + // SystemMessageException. + error(e); + } + } + return ret; + } + + /** + * Use this method to get selected string from an + * IRemoteFile object. + */ + public static String getAsString(IRemoteFile selectedDirectory) { + return selectedDirectory.getSystemConnection().getSystemProfileName() + '.' + selectedDirectory.getSystemConnection().getAliasName() + ":" + selectedDirectory.getAbsolutePath(); //$NON-NLS-1$ + } + + /** + * Use this method to get selected string from an + * UniFilePlus object. + */ + public static String getAsString(UniFilePlus selectedDirectory) { + return selectedDirectory.remoteFile.getSystemConnection().getSystemProfileName() + '.' + selectedDirectory.remoteFile.getSystemConnection().getAliasName() + ":" + selectedDirectory.getPath(); //$NON-NLS-1$ + } + + /** + * Validate remote connection, and issue error if required. + * + */ + public static boolean isConnectionValid(String name, Shell s) { + boolean ret = true; + IHost sc = parseForSystemConnection(name); + if (sc == null) { + // invalid connection + ret = false; + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_IMPORT_EXPORT_UNABLE_TO_USE_CONNECTION); + SystemMessageDialog.show(s, msg); + //displayMessage(s, ISystemMessages.MSG_IMPORT_EXPORT_UNABLE_TO_USE_CONNECTION, true); + } + return ret; + } + + /** + * Use this method to retrieve an IRemoteFile object from a + * selection string. + */ + public static IRemoteFile parseForIRemoteFile(String sel) { + IHost c = parseForSystemConnection(sel); + if (c != null) { + String path = parseForPath(sel); + return getIRemoteFile(c, path); + } else + return null; + } + + /** + * Use this method to retrieve the file path from a + * selection string. + */ + public static String parseForPath(String sel) { + return sel.indexOf(":") >= 0 ? sel.substring(sel.indexOf(":") + 1) : sel; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Use this method to retrieve a SystemConnection from profile and a + * connectionName string. + */ + public static IHost getConnection(String profileName, String connectionName) { + IHost[] connections = RSEUIPlugin.getTheSystemRegistry().getHosts(); + if (profileName != null) { + // given both profile and connection name... + for (int loop = 0; loop < connections.length; loop++) { + if (connections[loop].getAliasName().equalsIgnoreCase(connectionName) && connections[loop].getSystemProfileName().equalsIgnoreCase(profileName)) return connections[loop]; + } + } else + // given only connection name... + for (int loop = 0; loop < connections.length; loop++) { + if (connections[loop].getAliasName().equalsIgnoreCase(connectionName)) return connections[loop]; // return 1st match + } + return null; + } + + /** + * Use this method to retrieve a SystemConnection from a + * selection string. Should really be a part of RSE. If + * multiple separators ('.') are encountered will try + * profile names with 0,1,2,...n separators in order until a + * valid connection is found, or we run out of options. + * + * Not perfect, for example will never return connection C for + * profile one.two.three, if connection three.C for profile one.two + * exists. But this scheme should work fine for most practical + * cases. + * + * Wish RSE had chosen a separator that could not be part of + * valid connection name. + */ + public static IHost parseForSystemConnection(String sel) { + try { + // Assumption: following will return null if connection has + // been deleted or renamed! + String connectionName = sel.substring(0, sel.indexOf(":")); //$NON-NLS-1$ + if (connectionName.indexOf('.') < 0) + return getConnection(null, connectionName); + else { + // iterate through all possible combinations until we find a match, or + // run out of options + int dots = 0, temp = 0; + IHost sc = null; + while (connectionName.indexOf('.', temp) >= 0) { + dots++; + temp = connectionName.indexOf('.', temp) + 1; + sc = getConnection(connectionName.substring(0, temp - 1), connectionName.substring(temp)); + if (sc != null) return sc; + } + // did not find any, last hope try no profile, and '.' in name + return getConnection(null, connectionName); + } + } catch (Exception e) { + // Received exception while validating string. + // Ignore exception, just return null on fall-thru + } + // Connection with specified name was not found + return null; + } + + // generic classes: + public static void error(Exception e) { + Object[] o = null; + // While developing launch configuration work we noticed that + // we could enter here with no access to a Shell object. Changed + // this method to simply log the exception in such cases. + Shell s = getShell(); + try { + s = SystemBasePlugin.getActiveWorkbenchWindow().getShell(); + } catch (Exception e1) { + s = null; + } + if (SystemMessageException.class.isInstance(e)) { + String mID = ((SystemMessageException) e).getSystemMessage().getFullMessageID().substring(0, 8); + Debug.out("About to issue SystemMessageException for " + mID); //$NON-NLS-1$ + if (mID.compareToIgnoreCase("EVFC9104") != 0 && mID.compareToIgnoreCase("EVFC9112") != 0) { //$NON-NLS-1$ //$NON-NLS-2$ + // As per DY, do not issue 9104, or 9112 messages; they must have already been issued! + if (s != null) { + SystemMessageDialog d = new SystemMessageDialog(s, ((SystemMessageException) e).getSystemMessage()); + d.open(); + } + } + } else { + o = new Object[] { e.getLocalizedMessage() == null ? e.toString() : e.getLocalizedMessage() }; + logExceptionError(ISystemMessages.MSG_IMPORT_EXPORT_UNEXPECTED_EXCEPTION, o, e); + if (s != null) { + //displayMessage(s, ISystemMessages.MSG_IMPORT_EXPORT_UNEXPECTED_EXCEPTION, o, false); + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_IMPORT_EXPORT_UNEXPECTED_EXCEPTION); + msg.makeSubstitution(o[0]); + SystemMessageDialog.show(s, msg); + } + } + } + + public static Shell getShell() { + Shell s = null; + try { + s = SystemBasePlugin.getActiveWorkbenchWindow().getShell(); + } catch (Exception e1) { + s = null; + } + return s; + } + + public static void logExceptionError(String msgId, Throwable exception) { + String msg = msgId + " " + RSEUIPlugin.getPluginMessage(msgId).getLevelOneText(); //$NON-NLS-1$ + SystemBasePlugin.logError(msg, exception); + } + + public static void logExceptionError(String msgId, Object[] subs, Throwable exception) { + SystemMessage sysMsg = RSEUIPlugin.getPluginMessage(msgId); + sysMsg.makeSubstitution(subs); + String msg = msgId + " " + sysMsg.getLevelOneText(); //$NON-NLS-1$ + SystemBasePlugin.logError(msg, exception); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/RemoteImportExportPlugin.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/RemoteImportExportPlugin.java new file mode 100644 index 00000000000..bf584a1a85f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/RemoteImportExportPlugin.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.importexport; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class RemoteImportExportPlugin extends AbstractUIPlugin { + //The shared instance. + private static RemoteImportExportPlugin plugin; + + /** + * The constructor. + */ + public RemoteImportExportPlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static RemoteImportExportPlugin getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.rse.importexport", path); //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.java new file mode 100644 index 00000000000..eb93474af98 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.importexport; + +import org.eclipse.osgi.util.NLS; + +public class SystemImportExportResources extends NLS { + private static String BUNDLE_NAME = "org.eclipse.rse.importexport.SystemImportExportResources";//$NON-NLS-1$ + public static String IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_MESSAGE; + public static String IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_TITLE; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_ABSOLUTE; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_EXISTING_CONTAINER; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_INVALID_EXTENSION; + public static String IMPORT_EXPORT_ERROR_DESCRIPTION_NO_CONTAINER; + // REMOTE FILE EXPORT WIZARD... + public static String RESID_FILEEXPORT_TITLE; + public static String RESID_FILEEXPORT_PAGE1_TITLE; + public static String RESID_FILEEXPORT_PAGE1_DESCRIPTION; + public static String RESID_FILEEXPORT_DESTINATION_LABEL; + public static String RESID_FILEEXPORT_DESTINATION_TOOLTIP; + public static String RESID_FILEEXPORT_DESTINATION_BROWSE_LABEL; + public static String RESID_FILEEXPORT_DESTINATION_BROWSE_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_OVERWRITE_LABEL; + public static String RESID_FILEEXPORT_OPTION_OVERWRITE_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_CREATEALL_LABEL; + public static String RESID_FILEEXPORT_OPTION_CREATEALL_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_CREATESEL_LABEL; + public static String RESID_FILEEXPORT_OPTION_CREATESEL_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_LABEL; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_LABEL; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_BROWSE_LABEL; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_BROWSE_TOOLTIP; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_DELTA_LABEL; + public static String RESID_FILEEXPORT_OPTION_SETTINGS_DELTA_TOOLTIP; + public static String RESID_FILEEXPORT_EXPORTING; + // REMOTE FILE IMPORT WIZARD... + public static String RESID_FILEIMPORT_TITLE; + public static String RESID_FILEIMPORT_PAGE1_TITLE; + public static String RESID_FILEIMPORT_PAGE1_DESCRIPTION; + public static String RESID_FILEIMPORT_OPTION_OVERWRITE_LABEL; + public static String RESID_FILEIMPORT_OPTION_OVERWRITE_TOOLTIP; + public static String RESID_FILEIMPORT_OPTION_CREATEALL_LABEL; + public static String RESID_FILEIMPORT_OPTION_CREATEALL_TOOLTIP; + public static String RESID_FILEIMPORT_OPTION_CREATESEL_LABEL; + public static String RESID_FILEIMPORT_OPTION_CREATESEL_TOOLTIP; + public static String RESID_FILEIMPORT_OPTION_SETTINGS_LABEL; + public static String RESID_FILEIMPORT_OPTION_SETTINGS_TOOLTIP; + public static String RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_LABEL; + public static String RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP; + public static String RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_BROWSE_LABEL; + public static String RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_BROWSE_TOOLTIP; + public static String RESID_FILEIMPORT_SOURCE_LABEL; + public static String RESID_FILEIMPORT_SOURCE_TOOLTIP; + public static String RESID_FILEIMPORT_SOURCE_BROWSE_LABEL; + public static String RESID_FILEIMPORT_SOURCE_BROWSE_TOOLTIP; + public static String RESID_FILEIMPORT_IMPORTING; + public static String RESID_FILEIMPEXP_BUTTON_SELECTALL_LABEL; + public static String RESID_FILEIMPEXP_BUTTON_SELECTALL_TOOLTIP; + public static String RESID_FILEIMPEXP_BUTTON_DESELECTALL_LABEL; + public static String RESID_FILEIMPEXP_BUTTON_DESELECTALL_TOOLTIP; + public static String RESID_FILEIMPEXP_BUTTON_SELECTTYPES_LABEL; + public static String RESID_FILEIMPEXP_BUTTON_SELECTTYPES_TOOLTIP; + // REMOTE JAR EXPORT WIZARD + public static String RESID_RMTJAREXP_PREFIX; + public static String RESID_RMTJAREXP_FILEDIALOG_PREFIX; + public static String RESID_RMTJAREXP_FILEDIALOG_TITLE; + public static String RESID_RMTJAREXP_FILEDIALOG_PROMPT_LABEL; + public static String RESID_RMTJAREXP_FILEDIALOG_FILENAME_LABEL; + public static String RESID_RMTJAREXP_FILEDIALOG_FILENAME_TOOLTIP; + public static String RESID_RMTJAREXP_FILEDIALOG_FILETYPE_LABEL; + public static String RESID_RMTJAREXP_FILEDIALOG_FILETYPE_TOOLTIP; + public static String RESID_RMTJAREXP_SETTINGS_PREFIX; + public static String RESID_RMTJAREXP_SETTINGS_LABEL; + public static String RESID_RMTJAREXP_SETTINGS_TOOLTIP; + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, SystemImportExportResources.class); + } +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.properties b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.properties new file mode 100644 index 00000000000..c9da53b5008 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/importexport/SystemImportExportResources.properties @@ -0,0 +1,122 @@ +############################################################################### +# Copyright (c) 2000, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +# NLS_MESSAGEFORMAT_NONE +# NLS_ENCODING=UTF-8 + +#============================================================= +# REMOTE FILE EXPORT WIZARD... +#============================================================= +RESID_FILEEXPORT_TITLE=Export +RESID_FILEEXPORT_PAGE1_TITLE=Remote file system +RESID_FILEEXPORT_PAGE1_DESCRIPTION=Export resources to a remote file system. +RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_LABEL=Description file: +RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP=Enter the description file path +RESID_FILEEXPORT_EXPORTING=Exporting: + +RESID_FILEEXPORT_DESTINATION_LABEL=Destination folder, qualified by its remote connection name +RESID_FILEEXPORT_DESTINATION_TOOLTIP=Select the destination folder by browsing a remote system for it + +RESID_FILEEXPORT_DESTINATION_BROWSE_LABEL=Browse... +RESID_FILEEXPORT_DESTINATION_BROWSE_TOOLTIP=Select the destination folder by browsing a remote system for it + +RESID_FILEEXPORT_OPTION_OVERWRITE_LABEL=Overwrite existing files without warning +RESID_FILEEXPORT_OPTION_OVERWRITE_TOOLTIP=If a file being exported already exists remotely, replace it without a message + +RESID_FILEEXPORT_OPTION_CREATEALL_LABEL=Create directory structure for files +RESID_FILEEXPORT_OPTION_CREATEALL_TOOLTIP=Create hierarchy (folder) structure in the file system as it exists in the Workbench + +RESID_FILEEXPORT_OPTION_CREATESEL_LABEL=Create only selected directories +RESID_FILEEXPORT_OPTION_CREATESEL_TOOLTIP=Create hierarchy (folder) structure in the file system only for selected folders + +RESID_FILEEXPORT_OPTION_SETTINGS_LABEL=Save the settings of this export in the workspace (e.g. /ExportSettings/hello.rexpfd) +RESID_FILEEXPORT_OPTION_SETTINGS_TOOLTIP=Save the export settings to a description file for quicker export in the future + +RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_LABEL=Description file: + +RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP=Enter the description file path + +RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_BROWSE_LABEL=Browse... +RESID_FILEEXPORT_OPTION_SETTINGS_DESCFILE_BROWSE_TOOLTIP=Specify the description file by browsing the workspace + +RESID_FILEEXPORT_OPTION_SETTINGS_DELTA_LABEL=Export only changed resources +RESID_FILEEXPORT_OPTION_SETTINGS_DELTA_TOOLTIP=Export resources that have changed since last export when description file is used + + +#============================================================= +# REMOTE FILE IMPORT WIZARD... +#============================================================= +RESID_FILEIMPORT_TITLE=Import +RESID_FILEIMPORT_PAGE1_TITLE=Remote file system +RESID_FILEIMPORT_PAGE1_DESCRIPTION=Import resources from a remote file system. +RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_LABEL=Description file: +RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_PATH_TOOLTIP=Enter the description file path +RESID_FILEIMPORT_IMPORTING=Importing: + +RESID_FILEIMPORT_OPTION_OVERWRITE_LABEL=Overwrite existing resources without warning +RESID_FILEIMPORT_OPTION_OVERWRITE_TOOLTIP=If a file being exported already exists remotely, replace it without a message + +RESID_FILEIMPORT_OPTION_CREATEALL_LABEL=Create complete folder structure +RESID_FILEIMPORT_OPTION_CREATEALL_TOOLTIP=Create hierarchy (folder) structure in the Workbench, including parent folders + +RESID_FILEIMPORT_OPTION_CREATESEL_LABEL=Create selected folders only +RESID_FILEIMPORT_OPTION_CREATESEL_TOOLTIP=Create hierarchy (folder) structure in the Workbench + +RESID_FILEIMPORT_OPTION_SETTINGS_LABEL=Save the settings of this import in the workspace (e.g. /ImportSettings/hello.rimpfd) +RESID_FILEIMPORT_OPTION_SETTINGS_TOOLTIP=Save the import settings to a description file for quicker import in the future + +RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_BROWSE_LABEL=Browse... +RESID_FILEIMPORT_OPTION_SETTINGS_DESCFILE_BROWSE_TOOLTIP=Specify the description file by browsing the workspace + +RESID_FILEIMPORT_SOURCE_LABEL=From directory: +RESID_FILEIMPORT_SOURCE_TOOLTIP=Source folder, qualified by its remote connection name + +RESID_FILEIMPORT_SOURCE_BROWSE_LABEL=Browse... +RESID_FILEIMPORT_SOURCE_BROWSE_TOOLTIP=Select the source folder by browsing a remote system for it + +RESID_FILEIMPEXP_BUTTON_SELECTALL_LABEL=Select All +RESID_FILEIMPEXP_BUTTON_SELECTALL_TOOLTIP=Select all resources + +RESID_FILEIMPEXP_BUTTON_DESELECTALL_LABEL=Deselect All +RESID_FILEIMPEXP_BUTTON_DESELECTALL_TOOLTIP=De-select all resources + +RESID_FILEIMPEXP_BUTTON_SELECTTYPES_LABEL=Select Types +RESID_FILEIMPEXP_BUTTON_SELECTTYPES_TOOLTIP=Select resource types to subset the selection list by + +com.ibm.etools.systems.ui.FileImport.option.settings.descfile.label=Description file: +com.ibm.etools.systems.ui.FileImport.option.settings.descfile.path.tooltip=Enter the description file path + + + +#============================================================= +# REMOTE JAR EXPORT WIZARD +#============================================================= +RESID_RMTJAREXP_FILEDIALOG_TITLE= Save As +RESID_RMTJAREXP_FILEDIALOG_PROMPT_LABEL= Specify or select a remote jar file +RESID_RMTJAREXP_FILEDIALOG_FILENAME_LABEL= File name +RESID_RMTJAREXP_FILEDIALOG_FILENAME_TOOLTIP= Enter the name of the jar file +RESID_RMTJAREXP_FILEDIALOG_FILETYPE_LABEL= Save as type +RESID_RMTJAREXP_FILEDIALOG_FILETYPE_TOOLTIP= Select the file type + +RESID_RMTJAREXP_SETTINGS_LABEL=Save the settings of this jar export in the workspace (e.g. /ExportSettings/hello.rmtjardesc) +RESID_RMTJAREXP_SETTINGS_TOOLTIP=Save the jar export settings to a description file for quicker export in the future + + + + + + +IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_TITLE= +IMPORT_EXPORT_DESCRIPTION_FILE_DIALOG_MESSAGE= +IMPORT_EXPORT_ERROR_DESCRIPTION_ABSOLUTE= +IMPORT_EXPORT_ERROR_DESCRIPTION_EXISTING_CONTAINER= +IMPORT_EXPORT_ERROR_DESCRIPTION_NO_CONTAINER= +IMPORT_EXPORT_ERROR_DESCRIPTION_INVALID_EXTENSION= diff --git a/rse/plugins/org.eclipse.rse.useractions/.classpath b/rse/plugins/org.eclipse.rse.useractions/.classpath new file mode 100644 index 00000000000..7398f97e2d0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.useractions/.cvsignore b/rse/plugins/org.eclipse.rse.useractions/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/rse/plugins/org.eclipse.rse.useractions/.project b/rse/plugins/org.eclipse.rse.useractions/.project new file mode 100644 index 00000000000..ad67c8e1dea --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/.project @@ -0,0 +1,28 @@ + + + org.eclipse.rse.useractions + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/rse/plugins/org.eclipse.rse.useractions/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.useractions/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..f1d9aa8cb1f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/META-INF/MANIFEST.MF @@ -0,0 +1,32 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %plugin.name +Bundle-SymbolicName: org.eclipse.rse.useractions;singleton:=true +Bundle-Version: 2.0.0 +Bundle-Activator: org.eclipse.rse.useractions.Activator +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.resources, + org.eclipse.core.runtime, + org.eclipse.jface.text, + org.eclipse.ui, + org.eclipse.ui.views, + org.eclipse.ui.workbench.texteditor, + org.eclipse.ui.ide, + org.eclipse.rse.core, + org.eclipse.rse.services, + org.eclipse.rse.subsystems.shells.core, + org.eclipse.rse.subsystems.files.core, + org.eclipse.rse.shells.ui, + org.eclipse.rse.ui +Eclipse-LazyStart: true +Export-Package: org.eclipse.rse.useractions, + org.eclipse.rse.useractions.files.compile, + org.eclipse.rse.useractions.files.uda, + org.eclipse.rse.useractions.ui, + org.eclipse.rse.useractions.ui.compile, + org.eclipse.rse.useractions.ui.compile.teamview, + org.eclipse.rse.useractions.ui.propertypages, + org.eclipse.rse.useractions.ui.uda, + org.eclipse.rse.useractions.ui.uda.actions, + org.eclipse.rse.useractions.ui.uda.util +Bundle-Vendor: Eclipse.org diff --git a/rse/plugins/org.eclipse.rse.useractions/about.html b/rse/plugins/org.eclipse.rse.useractions/about.html new file mode 100644 index 00000000000..e8ed9d8aad1 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/about.html @@ -0,0 +1,30 @@ + + + + +About + + +

About This Content

+ +

June 5, 2006

+

License

+

The Eclipse Foundation makes available all content in this plug-in ("Content"). +Unless otherwise indicated below, the Content is provided to you under the +terms and conditions of the Eclipse Public License Version 1.0 ("EPL"). +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content. +

+

+If you did not receive this Content directly from the Eclipse Foundation, +the Content is being redistributed by another party ("Redistributor") and different +terms and conditions may apply to your use of any object code in the Content. +Check the Redistributor’s license that was provided with the Content. +If no such license exists, contact the Redistributor. +Unless otherwise indicated below, the terms and conditions of the EPL still +apply to any source code in the Content and such source code may be obtained +at http://www.eclipse.org. +

+ + \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.useractions/build.properties b/rse/plugins/org.eclipse.rse.useractions/build.properties new file mode 100644 index 00000000000..c2b9e0b19e0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/build.properties @@ -0,0 +1,17 @@ +############################################################################### +# Copyright (c) 2002, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/,\ + plugin.properties diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibm_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibm_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..c7a0c3fc2fa8114f01df4996e5d34018f0ddaaaf GIT binary patch literal 596 zcmZ?wbhEHb6krfwc*el+_{qBy=kBiDbZq_hldY52bxmFU?Z=;=zy3HSFLFy?;+3`B zH*b|s=Ddiq^$B&`Qk%A?HEr)+e0Jiztp`qAd-(GE(>FiGjbd|p_80UYD4BGqV%pK# z8ONIDoM@YW>gD^NpTGUi=-g92?NH_PBU4wOK6d5hy%*n~zWw>?!_Rl0e|4`s+qL4% z>C@xn*{jg!yXbm*>PHvgsr8Ho-$WxNN0DrxUIE`mNq9FTi}&& z1#>GCO+^lQ`G5!E{u=K;X!yPHm6Kx@6H*rvV+{Wx#PV=Oz{2^h5{$oM4K-G>(n3&W)OkU9P*rQBiJqr_qH2`i>@@D`5 literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibmuser_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibmuser_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..1c277194b2173de4d7933fce6294ba893bd4811c GIT binary patch literal 587 zcmZ?wbhEHb6krfwc*el+_wTb|sZHC{ znznZ@K09&V*6oLH95`|9;mhw&-~1Feip}ZSU(kP`WYVFEX-8{k9BZ0$qHX@Et9M_$ zeE&0}b5G^;Bgd}1JbCr`y%*n~zWw>?!_Rl0e|4`s+qL4%O%+w>O`-x9QmJ9j9-dyZiLqy~i`>FMROw^|iZquiwA>Fu5YI zKhvTw)1p7eZbE_cgaVgIC0_lRme)`1`VR&Sg8(T0WMO1r2xia$xdjv_4D2f!f}41_ zxSQIWJY1cdB#qQ$IXi;gyIquyeF~E@%%DV`p>P;6KfOwWy_z z93O+PgR_fYhlrJ#y0%oHkE5g4WML}{Lsd_J;qnQAJsWnSvdYVv21ZK@M08D__H;_!eD^{6O-J9 R> zoD*&HPrZEq^Ygdg8J&B|ryZ)Ceq`$E)5os7y!Yb!)3-lgefatA^RMoeXS-IMnY`iB zo-_9+%vv^g$F+<1-adNs{rUSJ8;;)IeB$1wW4CvlzIE>I({uM8&z!&T!OPdz?%utA z|L&8wub#epb?w%*MN4L1zIod}UMSt-Uq>!GK}lfZ|UUMh1p31|5(S zKykvrzNsOsNq~>PsXffABTU9bOOdz3%dx9n+R{*wyWPXn(bKbC%G8LPrzybA&E4HC zpea<6o6E)3HO$}N+s}7{gteYBH(T&_pFp2>aT^P5T_w(tqhUcEVm4OBnpzyJtj^tG z@@AIC8Vc-ka!wD!9MnI2RJVU?Co9V&DySwX$`JNbiDQ>zW7B>v1BM@)ivk3?IfePA l1^igQP?Sl zoD*&HPrZEq^Ygdg8J&B|ryZ)Ceq`$E)5os7y!Yb!)3-lgefatA^RMoeXS-IMnY`iB zo-_9+%vv^g$F+<1-adNs{rUSJ8;;)IeB$1wW4CvlzIE>I({uM8&z!&T!OPdz?%utA z|L&8wub#epb?w%*MN4L1zIFKO@h1x- z1A_;H4#=^fIALI)(BRP|z{lUz-q9{&qNT{&IYHXeP?38=rf1*jJXlmzUg>{-e~VK}z=3H8hb@EL KmnWJ64AuaUd(Gtl literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..802d0ebe890983f9af0ac6e25588a094ef55c2d7 GIT binary patch literal 338 zcmZ?wbhEHb6krfwxXQq=X2a=evo=nhwK2b>t)XpZ9*}IG5tmX}(=k6Ov)nCxiC5Ng z-@H{mne!sb)~7aYPixwq)3d*z|3Jy4L$x!GHO)B@ms)t`{>RGcN2abmeeBB1t`%n{ zZ@9GQ%>B7Lu3fzMcEi!zn@`-^bnJFmd`4J8hF?UyUu1%NP`Hy{;L~@n{(}Jn1wip9 z3nK%AHiHhx43M7~*zymECVA+r>+@*IIvJxh;pEe&j5{qBx-VVDbjV~~gs$q9f(GHh zt4j}VST#>OPmO@O`A4Mc4V*y05Gw8+5i9m literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_user_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_user_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..15d6f4ba853da500e39e552732b5e44b29a390a7 GIT binary patch literal 361 zcmV-v0hazpNk%w1VGsZi0M!5htgy?Lnz5Cdv2S#SfQFfFbcTS3n9I-EUSx56h@WC< zceTRXO>U}8X`WbiuVsR_W`ei3!`N($zi^Mhbdth-n8t#f$X;b})Zg*d-RgOl#KzR= zim1%I%-_`C?IJ^Gow(M~-tDl(+q1~tvc}t1UuaffXiivPPFY|_QddGwQM0(YBN5a=E#$LSCe>Ak7+oLX*iE;K9F!jkZ?qjbV_SgIFD&L|NsC0|Nj60 z00000A^8LW002DzEC2ui01yBW000Jtz+PfVEcSZ3*h|Q3I-7@{ObKK1Fb@a@I-}04 z7LlgW%u#d4M6)t#IC!_#3x+#dF%8Dn=5payc4`>5U1_33nb|?e_04KmlDapyl HsX+ic{u`t( literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_new_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_new_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..b595eb20bf27eb0063c8bfd882dcbb010c1952d3 GIT binary patch literal 370 zcmV-&0ge7gNk%w1VGsZi0M!5h|C#@+u*;U3v6Y&!Z*+!$hM8`3hJc5dUSx4%X?I>_ zaaLbwR$ypOSYJ+AU`J9{LQYZs{qNJnd&#$NZDc;y#CzP!hW+%htz~j%JaT3| zZe%`fV?OBJw*B+ZwUHyWk|Vm8CT?Rs{O6b z%Ub5vTY^H7Q0Qn2OL#e->T>yfE~?+E+T&$?DJdi;>-T(jq literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..556c02836333ee70df93ad0162414dcd51fff64f GIT binary patch literal 353 zcmZ?wbhEHb6krfwxXQq=X2a=evo=nhwK2b>t)XpZ9*}IG5tmY!lvy5^S{N3e5tfkQ z7ZL9lncyB2?&KGE`AGH2?fJPWcGr$n-#Oj3XIa#twW&pEHbrT+c`0_e$#yU9ZmY<& z&P%p?ba`n@zIk)L`H>Y7bvc%`IhN%a)-$UOrdAkEC^eo?W<0abs;kI!!xZniHTtuv z47yX5a{Oifg8>84K=CIFBLjmWgAPas$WIJxbq6G}J#>!soe;}888dBy$K|5QUb)lM zUI=dWi40r+)KfaRR8j9*P^pW8=RZ|1V5&*zbjzr@wlTAuk{7w9FY(G+?v^sgH*b|s=DdWu zZD~#0yBD7gDBG0Nv%jGKK*^*-71NG3%{kFF|CE3E#-Pg0p;ep1Yqmz#ZHsN(kCc8?p%EM=B*c>K79Li?%v}E&t5!u`TD_&mq)MPxOVsM`8&6tynXfb z-K#s#ZvFfF{_mIbe?On!I#GG+B;{Sx)&4wRJg-u0S)XG0Q2fcl$iU#kpaXIsC{7sIXE*pXHMg`j>+tgEv^lkkSjcj>I@$I%3+u>owKzE1 zIy$xpakhBa+1cCMc{B-HY0PeRcXxJkZ4$6H)sSazaq)C%=C{^RQD@WEI<4(>O5aD? zSVLKc)$qm*qZ@iYQs$b9s?6R`pLrYJ^^vqu<1&2y>}8XLnG(l`k1t+{n<%i{WGWI) dQEX>tG>FoOSs@@L%r45nV&JkdX`usyH2@Z8#%TZm literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..8d1885ba6d462b50c91d83917187da89c1d6ba3d GIT binary patch literal 341 zcmV-b0jmB-Nk%w1VGsZi0M!5hE>D#%P?a=QmpNLUJzSbXW1>c9q)KY1Mr52#ZmLXa zo?w2qW`ehiqs>ruvTTgMaF4)rlEQeF#e$s3hM&q$cd=4=vsHStSA4ZuezskKxM+#I zcb39=m&Asn&6TUmh^5Y>yV{GW&5Nncim1$zuhf#S(vz^#ow(Mx%iKtaxVF#ZxXaoY zXrM57taY8aqr=(S=fGkq|NsC0|Nj60 z00000A^8LW002DzEC2ui01yBW000JZz@BhOEDl)>2Fqxq+&T+pal+~-q(w;rON``D zS1v?HLwye1hYm$L8CI&eT=nX0WT+9R5bOKGtbv+Ih00CULML_^Nw%MdP literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_user_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_user_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..19ef4a224c6eba8e3117289ae1313a6594f2791b GIT binary patch literal 577 zcmZ?wbhEHb6krfwc*ek>=RZ|1V5&*zbjzr@wlTAuk{7w9FY(G+?v^sgH*b|s=DdWu zZD~#0yBD7gDBG0Nv%jGKK*^*-71NG3%{kFF|CE3E#-Pg0p;ep1Yqmz#ZHsN(k7B^VW+`AHMxMckl6oXD=SSeEs0X%cIwCT)TVs{GHoR-oASJ z?$w=Vw{BlvxO+?2hZ`$i9;y5G?8M}n@G14NQyUW|R|NKFTJ&XF^yk=3C~%%o;4-Pi zD?8MpKhyF*7%&Vnp!k!8k%7UVK?me6P@FKZ&uj2+YHn$5*5T#RX>0ar60wlw?(uhV zY!cRy~Wg!&?IQ3Ij6;SnXA8mwW+2&d$ad4?O94XQs1-FH{Ep0d&E-qSlxb5^jixmtC3`@JknHd?Z0noe22mk;8 literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_new_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_new_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..823609da24a3264223dd67f8a949052be521b1e0 GIT binary patch literal 577 zcmZ?wbhEHb6krfwc*ek>Fu5YIKhvTw)1p7eZbE_cgaVgIC0^N~ z7X6u)|G|J^kO9S?EQ|~c{tP-GcY)%BfqhCi#u`&Cr^9W1JS^F{gy1V)L-D*|%<$sHD}NO}SUE+gEauI%Db-s literal 0 HcmV?d00001 diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..2ecef415faf0314feaf64c575b1b855defa69b64 GIT binary patch literal 341 zcmV-b0jmB-Nk%w1VGsZi0M!5hNQk($&*Kb)C7R!`a&C^7HVe?&oyp-gfiu zrR3Oe=iiU;>7nrHs_Wi+@aLf0%yiq#dB3Vv!K_!sv0%ioV9dH|&%Jc9nM1*VJvcFD@f6|Aq{Yq-OEf7i zS8nUzxOjBj(%~|x + + + + + + + + + + + + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/Activator.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/Activator.java new file mode 100644 index 00000000000..cee42ef9066 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/Activator.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The main plugin class to be used in the desktop. + */ +public class Activator extends AbstractUIPlugin { + //The shared instance. + private static Activator plugin; + + /** + * The constructor. + */ + public Activator() { + plugin = this; + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.rse.useractions", path); //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsIcon.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsIcon.java new file mode 100644 index 00000000000..2ff84f8e650 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsIcon.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * Defines the standard icons for user actions, user types, and compile commands. + * Images and image descriptions may be extracted from these. + * There is no public constructor. Use the predefined instances of this class + * to access the images and descriptors. + */ +public class UserActionsIcon { + /** + * A new user defined action. + */ + public static final UserActionsIcon USERACTION_NEW = new UserActionsIcon("user_action_new_obj"); //$NON-NLS-1$ + /** + * An existing user defined user action. + */ + public static final UserActionsIcon USERACTION_USR = new UserActionsIcon("user_action_obj"); //$NON-NLS-1$ + /** + * A predefined user defined action. + */ + public static final UserActionsIcon USERACTION_IBM = new UserActionsIcon("user_action_ibm_obj"); //$NON-NLS-1$ + /** + * A predefined user defined action that has been modified. + */ + public static final UserActionsIcon USERACTION_IBMUSR = new UserActionsIcon("user_action_ibm_user_obj"); //$NON-NLS-1$ + /** + * A new user defined type. + */ + public static final UserActionsIcon USERTYPE_NEW = new UserActionsIcon("user_type_new_obj"); //$NON-NLS-1$ + /** + * An existing user defined type. + */ + public static final UserActionsIcon USERTYPE_USR = new UserActionsIcon("user_type_obj"); //$NON-NLS-1$ + /** + * A predefined user defined type. + */ + public static final UserActionsIcon USERTYPE_IBM = new UserActionsIcon("user_type_ibm_obj"); //$NON-NLS-1$ + /** + * A predefined user defined type that has been modified. + */ + public static final UserActionsIcon USERTYPE_IBMUSR = new UserActionsIcon("user_type_ibm_user_obj"); //$NON-NLS-1$ + /** + * A new user defined compile command. + */ + public static final UserActionsIcon COMPILE_NEW = new UserActionsIcon("compcmd_new_obj"); //$NON-NLS-1$ + /** + * An existing user defined compile command. + */ + public static final UserActionsIcon COMPILE_USR = new UserActionsIcon("compcmd_user_obj"); //$NON-NLS-1$ + /** + * A predefined user defined compile command. + */ + public static final UserActionsIcon COMPILE_IBM = new UserActionsIcon("compcmd_ibm_obj"); //$NON-NLS-1$ + /** + * A predefined user defined compile command that has been edited. + */ + public static final UserActionsIcon COMPILE_IBMUSR = new UserActionsIcon("compcmd_ibmuser_obj"); //$NON-NLS-1$ + private static final String PREFIX = "icon."; //$NON-NLS-1$ + private static final String ICON_DIR = "icons/full/obj16/"; //$NON-NLS-1$ + private static final String ICON_EXT = ".gif"; //$NON-NLS-1$ + private String name; + private String id; + private String location; + + private UserActionsIcon(String name) { + this.name = name; + this.id = PREFIX + name; + this.location = ICON_DIR + name + ICON_EXT; + } + + /** + * Gets the image associated with this icon. This image is stored in the image registry of the + * user actions plugin and therefore the image must not be disposed when its use is completed. + * @return the image + */ + public Image getImage() { + ImageRegistry registry = Activator.getDefault().getImageRegistry(); + Image image = registry.get(id); + if (image == null) { + ImageDescriptor descriptor = getImageDescriptor(); + image = descriptor.createImage(); + registry.put(id, image); + } + return image; + } + + /** + * Gets the image descriptor associated with this icon. + * @return the image descriptor + */ + public ImageDescriptor getImageDescriptor() { + ImageDescriptor descriptor = Activator.getImageDescriptor(location); + return descriptor; + } + + /** + * @return the name of the icon + */ + public String getName() { + return name; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.java new file mode 100644 index 00000000000..acf7b2df203 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions; + +import org.eclipse.osgi.util.NLS; + +public class UserActionsResources extends NLS { + private static String BUNDLE_NAME = "org.eclipse.rse.useractions.UserActionsResources"; //$NON-NLS-1$ + // Property sheet values: Categories in Team view + public static String RESID_PROPERTY_TEAM_USERACTION_TYPE_VALUE; + public static String RESID_PROPERTY_TEAM_COMPILETYPE_TYPE_VALUE; + public static String RESID_PROPERTY_TEAM_COMPILECMD_TYPE_VALUE; + // USER ACTION PROPERTIES PAGE... + public static String RESID_PP_USERACTION_TITLE; + public static String RESID_PP_USERACTION_TYPE_VALUE; + public static String RESID_PP_USERACTION_PROFILE_LABEL; + public static String RESID_PP_USERACTION_PROFILE_TOOLTIP; + public static String RESID_PP_USERACTION_ORIGIN_LABEL; + public static String RESID_PP_USERACTION_ORIGIN_TOOLTIP; + public static String RESID_PP_USERACTION_DOMAIN_LABEL; + public static String RESID_PP_USERACTION_DOMAIN_TOOLTIP; + // COMPILE TYPE PROPERTIES PAGE... + public static String RESID_PP_COMPILETYPE_TITLE; + public static String RESID_PP_COMPILETYPE_TYPE_VALUE; + public static String RESID_PP_COMPILETYPE_TYPE_TOOLTIP; + public static String RESID_PP_COMPILETYPE_PROFILE_LABEL; + public static String RESID_PP_COMPILETYPE_PROFILE_TOOLTIP; + public static String RESID_PP_COMPILETYPE_FILETYPE_LABEL; + public static String RESID_PP_COMPILETYPE_FILETYPE_TOOLTIP; + // COMPILE COMMAND PROPERTIES PAGE... + public static String RESID_PP_COMPILECMD_TITLE; + public static String RESID_PP_COMPILECMD_TYPE_VALUE; + public static String RESID_PP_COMPILECMD_PROFILE_LABEL; + public static String RESID_PP_COMPILECMD_PROFILE_TOOLTIP; + public static String RESID_PP_COMPILECMD_ORIGIN_LABEL; + public static String RESID_PP_COMPILECMD_ORIGIN_TOOLTIP; + // USER ACTIONS + public static String ACTION_COMPILE_NOPROMPT_LABEL; + public static String ACTION_COMPILE_NOPROMPT_TOOLTIP; + public static String ACTION_COMPILE_PROMPT_LABEL; + public static String ACTION_COMPILE_PROMPT_TOOLTIP; + // Property sheet values: User actions + public static String RESID_PROPERTY_ORIGIN_IBM_VALUE; + public static String RESID_PROPERTY_ORIGIN_IBMUSER_VALUE; + public static String RESID_PROPERTY_ORIGIN_USER_VALUE; + public static String RESID_PROPERTY_ORIGIN_ISV_VALUE; + public static String RESID_PROPERTY_ORIGIN_ISVUSER_VALUE; + public static String RESID_PROPERTY_USERACTION_VENDOR_LABEL; + public static String RESID_PROPERTY_USERACTION_VENDOR_TOOLTIP; + public static String RESID_PROPERTY_USERACTION_DOMAIN_LABEL; + public static String RESID_PROPERTY_USERACTION_DOMAIN_TOOLTIP; + public static String RESID_PROPERTY_USERACTION_DOMAIN_ALL_VALUE; + // Property sheet values: Compile types + public static String RESID_PROPERTY_COMPILETYPE_TYPES_LABEL; + public static String RESID_PROPERTY_COMPILETYPE_TYPES_DESCRIPTION; + // TEAM VIEW + public static String RESID_TEAMVIEW_USERACTION_VALUE; + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, UserActionsResources.class); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.properties b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.properties new file mode 100644 index 00000000000..3648682e42f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/UserActionsResources.properties @@ -0,0 +1,85 @@ +############################################################################### +# Copyright (c) 2002, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +# NLS_MESSAGEFORMAT_NONE +# NLS_ENCODING=UTF-8 + +#TEAM VIEW PROPERTIES +RESID_PROPERTY_TEAM_USERACTION_TYPE_VALUE=User action +RESID_PROPERTY_TEAM_COMPILETYPE_TYPE_VALUE=Compilable source type +RESID_PROPERTY_TEAM_COMPILECMD_TYPE_VALUE=Compile command + +#============================================================= +# USER ACTION PROPERTIES PAGE... +#============================================================= +RESID_PP_USERACTION_TITLE=Properties for User Action +RESID_PP_USERACTION_TYPE_VALUE=User action +RESID_PP_USERACTION_PROFILE_LABEL=Parent profile +RESID_PP_USERACTION_PROFILE_TOOLTIP=Profile that contains this user action +RESID_PP_USERACTION_ORIGIN_LABEL=Origin +RESID_PP_USERACTION_ORIGIN_TOOLTIP=Who supplied this user action? +RESID_PP_USERACTION_DOMAIN_LABEL=Domain +RESID_PP_USERACTION_DOMAIN_TOOLTIP=What domain is this action scoped to? + +#============================================================= +# COMPILE TYPE PROPERTIES PAGE... +#============================================================= +RESID_PP_COMPILETYPE_TITLE=Properties for Compilable Source Type +RESID_PP_COMPILETYPE_TYPE_VALUE=Compilable source type +RESID_PP_COMPILETYPE_TYPE_TOOLTIP=What type of artifact is this? +RESID_PP_COMPILETYPE_PROFILE_LABEL=Parent profile +RESID_PP_COMPILETYPE_PROFILE_TOOLTIP=Profile that contains this compile type and its compile commands +RESID_PP_COMPILETYPE_FILETYPE_LABEL=Source type +RESID_PP_COMPILETYPE_FILETYPE_TOOLTIP=The type of source that this type's compile commands apply to + +#============================================================= +# COMPILE COMMAND PROPERTIES PAGE... +#============================================================= +RESID_PP_COMPILECMD_TITLE=Properties for Compilable Command +RESID_PP_COMPILECMD_TYPE_VALUE=Compile command +RESID_PP_COMPILECMD_PROFILE_LABEL=Parent profile +RESID_PP_COMPILECMD_PROFILE_TOOLTIP=Profile that contains this compile command +RESID_PP_COMPILECMD_ORIGIN_LABEL=Origin +RESID_PP_COMPILECMD_ORIGIN_TOOLTIP=Who supplied this compile command? + +#============================================================= +# USER ACTIONS... +#============================================================= +ACTION_COMPILE_NOPROMPT_LABEL=Compile +ACTION_COMPILE_NOPROMPT_TOOLTIP=Run compile commands without prompting them +ACTION_COMPILE_PROMPT_LABEL=Compile (Prompt) +ACTION_COMPILE_PROMPT_TOOLTIP=Prompt and then run compile commands + +#============================================================= +#USER ACTION PROPERTIES - PROPERTY SHEET +#============================================================= +RESID_PROPERTY_ORIGIN_IBM_VALUE=IBM supplied +RESID_PROPERTY_ORIGIN_IBMUSER_VALUE=IBM supplied, user edited +RESID_PROPERTY_ORIGIN_ISV_VALUE=ISV supplied +RESID_PROPERTY_ORIGIN_ISVUSER_VALUE=ISV supplied, user edited +RESID_PROPERTY_ORIGIN_USER_VALUE=User defined +RESID_PROPERTY_USERACTION_DOMAIN_ALL_VALUE=All +RESID_PROPERTY_USERACTION_VENDOR_LABEL=Vendor +RESID_PROPERTY_USERACTION_VENDOR_TOOLTIP=Vendor that supplied this command +RESID_PROPERTY_USERACTION_DOMAIN_LABEL=Domain +RESID_PROPERTY_USERACTION_DOMAIN_TOOLTIP=Object domain this applies to + +#============================================================= +#COMPILE TYPE PROPERTIES - PROPERTY SHEET +#============================================================= +RESID_PROPERTY_COMPILETYPE_TYPES_LABEL=File type +RESID_PROPERTY_COMPILETYPE_TYPES_DESCRIPTION=File type this refers to + +#============================================================= +# Team View +#============================================================= +RESID_TEAMVIEW_USERACTION_VALUE=User action + diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileManager.java new file mode 100644 index 00000000000..26d97e87c0a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileManager.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.files.compile; + +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.compile.SystemCompileProfile; + +/** + * Specialization of the compile manager for universal files, for local files. + */ +public class LocalCompileManager extends UniversalCompileManager { + /** + * Constructor for LocalCompileManager. + */ + public LocalCompileManager() { + super(); + } + + /** + * Overridable method to instantiate the SystemCompileProfile for the + * given system profile. + *

+ * We return an instance of LocalCompileProfile + */ + protected SystemCompileProfile createCompileProfile(ISystemProfile profile) { + return new LocalCompileProfile(this, profile.getName()); + } + + /** + * For support of the Work With Compile Commands dialog. + *

+ * Return the substitution variables supported by compile commands managed by this manager. + */ + public SystemCmdSubstVarList getSubstitutionVariableList() { + return UniversalCompileSubstList.getSingleton(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileProfile.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileProfile.java new file mode 100644 index 00000000000..9c7ab8510fb --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/LocalCompileProfile.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.files.compile; + +import org.eclipse.rse.useractions.ui.compile.SystemCompileManager; + +/** + * Specialization of the compile profile class, uniquely for the compile support of files from + * the local file subsystem. + */ +public class LocalCompileProfile extends UniversalCompileProfile { + /** + * Constructor + * @param manager + * @param profileName + */ + public LocalCompileProfile(SystemCompileManager manager, String profileName) { + super(manager, profileName); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompilableSource.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompilableSource.java new file mode 100644 index 00000000000..65028040654 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompilableSource.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.files.compile; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.shells.ui.RemoteCommandHelpers; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.useractions.ui.compile.SystemCompilableSource; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommand; +import org.eclipse.swt.widgets.Shell; + +/** + * This encapsulates a file in a universal file system, which is to be compiled. + */ +public class UniversalCompilableSource extends SystemCompilableSource { + /** + * Constructor for UniversalCompilableSource. + * @param shell + * @param firstSelection + * @param compileCmd + * @param isPrompt + */ + public UniversalCompilableSource(Shell shell, Object firstSelection, SystemCompileCommand compileCmd, boolean isPrompt, Viewer viewer) { + super(shell, firstSelection, compileCmd, isPrompt, viewer); + } + + /** + * After the substituting and the prompting, it is now time to the remote running of the + * fully resolved compile command. Do that here. + *

+ * We use the RemoteCommandHelpers class to run it. + */ + protected boolean internalRunCompileCommand(String compileCmd) { + String path = RemoteCommandHelpers.getWorkingDirectory((IRemoteFile) firstSelection); + boolean ok = RemoteCommandHelpers.runUniversalCommand(shell, compileCmd, path, getCommandSubSystem(), true); + return ok; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileManager.java new file mode 100644 index 00000000000..f1c0a28d156 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileManager.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.files.compile; + +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.compile.ISystemCompileCommandSubstitutor; +import org.eclipse.rse.useractions.ui.compile.SystemCompileManager; +import org.eclipse.rse.useractions.ui.compile.SystemCompileProfile; +import org.eclipse.rse.useractions.ui.compile.SystemDefaultCompileCommands; + +/** + * Specializatio of compile support for universal file subsystems. + */ +public class UniversalCompileManager extends SystemCompileManager { + /** + * Constructor for UniversalCompileManager. + */ + public UniversalCompileManager() { + super(); + } + + /** + * Overridable method to instantiate the SystemCompileProfile for the + * given system profile. + *

+ * We return an instance of UniversalCompileProfile + */ + protected SystemCompileProfile createCompileProfile(ISystemProfile profile) { + return new UniversalCompileProfile(this, profile.getName()); + } + + /** + * Return the default list of compile commands to prime new documents with. + */ + public SystemDefaultCompileCommands getDefaultCompileCommands() { + return UniversalIBMCompileCommands.getIBMCompileCommands(); + } + + /** + * For support of the Work With Compile Commands dialog. + *

+ * Return the substitution variables supported by compile commands managed by this manager. + */ + public SystemCmdSubstVarList getSubstitutionVariableList() { + return UniversalCompileSubstList.getSingleton(); + } + + /** + * @see org.eclipse.rse.useractions.ui.compile.SystemCompileManager#createSubstitutor(IHost) + */ + protected ISystemCompileCommandSubstitutor createSubstitutor(IHost connection) { + return new UniversalCompileSubstitutor(connection); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileProfile.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileProfile.java new file mode 100644 index 00000000000..9d8fcd15205 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileProfile.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.files.compile; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.useractions.ui.compile.SystemCompilableSource; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommand; +import org.eclipse.rse.useractions.ui.compile.SystemCompileManager; +import org.eclipse.rse.useractions.ui.compile.SystemCompileProfile; +import org.eclipse.swt.widgets.Shell; + +/** + * Specialization of the compile profile class, uniquely for the compile support of files from + * a universal file subsystem. + */ +public class UniversalCompileProfile extends SystemCompileProfile { + /** + * Constructor for UniversalCompileProfile. + * @param manager + * @param profileName + */ + public UniversalCompileProfile(SystemCompileManager manager, String profileName) { + super(manager, profileName); + } + + /** + * When the time comes to actually run a compile command against a selected source object, + * this method is called to return the instance of SystemCompilableSource to do that. + *

+ * This method must be implemented to return an instance of your subclass of SystemCompilableSource. + */ + public SystemCompilableSource getCompilableSourceObject(Shell shell, Object selectedObject, SystemCompileCommand compileCmd, boolean isPrompt, Viewer viewer) { + UniversalCompilableSource compilableSrc = new UniversalCompilableSource(shell, selectedObject, compileCmd, isPrompt, viewer); + return compilableSrc; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstList.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstList.java new file mode 100644 index 00000000000..48cfbb7dd87 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstList.java @@ -0,0 +1,54 @@ +package org.eclipse.rse.useractions.files.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; + +/** + * Encapsulation of the compile command substitution variables for universal files. + */ +public class UniversalCompileSubstList extends SystemCmdSubstVarList { + private static final String[] UNIVERSAL_FILES_VARNAMES = { "system_filesep", //$NON-NLS-1$ + "system_homedir", //$NON-NLS-1$ + "system_pathsep", //$NON-NLS-1$ + "system_tempdir", //$NON-NLS-1$ + "resource_name", //$NON-NLS-1$ + "resource_name_root", //$NON-NLS-1$ + "resource_path", //$NON-NLS-1$ + "resource_path_root", //$NON-NLS-1$ + "resource_path_drive", //$NON-NLS-1$ + "container_name", //$NON-NLS-1$ + "container_path" //$NON-NLS-1$ + }; + private static final String[] UNIVERSAL_FILES_DESCRIPTIONS = { SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_SYSTEM_FILESEP, SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_SYSTEM_HOMEDIR, + SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_SYSTEM_PATHSEP, SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_SYSTEM_TEMPDIR, SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME, + SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME_ROOT, SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH, + SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH_ROOT, SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH_DRIVE, + SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_CONTAINER_NAME, SystemUDAResources.RESID_COMPILE_FILES_SUBVAR_CONTAINER_PATH }; + private static UniversalCompileSubstList inst = null; + + /** + * Constructor . + * Not to be used directly. Rather, use getSingleton(). + */ + UniversalCompileSubstList() { + super(UNIVERSAL_FILES_VARNAMES, UNIVERSAL_FILES_DESCRIPTIONS); + } + + /** + * Return the singleton of this object. No need ever for more than one instance + */ + public static UniversalCompileSubstList getSingleton() { + if (inst == null) inst = new UniversalCompileSubstList(); + return inst; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstitutor.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstitutor.java new file mode 100644 index 00000000000..593291f61f6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalCompileSubstitutor.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.files.compile; + +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.shells.ui.RemoteCommandHelpers; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystemConfiguration; +import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem; +import org.eclipse.rse.useractions.ui.compile.ISystemCompileCommandSubstitutor; + +/** + * This class is responsible for doing variable substitution for iSeries compile + * commands + */ +public class UniversalCompileSubstitutor implements ISystemCompileCommandSubstitutor { + private IHost connection; + + /** + * Constructor for UniversalCompileSubstitutor. + */ + public UniversalCompileSubstitutor(IHost connection) { + super(); + this.connection = connection; + } + + /** + * Reset the connection so one instance can be re-used + */ + public void setConnection(IHost connection) { + this.connection = connection; + } + + /** + * @see org.eclipse.rse.useractions.ui.ISystemSubstitutor#getSubstitutionValue(String, Object) + */ + public String getSubstitutionValue(String substitutionVariable, Object context) { + //private static final String[] UNIVERSAL_FILES_VARNAMES = + //{"system_filesep", "system_homedir", "system_pathsep", "system_tempdir", + // "user_id", "resource_name", "resource_path", "resource_path_root", "resource_path_drive", "container_name", "container_path"}; + if (substitutionVariable.equals("${system_filesep}")) //$NON-NLS-1$ + return getFileSeparator(); + else if (substitutionVariable.equals("${system_homedir}")) //$NON-NLS-1$ + return getHomeDirectory(); + else if (substitutionVariable.equals("${system_pathsep}")) //$NON-NLS-1$ + return getPathSeparator(); + else if (substitutionVariable.equals("${system_tempdir}")) //$NON-NLS-1$ + return getTempDirectory(); + else if (substitutionVariable.equals("${user_id}")) //$NON-NLS-1$ + return getUserId(); + else if (substitutionVariable.equals("${resource_name}")) //$NON-NLS-1$ + return getResourceName(context); + else if (substitutionVariable.equals("${resource_name_root}")) //$NON-NLS-1$ + return getResourceNameRoot(context); + else if (substitutionVariable.equals("${resource_path}")) //$NON-NLS-1$ + return getResourcePath(context); + else if (substitutionVariable.equals("${resource_path_root}")) //$NON-NLS-1$ + return getPathRoot(context); + else if (substitutionVariable.equals("${resource_path_drive}")) //$NON-NLS-1$ + return getPathDrive(context); + else if (substitutionVariable.equals("${container_name}")) //$NON-NLS-1$ + return getContainerName(context); + else if (substitutionVariable.equals("${container_path}")) //$NON-NLS-1$ + return getContainerPath(context); + return null; + } + + /** + * Get the command subsystem + */ + protected IRemoteCmdSubSystem getCmdsSubSystem() { + return RemoteCommandHelpers.getCmdSubSystem(connection); + } + + /** + * Get the files subsystem + */ + protected IRemoteFileSubSystem getFilesSubSystem() { + return RemoteFileUtility.getFileSubSystem(connection); + } + + /** + * Get the files subsystem factory + */ + protected IRemoteFileSubSystemConfiguration getFilesSubSystemFactory() { + return RemoteFileUtility.getFileSubSystem(connection).getParentRemoteFileSubSystemConfiguration(); + } + + /** + * Return the file separator for the ${system_filesep} variable + */ + protected String getFileSeparator() { + return getFilesSubSystemFactory().getSeparator(); + } + + /** + * Return the path separator for the ${system_pathsep} variable + */ + protected String getPathSeparator() { + return getFilesSubSystemFactory().getPathSeparator(); + } + + /** + * Return the user's home directory on the remote system, for the ${system_homedir} variable + */ + protected String getHomeDirectory() { + return getCmdsSubSystem().getConnectorService().getHomeDirectory(); + } + + /** + * Return the temporary directory on the remote system, for the ${system_tempdir} variable + */ + protected String getTempDirectory() { + return getCmdsSubSystem().getConnectorService().getTempDirectory(); + } + + /** + * Return the user ID used to connect with the remote system, for the ${user_id} variable + */ + protected String getUserId() { + return getCmdsSubSystem().getConnectorService().getUserId(); + } + + /** + * Return the name of the currently selected resource, for the ${resource_name} variable + */ + protected String getResourceName(Object context) { + return SystemAdapterHelpers.getRemoteAdapter(context).getName(context); + } + + /** + * Return the root part of the name of the currently selected resource, for the ${resource_name_root} variable + */ + protected String getResourceNameRoot(Object context) { + IRemoteFile selectedFile = (IRemoteFile) context; + String name = selectedFile.getName(); + int dotIdx = name.lastIndexOf('.'); + if (dotIdx == 0) + return ""; //$NON-NLS-1$ + else if (dotIdx > 0) + return name.substring(0, dotIdx); + else + return name; + } + + /** + * Return the path of the currently selected resource, for the ${resource_path} variable + */ + protected String getResourcePath(Object context) { + return SystemAdapterHelpers.getRemoteAdapter(context).getAbsoluteName(context); + } + + /** + * Return the root part of the path, for the ${resource_path_root} variable + */ + protected String getPathRoot(Object context) { + IRemoteFile selectedFile = (IRemoteFile) context; + String name = selectedFile.getAbsolutePath(); + if (name != null) { + if (name.startsWith("/") || name.startsWith("\\")) //$NON-NLS-1$ //$NON-NLS-2$ + return name.substring(0, 1); + else { + int idx = name.indexOf(":\\"); //$NON-NLS-1$ + if (idx > 0) return name.substring(0, idx + 2); + } + } + return ""; //$NON-NLS-1$ + } + + /** + * Return the drive part of the path, for the ${resource_path_drive} variable + */ + protected String getPathDrive(Object context) { + IRemoteFile selectedFile = (IRemoteFile) context; + String name = selectedFile.getAbsolutePath(); + if ((name != null) && (name.length() > 1)) { + int idx = name.indexOf(':'); + if (idx > 0) return name.substring(0, idx); + } + return ""; //$NON-NLS-1$ + } + + /** + * Return the name of the parent folder, for the ${container_name} variable + */ + protected String getContainerName(Object context) { + IRemoteFile selectedFile = (IRemoteFile) context; + String fn = selectedFile.getParentName(); + if (fn != null) + return fn; + else + return ""; //$NON-NLS-1$ + } + + /** + * Return the path of the parent folder, for the ${container_path} variable + */ + protected String getContainerPath(Object context) { + IRemoteFile selectedFile = (IRemoteFile) context; + String name = selectedFile.getAbsolutePath(); + if ((name != null) && (name.length() > 1)) { + int idx = name.indexOf(':'); + if (idx > 0) return name.substring(0, idx); + } + return ""; //$NON-NLS-1$ + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommand.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommand.java new file mode 100644 index 00000000000..172fc9cbe24 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommand.java @@ -0,0 +1,44 @@ +package org.eclipse.rse.useractions.files.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.compile.SystemDefaultCompileCommand; + +/** + * Specialization of the the SystemDefaultCompileCommand for an IBM-supplied + * compile command for universal files. + */ +public class UniversalIBMCompileCommand extends SystemDefaultCompileCommand { + /** + * Constructor for UniversalCompileIBMCommand. + * @param commandLabel + * @param commandName + */ + public UniversalIBMCompileCommand(String commandLabel, String commandName) { + super(commandLabel, commandName); + } + + /** + * Constructor for UniversalCompileIBMCommand. + * @param commandName + */ + public UniversalIBMCompileCommand(String commandName) { + super(commandName); + } + + /** + * Constructor that takes a command name and label and the parameters. + * This avoids you having to call setAdditionalCommandParameters. + */ + public UniversalIBMCompileCommand(String commandLabel, String commandName, String parameters) { + super(commandLabel, commandName, parameters); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommands.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommands.java new file mode 100644 index 00000000000..30497b79e70 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/compile/UniversalIBMCompileCommands.java @@ -0,0 +1,65 @@ +package org.eclipse.rse.useractions.files.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.compile.SystemDefaultCompileCommands; + +/** + * Specialization of the SystemDefaultCompileCommands for the IBM-supplied compile commands + * for universal files + */ +public class UniversalIBMCompileCommands extends SystemDefaultCompileCommands { + private static UniversalIBMCompileCommands ibmCompileCommands; + // Source types supported + public static final String TYPE_C = "c"; //$NON-NLS-1$ + public static final String TYPE_CC = "cc"; //$NON-NLS-1$ + public static final String TYPE_CXX = "cxx"; //$NON-NLS-1$ + public static final String TYPE_CPP = "cpp"; //$NON-NLS-1$ + public static final String TYPE_CPP_C = "C"; //$NON-NLS-1$ + public static final String TYPE_CPP_CC = "CC"; //$NON-NLS-1$ + public static final String TYPE_CPP_CXX = "CXX"; //$NON-NLS-1$ + public static final String TYPE_JAVA = "java"; //$NON-NLS-1$ + public static final String[] ALL_IBM_SRC_TYPES = { TYPE_C, TYPE_CPP, TYPE_CC, TYPE_CPP_CC, TYPE_CXX, TYPE_CPP_CXX, TYPE_JAVA }; + + /** + * Constructor + */ + public UniversalIBMCompileCommands() { + super(); + } + + /** + * Get all IBM supplied compilable source types. + */ + public String[] getAllDefaultSuppliedSourceTypes() { + return ALL_IBM_SRC_TYPES; + } + + /** + * Return the singleton instance of the list of commands IBM recognizes by default + */ + public static UniversalIBMCompileCommands getIBMCompileCommands() { + if (ibmCompileCommands == null) { + ibmCompileCommands = new UniversalIBMCompileCommands(); + UniversalIBMCompileCommand cmd = null; + cmd = new UniversalIBMCompileCommand("JAVAC", "javac", "-deprecation -classpath . ${resource_name}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + cmd.setSourceTypes(new String[] { TYPE_JAVA }); + ibmCompileCommands.addCommand(cmd); + cmd = new UniversalIBMCompileCommand("GCC", "gcc", "-c ${resource_name} -o ${resource_name_root}.o"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + cmd.setSourceTypes(new String[] { TYPE_C, TYPE_CC, TYPE_CPP, TYPE_CPP_CC, TYPE_CPP_CXX, TYPE_CXX }); + ibmCompileCommands.addCommand(cmd); + cmd = new UniversalIBMCompileCommand("CC", "cc", "-c ${resource_name} -o ${resource_name_root}.o"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + cmd.setSourceTypes(new String[] { TYPE_C, TYPE_CC, TYPE_CPP, TYPE_CPP_CC, TYPE_CPP_CXX, TYPE_CXX }); + ibmCompileCommands.addCommand(cmd); + } + return ibmCompileCommands; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemFiles.java new file mode 100644 index 00000000000..3355e1d85df --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemFiles.java @@ -0,0 +1,783 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.services.clientserver.FileTypeMatcher; +import org.eclipse.rse.shells.ui.RemoteCommandHelpers; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; +import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.uda.ISystemUDAEditPaneHoster; +import org.eclipse.rse.useractions.ui.uda.ISystemUDTreeView; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionManager; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionSubsystem; +import org.eclipse.rse.useractions.ui.uda.SystemUDBaseManager; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeEditPane; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeManager; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * User action subsystem for universal files + */ +public class UDActionSubsystemFiles extends SystemUDActionSubsystem { + public static final String NO_EXTENSION_PLACEHOLDER = ".null"; //$NON-NLS-1$ + private static DateFormat dateFormatter; + // INSTANCE VARIABLES... + private FileTypeMatcher fileTypeMatcher; + // CONSTANTS... + private static final String DOMAINS[] = { "Folder", "File" }; //$NON-NLS-1$ //$NON-NLS-2$ + // Matching name string in the plugin resources (translated) + //private String DOMAIN_NEWTYPENAME_STRING[] = { RESID_UDT_FILES_DOMAIN_NEWFOLDER, RESID_UDT_FILES_DOMAIN_NEWFILE }; + // index values must match above 2 variables + public static final int DOMAIN_FOLDER = 0; + public static final int DOMAIN_FILE = 1; + protected static final String FILE_ACTIONS[][] = // todo! + // name, refresh, singleSel, collect, types, cmd + { { "java", "false", "true", "false", "CLASS", "java ${resource_name_root}" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + { "javac", "true", "false", "true", "JAVA", "javac -deprecation -classpath . ${resource_name}" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + { "jar", "true", "false", "true", "ALL", "jar -cvf classes.jar ${resource_name}" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + { "unjar", "false", "true", "false", "JAR ZIP", "jar -xf ${resource_name}" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + { "gmake", "true", "false", "false", "GNU_MAKEFILE", "gmake -f ${resource_name}" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + { "make", "true", "false", "false", "MAKEFILE", "make -f ${resource_name}" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + // I have decided against the following in favor of allowing these to be expanded in the tree view. Phil + //{"list", "false", "true", "false", "JAR ZIP", "jar tf ${resource_name}"}, + }; + protected static final String FOLDER_ACTIONS[][] = + // name, refresh, singleSel, collect, cmd + { { "javac", "true", "false", "true", "javac -deprecation -classpath . *.java" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + { "jar", "true", "false", "true", "jar cvf classes.jar *.class" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + }; + protected static final String IBM_DEFAULT_FOLDERTYPES[][] = { // name, types + { "ALL", "*" }, //$NON-NLS-1$ //$NON-NLS-2$ + }; + protected static final String IBM_DEFAULT_FILETYPES[][] = { // name, types + { "ALL", "*" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "C", "c,h,i" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "C_COMPILABLE", "c" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "CPP", "cpp,cxx,hpp,ipp" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "CPP_COMPILABLE", "cpp,cxx" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "CLASS", "class" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "CSS", "css" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "EAR", "ear" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "EXE", "exe,bat,cmd" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "GRAPHIC", "bmp,gif,jpg" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "GNU_MAKEFILE", "GNUMakefile" + NO_EXTENSION_PLACEHOLDER }, //$NON-NLS-1$ //$NON-NLS-2$ + { "HTML", "htm, html" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "JAVA", "java" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "JAVASCRIPT", "js" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "JAR", "jar" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "JARZIP", "jar,zip" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "JSP", "jsp" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "MAKEFILE", "makefile" + NO_EXTENSION_PLACEHOLDER + ", mak" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + { "NONE", "null" }, // our own invention! //$NON-NLS-1$ //$NON-NLS-2$ + { "PERL", "pl" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "PROFILE", "profile" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "PYTHON", "py" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "SHELL ", "csh, ksh, sh" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "SQLJ", "sqlj" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "WAR", "war" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "WEB", "css, htm, html, js, jsp" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "TAR", "tar" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "ZIP", "zip" }, //$NON-NLS-1$ //$NON-NLS-2$ + }; + protected String[] DOMAIN_NAME_STRING = new String[2]; + protected String[] DOMAIN_NEWNAME_STRING = new String[2]; + + /** + * Constructor + */ + public UDActionSubsystemFiles() { + super(); + DOMAIN_NAME_STRING[0] = SystemUDAResources.RESID_UDA_FILES_DOMAIN_FOLDER; + DOMAIN_NAME_STRING[1] = SystemUDAResources.RESID_UDA_FILES_DOMAIN_FILE; + DOMAIN_NEWNAME_STRING[0] = SystemUDAResources.RESID_UDA_FILES_DOMAIN_NEWFOLDER; + DOMAIN_NEWNAME_STRING[1] = SystemUDAResources.RESID_UDA_FILES_DOMAIN_NEWFILE; + } + + /** + * Overridable extension point for child classes to do migration of their actions. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done... we return false + */ + protected boolean doActionsMigration(ISystemProfile profile, String oldRelease) { + return false; + } + + /** + * Overridable extension point for child classes to do migration of their types. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done... we return false + */ + protected boolean doTypesMigration(ISystemProfile profile, String oldRelease) { + return false; + } + + /** + * Required override of parent for doing substitutions for our unique variables. + */ + public String internalGetSubstitutionValue(SystemUDActionElement currentAction, String subvar, Object selectedObject) { + return getUniversalSubstitutionValue(currentAction, subvar, selectedObject); + } + + /** + * Required override of parent for doing substitutions for our unique variables. + */ + public static String getUniversalSubstitutionValue(SystemUDActionElement currentAction, String subvar, Object selectedObject) { + /* from resource property file... + Common to files and folders: + ...uda.files.subvar.resource_date = Last modified date of selected resource + ...uda.files.subvar.resource_name = Name of selected resource, unqualified + ...uda.files.subvar.resource_path = Path of selected resource, including name + ...uda.files.subvar.resource_path_root=Root of selected file's path. "c:\\" on Windows, or "/" on others + ...uda.files.subvar.resource_path_drive=Drive letter on Windows, empty string on others + ...uda.files.subvar.container_name=Name of folder containing selected resource, unqualified + ...uda.files.subvar.container_path=Path of folder containing selected resource, including name + // note: resource_name and resource_path handled for us in parent class! + File specific: + ...uda.files.subvar.resource_name_root=Name of selected resource without the extension + ...uda.files.subvar.resource_name_ext=Extension part of the name of the selected resource + */ + IRemoteFile selectedFile = (IRemoteFile) selectedObject; + if (subvar.equals("${resource_date}")) //$NON-NLS-1$ + { + if (dateFormatter == null) dateFormatter = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss z"); //new SimpleDateFormat(); //$NON-NLS-1$ + Date lmd = selectedFile.getLastModifiedDate(); + if (lmd != null) + return dateFormatter.format(lmd); + else + return "not available"; //$NON-NLS-1$ + } else if (subvar.equals("${resource_name_root}")) //$NON-NLS-1$ + { + String name = selectedFile.getName(); + int dotIdx = name.lastIndexOf('.'); + if (dotIdx == 0) + return ""; //$NON-NLS-1$ + else if (dotIdx > 0) + return name.substring(0, dotIdx); + else + return name; + } else if (subvar.equals("${resource_name_ext}")) //$NON-NLS-1$ + { + String name = selectedFile.getName(); + int dotIdx = name.lastIndexOf('.'); + if (dotIdx == 0) { + if (name.length() == 1) + return ""; //$NON-NLS-1$ + else + return name.substring(1); + } else if (dotIdx > 0) + return name.substring(dotIdx + 1); + else + return ""; //$NON-NLS-1$ + } + /* + else if (subvar.equals("${path}")) + { + String p = selectedFile.getParentNoRoot(); + if (p != null) + return p; + else + return ""; + } + */ + else if (subvar.equals("${container_name}")) //$NON-NLS-1$ + { + // another example where the info can't be trusted! + /* + String fn = selectedFile.getParentName(); + if (fn != null) + return fn; + else + return ""; + */ + String fullpath = selectedFile.getParentPath(); + if ((fullpath == null) || (fullpath.length() == 0)) return ""; //$NON-NLS-1$ + IRemoteFileSubSystem rfss = getFileSubSystem(selectedObject); + if (rfss == null) return ""; //$NON-NLS-1$ + char sep = rfss.getParentRemoteFileSubSystemConfiguration().getSeparatorChar(); + int idx = fullpath.lastIndexOf(sep); + if (idx >= 0) + return fullpath.substring(idx + 1); + else + return ""; //$NON-NLS-1$ + } else if (subvar.equals("${container_path}")) //$NON-NLS-1$ + return selectedFile.getParentPath(); + else if (subvar.equals("${resource_path_root}")) //$NON-NLS-1$ + { + String name = selectedFile.getAbsolutePath(); + if (name != null) { + if (name.startsWith("/") || name.startsWith("\\")) //$NON-NLS-1$ //$NON-NLS-2$ + return name.substring(0, 1); + else { + int idx = name.indexOf(":\\"); //$NON-NLS-1$ + if (idx > 0) return name.substring(0, idx + 2); + } + } + return ""; //$NON-NLS-1$ + } else if (subvar.equals("${resource_path_drive}")) //$NON-NLS-1$ + { + //String root = selectedFile.getRoot(); + String name = selectedFile.getAbsolutePath(); + if ((name != null) && (name.length() > 1)) { + int idx = name.indexOf(':'); + if (idx > 0) return name.substring(0, idx); + } + return ""; //$NON-NLS-1$ + } + /* now handled in common base class + else if (subvar.equals("${system_pathsep}")) + return selectedFile.getSeparator(); + */ + return null; // return null to tell parent we didn't do any substitutions! + } + + /** + * Get the delimiter used to delimiter the types in a type string. + * Default is " " + */ + protected String getTypesDelimiter() { + return ","; //$NON-NLS-1$ + } + + /** + * After an action's command has been resolved (vars substituted) this method + * is called to actually do the remote command execution + *

+ * Run the user action's command in the default shell, and + * log result in the command view. + * + * @param shell - the shell to use if need to prompt for password or show msg dialog + * @param action - the action being processed, in case attributes of it need to be queried + * @param cmdString - the resolved command + * @param cmdSubSystem - this connection's command subsystem, which will run the command + * @param context - the selected IRemoteFile object + * @param viewer + * @return true if we should continue, false if something went wrong + */ + protected boolean runCommand(Shell shell, SystemUDActionElement action, String cmdString, IRemoteCmdSubSystem cmdSubSystem, Object context, Viewer viewer) { + return runUniversalCommand(shell, cmdString, cmdSubSystem, context); + } + + /** + * Encapsulation of code needed to run a universal subsystem command. + * + * @param shell - the shell to use if need to prompt for password or show msg dialog + * @param cmdString - the resolved command + * @param cmdSubSystem - this connection's command subsystem, which will run the command + * @param context - the selected IRemoteFile object + * @return true if we should continue, false if something went wrong + */ + public static boolean runUniversalCommand(Shell shell, String cmdString, IRemoteCmdSubSystem cmdSubSystem, Object context) { + String path = RemoteCommandHelpers.getWorkingDirectory((IRemoteFile) context); + boolean ok = RemoteCommandHelpers.runUniversalCommand(shell, cmdString, path, cmdSubSystem); + return ok; + } // end method + + // ----------------------------------------------- + // OVERRIDDEN METHODS FOR CAPABILITY DEFINITION + // ----------------------------------------------- + /** + * Return true if actions can be scoped by file types + * The iSeries native file system does support types + */ + public boolean supportsTypes() { + return true; + } + + /** + * Return true if actions can be scoped by file types for the given domain. + * Default is supportsTypes() + */ + public boolean supportsTypes(int domain) { + if (domain == DOMAIN_FOLDER) + return false; + else + return true; + } + + /** + * Return true if the action/type manager supports domains. + * The iSeries native file system does support domains + */ + public boolean supportsDomains() { + return true; + } + + /** + * In some cases, we supports domains in general, but only want to expose + * one of those domains to the user. For example, for file subsystems, + * we support folder and file domains, but for named types we really only + * support the file domain. + *

+ * We return DOMAIN_FILE if the docManager is the type manager + */ + public int getSingleDomain(SystemUDBaseManager docManager) { + if (docManager != getUDTypeManager()) + return -1; + else + return DOMAIN_FILE; + } + + // -------------------- + // VARIOUS OVERRIDES... + // -------------------- + /** + * Subclasses may override to provide a custom type edit pane subclass + */ + public SystemUDTypeEditPane getCustomUDTypeEditPane(ISubSystem ss, ISubSystemConfiguration ssf, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return new UDTypesEditPaneFiles(ss, ssf, profile, parent, tv); + } + + /** + * Prime new document with default types. This adds all the types that common across all system types, + * but also allows unique types to be added per system by calling primeAdditionalDefaultUniversalTypes, + * which is a method that subclasses can override. + *

+ * Do no override this method, but instead override primeAdditionalDefaultUniversalTypes. + */ + public SystemUDTypeElement[] primeDefaultTypes(SystemUDTypeManager typeMgr) { + Vector v = new Vector(); + primeDefaultUniversalTypes(typeMgr, v); + // give subclasses a chance... + primeAdditionalDefaultUniversalTypes(typeMgr, v); + // convert vector to array + SystemUDTypeElement[] typesArray = new SystemUDTypeElement[v.size()]; + for (int idx = 0; idx < typesArray.length; idx++) + typesArray[idx] = (SystemUDTypeElement) v.elementAt(idx); + return typesArray; + } + + /** + * Static version of primeDefaultTypes that is called by the iSeries IFS action subsystem. + * @param typeMgr - the manager of the types document to be primed + * @param vectorOfTypes - the vector to populate with types. Can be null, in which case the results are returned as an array + * @return null if given a vector (it is populated), else the array of default types + */ + public static SystemUDTypeElement[] primeDefaultUniversalTypes(SystemUDTypeManager typeMgr, Vector vectorOfTypes) { + Vector v = vectorOfTypes; + if (v == null) v = new Vector(); + for (int i = 0; i < IBM_DEFAULT_FOLDERTYPES.length; i++) { + SystemUDTypeElement ft = typeMgr.addType(DOMAIN_FOLDER, IBM_DEFAULT_FOLDERTYPES[i][0]); + if (null == ft) continue; + v.addElement(ft); + ft.setTypes(IBM_DEFAULT_FOLDERTYPES[i][1]); + } + for (int i = 0; i < IBM_DEFAULT_FILETYPES.length; i++) { + SystemUDTypeElement ft = typeMgr.addType(DOMAIN_FILE, IBM_DEFAULT_FILETYPES[i][0]); + if (null == ft) continue; + v.addElement(ft); + ft.setTypes(IBM_DEFAULT_FILETYPES[i][1]); + } + if (vectorOfTypes != null) return null; + // convert vector to array + SystemUDTypeElement[] typesArray = new SystemUDTypeElement[v.size()]; + for (int idx = 0; idx < typesArray.length; idx++) + typesArray[idx] = (SystemUDTypeElement) v.elementAt(idx); + return typesArray; + } + + /** + * This is an override point for subclasses to add system-specify default types. + *

+ * To simplify processing, subclasses should add their additional SystemUDTypeElement + * objects to the given vector. + */ + protected void primeAdditionalDefaultUniversalTypes(SystemUDTypeManager typeMgr, Vector vectorOfTypes) { + } + + /** + * Prime new document with default action. This adds all the actions that common across all system types, + * but also allows unique actions to be added per system by calling primeAdditionalDefaultUniversalActions, + * which is a method that subclasses can override. + *

+ * Do no override this method, but instead override primeAdditionalDefaultUniversalActions. + */ + public SystemUDActionElement[] primeDefaultActions(SystemUDActionManager actionMgr, ISystemProfile profile) { + Vector v = new Vector(); + primeDefaultUniversalActions(actionMgr, profile, v); + // give subclasses a chance... + primeAdditionalDefaultUniversalActions(actionMgr, profile, v); + // convert vector to array + SystemUDActionElement[] actionArray = new SystemUDActionElement[v.size()]; + for (int idx = 0; idx < actionArray.length; idx++) + actionArray[idx] = (SystemUDActionElement) v.elementAt(idx); + return actionArray; + } + + /** + * Static version of primeDefaultActions that is called by the iSeries IFS action subsystem. + * @param actionMgr - the manager of the actions document to be primed + * @param vectorOfActions - the vector to populate with actions. Can be null, in which case the results are returned as an array + * @return null if given a vector (it is populated), else the array of default actions + */ + public static SystemUDActionElement[] primeDefaultUniversalActions(SystemUDActionManager actionMgr, ISystemProfile profile, Vector vectorOfActions) { + Vector v = vectorOfActions; + if (v == null) v = new Vector(); + // add file actions + int domain = DOMAIN_FILE; + SystemUDActionElement newAction; + for (int idx = 0; idx < FILE_ACTIONS.length; idx++) { + newAction = actionMgr.addAction(profile, FILE_ACTIONS[idx][0], domain); + v.addElement(newAction); + newAction.setCommand(FILE_ACTIONS[idx][5]); + newAction.setPrompt(true); // may as well always allow users chance to change command as its submitted + newAction.setRefresh(FILE_ACTIONS[idx][1].equals("true")); //$NON-NLS-1$ + newAction.setShow(true); + newAction.setSingleSelection(FILE_ACTIONS[idx][2].equals("true")); //$NON-NLS-1$ + newAction.setCollect(FILE_ACTIONS[idx][3].equals("true")); //$NON-NLS-1$ + newAction.setFileTypes(convertStringToArray(FILE_ACTIONS[idx][4])); + } + // add folder actions + domain = DOMAIN_FOLDER; + for (int idx = 0; idx < FOLDER_ACTIONS.length; idx++) { + newAction = actionMgr.addAction(profile, FOLDER_ACTIONS[idx][0], domain); + v.addElement(newAction); + newAction.setCommand(FOLDER_ACTIONS[idx][4]); + newAction.setPrompt(true); // may as well always allow users chance to change command as its submitted + newAction.setRefresh(FOLDER_ACTIONS[idx][1].equals("true")); //$NON-NLS-1$ + newAction.setShow(true); + newAction.setSingleSelection(FOLDER_ACTIONS[idx][2].equals("true")); //$NON-NLS-1$ + newAction.setCollect(FOLDER_ACTIONS[idx][3].equals("true")); //$NON-NLS-1$ + newAction.setFileTypes(new String[] { "ALL" }); //$NON-NLS-1$ + } + if (vectorOfActions != null) return null; + // convert vector to array... + SystemUDActionElement[] actionArray = new SystemUDActionElement[v.size()]; + for (int idx = 0; idx < actionArray.length; idx++) + actionArray[idx] = (SystemUDActionElement) v.elementAt(idx); + return actionArray; + } + + /** + * This is an override point for subclasses to add system-specify default actions. + *

+ * To simplify processing, subclasses should add their additional SystemUDActionElement + * objects to the given vector. + */ + protected void primeAdditionalDefaultUniversalActions(SystemUDActionManager actionMgr, ISystemProfile profile, Vector vectorOfActions) { + } + + /** + * Given this IBM-supplied named type, restore it to its IBM-supplied state + * @return true if all went well, false if it wasn't restore for some reason + */ + public boolean restoreDefaultType(SystemUDTypeElement element, int domain, String typeName) { + boolean ok = restoreUniversalDefaultType(element, domain, typeName); + if (!ok) ok = restoreAdditionalDefaultType(element, domain, typeName); + return ok; + } + + /** + * Given this IBM-supplied named type, restore it to its IBM-supplied state. + * This concrete method tests the commonly supplied universal types. + * @return true if all went well, false if it wasn't restore for some reason + */ + public static boolean restoreUniversalDefaultType(SystemUDTypeElement element, int domain, String typeName) { + boolean ok = false; + String[][] typesArray = IBM_DEFAULT_FILETYPES; + if (domain == DOMAIN_FOLDER) // no IBM types for folder. + typesArray = IBM_DEFAULT_FOLDERTYPES; + // first test the universal types... + int match = -1; + for (int idx = 0; (match == -1) && (idx < typesArray.length); idx++) { + if (typeName.equals(typesArray[idx][0])) match = idx; + } + if (match != -1) { + element.setName(typesArray[match][0]); + element.setTypes(typesArray[match][1]); + ok = true; + } + return ok; + } + + /** + * Given this IBM-supplied named type, restore it to its IBM-supplied state. + * This abstract method is for the subclasses. + * @return true if all went well, false if it wasn't restore for some reason + */ + protected boolean restoreAdditionalDefaultType(SystemUDTypeElement element, int domain, String typeName) { + return false; + } + + /** + * Given this IBM-supplied named action, restore it to its IBM-supplied state + * @return true if all went well, false if it wasn't restore for some reason + */ + public boolean restoreDefaultAction(SystemUDActionElement element, int domain, String typeName) { + boolean ok = restoreUniversalDefaultAction(element, domain, typeName); + if (!ok) ok = restoreAdditionalDefaultAction(element, domain, typeName); + return ok; + } + + /** + * Given this IBM-supplied named action, restore it to its IBM-supplied state. + * This concrete method tests the commonly supplied universal actions. + * @return true if all went well, false if it wasn't restore for some reason + */ + public static boolean restoreUniversalDefaultAction(SystemUDActionElement element, int domain, String actionName) { + boolean ok = false; + String[][] actionsArray = FILE_ACTIONS; + if (domain == DOMAIN_FOLDER) // no IBM types for folder. + actionsArray = FOLDER_ACTIONS; + // first test the universal types... + int match = -1; + for (int idx = 0; (match == -1) && (idx < actionsArray.length); idx++) { + if (actionName.equals(actionsArray[idx][0])) match = idx; + } + if (match != -1) { + element.setName(actionsArray[match][0]); + element.setPrompt(true); // may as well always allow users chance to change command as its submitted + element.setRefresh(actionsArray[match][1].equals("true")); //$NON-NLS-1$ + element.setShow(true); + element.setSingleSelection(actionsArray[match][2].equals("true")); //$NON-NLS-1$ + element.setCollect(actionsArray[match][3].equals("true")); //$NON-NLS-1$ + if (domain == DOMAIN_FOLDER) + element.setFileTypes(new String[] { "ALL" }); //$NON-NLS-1$ + else + element.setFileTypes(convertStringToArray(actionsArray[match][4])); + element.setCommand(actionsArray[match][5]); + ok = true; + } + return ok; + } + + /** + * Given this IBM-supplied named action, restore it to its IBM-supplied state. + * This abstract method is for the subclasses. + * @return true if all went well, false if it wasn't restore for some reason + */ + protected boolean restoreAdditionalDefaultAction(SystemUDActionElement element, int domain, String actionName) { + return false; + } + + /** + * Convert space-delimited string into array of strings + */ + protected static String[] convertStringToArray(String string) { + StringTokenizer tokens = new StringTokenizer(string); + Vector v = new Vector(); + while (tokens.hasMoreTokens()) { + v.addElement(tokens.nextToken()); + } + String[] strings = new String[v.size()]; + for (int idx = 0; idx < strings.length; idx++) + strings[idx] = (String) v.elementAt(idx); + return strings; + } + + /** + * We disable user defined actions if we are in work-offline mode. + * Currently, how we determine this is dependent on the subsystem factory. + */ + public boolean getWorkingOfflineMode() { + return false; // todo: change this when offline mode is supported for universal! + } + + /** + * Return the list of substitution variables for the given domain type. + * Called from edit pane in work with dialog. + * This must be overridden! + */ + public SystemCmdSubstVarList getActionSubstVarList(int actionDomainType) { + if (actionDomainType == DOMAIN_FOLDER) + return UDSubstListFolders.getSingleton(); + else if (actionDomainType == DOMAIN_FILE) + return UDSubstListFiles.getSingleton(); + else + return null; + } + + /** + * Given an action, and the currently selected remote objects, and the domain of those, + * return true if ALL of the selected remote objects matches any of the type criteria + * for this action + *

+ * Override of parent + */ + protected boolean meetsSelection(SystemUDActionElement action, IStructuredSelection selection, int domainType) { + if (domainType == DOMAIN_FOLDER) return true; // no point in further testing because our getDomainFromSelection method already did this + String unresolvedActionTypes[] = action.getFileTypes(); + // fastpath for "ALL"! + if ((unresolvedActionTypes == null) || (unresolvedActionTypes.length == 0)) + return true; // what else to do? + else if (unresolvedActionTypes[0].equals("ALL")) //$NON-NLS-1$ + return true; + // flatten types + String[] actionTypes = resolveTypes(unresolvedActionTypes, domainType); + // create file type matcher + fileTypeMatcher = null; + if (domainType == DOMAIN_FILE) { + if (fileTypeMatcher == null) fileTypeMatcher = new FileTypeMatcher(null, getSubsystem().getSubSystemConfiguration().isCaseSensitive()); + fileTypeMatcher.setTypesAndNames(actionTypes); + } + Iterator elements = selection.iterator(); + Object element = null; + while (elements.hasNext()) { + element = elements.next(); + IRemoteFile file = (IRemoteFile) element; + // OK if matches any one of the file types for an action + boolean foundMatch = false; + if (domainType == DOMAIN_FOLDER) { + if (file.isDirectory()) foundMatch = true; + } else { + if (fileTypeMatcher.matches(file.getName())) foundMatch = true; + } + if (!foundMatch) return false; + } + return true; + } + + /** + * Parent override. + *

+ * Compares a particular file type (not named, but actual scalar/generic type) + * to a specific user-selected remote object. + * Returns true if the object's information matches that of the given type + *

+ * BECAUSE WE OVERRRIDE meetsSelection, THIS METHOD IS NEVER CALLED FOR US! + * + * @param actionType - an unnamed file type, as in "*.cpp" + * @param selectedObject - one of the currently selected remote objects + * @param domainType - integer representation of current domain + */ + protected boolean isMatch(Object actionType, Object selectedObject, int domainType) { + return true; + } + + // ----------------------------------------------- + // OVERRIDDEN METHODS RELATED TO DOMAIN SUPPORT... + // ----------------------------------------------- + /** + * Parent override. + * Determine domain, given the selection. + * Eg subsystem that supports domains has to do this via overriding this method. + * If domains not supported, return -1. + */ + protected int getDomainFromSelection(IStructuredSelection selection) { + int domain = -1; + Iterator elements = selection.iterator(); + if (elements.hasNext()) { + IRemoteFile currFile = (IRemoteFile) elements.next(); + if (currFile.isDirectory()) + domain = DOMAIN_FOLDER; + else + domain = DOMAIN_FILE; + } + return domain; + } + + /** + * Parent override. + * For efficiency reasons, internally we use an integer to represent a domain. + * However, that has to be mapped to a name which is actually what is stored as the + * "type" attribute for the xml domain node. + * This returns the maximum integer number supported by this action/type manager. + * Returns 1 for us. + */ + public int getMaximumDomain() { + return 1; + } + + /** + * Get the list of untranslated domain names + */ + public String[] getDomainNames() { + return DOMAINS; + } + + /** + * Get the list of translated domain names + */ + public String[] getXlatedDomainNames() { + return DOMAIN_NAME_STRING; + } + + /** + * Get the list of translated domain names for the tree view's "New" nodes + */ + public String[] getXlatedDomainNewNames() { + return DOMAIN_NEWNAME_STRING; + } + + /** + * Get the list of translated domain names for "new" nodes in tree view, for the WW Named Types dialog + */ + public String[] getXlatedDomainNewTypeNames() { + return DOMAIN_NEWNAME_STRING; + //return DOMAIN_NEWTYPENAME_STRING; // SHOULD NEVER BE CALLED + } + + /** + * Get the domain icon to show in the tree views + */ + public Image getDomainImage(int domain) { + if (domain == DOMAIN_FOLDER) + return RSEUIPlugin.getDefault().getImage(ISystemIconConstants.ICON_SYSTEM_FOLDER_ID); + //return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); + else if (domain == DOMAIN_FILE) + //return RSEUIPlugin.getDefault().getImage(ISystemConstants.ICON_SYSTEM_FILE_ID); + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE); + return null; + } + + /** + * Get the domain icon to show in the tree views, for the new item for this domain + */ + public Image getDomainNewImage(int domain) { + if (domain == DOMAIN_FOLDER) + return RSEUIPlugin.getDefault().getImage(ISystemIconConstants.ICON_SYSTEM_NEWFOLDER_ID); + //return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); + else if (domain == DOMAIN_FILE) return RSEUIPlugin.getDefault().getImage(ISystemIconConstants.ICON_SYSTEM_NEWFILE_ID); + //return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE); + return null; + } + + /** + * Get the domain icon to show in the named type tree view, for the new item for this domain + */ + public Image getDomainNewTypeImage(int domain) { + return UserActionsIcon.USERTYPE_NEW.getImage(); + } + + /** + * Overridable method for child classes to supply the label to display in the + * "New" node for types. Typically only overriden if domains are not supported, as otherwise + * the child nodes of "New" have the specific labels. + * @return translated label for "New named type..." + */ + protected String getNewNodeTypeLabel() { + return SystemUDAResources.RESID_UDA_FILES_NEWNODE_LABEL; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemLocalFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemLocalFiles.java new file mode 100644 index 00000000000..8950f8efd72 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemLocalFiles.java @@ -0,0 +1,114 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionManager; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeManager; + +/** + * This is a specialization of the universal files user action support, for + * stuff unique to Local files. + */ +public class UDActionSubsystemLocalFiles extends UDActionSubsystemFiles { + /** + * Constructor for UDActionSubsystemLocalFiles. + */ + public UDActionSubsystemLocalFiles() { + super(); + } + + /** + * Parent intercept for adding default pre-defined types that are unique to us. + */ + protected void primeAdditionalDefaultUniversalTypes(SystemUDTypeManager typeMgr, Vector vectorOfTypes) { + // I have decided not to include the iSeries unique types as there are user actions I can imagine for them, + // and they clutter up the namespace for non-iSeries users... + /* + // the following contains ONLY those types that are unique to local. + // for now these are only local copies of remote iSeries members + final String fileTypes[][] = + { + {"CBL_400", "cbl,cblle,lbl,sqlcblle" }, + {"CL_400", "clp,clle,cmd400,icl" }, + {"DDS_400", "dds,dspf,prtf,pf,lf,icff" }, + {"RPG_400", "rpg,rpgle,rpt" }, + }; + + for (int i = 0; i < fileTypes.length; i++) + { + SystemUDTypeElement ft = typeMgr.addType(DOMAIN_FILE, fileTypes[i][0]); + if (null == ft) + continue; + vectorOfTypes.addElement(ft); + ft.setTypes(fileTypes[i][1]); + } + */ + } + + /** + * Parent intercept for adding default pre-defined actions that are unique to us. + */ + protected void primeAdditionalDefaultUniversalActions(SystemUDActionManager actionMgr, ISystemProfile profile, Vector vectorOfActions) { + // duplicate the non-iseries types... + int domain = DOMAIN_FILE; + SystemUDActionElement newAction; + for (int idx = 0; idx < UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS.length; idx++) { + newAction = actionMgr.addAction(profile, UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][0], domain); + vectorOfActions.addElement(newAction); + newAction.setCommand(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][5]); + newAction.setPrompt(true); // may as well always allow users chance to change command as its submitted + newAction.setRefresh(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][1].equals("true")); //$NON-NLS-1$ + newAction.setShow(true); + newAction.setSingleSelection(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][2].equals("true")); //$NON-NLS-1$ + newAction.setCollect(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][3].equals("true")); //$NON-NLS-1$ + newAction.setFileTypes(convertStringToArray(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][4])); + } + // add actions unique to local... + } + + /** + * Parent intercept for restoring one of our unique IBM-supplied actions to its original state. + * @return true if all went well, false if it wasn't restore for some reason + */ + protected boolean restoreAdditionalDefaultAction(SystemUDActionElement element, int domain, String actionName) { + boolean ok = false; + if (domain == DOMAIN_FOLDER) return ok; + int match = -1; + for (int idx = 0; (match == -1) && (idx < UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS.length); idx++) { + if (UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[idx][0].equals(actionName)) match = idx; + } + if (match != -1) { + element.setName(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[match][0]); + element.setPrompt(true); // may as well always allow users chance to change command as its submitted + element.setRefresh(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[match][1].equals("true")); //$NON-NLS-1$ + element.setShow(true); + element.setSingleSelection(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[match][2].equals("true")); //$NON-NLS-1$ + element.setCollect(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[match][3].equals("true")); //$NON-NLS-1$ + element.setFileTypes(convertStringToArray(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[match][4])); + element.setCommand(UDActionSubsystemUniversalFiles.UNIVERSAL_FILE_ACTIONS[match][5]); + ok = true; + } + return ok; + } + + /** + * Override of parent method to restore unique type supplied by us, to its original state. + * @return true if all went well, false if it wasn't restore for some reason + */ + protected boolean restoreAdditionalDefaultType(SystemUDTypeElement element, int domain, String typeName) { + return false; // nothing unique + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemUniversalFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemUniversalFiles.java new file mode 100644 index 00000000000..333e1e11d6a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDActionSubsystemUniversalFiles.java @@ -0,0 +1,113 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionManager; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeManager; + +/** + * This is a specialization of the universal files user action support, for + * stuff unique to non-Local, non-IFS files. + */ +public class UDActionSubsystemUniversalFiles extends UDActionSubsystemFiles { + /** + * Universal non-iseries actions + */ + protected static final String UNIVERSAL_FILE_ACTIONS[][] = + // name, refresh, singleSel, collect, types, cmd + { + // these probably should be deleted, as these are more appropriate as compile commands + // {"gcc", "true", "false", "false", "CPP_COMPILABLE C_COMPILABLE","gcc -c ${resource_name} -o ${resource_name_root}.o"}, + // {"cc", "true", "false", "false", "CPP_COMPILABLE C_COMPILABLE","cc -c ${resource_name} -o ${resource_name_root}.o"}, + //{"IBM C", "true", "false", "false", "C_COMPILABLE", "xlc -c -qinfo=all ${resource_name} -o ${resource_name_root}.o"}, + //{"IBM C++","true", "false", "false", "CPP_COMPILABLE", "xlC -c -qinfo=all ${resource_name} -o ${resource_name_root}.o"}, + }; + + /** + * Constructor + */ + public UDActionSubsystemUniversalFiles() { + super(); + } + + /** + * Parent intercept for adding default pre-defined types that are unique to us. + */ + protected void primeAdditionalDefaultUniversalTypes(SystemUDTypeManager typeMgr, Vector vectorOfTypes) { + return; // nothing unique + } + + /** + * Parent intercept for adding default pre-defined actions that are unique to us. + */ + protected void primeAdditionalDefaultUniversalActions(SystemUDActionManager actionMgr, ISystemProfile profile, Vector vectorOfActions) { + // add file actions + int domain = DOMAIN_FILE; + SystemUDActionElement newAction; + for (int idx = 0; idx < UNIVERSAL_FILE_ACTIONS.length; idx++) { + newAction = actionMgr.addAction(profile, UNIVERSAL_FILE_ACTIONS[idx][0], domain); + vectorOfActions.addElement(newAction); + newAction.setCommand(UNIVERSAL_FILE_ACTIONS[idx][5]); + newAction.setPrompt(true); // may as well always allow users chance to change command as its submitted + newAction.setRefresh(UNIVERSAL_FILE_ACTIONS[idx][1].equals("true")); //$NON-NLS-1$ + newAction.setShow(true); + newAction.setSingleSelection(UNIVERSAL_FILE_ACTIONS[idx][2].equals("true")); //$NON-NLS-1$ + newAction.setCollect(UNIVERSAL_FILE_ACTIONS[idx][3].equals("true")); //$NON-NLS-1$ + newAction.setFileTypes(convertStringToArray(UNIVERSAL_FILE_ACTIONS[idx][4])); + } + } + + /** + * We disable user defined actions if we are in work-offline mode. + * Currently, how we determine this is dependent on the subsystem factory. + */ + public boolean getWorkingOfflineMode() { + return false; // todo... set to preferences setting when offline mode supported for universal + } + + /** + * Parent intercept for restoring one of our unique IBM-supplied actions to its original state. + * @return true if all went well, false if it wasn't restore for some reason + */ + protected boolean restoreAdditionalDefaultAction(SystemUDActionElement element, int domain, String actionName) { + boolean ok = false; + if (domain == DOMAIN_FOLDER) return ok; + int match = -1; + for (int idx = 0; (match == -1) && (idx < UNIVERSAL_FILE_ACTIONS.length); idx++) { + if (UNIVERSAL_FILE_ACTIONS[idx][0].equals(actionName)) match = idx; + } + if (match != -1) { + element.setName(UNIVERSAL_FILE_ACTIONS[match][0]); + element.setPrompt(true); // may as well always allow users chance to change command as its submitted + element.setRefresh(UNIVERSAL_FILE_ACTIONS[match][1].equals("true")); //$NON-NLS-1$ + element.setShow(true); + element.setSingleSelection(UNIVERSAL_FILE_ACTIONS[match][2].equals("true")); //$NON-NLS-1$ + element.setCollect(UNIVERSAL_FILE_ACTIONS[match][3].equals("true")); //$NON-NLS-1$ + element.setFileTypes(convertStringToArray(UNIVERSAL_FILE_ACTIONS[match][4])); + element.setCommand(UNIVERSAL_FILE_ACTIONS[match][5]); + ok = true; + } + return ok; + } + + /** + * Override of parent method to restore unique type supplied by us, to its original state. + * @return true if all went well, false if it wasn't restore for some reason + */ + protected boolean restoreAdditionalDefaultType(SystemUDTypeElement element, int domain, String typeName) { + return false; // nothing unique + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListCommonFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListCommonFiles.java new file mode 100644 index 00000000000..04926c8f44d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListCommonFiles.java @@ -0,0 +1,59 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.rse.useractions.ui.uda.SystemUDASubstVarListCommon; + +/** + * Encapsulation of the common substitution variables for both folders and files. + * Superset of overall system common variables. + */ +public class UDSubstListCommonFiles extends SystemCmdSubstVarList { + /* from resource property file... + ...uda.files.subvar.resource_date = Last modified date of selected resource + ...uda.files.subvar.resource_name = Name of selected resource, unqualified + ...uda.files.subvar.resource_path = Path of selected resource, including name + ...uda.files.subvar.resource_path_root=Root of selected file's path. "c:\\" on Windows, or "/" on others + ...uda.files.subvar.resource_path_drive=Drive letter on Windows, empty string on others + ...uda.files.subvar.container_name=Name of folder containing selected resource, unqualified + ...uda.files.subvar.container_path=Path of folder containing selected resource, including name + */ + private static final String[] COMMON_VARNAMES = { "resource_date", //$NON-NLS-1$ + "resource_name", //$NON-NLS-1$ + "resource_path", //$NON-NLS-1$ + "resource_path_root", //$NON-NLS-1$ + "resource_path_drive", //$NON-NLS-1$ + "container_name", //$NON-NLS-1$ + "container_path" //$NON-NLS-1$ + }; + private static final String[] COMMON_DESCRIPTIONS = { SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_DATE, SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_NAME, + SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_PATH, SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_PATH_ROOT, SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_PATH_DRIVE, + SystemUDAResources.RESID_UDA_FILES_SUBVAR_CONTAINER_NAME, SystemUDAResources.RESID_UDA_FILES_SUBVAR_CONTAINER_PATH }; + private static UDSubstListCommonFiles inst = null; + + /** + * Constructor . + * Not to be used directly. Rather, use getSingleton(). + */ + UDSubstListCommonFiles() { + super(SystemUDASubstVarListCommon.getSingleton(), COMMON_VARNAMES, COMMON_DESCRIPTIONS); + } + + /** + * Return the singleton of this object. No need ever for more than one instance + */ + public static UDSubstListCommonFiles getSingleton() { + if (inst == null) inst = new UDSubstListCommonFiles(); + return inst; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFiles.java new file mode 100644 index 00000000000..0d156129123 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFiles.java @@ -0,0 +1,48 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; + +/** + * @author coulthar + * + * Substitution variables for folders. Superset of common list + */ +public class UDSubstListFiles extends SystemCmdSubstVarList { + /* from resource property file... + ...uda.files.subvar.resource_name_root=Name of selected resource without the extension + ...uda.files.subvar.resource_name_ext=Extension part of the name of the selected resource + */ + private static final String[] FILE_VARNAMES = { "resource_name_ext", //$NON-NLS-1$ + "resource_name_root" //$NON-NLS-1$ + }; + private static final String[] DESCRIPTIONS = { SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_NAME_EXT, SystemUDAResources.RESID_UDA_FILES_SUBVAR_RESOURCE_NAME_ROOT }; + private static UDSubstListFiles inst = null; + + /** + * Constructor . + * Not to be used directly. Rather, use getSingleton(). + */ + UDSubstListFiles() { + super(UDSubstListCommonFiles.getSingleton(), FILE_VARNAMES, DESCRIPTIONS); + testForDuplicates(); + } + + /** + * Return the singleton of this object. No need ever for more than one instance + */ + public static UDSubstListFiles getSingleton() { + if (inst == null) inst = new UDSubstListFiles(); + return inst; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFolders.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFolders.java new file mode 100644 index 00000000000..106f375e28b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDSubstListFolders.java @@ -0,0 +1,41 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; + +/** + * @author coulthar + * + * Substitution variables for folders. Superset of common list + */ +public class UDSubstListFolders extends SystemCmdSubstVarList { + private static final String[] FOLDER_VARNAMES = {}; + private static final String[] DESCRIPTIONS = {}; + private static UDSubstListFolders inst = null; + + /** + * Constructor . + * Not to be used directly. Rather, use getSingleton(). + */ + UDSubstListFolders() { + super(UDSubstListCommonFiles.getSingleton(), FOLDER_VARNAMES, DESCRIPTIONS); + testForDuplicates(); + } + + /** + * Return the singleton of this object. No need ever for more than one instance + */ + public static UDSubstListFolders getSingleton() { + if (inst == null) inst = new UDSubstListFolders(); + return inst; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditPaneFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditPaneFiles.java new file mode 100644 index 00000000000..b4ecaf8cac3 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditPaneFiles.java @@ -0,0 +1,71 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.useractions.ui.uda.ISystemUDAEditPaneHoster; +import org.eclipse.rse.useractions.ui.uda.ISystemUDTreeView; +import org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeEditPane; +import org.eclipse.swt.widgets.Composite; + +/** + * @author coulthar + * + * This is a refinement of the generic edit pane for defining + * new named file types, specifialized for universal files. + * Specifically, it overrides the editor used to select/specify + * the individual types that constitute the named type. + */ +public class UDTypesEditPaneFiles extends SystemUDTypeEditPane { + /** + * Constructor for UDTypesEditPaneFiles. + * @param ss + * @param parent + * @param tv + */ + public UDTypesEditPaneFiles(ISubSystem ss, ISubSystemConfiguration ssf, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + super(ss, ssf, profile, parent, tv); + } + + /** + * Overridable exit point. + * Return true if the types are to be auto-uppercased. + * We return false + */ + protected boolean getAutoUpperCaseTypes() { + return false; + } + + /** + * Overridable exit point from parent. + * Create the edit widgets that will allow the user to see and + * edit the list of file types that constitute this named type. + *

+ * To better facilitate this, the only requirement is that this + * "editor" meet the minimal interface + * {@link org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector} + *

+ * Our implementation is to return an instance of our custom UDDTypesEditorFiles class. + * + * @param parent - the parent composite where the widgets are to go + * @param nbrColumns - the number of columns in the parent composite, which these + * widgets should span + * @return a class implementing the required interface + */ + protected ISystemUDTypeEditPaneTypesSelector createTypesListEditor(Composite parent, int nbrColumns) { + UDTypesEditorFiles ourEditor = new UDTypesEditorFiles(parent, nbrColumns); + //ourEditor.setAutoUpperCase(getAutoUpperCaseTypes()); + return ourEditor; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditorFiles.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditorFiles.java new file mode 100644 index 00000000000..ca501439d8d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/files/uda/UDTypesEditorFiles.java @@ -0,0 +1,567 @@ +package org.eclipse.rse.useractions.files.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileFilterString; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.messages.ISystemMessageLine; +import org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +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.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IFileEditorMapping; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.FileEditorMappingContentProvider; +import org.eclipse.ui.dialogs.FileEditorMappingLabelProvider; + +/** + * This class implements the interface needed to supply + * custom widgets allowing the user to specify the file types + * for a named file type, in the Work With File Types dialog + */ +public class UDTypesEditorFiles implements ISystemUDTypeEditPaneTypesSelector, ISystemIconConstants, ICheckStateListener { + public static final String NO_EXTENSION_PLACEHOLDER = UDActionSubsystemFiles.NO_EXTENSION_PLACEHOLDER; + // gui widgets + private CheckboxTableViewer typesSelectionList; + //private Label typesSelectionListVerbage; + //private Button addTypesButton; + //private Text definedTypesText; + private Label definedTypesLabel; + private Text userDefinedText; + private Label nonEditableVerbage; + private Composite typesComposite; + // state + private java.util.List inpTypes; + private IFileEditorMapping[] currentInput; + private int currentDomain; + private boolean ignoreModifyEvents = false; + // constants + private static final int LIST_HEIGHT = 150; + private static final int LIST_WIDTH = 50; + private static final String TYPE_DELIMITER = ","; //GenericMessages.getString("TypesFiltering.typeDelimiter"); //$NON-NLS-1$ + // registered listeners + private Vector listeners = new Vector(); + + /** + * Constructor for UDTypesEditorFiles. + */ + public UDTypesEditorFiles(Composite comp, int nbrColumns) //, SystemPromptDialog parentDialog) + { + super(); + // List of currently selected types if given parent composite has 2 columns + if (nbrColumns == 2) { + //definedTypesText = + // SystemWidgetHelpers.createLabeledTextField(comp, null, rb, RESID_UDT_FILES_DEFINEDTYPES_ROOT); + definedTypesLabel = SystemWidgetHelpers.createLabeledLabel(comp, SystemUDAResources.RESID_UDT_FILES_DEFINEDTYPES_LABEL, SystemUDAResources.RESID_UDT_FILES_DEFINEDTYPES_TOOLTIP, true); + } + nonEditableVerbage = SystemWidgetHelpers.createVerbiage(comp, "", nbrColumns, false, 350); //$NON-NLS-1$ + nonEditableVerbage.setVisible(false); + //typesComposite = SystemWidgetHelpers.createGroupComposite(comp, 1, rb.getString(RESID_UDT_FILES_TYPESGROUP_ROOT_LABEL); + typesComposite = SystemWidgetHelpers.createTightComposite(comp, 1); + typesComposite.setToolTipText(SystemUDAResources.RESID_UDT_FILES_TYPESGROUP_TOOLTIP); + ((GridData) typesComposite.getLayoutData()).horizontalSpan = nbrColumns; + nbrColumns = 1; + // List of currently selected types if given parent composite did not have 2 columns + if (definedTypesLabel == null) + //definedTypesText = + // SystemWidgetHelpers.createLabeledTextField(typesComposite, null, rb, RESID_UDT_FILES_DEFINEDTYPES_ROOT); + definedTypesLabel = SystemWidgetHelpers.createLabeledLabel(typesComposite, SystemUDAResources.RESID_UDT_FILES_DEFINEDTYPES_LABEL, SystemUDAResources.RESID_UDT_FILES_DEFINEDTYPES_TOOLTIP, + true); + //definedTypesLabel.setEnabled(false); + definedTypesLabel.setForeground(definedTypesLabel.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); + //definedTypesText = + // SystemWidgetHelpers.createReadonlyTextField(typesComposite, rb, RESID_UDT_FILES_DEFINEDTYPES_ROOT); + //definedTypesText.setToolTipText(""); + //definedTypesText.setVisible(false); + // types selection label + //typesSelectionListVerbage = + // SystemWidgetHelpers.createLabel(typesComposite, rb, RESID_UDT_TYPESLIST_LABEL_ROOT, nbrColumns, false); + // types selection list + //typesSelectionList = CheckboxTableViewer.newCheckList(comp, SWT.BORDER); + Table table = new Table(typesComposite, SWT.CHECK | SWT.BORDER); + table.setToolTipText(SystemUDAResources.RESID_UDT_FILES_TYPESGROUP_TOOLTIP); + typesSelectionList = new CheckboxTableViewer(table); + GridData data = new GridData(GridData.FILL_BOTH); + data.horizontalSpan = nbrColumns; + data.heightHint = LIST_HEIGHT; + data.widthHint = LIST_WIDTH; + //data.grabExcessHorizontalSpace = false; + //data.grabExcessVerticalSpace = false; + typesSelectionList.getTable().setLayoutData(data); + typesSelectionList.setLabelProvider(FileEditorMappingLabelProvider.INSTANCE); + typesSelectionList.setContentProvider(FileEditorMappingContentProvider.INSTANCE); + addSelectionButtons(typesComposite); + Composite userComp = createUserEntryGroup(typesComposite); + ((GridData) userComp.getLayoutData()).horizontalSpan = nbrColumns; + // configure widgets... + initializeViewer(); + //if ((this.initialSelections != null) && !this.initialSelections.isEmpty()) + // checkInitialSelections(); + typesSelectionList.addCheckStateListener(this); + } + + /** + * Set domain. + * The edit pane may possibly appear differently, depending on the domain. + * When the domain changes (either in "new" or "edit" mode) this method is called. + */ + public void setDomain(int domain) { + this.currentDomain = domain; + } + + /** + * Set the message line for issuing msgs to + */ + public void setMessageLine(ISystemMessageLine msgLine) { + } + + /** + * Return the domain of the currently selected existing named type, or "new" node + */ + public int getDomain() { + return currentDomain; + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#setTypes(String) + */ + public void setTypes(String types) { + //this.inpTypes = types; + if (types == null) { + setTypes((String[]) null); + } else { + setTypes(RemoteFileFilterString.parseTypes(types)); + setDefinedTypesText(types); + } + } + + /** + * Set defined types text + */ + private void setDefinedTypesText(String types) { + definedTypesLabel.setText(" " + types); //$NON-NLS-1$ + definedTypesLabel.setToolTipText(types); + //definedTypesText.setText(types); + } + + /** + * Clear defined types text + */ + private void clearDefinedTypesText() { + definedTypesLabel.setText(""); //$NON-NLS-1$ + definedTypesLabel.setToolTipText(""); //$NON-NLS-1$ + //definedTypesText.setText(""); + } + + /** + * Set the types via an array + */ + private void setTypes(String[] types) { + clearTypes(); + if (types != null) { + this.inpTypes = Arrays.asList(types); + ignoreModifyEvents = true; + checkInitialSelections(); + ignoreModifyEvents = false; + } + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#clearTypes() + */ + public void clearTypes() { + ignoreModifyEvents = true; + this.inpTypes = null; + typesSelectionList.setAllChecked(false); + clearDefinedTypesText(); + userDefinedText.setText(""); //$NON-NLS-1$ + ignoreModifyEvents = false; + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#getTypes() + */ + public String getTypes() { + return RemoteFileFilterString.getTypesString(getTypesAsArray()); + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#getTypes() + */ + public String[] getTypesAsArray() { + java.util.List selectedEntries = getSelectedTypes(); + String[] seldArray = new String[selectedEntries.size()]; + for (int idx = 0; idx < seldArray.length; idx++) + seldArray[idx] = (String) selectedEntries.get(idx); + return seldArray; + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#addModifyListener(ModifyListener) + */ + public void addModifyListener(ModifyListener listener) { + listeners.add(listener); + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#removeModifyListener(ModifyListener) + */ + public void removeModifyListener(ModifyListener listener) { + listeners.remove(listener); + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#validate() + */ + public SystemMessage validate() { + if (typesSelectionList == null) return null; + if (!areTypesSelected()) return RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_VALIDATE_UDTTYPES_EMPTY); + // validate that user-defined entry field! + return validateUserDefinedTypes(); + } + + /** + * Validate the contents of the user-defined types entry field + */ + public SystemMessage validateUserDefinedTypes() { + String filename = userDefinedText.getText().trim(); + // copied from SystemSelectFileTypes... + // check for empty name and extension + if (filename.length() == 0) return null; + // check for empty extension if there is no name + int index = filename.indexOf('.'); + if (index == filename.length() - 1) { + if (index == 0 || (index == 1 && filename.charAt(0) == '*')) { + //setErrorMessage(GenericMessages.getString("FileExtension.extensionEmptyMessage")); //$NON-NLS-1$ + return RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_VALIDATE_UDTTYPES_NOTVALID); + } + } + int startScan = 0; + if (filename.startsWith("*.")) //$NON-NLS-1$ + startScan = 2; + // check for characters before * + // or no other characters + // or next character not '.' + index = filename.indexOf('*', startScan); + if (index > -1) { + if (filename.length() == 1) { + //setErrorMessage(GenericMessages.getString("FileExtension.extensionEmptyMessage")); //$NON-NLS-1$ + return RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_VALIDATE_UDTTYPES_NOTVALID); + } + if (index != 0 || filename.charAt(1) != '.') { + //setErrorMessage(GenericMessages.getString("FileExtension.fileNameInvalidMessage")); //$NON-NLS-1$ + return RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_VALIDATE_UDTTYPES_NOTVALID); + } + } + return null; + } + + /** + * @see org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector#getControl() + */ + public Control getControl() { + return typesSelectionList.getControl(); + } + + /** + * Enable or disable the input-capability of the constituent controls + */ + public void setEnabled(boolean enable) { + typesSelectionList.getControl().setEnabled(enable); + userDefinedText.setEnabled(enable); + } + + /** + * We want to disable editing of IBM or vendor-supplied + * types, so when one of these is selected, this method is + * called to enter non-editable mode. + * @param editable Whether to disable editing of this type or not + * @param vendor When disabling, it contains the name of the vendor for substitution purposes + */ + public void setEditable(boolean editable, String vendor) { + //setEnabled(editable); + typesComposite.setVisible(editable); + if (editable) + nonEditableVerbage.setVisible(false); + else { + nonEditableVerbage.setVisible(true); + if (vendor.equals("IBM")) //$NON-NLS-1$ + nonEditableVerbage.setText(SystemUDAResources.RESID_UDT_IBM_VERBAGE); + else { + String verbage = SystemUDAResources.RESID_UDT_VENDOR_VERBAGE; + verbage = SystemMessage.sub(verbage, "%1", vendor); //$NON-NLS-1$ + nonEditableVerbage.setText(verbage); + } + } + } + + // private methods... + /** + * Fire event to all listeners... + */ + private void fireModifiedEvent() { + Event event = new Event(); + event.widget = getControl(); + event.type = SWT.Modify; + event.data = this; + ModifyEvent mEvent = new ModifyEvent(event); + for (int idx = 0; idx < listeners.size(); idx++) { + ModifyListener l = (ModifyListener) listeners.elementAt(idx); + //System.out.println("...firing modify event"); + l.modifyText(mEvent); + } + setDefinedTypesText(getTypes()); + } + + /** + * From ICheckStateListener interface. + * Called when user checks/unchecks an item + */ + public void checkStateChanged(CheckStateChangedEvent event) { + //System.out.println("inside checkStateChanged"); + if (!ignoreModifyEvents) fireModifiedEvent(); + ignoreModifyEvents = false; // non-sticky + } + + // -------------------------------------------- + // Similar to org.eclipse.ui.dialogs.TypeFilteringDialog + // -------------------------------------------- + /** + * Add the selection and deselection buttons to the dialog. + * @param composite org.eclipse.swt.widgets.Composite + */ + private void addSelectionButtons(Composite composite) { + /* + Composite buttonComposite = new Composite(composite, SWT.RIGHT); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + buttonComposite.setLayout(layout); + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL); + data.grabExcessHorizontalSpace = true; + composite.setData(data); + + Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, GenericMessages.getString("WizardTransferPage.selectAll"), false); //$NON-NLS-1$ + + SelectionListener listener = new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) { + typesSelectionList.setAllChecked(true); + } + }; + selectButton.addSelectionListener(listener); + + Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, GenericMessages.getString("WizardTransferPage.deselectAll"), false); //$NON-NLS-1$ + + listener = new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) { + typesSelectionList.setAllChecked(false); + + } + }; + deselectButton.addSelectionListener(listener); + */ + } + + protected static Button createPushButton(Composite group, String label, String tooltip) { + Button button = createPushButton(group, label); + button.setToolTipText(tooltip); + return button; + } + + public static Button createPushButton(Composite group, String label) { + Button button = new Button(group, SWT.PUSH); + button.setText(label); + //button.setText("THIS IS A LONG LABEL. I MEAN, IT IS JUST HUGE!"); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + button.setLayoutData(data); + return button; + } + + /** + * Add the currently-specified extensions. + */ + private void addUserDefinedEntries(java.util.List result) { + StringTokenizer tokenizer = new StringTokenizer(userDefinedText.getText(), TYPE_DELIMITER); + //Allow the *. and . prefix and extract the extension + while (tokenizer.hasMoreTokens()) { + String currentExtension = tokenizer.nextToken().trim(); + if (!currentExtension.equals("")) //$NON-NLS-1$ + { + if (currentExtension.startsWith("*."))//$NON-NLS-1$ + result.add(currentExtension.substring(2)); + else { + if (currentExtension.startsWith("."))//$NON-NLS-1$ + result.add(currentExtension.substring(1)); + else + result.add(currentExtension); + } + } + } + } + + /** + * Visually checks the previously-specified elements in this dialog's list viewer. + */ + private void checkInitialSelections() { + if ((inpTypes == null) || (inpTypes.size() == 0)) return; + IFileEditorMapping editorMappings[] = PlatformUI.getWorkbench().getEditorRegistry().getFileEditorMappings(); + ArrayList selectedMappings = new ArrayList(); + for (int i = 0; i < editorMappings.length; i++) { + IFileEditorMapping mapping = editorMappings[i]; + if (inpTypes.contains(mapping.getLabel())) { + typesSelectionList.setChecked(mapping, true); + selectedMappings.add(mapping.getLabel()); + } else { + //System.out.println("name = '" + mapping.getName() + "', label = '" + mapping.getLabel() + "', ext = '" + mapping.getExtension() + "'"); + if (mapping.getName().equals("*")) //$NON-NLS-1$ + { + if (inpTypes.contains(mapping.getExtension())) { + typesSelectionList.setChecked(mapping, true); + selectedMappings.add(mapping.getExtension()); + } + } else if (mapping.getExtension().equals("")) // extension-less name like "makefile" //$NON-NLS-1$ + { + if (inpTypes.contains(mapping.getName() + NO_EXTENSION_PLACEHOLDER)) { + typesSelectionList.setChecked(mapping, true); + selectedMappings.add(mapping.getName() + NO_EXTENSION_PLACEHOLDER); + } + } + } + } + //Now add in the ones not selected to the user defined list + Iterator initialIterator = inpTypes.iterator(); + StringBuffer entries = new StringBuffer(); + while (initialIterator.hasNext()) { + String nextExtension = (String) initialIterator.next(); + if (!selectedMappings.contains(nextExtension)) { + entries.append(nextExtension); + entries.append(','); + } + } + this.userDefinedText.setText(entries.toString()); + } + + /** + * Create the group that shows the user defined entries for the dialog. + * @param parent the parent this is being created in. + */ + private Composite createUserEntryGroup(Composite parent) { + // destination specification group + int nbrColumns = 2; + Composite composite = SystemWidgetHelpers.createFlushComposite(parent, nbrColumns); + userDefinedText = SystemWidgetHelpers.createLabeledTextField(composite, null, SystemUDAResources.RESID_UDT_FILES_USERTYPES_LABEL, SystemUDAResources.RESID_UDT_FILES_USERTYPES_TOOLTIP); + userDefinedText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + if (!ignoreModifyEvents) fireModifiedEvent(); + ignoreModifyEvents = false; // non-sticky flag + } + }); + SystemWidgetHelpers.setHelp(userDefinedText, RSEUIPlugin.HELPPREFIX + "wwnt0002"); //$NON-NLS-1$ + return composite; + } + + /** + * Return the input to the dialog. + */ + private IFileEditorMapping[] getInput() { + //Filter the mappings to be just those with a wildcard extension + // Hmm, why does Eclipse do this? Phil + if (currentInput == null) { + currentInput = + //IFileEditorMapping [] allMappings = + PlatformUI.getWorkbench().getEditorRegistry().getFileEditorMappings(); + //java.util.List wildcardEditors = new ArrayList(); + //for (int i = 0; i < allMappings.length; i++) + //{ + //if (allMappings[i].getName().equals("*"))//$NON-NLS-1$ + //wildcardEditors.add(allMappings[i]); + //} + //currentInput = new IFileEditorMapping[wildcardEditors.size()]; + //wildcardEditors.toArray(currentInput); + } + return currentInput; + } + + /** + * Initializes this dialog's viewer after it has been laid out. + */ + private void initializeViewer() { + typesSelectionList.setInput(getInput()); + } + + /** + * Return the currently selected items as a java.util.List of Strings + */ + protected java.util.List getSelectedTypes() { + // Get the input children. + IFileEditorMapping[] children = getInput(); + java.util.List list = new ArrayList(); + // Build a list of selected children. + for (int i = 0; i < children.length; ++i) { + IFileEditorMapping element = children[i]; + if (typesSelectionList.getChecked(element)) { + if (element.getName().equals("*")) //$NON-NLS-1$ + list.add(element.getExtension()); + else if (element.getExtension().equals("")) //$NON-NLS-1$ + list.add(element.getName() + NO_EXTENSION_PLACEHOLDER); + else + list.add(element.getLabel()); + } + } + addUserDefinedEntries(list); + //setResult(list); + return list; + } + + /** + * Return true if there are any types currently selected + */ + protected boolean areTypesSelected() { + // Get the input children. + IFileEditorMapping[] children = getInput(); + // Test list of selected children. + for (int i = 0; i < children.length; ++i) { + IFileEditorMapping element = children[i]; + if (typesSelectionList.getChecked(element)) { + return true; + } + } + String udtText = userDefinedText.getText().trim(); + if (udtText.length() == 0) return false; + //StringTokenizer tokenizer = + // new StringTokenizer(udtText, TYPE_DELIMITER); + //return tokenizer.hasMoreTokens(); + return true; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemCommandTextAdditionalGUIProvider.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemCommandTextAdditionalGUIProvider.java new file mode 100644 index 00000000000..b4b65926315 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemCommandTextAdditionalGUIProvider.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui; + +import org.eclipse.swt.widgets.Composite; + +/** + * Interface that is to be implemented by anyone interested in + * supplying additional gui, beyond the default, to the command text widget. + */ +public interface ISystemCommandTextAdditionalGUIProvider { + /** + * Overridable entry point for subclasses that wish to put something to the right of the "Command:" label + * @return true if something entered to take up the available columns, false otherwise (will be padded) + */ + public boolean createCommandLabelLineControls(Composite parent, int availableColumns); + + /** + * Create additional buttons, to go under command prompt. + * Overridable. + * @return true if something entered to take up the available columns, false otherwise (will be padded) + */ + public boolean createExtraButtons(Composite parent, int availableColumns); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemSubstitutor.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemSubstitutor.java new file mode 100644 index 00000000000..f6808b69da2 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/ISystemSubstitutor.java @@ -0,0 +1,32 @@ +package org.eclipse.rse.useractions.ui; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/** + * Objects implementing this interface are passed to + * {@link SystemCmdSubstVarList} parse a given command + * string for variables defined in the substitution list. + * For each match, this object is called back to retrieve + * the substition value, given the variable name (including + * its prefix). It will also pass back the context object + * given to it. Presumably this is a currently selected object. + */ +public interface ISystemSubstitutor { + /** + * Return the string to substitute for the given substitution + * variable, given the current context object. This object will + * be passed whatever was passed into the doSubstitution method. + *

It is VERY IMPORTANT to return null if you can't do the + * substitution for some reason! This is a clue to the algorithm + * that no change was made and increases performance. + */ + public String getSubstitutionValue(String substitutionVariable, Object context); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVar.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVar.java new file mode 100644 index 00000000000..aa6a0f145d6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVar.java @@ -0,0 +1,77 @@ +package org.eclipse.rse.useractions.ui; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/** + * @author coulthar + * + * This class encapsulates a single substitution variable. + * Such a variable has the following information: + *

    + *
  1. The actual variable, as in "&L" + *
  2. A translated description of the variable, as in "Library name" + *
  3. A display string, which is typically a concatenation of the above two attributes + *
+ * Currently this class is not used at runtime to do the actual substitution, + * although that would be a natural next step. + */ +public class SystemCmdSubstVar implements Comparable { + private String var, desc; + + // public constants + /** + * Constructor + */ + public SystemCmdSubstVar(String variable, String description) { + super(); + this.var = variable; + this.desc = description; + } + + /** + * Return the substitution variable. Eg "&x" or "${xxxx}" + */ + public String getVariable() { + return var; + } + + /** + * Return the description. Eg "File name" + */ + public String getDescription() { + return desc; + } + + /** + * Return the display string. Eg var " - " description + */ + public String getDisplayString() { + return var + " - " + desc; //$NON-NLS-1$ + } + + // comparable interface method, to enable sorting + /** + * Compare ourself to another instance of this class + * @return -1 we are less than given object, 0 we are equal, 1 we are greater than + */ + public int compareTo(Object o) { + /* only re-use this when we want to bubble longer names to top... + SystemUDASubstVar other = (SystemUDASubstVar)o; + if (var.equals(other.getVariable())) + return 0; + else if (var.length() > other.getVariable().length()) + return -1; // we want longer names at the beginning of an ascending list! + else + return 1; + */ + return var.compareTo(((SystemCmdSubstVar) o).getVariable()); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVarList.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVarList.java new file mode 100644 index 00000000000..d2bd55c94c5 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCmdSubstVarList.java @@ -0,0 +1,292 @@ +package org.eclipse.rse.useractions.ui; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.PrintWriter; +import java.util.Arrays; + +/** + * @author coulthar + * + * This encapsulates a list of substitution variables. + * The input for the list is the variable prefix (eg "&"), an + * array of variable names (eg "A", "B", etc), plus the + * resource bundle and key-root for getting the variable + * descriptions (will append variable names to the key-root + * to get the resource bundle key). + *

+ * This class is also used to help with the actual substitutions + * at runtime. The method doSubstitutions will walk the given + * string looking for matches on any of the variables in this + * list, taking care to look for the longer-named variables first, + * and when a match is found, will call back to the given + * implementor of ISystemSubstitutor, to get the substitution + * value. The substitutor will be given the variable name (eg, "N", + * not "&N") and whatever context object was passed into + * doSubstitutions, presumably one of the currently selected + * objects. + */ +public class SystemCmdSubstVarList { + private SystemCmdSubstVar[] list, sortedList; + private char prefix = ' '; + private boolean usingDelimiters = false; + // constants + /** + * Typical substitution variable prefix when using single prefix char: '&' + */ + public static final char SUBST_PREFIX_AMP = '&'; + /** + * Typical substitution variable char prefix when using delimiters: "$" + */ + public static final char SUBST_PREFIX_DOLLAR = '$'; + /** + * Typical substitution variable char prefix when using delimiters: "{" + */ + public static final char SUBST_PREFIX_BRACE = '}'; + /** + * Typical substitution variable string prefix when using delimiters: "{" + */ + public static final String SUBST_PREFIX = "${"; //$NON-NLS-1$ + /** + * Typical substitution variable char suffix when using delimiters: "}" + */ + public static final char SUBST_SUFFIX_BRACE = '}'; + + /** + * Constructor when using single prefix like '&' + */ + public SystemCmdSubstVarList(char prefix, String[] names, String[] descriptions) { + this(null, prefix, names, descriptions); + } + + /** + * Constructor when using single prefix like '&', and based on another list + * Sometimes a substitution variable list contains common variables, plus some unique variables. + * In this case, use this construction, and pass in the list object for the common variables. + */ + public SystemCmdSubstVarList(SystemCmdSubstVarList commonList, char prefix, String[] names, String[] descriptions) { + super(); + this.prefix = prefix; + init(commonList, names, descriptions); + } + + /** + * Constructor when using ${xxx} delimiting, and not based on another list + */ + public SystemCmdSubstVarList(String[] names, String[] descriptions) { + this(null, names, descriptions); + } + + /** + * Constructor when using ${xxx} delimiting, and we are based on another list + */ + public SystemCmdSubstVarList(SystemCmdSubstVarList commonList, String[] names, String[] descriptions) { + super(); + usingDelimiters = true; + prefix = SUBST_PREFIX_DOLLAR; + init(commonList, names, descriptions); + } + + /** + * Abstraction of common stuff done by all constructors. + */ + public void init(SystemCmdSubstVarList commonList, String[] names, String[] descriptions) { + SystemCmdSubstVar[] commonArray = null; + int idx = 0; + if (commonList == null) + list = new SystemCmdSubstVar[names.length]; + else { + commonArray = commonList.getListAsArray(); + list = new SystemCmdSubstVar[commonArray.length + names.length]; + for (; idx < commonArray.length; idx++) + list[idx] = commonArray[idx]; + } + String varName = null; + String description = null; + for (int jdx = 0; jdx < names.length; idx++, jdx++) { + if (!usingDelimiters) { + varName = prefix + names[jdx]; + } else { + varName = SUBST_PREFIX + names[jdx] + SUBST_SUFFIX_BRACE; + } + description = descriptions[jdx]; + list[idx] = new SystemCmdSubstVar(varName, description); + } + // sort list alphabetically... + Arrays.sort(list); + // for testing... + /* + System.out.println("Sorted list: "); + for (int jdx=0; jdx + * Currently this assume all variables use the prefix given in the constructor, + * as it optimizes performance. + * Another flavour would be needed if arbitrary prefixes were to supported! + *

+ * Further, this also currently assumes a doubled up prefix is used for escaping, + * meaning the first prefix is to be removed, the next is to be left unsubstituted. + * + * @param commandString - the command from the user action, that contains vars to be substituted + * @param context - a selected object + * @param substitutor - an object that knows how to do substitutions. A callback. + */ + public String doSubstitutions(String commandString, Object context, ISystemSubstitutor substitutor) { + //System.out.println("Command before substitution: " + commandString); + // walk the command string, looking for variables... + String part1, part2; + int index = 0; + int lastindex = 0; + //int cmdLength = commandString.length(); + while ((index = commandString.indexOf(prefix, lastindex)) >= 0) { + lastindex = index + 1; // start next search at char after this '&' + // ampersand followed by at least one letter? + if (commandString.length() >= (index + 1)) { + char sc = commandString.charAt(index + 1); // char after this '&' + if (sc == prefix) // next char is also an '&'? + { + ++lastindex; // skip it. Note its ok to bump it past length of string + } else { + String var = findMatchingVar(commandString, index); + if (var != null) { + String replacement = substitutor.getSubstitutionValue(var, context); + if (replacement != null) { + if (index == 0) // substitution variable at front of command? + commandString = commandString.substring(index + var.length()); + else { + part1 = commandString.substring(0, index); + part2 = commandString.substring(index + var.length()); + commandString = part1 + replacement + part2; + } + lastindex = index + replacement.length(); // assume replacement has no '&' chars in it! + } + } + } + } + } // end while + //System.out.println("Command after substitution : " + commandString); + //System.out.println(); + return commandString; + } + + /** + * For testing purposes. + * Given the selected object, this returns an array of strings, one for each substitution + * variable, of the form "varname = substituted-value". + * @param context - a selected object + * @param substitutor - an object that knows how to do substitutions. A callback + */ + public String[] doAllSubstitutions(Object context, ISystemSubstitutor substitutor) { + String[] substitutedVariables = new String[list.length]; + String currVar = null; + for (int idx = 0; idx < list.length; idx++) { + currVar = list[idx].getVariable(); + substitutedVariables[idx] = currVar + " = " + //$NON-NLS-1$ + doSubstitutions("\"" + currVar + "\"", context, substitutor); //$NON-NLS-1$ //$NON-NLS-2$ + } + return substitutedVariables; + } + + /** + * Check our list of sub vars for a match on given string at given index + */ + private String findMatchingVar(String cmd, int indexOfPrefix) { + if (sortedList == null) { + sortedList = list; + /* + * At this point we don't need to sort names as we are careful not + * to define variables that are ambiguous. Eg, &A and &AB. + * + sortedList = new SystemUDASubstVar[list.length]; + for (int i = 0; i < sortedList.length; i++) + sortedList[i] = list[i]; + Arrays.sort(sortedList); + */ + } + int cmdlen = cmd.length(); + for (int idx = 0; idx < sortedList.length; idx++) { + String var = sortedList[idx].getVariable(); + int varlen = var.length(); + if (((indexOfPrefix + varlen) <= cmdlen) && var.equals(cmd.substring(indexOfPrefix, indexOfPrefix + varlen))) return var; + } + return null; + } + + /** + * Helper method to test for duplicate variables + */ + public void testForDuplicates() { + String currname = null; + for (int idx = 0; idx < list.length; idx++) { + currname = list[idx].getVariable(); + for (int i = 0; i < list.length; i++) + if (i != idx) if (list[i].equals(currname)) System.out.println("duplicate subs var " + currname + " in list " + this.getClass().getName()); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /** + * This writes out the class name. + */ + public String toString() { + return getClass().getName(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandTextField.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandTextField.java new file mode 100644 index 00000000000..9156c684a3a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandTextField.java @@ -0,0 +1,287 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui; + +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.shells.ui.view.ISystemCommandTextModifyListener; +import org.eclipse.rse.shells.ui.view.SystemCommandEditor; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.ISystemMassager; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.validators.ISystemValidator; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * This class encapsulates a prompt for a remote command that supports + * substitution variables. It is used in both compile and user action dialogs. + */ +public class SystemCommandTextField implements ISystemIconConstants, SelectionListener { + protected SystemCommandEditor textCommand; + protected ISystemMassager cmdMassager; + protected Button insertVariableButton; + protected Button editButton; + protected boolean menuListenerAdded; + protected SystemCommandViewerConfiguration sourceViewerConfiguration; + //mri + private String cmdFieldLabel = SystemUDAResources.RESID_UDA_COMMAND_LABEL; + private String cmdFieldTooltip = SystemUDAResources.RESID_UDA_COMMAND_TOOLTIP; + private String insertVarButtonLabel = SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_LABEL; + private String insertVarButtonTooltip = SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_TOOLTIP; + private String editButtonLabel = SystemUDAResources.RESID_UDA_EDIT_BUTTON_LABEL; + private String editButtonTooltip = SystemUDAResources.RESID_UDA_EDIT_BUTTON_TOOLTIP; + /** + * Maximum text length for command field: 512 + */ + public static final int MAX_CMD_LENGTH = 512; + + /** + * Constructor . + * You must call setSubstitutionVariableList before + * calling createContents! + */ + public SystemCommandTextField(SystemCommandViewerConfiguration cmdAssistant) { + super(); + this.sourceViewerConfiguration = cmdAssistant; + } + + /** + * Reset what will be used to manage the content assist. A default is supplied. + */ + public void setCommandTextViewerConfiguration(SystemCommandViewerConfiguration cmdAssistant) { + // defect 46404... + if ((sourceViewerConfiguration != null) && (textCommand != null) && (sourceViewerConfiguration.getContentAssistant(textCommand) != null)) + sourceViewerConfiguration.getContentAssistant(textCommand).uninstall(); + this.sourceViewerConfiguration = cmdAssistant; + if (textCommand != null) { + textCommand.configure(sourceViewerConfiguration); + } + } + + /** + * Set the substitution variable list that Insert Variable will use. + */ + public void setSubstitutionVariableList(SystemCmdSubstVarList varList) { + sourceViewerConfiguration.setSubstVarList(varList); + } + + /** + * Set the action command massager. This is called to massage the contents + * when getCommandText is called. + */ + public void setCommandMassager(ISystemMassager massager) { + this.cmdMassager = massager; + } + + /** + * Return the command massager as set by setCommandMassager(...) + */ + public ISystemMassager getCommandMassager() { + return cmdMassager; + } + + /** + * Return the edit widget. Will be null until createEditor is called + */ + public SourceViewer getEditor() { + return textCommand; + } + + /** + * Return the control widget for the command prompt + */ + public Control getCommandWidget() { + return textCommand.getControl(); + } + + /** + * Return the text contents of the command widget + */ + public String getCommandText() { + return textCommand.getCommandText(); + } + + /** + * Return the text contents of the command widget, after applying the massager. + * If the massager is null, this is the same as calling getCommandText(). + */ + public String getMassagedCommandText() { + if (cmdMassager == null) + return getCommandText(); + else + return cmdMassager.massage(getCommandText()); + } + + /** + * Set the text contents of the command widget + */ + public void setCommandText(String text) { + textCommand.getDocument().set(text); + } + + /** + * Enable/disable command widget + */ + public void enableCommandWidget(boolean enable) { + if (textCommand != null) textCommand.getTextWidget().setEnabled(enable); + if (insertVariableButton != null) insertVariableButton.setEnabled(enable); + if (editButton != null) editButton.setEnabled(enable); + } + + /** + * Turn on or off event ignoring flag + */ + public void setIgnoreChanges(boolean ignore) { + if (textCommand != null) { + textCommand.setIgnoreChanges(ignore); + } + } + + /** + * Method createContents. + * @param comp - the parent composite into which to place the prompt, field and insert-variable buttons + * @return Control + */ + public Control createContents(Composite comp, int nbrColumns, ISystemCommandTextAdditionalGUIProvider guiProvider) { + Label labelCommand = SystemWidgetHelpers.createLabel(comp, cmdFieldLabel, cmdFieldTooltip); + String s = SystemWidgetHelpers.appendColon(labelCommand.getText()); + labelCommand.setText(s); + if ((guiProvider == null) || !guiProvider.createCommandLabelLineControls(comp, nbrColumns - 1)) ((GridData) labelCommand.getLayoutData()).horizontalSpan = nbrColumns; + int cmdSpan = nbrColumns; + textCommand = createEditor(comp, cmdSpan, sourceViewerConfiguration); + textCommand.getControl().setToolTipText(cmdFieldTooltip); + // Insert Variable... button + insertVariableButton = SystemWidgetHelpers.createPushButton(comp, null, insertVarButtonLabel, insertVarButtonTooltip); + // edit command button + editButton = SystemWidgetHelpers.createPushButton(comp, null, editButtonLabel, editButtonTooltip); + // SUBCLASS-SUPPLIED BUTTONS + if ((guiProvider == null) || !guiProvider.createExtraButtons(comp, nbrColumns - 1)) addFillerLine(comp, nbrColumns - 1); + insertVariableButton.addSelectionListener(this); + editButton.addSelectionListener(this); + return comp; + } + + /** + * Set the information needed to get the command field's mri + */ + public void setMRI(String cmdFieldLabel, String cmdFieldTooltip, String insertVarButtonLabel, String insertVarButtonTooltip) { + this.cmdFieldLabel = cmdFieldLabel; + this.cmdFieldTooltip = cmdFieldTooltip; + this.insertVarButtonLabel = insertVarButtonLabel; + this.insertVarButtonTooltip = insertVarButtonTooltip; + } + + /** + * SelectionListener Interface: + * For the checkboxes + */ + public void widgetDefaultSelected(SelectionEvent e) { + } + + /** + * SelectionListener Interface: + * For the checkboxes + */ + public void widgetSelected(SelectionEvent e) { + Object source = e.getSource(); + if (source == insertVariableButton) { + //sourceViewerConfiguration.getSubstVarList().printDisplayStrings(); + textCommand.getTextWidget().setFocus(); + textCommand.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); + } else if (source == editButton) { + // bring up dialog + SystemCommandViewerConfiguration cfg = new SystemCommandViewerConfiguration(); + cfg.setSubstVarList(sourceViewerConfiguration.getSubstVarList()); + SystemEditCommandDialog dlg = new SystemEditCommandDialog(getCommandWidget().getShell(), getCommandText(), cfg, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + if (dlg.open() == Window.OK) { + String str = dlg.getCommand(); + textCommand.getDocument().set(str); + } + } + } + + /** + * Create the editor widget + */ + private SystemCommandEditor createEditor(Composite parent, int nbrColumns, SystemCommandViewerConfiguration sourceViewerConfiguration) { + textCommand = new SystemCommandEditor(null, parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL, nbrColumns, sourceViewerConfiguration, + "", SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_LABEL); //$NON-NLS-1$ + return textCommand; + } + + /** + * Set the command validator to validate contents per keystroke + */ + public void setCommandValidator(ISystemValidator cmdValidator) { + if (textCommand != null) textCommand.setCommandValidator(cmdValidator); + } + + /** + * Validate command input + */ + public SystemMessage validateCommand() { + if (textCommand != null) + return textCommand.validateCommand(); + else + return null; + } + + /** + * Add a modify listener + */ + public void addModifyListener(ISystemCommandTextModifyListener listener) { + if (textCommand != null) textCommand.addModifyListener(listener); + } + + /** + * Remove a modify listener + */ + public void removeModifyListener(ISystemCommandTextModifyListener listener) { + if (textCommand != null) textCommand.removeModifyListener(listener); + } + + // ----------------------------- + // Helper methods... + // ----------------------------- + /** + * Add a separator line. This is a physically visible line. + */ + protected Label addSeparatorLine(Composite parent, int nbrColumns) { + Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + separator.setLayoutData(data); + return separator; + } + + /** + * Add a spacer line + */ + protected Label addFillerLine(Composite parent, int nbrColumns) { + Label filler = new Label(parent, SWT.LEFT); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + filler.setLayoutData(data); + return filler; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandViewerConfiguration.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandViewerConfiguration.java new file mode 100644 index 00000000000..1e5506f8597 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemCommandViewerConfiguration.java @@ -0,0 +1,200 @@ +package org.eclipse.rse.useractions.ui; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.contentassist.CompletionProposal; +import org.eclipse.jface.text.contentassist.ContentAssistant; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContentAssistProcessor; +import org.eclipse.jface.text.contentassist.IContentAssistant; +import org.eclipse.jface.text.contentassist.IContextInformation; +import org.eclipse.jface.text.contentassist.IContextInformationValidator; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewerConfiguration; + +/** + * @author coulthar + * + * This is the class which enables the popup window shown when + * Insert Variable is pressed in the UDA dialog. + */ +public class SystemCommandViewerConfiguration extends SourceViewerConfiguration { + private SystemCommandContentAssistProcessor contentAssistantProcessor; + private ContentAssistant contentAssistant; + + /** + * Constructor + * You must call setSubstVarList. + */ + public SystemCommandViewerConfiguration() { + super(); + contentAssistantProcessor = new SystemCommandContentAssistProcessor(this); + } + + /** + * Reset the variable list + */ + public void setSubstVarList(SystemCmdSubstVarList variableList) { + contentAssistantProcessor.setSubstVarList(variableList); + } + + /** + * Return the current substitution variable list + */ + public SystemCmdSubstVarList getSubstVarList() { + return contentAssistantProcessor.getSubstVarList(); + } + + /** + * Parent override. + * Returns the content assistant ready to be used with the given source viewer. + * + * @param sourceViewer the source viewer to be configured by this configuration + * @return a content assistant or null if content assist should not be supported + */ + public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { + if (contentAssistant == null) { + contentAssistant = new ContentAssistant(); + contentAssistant.setContentAssistProcessor(contentAssistantProcessor, IDocument.DEFAULT_CONTENT_TYPE); + contentAssistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY); + contentAssistant.enableAutoActivation(true); + } + return contentAssistant; + } + + /* + * Similar to org.eclipse.jdt.internal.ui.text.template.TemplateVariableProcessor#getStart(String,int). + */ + /** + * Guesses the start position of the completion. + *

+ * Overridable by subclasses for cases when not using ${...} substitution variable patterns + */ + protected int getStart(String string, int end) { + int start = end; + if (start >= 1 && string.charAt(start - 1) == '$') return start - 1; + while ((start != 0) && Character.isUnicodeIdentifierPart(string.charAt(start - 1))) + start--; + if (start >= 2 && string.charAt(start - 1) == '{' && string.charAt(start - 2) == '$') return start - 2; + return end; + } + + /** + * Return the characters which trigger the auto-display of the list + * substitution variables. We return '$' by default, but this can be + * overridden. + */ + protected char[] getCompletionProposalAutoActivationCharacters() { + return new char[] { '$' }; + } + + /** + * Internal class that implements the content assist processor interface + */ + private class SystemCommandContentAssistProcessor implements IContentAssistProcessor { + private SystemCmdSubstVarList variableList; + private SystemCommandViewerConfiguration configurator; + + /** + * Constructor + */ + public SystemCommandContentAssistProcessor(SystemCommandViewerConfiguration configurator) { + this.configurator = configurator; + } + + /** + * Reset the variable list + */ + public void setSubstVarList(SystemCmdSubstVarList variableList) { + this.variableList = variableList; + } + + /** + * Return the variable list + */ + public SystemCmdSubstVarList getSubstVarList() { + return variableList; + } + + /** + * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int) + */ + public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) { + if (variableList == null) { + System.out.println("Inside UDAContentAssistProcessor in SystemUDASourceViewerConfiguration. variableList is null!"); //$NON-NLS-1$ + return null; + } + SystemCmdSubstVar[] subVars = variableList.getListAsArray(); + ICompletionProposal[] proposalList = new ICompletionProposal[subVars.length]; + int replacementOffset = documentOffset; + int replacementLength = 0; + // this little algo comes from the Java template support example. + // I am not sure I like it... it seems to be designed to replace the + // contents of the text from the previous substitution-variable-start character + // (eg '&' or '$') to the current cursor position. + String text = viewer.getDocument().get(); + //System.out.println("docOffset = " + documentOffset + ", text = '" + text + "'"); + replacementOffset = configurator.getStart(text, documentOffset); + replacementLength = documentOffset - replacementOffset; + for (int idx = 0; idx < proposalList.length; idx++) { + SystemCmdSubstVar currVar = subVars[idx]; + // @param replacementString the actual string to be inserted into the document + // @param replacementOffset the offset of the text to be replaced + // @param replacementLength the length of the text to be replaced + // @param cursorPosition the position of the cursor following the insert relative to replacementOffset + // @param image the image to display for this proposal + // @param displayString the string to be displayed for the proposal + // @param contentInformation the context information associated with this proposal + // @param additionalProposalInfo the additional information associated with this proposal + proposalList[idx] = new CompletionProposal(currVar.getVariable(), replacementOffset, replacementLength, documentOffset + currVar.getVariable().length(), null, currVar + .getDisplayString(), null, null); + } + return proposalList; + } + + /* + * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int) + */ + public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) { + return null; + } + + /* + * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters() + */ + public char[] getCompletionProposalAutoActivationCharacters() { + return configurator.getCompletionProposalAutoActivationCharacters(); + } + + /* + * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters() + */ + public char[] getContextInformationAutoActivationCharacters() { + return null; + } + + /* + * @see IContentAssistProcessor#getErrorMessage() + */ + public String getErrorMessage() { + return null; + } + + /* + * @see IContentAssistProcessor#getContextInformationValidator() + */ + public IContextInformationValidator getContextInformationValidator() { + return null; + } + } // end inner class +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemEditCommandDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemEditCommandDialog.java new file mode 100644 index 00000000000..a5747480097 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemEditCommandDialog.java @@ -0,0 +1,141 @@ +package org.eclipse.rse.useractions.ui; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.rse.shells.ui.view.SystemCommandEditor; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.view.ISystemPropertyConstants; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +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.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * Dialog used for editing command text in a resizable widget + */ +public class SystemEditCommandDialog extends Dialog implements ISystemMessages, ISystemPropertyConstants, ISystemIconConstants { + // gui + protected Label newNamePrompt; + // input + protected String cmd; + // output + protected String newCmdString; + protected boolean ignoreChanges; + // state + protected SystemCommandViewerConfiguration sourceViewerConfiguration; + protected SystemCommandEditor textCommand; + protected Button insertVariableButton; + protected int style; + protected int INSERT_ID = 10; + + /** + * Constructor. + * @param shell The parent window hosting this dialog + * @param command The resolved command from the user action + * @param sourceViewerConfiguration configration for editor + * @param style for editor + */ + public SystemEditCommandDialog(Shell shell, String command, SystemCommandViewerConfiguration sourceViewerConfiguration, int style) { + this(shell, command, SystemUDAResources.RESID_UDA_PROMPTCMD_TITLE, sourceViewerConfiguration, style); + } + + /** + * Constructor when specifying your own title. + * @param shell The parent window hosting this dialog + * @param command The resolved command from the user action + * @param title title for the dialog + * @param sourceViewerConfiguration configration for editor + * @param style for editor + */ + public SystemEditCommandDialog(Shell shell, String command, String title, SystemCommandViewerConfiguration sourceViewerConfiguration, int style) { + super(shell); + setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX); + this.style = style; + this.cmd = command; + this.sourceViewerConfiguration = sourceViewerConfiguration; + } + + /** + * Create GUI controls, populate into given composite. + */ + protected Control createDialogArea(Composite gparent) { + Composite parent = new Composite(gparent, SWT.NONE); + GridData data = new GridData(); + data.heightHint = 100; + data.widthHint = 400; + parent.setLayout(new GridLayout()); + parent.setLayoutData(data); + createEditor(parent, 5, sourceViewerConfiguration, cmd); + String title = SystemUDAResources.RESID_UDA_COMMAND_LABEL; + getShell().setText(title); + return parent; + } + + /** + * Create the editor widget + */ + private SourceViewer createEditor(Composite parent, int columnSpan, SystemCommandViewerConfiguration sourceViewerConfiguration, String cmd) { + textCommand = new SystemCommandEditor(null, parent, style, columnSpan, sourceViewerConfiguration, cmd, SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_LABEL); + return textCommand; + } + + protected void createButtonsForButtonBar(Composite parent) { + String label = SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_LABEL; + createButton(parent, INSERT_ID, label, false); + super.createButtonsForButtonBar(parent); + } + + /** + * Return widget to set initial focus to + */ + protected Control getInitialFocusControl() { + return textCommand.getControl(); + } + + protected void buttonPressed(int buttonId) { + if (IDialogConstants.OK_ID == buttonId) { + processOK(); + textCommand.getTextWidget().dispose(); + } + if (buttonId == INSERT_ID) { + textCommand.getTextWidget().setFocus(); + textCommand.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); + } + super.buttonPressed(buttonId); + } + + /** + * Called when user presses OK button. + * Return true to close dialog. + * Return false to not close dialog. + */ + protected boolean processOK() { + newCmdString = textCommand.getDocument().get().trim(); + return true; + } + + /** + * Returns the user-edited command + */ + public String getCommand() { + return newCmdString; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemPromptCommandDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemPromptCommandDialog.java new file mode 100644 index 00000000000..9dfed801b52 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/SystemPromptCommandDialog.java @@ -0,0 +1,222 @@ +package org.eclipse.rse.useractions.ui; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.dialogs.SystemPromptDialog; +import org.eclipse.rse.ui.view.ISystemPropertyConstants; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +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; + +/** + * Dialog used when to prompt the user with a command, with the intention that + * the user can change. + *

+ * This default implementation merely puts the command into an entry field, which + * the user can edit. + *

+ * Typically this is subclassed or configured to supply unique translated text. + */ +public class SystemPromptCommandDialog extends SystemPromptDialog implements ISystemMessages, ISystemPropertyConstants { + // gui + protected Text cmdText; + protected Label newNamePrompt; + // input + protected String cmd; + // output + protected String newCmdString; + // state + protected SystemMessage errorMessage; + + /** + * Constructor. + * @param shell The parent window hosting this dialog + * @param command The resolved command from the user action + */ + public SystemPromptCommandDialog(Shell shell, String command) { + this(shell, command, SystemUDAResources.RESID_UDA_PROMPTCMD_TITLE); + } + + /** + * Constructor when specifying your own title. + * @param shell The parent window hosting this dialog + * @param command The resolved command from the user action + */ + public SystemPromptCommandDialog(Shell shell, String command, String title) { + super(shell, title); + this.cmd = command; + super.setOkButtonLabel(getOKButtonLabel()); + super.setOkButtonToolTipText(getOKButtonToolTipText()); + super.setCancelButtonToolTipText(getCancelButtonToolTipText()); + //setHelp(RSEUIPlugin.HELPPREFIX+"drnp0000"); + } + + // -------------- + // MRI METHODS... + // -------------- + /** + * Translated text configuration method. + * Override to return OK button label if you don't want the default + */ + protected String getOKButtonLabel() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_OKBUTTON_LABEL; + } + + /** + * Translated text configuration method. + * Override to return OK button tooltip if you don't want the default + */ + protected String getOKButtonToolTipText() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_OKBUTTON_TOOLTIP; + } + + /** + * Translated text configuration method. + * Override to return Cancel button tooltip if you don't want the default + */ + protected String getCancelButtonToolTipText() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_CANCELBUTTON_TOOLTIP; + } + + /** + * Translated text configuration method. + * Override to return verbage message if you don't want the default + */ + protected String getVerbage() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_VERBAGE_LABEL; + } + + /** + * Translated text configuration method. + * Override to return label for the command prompt, if you don't want the default + */ + protected String getPromptLabel() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_PROMPT_LABEL; + } + + /** + * Translated text configuration method. + * Override to return tooltip text for the command prompt, if you don't want the default + */ + protected String getPromptToolTipText() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_PROMPT_TOOLTIP; + } + + /** + * Create GUI controls, populate into given composite. + */ + protected Control createInner(Composite parent) { + // Inner composite + int nbrColumns = 1; + Composite composite_prompts = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // VERBAGE + SystemWidgetHelpers.createVerbiage(composite_prompts, getVerbage(), nbrColumns, false, 250); + addFillerLine(composite_prompts, nbrColumns); + // ENTRY FIELD + SystemWidgetHelpers.createLabel(composite_prompts, getPromptLabel()); + cmdText = SystemWidgetHelpers.createMultiLineTextField(composite_prompts, null, 65); + ((GridData) cmdText.getLayoutData()).widthHint = 350; + cmdText.setToolTipText(getPromptToolTipText()); + cmdText.setTextLimit(2000); + cmdText.setText(cmd); + // add keystroke listeners... + cmdText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateInput(); + } + }); + return composite_prompts; + } + + /** + * Return widget to set initial focus to + */ + protected Control getInitialFocusControl() { + return cmdText; + } + + /** + * Called when user presses OK button. + * Return true to close dialog. + * Return false to not close dialog. + */ + protected boolean processOK() { + newCmdString = cmdText.getText().trim(); + boolean closeDialog = verify(); + if (closeDialog) { + setOutputObject(newCmdString); + } + return closeDialog; + } + + /** + * Verifies all input. Currently, we do no verification! + * @return true if there are no errors in the user input + */ + public boolean verify() { + //clearErrorMessage(); + //errorMessage = null; + //if (errorMessage != null) + // cmdText.setFocus(); + return (errorMessage == null); + } + + /** + * This hook method is called whenever the text changes in the cmd input field. + * Currently not used. + */ + protected SystemMessage validateInput() { + //errorMessage = null; + //if (errorMessage != null) + // displayErrorMessage(errorMessage); + //else + // clearErrorMessage(); + setPageComplete(); + return errorMessage; + } + + /** + * This method can be called by the dialog or wizard page host, to decide whether to enable + * or disable the next, final or ok buttons. It returns true if the minimal information is + * available and is correct. + */ + public boolean isPageComplete() { + boolean pageComplete = false; + if (errorMessage == null) { + String theNewCmd = cmdText.getText().trim(); + pageComplete = (theNewCmd.length() > 0); + } + return pageComplete; + } + + /** + * Inform caller of page-complete status of this form + */ + public void setPageComplete() { + setPageComplete(isPageComplete()); + } + + /** + * Returns the user-edited command + */ + public String getCommand() { + return newCmdString; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneHoster.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneHoster.java new file mode 100644 index 00000000000..c231013b438 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneHoster.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile; + +//import org.eclipse.jface.viewers.ISelection; +//import org.eclipse.jface.viewers.IStructuredSelection; +//import org.eclipse.jface.viewers.StructuredSelection; +//import org.eclipse.jface.viewers.ISelection; +//import org.eclipse.swt.widgets.Control; +import org.eclipse.rse.ui.messages.ISystemMessageLine; +import org.eclipse.swt.widgets.Shell; + +/** + * The interface that must be implemented for any dialog or property page that wants to + * host a user action edit pane. + */ +public interface ISystemCompileCommandEditPaneHoster extends ISystemMessageLine { + /** + * Get the shell for this dialog or property page + */ + public Shell getShell(); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneListener.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneListener.java new file mode 100644 index 00000000000..2ebec28439b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandEditPaneListener.java @@ -0,0 +1,26 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.services.clientserver.messages.SystemMessage; + +/** + * This listener interface is implemented by any code desired to be kept aware + * of all user changes to a compile command in the SystemCompileCommandEditPane. + */ +public interface ISystemCompileCommandEditPaneListener { + /** + * Callback method. The user has changed the compile command. It may or may not + * be valid. If not, the given message is non-null. If it is, and you want it, + * call getSystemCompileCommand() in the edit pane. + */ + public void compileCommandChanged(SystemMessage message); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandSubstitutor.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandSubstitutor.java new file mode 100644 index 00000000000..59b0c920afc --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileCommandSubstitutor.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile; + +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.useractions.ui.ISystemSubstitutor; + +/** + * This is the callback from SystemCmdSubstVarList that is used to substitute + * a particular substitution variable into the given compile command, for the + * given remote object. + */ +public interface ISystemCompileCommandSubstitutor extends ISystemSubstitutor { + /** + * Reset the connection so one instance can be re-used + */ + public void setConnection(IHost connection); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileXMLConstants.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileXMLConstants.java new file mode 100644 index 00000000000..d5a6c06d07b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/ISystemCompileXMLConstants.java @@ -0,0 +1,140 @@ +package org.eclipse.rse.useractions.ui.compile; + +import org.eclipse.rse.ui.SystemResources; + +/** + * Constants used in the persistence of the compile commands, into an xml file + */ +public interface ISystemCompileXMLConstants { + // The file name to use to store the xml file that + // holds info on compile name associations for a + // profile + public static final String FILE_NAME = "compileCommands.xml"; //$NON-NLS-1$ + // root tag + /** + * The name of the root element (tag) for the compile types xml file. That element is named "types". + */ + public static final String ROOT_ELEMENT = "types"; //$NON-NLS-1$ + /** + * The name of the attribute holding the version number when this document was last written. + * The xml attribute is named "version". + */ + public static final String VERSION_ATTRIBUTE = "version"; //$NON-NLS-1$ + /** + * Current version number for the compile framework + */ + public static final String VERSION_VALUE = SystemResources.CURRENT_RELEASE_NAME; // changed from "5.1.0" by Phil + /** + * The name of the copyright element (tag) holding the copyright value. That element is named "copyright". + */ + public static final String COPYRIGHT_ELEMENT = "copyright"; //$NON-NLS-1$ + /** + * The data of the copyright element (tag). + */ + public static final String COPYRIGHT_TEXT = "Copyright (c) IBM Corporation and others 2002, 2007"; //$NON-NLS-1$ + // type tag + /** + * The name of the element (tag) containing all the compile command sub-elements (tags) for + * a source type. + *

+ * The xml element is named "compiletype". + */ + public static final String TYPE_ELEMENT = "compiletype"; //$NON-NLS-1$ + public static final String TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$ + /** + * The name of the attribute holding the last-used compile command. This value identifies that + * command via its label value. + *

+ * The xml attribute is named "lastcompilename", for historical reasons (when compile commands + * were called compile names). + */ + public static final String LASTUSED_ATTRIBUTE = "lastcompilename"; //$NON-NLS-1$ + // compile name tag + /** + * The name of the element (tag) containing all the compile command attributes. + * The xml element is named "compilename", for historical reasons (when compile commands + * were called compile names). + */ + public static final String COMPILECOMMAND_ELEMENT = "compilename"; //$NON-NLS-1$ + /** + * The name of the attribute holding the compile command label. This is the name the user sees for this + * compile command. The xml attribute is named "name" for historical reasons (when compile commands + * were called compile names). + */ + public static final String LABEL_ATTRIBUTE = "name"; //$NON-NLS-1$ + /** + * The name of the attribute holding the nature value. This tells the framework if this is + * an IBM-supplied or user-supplied compile command. The xml attribute is named "nature". + */ + public static final String NATURE_ATTRIBUTE = "nature"; //$NON-NLS-1$ + /** + * Value for the compile command nature attribute for IBM-supplied commands: "IBM defined" + */ + public static final String NATURE_IBM_VALUE = "IBM defined"; //$NON-NLS-1$ + /** + * Value for the compile command nature attribute for user-supplied commands: "User defined" + */ + public static final String NATURE_USER_VALUE = "User defined"; //$NON-NLS-1$ + /** + * Value for the compile command nature attribute for vendor-supplied commands: "ISV defined" + */ + public static final String NATURE_ISV_VALUE = "ISV defined"; //$NON-NLS-1$ + /** + * The name of the attribute holding the default string value. This is the IBM-supplied value for + * support of "Restore Defaults". The xml attribute is named "default". + */ + public static final String DEFAULT_ATTRIBUTE = "default"; //$NON-NLS-1$ + /** + * The name of the attribute holding the current string value. This is the potentially user-edited + * compile command including parameters. The xml attribute is named "current". + */ + public static final String CURRENT_ATTRIBUTE = "current"; //$NON-NLS-1$ + /** + * The name of the attribute holding the menu option value. This tells the compile framework if this + * user action is to displayed in the non-promptable cascading menu, the promptable cascading menu, + * or both cascading menus. These menus shown in the popup menu for a compilable remote source + * object. + * The xml attribute is named "menu". + */ + public static final String MENU_ATTRIBUTE = "menu"; //$NON-NLS-1$ + /** + * Value for the compile command menu attribute for prompt-only commands: "Prompt" + */ + public static final String MENU_PROMPTABLE_VALUE = "Prompt"; //$NON-NLS-1$ + /** + * Value for the compile command menu attribute for no-prompt-only commands: "NoPrompt" + */ + public static final String MENU_NON_PROMPTABLE_VALUE = "NoPrompt"; //$NON-NLS-1$ + /** + * Value for the compile command menu attribute for both prompt and no-prompt commands: "Both" + */ + public static final String MENU_BOTH_VALUE = "Both"; //$NON-NLS-1$ + /** + * Value for the compile command menu attribute for neither promptable nor non-promptable commands: "None". + * These compile commands do not appear in the menu. + */ + public static final String MENU_NONE_VALUE = "None"; //$NON-NLS-1$ + /** + * The name of the attribute holding the relative order the compile command is to appear in any + * list of compile commands: "order" + */ + public static final String ORDER_ATTRIBUTE = "order"; //$NON-NLS-1$ + /** + * The name of the attribute holding the job environment value. This is not used in all cases, but those + * that need it (such as for iSeries IFS which needs to prompt for QSYS vs QSHELL cmd), this is where to + * store it. The attribute name is "jobenv". + */ + public static final String JOBENV_ATTRIBUTE = "jobenv"; //$NON-NLS-1$ + /** + * The name of the attribute holding the id: "id" + */ + public static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$ + /** + * The name of the attribute holding whether the label is editable: "labeleditable" + */ + public static final String LABEL_EDITABLE_ATTRIBUTE = "labeleditable"; //$NON-NLS-1$ + /** + * The name of the attribute holding whether the command string is editable: "stringeditable" + */ + public static final String STRING_EDITABLE_ATTRIBUTE = "stringeditable"; //$NON-NLS-1$ +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCascadingCompileAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCascadingCompileAction.java new file mode 100644 index 00000000000..62a6ebdb723 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCascadingCompileAction.java @@ -0,0 +1,91 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemPreferencesManager; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.ui.actions.SystemBaseSubMenuAction; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.swt.widgets.Shell; + +/** + * Cascading Compile-> menu for remote compilable resources. + */ +public class SystemCascadingCompileAction extends SystemBaseSubMenuAction implements IMenuListener { + private boolean isPrompt; + + /** + * Constructor for SystemCascadingCompileAction + */ + public SystemCascadingCompileAction(Shell shell, boolean isPrompt) { + super(isPrompt ? UserActionsResources.ACTION_COMPILE_PROMPT_LABEL : UserActionsResources.ACTION_COMPILE_NOPROMPT_LABEL, isPrompt ? UserActionsResources.ACTION_COMPILE_PROMPT_TOOLTIP + : UserActionsResources.ACTION_COMPILE_NOPROMPT_TOOLTIP, (ImageDescriptor) null, shell); + this.isPrompt = isPrompt; + allowOnMultipleSelection(false); + setMenuID(ISystemContextMenuConstants.MENU_COMPILE); + setCreateMenuEachTime(false); + setPopulateMenuEachTime(true); + //setTest(true); + if (isPrompt) + setHelp(RSEUIPlugin.HELPPREFIX + "ccpa0000"); //$NON-NLS-1$ + else + setHelp(RSEUIPlugin.HELPPREFIX + "ccna0000"); //$NON-NLS-1$ + } + + /** + * @see SystemBaseSubMenuAction#getSubMenu() + */ + public IMenuManager populateSubMenu(IMenuManager ourSubMenu) { + ourSubMenu.addMenuListener(this); + ourSubMenu.setRemoveAllWhenShown(true); + //menu.setEnabled(true); + ourSubMenu.add(new SystemBaseAction("dummy", null)); //$NON-NLS-1$ + return ourSubMenu; + } + + /** + * Called when submenu is about to show + */ + public void menuAboutToShow(IMenuManager ourSubMenu) { + //System.out.println("Inside menuAboutToShow for SystemCascadingCompileAction"); + Object firstSelection = getFirstSelection(); + if (firstSelection == null) { + System.out.println("Hmm, selection is null! "); //$NON-NLS-1$ + ourSubMenu.add(new SystemBaseAction("Programming error. Selection is null! ", null)); //$NON-NLS-1$ + return; + } + // is cascading-by-profile preference turned on? + if (SystemPreferencesManager.getCascadeUserActions()) { + ISystemProfile[] activeProfiles = RSEUIPlugin.getTheSystemRegistry().getActiveSystemProfiles(); + for (int idx = 0; idx < activeProfiles.length; idx++) { + SystemBaseSubMenuAction profileAction = new SystemCompileCascadeByProfileAction(getShell(), firstSelection, activeProfiles[idx], isPrompt); + ourSubMenu.add(profileAction.getSubMenu()); + } + } + // else concatenate all the compile commands from all the active profiles... + else { + ISystemProfile[] activeProfiles = RSEUIPlugin.getTheSystemRegistry().getActiveSystemProfiles(); + for (int idx = 0; idx < activeProfiles.length; idx++) + SystemCompileCascadeByProfileAction.populateMenuWithCompileActions(ourSubMenu, getShell(), activeProfiles[idx], firstSelection, isPrompt); + } + // add a separator before Work With Compile Commands... menu item + ourSubMenu.add(new Separator()); + // add Work With Commands... action + ourSubMenu.add(new SystemWorkWithCompileCommandsAction(getShell(), true)); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompilableSource.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompilableSource.java new file mode 100644 index 00000000000..b799c009576 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompilableSource.java @@ -0,0 +1,230 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.shells.ui.RemoteCommandHelpers; +import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +/** + * When a user selects a remote compilable source member, and then one of the compile commands + * from the cascading compile popup menu action, an instance of this class is created to manage + * the actual running of the compile command against the selected source. + */ +public class SystemCompilableSource implements Runnable { + protected Object firstSelection; + protected boolean isPrompt; + protected SystemCompileCommand compileCmd; + protected ISystemRemoteElementAdapter rmtAdapter; + protected Shell shell; + protected Viewer viewer; + + /** + * Constructor for SystemCompilableSource. + * Instantiated by SystemCompileAction. + * @param shell - the current shell, in case we need it for the prompt dialog or error messages. + * @param firstSelection - the selected compilable source member + * @param compileCmd - the Compile Command that is to be run against the selected compilable source member + * @param isPrompt - true if the user choose the flavor of the action to prompt the compile command + * @param viewer - the viewer that originated the compile action + */ + public SystemCompilableSource(Shell shell, Object firstSelection, SystemCompileCommand compileCmd, boolean isPrompt, Viewer viewer) { + super(); + this.shell = shell; + this.firstSelection = firstSelection; + this.compileCmd = compileCmd; + this.isPrompt = isPrompt; + this.rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(firstSelection); + this.viewer = viewer; + } + + /** + * Return the shell as set in the constructor. + * If this is null, we attempt to get the active shell + */ + public Shell getShell() { + if (shell != null) + return shell; + else { + shell = SystemBasePlugin.getActiveWorkbenchShell(); + if (shell == null) { + shell = Display.getCurrent().getActiveShell(); + if (shell == null) { + Shell[] shells = Display.getCurrent().getShells(); + for (int i = 0; (i < shells.length) && (shell == null); i++) + if (!shells[i].isDisposed() && shells[i].isEnabled()) shell = shells[i]; + } + } + return shell; + } + } + + /** + * Return the selected compilable remote source object we are to compile + */ + protected Object getSelectedObject() { + return firstSelection; + } + + /** + * Return the compile command to compile the selected source object with. + */ + protected SystemCompileCommand getCompileCommand() { + return compileCmd; + } + + /** + * Return if the compile command is to be prompted or not + */ + protected boolean isPrompt() { + return isPrompt; + } + + /** + * Return the remote adapter for the currently selected compilable remote source object + */ + protected ISystemRemoteElementAdapter getRemoteAdapter() { + return rmtAdapter; + } + + /** + * Return the source type of this remote object + */ + public String getSourceType() { + return rmtAdapter.getRemoteSourceType(firstSelection); + } + + /** + * Return the system connection from the which the selected object came from + */ + public IHost getSystemConnection() { + return getSubSystem().getHost(); + } + + /** + * Return the subsystem which is responsible for producing the remote object. + */ + protected ISubSystem getSubSystem() { + return rmtAdapter.getSubSystem(firstSelection); + } + + /** + * Return the command subsystem for the remote connection. Typically needed to actually run the + * compile command. + */ + protected IRemoteCmdSubSystem getCommandSubSystem() { + return RemoteCommandHelpers.getCmdSubSystem(getSubSystem().getHost()); + } + + /** + * Return the substitution variable list. Called by runCompileCommand default implementation. + * By default, returns it from the SystemCompileManager, but you can override if you have your + * own list. + */ + protected SystemCmdSubstVarList getSubstitutionVariableList() { + SystemCompileManager mgr = compileCmd.getParentType().getParentProfile().getParentManager(); + mgr.setCurrentCompileCommand(compileCmd); // defect 47808 + SystemCmdSubstVarList varlist = mgr.getSubstitutionVariableList(); + mgr.setCurrentCompileCommand(null); // defect 47808 + return varlist; + } + + /** + * Return the substitutor for doing variable substitution. Called by runCompileCommand default implementation. + * By default, returns it from the SystemCompileManager, but you can override if you have your + * own list. + */ + protected ISystemCompileCommandSubstitutor getSubstitutor() { + SystemCompileManager mgr = compileCmd.getParentType().getParentProfile().getParentManager(); + mgr.setCurrentCompileCommand(compileCmd); // defect 47808 + // if not called by the compile action, system connection is not set, so set it here + if (mgr.getSystemConnection() == null) mgr.setSystemConnection(getSystemConnection()); + ISystemCompileCommandSubstitutor substitutor = compileCmd.getParentType().getParentProfile().getParentManager().getSubstitutor(); + mgr.setCurrentCompileCommand(null); // defect 47808 + return substitutor; + } + + /** + * Run the compile command against the selected source. + * Do not override this directly, as it tries to handle the prompting first. + * Rather, override internalPromptCompileCommand(String) and internalRunCompileCommand(String) + */ + public boolean runCompileCommand() { + //String originalString = compileCmd.getCurrentString(); + String substitutedString = getSubstitutedString(compileCmd, firstSelection, getSubstitutor()); + if (isPrompt()) { + substitutedString = internalPromptCompileCommand(substitutedString); + if (substitutedString == null || substitutedString.trim().equals("")) //$NON-NLS-1$ + return false; + } + //System.out.println("Running compile command..."); + //System.out.println("...original cmd: '" + originalString + "'"); + //System.out.println("...final cmd...: '" + substitutedString + "'"); + return internalRunCompileCommand(substitutedString); + } + + /** + * Given the compile command, the selected source object, do the variable substitution. + * This can be overridden if needed. The default implementation here is: + *


+	 *	return compileCmd.doVariableSubstitution(firstSelection, substitutor);
+	 * 
+ */ + protected String getSubstitutedString(SystemCompileCommand compileCmd, Object firstSelection, ISystemCompileCommandSubstitutor substitutor) { + return compileCmd.doVariableSubstitution(firstSelection, substitutor); + } + + /** + * After the substituting and the prompting, it is now time to the remote running of the + * fully resolved compile command. Do that here. + *

+ * Must be overridden. + * @return true if all is well, false if something went wrong. This prevents the next compile from running + */ + protected boolean internalRunCompileCommand(String compileCmd) { + return true; + } + + /** + * When running a compile command from the prompt menu, we prompt the command. This is the + * method that does this prompt. Override if appropriate, else a simple dialog is presented + * to the user showing the substituted compile command and allowing them to change it. + *

+ * By default, this uses the SystemPromptCompileCommandDialog dialog to prompt the user to change + * the compile command. + */ + protected String internalPromptCompileCommand(String substitutedCompileCommand) { + String promptedCmd = substitutedCompileCommand; + SystemPromptCompileCommandDialog promptDlg = new SystemPromptCompileCommandDialog(shell, substitutedCompileCommand); + promptDlg.open(); + if (!promptDlg.wasCancelled()) + promptedCmd = promptDlg.getCommand(); + else + promptedCmd = null; + return promptedCmd; + } + + /** + * The run() method for running code in a thread. This is empty by default, but we include it + * for your convenience to save adding "implements Runnable" in your subclass. Override if + * using threads or asynchExec. + */ + public void run() { + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileAction.java new file mode 100644 index 00000000000..8cbd27ce8e2 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileAction.java @@ -0,0 +1,194 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.internal.ui.view.SystemTableViewProvider; +import org.eclipse.rse.ui.GenericMessages; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.ui.view.ISystemEditableRemoteObject; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.ListSelectionDialog; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.WorkbenchContentProvider; + +/** + * This is the action for an individual compile command, either prompted or not prompted. + * The label for the action is simply the compile command's label. If promptable, then "..." is appended. + */ +public class SystemCompileAction extends SystemBaseAction { + private SystemCompileCommand compileCmd; + private boolean isPrompt; + + /** + * Constructor + */ + public SystemCompileAction(Shell shell, SystemCompileCommand compileCommand, boolean isPrompt) { + super( + isPrompt ? compileCommand.getLabel() + "..." : compileCommand.getLabel(), compileCommand.getLabel(), RSEUIPlugin.getDefault().getImageDescriptor(ISystemIconConstants.ICON_SYSTEM_COMPILE_ID), shell); // null == image //$NON-NLS-1$ + this.compileCmd = compileCommand; + this.isPrompt = isPrompt; + SystemCompileManager mgr = compileCommand.getParentType().getParentProfile().getParentManager(); + allowOnMultipleSelection(mgr.isMultiSelectSupported(compileCommand)); + if (isPrompt) + setHelp(RSEUIPlugin.HELPPREFIX + "scpa0000"); //$NON-NLS-1$ + else + setHelp(RSEUIPlugin.HELPPREFIX + "scna0000"); //$NON-NLS-1$ + SystemCompileCommand lucc = compileCmd.getParentType().getLastUsedCompileCommand(); + if ((lucc != null) && lucc.getLabel().equals(compileCmd.getLabel())) { + setChecked(true); + // if (!isPrompt) + // setAccelerator(SWT.CTRL | SWT.SHIFT | 'c'); + } else + setChecked(false); + } + + /** + * Intercept of parent method that is our first opportunity to enable/disable this action, typically + * by interrogating the current selection, retrievable via getSelection. + *

+ * For this compile action, we disable if we are not currently connected. + */ + public boolean updateSelection(IStructuredSelection selection) { + boolean enable = true; + Object selected = getFirstSelection(); + if (selected == null) return false; + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(selected); + if (rmtAdapter == null) enable = false; + // yantzi:artemis6.0, we need to allow the menu item to show up even if disconnected in order + // to allow customers to restore the tree view from cache on startup and still have all actions + // available. It is up to the subsystme to make sure to connect if required when the compile + // command is run + //else + // enable = rmtAdapter.getSubSystem(selected).isConnected(); + if (!enable) return false; + SystemCompileManager mgr = compileCmd.getParentType().getParentProfile().getParentManager(); + while (enable && (selected != null)) { + enable = mgr.isCompilable(selected); + selected = getNextSelection(); + } + return enable; + } + + /** + * Intercept of parent method that is our opportunity to enable/disable this action, typically + * by interrogating the current selection, retrievable via getSelection. + *

+ * For this compile action, we disable if we are not currently connected. + */ + public boolean checkObjectType(Object selectedObject) { + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(selectedObject); + if (rmtAdapter == null) + return false; + else + return rmtAdapter.getSubSystem(selectedObject).isConnected(); + } + + /** + * Called by eclipse when the user selects this action. Does the actual running of the action. + */ + public void run() { + if (checkDirtyEditors()) { + Object element = getFirstSelection(); + boolean ok = true; + while (ok && (element != null)) { + /* FIXME - compile actions not coupled with subsystem API anymore + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(element); + ISubSystem ss = rmtAdapter.getSubSystem(element); + ss.getParentSubSystemFactory().getCompileManager().setSystemConnection(ss.getHost()); + */ + SystemCompileType compType = compileCmd.getParentType(); + compType.setLastUsedCompileCommand(compileCmd); + compType.getParentProfile().writeToDisk(); + SystemCompilableSource compilableSrc = compType.getParentProfile().getCompilableSourceObject(getShell(), element, compileCmd, isPrompt, viewer); + ok = compilableSrc.runCompileCommand(); + if (ok) element = getNextSelection(); + } + } + } + + protected List getDirtyEditors() { + IStructuredSelection sel = getSelection(); + List selection = sel.toList(); + List dirtyEditors = new ArrayList(); + for (int i = 0; i < selection.size(); i++) { + Object selected = selection.get(i); + if (selected instanceof IAdaptable) { + ISystemEditableRemoteObject editable = getEditableFor((IAdaptable) selected); + if (editable != null) { + try { + // is the file being edited? + if (editable.checkOpenInEditor() == 0) { + // reference the editing editor + editable.openEditor(); + // file is open in editor - prompt for save + if (editable.isDirty()) { + dirtyEditors.add(editable); + } + } + } catch (Exception e) { + } + } + } + } + return dirtyEditors; + } + + protected ISystemEditableRemoteObject getEditableFor(IAdaptable selected) { + ISystemRemoteElementAdapter adapter = (ISystemRemoteElementAdapter) selected.getAdapter(ISystemRemoteElementAdapter.class); + if (adapter.canEdit(selected)) { + ISystemEditableRemoteObject editable = adapter.getEditableRemoteObject(selected); + try { + editable.setLocalResourceProperties(); + } catch (Exception e) { + } + return editable; + } + return null; + } + + protected boolean checkDirtyEditors() { + List dirtyEditors = getDirtyEditors(); + if (dirtyEditors.size() > 0) { + AdaptableList input = new AdaptableList(); + for (int i = 0; i < dirtyEditors.size(); i++) { + ISystemEditableRemoteObject rmtObj = (ISystemEditableRemoteObject) dirtyEditors.get(i); + input.add(rmtObj.getRemoteObject()); + } + WorkbenchContentProvider cprovider = new WorkbenchContentProvider(); + SystemTableViewProvider lprovider = new SystemTableViewProvider(null); + // TODO: Cannot use WorkbenchMessages -- it's internal + ListSelectionDialog dlg = new ListSelectionDialog(getShell(), input, cprovider, lprovider, GenericMessages.EditorManager_saveResourcesMessage); + dlg.setInitialSelections(input.getChildren()); + // TODO: Cannot use WorkbenchMessages -- it's internal + dlg.setTitle(GenericMessages.EditorManager_saveResourcesTitle); + int result = dlg.open(); + //Just return false to prevent the operation continuing + if (result == IDialogConstants.CANCEL_ID) return false; + Object[] filesToSave = dlg.getResult(); + for (int s = 0; s < filesToSave.length; s++) { + IAdaptable rmtObj = (IAdaptable) filesToSave[s]; + ISystemEditableRemoteObject editable = getEditableFor(rmtObj); + editable.doImmediateSaveAndUpload(); + } + } + return true; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCascadeByProfileAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCascadeByProfileAction.java new file mode 100644 index 00000000000..d5d246a292f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCascadeByProfileAction.java @@ -0,0 +1,110 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.internal.ui.view.SystemViewMenuListener; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseDummyAction; +import org.eclipse.rse.ui.actions.SystemBaseSubMenuAction; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.swt.widgets.Shell; + +/** + * A cascading submenu action for "Compile->". + * This is after the first cascade, which lists profiles. + * Here, for that profile, we list actions + */ +public class SystemCompileCascadeByProfileAction extends SystemBaseSubMenuAction implements IMenuListener { + private ISystemProfile profile; + private Object firstSelection; + private boolean isPrompt; + + /** + * Constructor. + */ + public SystemCompileCascadeByProfileAction(Shell shell, Object firstSelection, ISystemProfile profile, boolean isPrompt) { + super(profile.getName(), RSEUIPlugin.getDefault().getImageDescriptor(ISystemIconConstants.ICON_SYSTEM_PROFILE_ID), shell); + this.profile = profile; + this.firstSelection = firstSelection; + this.isPrompt = isPrompt; + setCreateMenuEachTime(false); + setPopulateMenuEachTime(true); + //this.setTest(true); + } + + /** + * @see org.eclipse.rse.ui.actions.SystemBaseSubMenuAction#getSubMenu() + */ + public IMenuManager populateSubMenu(IMenuManager menu) { + //System.out.println("Inside populateSubMenu for SystemUDACascadeByProfileAction"); + menu.addMenuListener(this); + menu.setRemoveAllWhenShown(true); + //menu.setEnabled(true); + menu.add(new SystemBaseDummyAction()); + return menu; + } + + /** + * Called when submenu is about to show. Called because we + * implement IMenuListener, and registered ourself for this event. + */ + public void menuAboutToShow(IMenuManager ourSubMenu) { + //System.out.println("Inside menuAboutToShow for SystemUDACascadeByProfileAction"); + Shell shell = getShell(); + populateMenuWithCompileActions(ourSubMenu, shell, profile, firstSelection, isPrompt); + } + + /** + * Overridable method from parent that instantiates the menu listener who job is to add mnemonics. + * @param setMnemonicsOnlyOnce true if the menu is static and so mnemonics need only be set once. False if it is dynamic + */ + protected SystemViewMenuListener createMnemonicsListener(boolean setMnemonicsOnlyOnce) { + return new SystemViewMenuListener(false); // our menu is re-built dynamically each time + } + + /** + * Re-usable method to populate a sub-menu with compile actions... + */ + public static IMenuManager populateMenuWithCompileActions(IMenuManager ourSubMenu, Shell shell, ISystemProfile profile, Object firstSelection, boolean isPrompt) { + String srcType = null; + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(firstSelection); + if (rmtAdapter != null) { + srcType = rmtAdapter.getRemoteSourceType(firstSelection); + if (srcType == null) + srcType = "null"; //$NON-NLS-1$ + else if (srcType.equals("")) //$NON-NLS-1$ + srcType = "blank"; //$NON-NLS-1$ + } else + return ourSubMenu; // should never happen + /* FIXME - compile actions not coupled with subsystem API anymore + ISubSystem subsystem = rmtAdapter.getSubSystem(firstSelection); + SystemCompileProfile compileProfile = subsystem.getParentSubSystemFactory().getCompileManager().getCompileProfile(profile); + // compileProfile.addContributions(firstSelection); + SystemCompileType compileType = (SystemCompileType)compileProfile.getCompileType(srcType); + + if (compileType != null) + { + SystemCompileCommand[] cmds = compileType.getCompileCommandsArray(); + for (int idx=0; idx + * The attributes of a compile command include: + *

    + *
  • Nature. Either IBM-supplied or user defined. See {@link #setNature(String)} and {@link #getNature()} + *
  • Label. The visual name the user sees, representing this compile command. See {@link #setLabel(String)} and {@link #getLabel()} + *
  • DefaultString. The default IBM-supplied compile command (with parms) for support of restore defaults. See {@link #setDefaultString(String)} and {@link #getDefaultString()} + *
  • CurrentString. The current potentially user-edited compile command (with parms) for support of restore defaults. + * See {@link #setCurrentString(String)} and {@link #getCurrentString()} + *
  • MenuOption. Identifies what compile popup menu this command appears in, if any. + * See {@link #setMenuOption(String)} and {@link #getMenuOption()} and {@link #isPromptable()} and {@link #isNonPromptable()}. + *
  • Option. This compile commands position within the list of compile commands for a given compile type. + * See {@link #setOrder(int)} and {@link #getOrder()} + *
  • JobEnvironment. This is available for subsystems that need it, and they decide what to put in this attribute. + *
+ */ +public class SystemCompileCommand implements Cloneable, ISystemCompileXMLConstants, IAdaptable { + private SystemCompileType parentType; // reference to parent type + private String nature; + private String id; + private String label; + private String defaultString; + private String currentString; + private String menuOption; + private String jobEnv; + private int order; + private boolean isLabelEditable = true; + private static final String ID_IBM_PREFIX = "com.ibm"; //$NON-NLS-1$ + private static final String ID_USER_PREFIX = "user"; //$NON-NLS-1$ + + /** + * Constructor for SystemCompileCommand + */ + public SystemCompileCommand(SystemCompileType parentType) { + super(); + setParentType(parentType); + setMenuOptionBoth(); + } + + /** + * Constructor for SystemCompileCommand. Id and label must be a unique value. + */ + public SystemCompileCommand(SystemCompileType parentType, String id, String label, String nature, String defaultString, String currentString, String menuOption, int order) { + super(); + setParentType(parentType); + setId(id); + setLabel(label); + setNature(nature); + setDefaultString(defaultString); + setCurrentString(currentString); + setMenuOption(menuOption); + setOrder(order); + // if the given id is null, then try to configure it automatically. + // This is only good for IBM and user supplied commands. + // We assume ISV supplied commands have unique ids. + if (id == null) { + configureId(); + } + } + + /** + * Sets the parent type + * @param parentType the parent type + */ + public void setParentType(SystemCompileType parentType) { + this.parentType = parentType; + } + + /** + * Get the parent type + * @return the parent type + */ + public SystemCompileType getParentType() { + return parentType; + } + + /** + * Set the id. This is the unique id of the compile command. + * @param identifier the id + */ + public void setId(String identifier) { + this.id = identifier; + } + + /** + * Get the id. + * @return the unique id. + */ + public String getId() { + return id; + } + + /** + * Sets the id automatically. This only works for IBM supplied or user supplied commands. It does + * not work with ISV supplied commands. ISVs should set their own unique id. + */ + private void configureId() { + if (nature != null && label != null) { + if (isIBMSupplied()) { + setId(ID_IBM_PREFIX + "." + label); //$NON-NLS-1$ + } else if (isUserSupplied()) { + setId(ID_USER_PREFIX + "." + label); //$NON-NLS-1$ + } + } + } + + /** + * Set the label. This is the visual name the user sees in the compile command list. + * @param name the label + */ + public void setLabel(String name) { + this.label = name; + configureId(); // Id may change as a result + } + + /** + * Get the label. This is the visual name the user sees in the compile command list. + * @return the label + */ + public String getLabel() { + return label; + } + + /** + * Set the nature: either IBM-supplied or user defined. + * @param nature Typically one of {#link ISystemCompileXMLConstants#NATURE_IBM_VALUE} or {#link ISystemCompileXMLConstants#NATURE_USER_VALUE} + * @see #setIsIBMSupplied() + * @see #setIsUserSupplied() + * @see #setIsISVSupplied() + */ + public void setNature(String nature) { + this.nature = nature; + configureId(); // Id may change as a result + // For IBM and User supplied commands, we set editability parameters. We do this here because it's convenient. + // During a copy and paste of an IBM supplied command, nature of newly created command is user supplied, + // and so label becomes editable. + if (isIBMSupplied()) { + setLabelEditable(false); + setCommandStringEditable(true); + } else if (isUserSupplied()) { + setLabelEditable(true); + setCommandStringEditable(true); + } + } + + /** + * Indicate this is IBM supplied. This sets the nature to {#link ISystemCompileXMLConstants#NATURE_IBM_VALUE} + */ + public void setIsIBMSupplied() { + setNature(NATURE_IBM_VALUE); + } + + /** + * Indicate this is user supplied. This sets the nature to {#link ISystemCompileXMLConstants#NATURE_USER_VALUE} + */ + public void setIsUserSupplied() { + setNature(NATURE_USER_VALUE); + } + + /** + * Indicate this is ISV supplied. This sets the nature to {#link ISystemCompileXMLConstants#NATURE_ISV_VALUE} + */ + public void setIsISVSupplied() { + setNature(NATURE_ISV_VALUE); + } + + /** + * Get the nature: either IBM-supplied or user defined. + * @return the nature. One of {#link ISystemCompileXMLConstants#NATURE_IBM_VALUE} or {#link ISystemCompileXMLConstants#NATURE_USER_VALUE} + * @see #isIBMSupplied() + * @see #isUserSupplied() + */ + public String getNature() { + return nature; + } + + /** + * Return true if this is an IBM-supplied type. If false it is user or ISV supplied. + */ + public boolean isIBMSupplied() { + return nature.equals(NATURE_IBM_VALUE); + } + + /** + * Return true if this is an user-supplied type. If false it is IBM or ISV supplied. + */ + public boolean isUserSupplied() { + return nature.equals(NATURE_USER_VALUE); + } + + /** + * Return true if this is an ISV-supplied type. If false it is IBM or user supplied. + */ + public boolean isISVSupplied() { + return nature.equals(NATURE_ISV_VALUE); + } + + /** + * Set the default string. This is the IBM-supplied compile command (with parameters) that is restored when "Restore Defaults" is pressed. + * @param defaultString the default string + */ + public void setDefaultString(String defaultString) { + //this.defaultString = defaultString.toUpperCase(); // now leave it up to GUI to do massaging + this.defaultString = defaultString; + } + + /** + * Get the default string. This is the IBM-supplied compile command (with parameters) that is restored when "Restore Defaults" is pressed. + * @return the default string + */ + public String getDefaultString() { + return defaultString; + } + + /** + * Set the current string. This is the current value of the compile command (with parameters). + * @param currentString the current string + */ + public void setCurrentString(String currentString) { + //this.currentString = currentString.toUpperCase(); now leave it up to GUI to massage command string + this.currentString = currentString; + } + + /** + * Get the current string. This is the current value of the compile command (with parameters). + * @return the current string + */ + public String getCurrentString() { + return currentString; + } + + /** + * Set the menu option. Dictates in what popup menu, if any, this compile command appears in. + * @param menuOption the menu option. + * One of {#link ISystemCompileXMLConstants#MENU_PROMPTABLE_VALUE} + * or {#link ISystemCompileXMLConstants#MENU_NON_PROMPTABLE_VALUE} + * or {#link ISystemCompileXMLConstants#MENU_BOTH_VALUE} + * or {#link ISystemCompileXMLConstants#MENU_NONE_VALUE} + */ + public void setMenuOption(String menuOption) { + this.menuOption = menuOption; + } + + /** + * Fastpath to setting the menu option to both, which is the typical case + */ + public void setMenuOptionBoth() { + setMenuOption(MENU_BOTH_VALUE); + } + + /** + * Get the menu option. Dictates in what popup menu, if any, this compile command appears in. + * @return the menu option: + * One of {#link ISystemCompileXMLConstants#MENU_PROMPTABLE_VALUE} + * or {#link ISystemCompileXMLConstants#MENU_NON_PROMPTABLE_VALUE} + * or {#link ISystemCompileXMLConstants#MENU_BOTH_VALUE} + * or {#link ISystemCompileXMLConstants#MENU_NONE_VALUE} + */ + public String getMenuOption() { + return menuOption; + } + + /** + * Set the order. That is, this compile commands position within the list of compile commands for a given compile type. + * @returns the compile command's order or position. + */ + public void setOrder(int order) { + this.order = order; + } + + /** + * Get the order. That is, this compile commands position within the list of compile commands for a given compile type. + * @return the order or position. + */ + public int getOrder() { + return order; + } + + /** + * Returns if it is promptable. Queries the value of the menuOption attribute. + * + * @return true if promptable, false otherwise + */ + public boolean isPromptable() { + if (menuOption.equals(MENU_BOTH_VALUE) || menuOption.equals(MENU_PROMPTABLE_VALUE)) + return true; + else + return false; + } + + /** + * Returns if it is non-promptable. Queries the value of the menuOption attribute. + */ + public boolean isNonPromptable() { + if (menuOption.equals(MENU_BOTH_VALUE) || menuOption.equals(MENU_NON_PROMPTABLE_VALUE)) + return true; + else + return false; + } + + /** + * Set the job environment property. This is subsystem specific, and not used by all subsystems. + */ + public void setJobEnvironment(String jobenv) { + this.jobEnv = jobenv; + } + + /** + * Get the job environment property. + */ + public String getJobEnvironment() { + return jobEnv; + } + + /** + * Sets whether the label is editable in the Work With Compile Commands dialog. + */ + public void setLabelEditable(boolean editable) { + isLabelEditable = editable; + } + + /** + * Gets whether the label is editable in the Work With Compile Commands dialog. + */ + public boolean isLabelEditable() { + return isLabelEditable; + } + + /** + * Sets whether the command string is editable in the Work With Compile Commands dialog. + */ + public void setCommandStringEditable(boolean editable) { + } + + /** + * Gets whether the command string is editable in the Work With Compile Commands dialog. + */ + public boolean isCommandStringEditable() { + // return isCommandStringEditable; + return true; // for 5.1, all command strings are editable + // TODO: For V6, think about the scenario when it's false + // how do we handle that in the various dialogs? + } + + /** + * Clone the object. Creates a new compile command and copies all its attributes. + * If a subclass adds additional attributes, this method should be subclassed to clone those attributes. + */ + public Object clone() { + SystemCompileCommand clone = new SystemCompileCommand(getParentType(), getId(), getLabel(), NATURE_USER_VALUE, null, getCurrentString(), getMenuOption(), getOrder()); + if (jobEnv != null) clone.setJobEnvironment(jobEnv); + return clone; + } + + /** + * Print the full command string to standard out, for debugging purposes + */ + public void printCommand(String indent) { + System.out.println(indent + "Label: '" + label + "', Cmd: '" + currentString + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * Do substitution of any variables found in the compile command, using the given + * remote source object. It is the responsibility of the caller of this method to + * supply a "substitutor" that has knowledge of the supported substitution variables + * for these compile commands. Each implementation will override the substitutor + * interface to support the necessary getters for resolving their supported variables. + *

+ * This method retrieves the substitution variable list from the compile manager, and + * then calls doSubstitutions in it. This in turn will call back to the supplied substitutor + * for each match it finds in compile string, of a variable in its list. + */ + public String doVariableSubstitution(Object remoteObject, ISystemCompileCommandSubstitutor substitutor) { + SystemCompileManager mgr = parentType.getParentProfile().getParentManager(); + mgr.setCurrentCompileCommand(this); // defect 47808 + SystemCmdSubstVarList substVarList = mgr.getSubstitutionVariableList(); + String substitutedString = substVarList.doSubstitutions(getCurrentString(), remoteObject, substitutor); + mgr.setCurrentCompileCommand(null); // defect 47808 + //System.out.println("mgr class = " + mgr.getClass().getName()); + //System.out.println("substVL class = " + substVarList.getClass().getName()); + //System.out.println("substitutor class = " + substitutor.getClass().getName()); + return substitutedString; + } + + /** + * Return this object as a string. + */ + public String toString() { + return getCurrentString(); + } + + /** + * This is the method required by the IAdaptable interface. + * Given an adapter class type, return an object castable to the type, or + * null if this is not possible. + */ + public Object getAdapter(Class adapterType) { + return Platform.getAdapterManager().getAdapter(this, adapterType); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionCopy.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionCopy.java new file mode 100644 index 00000000000..da72196286e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionCopy.java @@ -0,0 +1,54 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * The action is used within the Work With Compile Commands dialog, in the context menu of the selected compile command. + * It is used to copy the selected compile command to the clipboard for subsequent paste. + */ +public class SystemCompileCommandActionCopy extends SystemBaseAction { + private SystemWorkWithCompileCommandsDialog parentDialog; + + /** + * Constructor + */ + public SystemCompileCommandActionCopy(SystemWorkWithCompileCommandsDialog parentDialog) { + super(SystemUDAResources.RESID_WWCOMPCMDS_ACTION_COPY_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_ACTION_COPY_TOOLTIP, PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( + ISharedImages.IMG_TOOL_COPY), null); + allowOnMultipleSelection(false); + this.parentDialog = parentDialog; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc2000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the "new" filter string + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentDialog.canCopy(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentDialog.doCopy(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionDelete.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionDelete.java new file mode 100644 index 00000000000..8cb81b1ec2b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionDelete.java @@ -0,0 +1,54 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * The action is used within the Work With Compile Commands dialog, in the context menu of the selected compile command. + * It is used to delete the selected compile command. + */ +public class SystemCompileCommandActionDelete extends SystemBaseAction { + private SystemWorkWithCompileCommandsDialog parentDialog; + + /** + * Constructor + */ + public SystemCompileCommandActionDelete(SystemWorkWithCompileCommandsDialog parentDialog) { + super(SystemUDAResources.RESID_WWCOMPCMDS_ACTION_DELETE_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_ACTION_DELETE_TOOLTIP, PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( + ISharedImages.IMG_TOOL_DELETE), null); + allowOnMultipleSelection(false); + this.parentDialog = parentDialog; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc1000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the "new" filter string + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentDialog.canDelete(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentDialog.doDelete(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveDown.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveDown.java new file mode 100644 index 00000000000..24b606b326d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveDown.java @@ -0,0 +1,53 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; + +/** + * The action is used within the Work With Compile Commands dialog, in the context menu of the selected compile command. + * It is used to move the selected compile command up by one in the list. + */ +public class SystemCompileCommandActionMoveDown extends SystemBaseAction { + private SystemWorkWithCompileCommandsDialog parentDialog; + + /** + * Constructor + */ + public SystemCompileCommandActionMoveDown(SystemWorkWithCompileCommandsDialog parentDialog) { + super(SystemUDAResources.RESID_WWCOMPCMDS_ACTION_MOVEDOWN_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_ACTION_MOVEDOWN_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_MOVEDOWN_ID), null); + allowOnMultipleSelection(false); + this.parentDialog = parentDialog; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORDER); + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc5000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the last filter string in the list + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentDialog.canMoveDown(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentDialog.doMoveDown(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveUp.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveUp.java new file mode 100644 index 00000000000..3a6a55f84ec --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionMoveUp.java @@ -0,0 +1,53 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; + +/** + * The action is used within the Work With Compile Commands dialog, in the context menu of the selected compile command. + * It is used to move the selected compile command down by one in the list + */ +public class SystemCompileCommandActionMoveUp extends SystemBaseAction { + private SystemWorkWithCompileCommandsDialog parentDialog; + + /** + * Constructor + */ + public SystemCompileCommandActionMoveUp(SystemWorkWithCompileCommandsDialog parentDialog) { + super(SystemUDAResources.RESID_WWCOMPCMDS_ACTION_MOVEUP_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_ACTION_MOVEUP_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_MOVEUP_ID), null); + allowOnMultipleSelection(false); + this.parentDialog = parentDialog; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORDER); + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc4000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the fist filter string + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentDialog.canMoveUp(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentDialog.doMoveUp(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionPaste.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionPaste.java new file mode 100644 index 00000000000..5000a55c677 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionPaste.java @@ -0,0 +1,54 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * The action is used within the Work With Compile Commands dialog, in the context menu of the selected compile command. + * It is used to paste the copied compile command from the clipboard to the list. + */ +public class SystemCompileCommandActionPaste extends SystemBaseAction { + private SystemWorkWithCompileCommandsDialog parentDialog; + + /** + * Constructor + */ + public SystemCompileCommandActionPaste(SystemWorkWithCompileCommandsDialog parentDialog) { + super(SystemUDAResources.RESID_WWCOMPCMDS_ACTION_PASTE_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_ACTION_PASTE_TOOLTIP, PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( + ISharedImages.IMG_TOOL_PASTE), null); + allowOnMultipleSelection(false); + this.parentDialog = parentDialog; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc3000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure there is something in the clipboard to copy + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentDialog.canPaste(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentDialog.doPaste(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionRestoreDefaults.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionRestoreDefaults.java new file mode 100644 index 00000000000..b8793d8c523 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandActionRestoreDefaults.java @@ -0,0 +1,54 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; + +/** + * The action is used within the Work With Compile Commands dialog, in the context menu + * of the selected compile command. + * It is used to restore shipped defaults of the selected IBM-supplied compile command. + */ +public class SystemCompileCommandActionRestoreDefaults extends SystemBaseAction { + private SystemWorkWithCompileCommandsDialog parentDialog; + + /** + * Constructor + */ + public SystemCompileCommandActionRestoreDefaults(SystemWorkWithCompileCommandsDialog parentDialog) { + super(SystemUDAResources.RESID_WWCOMPCMDS_ACTION_RESTORE_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_ACTION_RESTORE_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptorFromIDE( + ISystemIconConstants.ICON_IDE_REFRESH_ID), null); + allowOnMultipleSelection(false); + this.parentDialog = parentDialog; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_CHANGE); + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc6000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is an IBM-supplied compile command + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentDialog.canRestore(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentDialog.doRestore(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandContentProvider.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandContentProvider.java new file mode 100644 index 00000000000..8348c99dd1d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandContentProvider.java @@ -0,0 +1,45 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * Content provider for the list viewer in the Work With Compile Commands dialog. + */ +public class SystemCompileCommandContentProvider implements IStructuredContentProvider { + /** + * Constructor for SystemCompileCommandContentProvider. + */ + public SystemCompileCommandContentProvider() { + super(); + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /** + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + /** + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object) + */ + public Object[] getElements(Object inputElement) { + return null; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandEditPane.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandEditPane.java new file mode 100644 index 00000000000..516ebc8ec46 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandEditPane.java @@ -0,0 +1,675 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.shells.ui.view.ISystemCommandTextModifyListener; +import org.eclipse.rse.ui.ISystemMassager; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.validators.ISystemValidator; +import org.eclipse.rse.ui.validators.ISystemValidatorUniqueString; +import org.eclipse.rse.ui.validators.ValidatorCompileCommandLabel; +import org.eclipse.rse.useractions.ui.ISystemCommandTextAdditionalGUIProvider; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.SystemCommandTextField; +import org.eclipse.rse.useractions.ui.SystemCommandViewerConfiguration; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.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.swt.widgets.Text; + +/** + * This class prompts the user to create or edit the contents of a single + * compile command. This edit pane is used in the Work With Compile Commands dialog. + *

+ * So what is the "contract" the edit pane has to fulfill? + *

    + *
  • work in "new" or "edit" mode. In the latter case it is given a SystemCompileCommand as input. + * This needs to be switchable on the fly. This is typically automated by use of a "state machine". + *
  • give as output a new or updated SystemCompileCommand + *
  • allow interested parties to know when the contents have been changed, as they change, + * and whether there are errors in those changes + *
+ * Contractually, here are the methods called by the main page of the new filter wizard: + *
    + *
  • addChangeListener ... no need to ever override + *
  • setSubSystem ... no need to ever override + *
  • setCompileCommandValidator ... no need to ever override + *
  • isComplete ... no need to ever override + *
  • createContents ... you will typically override + *
  • verify ... you will typically override + *
  • getInitialFocusControl ... you will typically override + *
  • getCompileCommand ... you will typically override + *
  • areFieldsComplete ... you will typically override + *
+ */ +public class SystemCompileCommandEditPane implements SelectionListener, ISystemCommandTextAdditionalGUIProvider, ISystemCommandTextModifyListener { + // inputs + protected Shell shell; + protected ISystemCompileCommandEditPaneHoster hoster; + protected SystemCompileManager compileManager; + protected SystemCompileCommand inputCompileCommand; + protected SystemCompileType parentCompileType; + protected Vector listeners = new Vector(); + protected SystemCmdSubstVarList varList; + protected boolean newMode = true; + protected boolean ignoreChanges; + // default GUI + protected Label labelLabel; + protected Text textLabel; + protected SystemCommandTextField commandField; + // state + protected SystemMessage errorMessage; + protected boolean skipEventFiring; + protected boolean fromVerify; + protected boolean caseSensitive; + protected Control controlInError = null; + // validators + protected ISystemValidator cmdLabelValidator; + + /** + * Constructor + * @param compileManager - the compile manager owner of this compile command + * @param shell - the shell of the wizard or dialog host this + * @param owner - the dialog or property page hosting this edit pane + * @param caseSensitive - whether the file system is case sensitive for where this compile command will run. Usually from isCaseSensitive() of a subsystem factory. + */ + public SystemCompileCommandEditPane(SystemCompileManager compileManager, Shell shell, ISystemCompileCommandEditPaneHoster owner, boolean caseSensitive) { + super(); + this.compileManager = compileManager; + this.shell = shell; + this.caseSensitive = caseSensitive; + this.commandField = new SystemCommandTextField(getCommandTextViewerConfiguration()); + this.commandField.setSubstitutionVariableList(compileManager.getSubstitutionVariableList()); + this.hoster = owner; + } + + // ------------------------------ + // HELPER METHODS... + // ------------------------------ + /** + * Return the shell given us in the ctor + */ + protected Shell getShell() { + return shell; + } + + /** + * Return the input compile command as given us in setCompileCommand + */ + protected SystemCompileCommand getInputCompileCommand() { + return inputCompileCommand; + } + + /** + * For subclasses: return the input compile manager + */ + protected SystemCompileManager getCompileManager() { + return compileManager; + } + + /** + * For subclasses within the subsystem factory framework: return the system connection + * within which this dialog was launched. + */ + protected IHost getSystemConnection() { + return compileManager.getSystemConnection(); + } + + // ------------------------------ + // CONFIGURATION/INPUT METHODS... + // ------------------------------ + /** + * Set the validator to use for the compile command. By default, ValidatorCompileCommandLabel is used. + */ + public void setCompileLabelValidator(ISystemValidator validator) { + this.cmdLabelValidator = validator; + } + + /** + * Turn on ignore changes mode. Subclasses typically can just query the inherited + * field ignoreChanges, unless they need to set the ignoreChanges mode in their + * own composite widgets, in which case they can override and intercept this. + */ + protected void setIgnoreChanges(boolean ignoreChanges) { + this.ignoreChanges = ignoreChanges; + commandField.setIgnoreChanges(ignoreChanges); + } + + /** + * Identify a listener interested in any changes made to the filter string, + * as they happen + */ + public void addChangeListener(ISystemCompileCommandEditPaneListener l) { + listeners.add(l); + } + + /** + * Remove a listener interested in any changes made to the filter string, + * as they happen + */ + public void removeChangeListener(ISystemCompileCommandEditPaneListener l) { + listeners.remove(l); + } + + /** + * Set the action command validator. This is called per keystroke as + * the user types the command. + */ + public void setCommandValidator(ISystemValidator validator) { + commandField.setCommandValidator(validator); + } + + /** + * Set the action command massager. This is called before saving the + * command to the persistent store, to allow for massaging what the + * user typed, such as doing intelligent uppercasing. + */ + public void setCommandMassager(ISystemMassager massager) { + commandField.setCommandMassager(massager); + } + + /** + * Set the substitution variable list that Insert Variable will use. + */ + public void setSubstitutionVariableList(SystemCmdSubstVarList varList) { + commandField.setSubstitutionVariableList(varList); + } + + /** + * For child classes to return their own subclasses of the default configurator + * used to enable proposal support in the command entry field. + */ + protected SystemCommandViewerConfiguration getCommandTextViewerConfiguration() { + return new SystemCommandViewerConfiguration(); + } + + /** + * For child classes (such as iSeries IFS) that need to dynamically change the command + * entry field configuration, on the fly. + */ + protected void setCommandTextViewerConfiguration(SystemCommandViewerConfiguration cmdAssistant) { + commandField.setCommandTextViewerConfiguration(cmdAssistant); + } + + // ------------------------------ + // LIFECYCLE METHODS... + // ------------------------------ + /** + * Set the input filter string, in edit mode. + * Or pass null if reseting to new mode. + */ + public void setCompileCommand(SystemCompileType parentCompileType, SystemCompileCommand compileCommand) { + this.inputCompileCommand = compileCommand; + //System.out.println("inside setCompileCommand: input null? " + (compileCommand==null)); + this.parentCompileType = parentCompileType; + if ((parentCompileType != null) && (cmdLabelValidator instanceof ISystemValidatorUniqueString)) { + Vector existingLabels = parentCompileType.getExistingLabels(); + if (compileCommand != null) existingLabels.removeElement(compileCommand.getLabel()); + ((ISystemValidatorUniqueString) cmdLabelValidator).setExistingNamesList(existingLabels); + } + newMode = (compileCommand == null); + setIgnoreChanges(true); + resetFields(); + if (compileCommand != null) doInitializeFields(); + enableExtraButtons(); + if (newMode) + resetExtraButtonsForNewMode(); + else + resetExtraButtons(compileCommand); + setIgnoreChanges(false); + } + + /** + * Save all pending changes. Called by dialog when user Presses Apply. + * @return new or updated compile command object. Caller must call writeToDisk() on the parent SystemCompileProfile object + */ + public SystemCompileCommand saveChanges() { + String cmdLabel = textLabel.getText().trim(); + if (cmdLabel.length() == 0) return null; + String cmdString = commandField.getMassagedCommandText(); + if (cmdString.length() == 0) return null; + cmdString = preSaveMassage(cmdString); + SystemCompileCommand currentCmd = inputCompileCommand; + if (currentCmd == null) // new mode? Must create the new compile command object + { + currentCmd = new SystemCompileCommand(parentCompileType); + currentCmd.setDefaultString(cmdString); + currentCmd.setIsUserSupplied(); + } else if (commandField.getCommandMassager() != null) { + setIgnoreChanges(true); // disable modify listeners + setCommandText(cmdString); + setIgnoreChanges(false); // re-enable modify listeners + } + if (!caseSensitive) { + //cmdLabel = cmdLabel.toUpperCase(); I0 decision not to do this anymore + //cmdString = cmdString.toUpperCase(); we use a massager now + } + currentCmd.setLabel(cmdLabel); + currentCmd.setCurrentString(cmdString); + processExtraButtonsChanges(currentCmd); // allow subclasses to save their extra data + /* + String option = null; + if (yesPromptButton.getSelection() && noPromptButton.getSelection()) + option = ISystemCompileXMLConstants.MENU_BOTH_VALUE; + else if (yesPromptButton.getSelection() && !noPromptButton.getSelection()) + option = ISystemCompileXMLConstants.MENU_PROMPTABLE_VALUE; + else if (!yesPromptButton.getSelection() && noPromptButton.getSelection()) + option = ISystemCompileXMLConstants.MENU_NON_PROMPTABLE_VALUE; + else + option = ISystemCompileXMLConstants.MENU_NONE_VALUE; + currentCmd.setMenuOption(option); + */ + return currentCmd; + } + + /** + * Opportunity for subclasses to perform any additional massaging of the + * user-entered command string, just prior to saving it. + */ + protected String preSaveMassage(String commandString) { + return commandString; + } + + /** + * In the Work With dialog, this edit pane is shown on the right side, beside + * the compile command selection list. Above it is a label, that shows something + * like "Selected Compile Command" in edit mode, or "New Compile Command" in new mode. + *

+ * This method gives subclasses the opportunity to specify unique values for this label. + * In addition to setting the text, the tooltip text should also be set. + */ + public void configureHeadingLabel(Label label) { + if (!newMode) { + label.setText(SystemUDAResources.RESID_WWCOMPCMDS_EDITCMD_LABEL); + label.setToolTipText(SystemUDAResources.RESID_WWCOMPCMDS_EDITCMD_TOOLTIP); + } else { + label.setText(SystemUDAResources.RESID_WWCOMPCMDS_NEWCMD_LABEL); + label.setToolTipText(SystemUDAResources.RESID_WWCOMPCMDS_NEWCMD_TOOLTIP); + } + } + + /** + * Populate the pane with the GUI widgets + * @param parent + * @return Control + */ + public Control createContents(Composite parent) { + if (cmdLabelValidator == null) cmdLabelValidator = new ValidatorCompileCommandLabel(); + if (cmdLabelValidator instanceof ISystemValidatorUniqueString) ((ISystemValidatorUniqueString) cmdLabelValidator).setCaseSensitive(caseSensitive); + // Inner composite + int nbrColumns = 3; + Composite composite_prompts = SystemWidgetHelpers.createComposite(parent, nbrColumns); + ((GridLayout) composite_prompts.getLayout()).marginWidth = 0; + // COMPILE LABEL PROMPT + textLabel = SystemWidgetHelpers.createLabeledTextField(composite_prompts, null, getCompileCommandLabel(), getCompileCommandTooltip()); + labelLabel = SystemWidgetHelpers.getLastLabel(); + textLabel.setTextLimit(cmdLabelValidator.getMaximumNameLength()); + ((GridData) textLabel.getLayoutData()).horizontalSpan = nbrColumns - 1; + // COMPILE COMMAND PROMPT + /* + textString = SystemWidgetHelpers.createLabeledTextField(composite_prompts,null,rb, getCompileCommandPromptRBKey()); + labelString = SystemWidgetHelpers.getLastLabel(); + //textString.setTextLimit(1000); + ((GridData)textString.getLayoutData()).widthHint=300; + */ + commandField.createContents(composite_prompts, nbrColumns, this); + resetFields(); + doInitializeFields(); + // add keystroke listeners... + textLabel.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateLabelInput(); + } + }); + commandField.addModifyListener(this); + return composite_prompts; + } + + /** + * Return the control to recieve initial focus. Should be overridden if you override createContents + */ + public Control getInitialFocusControl() { + if (textLabel.isEnabled()) + return textLabel; + else + return commandField.getCommandWidget(); + } + + /** + * Overridable entry point for subclasses that wish to put something to the right of the "Command:" label + * From interface ISystemCommandTextAdditionalGUIProvider. + * @return true if something entered to take up the available columns, false otherwise (will be padded) + */ + public boolean createCommandLabelLineControls(Composite parent, int availableColumns) { + return false; + } + + /** + * Create additional buttons, to go under command prompt. + * Overridable. + * From interface ISystemCommandTextAdditionalGUIProvider. + * @return true if something entered to take up the available columns, false otherwise (will be padded) + */ + public boolean createExtraButtons(Composite parent, int availableColumns) { + return false; + } + + /** + * Enable/disable extra buttons added by subclass. + * Called when state changes + * Overridable + */ + protected void enableExtraButtons() { + } + + /** + * Overridable method for resetting GUI in subclass-supplied additional GUI, + * when in "new" mode + */ + protected void resetExtraButtonsForNewMode() { + } + + /** + * Overridable method for resetting GUI in subclass-supplied additional GUI, + * when in "edit" mode + */ + protected void resetExtraButtons(SystemCompileCommand originalCmd) { + } + + /** + * Overridable method for saving data in subclass-supplied additional GUI. + */ + protected void processExtraButtonsChanges(SystemCompileCommand currentCmd) { + } + + protected String getCompileCommandLabel() { + return SystemUDAResources.RESID_WWCOMPCMDS_CMDLABEL_LABEL; + } + + protected String getCompileCommandTooltip() { + return SystemUDAResources.RESID_WWCOMPCMDS_CMDLABEL_TOOLTIP; + } + + protected String getCompileCommandPromptLabel() { + return SystemUDAResources.RESID_WWCOMPCMDS_CMD_LABEL; + } + + protected String getCompileCommandPromptTooltip() { + return SystemUDAResources.RESID_WWCOMPCMDS_CMD_TOOLTIP; + } + + /** + * Initialize the input fields based on the inputCompileCommand, and perhaps subsystem. + * This can be called before createContents, so test for null widgets first! + * Prior to this being called, resetFields is called to set the initial default state prior to input + */ + protected void doInitializeFields() { + //System.out.println("inside doInitializeFields: textString null? " + (commandField==null) + " input null? " + (inputCompileCommand==null)); + if (commandField == null) return; // do nothing + if (inputCompileCommand != null) { + textLabel.setText(inputCompileCommand.getLabel()); + /* if (!inputCompileCommand.isLabelEditable()) { // ibm or vendor supplied? + textLabel.setEnabled(false); + } */ + textLabel.setEnabled(inputCompileCommand.isLabelEditable()); + commandField.setCommandText(inputCompileCommand.getCurrentString()); + /* if (!inputCompileCommand.isCommandStringEditable()) { + System.out.println("Compile command not editable"); + commandField.enableCommandWidget(false); + } */ + commandField.enableCommandWidget(inputCompileCommand.isCommandStringEditable()); + } + } + + /** + * This is called in the work with compile commands dialog when the user selects "new", or selects another command. + * You must override this if you override createContents. Be sure to test if the contents have even been created yet! + */ + protected void resetFields() { + textLabel.setEnabled(true); + textLabel.setText(""); //$NON-NLS-1$ + commandField.setCommandText(""); //$NON-NLS-1$ + errorMessage = null; + } + + /** + * Do not override. Instead, override areFieldsComplete(). + *

+ * This is called by the dialog when first shown, to decide if the default information + * is complete enough to enable finish. It doesn't do validation, that will be done when + * finish is pressed. + */ + public boolean isComplete() { + boolean complete = true; + if (errorMessage != null) // pending errors? + complete = false; // clearly not complete. + else + complete = areFieldsComplete(); + return complete; + } + + /** + * Must be overridden if createContents is overridden. + *

+ * This is called by the isComplete, to decide if the default information + * is complete enough to enable finish. It doesn't do validation, that will be done when + * finish is pressed. + */ + protected boolean areFieldsComplete() { + if (commandField == null) + return false; + else + return (textLabel.getText().trim().length() > 0) && (commandField.getCommandText().length() > 0); + } + + /** + * Are errors pending? Used in dialog to prevent changing the compile command selection + */ + public boolean areErrorsPending() { + return (errorMessage != null); + } + + /** + * Clear any pending errors. Called when Revert pressed. + */ + public void clearErrorMessage() { + errorMessage = null; + } + + /** + * Callback from SystemCommandTextField when the user modifies the command. + * @param cmdText - current contents of the field + * @param errorMessage - potential error detected by the default validator + */ + public void commandModified(String cmdText, SystemMessage errorMessage) { + this.errorMessage = errorMessage; + processCommandTextChange(cmdText, (errorMessage != null)); + if (!fromVerify) fireChangeEvent(errorMessage); + } + + /** + * Method called as user types into the command field + * Encapsulated out so that it can be called from various types of listeners. + * Further, it is easily overridden + */ + protected void processCommandTextChange(String newText, boolean hasError) { + } + + /** + * Set the command text + */ + protected void setCommandText(String text) { + commandField.setCommandText(text); + } + + /** + * Get the command text as is, no massaging done. + */ + protected String getCommandText() { + return commandField.getCommandText(); + } + + // ------------------------------ + // PRIVATE METHODS + // ------------------------------ + /** + * Fire an event to all registered listeners, that the user has changed the + * compile command. Include the error message, if in error, so it can be displayed to the user. + *

+ * Because this is used to enable/disable the Next and Finish buttons it is important + * to call it when asked to do verification, even if nothing has changed. + *

+ * It is more efficient, however, to defer the event firing during a full verification + * until after the last widget has been verified. To enable this, set the protected + * variable "skipEventFiring" to true at the top of your verify event, then to "false" + * at the end. Then do fireChangeEvent(errorMessage); + */ + protected void fireChangeEvent(SystemMessage error) { + if (skipEventFiring) return; + for (int idx = 0; idx < listeners.size(); idx++) { + ISystemCompileCommandEditPaneListener l = (ISystemCompileCommandEditPaneListener) listeners.elementAt(idx); + l.compileCommandChanged(error); + } + } + + // --------------------------------------------- + // METHODS FOR VERIFYING INPUT PER KEYSTROKE ... + // --------------------------------------------- + /** + * Validates compile command label as entered so far in the text field. + * Not called if you override createContents() and verify() + */ + protected SystemMessage validateLabelInput() { + if (ignoreChanges) return errorMessage; + errorMessage = cmdLabelValidator.validate(textLabel.getText().trim()); + //if ((errorMessage == null) && !fromVerify) + // errorMessage = validate(true, false); + if (!fromVerify) fireChangeEvent(errorMessage); + return errorMessage; + } + + /** + * Validates compile command string as entered so far in the text field. + * Not called if you override createContents() and verify() + */ + protected SystemMessage validateStringInput() { + if (ignoreChanges) return errorMessage; + errorMessage = commandField.validateCommand(); + if (!fromVerify) fireChangeEvent(errorMessage); + return errorMessage; + } + + /** + * Does complete verification of input fields. This has to handle being called + * from a particular validator method or from verify. + * + * @return error message if there is one, else null if ok + */ + public SystemMessage validate(boolean skipLabel, boolean skipString) { + errorMessage = null; + controlInError = null; + if (!skipLabel) { + errorMessage = validateLabelInput(); + if (errorMessage != null) controlInError = textLabel; + } + if ((errorMessage == null) && !skipString) { + errorMessage = validateStringInput(); + if (errorMessage != null) controlInError = commandField.getCommandWidget(); + } + return errorMessage; + } + + // --------------------------------- + // METHODS FOR VERIFICATION... + // --------------------------------- + /** + * Does complete verification of input fields. If this + * method returns null, there are no errors and the dialog or wizard can close; + * + * @return error message if there is one, else null if ok + */ + public SystemMessage verify() { + fromVerify = true; + errorMessage = validate(false, false); + if (errorMessage != null) { + if (controlInError != null) controlInError.setFocus(); + } + fromVerify = false; + fireChangeEvent(errorMessage); + return errorMessage; + } + + // ------------------ + // EVENT LISTENERS... + // ------------------ + /** + * User has selected something + */ + public void widgetSelected(SelectionEvent event) { + } + + /** + * User has selected something via enter/dbl-click + */ + public void widgetDefaultSelected(SelectionEvent event) { + } + + // --------------- + // HELPER METHODS + // --------------- + /** + * Add a separator line. This is a physically visible line. + */ + protected void addSeparatorLine(Composite parent, int nbrColumns) { + Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + separator.setLayoutData(data); + } + + /** + * Add a spacer line + */ + protected void addFillerLine(Composite parent, int nbrColumns) { + Label filler = new Label(parent, SWT.LEFT); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + filler.setLayoutData(data); + } + + /** + * Add a spacer line that grows in height to absorb extra space + */ + protected void addGrowableFillerLine(Composite parent, int nbrColumns) { + Label filler = new Label(parent, SWT.LEFT); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.FILL; + data.grabExcessVerticalSpace = true; + filler.setLayoutData(data); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandLabelProvider.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandLabelProvider.java new file mode 100644 index 00000000000..84829507551 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileCommandLabelProvider.java @@ -0,0 +1,49 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.swt.graphics.Image; + +/** + * Label provider for compile commands in the work with compile commands + * dialog. + */ +public class SystemCompileCommandLabelProvider extends LabelProvider { + /** + * Constructor + */ + public SystemCompileCommandLabelProvider() { + super(); + } + + /** + * Override of parent to return the visual label for the given compile command + */ + public String getText(Object element) { + if (element instanceof SystemCompileCommand) + return ((SystemCompileCommand) element).getLabel(); + else if (element != null) + return element.toString(); + else + return null; + } + + /** + * Override of parent so we can supply an image, if we desire. + */ + public Image getImage(Object element) { + if (element instanceof SystemCompileCommand) return RSEUIPlugin.getDefault().getImage(ISystemIconConstants.ICON_SYSTEM_COMPILE_ID); + return null; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributor.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributor.java new file mode 100644 index 00000000000..c7e3d6f7c62 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributor.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; + +public class SystemCompileContributor implements ISystemCompileXMLConstants { + private IConfigurationElement config; + private SystemCompileRemoteObjectMatcher matcher; + + public SystemCompileContributor(IConfigurationElement element) { + this.config = element; + String ssfId = element.getAttribute("subsystemconfigurationid"); //$NON-NLS-1$ + String namefilter = element.getAttribute("namefilter"); //$NON-NLS-1$ + String typefilter = element.getAttribute("typefilter"); //$NON-NLS-1$ + matcher = new SystemCompileRemoteObjectMatcher(ssfId, namefilter, typefilter); + } + + /** + * Getter method. + * Return what was specified for the subsystemconfigurationid xml attribute. + */ + public String getSubSystemFactoryId() { + return matcher.getSubSystemFactoryId(); + } + + /** + * Getter method. + * Return what was specified for the namefilter xml attribute. + */ + public String getNameFilter() { + return matcher.getNameFilter(); + } + + /** + * Getter method. + * Return what was specified for the typefilter xml attribute. + */ + public String getTypeFilter() { + return matcher.getTypeFilter(); + } + + /** + * Returns true if the current selection matches all the given filtering criteria, false otherwise. + */ + public boolean isApplicableTo(Object element) { + return matcher.appliesTo(element); + } + + /** + * Contribute the compile command. + */ + public void contributeCompileCommand(SystemCompileProfile prf, Object element) { + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(element); + if (rmtAdapter != null) { + String srcType = rmtAdapter.getRemoteSourceType(element); + if (srcType == null) { + srcType = "null"; //$NON-NLS-1$ + } else if (srcType.equals("")) { //$NON-NLS-1$ + srcType = "blank"; //$NON-NLS-1$ + } + String id = config.getAttribute("id"); //$NON-NLS-1$ + String label = config.getAttribute("label"); //$NON-NLS-1$ + String commandString = config.getAttribute("commandstring"); //$NON-NLS-1$ + String labelEditable = config.getAttribute("labeleditable"); //$NON-NLS-1$ + String commandStringEditable = config.getAttribute("stringeditable"); //$NON-NLS-1$ + // label and command string are editable by default + // they are only false if indicated in extension point + boolean isLabelEditable = true; + boolean isCommandStringEditable = true; + if (labelEditable != null && labelEditable.equalsIgnoreCase("false")) { //$NON-NLS-1$ + isLabelEditable = false; + } + if (commandStringEditable != null && commandStringEditable.equalsIgnoreCase("false")) { //$NON-NLS-1$ + isCommandStringEditable = false; + } + // check all required attributes + if (id == null || label == null || commandString == null || id.equals("") || label.equals("") || commandString.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return; + } + // obtain the compile type + SystemCompileType compileType = prf.getCompileType(srcType); + // if compile type exists, then get all the compile commands for this compile type + if (compileType != null) { + // search for a command with the id + boolean idExists = compileType.isIdExists(id); + // TODO: if compile commands with the id exist, we probably should update the default command string. + // Why update the default command string? Because a vendor might decide to update a + // compile command with a new release. We don't want to change the label, current string, etc. + // but at least change the default command string. On the other hand, changing the default + // command string is unnecessary most of the time, since idExists is true after the first time the + // the compile command is added. Hence we leave it for now. + if (!idExists) { + // now check if a command with the label exists; we want to avoid duplicate labels + // so only add the command if this label does not already exist. + boolean labelExists = compileType.isLabelExists(label); + if (!labelExists) { + int numOfCommands = compileType.getNumOfCommands(); + SystemCompileCommand command = new SystemCompileCommand(compileType, id, label, NATURE_ISV_VALUE, commandString, commandString, MENU_BOTH_VALUE, numOfCommands); + command.setLabelEditable(isLabelEditable); + command.setCommandStringEditable(isCommandStringEditable); + compileType.addCompileCommandInOrder(command); + // if the type had no existing commands at all, then make the compile command + // we have just added the last used compile command for the type + if (numOfCommands == 0) { + compileType.setLastUsedCompileCommand(command); + } + } + } + } + // compile type does not exist, so add a compile type, then add the compile command to it + else { + compileType = new SystemCompileType(prf, srcType); + SystemCompileCommand command = new SystemCompileCommand(compileType, id, label, NATURE_ISV_VALUE, commandString, commandString, MENU_BOTH_VALUE, 0); + command.setLabelEditable(isLabelEditable); + command.setCommandStringEditable(isCommandStringEditable); + compileType.addCompileCommandInOrder(command); + // since the compile command we have added is the first compile command for the newly created + // compile type, make it the last used compile command. + compileType.setLastUsedCompileCommand(command); + // add the compile type to the compile profile + prf.addCompileType(compileType); + } + } + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorManager.java new file mode 100644 index 00000000000..a52236d2605 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorManager.java @@ -0,0 +1,70 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +/** + * This singleton class manages all compile contributions added through extension points. + */ +public class SystemCompileContributorManager { + private static SystemCompileContributorManager inst; + private Vector contributors = new Vector(); + + private SystemCompileContributorManager() { + loadContributors(); + } + + /** + * Returns the singleton instance of the manager. + * @return The singleton instance of this class + */ + public static SystemCompileContributorManager getInstance() { + if (inst == null) { + inst = new SystemCompileContributorManager(); + } + return inst; + } + + /** + * Loads the compile contributors from the workbench's registry. + */ + private void loadContributors() { + SystemCompileContributorReader reader = new SystemCompileContributorReader(); + reader.readCompileContributors(this); + } + + /** + * Register a contributor with the manager. + * @param contributor a contributor. + */ + public void registerContributor(SystemCompileContributor contributor) { + contributors.add(contributor); + } + + /** + * Adds all compile command contributions through extension point for the remote object. + * Returns true if there are any contributions, false otherwise. + */ + public boolean contributeCompileCommands(SystemCompileProfile prf, Object element) { + boolean isContributions = false; + // go through list of all contributors, find out which ones apply for the selected element + // and add/change a compile type to the given compile profile. + for (int idx = 0; idx < contributors.size(); idx++) { + SystemCompileContributor contributor = (SystemCompileContributor) contributors.elementAt(idx); + if (contributor.isApplicableTo(element)) { + contributor.contributeCompileCommand(prf, element); + isContributions = true; + } + } + return isContributions; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorReader.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorReader.java new file mode 100644 index 00000000000..1e14fb05ad4 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileContributorReader.java @@ -0,0 +1,51 @@ +package org.eclipse.rse.useractions.ui.compile; + +/* + * (c) Copyright IBM Corp. 2000, 2003. + * All Rights Reserved. + */ +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.Platform; +import org.eclipse.rse.ui.RSEUIPlugin; + +/* + * (c) Copyright IBM Corp. 2000, 2003. + * All Rights Reserved. + */ +/** + * This class reads configuration elements from the workbench's registry, creates contributors + * and registers them with the manager. + */ +public class SystemCompileContributorReader { + private SystemCompileContributorManager manager; + private static final String COMPILE_COMMAND_ELEMENT_NAME = "compilecommand"; //$NON-NLS-1$ + + public SystemCompileContributorReader() { + } + + public void readCompileContributors(SystemCompileContributorManager mgr) { + this.manager = mgr; + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry.getExtensionPoint(RSEUIPlugin.PLUGIN_ID, "compile"); //$NON-NLS-1$ + if (extensionPoint != null) { + IExtension[] extensions = extensionPoint.getExtensions(); + for (int m = 0; m < extensions.length; m++) { + IExtension extension = extensions[m]; + IConfigurationElement[] elements = extension.getConfigurationElements(); + for (int n = 0; n < elements.length; n++) { + IConfigurationElement element = elements[n]; + // if the element is a compile command + // then create a contributor that represents the element + // and register the contributor with the contributor manager + if (element.getName().equals(COMPILE_COMMAND_ELEMENT_NAME)) { + SystemCompileContributor contributor = new SystemCompileContributor(element); + manager.registerContributor(contributor); + } + } + } + } + } +} \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileManager.java new file mode 100644 index 00000000000..a10a3dabc3c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileManager.java @@ -0,0 +1,418 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Hashtable; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemResourceManager; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.model.SystemStartHere; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.subsystems.files.core.subsystems.IVirtualRemoteFile; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemMenuManager; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.widgets.Shell; + +/** + * This class manages the compile framework for a particular instantiation. + * It is typically associated with a subsystem factory, but it is designed + * to be used in other contexts as well. + *

+ * Here is the model for the compile framework: + *

    + *
  • This compile manager manages a list of SystemCompileProfiles. For subsystem + * factories, there will be one of these per system profile. In other contexts, + * there may well be only one SystemCompileProfile per manager. + *
  • A SystemCompileProfile manages a list of a SystemCompileTypes, which are persisted. + * There is one compile type per compilable source type, like ".cpp" for unix file + * systems. + *
  • Each SystemCompileType manages a list of SystemCompileCommands. Each command + * represents a remote command for compiling source objects of this type. Each + * command has a label shown in the Compile popup menu and a compile string that + * is the command. + *
  • There is a Work With Compile Commmands dialog that shows all existing types, + * and for each type the list of existing compile commands. Users can use this + * to define new compile commands per type, and new types. + *
  • The compile profile will optionally pre-fill its list if the persistent file is + * not found (ie, on first touch). That pre-filled list is what the user gets by + * default until they define their own compile commands. The pre-filled compile + * commands can be edited by the user (except the label) and can be restored to + * their shipped values. + *
  • When the user selects a compile command to run, an instance of SystemCompilableSource + * is created, containing a reference to the selected source object and the + * selected SystemCompileCommand. A method in that object is called to actually + * run the compile command. + *
  • Compile commands can have substitution variables. The list of supported substitution + * variables is supplied by this SystemCompileManager. The work-with dialog allows the + * user to easily insert these into his command string, and the SystemCompilableSource + * object is responsible for making the substitutions at runtime, given the compile + * command and selected source object. + *
  • For subsystem factory support of compiling, the factory provider simply returns true + * to supportsCompileActions() and implements the + *
+ * @see SystemCompileProfile + * @see SystemCompileType + * @see SystemCompileCommand + * @see SystemWorkWithCompileCommandsDialog + */ +public abstract class SystemCompileManager { + private Hashtable compileProfilesPerProfile = new Hashtable(); + private Hashtable compileSubstitutorsPerConnection = new Hashtable(); + protected IHost systemConnection; + protected ISubSystemConfiguration subsystemFactory; + /** + * As last set by calling setCurrentCompileCommand. Sometimes needed by subclasses. + */ + protected SystemCompileCommand currentCompileCommand; + + /** + * Constructor for SystemCompileManager + */ + public SystemCompileManager() { + super(); + } + + /** + * Sets the subsystemconfiguration which instantiated this. Not called if using this + * framework outside of the world of subsystem factories. + */ + public void setSubSystemFactory(ISubSystemConfiguration ssFactory) { + this.subsystemFactory = ssFactory; + } + + /** + * Return the subsystem factory which instantiated this instance, or as set via {@link #setSubSystemFactory(ISubSystemConfiguration)}. + */ + public ISubSystemConfiguration getSubSystemFactory() { + return subsystemFactory; + } + + /** + * Set the current system connection. This is set in the work with dialog, and + * used by the edit pane and other downstream classes. + */ + public void setSystemConnection(IHost systemConnection) { + this.systemConnection = systemConnection; + } + + /** + * Return the system connection with which this manager instance is associated. + */ + public IHost getSystemConnection() { + return systemConnection; + } + + /** + * Sets the current compile command. Called by the framework when running a compile command, prior to calling + * commands that may be dependent on values in the compile command being processed. + */ + public void setCurrentCompileCommand(SystemCompileCommand compileCmd) { // defect 47808 + this.currentCompileCommand = compileCmd; + } + + /** + * Return the current compile cmd as set by {@link #setCurrentCompileCommand(SystemCompileCommand)}. + */ + public SystemCompileCommand getCurrentCompileCommand() { // defect 47808 + return currentCompileCommand; + } + + /** + * Return true (default) if multiple-select is supported for the compile action + */ + public boolean isMultiSelectSupported(SystemCompileCommand compileCmd) { + return true; + } + + /** + * Get the singleton compile profile given a SystemProfile. + *

+ * Called in the Work With Compile Commands and the Compile cascading actions. + *

+ * Do not override this, as the implementation is complete. However, + * you must override createCompileProfile. + *

+ * If you are using this outside of the subsystem framework, this method will not be called. + * + * @see #createCompileProfile(ISystemProfile) + */ + public SystemCompileProfile getCompileProfile(ISystemProfile profile) { + if (compileProfilesPerProfile == null) compileProfilesPerProfile = new Hashtable(); + SystemCompileProfile cprofile = (SystemCompileProfile) compileProfilesPerProfile.get(profile); + if (cprofile == null) { + cprofile = createCompileProfile(profile); + if (cprofile != null) compileProfilesPerProfile.put(profile, cprofile); + } + return cprofile; + } + + /** + * Return a list of all SystemCompileProfile objects. + * By default, returns one per active system profile. If not using the subsystem framework, + * this must be overridden. + */ + public SystemCompileProfile[] getAllCompileProfiles() { + ISystemProfile[] systemProfiles = SystemStartHere.getSystemProfileManager().getActiveSystemProfiles(); + SystemCompileProfile[] compProfiles = null; + if ((systemProfiles != null) && (systemProfiles.length > 0)) { + compProfiles = new SystemCompileProfile[systemProfiles.length]; + for (int idx = 0; idx < systemProfiles.length; idx++) + compProfiles[idx] = getCompileProfile(systemProfiles[idx]); + } + return compProfiles; + } + + /** + * Overridable method to instantiate your SystemCompileProfile subclass for the + * given system profile. + *

It is important you pass the SystemProfile's name to the ctor of SystemCompileProfile. + */ + protected abstract SystemCompileProfile createCompileProfile(ISystemProfile profile); + + /** + * Callback method from SystemCompileProfile to get the folder into which the + * xml file for this compile profile will be stored. By default uses the + * given subsystem factory. If you are using this framework outside of the + * subsystem factory world, then override this method. + */ + public IFolder getCompileProfileFolder(SystemCompileProfile compProfile) { + ISystemProfile systemProfile = getSystemProfile(compProfile); + if (systemProfile == null) { + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_GENERIC_E); + msg.makeSubstitution(SystemUDAResources.SystemCompileManager_0); + SystemBasePlugin + .logError("In SystemCompileManager#getCompileProfileFolder, and we have gotten a null for the system profile named " + compProfile.getProfileName() + ". That should never happen!"); //$NON-NLS-1$ //$NON-NLS-2$ + SystemMessageDialog.displayErrorMessage(SystemBasePlugin.getActiveWorkbenchShell(), msg); + //return null; BETTER TO LET IT CRASH... BETTER RECOVERY + } + //System.out.println("systemProfile = " + systemProfile); + //System.out.println("subsystemFactory = " + subsystemFactory); + IFolder folder = SystemResourceManager.getCompileCommandsFolder(systemProfile, subsystemFactory); + return folder; + } + + /** + * Callback from SystemProfile to decide, when no xml file is found, if we want + * to prime the new xml file with defaults. + *

+ * By default, returns true if the SystemProfile the given compile profile is + * associated with is a user-private profile. If not using the compile framework, + * override this to use your own criteria. + */ + public boolean wantToPrimeWithDefaults(SystemCompileProfile profile) { + ISystemProfile systemProfile = getSystemProfile(profile); + //System.out.println("Inside wantToPrimeWithDefaults("+systemProfile.getName()+") and result is " + systemProfile.isDefaultPrivate()); + return systemProfile.isDefaultPrivate(); + } + + /** + * Return the default (supplied) compile commands to prime the compile commands with. + */ + public abstract SystemDefaultCompileCommands getDefaultCompileCommands(); + + /** + * If the command is an default supplied command, returns its SystemDefaultCompileCommand object. + * Returns null if not a default supplied command. + * @param commandName - the name of the command, minus the parameters. This is not the label! + */ + public SystemDefaultCompileCommand getDefaultSuppliedCommand(String commandName) { + SystemDefaultCompileCommands dftCmds = getDefaultCompileCommands(); + if (dftCmds == null) return null; + return dftCmds.getCommand(commandName); + } + + /** + * Given a SystemCompileProfile, return the SystemProfile it is associated with + */ + private ISystemProfile getSystemProfile(SystemCompileProfile compProfile) { + //return currentProfile; + //SystemProfile[] systemProfiles = SystemStartHere.getSystemProfileManager().getActiveSystemProfiles(); THIS WAS THE BUG!! + ISystemProfile[] systemProfiles = SystemStartHere.getSystemProfileManager().getSystemProfiles(); + String profileName = compProfile.getProfileName(); + ISystemProfile currentProfile = null; + for (int idx = 0; (currentProfile == null) && (idx < systemProfiles.length); idx++) { + if (systemProfiles[idx].getName().equals(profileName)) currentProfile = systemProfiles[idx]; + } + return currentProfile; + /* + System.out.println("Searching for match on = " + compProfile.getProfileName()); + Enumeration keys = compileProfilesPerProfile.keys(); + System.out.println(":Keys exist? " + keys.hasMoreElements()); + SystemProfile match = null; + while ((match==null) && keys.hasMoreElements()) + { + SystemProfile key = (SystemProfile)keys.nextElement(); + SystemCompileProfile value = (SystemCompileProfile)compileProfilesPerProfile.get(key); + System.out.println("...key = " + key.getName()); + System.out.println("...value = " + value.getProfileName()); + if (value == compProfile) + match = key; + } + return match; + */ + } + + /** + * The compile manager and related classes is impacted by a profile rename, as we have + * some in-memory places to be updated. This method is called by the subsystem factory + * on a profile rename operation so we can update ourselves. + */ + public void profileRenamed(ISystemProfile profile, String oldName) { + if (compileProfilesPerProfile == null) return; + SystemCompileProfile cprofile = (SystemCompileProfile) compileProfilesPerProfile.get(profile); + if (cprofile != null) cprofile.setProfileName(profile.getName()); + } + + /** + * Return true if the given remote object is potentially compilable. This decides + * the existence of the Compile menu item. It is possible to enable/disable this if + * there is no current compile command... this is a more course grained decision. + *

+ * Our default implementation is to query the source type of the input object, + * and return true only if there is a source type defined for it in any of the + * currently active system profiles. + */ + public boolean isCompilable(Object selection) { + /* MJB: Hack to disable compilation on virtual files for now */ + if (selection instanceof IVirtualRemoteFile) return false; + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(selection); + if (rmtAdapter == null) return false; + String srcType = rmtAdapter.getRemoteSourceType(selection); + if (srcType == null) return false; + boolean compilable = false; + ISystemProfile[] activeProfiles = RSEUIPlugin.getTheSystemRegistry().getActiveSystemProfiles(); + for (int idx = 0; !compilable && (idx < activeProfiles.length); idx++) { + SystemCompileProfile compProfile = getCompileProfile(activeProfiles[idx]); + compProfile.addContributions(selection); + compilable = (compProfile.getCompileType(srcType) != null); + } + return compilable; + } + + /** + * Populate main context menu with a menu item for compile. + * Allows subclasses the opportunity to add compile actions for single and multiple selections. + *

+ * This is called by the addCommonRemoteObjectsActions method, if this subsystem + * supports compiles. + */ + public void addCompileActions(Shell shell, IStructuredSelection selection, SystemMenuManager menu, String menuGroup) { + if ((selection == null) || (selection.getFirstElement() == null)) { + return; + } + int size = selection.size(); + if (size == 1) { + addSingleSelectionCompileActions(shell, selection, menu, menuGroup); + } else if (size > 1) { + addMultipleSelectionCompileActions(shell, selection, menu, menuGroup); + } + } + + /** + * Adds compile actions for single selections. + * Populates main context menu with a "Compile->" submenu cascade, + * which will only be populated when the submenu is selected. + *

+ * This is called by the addCompileActions method for single selections. + * Subclasses may override. + */ + public void addSingleSelectionCompileActions(Shell shell, IStructuredSelection selection, SystemMenuManager menu, String menuGroup) { + SystemCascadingCompileAction promptAction = new SystemCascadingCompileAction(shell, true); + SystemCascadingCompileAction noPromptAction = new SystemCascadingCompileAction(shell, false); + menu.add(menuGroup, noPromptAction); + menu.add(menuGroup, promptAction); + } + + /** + * Adds compile actions for multiple selections. + * By default, does nothing. + * This is called by the addCompileActions method for multiple selections. + * Subclasses may override. + */ + public void addMultipleSelectionCompileActions(Shell shell, IStructuredSelection selection, SystemMenuManager menu, String menuGroup) { + SystemCompileMultipleSelectAction multiAction = new SystemCompileMultipleSelectAction(shell); + menu.add(menuGroup, multiAction); + } + + /** + * For support of the Work With Compile Commands dialog. + *

+ * Return the substitution variables supported by compile commands managed by this manager. + */ + public abstract SystemCmdSubstVarList getSubstitutionVariableList(); + + /** + * Return the substitutor for doing variable substitution. + *

+ * Override to return a class that implements ISystemCompileCommandSubstitutor, that knows how to + * substitute the variables found in getSubstitutionVariableList(). + */ + protected ISystemCompileCommandSubstitutor getSubstitutor() { + ISystemCompileCommandSubstitutor substor = (ISystemCompileCommandSubstitutor) compileSubstitutorsPerConnection.get(systemConnection); + if (substor == null) { + substor = createSubstitutor(systemConnection); + compileSubstitutorsPerConnection.put(systemConnection, substor); + } + return substor; + } + + /** + * Return the substitutor for doing variable substitution. + *

+ * Override to return a class that implements ISystemCompileCommandSubstitutor, that knows how to + * substitute the variables found in getSubstitutionVariableList(). + */ + protected abstract ISystemCompileCommandSubstitutor createSubstitutor(IHost connection); + + /** + * For support of the Work With Compile Commands dialog. + *

+ * Return our edit pane. Overriding this is an alternative to calling setEditPane. + * This is called in createContents + */ + public SystemCompileCommandEditPane getCompileCommandEditPane(Shell shell, ISystemCompileCommandEditPaneHoster hoster, boolean caseSensitive) { + return new SystemCompileCommandEditPane(this, shell, hoster, caseSensitive); + } + + /** + * For support of the Work With Compile Commands dialog. + *

+ * Return the dialog used to prompt for a new source type when "Add..." is pressed beside the + * source type combo. This returns an instance of the default SystemNewCompileSrcTypeDialog. + *

+ * One strategy for subclasses is to call super on this method, then configure the results via + * the setters in the default dialog. Another is to subclass that dialog and return an instance + * of the subclass. + */ + protected SystemNewCompileSrcTypeDialog getNewSrcTypeDialog(Shell shell, boolean caseSensitive) { + //System.out.println("test 1" + caseSensitive); + return new SystemNewCompileSrcTypeDialog(shell, this, caseSensitive); + } + + public String getSourceTypePromptMRILabel() { + return SystemUDAResources.RESID_WWCOMPCMDS_TYPES_LABEL; + } + + public String getSourceTypePromptMRITooltip() { + return SystemUDAResources.RESID_WWCOMPCMDS_TYPES_TOOLTIP; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileMultipleSelectAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileMultipleSelectAction.java new file mode 100644 index 00000000000..807a983cc0d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileMultipleSelectAction.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.internal.ui.view.SystemTableViewProvider; +import org.eclipse.rse.ui.GenericMessages; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.ui.view.ISystemEditableRemoteObject; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.ListSelectionDialog; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.WorkbenchContentProvider; + +public class SystemCompileMultipleSelectAction extends SystemBaseAction { + /** + * Constructor for multiple select compile action + */ + public SystemCompileMultipleSelectAction(Shell shell) { + super(UserActionsResources.ACTION_COMPILE_NOPROMPT_LABEL, UserActionsResources.ACTION_COMPILE_NOPROMPT_TOOLTIP, (ImageDescriptor) null, shell); + allowOnMultipleSelection(true); + setAccelerator(SWT.CTRL | SWT.SHIFT | 'c'); + } + + /** + * The default implementation runs the last used compile command for each selected resource. + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + if (checkDirtyEditors()) { + Object element = getFirstSelection(); + boolean ok = true; + while (ok && (element != null)) { + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(element); + /* FIXME - compile actions not coupled with subsystem API anymore + ISubSystem ss = rmtAdapter.getSubSystem(element); + ss.getParentSubSystemFactory().getCompileManager().setSystemConnection(ss.getHost()); + */ + String srcType = null; + srcType = rmtAdapter.getRemoteSourceType(element); + if (srcType == null) { + srcType = "null"; //$NON-NLS-1$ + } else if (srcType.equals("")) { //$NON-NLS-1$ + srcType = "blank"; //$NON-NLS-1$ + } + /* FIXME - compile actions not coupled with subsystem API anymore + ISubSystem subsystem = rmtAdapter.getSubSystem(element); + ISystemProfile profile = subsystem.getSystemProfile(); + + // get the compile profile + SystemCompileProfile compileProfile = subsystem.getParentSubSystemFactory().getCompileManager().getCompileProfile(profile); + + // add any contributions from compile extension points + // compileProfile.addContributions(element); + + // get the compile type for the current resource + SystemCompileType compType = (SystemCompileType)compileProfile.getCompileType(srcType); + + + // get the last used compile command for that type + SystemCompileCommand compileCmd = compType.getLastUsedCompileCommand(); + + SystemCompilableSource compilableSrc = compType.getParentProfile().getCompilableSourceObject(getShell(), element, compileCmd, false, viewer); + + ok = compilableSrc.runCompileCommand(); + */ + if (ok) { + element = getNextSelection(); + } + } + } + } + + protected List getDirtyEditors() { + IStructuredSelection sel = getSelection(); + List selection = sel.toList(); + List dirtyEditors = new ArrayList(); + for (int i = 0; i < selection.size(); i++) { + Object selected = selection.get(i); + if (selected instanceof IAdaptable) { + ISystemEditableRemoteObject editable = getEditableFor((IAdaptable) selected); + if (editable != null) { + try { + // is the file being edited? + if (editable.checkOpenInEditor() == 0) { + // reference the editing editor + editable.openEditor(); + // file is open in editor - prompt for save + if (editable.isDirty()) { + dirtyEditors.add(editable); + } + } + } catch (Exception e) { + } + } + } + } + return dirtyEditors; + } + + protected ISystemEditableRemoteObject getEditableFor(IAdaptable selected) { + ISystemRemoteElementAdapter adapter = (ISystemRemoteElementAdapter) selected.getAdapter(ISystemRemoteElementAdapter.class); + if (adapter.canEdit(selected)) { + ISystemEditableRemoteObject editable = adapter.getEditableRemoteObject(selected); + try { + editable.setLocalResourceProperties(); + } catch (Exception e) { + } + return editable; + } + return null; + } + + protected boolean checkDirtyEditors() { + List dirtyEditors = getDirtyEditors(); + if (dirtyEditors.size() > 0) { + AdaptableList input = new AdaptableList(); + for (int i = 0; i < dirtyEditors.size(); i++) { + ISystemEditableRemoteObject rmtObj = (ISystemEditableRemoteObject) dirtyEditors.get(i); + input.add(rmtObj.getRemoteObject()); + } + WorkbenchContentProvider cprovider = new WorkbenchContentProvider(); + SystemTableViewProvider lprovider = new SystemTableViewProvider(null); + // TODO: Cannot use WorkbenchMessages -- it's internal + ListSelectionDialog dlg = new ListSelectionDialog(getShell(), input, cprovider, lprovider, GenericMessages.EditorManager_saveResourcesMessage); + dlg.setInitialSelections(input.getChildren()); + // TODO: Cannot use WorkbenchMessages -- it's internal + dlg.setTitle(GenericMessages.EditorManager_saveResourcesTitle); + int result = dlg.open(); + //Just return false to prevent the operation continuing + if (result == IDialogConstants.CANCEL_ID) return false; + Object[] filesToSave = dlg.getResult(); + for (int s = 0; s < filesToSave.length; s++) { + IAdaptable rmtObj = (IAdaptable) filesToSave[s]; + ISystemEditableRemoteObject editable = getEditableFor(rmtObj); + editable.doImmediateSaveAndUpload(); + } + } + return true; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileProfile.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileProfile.java new file mode 100644 index 00000000000..d77fb92121a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileProfile.java @@ -0,0 +1,617 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.File; +import java.util.Iterator; +import java.util.Vector; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemResourceHelpers; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.swt.widgets.Shell; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +/** + * A SystemCompileProfile has a one-to-one correspondence with a SystemProfile. There is one + * for each profile, for each subsystem factory that supports compiles. + *

+ * The compile profile manages all aspects of the compile framework for this subsystem factory, + * for this system profile. Underneath, this basically means managing the xml file where the + * compile information is stored. + *

+ * At a high level, a SystemCompileProfile manages a list of {@link SystemCompileType} objects, + * of which there is one per compilable source type. Given a raw source type like ".cpp" there + * is a method {@link #getCompileType(String)} to return the SystemCompileType object for it. + * From that, one can get a list of compile commands registered for that type, and the + * last-used compile command for that type. + */ +public abstract class SystemCompileProfile implements ISystemCompileXMLConstants { + private SystemCompileManager parentManager; + //private SystemProfile systemProfile; + private String profileName; + private Vector compileTypes; + private String[] srcTypes; + private boolean isRead; + private Object associatedData; + + /** + * Constructor for SystemCompileProfile + * Will automatically read from disk. + * @param manager - the SystemCompileManager which instantiated this + * @param profileName - the name for this profile. + */ + public SystemCompileProfile(SystemCompileManager manager, String profileName) { + super(); + this.parentManager = manager; + this.profileName = profileName; + //this.systemProfile = profile; + doPreRead(); + readFromDisk(); + } + + // ----------------- + // PUBLIC METHODS... + // ----------------- + /** + * Reset the profile name, on a profile rename operation, say. + */ + public void setProfileName(String name) { + //System.out.println("Inside SystemCompileProfile#setProfileName. Old = " + profileName + ", New = " + name); + this.profileName = name; + } + + /** + * Set any data you want associated with this profile, while it is in memory + */ + public void setAssociatedData(Object data) { + this.associatedData = data; + } + + /** + * Get the associated data set via setAssociatedData + */ + public Object getAssociatedData() { + return associatedData; + } + + /** + * Return the name of this profile as given in the constructor + */ + public String getProfileName() { + return profileName; + } + + /** + * Return the system profile this is associated with + */ + public ISystemProfile getProfile() { + return RSEUIPlugin.getTheSystemRegistry().getSystemProfile(profileName); + } + + /** + * Return the SystemCompileManager responsible for this profile + */ + public SystemCompileManager getParentManager() { + return parentManager; + } + + /** + * Add a compile type + */ + public void addCompileType(SystemCompileType type) { + compileTypes.add(type); + flushCache(); + } + + /** + * Remote a compile type. + * Should only be called if the type is empty of compile commands + */ + public void removeCompileType(SystemCompileType type) { + compileTypes.remove(type); + flushCache(); + } + + /** + * Get compile types. + * @return a Vector of SystemCompileType objects. + */ + public Vector getCompileTypes() { + return compileTypes; + } + + /** + * Get compile types as an array of strings. + */ + public String[] getCompileTypesArray() { + if ((srcTypes == null) || (srcTypes.length != compileTypes.size())) { + srcTypes = new String[compileTypes.size()]; + for (int idx = 0; idx < srcTypes.length; idx++) + srcTypes[idx] = ((SystemCompileType) compileTypes.elementAt(idx)).getType(); + } + return srcTypes; + } + + /** + * Get the compile type, given a type + */ + public SystemCompileType getCompileType(String typeString) { + SystemCompileType compileType; + for (int i = 0; i < compileTypes.size(); i++) { + compileType = (SystemCompileType) (compileTypes.get(i)); + if (compileType.getType().equalsIgnoreCase(typeString)) return compileType; + } + return null; + } + + /** + * Save this profile to disk. It is saved to an xml file that is scoped + * to a folder named after the subsystem factory, and that in turn is + * scoped to a folder named "CompileCommands" within this system profile's + * folder. + */ + public void writeToDisk() { + write(compileTypes); + isRead = false; + } + + /** + * Should you require access to the IFolder containing the persisted xml + * file, call this method. Note, this folder is only created on first touch, + * so this call may have the side-effect of creating the folder. + *

+ * This defers back to the owning SystemCompileManager. + */ + public IFolder getCompileFolder() { + return parentManager.getCompileProfileFolder(this); + } + + /** + * Should you require access to the IFile handle to the persisted xml file, + * call this method. Note, this file is only created on first touch, + * so file may be a handle to something that doesn't exist yet. + */ + public IFile getCompileProfileFile() { + IFolder folder = getCompileFolder(); + IFile file = folder.getFile(getSaveFileName()); + return file; + } + + /** + * Should you require access to the java.io.File handle to the persisted xml file, + * call this method. Note, this file is only created on first touch, + * so file may be a handle to something that doesn't exist yet. + */ + public File getCompileProfileJavaFile() { + IFolder folder = getCompileFolder(); + IPath path = folder.getLocation().makeAbsolute(); + path = path.append(IPath.SEPARATOR + getSaveFileName()); + File file = new File(path.makeAbsolute().toOSString()); + return file; + } + + // ------------------- + // ABSTRACT METHODS... + // ------------------- + /** + * When the time comes to actually run a compile command against a selected source object, + * this method is called to return the instance of SystemCompilableSource to do that. + *

+ * This method must be implemented to return an instance of your subclass of SystemCompilableSource. + */ + public abstract SystemCompilableSource getCompilableSourceObject(Shell shell, Object selectedObject, SystemCompileCommand compileCmd, boolean isPrompt, Viewer viewer); + + // ----------------------------------- + // POTENTIALLY OVERRIDABLE METHODS... + // ----------------------------------- + /** + * Return the name of the xml file we will persist this profile's compile command + * information to. + * The default is "compile.xml" and need not be overridden unless you don't like that name :-). + */ + protected String getSaveFileName() { + return FILE_NAME; + } + + /** + * This method is called by the constructor, prior to reading the xml contents from disk. + * It is an exit point in case subclasses need to do anything before the read, such as rename + * or migrate legacy information. + */ + protected void doPreRead() { + } + + // ------------------- + // PRIVATE METHODS... + // ------------------- + /** + * Read all compile types associated with the profile from the disk + */ + private void readFromDisk() { + if (!isRead) { + compileTypes = read(); + isRead = true; + } + } + + /** + * Clear any cached info, as something has changed. + */ + private void flushCache() { + srcTypes = null; + } + + /** + * Read the XML file that holds all information about the + * types and associated compile names in this profile. + */ + private Vector read() { + Vector types = null; + File file = getCompileProfileJavaFile(); + // If the file does not exist, then write all IBM supplied default + // types and compile names first before reading + if (file == null || !file.exists()) { + if (parentManager.wantToPrimeWithDefaults(this)) // we only prime the user's private profile with default compile commands + { + if (!writeDefaults()) return new Vector(); + } else { + return new Vector(); + } + } + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(file); + types = getTypes(doc); + } catch (Exception e) { + SystemBasePlugin.logError("Error reading compile names XML file for profile " + getProfileName(), e); //$NON-NLS-1$ + } + return types; + } + + /** + * Get all the compile types. + * @return a vector of SystemCompileType objects. + */ + private Vector getTypes(Document doc) { + Vector types = new Vector(); + Element root = doc.getDocumentElement(); + String oldvrm = root.getAttribute(VERSION_ATTRIBUTE); + boolean oldversion = (oldvrm != null) && !oldvrm.equals(VERSION_VALUE); + NodeList list = doc.getElementsByTagName(TYPE_ELEMENT); + if (list == null) return types; + for (int i = 0; i < list.getLength(); i++) { + Node node = list.item(i); + NamedNodeMap map = node.getAttributes(); + // get the type + Node typeAttr = map.getNamedItem(TYPE_ATTRIBUTE); + String type = typeAttr.getNodeValue(); + // get the label of the last compile name + Node lastUsedAttr = map.getNamedItem(LASTUSED_ATTRIBUTE); + String lastUsed = lastUsedAttr.getNodeValue(); + SystemCompileType newType = new SystemCompileType(this, type); + NodeList childList = node.getChildNodes(); + for (int j = 0; j < childList.getLength(); j++) { + Node child = childList.item(j); + NamedNodeMap childAttrMap = child.getAttributes(); + // get the name of the compile name + Node nameAttr = childAttrMap.getNamedItem(LABEL_ATTRIBUTE); + String name = nameAttr.getNodeValue(); + // get the nature of the compile name + Node natureAttr = childAttrMap.getNamedItem(NATURE_ATTRIBUTE); + String nature = natureAttr.getNodeValue(); + // get the default command string + Node defaultAttr = childAttrMap.getNamedItem(DEFAULT_ATTRIBUTE); + String defaultString = (defaultAttr != null) ? defaultAttr.getNodeValue() : ""; //$NON-NLS-1$ + // get the current string + Node currentAttr = childAttrMap.getNamedItem(CURRENT_ATTRIBUTE); + String currentString = currentAttr.getNodeValue(); + // get the menu option + Node menuAttr = childAttrMap.getNamedItem(MENU_ATTRIBUTE); + String menuOption = menuAttr.getNodeValue(); + // get the jobenv option + Node jobenvAttr = childAttrMap.getNamedItem(JOBENV_ATTRIBUTE); + String jobEnv = null; + if (jobenvAttr != null) jobEnv = jobenvAttr.getNodeValue(); + // get the ordering + int order = j; + Node orderAttr = childAttrMap.getNamedItem(ORDER_ATTRIBUTE); + // to ensure previous beta customers do not have problems + if (orderAttr != null) { + order = Integer.valueOf(orderAttr.getNodeValue()).intValue(); + } + // get the id option + Node idAttr = childAttrMap.getNamedItem(ID_ATTRIBUTE); + String id = null; + if (idAttr != null) { + id = idAttr.getNodeValue(); + } + // get the label editable option + Node labelEditableAttr = childAttrMap.getNamedItem(LABEL_EDITABLE_ATTRIBUTE); + String labelEditable = null; + if (labelEditableAttr != null) { + labelEditable = labelEditableAttr.getNodeValue(); + } + // get the label editable option + Node stringEditableAttr = childAttrMap.getNamedItem(STRING_EDITABLE_ATTRIBUTE); + String stringEditable = null; + if (stringEditableAttr != null) { + stringEditable = stringEditableAttr.getNodeValue(); + } + // id can be null, in which case the contructor will try to configure the id automatically + // so no need to check for id == null here + SystemCompileCommand newCmd = new SystemCompileCommand(newType, id, name, nature, defaultString, currentString, menuOption, order); + // if label editable is null, i.e. attribute did not exist, then don't do anything + // because the command is either IBM supplied or user supplied, and the constructor will take + // care of it. We only care if the attribute is not null. + if (labelEditable != null) { + boolean isLabelEditable = Boolean.valueOf(labelEditable).booleanValue(); + newCmd.setLabelEditable(isLabelEditable); + } + // if string editable is null, i.e. attribute did not exist, then don't do anything + // because the command is either IBM supplied or user supplied, and the constructor will take + // care of it. We only care if the attribute is not null. + if (stringEditable != null) { + boolean isStringEditable = Boolean.valueOf(stringEditable).booleanValue(); + newCmd.setCommandStringEditable(isStringEditable); + } + if (jobEnv != null) newCmd.setJobEnvironment(jobEnv); + if (name.equalsIgnoreCase(lastUsed)) newType.setLastUsedCompileCommand(newCmd); + if (oldversion) newCmd = migrateCompileCommand(newCmd, oldvrm); + newType.addCompileCommandInOrder(newCmd); + } + // add compile type and all its contents to the types list + types.add(newType); + } + // if we currently have an older version on disk, we may have added new default types and associated + // default compile commands for this release. so find out what new default source types we have + // in this release, and add them to list of types in memory. + // We only want to add these new default types to the default private profile. + // Warning:: this will not handle the case where we want to change a default compile command for + // an existing type with a new release. Need to modify the code below for that. + if (parentManager.wantToPrimeWithDefaults(this) && oldversion) { + SystemDefaultCompileCommands allCmds = parentManager.getDefaultCompileCommands(); + if (allCmds == null) { + return types; + } + // get all default types + String[] defaultTypes = allCmds.getAllDefaultSuppliedSourceTypes(); + // for each default type, find out if we already have it in memory, i.e. + // it exists from a previous release and so is not new. + for (int i = 0; i < defaultTypes.length; i++) { + boolean typeFound = false; + Iterator iter = types.iterator(); + // iterate over all types in memory + while (iter.hasNext()) { + SystemCompileType tempType = (SystemCompileType) iter.next(); + // if the types match, we know this type is not new + if (tempType.getType().equalsIgnoreCase(defaultTypes[i])) { + typeFound = true; + break; + } + } + // type wasn't found in memory, so this is a new default type which we need to add + // also need to add the default commands for that source type + if (!typeFound) { + SystemCompileType type = new SystemCompileType(this, defaultTypes[i]); + SystemDefaultCompileCommand[] defaultCmds = allCmds.getCommandsForSrcType(defaultTypes[i]); + if ((defaultCmds == null) || (defaultCmds.length == 0)) { + types.add(type); + continue; + } + SystemCompileCommand[] cmds = new SystemCompileCommand[defaultCmds.length]; + for (int j = 0; j < defaultCmds.length; j++) { + String cmdName = defaultCmds[j].getLabel(); + String commandString = defaultCmds[j].getCommandWithParameters(); + // we can pass in null for the id, because the constructor checks if id is null + // and if so tries to configure id automatically. This will work for IBM supplied commands. + cmds[j] = new SystemCompileCommand(type, null, cmdName, NATURE_IBM_VALUE, commandString, commandString, MENU_BOTH_VALUE, j); + type.addCompileCommandInOrder(cmds[j]); + String jobEnv = defaultCmds[j].getJobEnvironment(); + if (jobEnv != null) { + cmds[j].setJobEnvironment(jobEnv); + } + if (j == 0) { + type.setLastUsedCompileCommand(cmds[j]); + } + } + types.add(type); + } + } + } + return types; + } + + /** + * + * Add compile contributions made through extension points for the given resource, + * and save them to disk. + */ + public void addContributions(Object element) { + // we only add contributions to the default private profile + // Should we update existing labels in other profiles, e.g. a user may have copied a contributed + // label to another profile? This won't change those labels, only the label in the default private profile. + if (parentManager.wantToPrimeWithDefaults(this)) { + SystemCompileContributorManager.getInstance().contributeCompileCommands(this, element); + } + // write the contributions to disk + // writeToDisk(); + } + + /** + * Opportunity for subclasses to do migration of compile commands read from disk, + * from a document that has an older vrm than the current vrm. + */ + protected SystemCompileCommand migrateCompileCommand(SystemCompileCommand oldCmd, String oldVrm) { + return oldCmd; + } + + /** + * Do substring substitution. Using you are replacing &1 (say) with + * another string. + * @param string - string containing substring to be substituted. + * @param subOld - substitution variable. Eg "%1" + * @param subNew - substitution data. Eg "001" + * @return string with all occurrences of subOld substituted with subNew. + */ + protected String sub(String string, String subOld, String subNew) { + if (string == null) return string; + StringBuffer temp = new StringBuffer(); + int lastHit = 0; + int newHit = 0; + for (newHit = string.indexOf(subOld, lastHit); newHit != -1; lastHit = newHit, newHit = string.indexOf(subOld, lastHit)) { + if (newHit >= 0) temp.append(string.substring(lastHit, newHit)); + temp.append(subNew); + newHit += subOld.length(); + } + if (lastHit >= 0) temp.append(string.substring(lastHit)); + return temp.toString(); + } + + /** + * Write the contents of the file, given the contents as a Vector of SystemCompileType objects. + */ + private void write(Vector types) { + File file = getCompileProfileJavaFile(); + try { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + Document doc = builder.getDOMImplementation().createDocument(null, ROOT_ELEMENT, null); + // get root element and set attributes + Element root = doc.getDocumentElement(); + root.setAttribute(VERSION_ATTRIBUTE, VERSION_VALUE); + // write the copyright info + Element copyright = doc.createElement(COPYRIGHT_ELEMENT); + Text copyrightText = doc.createTextNode(COPYRIGHT_TEXT); + copyright.appendChild(copyrightText); + root.appendChild(copyright); + // write type and compile commands for each + for (int i = 0; i < types.size(); i++) { + SystemCompileType type = (SystemCompileType) (types.get(i)); + Element typeElement = doc.createElement(TYPE_ELEMENT); + typeElement.setAttribute(TYPE_ATTRIBUTE, type.getType()); + SystemCompileCommand lastUsedCompileName = type.getLastUsedCompileCommand(); + String lastUsedName = null; + if (lastUsedCompileName == null) { + lastUsedName = ""; //$NON-NLS-1$ + } else { + lastUsedName = lastUsedCompileName.getLabel(); + } + typeElement.setAttribute(LASTUSED_ATTRIBUTE, lastUsedName); + Vector cmds = type.getCompileCommands(); + for (int j = 0; j < cmds.size(); j++) { + SystemCompileCommand cmd = (SystemCompileCommand) (cmds.get(j)); + Element cmdElement = doc.createElement(COMPILECOMMAND_ELEMENT); + if (cmd.getId() != null) { + cmdElement.setAttribute(ID_ATTRIBUTE, cmd.getId()); + } + cmdElement.setAttribute(LABEL_ATTRIBUTE, cmd.getLabel()); + cmdElement.setAttribute(NATURE_ATTRIBUTE, cmd.getNature()); + cmdElement.setAttribute(DEFAULT_ATTRIBUTE, cmd.getDefaultString()); + cmdElement.setAttribute(CURRENT_ATTRIBUTE, cmd.getCurrentString()); + cmdElement.setAttribute(MENU_ATTRIBUTE, cmd.getMenuOption()); + cmdElement.setAttribute(ORDER_ATTRIBUTE, String.valueOf(j)); + cmdElement.setAttribute(LABEL_EDITABLE_ATTRIBUTE, String.valueOf(cmd.isLabelEditable())); + cmdElement.setAttribute(STRING_EDITABLE_ATTRIBUTE, String.valueOf(cmd.isCommandStringEditable())); + if (cmd.getJobEnvironment() != null) { + cmdElement.setAttribute(JOBENV_ATTRIBUTE, cmd.getJobEnvironment()); + } + typeElement.appendChild(cmdElement); + } + root.appendChild(typeElement); + } + // write out document to XML file + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource input = new DOMSource(doc); + Result output = new StreamResult(file); + transformer.transform(input, output); + // now refresh the eclipse workspace model for the parent folder, to recognize changes we made + SystemResourceHelpers.getResourceHelpers().refreshResource(getCompileFolder()); + } catch (Exception e) { + SystemBasePlugin.logError("Error writing compile names xml file for profile " + getProfileName(), e); //$NON-NLS-1$ + } + } + + /** + * Prime document with default (supplied) types and names. + * Return true if any written, false if none to write. + */ + private boolean writeDefaults() { + SystemDefaultCompileCommands allCmds = parentManager.getDefaultCompileCommands(); + if (allCmds == null) return false; + String[] defaultTypes = allCmds.getAllDefaultSuppliedSourceTypes(); + Vector types = new Vector(); + for (int i = 0; i < defaultTypes.length; i++) { + SystemCompileType type = new SystemCompileType(this, defaultTypes[i]); + SystemDefaultCompileCommand[] defaultCmds = allCmds.getCommandsForSrcType(defaultTypes[i]); + if ((defaultCmds == null) || (defaultCmds.length == 0)) { + types.add(type); + continue; + } + SystemCompileCommand[] cmds = new SystemCompileCommand[defaultCmds.length]; + for (int j = 0; j < defaultCmds.length; j++) { + String cmdName = defaultCmds[j].getLabel(); + String commandString = defaultCmds[j].getCommandWithParameters(); + // we can pass in null for the id, because the constructor checks if id is null + // and if so tries to configure id automatically. This will work for IBM supplied commands. + cmds[j] = new SystemCompileCommand(type, null, cmdName, NATURE_IBM_VALUE, commandString, commandString, MENU_BOTH_VALUE, j); + type.addCompileCommandInOrder(cmds[j]); + String jobEnv = defaultCmds[j].getJobEnvironment(); + if (jobEnv != null) cmds[j].setJobEnvironment(jobEnv); + if (j == 0) { + type.setLastUsedCompileCommand(cmds[j]); + } + } + types.add(type); + } + write(types); + //printCommandsByType(types); // temporary, for debugging + return (defaultTypes.length > 0); + } + + /** + * Print the commands to standard out, sorted by source type, for debugging purposes + */ + public void printCommandsByType(Vector compileTypes) { + System.out.println(); + System.out.println("Compile commands"); //$NON-NLS-1$ + System.out.println("-----------------"); //$NON-NLS-1$ + for (int idx = 0; idx < compileTypes.size(); idx++) { + SystemCompileType type = (SystemCompileType) compileTypes.elementAt(idx); + System.out.println("Type: " + type.getType()); //$NON-NLS-1$ + for (int jdx = 0; jdx < type.getNumOfCommands(); jdx++) { + SystemCompileCommand cmd = type.getCompileCommand(jdx); + cmd.printCommand(" "); //$NON-NLS-1$ + } + } + System.out.println(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileRemoteObjectMatcher.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileRemoteObjectMatcher.java new file mode 100644 index 00000000000..eb0186d5267 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileRemoteObjectMatcher.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile; + +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; + +public class SystemCompileRemoteObjectMatcher { + private String ssfId, nameFilter, typeFilter; + private boolean allSsfs, allNames, allTypes; + private boolean genericSsfStart, genericNamesStart, genericTypesStart; + private boolean genericSsfEnd, genericNamesEnd, genericTypesEnd; + private String ssfIdPart, nameFilterPart, typeFilterPart; + + public SystemCompileRemoteObjectMatcher(String ssfId, String nameFilter, String typeFilter) { + this.ssfId = ssfId; + this.nameFilter = nameFilter; + this.typeFilter = typeFilter; + if (ssfId == null) { + ssfId = "*"; //$NON-NLS-1$ + } + if (nameFilter == null) { + nameFilter = "*"; //$NON-NLS-1$ + } + if (typeFilter == null) { + typeFilter = "*"; //$NON-NLS-1$ + } + // determine if any attribute is totally generic + this.allSsfs = ssfId.equals("*"); //$NON-NLS-1$ + this.allNames = nameFilter.equals("*"); //$NON-NLS-1$ + this.allTypes = typeFilter.equals("*"); //$NON-NLS-1$ + // determine if any attribute value starts with asterisk + this.genericSsfStart = !allSsfs && startsWithAsterisk(ssfId); + this.genericNamesStart = !allNames && startsWithAsterisk(nameFilter); + this.genericTypesStart = !allTypes && startsWithAsterisk(typeFilter); + // determine if any attribute value ends with asterisk + this.genericSsfEnd = !allSsfs && endsWithAsterisk(ssfId); + this.genericNamesEnd = !allNames && endsWithAsterisk(nameFilter); + this.genericTypesEnd = !allTypes && endsWithAsterisk(typeFilter); + // strip of leading asterisk if there is one + if (genericSsfStart) { + ssfIdPart = stripLeadingAsterisk(ssfId); + } + if (genericNamesStart) { + nameFilterPart = stripLeadingAsterisk(nameFilter); + } + if (genericTypesStart) { + typeFilterPart = stripLeadingAsterisk(typeFilter); + } + // strip of trailing asterisk if there is one + if (genericSsfEnd) { + ssfIdPart = stripTrailingAsterisk(ssfId); + } + if (genericNamesEnd) { + nameFilterPart = stripTrailingAsterisk(nameFilter); + } + if (genericTypesEnd) { + typeFilterPart = stripTrailingAsterisk(typeFilter); + } + } + + /** + * Helper method. + * Returns true if given name starts with an asterisk. + */ + protected boolean startsWithAsterisk(String name) { + return name.startsWith("*"); //$NON-NLS-1$ + } + + /** + * Helper method. + * Returns true if given name ends with an asterisk. + */ + protected boolean endsWithAsterisk(String name) { + return name.endsWith("*"); //$NON-NLS-1$ + } + + /** + * Helper method. + * Strips off the leading asterisk. + */ + protected String stripLeadingAsterisk(String name) { + return name.substring(1); + } + + /** + * Helper method. + * Strips off the trailing asterisk. + */ + protected String stripTrailingAsterisk(String name) { + return name.substring(0, name.length() - 1); + } + + /** + * Getter method. + * Return what was specified for the subsystemconfigurationid xml attribute. + */ + public String getSubSystemFactoryId() { + return ssfId; + } + + /** + * Getter method. + * Return what was specified for the namefilter xml attribute. + */ + public String getNameFilter() { + return nameFilter; + } + + /** + * Getter method. + * Return what was specified for the typefilter xml attribute. + */ + public String getTypeFilter() { + return typeFilter; + } + + /** + * Returns true if the current selection matches all the given filtering criteria, false otherwise. + */ + public boolean appliesTo(Object element) { + ISystemRemoteElementAdapter adapter = SystemAdapterHelpers.getRemoteAdapter(element); + if (adapter == null) { + return false; + } + boolean applies = true; + // must match on all attributes + // check for match on subsystem factory id + boolean ssfIdMatch = true; + if (!allSsfs) { + String subsystem = adapter.getSubSystemConfigurationId(element); + if (ssfId == null) { + ssfIdMatch = false; + } else if (!genericSsfStart && !genericSsfEnd) { + ssfIdMatch = subsystem.equals(ssfId); + } else if (genericSsfStart) { + ssfIdMatch = subsystem.endsWith(ssfIdPart); + } else if (genericSsfEnd) { + ssfIdMatch = subsystem.startsWith(ssfIdPart); + } + } + if (!ssfIdMatch) { + return false; + } + // check for match on name filter + boolean nameMatch = true; + if (!allNames) { + String name = adapter.getName(element); + if (name == null || !genericNamesStart) { + nameMatch = false; + } else if (!genericNamesStart && !genericNamesEnd) { + nameMatch = name.equals(nameFilter); + } else if (genericNamesStart) { + nameMatch = name.endsWith(nameFilterPart); + } else if (genericNamesEnd) { + nameMatch = name.startsWith(nameFilterPart); + } + } + if (!nameMatch) { + return false; + } + // check for match on type filter + boolean typeMatch = true; + if (!allTypes) { + String type = adapter.getRemoteSourceType(element); + if (type == null) { + typeMatch = false; + } else if (!genericTypesStart && !genericTypesEnd) { + typeMatch = type.equals(typeFilter); + } else if (genericTypesStart) { + typeMatch = type.endsWith(typeFilterPart); + } else if (genericTypesEnd) { + typeMatch = type.startsWith(typeFilterPart); + } + } + if (!typeMatch) { + return false; + } + return applies; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileType.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileType.java new file mode 100644 index 00000000000..2ec9feadd5c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemCompileType.java @@ -0,0 +1,348 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; + +/** + * A SystemCompileType is effectively an index that maps a compilable source type (like ".cpp") to a + * list of SystemCompileCommand objects that represent the commands that are registered against that source + * type. It also remembers the last-used such compile command. + *

+ * There is a one-to-one relationship between a source type like (".cpp") and a SystemCompileType... for + * each compilable source type there will be one SystemCompileType object. It is a list of these that is + * effectively persisted to disk via an xml file, one file per system profile. This is what the SystemCompileProfile + * class manages ... a list of SystemCompileProfile objects. + */ +public class SystemCompileType implements IAdaptable { + private SystemCompileProfile profile; + private String type; + private SystemCompileCommand lastUsedCompileCommand; + private Vector commands = new Vector(); + + /** + * Constructor for SystemCompileType when the source type isn't known yet. + * @see #setType(String) + */ + public SystemCompileType(SystemCompileProfile profile) { + super(); + setParentProfile(profile); + } + + /** + * Constructor for SystemCompileType when you know the source type it represents. + */ + public SystemCompileType(SystemCompileProfile profile, String type) { + super(); + setParentProfile(profile); + setType(type); + } + + /** + * Constructor for SystemCompileType when you know the source type and last used command + */ + public SystemCompileType(SystemCompileProfile profile, String type, SystemCompileCommand lastUsedCompileCmd) { + super(); + setParentProfile(profile); + setType(type); + setLastUsedCompileCommand(lastUsedCompileCmd); + } + + /** + * Set the parent SystemCompileProfile profile + * @param profile the parent profile + */ + public void setParentProfile(SystemCompileProfile profile) { + this.profile = profile; + } + + /** + * Get the parent SystemCompileProfile profile + * @return the parent profile + */ + public SystemCompileProfile getParentProfile() { + return profile; + } + + /** + * Set the source type value this represents. This is typically a file type like "cpp". + * @param type the type + */ + public void setType(String type) { + //this.type = type.toUpperCase(); defect 46282 + this.type = type; + } + + /** + * Get the source type value this represents. This is typically a file type like "cpp". + * @return the type + */ + public String getType() { + return type; + } + + /** + * Set the last used compile command + * @param lastUsedCompileCommand the last used compile command + */ + public void setLastUsedCompileCommand(SystemCompileCommand lastUsedCompileCommand) { + this.lastUsedCompileCommand = lastUsedCompileCommand; + } + + /** + * Get the last used compile command + */ + public SystemCompileCommand getLastUsedCompileCommand() { + return lastUsedCompileCommand; + } + + /** + * Add a compile command at the end. + * @param command a compile command object + */ + public void addCompileCommand(SystemCompileCommand command) { + flushCache(); + commands.add(command); + } + + /** + * Add a compile command, into its appropriate order as per its getOrder() value. + * @param compileCommand a compile command object + */ + public void addCompileCommandInOrder(SystemCompileCommand compileCommand) { + flushCache(); + if (commands.size() == 0) { + commands.add(compileCommand); + return; + } + int order = compileCommand.getOrder(); + SystemCompileCommand cmd = null; + for (int i = 0; i < commands.size(); i++) { + cmd = (SystemCompileCommand) (commands.get(i)); + if (order < cmd.getOrder()) { + commands.insertElementAt(compileCommand, i); + return; + } + } + // reached the end, so just add + commands.add(compileCommand); + } + + /** + * Remove a compile command give its reference + * @param cmd the compile command to remove + */ + public void removeCompileCommand(SystemCompileCommand cmd) { + flushCache(); + SystemCompileCommand compileCmd; + for (int i = 0; i < commands.size(); i++) { + compileCmd = (SystemCompileCommand) (commands.get(i)); + if (compileCmd == cmd) { + commands.remove(i); + return; + } + } + } + + /** + * Remove a compile command given its index + * @param index the zero-based index of the compile command to remove + */ + public SystemCompileCommand removeCompileCommand(int index) { + flushCache(); + return (SystemCompileCommand) (commands.remove(index)); + } + + /** + * Insert a compile command at the given index + * @param compileName a compile command + * @param index the zero-based index to insert it at + */ + public void insertCompileCommand(SystemCompileCommand compileName, int index) { + commands.insertElementAt(compileName, index); + flushCache(); + } + + /** + * Get all compile commands associated with this type + * @return a Vector of SystemCompileCommand objects + */ + public Vector getCompileCommands() { + return commands; + } + + /** + * Get all compile commands associated with this type, as an array. + * @return an array of SystemCompileCommand objects + */ + public SystemCompileCommand[] getCompileCommandsArray() { + SystemCompileCommand[] cmds = new SystemCompileCommand[commands.size()]; + for (int idx = 0; idx < cmds.length; idx++) + cmds[idx] = (SystemCompileCommand) commands.elementAt(idx); + return cmds; + } + + /** + * Get the number of compile commands associated with this type + */ + public int getNumOfCommands() { + return commands.size(); + } + + /** + * Get all promptable compile commands associated with this type + * @return a vector of all promptable compile commands ... that is, SystemCompileCommand objecs + */ + public Vector getPromptableCompileCommands() { + Vector promptableCmds = new Vector(); + SystemCompileCommand compileCmd = null; + for (int i = 0; i < commands.size(); i++) { + compileCmd = (SystemCompileCommand) (commands.get(i)); + if (compileCmd.isPromptable()) promptableCmds.add(compileCmd); + } + return promptableCmds; + } + + /** + * Get all non-promptable compile commands associated with this type + * @return a vector of all non-promptable compile commands ... that is, SystemCompileCommand objecs + */ + public Vector getNonPromptableCompileCommands() { + Vector nonPromptableCmds = new Vector(); + SystemCompileCommand compileCmd = null; + for (int i = 0; i < commands.size(); i++) { + compileCmd = (SystemCompileCommand) (commands.get(i)); + if (compileCmd.isNonPromptable()) nonPromptableCmds.add(compileCmd); + } + return nonPromptableCmds; + } + + /** + * Get the compile command, given its label + */ + public SystemCompileCommand getCompileLabel(String label) { + SystemCompileCommand compileCmd = null; + for (int i = 0; i < commands.size(); i++) { + compileCmd = (SystemCompileCommand) (commands.get(i)); + if (compileCmd.getLabel().equalsIgnoreCase(label)) { + return compileCmd; + } + } + return null; + } + + /** + * Get compile commands, given the id. Note that compile commands with the same + * id might exist for a compile type. This is possible if a user copies a compile + * command in the Work With dialog, and pastes it in the same type. We only + * require the label to be changed, but the id remains the same. + * @return a vector of compile commands that have the given id. + */ + public Vector getCompileId(String id) { + Vector list = new Vector(); + SystemCompileCommand compileCmd = null; + for (int i = 0; i < commands.size(); i++) { + compileCmd = (SystemCompileCommand) (commands.get(i)); + if (compileCmd.getId().equalsIgnoreCase(id)) { + list.add(compileCmd); + } + } + return list; + } + + /** + * Find out if a given compile label already exists + */ + public boolean isIdExists(String id) { + SystemCompileCommand compileCmd = null; + for (int idx = 0; idx < commands.size(); idx++) { + compileCmd = (SystemCompileCommand) (commands.get(idx)); + if (compileCmd.getId().equalsIgnoreCase(id)) { + return true; + } + } + return false; + } + + /** + * Get the compile command, given its index + */ + public SystemCompileCommand getCompileCommand(int index) { + return (SystemCompileCommand) (commands.get(index)); + } + + /** + * Find out if a given compile label already exists + */ + public boolean isLabelExists(String nameString) { + SystemCompileCommand compileCmd = null; + for (int idx = 0; idx < commands.size(); idx++) { + compileCmd = (SystemCompileCommand) (commands.get(idx)); + if (compileCmd.getLabel().equalsIgnoreCase(nameString)) return true; + } + return false; + } + + /** + * Find out if a compile label with the same name already exists. + * Checks if it exists twice or more, since the first is assumed to + * be the current one being edited. + */ + public boolean isDuplicateLabelExists(String nameString) { + SystemCompileCommand compileCmd = null; + boolean once = false; + // has to match twice for us to know that there is a duplicate + for (int idx = 0; idx < commands.size(); idx++) { + compileCmd = (SystemCompileCommand) (commands.get(idx)); + if (compileCmd.getLabel().equalsIgnoreCase(nameString)) { + if (!once) + once = true; + else + return true; + } + } + return false; + } + + /** + * Return a vector of Strings representing the labels for all the compile commands + * within this type. This is typically for uniqueness checking. + */ + public Vector getExistingLabels() { + Vector labels = new Vector(); + for (int idx = 0; idx < commands.size(); idx++) + labels.add(((SystemCompileCommand) commands.get(idx)).getLabel()); + return labels; + } + + /** + * Return this object as a string. + */ + public String toString() { + return getType(); + } + + /** + * This is the method required by the IAdaptable interface. + * Given an adapter class type, return an object castable to the type, or + * null if this is not possible. + */ + public Object getAdapter(Class adapterType) { + return Platform.getAdapterManager().getAdapter(this, adapterType); + } + + // PRIVATE METHODS + private void flushCache() { + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommand.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommand.java new file mode 100644 index 00000000000..0ece50a16db --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommand.java @@ -0,0 +1,214 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.StringTokenizer; + +/** + * This class encapsulates, for a particular compile command, the + * important information for that command including: + *

    + *
  • The label of the command... which is what the user sees in the compile menu + *
  • The name of the command... without parameters. + *
  • The default command string with the minimum parameters we need to compile with this command, using substitution variables. + *
+ */ +public class SystemDefaultCompileCommand { + // instance variables + protected String name, label, jobEnv; + protected String addlParms; + protected String[] srcTypes; + + /** + * Constructor that takes a command name and label. + * You must call setAdditionalCommandParameters after this. + */ + public SystemDefaultCompileCommand(String commandLabel, String commandName) { + super(); + this.name = commandName; + this.label = commandLabel; + } + + /** + * Constructor that just takes a command name and defaults the label to it. + * You must call setAdditionalCommandParameters after this. + */ + public SystemDefaultCompileCommand(String commandName) { + this(commandName, commandName); + } + + /** + * Constructor that takes a command name and label and the parameters. + * This avoids you having to call setAdditionalCommandParameters. + */ + public SystemDefaultCompileCommand(String commandLabel, String commandName, String parameters) { + this(commandLabel, commandName); + setAdditionalParameters(parameters); + } + + /** + * Set additional minimum parameters not specified via the constructor. Will be appended to the + * command string in the methods getMinimumCommandWithParameters and getFullCommandWithParameters. + *

+ * Don't worry about a leading blank. + */ + public void setAdditionalParameters(String parms) { + this.addlParms = " " + parms; //$NON-NLS-1$ + } + + /** + * Set the source type this applies to, when there is only one + */ + public void setSourceType(String type) { + setSourceTypes(new String[] { type }); + } + + /** + * Set the source types this applies to + */ + public void setSourceTypes(String[] types) { + this.srcTypes = types; + } + + /** + * Get the source types this applies to + */ + public String[] getSourceTypes() { + return srcTypes; + } + + /** + * Return true if this command applies to the given source type + */ + public boolean appliesToSourceType(String type) { + if (srcTypes == null) + return false; + else { + boolean match = false; + for (int idx = 0; !match && (idx < srcTypes.length); idx++) { + if (type.equals(srcTypes[idx])) match = true; + } + return match; + } + } + + /** + * Return the command label + */ + public String getLabel() { + return label; + } + + /** + * Return the command name, without parameters + */ + public String getName() { + return name; + } + + /** + * Return command fully populated with default parameters and substitution variables + */ + public String getCommandWithParameters() { + return getCommandWithParameters(null); + } + + /** + * Set the job environment. Some systems support multiple command systems, and this attribute + * is needed to identify which system this should run in. + */ + public void setJobEnvironment(String jobEnv) { + this.jobEnv = jobEnv; + } + + /** + * Return the job environment. This is not often used, but sometimes needed for systems + * that support multiple command systems. + */ + public String getJobEnvironment() { + return jobEnv; + } + + /** + * Given user-specified command paramaters (minus the cmd name), + * verify it has all the minimum parameters we defined for this command. + * For any that are missing, add them... + */ + public String fillWithRequiredParams(String commandParams) { + if ((commandParams == null) || (commandParams.length() == 0)) + return getCommandWithParameters(); + else + return getCommandWithParameters(commandParams); + } + + /** + * Print the command lable to standard out, for debugging purposes + */ + public void printCommandLabel() { + System.out.println(label); + } + + /** + * Print the command name to standard out, for debugging purposes + */ + public void printCommandName() { + System.out.println(name); + } + + /** + * Print the full command string to standard out, for debugging purposes + */ + public void printCommand() { + System.out.println(getCommandWithParameters()); + } + + // ------------------- + // PRIVATE METHODS... + // ------------------- + /** + * Private implementation that supports two modes: + * - append all required parameters + * - append only those required parameters that do not already exist + *

+ * Typically not overridden. Rather populateWithParameters is overridden, which this calls. + */ + protected String getCommandWithParameters(String existingParameters) { + StringBuffer buffer = null; + if (existingParameters == null) + buffer = new StringBuffer(name); + else + buffer = new StringBuffer(name + " " + existingParameters); //$NON-NLS-1$ + populateWithParameters(buffer); + if (addlParms != null) { + if (existingParameters == null) + buffer.append(" " + addlParms); //$NON-NLS-1$ + else { + // we have to look at each additional parameter and determine if it has been specified in + // given parameter string or not. If not, we add that additional parameter. + StringTokenizer tokens = new StringTokenizer(addlParms); + while (tokens.hasMoreTokens()) { + String parm = tokens.nextToken(); + String parmName = parm.substring(0, parm.indexOf('(') + 1); // "PARM(" + if (existingParameters.indexOf(parmName) == -1) buffer.append(" " + parm); //$NON-NLS-1$ + } + } + } + return buffer.toString(); + } + + /** + * Overridable method that will append required parameters to the command string. + * These are any not already specified via additional parameters + */ + protected void populateWithParameters(StringBuffer bufferSoFar) { + return; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommands.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommands.java new file mode 100644 index 00000000000..f619d819d58 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemDefaultCompileCommands.java @@ -0,0 +1,196 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +/** + * This class manages a list of compile commands. + */ +public abstract class SystemDefaultCompileCommands { + // instance variables + private Vector commands = new Vector(); + private SystemDefaultCompileCommand[] array; + private String[] nameArray, stringArray; + + /** + * Constructor for ISeriesCompileCommands. + */ + public SystemDefaultCompileCommands() { + super(); + } + + /** + * Return all pre-defined compilable source types. Eg, for a typical file system, this + * would be file extensions, like ".c", ".cpp",etc. + */ + public abstract String[] getAllDefaultSuppliedSourceTypes(); + + /** + * Get the compile command at the given index + */ + public SystemDefaultCompileCommand getCommand(int idx) { + return (SystemDefaultCompileCommand) commands.elementAt(idx); + } + + /** + * Get the compile command the corresponds to the given command name. + * Will return null if none found. + */ + public SystemDefaultCompileCommand getCommand(String commandName) { + SystemDefaultCompileCommand match = null; + for (int idx = 0; (match == null) && (idx < commands.size()); idx++) { + SystemDefaultCompileCommand cmd = (SystemDefaultCompileCommand) commands.elementAt(idx); + if (cmd.getName().equalsIgnoreCase(commandName)) match = cmd; + } + return match; + } + + /** + * Get the commands as an array + */ + public SystemDefaultCompileCommand[] getCommands() { + if ((array == null) || (array.length != commands.size())) { + array = new SystemDefaultCompileCommand[commands.size()]; + for (int idx = 0; idx < commands.size(); idx++) + array[idx] = (SystemDefaultCompileCommand) commands.elementAt(idx); + } + return array; + } + + /** + * Get the commands that match the given source types. + * Never returns null, but may return an empty array. + */ + public SystemDefaultCompileCommand[] getCommandsForSrcType(String srcType) { + Vector v = new Vector(); + for (int idx = 0; idx < commands.size(); idx++) { + if (((SystemDefaultCompileCommand) commands.elementAt(idx)).appliesToSourceType(srcType)) v.addElement(commands.elementAt(idx)); + } + SystemDefaultCompileCommand[] matches = new SystemDefaultCompileCommand[v.size()]; + for (int idx = 0; idx < matches.length; idx++) + matches[idx] = (SystemDefaultCompileCommand) v.elementAt(idx); + return matches; + } + + /** + * Get the command names only as an array + */ + public String[] getCommandNames() { + if ((nameArray == null) || (nameArray.length != commands.size())) { + nameArray = new String[commands.size()]; + for (int idx = 0; idx < commands.size(); idx++) + nameArray[idx] = ((SystemDefaultCompileCommand) commands.elementAt(idx)).getName(); + } + return nameArray; + } + + /** + * Get the fully-populated command strings as an array of string + */ + public String[] getCommandStrings() { + if ((stringArray == null) || (stringArray.length != commands.size())) { + stringArray = new String[commands.size()]; + for (int idx = 0; idx < commands.size(); idx++) + stringArray[idx] = ((SystemDefaultCompileCommand) commands.elementAt(idx)).getCommandWithParameters(); + } + return stringArray; + } + + /** + * Return a count of the compile commands in this list + */ + public int getSize() { + return commands.size(); + } + + /** + * Given a user-specified command string, check if the command is one of those defined in this list, + * and if so, verify it has all the minimum parameters. For any that are missing, add them... + */ + public String fillWithRequiredParams(String commandString) { + if (commandString == null) return null; + // first, extract the command name + commandString = commandString.trim(); + if (commandString.length() == 0) return commandString; + int blankIdx = commandString.indexOf(' '); + String cmdName = null; + String cmdParms = null; + if (blankIdx == -1) // no blanks? + { + cmdName = commandString; // assume the string only contains a command name, no parms + } else { + cmdName = commandString.substring(0, blankIdx); + cmdParms = commandString.substring(blankIdx + 1); + } + // second, test if this command name is in our list... + SystemDefaultCompileCommand cmdMatch = getCommand(cmdName); + if (cmdMatch != null) + return cmdMatch.fillWithRequiredParams(cmdParms); + else + return commandString; + } + + /** + * Add a new compile command to the list + */ + public void addCommand(SystemDefaultCompileCommand cmd) { + commands.add(cmd); + clearCache(); + } + + /** + * Print the command labels to standard out, for debugging purposes + */ + public void printCommandLabels() { + System.out.println(); + System.out.println("Total commands: " + getSize()); //$NON-NLS-1$ + for (int idx = 0; idx < commands.size(); idx++) { + SystemDefaultCompileCommand cmd = (SystemDefaultCompileCommand) commands.elementAt(idx); + cmd.printCommandLabel(); + } + System.out.println(); + } + + /** + * Print the command names to standard out, for debugging purposes + */ + public void printCommandNames() { + System.out.println(); + System.out.println("Total commands: " + getSize()); //$NON-NLS-1$ + for (int idx = 0; idx < commands.size(); idx++) { + SystemDefaultCompileCommand cmd = (SystemDefaultCompileCommand) commands.elementAt(idx); + cmd.printCommandName(); + } + System.out.println(); + } + + /** + * Print the full command strings to standard out, for debugging purposes + */ + public void printCommands() { + System.out.println(); + System.out.println("Total commands: " + getSize()); //$NON-NLS-1$ + for (int idx = 0; idx < commands.size(); idx++) { + SystemDefaultCompileCommand cmd = (SystemDefaultCompileCommand) commands.elementAt(idx); + cmd.printCommand(); + } + System.out.println(); + } + + /** + * Clear array cache + */ + private void clearCache() { + array = null; + nameArray = null; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemNewCompileSrcTypeDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemNewCompileSrcTypeDialog.java new file mode 100644 index 00000000000..895dd1b2383 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemNewCompileSrcTypeDialog.java @@ -0,0 +1,219 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemMassager; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.dialogs.SystemPromptDialog; +import org.eclipse.rse.ui.validators.ISystemValidator; +import org.eclipse.rse.ui.validators.ISystemValidatorUniqueString; +import org.eclipse.rse.ui.validators.ValidatorSourceType; +import org.eclipse.rse.ui.view.ISystemPropertyConstants; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * Dialog used when in the Work With Compile Commands dialog when the user presses + * the "Add..." button to add a new source type. + *

+ * This class is designed so that it need not be subclassed. Rather, the mri, validation + * and massaging can all be configured. + */ +public class SystemNewCompileSrcTypeDialog extends SystemPromptDialog implements ISystemMessages, ISystemPropertyConstants { + // gui + protected Text srcTypeText; + // input + protected SystemCompileManager manager; + protected ISystemValidator srcTypeValidator; + protected ISystemMassager srcTypeMassager; + protected boolean caseSensitive; + protected String[] existingTypes; + // output + protected String newSrcType; + // state + protected SystemMessage errorMessage; + protected boolean ignoreEvents; + // mri + protected String mriVerbageLabel, mriPromptLabel, mriPromptTooltip; + + /** + * Constructor when you want to use the default title. + * @param shell The parent window hosting this dialog + * @param compileManager The compile manager that manages these compile commands + * @param caseSensitive True if source types are case-sensitive. False if not. + */ + public SystemNewCompileSrcTypeDialog(Shell shell, SystemCompileManager compileManager, boolean caseSensitive) { + this(shell, compileManager, caseSensitive, SystemUDAResources.RESID_COMPILE_NEWSRCTYPE_TITLE); + } + + /** + * Constructor when you want to supply your own title. + * @param shell The parent window hosting this dialog + * @param compileManager The compile manager that manages these compile commands + * @param caseSensitive True if source types are case-sensitive. False if not. + */ + public SystemNewCompileSrcTypeDialog(Shell shell, SystemCompileManager compileManager, boolean caseSensitive, String title) { + super(shell, title); + this.manager = compileManager; + this.caseSensitive = caseSensitive; + setMRI(SystemUDAResources.RESID_COMPILE_NEWSRCTYPE_VERBAGE_LABEL, SystemUDAResources.RESID_COMPILE_NEWSRCTYPE_PROMPT_LABEL, SystemUDAResources.RESID_COMPILE_NEWSRCTYPE_PROMPT_TOOLTIP); + } + + public void setMRI(String verbageMRILabel, String promptMRILabel, String promptMRITooltip) { + if (verbageMRILabel != null) this.mriVerbageLabel = verbageMRILabel; + if (promptMRILabel != null) this.mriPromptLabel = promptMRILabel; + if (promptMRITooltip != null) this.mriPromptTooltip = promptMRITooltip; + } + + /** + * Set the validator for the new src type + */ + public void setSrcTypeValidator(ISystemValidator validator) { + this.srcTypeValidator = validator; + if ((existingTypes != null) && (srcTypeValidator instanceof ISystemValidatorUniqueString)) { + ((ISystemValidatorUniqueString) srcTypeValidator).setExistingNamesList(existingTypes); + } + } + + /** + * Set the existing source types so error checking will prevent them from being entered again. + */ + public void setExistingSrcTypes(String[] srcTypes) { + this.existingTypes = srcTypes; + if ((srcTypeValidator != null) && (srcTypeValidator instanceof ISystemValidatorUniqueString)) { + ((ISystemValidatorUniqueString) srcTypeValidator).setExistingNamesList(existingTypes); + } + } + + /** + * Set the massager for the new src type. This will be + * called to massage the source type before it is returned. + * Eg, you might pass MassagerFoldCase to fold the result to uppercase or lowercase. + */ + public void setSrcTypeMassager(ISystemMassager massager) { + this.srcTypeMassager = massager; + } + + /** + * Create GUI controls, populate into given composite. + */ + protected Control createInner(Composite parent) { + if (srcTypeValidator == null) setSrcTypeValidator(new ValidatorSourceType(caseSensitive)); + // Inner composite + int nbrColumns = 2; + Composite composite_prompts = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // VERBAGE + SystemWidgetHelpers.createVerbiage(composite_prompts, mriVerbageLabel, nbrColumns, false, 250); + // ENTRY FIELD + srcTypeText = SystemWidgetHelpers.createLabeledTextField(composite_prompts, null, mriPromptLabel, mriPromptTooltip); + // add keystroke listeners... + srcTypeText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateInput(); + } + }); + setPageComplete(false); // since input is currently empty + return composite_prompts; + } + + /** + * Return widget to set initial focus to + */ + protected Control getInitialFocusControl() { + return srcTypeText; + } + + /** + * Called when user presses OK button. + * Return true to close dialog. + * Return false to not close dialog. + */ + protected boolean processOK() { + newSrcType = srcTypeText.getText().trim(); + if (srcTypeMassager != null) { + newSrcType = srcTypeMassager.massage(newSrcType); + ignoreEvents = true; + srcTypeText.setText(newSrcType); + ignoreEvents = false; + } + boolean closeDialog = verify(); + if (closeDialog) { + setOutputObject(newSrcType); + } + return closeDialog; + } + + /** + * Verifies all input. + * @return true if there are no errors in the user input + */ + public boolean verify() { + errorMessage = validateInput(); + if (errorMessage == null) + clearErrorMessage(); + else { + srcTypeText.setFocus(); + setErrorMessage(errorMessage); + } + return (errorMessage == null); + } + + /** + * This hook method is called whenever the text changes in the cmd input field. + * Currently not used. + */ + protected SystemMessage validateInput() { + if (ignoreEvents) return errorMessage; + errorMessage = null; + if (srcTypeValidator != null) errorMessage = srcTypeValidator.validate(srcTypeText.getText().trim()); + if (errorMessage != null) + setErrorMessage(errorMessage); + else + clearErrorMessage(); + setPageComplete(); + return errorMessage; + } + + /** + * This method can be called by the dialog or wizard page host, to decide whether to enable + * or disable the next, final or ok buttons. It returns true if the minimal information is + * available and is correct. + */ + public boolean isPageComplete() { + boolean pageComplete = false; + if (errorMessage == null) { + pageComplete = (srcTypeText.getText().trim().length() > 0); + } + return pageComplete; + } + + /** + * Inform caller of page-complete status of this form + */ + public void setPageComplete() { + setPageComplete(isPageComplete()); + } + + /** + * Returns the user-specified new source type + */ + public String getNewSrcType() { + //System.out.println("Returning " + newSrcType); + return newSrcType; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemPromptCompileCommandDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemPromptCompileCommandDialog.java new file mode 100644 index 00000000000..dc693a64f73 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemPromptCompileCommandDialog.java @@ -0,0 +1,84 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemPromptCommandDialog; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.widgets.Shell; + +/** + * Dialog used when running a user action, which has the prompt option specified. + * This allows the user to edit the resolved command, and the result is placed + * in the output object. + *

+ * This default implementation merely puts the command into an entry field, which + * the user can edit. + */ +public class SystemPromptCompileCommandDialog extends SystemPromptCommandDialog { + /** + * Constructor. + * @param shell The parent window hosting this dialog + * @param command The resolved command from the user action + */ + public SystemPromptCompileCommandDialog(Shell shell, String command) { + super(shell, command, SystemUDAResources.RESID_COMPILE_PROMPTCMD_TITLE); + this.cmd = command; + //setHelp(RSEUIPlugin.HELPPREFIX+"drnp0000"); + } + + /** + * Translated text configuration method. + * Override to return OK button label if you don't want the default + */ + protected String getOKButtonLabel() { + return SystemUDAResources.RESID_COMPILE_PROMPTCMD_OKBUTTON_LABEL; + } + + /** + * Translated text configuration method. + * Override to return OK button tooltip if you don't want the default + */ + protected String getOKButtonToolTipText() { + return SystemUDAResources.RESID_COMPILE_PROMPTCMD_OKBUTTON_TOOLTIP; + } + + /** + * Translated text configuration method. + * Override to return Cancel button tooltip if you don't want the default + */ + protected String getCancelButtonToolTipText() { + return SystemUDAResources.RESID_COMPILE_PROMPTCMD_CANCELBUTTON_TOOLTIP; + } + + /** + * Translated text configuration method. + * Override to return verbage message if you don't want the default + */ + protected String getVerbage() { + return SystemUDAResources.RESID_COMPILE_PROMPTCMD_VERBAGE_LABEL; + } + + /** + * Translated text configuration method. + * Override to return label for the command prompt, if you don't want the default + */ + protected String getPromptLabel() { + return SystemUDAResources.RESID_COMPILE_PROMPTCMD_PROMPT_LABEL; + } + + /** + * Translated text configuration method. + * Override to return tooltip text for the command prompt, if you don't want the default + */ + protected String getPromptToolTipText() { + return SystemUDAResources.RESID_COMPILE_PROMPTCMD_PROMPT_TOOLTIP; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsAction.java new file mode 100644 index 00000000000..10ed75c75c7 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsAction.java @@ -0,0 +1,149 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.internal.ui.view.team.SystemTeamViewSubSystemConfigurationNode; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseDialogAction; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.rse.useractions.ui.compile.teamview.SystemTeamViewCompileTypeNode; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.widgets.Shell; + +/** + * The action that displays the Work With -> Compile Commands menu item + */ +public class SystemWorkWithCompileCommandsAction extends SystemBaseDialogAction { + /** + * Constructor + * @param shell The Shell of the parent UI for this dialog + * @param fromCascadingCompileAction true to get "Work with Compile Commands" label, false to get "Compile Commands" label. + */ + public SystemWorkWithCompileCommandsAction(Shell shell, boolean fromCascadingCompileAction) { + super(fromCascadingCompileAction ? SystemUDAResources.ACTION_WORKWITH_WWCOMPILE_CMDS_LABEL : SystemUDAResources.ACTION_WORKWITH_COMPILE_CMDS_LABEL, + fromCascadingCompileAction ? SystemUDAResources.ACTION_WORKWITH_WWCOMPILE_CMDS_TOOLTIP : SystemUDAResources.ACTION_WORKWITH_COMPILE_CMDS_TOOLTIP, RSEUIPlugin.getDefault() + .getImageDescriptor(ISystemIconConstants.ICON_SYSTEM_WORKWITHCOMPILECMDS_ID), shell); + allowOnMultipleSelection(false); + if (!fromCascadingCompileAction) + setContextMenuGroup(ISystemContextMenuConstants.GROUP_WORKWITH); + else + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "actnwwcc"); //$NON-NLS-1$ + setAvailableOffline(true); + } + + /** + * Reset between runs + */ + public void reset() { + // nothing to do as we have no instance vars. + } + + /** + * Called by SystemBaseAction when selection is set. + * Our opportunity to verify we are allowed for this selected type. + */ + public boolean updateSelection(IStructuredSelection selection) { + boolean enable = true; + Object inputObject = selection.getFirstElement(); + if (inputObject instanceof SystemTeamViewCompileTypeNode) { + SystemTeamViewCompileTypeNode typeNode = ((SystemTeamViewCompileTypeNode) inputObject); + ISystemProfile currSystemProfile = typeNode.getProfile(); + enable = currSystemProfile.isActive(); + } else if (inputObject instanceof SystemTeamViewSubSystemConfigurationNode) { + ISystemProfile currSystemProfile = ((SystemTeamViewSubSystemConfigurationNode) inputObject).getProfile(); + enable = currSystemProfile.isActive(); + } + return enable; + } + + /** + * If you decide to use the supplied run method as is, + * then you must override this method to create and return + * the dialog that is displayed by the default run method + * implementation. + *

+ * If you override run with your own, then + * simply implement this to return null as it won't be used. + * @see #run() + */ + protected Dialog createDialog(Shell shell) { + Object inputObject = getFirstSelection(); + boolean caseSensitive = false; + ISubSystem subsystem = null; + ISubSystemConfiguration ssf = null; + ISystemProfile currSystemProfile = null; + if (inputObject instanceof ISubSystem) + subsystem = (ISubSystem) inputObject; + else if (inputObject instanceof SystemTeamViewCompileTypeNode) { + SystemTeamViewCompileTypeNode typeNode = ((SystemTeamViewCompileTypeNode) inputObject); + ssf = typeNode.getParentSubSystemFactory().getSubSystemConfiguration(); + currSystemProfile = typeNode.getProfile(); + } else if (inputObject instanceof SystemTeamViewSubSystemConfigurationNode) { + ssf = ((SystemTeamViewSubSystemConfigurationNode) inputObject).getSubSystemConfiguration(); + currSystemProfile = ((SystemTeamViewSubSystemConfigurationNode) inputObject).getProfile(); + } else { + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(inputObject); + if (rmtAdapter != null) subsystem = rmtAdapter.getSubSystem(inputObject); + } + SystemCompileProfile currProfile = null; + SystemCompileProfile[] currProfiles = null; + SystemCompileManager compileManager = null; + if (subsystem != null) { + if (ssf == null) ssf = subsystem.getSubSystemConfiguration(); + if (currSystemProfile == null) currSystemProfile = subsystem.getSystemProfile(); + } + if (ssf != null) { + /* FIXME - compile actions not coupled with subsystem API anymore + + compileManager = ssf.getCompileManager(); + if (subsystem != null) + { + compileManager.setSystemConnection(subsystem.getHost()); + } + if (currSystemProfile != null) + currProfile = compileManager.getCompileProfile(currSystemProfile); + currProfiles = compileManager.getAllCompileProfiles(); + */ + caseSensitive = ssf.isCaseSensitive(); + } + SystemWorkWithCompileCommandsDialog dlg = new SystemWorkWithCompileCommandsDialog(shell, compileManager, currProfile); + /* FIXME - currProfiles cannot be null since above stuff was commented out + if (currProfiles != null) { + dlg.setProfiles(currProfiles); + } + */ + dlg.setProfiles(currProfiles); + dlg.setCaseSensitive(caseSensitive); + if (inputObject instanceof SystemTeamViewCompileTypeNode) { + SystemTeamViewCompileTypeNode node = (SystemTeamViewCompileTypeNode) inputObject; + dlg.setCompileType(node.getCompileType()); + dlg.setSupportsAddSrcTypeButton(false); + } + return dlg; + } + + /** + * Required by parent. We use it to return the new name. + * In our case, we don't need it, so we return null. + */ + protected Object getDialogValue(Dialog dlg) { + return null; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsDialog.java new file mode 100644 index 00000000000..d74ec81dc88 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/SystemWorkWithCompileCommandsDialog.java @@ -0,0 +1,1117 @@ +package org.eclipse.rse.useractions.ui.compile; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +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.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.core.SystemAdapterHelpers; +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.internal.ui.view.SystemViewMenuListener; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.actions.ISystemAction; +import org.eclipse.rse.ui.dialogs.SystemPromptDialog; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.rse.ui.widgets.ISystemEditPaneStates; +import org.eclipse.rse.ui.widgets.SystemEditPaneStateMachine; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; + +/** + * A dialog that allows the user to work with the compile commands for the compile actions in this subsystem. + */ +public class SystemWorkWithCompileCommandsDialog extends SystemPromptDialog implements ISystemMessages, SelectionListener, ISystemCompileCommandEditPaneListener, IMenuListener, Runnable, + ISystemCompileCommandEditPaneHoster { + protected Button applyButton, revertButton, newSrcTypeButton, rmvSrcTypeButton; + protected Combo profileCombo; + protected Combo srcTypeCombo; + protected List listView; + protected Label ccLabel; + protected SystemEditPaneStateMachine sm; + // context menu actions support + private SystemCompileCommandActionCopy copyAction; + private SystemCompileCommandActionPaste pasteAction; + private SystemCompileCommandActionDelete deleteAction; + private SystemCompileCommandActionMoveUp moveUpAction; + private SystemCompileCommandActionMoveDown moveDownAction; + private SystemCompileCommandActionRestoreDefaults restoreAction; + private MenuManager menuMgr; + private Clipboard clipboard; + private boolean menuListenerAdded; + // inputs + protected SystemCompileManager compileManager; + protected SystemCompileCommandEditPane editpane; + protected SystemCompileProfile[] compProfiles; + protected SystemCompileProfile currentCompProfile; + protected SystemCompileType currentCompType; + protected boolean caseSensitive; + protected boolean supportsAddSrcTypeButton; + private String srcTypeLabel, srcTypeTooltip; + // state + protected boolean ignoreEvents = false; + protected boolean restoreProfileComboSelection = true; + protected boolean showProfileCombo; + protected boolean resetting = false; + protected boolean giveEditorFocus = true; + protected int prevProfileComboSelection = 0; + protected int prevSrcTypeComboSelection = 0; + protected int prevListSelection = 0; + protected String[] compileTypeNames; + private boolean traceTest; + + /** + * Constructor + */ + public SystemWorkWithCompileCommandsDialog(Shell shell, SystemCompileManager compileManager, SystemCompileProfile currentCompProfile) { + this(shell, compileManager, currentCompProfile, SystemUDAResources.RESID_WWCOMPCMDS_TITLE); + } + + /** + * Constructor, when unique title desired + */ + public SystemWorkWithCompileCommandsDialog(Shell shell, SystemCompileManager compileManager, SystemCompileProfile currentCompProfile, String title) { + super(shell, title); + this.compileManager = compileManager; + this.currentCompProfile = currentCompProfile; + this.compProfiles = new SystemCompileProfile[] { currentCompProfile }; + this.supportsAddSrcTypeButton = true; + setCancelButtonLabel(SystemResources.BUTTON_CLOSE); + setShowOkButton(false); + setOutputObject(null); + setHelp(); + // default mri values... + setSourceTypePromptMRI(compileManager.getSourceTypePromptMRILabel(), compileManager.getSourceTypePromptMRITooltip()); + } + + /** + * Overridable extension point for setting dialog help + */ + protected void setHelp() { + setHelp(RSEUIPlugin.HELPPREFIX + "wwcc0000"); //$NON-NLS-1$ + } + + // INPUT/CONFIGURATION + /** + * Specify an edit pane that prompts the user for the contents of a compile command + */ + public void setCompileCommandEditPane(SystemCompileCommandEditPane editPane) { + this.editpane = editPane; + } + + /** + * Set the compile profiles to show in the profile combo. + * @param profiles - array of profiles to show + */ + public void setProfiles(SystemCompileProfile[] profiles) { + if (profiles == null) + compProfiles = new SystemCompileProfile[0]; + else { + compProfiles = profiles; + showProfileCombo = true; + } + } + + /** + * Set whether the source types, labels, etc are case sensitive + */ + public void setCaseSensitive(boolean caseSensitive) { + this.caseSensitive = caseSensitive; + } + + /** + * Set supports the "Add..." button beside the source type combo. + * The default is true. + */ + public void setSupportsAddSrcTypeButton(boolean supports) { + this.supportsAddSrcTypeButton = supports; + } + + /** + * Set the mri for the source type prompt + */ + public void setSourceTypePromptMRI(String srcTypeMRILabel, String srcTypeMRITooltip) { + this.srcTypeLabel = srcTypeMRILabel; + this.srcTypeTooltip = srcTypeMRITooltip; + } + + /** + * Set the compile to pre-select in the types combo + */ + public void setCompileType(SystemCompileType type) { + this.currentCompType = type; + } + + /** + * @see SystemPromptDialog#getInitialFocusControl() + */ + protected Control getInitialFocusControl() { + return editpane.getInitialFocusControl(); + } + + /** + * @see SystemPromptDialog#createInner(Composite) + */ + protected Control createInner(Composite parent) { + editpane = getCompileCommandEditPane(getShell()); + //editpane.setSubSystem(subsystem); + // Inner composite + int nbrColumns = 4; + Composite composite = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // profile combo + profileCombo = SystemWidgetHelpers.createLabeledReadonlyCombo(composite, null, SystemUDAResources.RESID_WWCOMPCMDS_PROFILE_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_PROFILE_TOOLTIP); + ((GridData) profileCombo.getLayoutData()).horizontalSpan = nbrColumns - 1; + // source type combo + srcTypeCombo = SystemWidgetHelpers.createLabeledReadonlyCombo(composite, null, srcTypeLabel, srcTypeTooltip); + if (supportsAddSrcTypeButton) { + newSrcTypeButton = SystemWidgetHelpers.createPushButton(composite, null, SystemUDAResources.RESID_WWCOMPCMDS_TYPES_BUTTON_ADD_LABEL, + SystemUDAResources.RESID_WWCOMPCMDS_TYPES_BUTTON_ADD_TOOLTIP); + rmvSrcTypeButton = SystemWidgetHelpers.createPushButton(composite, null, SystemUDAResources.RESID_WWCOMPCMDS_TYPES_BUTTON_RMV_LABEL, + SystemUDAResources.RESID_WWCOMPCMDS_TYPES_BUTTON_RMV_TOOLTIP); + rmvSrcTypeButton.setEnabled(false); + } else + ((GridData) srcTypeCombo.getLayoutData()).horizontalSpan = nbrColumns - 1; + //SystemWidgetHelpers.setHelp(profileCombo, RSEUIPlugin.HELPPREFIX + "ccon0001", parentHelpId); + addFillerLine(composite, nbrColumns); + // create list view on left + listView = SystemWidgetHelpers.createListBox(composite, SystemUDAResources.RESID_WWCOMPCMDS_LIST_LABEL, null, false, 1); + //listView.setToolTipText(listPromptTip); annoying! + GridData data = (GridData) listView.getLayoutData(); + data.grabExcessHorizontalSpace = false; + data.horizontalAlignment = GridData.FILL; + data.grabExcessVerticalSpace = true; + data.verticalAlignment = GridData.FILL; + data.widthHint = 110; + // we want the tree view on the left to extend to the bottom of the page, so on the right + // we create a 1-column composite that will hold the edit pane on top, and the apply/revert + // buttons on the bottom... + Composite rightSideComposite = SystemWidgetHelpers.createFlushComposite(composite, 1); + ((GridData) rightSideComposite.getLayoutData()).horizontalSpan = nbrColumns - 1; + // now add a top spacer line and visual separator line, for the right side + addFillerLine(rightSideComposite, 1); + ccLabel = SystemWidgetHelpers.createLabel(rightSideComposite, ""); //$NON-NLS-1$ + addSeparatorLine(rightSideComposite, 1); + // now populate top of right-side composite with edit pane... + editpane.createContents(rightSideComposite); + // now add a bottom visual separator line + addSeparatorLine(rightSideComposite, 1); + // now populate bottom of right-side composite with apply/revert buttons within their own composite + int nbrColumns_buttonComposite = 3; + Composite applyResetButtonComposite = SystemWidgetHelpers.createFlushComposite(rightSideComposite, nbrColumns_buttonComposite); + ((GridData) applyResetButtonComposite.getLayoutData()).horizontalIndent = 200; // shift buttons to the right + // now populate the buttons composite with apply and revert buttons + Label filler = SystemWidgetHelpers.createLabel(applyResetButtonComposite, ""); //$NON-NLS-1$ + ((GridData) filler.getLayoutData()).grabExcessHorizontalSpace = true; + ((GridData) filler.getLayoutData()).horizontalAlignment = GridData.FILL; + applyButton = SystemWidgetHelpers.createPushButton(applyResetButtonComposite, this, SystemUDAResources.RESID_WWCOMPCMDS_BUTTON_APPLY_LABEL, + SystemUDAResources.RESID_WWCOMPCMDS_BUTTON_APPLY_TOOLTIP); + revertButton = SystemWidgetHelpers.createPushButton(applyResetButtonComposite, this, SystemUDAResources.RESID_WWCOMPCMDS_BUTTON_REVERT_LABEL, + SystemUDAResources.RESID_WWCOMPCMDS_BUTTON_REVERT_TOOLTIP); + // now add a spacer to soak up left-over height... + addGrowableFillerLine(rightSideComposite, 1); + // create state machine to manage edit pane + sm = new SystemEditPaneStateMachine(rightSideComposite, applyButton, revertButton); + sm.setApplyLabelForNewMode(SystemUDAResources.RESID_WWCOMPCMDS_BUTTON_CREATE_LABEL, SystemUDAResources.RESID_WWCOMPCMDS_BUTTON_CREATE_TOOLTIP); + sm.setUnsetMode(); + // populate profile dropdown + initProfileCombo(); + composite.layout(true); + // add listeners + profileCombo.addSelectionListener(this); + srcTypeCombo.addSelectionListener(this); + if (supportsAddSrcTypeButton) { + newSrcTypeButton.addSelectionListener(this); + rmvSrcTypeButton.addSelectionListener(this); + } + listView.addSelectionListener(this); + applyButton.addSelectionListener(this); + revertButton.addSelectionListener(this); + editpane.addChangeListener(this); + // add special listeners for accessibility -- do not change focus when navigating list with keys + listView.addMouseListener(new MouseListener() { + public void mouseDoubleClick(MouseEvent e) { + giveEditorFocus = true; + } + + public void mouseDown(MouseEvent e) { + giveEditorFocus = true; + } + + public void mouseUp(MouseEvent e) { + giveEditorFocus = true; + } + }); + listView.addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent e) { + giveEditorFocus = false; + } + + public void keyReleased(KeyEvent e) { + giveEditorFocus = false; + } + }); + // add context menu + // ----------------------------- + // Enable right-click popup menu + // ----------------------------- + menuMgr = new MenuManager("#WWCompCmdsPopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(this); + Menu menu = menuMgr.createContextMenu(listView); + listView.setMenu(menu); + editpane.configureHeadingLabel(ccLabel); + editpane.isComplete();// side effect is initial enablement of test button + return composite; + } + + /** + * Intercept of parent so we can reset the default button + */ + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + getShell().setDefaultButton(applyButton); // defect 46129 + } + + /** + * Return our edit pane. Overriding this is an alternative to calling setEditPane. + * This is called in createContents + */ + protected SystemCompileCommandEditPane getCompileCommandEditPane(Shell shell) { + if (editpane == null) editpane = compileManager.getCompileCommandEditPane(shell, this, caseSensitive); + return editpane; + } + + /** + * Initialize contents and selection of profile combo + */ + private void initProfileCombo() { + if (profileCombo != null) { + if ((compProfiles != null) && (compProfiles.length > 0)) { + String[] names = new String[compProfiles.length]; + int selIdx = -1; + for (int idx = 0; idx < names.length; idx++) { + names[idx] = compProfiles[idx].getProfileName(); + if ((currentCompProfile != null) && (currentCompProfile == compProfiles[idx])) selIdx = idx; + } + if (selIdx == -1) { + selIdx = 0; + currentCompProfile = compProfiles[0]; + } + profileCombo.setItems(names); + profileCombo.setText(names[selIdx]); + prevProfileComboSelection = selIdx; + if (currentCompProfile != null) { + if (currentCompType != null) + processProfileSelected(currentCompType.getType()); + else + processProfileSelected(null); + } + } + } + } + + /** + * Process when a profile is selected + */ + private void processProfileSelected(String srcType) { + if (srcType == null) { + ISystemRemoteElementAdapter rmtAdapter = SystemAdapterHelpers.getRemoteAdapter(getInputObject()); + if (rmtAdapter != null) { + srcType = rmtAdapter.getRemoteSourceType(getInputObject()); + /* + if (currentCompProfile.getCompileType(srcType) == null) + { + currentCompProfile.addCompileType(new SystemCompileType(currentCompProfile, srcType)); + saveData(); + }*/ + } + } + Vector types = currentCompProfile.getCompileTypes(); + if (srcType == null) { + if (types.size() > 0) + srcType = ((SystemCompileType) types.elementAt(0)).getType(); + else { + srcType = ""; //$NON-NLS-1$ + } + } + compileTypeNames = new String[types.size()]; + int index = 0; + // when profile is selected, show the member type + // of the DataElement selected. + for (int i = 0; i < compileTypeNames.length; i++) { + compileTypeNames[i] = ((SystemCompileType) types.get(i)).getType(); + if (!caseSensitive) { + if (srcType.equalsIgnoreCase(compileTypeNames[i])) index = i; + } else { + if (srcType.equals(compileTypeNames[i])) index = i; + } + } + srcTypeCombo.setItems(compileTypeNames); + if (srcTypeCombo.getItemCount() > 0) { + srcTypeCombo.setText(srcTypeCombo.getItem(index)); + prevSrcTypeComboSelection = index; + currentCompType = currentCompProfile.getCompileType(srcTypeCombo.getText()); + processSrcTypeSelected(0); + } else { + prevSrcTypeComboSelection = -1; + currentCompType = null; + processSrcTypeSelected(-1); + } + } + + /** + * Process when src type selected + */ + private void processSrcTypeSelected(int selection) { + Vector cmds = new Vector(); + if (currentCompType != null) cmds = currentCompType.getCompileCommands(); + if (rmvSrcTypeButton != null) rmvSrcTypeButton.setEnabled((currentCompType != null) && (cmds.size() == 0)); + if (currentCompType != null) { + String[] listItems = new String[1 + cmds.size()]; + listItems[0] = SystemUDAResources.RESID_WWCOMPCMDS_LIST_NEWITEM; + for (int idx = 0; idx < cmds.size(); idx++) + listItems[idx + 1] = ((SystemCompileCommand) cmds.get(idx)).getLabel(); + listView.setItems(listItems); + listView.setSelection(selection); + } else { + listView.removeAll(); + } + processCommandsListSelected(); + } + + /** + * Process when compile command is selected in the list view + */ + private void processCommandsListSelected() { + int index = listView.getSelectionIndex(); + if (index == 0) { + sm.setNewMode(); + editpane.setCompileCommand(currentCompType, null); + editpane.configureHeadingLabel(ccLabel); + } else if (index > -1) // and not zero + { + SystemCompileCommand currCmd = getCurrentlySelectedCompileCommand(); + sm.setEditMode(); + editpane.setCompileCommand(currentCompType, currCmd); + editpane.configureHeadingLabel(ccLabel); + } else { + sm.setUnsetMode(); + editpane.setCompileCommand(null, null); + } + prevListSelection = index; + } + + /** + * Gets the current compile profile, given the profile selection index + */ + private SystemCompileProfile getCompileProfile(int currSelIdx) { + return compProfiles[currSelIdx]; + } + + /** + * Parent override. + * Called when user presses CLOSE button. + * We simply close the dialog (since we save as we go), unless there are pending changes. + */ + protected boolean processCancel() { + if (sm.isSaveRequired()) { + ignoreEvents = true; + if ((editpane.verify() != null)) { + ignoreEvents = false; + sm.setChangesMade(); // defect 45773 + return false; // pending errors. Cannot save, so cannot close! + } + ignoreEvents = false; + //saveData(); + applyPressed(false); // defect 46379 + } + return super.processCancel(); + } + + /** + * Save the data in the currently selected profile + */ + private void saveData() { + if (currentCompProfile != null) currentCompProfile.writeToDisk(); + } + + /** + * Handles events generated by controls on this page. + */ + public void widgetSelected(SelectionEvent e) { + clearMessage(); + Widget source = e.widget; + if (resetting) return; + if (source == applyButton) { + applyPressed(true); + } else if (source == revertButton) { + revertPressed(); + } else if (source == newSrcTypeButton) { + newSrcTypePressed(); + } else if (source == rmvSrcTypeButton) { + rmvSrcTypePressed(); + } else if (source == listView) { + if (traceTest) System.out.println("Inside widgetSelected for listView: " + listView.getSelectionIndex()); //$NON-NLS-1$ + // change for pendings changes or unresolved errors... + if (editpane.areErrorsPending()) { + //System.out.println("errors pending in editpane"); + e.doit = false; // dang, this doesn't work! + resetting = true; + listView.select(prevListSelection); + resetting = false; + return; + } else if (sm.isSaveRequired()) { + boolean newMode = (sm.getMode() == ISystemEditPaneStates.MODE_NEW); + if (editpane.verify() != null) { + //System.out.println("verify in editpane returned an error"); + e.doit = false; // dang, this doesn't work! + resetting = true; + listView.select(prevListSelection); + resetting = false; + sm.setChangesMade(); // isSaveRequired() resets it so we need to undo that + return; + } + int newSelection = listView.getSelectionIndex(); + saveCompileCommand(editpane.saveChanges(), newMode, prevListSelection); + listView.select(newSelection); // the save changed the selection, so we need to restore it + } + processCommandsListSelected(); + if (giveEditorFocus) { + Control c = editpane.getInitialFocusControl(); + if ((c != null) && !c.isDisposed() && c.isVisible()) c.setFocus(); + } + } else if (source == profileCombo) { + if (editpane.areErrorsPending()) { + restoreProfileComboSelection = true; + profileCombo.getDisplay().asyncExec(this); + return; + } else if (sm.isSaveRequired()) // defect 46318 + { + boolean newMode = (sm.getMode() == ISystemEditPaneStates.MODE_NEW); + if (editpane.verify() != null) { + restoreProfileComboSelection = true; + sm.setChangesMade(); // isSaveRequired() resets it so we need to undo that + profileCombo.getDisplay().asyncExec(this); + return; // newly-found errors are pending so go no further + } + //int newSelection = listView.getSelectionIndex(); + saveCompileCommand(editpane.saveChanges(), newMode, prevListSelection); + //listView.select(newSelection); // the save changed the selection, so we need to restore it + } + int idx = profileCombo.getSelectionIndex(); + currentCompProfile = getCompileProfile(idx); + //processProfileSelected(srcTypeCombo.getText()); + processProfileSelected(null); + prevProfileComboSelection = idx; + } else if (source == srcTypeCombo) { + if (editpane.areErrorsPending()) { + restoreProfileComboSelection = false; + srcTypeCombo.getDisplay().asyncExec(this); + return; + } else if (sm.isSaveRequired()) // defect 46318 + { + boolean newMode = (sm.getMode() == ISystemEditPaneStates.MODE_NEW); + if (editpane.verify() != null) { + restoreProfileComboSelection = false; + sm.setChangesMade(); // isSaveRequired() resets it so we need to undo that + profileCombo.getDisplay().asyncExec(this); + return; // newly-found errors are pending so go no further + } + //int newSelection = listView.getSelectionIndex(); + saveCompileCommand(editpane.saveChanges(), newMode, prevListSelection); + //listView.select(newSelection); // the save changed the selection, so we need to restore it + } + int idx = srcTypeCombo.getSelectionIndex(); + currentCompType = currentCompProfile.getCompileType(srcTypeCombo.getText()); + processSrcTypeSelected(0); + prevSrcTypeComboSelection = idx; + } + } + + /** + * User pressed Apply to save the pending changes the current filter string + */ + protected void applyPressed(boolean doVerify) { + ignoreEvents = true; + if (!doVerify || (editpane.verify() == null)) { + SystemCompileCommand editedCompileCmd = editpane.saveChanges(); + boolean ok = (editedCompileCmd != null); + if (ok) { + boolean newMode = (sm.getMode() == ISystemEditPaneStates.MODE_NEW); + sm.applyPressed(); + saveCompileCommand(editedCompileCmd, newMode, prevListSelection); + processCommandsListSelected(); + if (newMode) + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_ADDED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, editedCompileCmd, + null); + else + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_CHANGED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, + editedCompileCmd, null); + } + } + ignoreEvents = false; + } + + /** + * User pressed Revert to discard the pending changes the current filter string + */ + protected void revertPressed() { + ignoreEvents = true; + editpane.clearErrorMessage(); + sm.resetPressed(); + if (isNewSelected() || (listView.getSelectionIndex() == -1)) + editpane.setCompileCommand(currentCompType, null); + else + editpane.setCompileCommand(currentCompType, getCurrentlySelectedCompileCommand()); + setPageComplete(true); + clearErrorMessage(); + ignoreEvents = false; + } + + /** + * User pressed New... beside the Source Type combo + */ + protected void newSrcTypePressed() { + if (sm.isSaveRequired()) { + ignoreEvents = true; + if ((editpane.verify() != null)) { + ignoreEvents = false; + return; // pending errors. Cannot save, so cannot process! + } + ignoreEvents = false; + //saveData(); + applyPressed(false); // defect 46379 + } + SystemNewCompileSrcTypeDialog dlg = compileManager.getNewSrcTypeDialog(getShell(), caseSensitive); + dlg.setExistingSrcTypes(compileTypeNames); + dlg.open(); + if (!dlg.wasCancelled()) { + String newSrcType = dlg.getNewSrcType(); + currentCompProfile.addCompileType(new SystemCompileType(currentCompProfile, newSrcType)); + saveData(); + processProfileSelected(newSrcType); + //System.out.println("New src type: " + newSrcType); + } + } + + /** + * User pressed Remove... beside the Source Type combo + */ + protected void rmvSrcTypePressed() { + if (sm.isSaveRequired()) { + ignoreEvents = true; + if ((editpane.verify() != null)) { + ignoreEvents = false; + return; // pending errors. Cannot save, so cannot process! + } + ignoreEvents = false; + //saveData(); + applyPressed(false); // defect 46379 + } + currentCompProfile.removeCompileType(currentCompType); + saveData(); + processProfileSelected(null); + } + + /** + * Handles events generated by controls on this page. + */ + public void widgetDefaultSelected(SelectionEvent e) { + } + + /** + * Save the given edited/new compile command and updates the gui list. + */ + protected void saveCompileCommand(SystemCompileCommand editedCompileCommand, boolean newMode, int selectionIndex) { + if (newMode) { + currentCompType.addCompileCommand(editedCompileCommand); + listView.add(editedCompileCommand.getLabel()); + saveData(); + //listView.select(listView.getItemCount()-1); + processSrcTypeSelected(listView.getItemCount() - 1); + } else { + saveData(); + //listView.select(selectionIndex); + //listView.setItem(selectionIndex, editedCompileCommand.getLabel()); + //processCommandsListSelected(); + processSrcTypeSelected(selectionIndex); + } + } + + /** + * Intercept of parent method so we can direct it to the Apply button versus the OK button (which we don't have). + */ + public void setPageComplete(boolean complete) { + // d45795 + if (applyButton != null) { + if (!complete) applyButton.setEnabled(false); + // else: we never enable it because the state machine does that anyway on any user-input change + } + } + + // --------------- + // HELPER METHODS + // --------------- + /** + * Returns the implementation of ISystemRemoteElement for the given + * object. Returns null if this object does not adaptable to this. + */ + protected ISystemRemoteElementAdapter getRemoteAdapter(Object o) { + ISystemRemoteElementAdapter adapter = null; + if (!(o instanceof IAdaptable)) + adapter = (ISystemRemoteElementAdapter) Platform.getAdapterManager().getAdapter(o, ISystemRemoteElementAdapter.class); + else + adapter = (ISystemRemoteElementAdapter) ((IAdaptable) o).getAdapter(ISystemRemoteElementAdapter.class); + return adapter; + } + + // ------------ + // List methods + // ------------ + /** + * Return true if currently selected item is "New" + */ + protected boolean isNewSelected() { + return (listView.getSelectionIndex() == 0); + } + + /** + * Return true if currently selected item is IBM- or vendor-supplied + */ + protected boolean isIBMSupplied() { + if (listView.getSelectionIndex() > 0) { + return !getCurrentlySelectedCompileCommand().isUserSupplied(); + } else + return false; + } + + /** + * Return currently selected list item + */ + protected String getCurrentSelection() { + if (listView.getSelectionCount() >= 1) + return listView.getSelection()[0]; + else + return null; + } + + /** + * Return the currently selected compile command + */ + protected SystemCompileCommand getCurrentlySelectedCompileCommand() { + int selIdx = listView.getSelectionIndex(); + if (selIdx > 0) // item 0 is "new" so skip it + return currentCompType.getCompileCommand(selIdx - 1); + else + return null; + } + + // ---------------------------------------------- + // EDIT PANE CHANGE LISTENER INTERFACE METHODS... + // ---------------------------------------------- + /** + * Callback method. The user has changed the compile command. It may or may not + * be valid. If not, the given message is non-null. If it is, and you want it, + * call getCompileCommand() in the edit pane. + */ + public void compileCommandChanged(SystemMessage message) { + if (message != null) + setErrorMessage(message); + else + clearErrorMessage(); + if (!ignoreEvents) // this is set on while verifying, indicating these are not real change events per se + { + sm.setChangesMade(); + } + setPageComplete(message == null); // d45795 + } + + // ------------------------------ + // CONTEXT MENU ACTION SUPPORT... + // ------------------------------ + /** + * Called when the context menu is about to open. + * Calls {@link #fillContextMenu(IMenuManager)} + */ + public void menuAboutToShow(IMenuManager menu) { + fillContextMenu(menu); + if (!menuListenerAdded) { + if (menu instanceof MenuManager) { + Menu m = ((MenuManager) menu).getMenu(); + if (m != null) { + menuListenerAdded = true; + SystemViewMenuListener ml = new SystemViewMenuListener(); + //ml.setShowToolTipText(true, wwDialog.getMessageLine()); does not work for some reason + m.addMenuListener(ml); + } + } + } + } + + /** + * This is method is called to populate the popup menu + */ + public void fillContextMenu(IMenuManager menu) { + String currentString = getCurrentSelection(); + IStructuredSelection selection = null; + if (currentString != null) selection = new StructuredSelection(currentString); + // Partition into groups... + createStandardGroups(menu); + ISystemAction action = null; + boolean isNewSelected = isNewSelected(); + //System.out.println("new selected? " + isNewSelected); + if ((selection != null) && !isNewSelected) { + action = getDeleteAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getCopyAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getMoveUpAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getMoveDownAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getRestoreAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + } + //if (!isNewSelected) + { + action = getPasteAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + } + } + + /** + * Creates the Systems plugin standard groups in a context menu. + */ + public void createStandardGroups(IMenuManager menu) { + if (!menu.isEmpty()) return; + menu.add(new Separator(ISystemContextMenuConstants.GROUP_REORGANIZE)); // rename,move,copy,delete,bookmark,refactoring + menu.add(new Separator(ISystemContextMenuConstants.GROUP_REORDER)); // move up, move down + menu.add(new Separator(ISystemContextMenuConstants.GROUP_CHANGE)); // restore + menu.add(new Separator(ISystemContextMenuConstants.GROUP_ADDITIONS)); // user or BP/ISV additions + } + + /** + * Get the delete action + */ + private SystemCompileCommandActionDelete getDeleteAction(ISelection selection) { + if (deleteAction == null) deleteAction = new SystemCompileCommandActionDelete(this); + deleteAction.setShell(getShell()); + deleteAction.setSelection(selection); + return deleteAction; + } + + /** + * Get the move up action + */ + private SystemCompileCommandActionMoveUp getMoveUpAction(ISelection selection) { + if (moveUpAction == null) moveUpAction = new SystemCompileCommandActionMoveUp(this); + moveUpAction.setShell(getShell()); + moveUpAction.setSelection(selection); + return moveUpAction; + } + + /** + * Get the move down action + */ + private SystemCompileCommandActionMoveDown getMoveDownAction(ISelection selection) { + if (moveDownAction == null) moveDownAction = new SystemCompileCommandActionMoveDown(this); + moveDownAction.setShell(getShell()); + moveDownAction.setSelection(selection); + return moveDownAction; + } + + /** + * Get the copy action + */ + private SystemCompileCommandActionCopy getCopyAction(ISelection selection) { + if (copyAction == null) copyAction = new SystemCompileCommandActionCopy(this); + copyAction.setShell(getShell()); + copyAction.setSelection(selection); + return copyAction; + } + + /** + * Get the paste action + */ + private SystemCompileCommandActionPaste getPasteAction(ISelection selection) { + if (pasteAction == null) pasteAction = new SystemCompileCommandActionPaste(this); + pasteAction.setShell(getShell()); + if (selection != null) pasteAction.setSelection(selection); + return pasteAction; + } + + /** + * Get the restore defaults action + */ + private SystemCompileCommandActionRestoreDefaults getRestoreAction(ISelection selection) { + if (restoreAction == null) restoreAction = new SystemCompileCommandActionRestoreDefaults(this); + restoreAction.setShell(getShell()); + if (selection != null) restoreAction.setSelection(selection); + return restoreAction; + } + + // ------------------------------------------------------------- + // CALLBACK METHODS FROM THE RIGHT CLICK CONTEXT MENU ACTIONS... + // ------------------------------------------------------------- + /** + * Decide if we can do the delete or not. + * Will decide the enabled state of the delete action. + */ + public boolean canDelete() { + return (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isNewSelected() && (listView.getSelectionIndex() != -1) && !isIBMSupplied(); + } + + /** + * Perform the delete action + */ + public void doDelete() { + int idx = listView.getSelectionIndex(); + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_CONFIRM_DELETE); + SystemMessageDialog msgDlg = new SystemMessageDialog(getShell(), msg); + try { + if (msgDlg.openQuestion()) { + SystemCompileCommand deletedCmd = getCurrentlySelectedCompileCommand(); + currentCompType.removeCompileCommand(deletedCmd); + saveData(); + //traceTest = true; + listView.remove(idx); // remove item from list + if (idx <= (listView.getItemCount() - 1)) // can we select next item? + listView.select(idx); // select next item + else + listView.select(idx - 1); // select previous item + processCommandsListSelected(); + if (listView.getItemCount() == 1) //d47206 + rmvSrcTypeButton.setEnabled(true); + //traceTest = false; + // fire model change event in case any BP code is listening... + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REMOVED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, deletedCmd, null); + } + } catch (Exception exc) { + } + } + + /** + * Decide if we can do the move up or not. + * Will decide the enabled state of the move up action. + */ + public boolean canMoveUp() { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isNewSelected() && (listView.getSelectionIndex() != -1); + if (can) { + int idx = listView.getSelectionIndex(); + can = (idx > 1); // skip new at index 0, and skip first actual compile command as it can't be moved up + } + return can; + } + + /** + * Perform the move up action + */ + public void doMoveUp() { + int idx = listView.getSelectionIndex(); + SystemCompileCommand currCmd = getCurrentlySelectedCompileCommand(); + if (currCmd == null) return; // better never happen! + // remove and add in model... + currentCompType.removeCompileCommand(currCmd); // remove item from model + currentCompType.insertCompileCommand(currCmd, idx - 2); // re-add one position up (remembering that the UI has one extra node at the top for "new") + saveData(); + // remove and add in UI... + listView.remove(idx); // remove item from UI list + listView.add(currCmd.getLabel(), idx - 1); // re-add one position up + listView.select(idx - 1); + listView.showSelection(); + processCommandsListSelected(); + // fire model change event in case any BP code is listening... + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REORDERED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, currCmd, null); + } + + /** + * Decide if we can do the move down or not. + * Will decide the enabled state of the move down action. + */ + public boolean canMoveDown() { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isNewSelected() && (listView.getSelectionIndex() != -1); + if (can) { + int idx = listView.getSelectionIndex(); + can = (idx <= (listView.getItemCount() - 2)); // -1 is to be zero-based. Another -1 is to discount "New". + } + return can; + } + + /** + * Perform the move down action + */ + public void doMoveDown() { + int idx = listView.getSelectionIndex(); + SystemCompileCommand currCmd = getCurrentlySelectedCompileCommand(); + if (currCmd == null) return; // better never happen! + // remove and add in model... + currentCompType.removeCompileCommand(currCmd); // remove item from model + currentCompType.insertCompileCommand(currCmd, idx); // re-add one position down (remembering that the UI has one extra node at the top for "new") + saveData(); + // remove and add in UI... + listView.remove(idx); // remove item from UI list + listView.add(currCmd.getLabel(), idx + 1); // re-add one position down + listView.select(idx + 1); + listView.showSelection(); + processCommandsListSelected(); + // fire model change event in case any BP code is listening... + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REORDERED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, currCmd, null); + } + + /** + * Decide if we can do the copy or not. + * Will decide the enabled state of the copy action. + */ + public boolean canCopy() { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isNewSelected() && (listView.getSelectionIndex() != -1); + return can; + } + + /** + * Actually do the copy of the current filter string to the clipboard. + */ + public void doCopy() { + if (clipboard == null) clipboard = new Clipboard(getShell().getDisplay()); + String selection = getCurrentSelection(); + TextTransfer transfer = TextTransfer.getInstance(); + clipboard.setContents(new Object[] { selection }, new Transfer[] { transfer }); + } + + /** + * Decide if we can do the paste or not. + * Will decide the enabled state of the copy action. + */ + public boolean canPaste() { + if (clipboard == null) return false; + TextTransfer textTransfer = TextTransfer.getInstance(); + String textData = (String) clipboard.getContents(textTransfer); + return ((textData != null) && (textData.length() > 0)); + } + + /** + * Actually do the copy of the current filter string to the clipboard. + * If an existing string is selected, it is pasted before it. Else. it is appended to the end of the list. + */ + public void doPaste() { + if (clipboard == null) return; + TextTransfer textTransfer = TextTransfer.getInstance(); + String textData = (String) clipboard.getContents(textTransfer); + SystemCompileCommand oldCmd = currentCompType.getCompileLabel(textData); + if (oldCmd == null) return; + SystemCompileCommand newCmd = (SystemCompileCommand) oldCmd.clone(); + newCmd.setLabel(getUniqueCloneLabel(oldCmd)); + String newCopy = newCmd.getLabel(); + int newLocation = listView.getSelectionIndex(); + if (newLocation <= 0) { + listView.add(newCopy); + listView.select(listView.getItemCount() - 1); + } else { + listView.add(newCopy, newLocation); + listView.select(newLocation); + } + listView.showSelection(); + currentCompType.insertCompileCommand(newCmd, listView.getSelectionIndex() - 1); // the "-1" is to discount for the "new" item at the top + saveData(); + processCommandsListSelected(); + // we don't need to do the following but for consistency with change user actions and types, we do + clipboard.dispose(); + clipboard = null; + // fire model change event in case any BP code is listening... + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REMOVED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, oldCmd, null); + } + + /** + * Return a new unique label to assign to a pastable compile command node clone + */ + private String getUniqueCloneLabel(SystemCompileCommand clonableCmd) { + String newName = SystemUDAResources.RESID_WWCOMPCMDS_COPY_NAME_1; + newName = SystemMessage.sub(newName, "%1", clonableCmd.getLabel()); //$NON-NLS-1$ + Vector existingNames = currentCompType.getExistingLabels(); + boolean nameInUse = (existingNames.indexOf(newName) >= 0); + int nbr = 2; + while (nameInUse) { + newName = SystemUDAResources.RESID_WWCOMPCMDS_COPY_NAME_N; + newName = SystemMessage.sub(newName, "%1", clonableCmd.getLabel()); //$NON-NLS-1$ + newName = SystemMessage.sub(newName, "%2", Integer.toString(nbr)); //$NON-NLS-1$ + nameInUse = (existingNames.indexOf(newName) >= 0); + ++nbr; + } + return newName; + } + + /** + * Decide if we can do the restore defaults or not. + * Will decide the enabled state of the restore defaults action. + */ + public boolean canRestore() { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isNewSelected(); + if (can) { + SystemCompileCommand cmd = getCurrentlySelectedCompileCommand(); + if (cmd != null) + can = !cmd.isUserSupplied() && !cmd.getDefaultString().equals(cmd.getCurrentString()); + else + can = false; + } + return can; + } + + /** + * Perform the restore defaults action + */ + public void doRestore() { + SystemCompileCommand cmd = getCurrentlySelectedCompileCommand(); + cmd.setCurrentString(cmd.getDefaultString()); + saveData(); + processCommandsListSelected(); + } + + /** + * For asynch exec we defer some operations until other pending events are processed. + */ + public void run() { + if (restoreProfileComboSelection) + profileCombo.select(prevProfileComboSelection); + else + srcTypeCombo.select(prevSrcTypeComboSelection); + super.run(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandAdapter.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandAdapter.java new file mode 100644 index 00000000000..9333ba16fe1 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandAdapter.java @@ -0,0 +1,196 @@ +package org.eclipse.rse.useractions.ui.compile.teamview; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.internal.ui.view.SystemViewResources; +import org.eclipse.rse.ui.SystemMenuManager; +import org.eclipse.rse.ui.view.AbstractSystemViewAdapter; +import org.eclipse.rse.ui.view.ISystemPropertyConstants; +import org.eclipse.rse.ui.view.ISystemViewElementAdapter; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommand; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +/** + * Adapter for displaying and processing SystemTeamViewCompileCommandNode objects in tree views, such as + * the Team view. + */ +public class SystemTeamViewCompileCommandAdapter extends AbstractSystemViewAdapter implements ISystemViewElementAdapter { + private boolean actionsCreated = false; + //private SystemWorkWithUDAsAction wwActionsAction; + // ------------------- + // property descriptors + // ------------------- + private static PropertyDescriptor[] propertyDescriptorArray = null; + + /** + * Returns any actions that should be contributed to the popup menu + * for the given element. + * @param menu The menu to contribute actions to + * @param selection The window's current selection. + * @param shell Shell of viewer + * @param menuGroup recommended menu group to add actions to. If added to another group, you must be sure to create that group first. + */ + public void addActions(SystemMenuManager menu, IStructuredSelection selection, Shell shell, String menuGroup) { + if (!actionsCreated) createActions(); + //wwActionsAction.setShell(shell); + //if (categoryType.equals(SystemTeamViewCategoryNode.MEMENTO_USERACTIONS) && ssfNode.getSubSystemFactory().supportsUserDefinedActions()) + // menu.add(menuGroup, wwActionsAction); + } + + private void createActions() { + actionsCreated = true; + //wwActionsAction = new SystemWorkWithUDAsAction(null); + } + + /** + * Returns an image descriptor for the image. More efficient than getting the image. + * @param element The element for which an image is desired + */ + public ImageDescriptor getImageDescriptor(Object element) { + return ((SystemTeamViewCompileCommandNode) element).getImageDescriptor(); + } + + /** + * Return the label for this object + */ + public String getText(Object element) { + return ((SystemTeamViewCompileCommandNode) element).getLabel(); + } + + /** + * Return the name of this object, which may be different than the display text ({#link #getText(Object)}. + *

+ * Called by common rename and delete actions. + */ + public String getName(Object element) { + return ((SystemTeamViewCompileCommandNode) element).getLabel(); + } + + /** + * Return the absolute name, versus just display name, of this object + */ + public String getAbsoluteName(Object element) { + SystemTeamViewCompileCommandNode cmd = (SystemTeamViewCompileCommandNode) element; + return cmd.getParentCompileType().getLabel() + "." + getLabel(element); //$NON-NLS-1$ + } + + /** + * Return the type label for this object + */ + public String getType(Object element) { + return UserActionsResources.RESID_PROPERTY_TEAM_COMPILECMD_TYPE_VALUE; + } + + /** + * Return the string to display in the status line when the given object is selected. + */ + public String getStatusLineText(Object element) { + SystemTeamViewCompileCommandNode cmd = (SystemTeamViewCompileCommandNode) element; + return UserActionsResources.RESID_PROPERTY_TEAM_COMPILECMD_TYPE_VALUE + ": " + cmd.getLabel(); //$NON-NLS-1$ + } + + /** + * Return the parent of this object. We return the RemoteSystemsConnections project + */ + public Object getParent(Object element) { + SystemTeamViewCompileCommandNode cmd = (SystemTeamViewCompileCommandNode) element; + return cmd.getParentCompileType(); + } + + /** + * Return the children of this profile. + */ + public Object[] getChildren(IProgressMonitor mon, IAdaptable element) { + //SystemTeamViewCompileCommandNode cmd = (SystemTeamViewCompileCommandNode)element; + return null; + } + + /** + * Return true if this profile has children. We return true. + */ + public boolean hasChildren(IAdaptable element) { + return false; + } + + // Property sheet descriptors defining all the properties we expose in the Property Sheet + /** + * Return our unique property descriptors, which getPropertyDescriptors adds to the common properties. + */ + protected org.eclipse.ui.views.properties.IPropertyDescriptor[] internalGetPropertyDescriptors() { + if (propertyDescriptorArray == null) { + propertyDescriptorArray = new PropertyDescriptor[2]; + int idx = 0; + // origin + propertyDescriptorArray[idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_ORIGIN, SystemViewResources.RESID_PROPERTY_ORIGIN_LABEL, + SystemViewResources.RESID_PROPERTY_ORIGIN_TOOLTIP); + // command + propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_COMMAND, SystemViewResources.RESID_PROPERTY_COMMAND_LABEL, + SystemViewResources.RESID_PROPERTY_COMMAND_TOOLTIP); + } + return propertyDescriptorArray; + } + + /** + * Returns the current value for the named property. + * The parent handles P_TEXT and P_TYPE only, and we augment that here. + * @param key - the name of the property as named by its property descriptor + * @return the current value of the property + */ + public Object internalGetPropertyValue(Object key) { + String name = (String) key; + SystemTeamViewCompileCommandNode cmdNode = (SystemTeamViewCompileCommandNode) propertySourceInput; + SystemCompileCommand cmd = cmdNode.getCompileCommand(); + if (name.equals(ISystemPropertyConstants.P_ORIGIN)) { + if (cmd.isIBMSupplied()) { + if (!cmd.getCurrentString().equals(cmd.getDefaultString())) + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBMUSER_VALUE; + else + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBM_VALUE; + } else if (cmd.isISVSupplied()) { + if (!cmd.getCurrentString().equals(cmd.getDefaultString())) + return UserActionsResources.RESID_PROPERTY_ORIGIN_ISVUSER_VALUE; + else + return UserActionsResources.RESID_PROPERTY_ORIGIN_ISV_VALUE; + } else + return UserActionsResources.RESID_PROPERTY_ORIGIN_USER_VALUE; + } else if (name.equals(ISystemPropertyConstants.P_COMMAND)) { + return cmd.getCurrentString(); + } else + return null; + } + // ------------------------------------------------------------ + // METHODS FOR SAVING AND RESTORING EXPANSION STATE OF VIEWER... + // ------------------------------------------------------------ + //we currently don't support re-expanding past the profile level, for performance reasons: + // we don't want to bring all subsystems to life to restore expansion state. + /* + * Return what to save to disk to identify this element in the persisted list of expanded elements. + * + public String getMementoHandle(Object element) + { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode)element; + return type.getMementoHandle(); + }*/ + /* + * Return a short string to uniquely identify the type of resource. + * + public String getMementoHandleKey(Object element) + { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode)element; + return type.getProfile().getName() + "." + type.getParentCategory().getLabel() +"." + type.getParentSubSystemFactory().getName() + "." + type.getLabel(); + }*/ +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandNode.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandNode.java new file mode 100644 index 00000000000..35ada21cdcc --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileCommandNode.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile.teamview; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommand; + +/** + * This class represents a compile command node in the Team view. + */ +public class SystemTeamViewCompileCommandNode implements IAdaptable { + //private String mementoHandle; + private SystemCompileCommand command; + private SystemTeamViewCompileTypeNode parentType; + + /** + * Constructor + */ + public SystemTeamViewCompileCommandNode(SystemTeamViewCompileTypeNode parentType, SystemCompileCommand command) { + super(); + this.command = command; + this.parentType = parentType; + } + + /** + * This is the method required by the IAdaptable interface. + * Given an adapter class type, return an object castable to the type, or + * null if this is not possible. + */ + public Object getAdapter(Class adapterType) { + return Platform.getAdapterManager().getAdapter(this, adapterType); + } + + /** + * Return this node's image + * @return the image to show in the tree, for this node + */ + public ImageDescriptor getImageDescriptor() { + return RSEUIPlugin.getDefault().getImageDescriptor(ISystemIconConstants.ICON_SYSTEM_COMPILE_ID); + } + + /** + * Return this node's label + * @return the translated label to show in the tree, for this node + */ + public String getLabel() { + return command.getLabel(); + } + + /** + * @return profile this category is associated with + */ + public ISystemProfile getProfile() { + return parentType.getProfile(); + } + + /* + * @return the untranslated value to store in the memento, to uniquely identify this node + * + public String getMementoHandle() + { + return mementoHandle; + }*/ + /* + * Set the untranslated value to store in the memento, to uniquely identify this node + * @param string - untranslated value + * + public void setMementoHandle(String string) + { + mementoHandle = string; + }*/ + /** + * Return the compile command this node represents + */ + public SystemCompileCommand getCompileCommand() { + return command; + } + + /** + * Set the compile command this node represents + */ + public void setCompileCommand(SystemCompileCommand command) { + this.command = command; + } + + /** + * Return the parent compile type this is a child of. + */ + public SystemTeamViewCompileTypeNode getParentCompileType() { + return parentType; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeAdapter.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeAdapter.java new file mode 100644 index 00000000000..2eb82ff027b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeAdapter.java @@ -0,0 +1,187 @@ +package org.eclipse.rse.useractions.ui.compile.teamview; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.ui.SystemMenuManager; +import org.eclipse.rse.ui.view.AbstractSystemViewAdapter; +import org.eclipse.rse.ui.view.ISystemPropertyConstants; +import org.eclipse.rse.ui.view.ISystemViewElementAdapter; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommand; +import org.eclipse.rse.useractions.ui.compile.SystemWorkWithCompileCommandsAction; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +/** + * Adapter for displaying and processing SystemTeamViewCompileTypeNode objects in tree views, such as + * the Team view. + */ +public class SystemTeamViewCompileTypeAdapter extends AbstractSystemViewAdapter implements ISystemViewElementAdapter { + private boolean actionsCreated = false; + private SystemWorkWithCompileCommandsAction wwCmdsAction; + // ------------------- + // property descriptors + // ------------------- + private static PropertyDescriptor[] propertyDescriptorArray = null; + + /** + * Returns any actions that should be contributed to the popup menu + * for the given element. + * @param menu The menu to contribute actions to + * @param selection The window's current selection. + * @param shell Shell of viewer + * @param menuGroup recommended menu group to add actions to. If added to another group, you must be sure to create that group first. + */ + public void addActions(SystemMenuManager menu, IStructuredSelection selection, Shell shell, String menuGroup) { + if (!actionsCreated) createActions(); + wwCmdsAction.setShell(shell); + menu.add(menuGroup, wwCmdsAction); + } + + private void createActions() { + actionsCreated = true; + wwCmdsAction = new SystemWorkWithCompileCommandsAction(null, true); + } + + /** + * Returns an image descriptor for the image. More efficient than getting the image. + * @param element The element for which an image is desired + */ + public ImageDescriptor getImageDescriptor(Object element) { + return ((SystemTeamViewCompileTypeNode) element).getImageDescriptor(); + } + + /** + * Return the label for this object + */ + public String getText(Object element) { + return ((SystemTeamViewCompileTypeNode) element).getLabel(); + } + + /** + * Return the name of this object, which may be different than the display text ({#link #getText(Object)}. + *

+ * Called by common rename and delete actions. + */ + public String getName(Object element) { + return ((SystemTeamViewCompileTypeNode) element).getLabel(); + } + + /** + * Return the absolute name, versus just display name, of this object + */ + public String getAbsoluteName(Object element) { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode) element; + ISystemProfile profile = type.getProfile(); + return profile.getName() + "." + type.getLabel(); //$NON-NLS-1$ + } + + /** + * Return the type label for this object + */ + public String getType(Object element) { + return UserActionsResources.RESID_PROPERTY_TEAM_COMPILETYPE_TYPE_VALUE; + } + + /** + * Return the string to display in the status line when the given object is selected. + */ + public String getStatusLineText(Object element) { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode) element; + return UserActionsResources.RESID_PROPERTY_TEAM_COMPILETYPE_TYPE_VALUE + ": " + type.getLabel(); //$NON-NLS-1$ + } + + /** + * Return the parent of this object. We return the RemoteSystemsConnections project + */ + public Object getParent(Object element) { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode) element; + return type.getParentSubSystemFactory(); + } + + /** + * Return the children of this profile. + */ + public Object[] getChildren(IProgressMonitor mon, IAdaptable element) { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode) element; + SystemCompileCommand[] cmds = type.getCompileType().getCompileCommandsArray(); + SystemTeamViewCompileCommandNode[] nodes = null; + if (cmds != null) { + nodes = new SystemTeamViewCompileCommandNode[cmds.length]; + for (int idx = 0; idx < cmds.length; idx++) + nodes[idx] = new SystemTeamViewCompileCommandNode(type, cmds[idx]); + } + return nodes; + } + + /** + * Return true if this profile has children. We return true. + */ + public boolean hasChildren(IAdaptable element) { + return true; + } + + // Property sheet descriptors defining all the properties we expose in the Property Sheet + /** + * Return our unique property descriptors, which getPropertyDescriptors adds to the common properties. + */ + protected org.eclipse.ui.views.properties.IPropertyDescriptor[] internalGetPropertyDescriptors() { + if (propertyDescriptorArray == null) { + propertyDescriptorArray = new PropertyDescriptor[1]; + int idx = 0; + // file types + propertyDescriptorArray[idx] = new PropertyDescriptor(ISystemPropertyConstants.P_COMPILETYPE_TYPES, UserActionsResources.RESID_PROPERTY_COMPILETYPE_TYPES_LABEL); + propertyDescriptorArray[idx].setDescription(UserActionsResources.RESID_PROPERTY_COMPILETYPE_TYPES_DESCRIPTION); + ++idx; + } + return propertyDescriptorArray; + } + + /** + * Returns the current value for the named property. + * The parent handles P_TEXT and P_TYPE only, and we augment that here. + * @param key - the name of the property as named by its property descriptor + * @return the current value of the property + */ + public Object internalGetPropertyValue(Object key) { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode) propertySourceInput; + if (key.equals(ISystemPropertyConstants.P_COMPILETYPE_TYPES)) { + return type.getCompileType().getType(); + } else + return null; + } + // ------------------------------------------------------------ + // METHODS FOR SAVING AND RESTORING EXPANSION STATE OF VIEWER... + // ------------------------------------------------------------ + //we currently don't support re-expanding past the profile level, for performance reasons: + // we don't want to bring all subsystems to life to restore expansion state. + /* + * Return what to save to disk to identify this element in the persisted list of expanded elements. + * + public String getMementoHandle(Object element) + { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode)element; + return type.getMementoHandle(); + }*/ + /* + * Return a short string to uniquely identify the type of resource. + * + public String getMementoHandleKey(Object element) + { + SystemTeamViewCompileTypeNode type = (SystemTeamViewCompileTypeNode)element; + return type.getProfile().getName() + "." + type.getParentCategory().getLabel() +"." + type.getParentSubSystemFactory().getName() + "." + type.getLabel(); + }*/ +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeNode.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeNode.java new file mode 100644 index 00000000000..8c2e56a0c68 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewCompileTypeNode.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.compile.teamview; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.internal.ui.view.team.SystemTeamViewCategoryNode; +import org.eclipse.rse.internal.ui.view.team.SystemTeamViewSubSystemConfigurationNode; +import org.eclipse.rse.useractions.ui.compile.SystemCompileType; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +//import com.ibm.etools.systems.subsystems.SubSystemFactory; +/** + * This class represents a compile type node in the Team view. + */ +public class SystemTeamViewCompileTypeNode implements IAdaptable { + //private String mementoHandle; + private SystemCompileType type; + private SystemTeamViewSubSystemConfigurationNode parentSSF; + + /** + * Constructor + */ + public SystemTeamViewCompileTypeNode(SystemTeamViewSubSystemConfigurationNode parentSSF, SystemCompileType type) { + super(); + this.type = type; + this.parentSSF = parentSSF; + } + + /** + * This is the method required by the IAdaptable interface. + * Given an adapter class type, return an object castable to the type, or + * null if this is not possible. + */ + public Object getAdapter(Class adapterType) { + return Platform.getAdapterManager().getAdapter(this, adapterType); + } + + /** + * Compare this node to another. + */ + public boolean equals(Object o) { + if (o instanceof SystemTeamViewCompileTypeNode) { + SystemTeamViewCompileTypeNode other = (SystemTeamViewCompileTypeNode) o; + if ((type == other.getCompileType()) && parentSSF.equals(other.getParentSubSystemFactory())) + return true; + else + return false; + } else + return super.equals(o); + } + + /** + * Return this node's image + * @return the image to show in the tree, for this node + */ + public ImageDescriptor getImageDescriptor() { + //return RSEUIPlugin.getDefault().getImageDescriptor(ISystemConstants.ICON_SYSTEM_FILE_ID); + return PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FILE); // + } + + /** + * Return this node's label + * @return the translated label to show in the tree, for this node + */ + public String getLabel() { + return type.toString(); + } + + /** + * @return profile this category is associated with + */ + public ISystemProfile getProfile() { + return parentSSF.getProfile(); + } + + /* + * @return the untranslated value to store in the memento, to uniquely identify this node + * + public String getMementoHandle() + { + return mementoHandle; + }*/ + /* + * Set the untranslated value to store in the memento, to uniquely identify this node + * @param string - untranslated value + * + public void setMementoHandle(String string) + { + mementoHandle = string; + }*/ + /** + * Return the compile type this node represents + */ + public SystemCompileType getCompileType() { + return type; + } + + /** + * Set the compile type this node represents + */ + public void setCompileType(SystemCompileType type) { + this.type = type; + } + + /** + * Return the grandparent category this is a grandchild of. + */ + public SystemTeamViewCategoryNode getParentCategory() { + return parentSSF.getParentCategory(); + } + + /** + * Return the parent subsystem factory this is a child of. + */ + public SystemTeamViewSubSystemConfigurationNode getParentSubSystemFactory() { + return parentSSF; + } + + /** + * Set the parent subsystem factory this is a child of. + */ + public void setParentSubSystemFactory(SystemTeamViewSubSystemConfigurationNode factory) { + parentSSF = factory; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewUserActionAdapter.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewUserActionAdapter.java new file mode 100644 index 00000000000..6cba2e28cdb --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/compile/teamview/SystemTeamViewUserActionAdapter.java @@ -0,0 +1,209 @@ +package org.eclipse.rse.useractions.ui.compile.teamview; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.internal.ui.view.SystemViewResources; +import org.eclipse.rse.ui.SystemMenuManager; +import org.eclipse.rse.ui.view.AbstractSystemViewAdapter; +import org.eclipse.rse.ui.view.ISystemPropertyConstants; +import org.eclipse.rse.ui.view.ISystemViewElementAdapter; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionElement; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +/** + * Adapter for displaying and processing user action objects in tree views, such as + * the Team view. + */ +public class SystemTeamViewUserActionAdapter extends AbstractSystemViewAdapter implements ISystemViewElementAdapter { + private boolean actionsCreated = false; + // ------------------- + // property descriptors + // ------------------- + private static PropertyDescriptor[] propertyDescriptorArray = null; + + /** + * Returns any actions that should be contributed to the popup menu + * for the given element. + * @param menu The menu to contribute actions to + * @param selection The window's current selection. + * @param shell Shell of viewer + * @param menuGroup recommended menu group to add actions to. If added to another group, you must be sure to create that group first. + */ + public void addActions(SystemMenuManager menu, IStructuredSelection selection, Shell shell, String menuGroup) { + if (!actionsCreated) createActions(); + //menu.add(menuGroup, copyAction); + } + + private void createActions() { + actionsCreated = true; + } + + /** + * Returns an image descriptor for the image. More efficient than getting the image. + * @param element The element for which an image is desired + */ + public ImageDescriptor getImageDescriptor(Object element) { + SystemUDActionElement action = (SystemUDActionElement) element; + //return action.getImage(); + if (action.isIBM()) { + if (action.isUserChanged()) + return UserActionsIcon.USERACTION_IBMUSR.getImageDescriptor(); + else + return UserActionsIcon.USERACTION_IBM.getImageDescriptor(); + } else + return UserActionsIcon.USERACTION_USR.getImageDescriptor(); + } + + /** + * Return the label for this object + */ + public String getText(Object element) { + SystemUDActionElement action = (SystemUDActionElement) element; + return action.getName(); // hmm, should it be getCommand()? + } + + /** + * Return the name of this object, which may be different than the display text ({#link #getText(Object)}. + *

+ * Called by common rename and delete actions. + */ + public String getName(Object element) { + SystemUDActionElement action = (SystemUDActionElement) element; + return action.getName(); + } + + /** + * Return the absolute name, versus just display name, of this object + */ + public String getAbsoluteName(Object element) { + SystemUDActionElement action = (SystemUDActionElement) element; + return action.getName(); + } + + /** + * Return the type label for this object + */ + public String getType(Object element) { + return UserActionsResources.RESID_PROPERTY_TEAM_USERACTION_TYPE_VALUE; + } + + /** + * Return the string to display in the status line when the given object is selected. + */ + public String getStatusLineText(Object element) { + SystemUDActionElement action = (SystemUDActionElement) element; + return UserActionsResources.RESID_TEAMVIEW_USERACTION_VALUE + ": " + action.getName(); //$NON-NLS-1$ + } + + /** + * Return the parent of this object. We return the RemoteSystemsConnections project + */ + public Object getParent(Object element) { + SystemUDActionElement action = (SystemUDActionElement) element; + return action.getData(); + } + + /** + * Return the children of this profile. + */ + public Object[] getChildren(IProgressMonitor mon, IAdaptable element) { + //SystemUDActionElement action = (SystemUDActionElement)element; + return null; + } + + /** + * Return true if this profile has children. We return false. + */ + public boolean hasChildren(IAdaptable element) { + return false; + } + + // Property sheet descriptors defining all the properties we expose in the Property Sheet + /** + * Return our unique property descriptors, which getPropertyDescriptors adds to the common properties. + */ + protected IPropertyDescriptor[] internalGetPropertyDescriptors() { + if (propertyDescriptorArray == null) { + propertyDescriptorArray = new PropertyDescriptor[4]; + int idx = 0; + // origin + propertyDescriptorArray[idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_ORIGIN, SystemViewResources.RESID_PROPERTY_ORIGIN_LABEL, + SystemViewResources.RESID_PROPERTY_ORIGIN_TOOLTIP); + // command + propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_COMMAND, SystemViewResources.RESID_PROPERTY_COMMAND_LABEL, + SystemViewResources.RESID_PROPERTY_COMMAND_TOOLTIP); + // comment + propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_COMMENT, SystemViewResources.RESID_PROPERTY_COMMENT_LABEL, + SystemViewResources.RESID_PROPERTY_COMMENT_TOOLTIP); + // domain + propertyDescriptorArray[++idx] = createSimplePropertyDescriptor(ISystemPropertyConstants.P_USERACTION_DOMAIN, UserActionsResources.RESID_PROPERTY_USERACTION_DOMAIN_LABEL, + UserActionsResources.RESID_PROPERTY_USERACTION_DOMAIN_TOOLTIP); + } + return propertyDescriptorArray; + } + + /** + * Returns the current value for the named property. + * The parent handles P_TEXT and P_TYPE only, and we augment that here. + * @param key - the name of the property as named by its property descriptor + * @return the current value of the property + */ + public Object internalGetPropertyValue(Object key) { + String name = (String) key; + SystemUDActionElement action = (SystemUDActionElement) propertySourceInput; + //action.get + if (name.equals(ISystemPropertyConstants.P_ORIGIN)) { + if (action.isIBM()) { + if (action.isUserChanged()) + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBMUSER_VALUE; + else + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBM_VALUE; + } else + return UserActionsResources.RESID_PROPERTY_ORIGIN_USER_VALUE; + } else if (name.equals(ISystemPropertyConstants.P_COMMAND)) { + return action.getCommand(); + } else if (name.equals(ISystemPropertyConstants.P_COMMENT)) { + return action.getComment(); + } else if (name.equals(ISystemPropertyConstants.P_USERACTION_DOMAIN)) { + int domain = action.getDomain(); + if (domain == -1) + return UserActionsResources.RESID_PROPERTY_USERACTION_DOMAIN_ALL_VALUE; + else + return action.getManager().getActionSubSystem().getXlatedDomainNames()[domain]; + } else + return null; + } + + // ------------------------------------------------------------ + // METHODS FOR SAVING AND RESTORING EXPANSION STATE OF VIEWER... + // ------------------------------------------------------------ + /** + * Return what to save to disk to identify this element in the persisted list of expanded elements. + */ + public String getMementoHandle(Object element) { + return null; // not needed now as we don't re-expand to this level + } + + /** + * Return a short string to uniquely identify the type of resource. + */ + public String getMementoHandleKey(Object element) { + return null; // not needed now as we don't re-expand to this level + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileCommandPropertyPage.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileCommandPropertyPage.java new file mode 100644 index 00000000000..9094fc3cf1e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileCommandPropertyPage.java @@ -0,0 +1,186 @@ +package org.eclipse.rse.useractions.ui.propertypages; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.propertypages.SystemBasePropertyPage; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.rse.useractions.ui.compile.ISystemCompileCommandEditPaneHoster; +import org.eclipse.rse.useractions.ui.compile.ISystemCompileCommandEditPaneListener; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommand; +import org.eclipse.rse.useractions.ui.compile.SystemCompileCommandEditPane; +import org.eclipse.rse.useractions.ui.compile.SystemCompileManager; +import org.eclipse.rse.useractions.ui.compile.teamview.SystemTeamViewCompileCommandNode; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * The property page for compile command nodes in the Team view. + * This is an output-only page. + */ +public class SystemTeamViewCompileCommandPropertyPage extends SystemBasePropertyPage implements ISystemCompileCommandEditPaneHoster, ISystemCompileCommandEditPaneListener { + protected SystemCompileManager compileManager; + protected SystemCompileCommandEditPane editpane; + protected Label labelType, labelProfile, labelOrigin, ccLabel; + protected Composite composite_prompts; + protected boolean initDone = false; + protected int nbrColumns; + + /** + * Constructor + */ + public SystemTeamViewCompileCommandPropertyPage() { + super(); + } + + /** + * We do want the Apply and the Default buttons + */ + protected boolean wantDefaultAndApplyButton() { + return true; + } + + /** + * Create the page's GUI contents. + * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite) + */ + protected Control createContentArea(Composite parent) { + // Inner composite + nbrColumns = 2; + composite_prompts = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // Type prompt + String typeLabel = SystemResources.RESID_PP_PROPERTIES_TYPE_LABEL; + String typeTooltip = SystemResources.RESID_PP_PROPERTIES_TYPE_TOOLTIP; + labelType = SystemWidgetHelpers.createLabeledLabel(composite_prompts, typeLabel, typeTooltip, false); + labelType.setText(UserActionsResources.RESID_PP_COMPILECMD_TYPE_VALUE); + // Profile prompt + String profileLabel = UserActionsResources.RESID_PP_COMPILECMD_PROFILE_LABEL; + String profileTooltip = UserActionsResources.RESID_PP_COMPILECMD_PROFILE_TOOLTIP; + labelProfile = createLabeledLabel(composite_prompts, profileLabel, profileTooltip); + // Source Type prompt + String origPromptLabel = UserActionsResources.RESID_PP_COMPILECMD_ORIGIN_LABEL; + String origPromptTooltip = UserActionsResources.RESID_PP_COMPILECMD_ORIGIN_TOOLTIP; + labelOrigin = createLabeledLabel(composite_prompts, origPromptLabel, origPromptTooltip); + // now add a top spacer line and visual separator line, for the edit pane + addFillerLine(composite_prompts, nbrColumns); + ccLabel = SystemWidgetHelpers.createLabel(composite_prompts, ""); //$NON-NLS-1$ + ((GridData) ccLabel.getLayoutData()).horizontalSpan = nbrColumns; + addSeparatorLine(composite_prompts, nbrColumns); + if (!initDone) doInitializeFields(); + return composite_prompts; + } + + /** + * From parent: do full page validation + */ + protected boolean verifyPageContents() { + return true; + } + + /** + * Get the input node + */ + protected SystemTeamViewCompileCommandNode getCompileCommand() { + Object element = getElement(); + return ((SystemTeamViewCompileCommandNode) element); + } + + /** + * Initialize values of input fields based on input + */ + protected void doInitializeFields() { + initDone = true; + SystemTeamViewCompileCommandNode cmd = getCompileCommand(); + // populate GUI... + labelProfile.setText(cmd.getProfile().getName()); + labelOrigin.setText(getOrigin(cmd.getCompileCommand())); + // edit pane + compileManager = cmd.getCompileCommand().getParentType().getParentProfile().getParentManager(); + ISubSystemConfiguration ssf = compileManager.getSubSystemFactory(); + boolean caseSensitive = true; + if (ssf != null) caseSensitive = ssf.isCaseSensitive(); + editpane = compileManager.getCompileCommandEditPane(getShell(), this, caseSensitive); + Control editpaneComposite = editpane.createContents(composite_prompts); + ((GridData) editpaneComposite.getLayoutData()).horizontalSpan = nbrColumns; + editpane.addChangeListener(this); + editpane.isComplete();// side effect is initial enablement of test button + editpane.setCompileCommand(cmd.getCompileCommand().getParentType(), cmd.getCompileCommand()); + editpane.configureHeadingLabel(ccLabel); // sets the heading for edit mode + } + + /** + * Get xlated origin value + */ + private String getOrigin(SystemCompileCommand cmd) { + if (cmd.isIBMSupplied()) { + if (!cmd.getCurrentString().equals(cmd.getDefaultString())) + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBMUSER_VALUE; + else + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBM_VALUE; + } else if (cmd.isISVSupplied()) { + if (!cmd.getCurrentString().equals(cmd.getDefaultString())) + return UserActionsResources.RESID_PROPERTY_ORIGIN_ISVUSER_VALUE; + else + return UserActionsResources.RESID_PROPERTY_ORIGIN_ISV_VALUE; + } else + return UserActionsResources.RESID_PROPERTY_ORIGIN_USER_VALUE; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.compile.ISystemCompileCommandEditPaneListener#compileCommandChanged(com.ibm.etools.systems.core.ui.messages.SystemMessage) + */ + public void compileCommandChanged(SystemMessage message) { + if (message == null) + clearErrorMessage(); + else + setErrorMessage(message); + } + + /** + * Intercept of parent. + * Called when user presses OK. + */ + public boolean performOk() { + boolean ok = super.performOk(); + if (!ok || (editpane.verify() != null)) // verify will call back to compileCommandChanged + return false; + SystemCompileCommand editedCompileCmd = editpane.saveChanges(); + ok = (editedCompileCmd != null); + if (!ok) return false; + getCompileCommand().getCompileCommand().getParentType().getParentProfile().writeToDisk(); + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_CHANGED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_COMPILECMD, editedCompileCmd, null); + return ok; + } + + /** + * Called by parent when user presses Default button + */ + public void performDefaults() { + editpane.clearErrorMessage(); + SystemTeamViewCompileCommandNode cmd = getCompileCommand(); + editpane.setCompileCommand(cmd.getCompileCommand().getParentType(), cmd.getCompileCommand()); + clearErrorMessage(); + } + + /** + * Called by parent when user presses OK button + */ + public boolean performCancel() { + return super.performCancel(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileTypePropertyPage.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileTypePropertyPage.java new file mode 100644 index 00000000000..a19301e2f59 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewCompileTypePropertyPage.java @@ -0,0 +1,87 @@ +package org.eclipse.rse.useractions.ui.propertypages; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.propertypages.SystemBasePropertyPage; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.rse.useractions.ui.compile.teamview.SystemTeamViewCompileTypeNode; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * The property page for compile type nodes in the Team view. + * This is an output-only page. + */ +public class SystemTeamViewCompileTypePropertyPage extends SystemBasePropertyPage { + protected Label labelType, labelProfile, labelFileType; + protected String errorMessage; + protected boolean initDone = false; + + /** + * Constructor + */ + public SystemTeamViewCompileTypePropertyPage() { + super(); + } + + /** + * Create the page's GUI contents. + * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite) + */ + protected Control createContentArea(Composite parent) { + // Inner composite + Composite composite_prompts = SystemWidgetHelpers.createComposite(parent, 2); + // Type prompt + String typeLabel = SystemResources.RESID_PP_PROPERTIES_TYPE_LABEL; + String typeTooltip = SystemResources.RESID_PP_PROPERTIES_TYPE_TOOLTIP; + labelType = createLabeledLabel(composite_prompts, typeLabel, typeTooltip); + labelType.setText(UserActionsResources.RESID_PP_COMPILETYPE_TYPE_VALUE); + // Profile prompt + String profileLabel = UserActionsResources.RESID_PP_COMPILETYPE_PROFILE_LABEL; + String profileTooltip = UserActionsResources.RESID_PP_COMPILETYPE_PROFILE_TOOLTIP; + labelProfile = createLabeledLabel(composite_prompts, profileLabel, profileTooltip); + // Source Type prompt + String fileTypeLabel = UserActionsResources.RESID_PP_COMPILETYPE_FILETYPE_LABEL; + String fileTypeTooltip = UserActionsResources.RESID_PP_COMPILETYPE_FILETYPE_TOOLTIP; + labelFileType = createLabeledLabel(composite_prompts, fileTypeLabel, fileTypeTooltip); + if (!initDone) doInitializeFields(); + return composite_prompts; + } + + /** + * From parent: do full page validation + */ + protected boolean verifyPageContents() { + return true; + } + + /** + * Get the input node + */ + protected SystemTeamViewCompileTypeNode getCompileType() { + Object element = getElement(); + return ((SystemTeamViewCompileTypeNode) element); + } + + /** + * Initialize values of input fields based on input + */ + protected void doInitializeFields() { + initDone = true; + SystemTeamViewCompileTypeNode type = getCompileType(); + // populate GUI... + labelProfile.setText(type.getProfile().getName()); + labelFileType.setText(type.getCompileType().getType()); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewUserActionPropertyPage.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewUserActionPropertyPage.java new file mode 100644 index 00000000000..03be0cc0e13 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/propertypages/SystemTeamViewUserActionPropertyPage.java @@ -0,0 +1,313 @@ +package org.eclipse.rse.useractions.ui.propertypages; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.propertypages.SystemBasePropertyPage; +import org.eclipse.rse.useractions.UserActionsResources; +import org.eclipse.rse.useractions.ui.uda.ISystemUDAEditPaneHoster; +import org.eclipse.rse.useractions.ui.uda.ISystemUDTreeView; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionEditPane; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDActionSubsystem; +import org.eclipse.rse.useractions.ui.uda.SystemUDBaseManager; +import org.eclipse.rse.useractions.ui.uda.SystemXMLElementWrapper; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TreeItem; + +/** + * The property page for user action nodes in the Team view. + * This is an output-only page. + */ +public class SystemTeamViewUserActionPropertyPage extends SystemBasePropertyPage implements ISystemUDAEditPaneHoster, ISystemUDTreeView { + protected SystemUDActionEditPane editpane; + protected Composite composite_prompts; + protected Label labelType, labelProfile, labelOrigin, labelDomain; + protected String errorMessage; + protected boolean initDone = false; + + /** + * Constructor + */ + public SystemTeamViewUserActionPropertyPage() { + super(); + } + + /** + * We do want the Apply and the Default buttons + */ + protected boolean wantDefaultAndApplyButton() { + return true; + } + + /** + * Create the page's GUI contents. + * @see org.eclipse.jface.preference.PreferencePage#createContents(Composite) + */ + protected Control createContentArea(Composite parent) { + // Inner composite + composite_prompts = SystemWidgetHelpers.createComposite(parent, 2); + // Type prompt + labelType = createLabeledLabel(composite_prompts, SystemResources.RESID_PP_PROPERTIES_TYPE_LABEL, SystemResources.RESID_PP_PROPERTIES_TYPE_TOOLTIP); + labelType.setText(UserActionsResources.RESID_PP_USERACTION_TYPE_VALUE); + // Profile prompt + labelProfile = createLabeledLabel(composite_prompts, UserActionsResources.RESID_PP_USERACTION_PROFILE_LABEL, UserActionsResources.RESID_PP_USERACTION_PROFILE_TOOLTIP); + // Origin prompt + labelOrigin = createLabeledLabel(composite_prompts, UserActionsResources.RESID_PP_USERACTION_ORIGIN_LABEL, UserActionsResources.RESID_PP_USERACTION_ORIGIN_TOOLTIP); + if (!initDone) doInitializeFields(); + return composite_prompts; + } + + /** + * From parent: do full page validation + */ + protected boolean verifyPageContents() { + return true; + } + + /** + * Get the input node + */ + protected SystemUDActionElement getAction() { + Object element = getElement(); + return ((SystemUDActionElement) element); + } + + /** + * Return the user defined action subsystem + */ + protected SystemUDActionSubsystem getUDActionSubsystem(SystemUDActionElement action) { + return action.getManager().getActionSubSystem(); + } + + /** + * Initialize values of input fields based on input + */ + protected void doInitializeFields() { + initDone = true; + SystemUDActionElement action = getAction(); + // populate GUI... + labelProfile.setText(action.getProfile().getName()); + labelOrigin.setText(getOrigin(action)); + // Domain prompt + if (action.getDomain() != -1) { + labelDomain = createLabeledLabel(composite_prompts, UserActionsResources.RESID_PP_USERACTION_DOMAIN_LABEL, UserActionsResources.RESID_PP_USERACTION_DOMAIN_TOOLTIP); + String[] domainNames = action.getManager().getActionSubSystem().getXlatedDomainNames(); + labelDomain.setText(domainNames[action.getDomain()]); + } + addSeparatorLine(composite_prompts, 2); + // add edit pane... + ISubSystemConfiguration ssf = getUDActionSubsystem(action).getSubSystemFactory(); + ISystemProfile profile = action.getProfile(); + editpane = getUDActionSubsystem(action).getCustomUDActionEditPane(null, ssf, profile, this, this); + //System.out.println("UDActionSubsystem is of type: "+getUDActionSubsystem(action).getClass().getName()); + //System.out.println("EditPane is of type: "+editpane.getClass().getName()); + Control c = editpane.createContents(composite_prompts); + ((GridData) c.getLayoutData()).horizontalSpan = 2; + editpane.setAction(action); + } + + /** + * Return xlated string stating where the origin of the given user action is from: + */ + private String getOrigin(SystemUDActionElement action) { + if (action.isIBM()) { + if (action.isUserChanged()) + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBMUSER_VALUE; + else + return UserActionsResources.RESID_PROPERTY_ORIGIN_IBM_VALUE; + } else + return UserActionsResources.RESID_PROPERTY_ORIGIN_USER_VALUE; + } + + /** + * Called by parent when user presses OK or Apply + */ + public boolean performOk() { + boolean ok = super.performOk(); + if (!ok) return false; + editpane.applyPressed(); + return ok; + } + + /** + * Called by parent when user presses Default button + */ + public void performDefaults() { + editpane.revertPressed(); + } + + /** + * Called by parent when user presses OK button + */ + public boolean performCancel() { + return super.performCancel(); + } + + /** + * Identify that the page/dialog is complete + */ + public void setPageComplete(boolean complete) { + setValid(complete); + } + + /** + * Set the help for the given control + */ + public void setHelp(Control c, String id) { + SystemWidgetHelpers.setHelp(c, id); + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#expandDomainNodes() + */ + public void expandDomainNodes() { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#expandDomainNode(java.lang.String) + */ + public void expandDomainNode(String displayName) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getDocumentManager() + */ + public SystemUDBaseManager getDocumentManager() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedElementName() + */ + public String getSelectedElementName() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedElementDomain() + */ + public int getSelectedElementDomain() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#isElementAllSelected() + */ + public boolean isElementAllSelected() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedElement() + */ + public SystemXMLElementWrapper getSelectedElement() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#selectElement(com.ibm.etools.systems.core.ui.uda.SystemXMLElementWrapper) + */ + public void selectElement(SystemXMLElementWrapper element) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#findParentItem(com.ibm.etools.systems.core.ui.uda.SystemXMLElementWrapper) + */ + public TreeItem findParentItem(SystemXMLElementWrapper element) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#refreshElementParent(com.ibm.etools.systems.core.ui.uda.SystemXMLElementWrapper) + */ + public void refreshElementParent(SystemXMLElementWrapper element) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedTreeItem() + */ + public TreeItem getSelectedTreeItem() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedPreviousTreeItem() + */ + public TreeItem getSelectedPreviousTreeItem() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedNextTreeItem() + */ + public TreeItem getSelectedNextTreeItem() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getSelectedNextNextTreeItem() + */ + public TreeItem getSelectedNextNextTreeItem() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#isSelectionVendorSupplied() + */ + public boolean isSelectionVendorSupplied() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#getVendorOfSelection() + */ + public String getVendorOfSelection() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#setSelection(org.eclipse.jface.viewers.ISelection) + */ + public void setSelection(ISelection selection) { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see com.ibm.etools.systems.core.ui.uda.ISystemUDTreeView#refresh(java.lang.Object) + */ + public void refresh(Object element) { + // TODO Auto-generated method stub + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAConstants.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAConstants.java new file mode 100644 index 00000000000..60eede20353 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAConstants.java @@ -0,0 +1,50 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/** + * @author coulthar + * + * Constants used throughout the User Defined Action framework. + */ +public interface ISystemUDAConstants { + /** + * The name of the xml tag for domain tags. + * Domains are used to partition actions. + * Eg, you might have "Folder" and "File" domains + * or for iSeries "Object" and "Member" domains + */ + public static final String XE_DOMAIN = "Domain"; //$NON-NLS-1$ + /** + * The name of the xml attribute of domain tags which + * identifies the domain type. Its values will be + * an untranslated name like "Object" or "Folder". + */ + public static final String XE_DOMTYPE = "Type"; //$NON-NLS-1$ + /** + * The name of the xml attribute of domain tags which + * identifies the domain name. Its values will be + * a translated name like "Object" or "Folder". + */ + public static final String XE_DOMNAME = "Name"; //$NON-NLS-1$ + /** + * The name of the attribute we consistently use to store an element's name + */ + public static final String NAME_ATTR = "Name"; //$NON-NLS-1$ + /** + * The name of the attribute we consistently use to store an element's original IBM-supplied name + */ + public static final String ORIGINAL_NAME_ATTR = "OriginalName"; //$NON-NLS-1$ + /** + * The name of the attribute we consistently use to store a release number + */ + public static final String RELEASE_ATTR = "release"; //$NON-NLS-1$ +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAEditPaneHoster.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAEditPaneHoster.java new file mode 100644 index 00000000000..3bb38295af9 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDAEditPaneHoster.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +//import org.eclipse.jface.viewers.ISelection; +//import org.eclipse.jface.viewers.IStructuredSelection; +//import org.eclipse.jface.viewers.StructuredSelection; +//import org.eclipse.jface.viewers.ISelection; +import org.eclipse.rse.ui.messages.ISystemMessageLine; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +/** + * The interface that must be implemented for any dialog or property page that wants to + * host a user action edit pane. + */ +public interface ISystemUDAEditPaneHoster extends ISystemMessageLine { + /** + * Get the shell for this dialog or property page + */ + public Shell getShell(); + + /** + * Identify that the page/dialog is complete + */ + public void setPageComplete(boolean complete); + + /** + * Set the help for the given control + */ + public void setHelp(Control c, String id); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDSelectTypeListener.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDSelectTypeListener.java new file mode 100644 index 00000000000..248790be0f0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDSelectTypeListener.java @@ -0,0 +1,32 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/** + * @author coulthar + * + * This is an interface for listening for changes made to the + * user-selected list of types for an action. + * Used by the SystemUDSelectTypesForm class. + */ +public interface ISystemUDSelectTypeListener { + /** + * The user has added or removed a type. + * Call getTypes() on given form to get the new list. + */ + public void selectedTypeListChanged(SystemUDSelectTypesForm form); + + /** + * The user has edited the master list of types. It needs to be refreshed. + * You must call setMasterTypes() to update the form's master type list + */ + public void masterTypeListChanged(SystemUDSelectTypesForm form); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTreeView.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTreeView.java new file mode 100644 index 00000000000..52ded6e9a5b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTreeView.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +/* + * Created on Dec 5, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.eclipse.rse.useractions.ui.uda; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TreeItem; + +/** + * @author coulthar + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public interface ISystemUDTreeView { + /** + * Expand the non-new domain (parent) nodes + */ + public abstract void expandDomainNodes(); + + /** + * Expand the given domain (parent) node, named by its + * translatable name. + */ + public abstract void expandDomainNode(String displayName); + + /** + * Convenience method for returning the shell of this viewer. + */ + public abstract Shell getShell(); + + /** + * Return the action or type manager + */ + public abstract SystemUDBaseManager getDocumentManager(); + + /** + * Get the selected action or type name. + * Returns "" if nothing selected + */ + public abstract String getSelectedElementName(); + + /** + * Get the selected action or type domain. + * Returns -1 if nothing selected or domains not supported + */ + public abstract int getSelectedElementDomain(); + + /** + * Return true if currently selected element is "ALL" + */ + public boolean isElementAllSelected(); + + // ------------------------------------ + public abstract SystemXMLElementWrapper getSelectedElement(); + + /** + * Select the given type + */ + public abstract void selectElement(SystemXMLElementWrapper element); + + /** + * Find the parent tree item of the given type. + * If it is not currently shown in the tree, or there is no parent, returns null. + */ + public abstract TreeItem findParentItem(SystemXMLElementWrapper element); + + /** + * Refresh the parent of the given action. + * That is, find the parent and refresh the children. + * If the parent is not found, assume it is because it is new too, + * so refresh the whole tree. + */ + public abstract void refreshElementParent(SystemXMLElementWrapper element); + + /** + * Returns the tree item of the first selected object. + */ + public abstract TreeItem getSelectedTreeItem(); + + /** + * Returns the tree item of the sibling before the first selected object. + */ + public abstract TreeItem getSelectedPreviousTreeItem(); + + /** + * Returns the tree item of the sibling after the first selected object. + */ + public abstract TreeItem getSelectedNextTreeItem(); + + /** + * Returns the tree item of the sibling two after the first selected object. + */ + public abstract TreeItem getSelectedNextNextTreeItem(); + + /** + * Return true if currently selected element is vendor supplied + */ + public boolean isSelectionVendorSupplied(); + + /** + * Return the vendor that is responsible for pre-supplying this existing type, + * or null if not applicable. + */ + public String getVendorOfSelection(); + + /** + * Set the selection + */ + public void setSelection(ISelection selection); + + /** + * Refresh given element + */ + public void refresh(Object element); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTypeEditPaneTypesSelector.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTypeEditPaneTypesSelector.java new file mode 100644 index 00000000000..85cc11e9d1c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDTypeEditPaneTypesSelector.java @@ -0,0 +1,108 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.messages.ISystemMessageLine; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Control; + +/** + * @author coulthar + * + * Within the Work With Files Types dialog is an edit pane + * ({@link org.eclipse.rse.useractions.ui.uda.SystemUDTypeEditPane}) + * that contains an entry field for the name, and then one or + * more widgets that prompt for the file types that constitute + * this named type. + *

+ * This is interface abstracts out the minimal requirements for that + * set of widgets, so that it can be pluggable by subsystems wishing + * to supply customer widgets. These could be as simple as an entry + * field or as complex as a checkbox viewer with add and remove + * buttons. As far as the edit pane class is concerned, it need only + * be able to set the inputs, get the outputs and listen for changes. + * + */ +public interface ISystemUDTypeEditPaneTypesSelector { + /** + * Set domain. + * The edit pane may possibly appear differently, depending on the domain. + * When the domain changes (either in "new" or "edit" mode) this method is called. + */ + public void setDomain(int domain); + + /** + * Set the msg line in case this composite widget needs to issue an error msg + */ + public void setMessageLine(ISystemMessageLine msgLine); + + /** + * Initialize the types. These are stored as a single string using + * a subsystem-decidable delimiter character. This is called when + * entering "edit" mode. + */ + public void setTypes(String types); + + /** + * Clear the types. That is, make sure none are selected. This is + * called when entering "new" mode. + */ + public void clearTypes(); + + /** + * Retrieve the types as a single string. The delimiter used is up to + * the implementor, as long as it knows how to parse and assemble the + * types list as a single string. + */ + public String getTypes(); + + /** + * Allow the edit pane (or any consumer) to be informed as + * changes are made to the list. When events are fired, the consumer + * will call getTypes() to get the new list. + */ + public void addModifyListener(ModifyListener listener); + + /** + * Allow the edit pane (or any consumer) to stop listening as + * changes are made to the list. + */ + public void removeModifyListener(ModifyListener listener); + + /** + * Validate input, and return the error message if an error is found. + * This is called by the consumer upon receipt of a modify event, to + * show any error messages and to know if there are errors pending or + * not. + */ + public SystemMessage validate(); + + /** + * Return the primary input-capable control. + * Used to set focus, among other things. + */ + public Control getControl(); + + /** + * Enable or disable the input-capability of the constituent controls + */ + public void setEnabled(boolean enable); + + /** + * We want to disable editing of IBM or vendor-supplied + * types, so when one of these is selected, this method is + * called to enter non-editable mode. + * @param editable Whether to disable editing of this type or not + * @param vendor When disabling, it contains the name of the vendor for substitution purposes + */ + public void setEditable(boolean editable, String vendor); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDWorkWithDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDWorkWithDialog.java new file mode 100644 index 00000000000..c6c97109a44 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemUDWorkWithDialog.java @@ -0,0 +1,63 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.ui.messages.ISystemMessageLine; + +/** + * A common interface that the action, and types, edit panes for user actions + * implement. + */ +public interface ISystemUDWorkWithDialog { + /** + * Decide if we can do the delete or not. + * Will decide the enabled state of the delete action. + */ + public boolean canDelete(Object selectedObject); + + /** + * Decide if we can do the move up or not. + * Will decide the enabled state of the move up action. + */ + public boolean canMoveUp(Object selectedObject); + + /** + * Decide if we can do the move down or not. + * Will decide the enabled state of the move down action. + */ + public boolean canMoveDown(Object selectedObject); + + /** + * Decide if we can do the copy or not. + * Will decide the enabled state of the copy action. + */ + public boolean canCopy(Object selectedObject); + + /** + * Return the message line + */ + public ISystemMessageLine getMessageLine(); + + /** + * Return true if changes are pending in the edit pane + */ + public boolean areChangesPending(); + + /** + * Process the apply button + */ + public void processApply(); + + /** + * Process the revert button + */ + public void processRevert(); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemXMLElementWrapperFactory.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemXMLElementWrapperFactory.java new file mode 100644 index 00000000000..76199fc1b05 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/ISystemXMLElementWrapperFactory.java @@ -0,0 +1,33 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.core.model.ISystemProfile; +import org.w3c.dom.Element; + +/** + * @author coulthar + * + * Classes that implement this know how to create the approprate + * subclass of SystemXMLElementWrapper + */ +public interface ISystemXMLElementWrapperFactory { + /** + * Given an xml element node, create an instance of the appropriate + * subclass of SystemXMLElementWrapper to represent it. + */ + public SystemXMLElementWrapper createElementWrapper(Element xmlElementToWrap, ISystemProfile profile, int domain); + + /** + * Return the tag name for these elements. Will be "Action" or "Type" + */ + public String getTagName(); +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemPromptUDADialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemPromptUDADialog.java new file mode 100644 index 00000000000..d524467fcb3 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemPromptUDADialog.java @@ -0,0 +1,79 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemPromptCommandDialog; +import org.eclipse.swt.widgets.Shell; + +/** + * Dialog used when running a user action, which has the prompt option specified. + * This allows the user to edit the resolved command, and the result is placed + * in the output object. + */ +public class SystemPromptUDADialog extends SystemPromptCommandDialog { + /** + * Constructor. + * @param shell The parent window hosting this dialog + * @param command The resolved command from the user action + */ + public SystemPromptUDADialog(Shell shell, String command) { + super(shell, command, SystemUDAResources.RESID_UDA_PROMPTCMD_TITLE); + //setHelp(RSEUIPlugin.HELPPREFIX+"drnp0000"); + } + + /** + * Translated text configuration method. + * Override to return OK button label if you don't want the default + */ + protected String getOKButtonLabel() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_OKBUTTON_LABEL; + } + + /** + * Translated text configuration method. + * Override to return OK button tooltip if you don't want the default + */ + protected String getOKButtonToolTipText() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_OKBUTTON_TOOLTIP; + } + + /** + * Translated text configuration method. + * Override to return Cancel button tooltip if you don't want the default + */ + protected String getCancelButtonToolTipText() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_CANCELBUTTON_TOOLTIP; + } + + /** + * Translated text configuration method. + * Override to return verbage message if you don't want the default + */ + protected String getVerbage() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_VERBAGE_LABEL; + } + + /** + * Translated text configuration method. + * Override to return label for the command prompt, if you don't want the default + */ + protected String getPromptLabel() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_PROMPT_LABEL; + } + + /** + * Translated text configuration method. + * Override to return tooltip text for the command prompt, if you don't want the default + */ + protected String getPromptToolTipText() { + return SystemUDAResources.RESID_UDA_PROMPTCMD_PROMPT_TOOLTIP; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeAction.java new file mode 100644 index 00000000000..7890a0906b8 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeAction.java @@ -0,0 +1,101 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemPreferencesManager; +import org.eclipse.rse.ui.actions.SystemBaseDummyAction; +import org.eclipse.rse.ui.actions.SystemBaseSubMenuAction; +import org.eclipse.rse.useractions.ui.uda.actions.SystemWorkWithUDAsAction; +import org.eclipse.swt.widgets.Shell; + +/** + * A cascading menu action for "User actions->" + */ +public class SystemUDACascadeAction extends SystemBaseSubMenuAction implements ISystemIconConstants, IMenuListener { + private SystemUDActionSubsystem udsubsystem; + //private IStructuredSelection selection; + private SystemWorkWithUDAsAction wwAction; + + /** + * Constructor for the "User Actions" menu item. + * Expansion will either list profiles, or actions, depending on preferences setting + */ + public SystemUDACascadeAction(SystemUDActionSubsystem udsubsystem, IStructuredSelection selection) { + super(SystemUDAResources.ACTION_UDA_CASCADE_LABEL, SystemUDAResources.ACTION_UDA_CASCADE_TOOLTIP, null); + this.udsubsystem = udsubsystem; + super.setSelection(selection); + setCreateMenuEachTime(false); + setPopulateMenuEachTime(true); + } + + /** + * This is called by the parent class, in its getSubMenu() method. + * That in turn is called when this menu is added to its parent menu. + */ + public IMenuManager populateSubMenu(IMenuManager menu) { + menu.addMenuListener(this); + menu.setRemoveAllWhenShown(true); + //menu.setEnabled(true); + menu.add(new SystemBaseDummyAction()); + //((SystemSubMenuManager)menu).setTracing(true); + return menu; + } + + /** + * Called when submenu is about to show, by JFace. + * It is part of the IMenuListener interface, and we are called + * because we registered ourself as a listener in our populateSubMenu + * method. + */ + public void menuAboutToShow(IMenuManager ourSubMenu) { + //System.out.println("UDA submenu AboutToShow():"); + Shell shell = getShell(); + // is cascading-by-profile preference turned off? + //System.out.println("Preference setting: " + SystemPreferencesGlobal.getGlobalSystemPreferences().getCascadeUserActions()); + if (!SystemPreferencesManager.getCascadeUserActions()) { + udsubsystem.addUserActions(ourSubMenu, getSelection(), null, shell); + } + // is cascading-by-profile preference turned on? + else { + ISystemProfile[] activeProfiles = RSEUIPlugin.getTheSystemRegistry().getActiveSystemProfiles(); + for (int idx = 0; idx < activeProfiles.length; idx++) { + SystemBaseSubMenuAction profileAction = new SystemUDACascadeByProfileAction(shell, udsubsystem, getSelection(), activeProfiles[idx]); + ourSubMenu.add(profileAction.getSubMenu()); + } + } + ourSubMenu.add(new Separator(ISystemContextMenuConstants.GROUP_WORKWITH)); + if (wwAction == null) { + wwAction = new SystemWorkWithUDAsAction(shell, udsubsystem.getSubsystem()); + wwAction.setText(SystemUDAResources.RESID_WORKWITH_UDAS_ACTION_LABEL); + wwAction.setToolTipText(SystemUDAResources.RESID_WORKWITH_UDAS_ACTION_TOOLTIP); + wwAction.allowOnMultipleSelection(true); + } + ourSubMenu.appendToGroup(ISystemContextMenuConstants.GROUP_WORKWITH, wwAction); + } + + /** + * Override for debugging + */ + public void setInputs(Shell shell, Viewer v, ISelection selection) { + super.setInputs(shell, v, selection); + //System.out.println("Inside setInputs for SystemCascadeAction"); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeByProfileAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeByProfileAction.java new file mode 100644 index 00000000000..7723d1570a0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDACascadeByProfileAction.java @@ -0,0 +1,76 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.internal.ui.view.SystemViewMenuListener; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseDummyAction; +import org.eclipse.rse.ui.actions.SystemBaseSubMenuAction; +import org.eclipse.swt.widgets.Shell; + +/** + * A cascading submenu action for "User Actions->". + * This is after the first cascade, which lists profiles. + * Here, for that profile, we list actions + */ +public class SystemUDACascadeByProfileAction extends SystemBaseSubMenuAction implements IMenuListener { + private ISystemProfile profile; + private SystemUDActionSubsystem udsubsystem; + + //private IStructuredSelection selection; + /** + * Constructor. + */ + public SystemUDACascadeByProfileAction(Shell shell, SystemUDActionSubsystem udss, IStructuredSelection selection, ISystemProfile profile) { + super(profile.getName(), RSEUIPlugin.getDefault().getImageDescriptor(ISystemIconConstants.ICON_SYSTEM_PROFILE_ID), shell); + this.profile = profile; + this.udsubsystem = udss; + super.setSelection(selection); + setCreateMenuEachTime(false); + setPopulateMenuEachTime(true); + //System.out.println("Inside ctor for SystemUDACascadeByProfileAction"); + } + + /** + * @see org.eclipse.rse.ui.actions.SystemBaseSubMenuAction#getSubMenu() + */ + public IMenuManager populateSubMenu(IMenuManager menu) { + //System.out.println("Inside populateSubMenu for SystemUDACascadeByProfileAction"); + menu.addMenuListener(this); + menu.setRemoveAllWhenShown(true); + //menu.setEnabled(true); + menu.add(new SystemBaseDummyAction()); + return menu; + } + + /** + * Called when submenu is about to show. Called because we + * implement IMenuListener, and registered ourself for this event. + */ + public void menuAboutToShow(IMenuManager ourSubMenu) { + //System.out.println("Inside menuAboutToShow for SystemUDACascadeByProfileAction"); + Shell shell = getShell(); + udsubsystem.addUserActions(ourSubMenu, getSelection(), profile, shell); + } + + /** + * Overridable method from parent that instantiates the menu listener who job is to add mnemonics. + * @param setMnemonicsOnlyOnce true if the menu is static and so mnemonics need only be set once. False if it is dynamic + */ + protected SystemViewMenuListener createMnemonicsListener(boolean setMnemonicsOnlyOnce) { + return new SystemViewMenuListener(false); // our menu is re-built dynamically each time + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAFileTypesForName.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAFileTypesForName.java new file mode 100644 index 00000000000..136bec6adb8 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAFileTypesForName.java @@ -0,0 +1,29 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +public class SystemUDAFileTypesForName { + String name; + String types; + + public SystemUDAFileTypesForName(String p_name, String p_types) { + name = p_name; + types = p_types; + } + + public String getName() { + return name; + } + + public String getTypes() { + return types; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResolvedTypes.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResolvedTypes.java new file mode 100644 index 00000000000..a22dfd2da90 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResolvedTypes.java @@ -0,0 +1,131 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +/** + * + */ +public class SystemUDAResolvedTypes { + protected Vector previousTypes = null; + protected Vector[] UDAFileTypesForNameByDomain; + protected Vector UDAFileTypesForNameNoDomain; + + //private char delimiter = ' '; + // I have done a bit of work in here, but I really have not analyzed this logic + // to see what its doing, and if its doing it all correctly. Phil. + /** + * Constructor when using blank as the type delimiter + */ + public SystemUDAResolvedTypes() { + previousTypes = null; + } + + /* + * Constructor when specifying your own character as the type delimiter + * + public UDAResolvedTypes(char delimiter) + { + previousTypes = null; + this.delimiter = delimiter; + }*/ + /** + * + */ + protected void addTypesToVector(Vector v, Object[] objElems) { + for (int i = 0; i < objElems.length; i++) { + SystemUDTypeElement typeElem = (SystemUDTypeElement) objElems[i]; + String name = typeElem.toString(); + resolveType(name, v, objElems); + } + } + + /** + * + */ + protected String resolveTypes(String types, Vector v, Object[] objElems) { + int i = types.indexOf("<"); //$NON-NLS-1$ + if (i < 0) return types; + int j = types.indexOf(">"); //$NON-NLS-1$ + if (i >= j) return types; + String type = types.substring(i + 1, j); + String resolvedType = resolveType(type, v, objElems); + return types.substring(0, i) + " " + resolvedType + " " + resolveTypes(types.substring(j + 1), v, objElems); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * + */ + protected String resolveType(String type, Vector v, Object[] objElems) { + if (previousTypes.contains(type)) return ""; //$NON-NLS-1$ + String resolvedTypes = resolveType(type, v); + if (resolvedTypes != null) return resolvedTypes; + for (int i = 0; i < objElems.length; i++) { + SystemUDTypeElement typeElem = (SystemUDTypeElement) objElems[i]; + if (type.equals(typeElem.toString())) { + previousTypes.addElement(type); + resolvedTypes = resolveTypes(typeElem.getTypes(), v, objElems); + previousTypes.remove(type); + v.addElement(new SystemUDAFileTypesForName(type, resolvedTypes)); + return resolvedTypes; + } + } + return ""; //$NON-NLS-1$ + } + + /** + * + */ + protected String resolveType(String type, Vector v) { + for (int i = 0; i < v.size(); i++) { + SystemUDAFileTypesForName typesForName = (SystemUDAFileTypesForName) v.elementAt(i); + if (type.equals(typesForName.getName())) return typesForName.getTypes(); + } + return null; + } + + /** + * Given a named type, return all the types that this typed name represents, + * concatenated as a single string. + * @param name - the named type to be resolved + * @param domain - the domain, expressed in its integer form + */ + public String getFileTypesForTypeName(String name, int domain, SystemUDTypeManager typeMgr) { + Vector typesVector = null; + boolean supportsDomains = typeMgr.getActionSubSystem().supportsDomains(); + boolean needToPopulate = false; + if (supportsDomains) { + if (UDAFileTypesForNameByDomain == null) { + int nbrDomains = typeMgr.getActionSubSystem().getMaximumDomain() + 1; + UDAFileTypesForNameByDomain = new Vector[nbrDomains]; + } + typesVector = UDAFileTypesForNameByDomain[domain]; + if (typesVector == null) { + typesVector = new Vector(); + UDAFileTypesForNameByDomain[domain] = typesVector; + needToPopulate = true; + } + } else { + typesVector = UDAFileTypesForNameNoDomain; + if (typesVector == null) { + typesVector = new Vector(); + UDAFileTypesForNameNoDomain = typesVector; + needToPopulate = true; + } + } + if (needToPopulate) { + previousTypes = new Vector(); // what's this for? + addTypesToVector(typesVector, typeMgr.getTypes(null, domain)); + } + return resolveType(name, typesVector); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.java new file mode 100644 index 00000000000..22e94b4b6eb --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +import org.eclipse.osgi.util.NLS; + +public class SystemUDAResources extends NLS { + private static String BUNDLE_NAME = "org.eclipse.rse.useractions.ui.uda.SystemUDAResources";//$NON-NLS-1$ + // WORK WITH USER DEFINED ACTIONS DIALOG... + public static String RESID_WORKWITH_UDAS_TITLE; + public static String RESID_WORKWITH_UDAS_ACTION_LABEL; + public static String RESID_WORKWITH_UDAS_ACTION_TOOLTIP; + public static String RESID_UDA_TREE_TIP; + public static String RESID_UDA_PROFILE_LABEL; + public static String RESID_UDA_PROFILE_TOOLTIP; + public static String RESID_UDA_APPLY_BUTTON_LABEL; + public static String RESID_UDA_APPLY_BUTTON_TOOLTIP; + public static String RESID_UDA_RESET_BUTTON_LABEL; + public static String RESID_UDA_RESET_BUTTON_TOOLTIP; + public static String RESID_UDA_REVERT_BUTTON_LABEL; + public static String RESID_UDA_REVERT_BUTTON_TOOLTIP; + public static String RESID_UDA_DELETE_BUTTON_LABEL; + public static String RESID_UDA_DELETE_BUTTON_TOOLTIP; + public static String RESID_UDA_COPY_BUTTON_LABEL; + public static String RESID_UDA_COPY_BUTTON_TOOLTIP; + public static String RESID_UDA_ACTION_DELETE; + public static String RESID_UDA_ACTION_MOVEUP; + public static String RESID_UDA_ACTION_MOVEDOWN; + public static String RESID_UDA_ACTION_COPY; + public static String RESID_UDA_ACTION_PASTE; + public static String RESID_UDA_ACTION_RESTORE; + public static String RESID_UDA_COPY_NAME_1; + public static String RESID_UDA_COPY_NAME_N; + public static String RESID_UDA_IBM_VERBAGE; + public static String RESID_UDA_VENDOR_VERBAGE; + // WORK WITH USER DEFINED ACTIONS NEW/EDIT PANE ... + public static String RESID_UDA_NAME_LABEL; + public static String RESID_UDA_NAME_TOOLTIP; + public static String RESID_UDA_COMMENT_LABEL; + public static String RESID_UDA_COMMENT_TOOLTIP; + public static String RESID_UDA_COMMAND_LABEL; + public static String RESID_UDA_COMMAND_TOOLTIP; + public static String RESID_UDA_INSERTVAR_BUTTON_LABEL; + public static String RESID_UDA_INSERTVAR_BUTTON_TOOLTIP; + public static String RESID_UDA_EDIT_BUTTON_LABEL; + public static String RESID_UDA_EDIT_BUTTON_TOOLTIP; + public static String RESID_UDA_OPTION_PROMPT_LABEL; + public static String RESID_UDA_OPTION_PROMPT_TOOLTIP; + public static String RESID_UDA_OPTION_SHOW_LABEL; + public static String RESID_UDA_OPTION_SHOW_TOOLTIP; + public static String RESID_UDA_OPTION_REFRESH_LABEL; + public static String RESID_UDA_OPTION_REFRESH_TOOLTIP; + public static String RESID_UDA_OPTION_COLLECT_LABEL; + public static String RESID_UDA_OPTION_COLLECT_TOOLTIP; + public static String RESID_UDA_OPTION_SINGLESEL_LABEL; + public static String RESID_UDA_OPTION_SINGLESEL_TOOLTIP; + public static String RESID_UDA_OPTION_REMOTE_LABEL; + public static String RESID_UDA_OPTION_REMOTE_TOOLTIP; + public static String RESID_UDA_TYPE_LIST_LABEL; + public static String RESID_UDA_TYPE_LIST_TOOLTIP; + public static String RESID_UDA_TYPE_LIST_MASTER_LABEL; + public static String RESID_UDA_TYPE_LIST_MASTER_TOOLTIP; + public static String RESID_UDA_TYPE_LIST_SELECTED_LABEL; + public static String RESID_UDA_TYPE_LIST_SELECTED_TOOLTIP; + public static String RESID_UDA_TYPE_EDIT_BUTTON_LABEL; + public static String RESID_UDA_TYPE_EDIT_BUTTON_TOOLTIP; + public static String RESID_UDA_TYPE_ADD_BUTTON_LABEL; + public static String RESID_UDA_TYPE_ADD_BUTTON_TOOLTIP; + public static String RESID_UDA_TYPE_RMV_BUTTON_LABEL; + public static String RESID_UDA_TYPE_RMV_BUTTON_TOOLTIP; + // PROMPT USER DEFINED ACTION COMMAND DIALOG... + public static String RESID_UDA_PROMPTCMD_TITLE; + public static String RESID_UDA_PROMPTCMD_VERBAGE_LABEL; + public static String RESID_UDA_PROMPTCMD_PROMPT_LABEL; + public static String RESID_UDA_PROMPTCMD_PROMPT_TOOLTIP; + public static String RESID_UDA_PROMPTCMD_OKBUTTON_LABEL; + public static String RESID_UDA_PROMPTCMD_OKBUTTON_TOOLTIP; + public static String RESID_UDA_PROMPTCMD_CANCELBUTTON_LABEL; + public static String RESID_UDA_PROMPTCMD_CANCELBUTTON_TOOLTIP; + // COMMON USER DEFINED ACTION SUBSTITUTION VARIABLES SUPPORT... + public static String RESID_UDA_SUBVAR_ACTION_NAME; + public static String RESID_UDA_SUBVAR_CONNECTION_NAME; + public static String RESID_UDA_SUBVAR_LOCAL_HOSTNAME; + public static String RESID_UDA_SUBVAR_LOCAL_IP; + public static String RESID_UDA_SUBVAR_USER_ID; + public static String RESID_UDA_SUBVAR_SYSTEM_TEMPDIR; + public static String RESID_UDA_SUBVAR_SYSTEM_HOMEDIR; + public static String RESID_UDA_SUBVAR_SYSTEM_HOSTNAME; + public static String RESID_UDA_SUBVAR_SYSTEM_PATHSEP; + public static String RESID_UDA_SUBVAR_SYSTEM_FILESEP; + // Resource type shown in property sheet / delete confirmation dialog for + // UDAs + public static String RESID_UDA_RESOURCE_TYPE; + // WORK WITH USER DEFINED TYPE DIALOG... + public static String RESID_WORKWITH_UDT_TITLE; + public static String RESID_UDT_TREE_TIP; + public static String RESID_UDT_NAME_LABEL; + public static String RESID_UDT_NAME_TOOLTIP; + public static String RESID_UDT_TYPES_LABEL; + public static String RESID_UDT_TYPES_TOOLTIP; + public static String RESID_UDT_TYPESLIST_LABEL_LABEL; + public static String RESID_UDT_TYPESLIST_LABEL_TOOLTIP; + public static String RESID_UDT_DELETE_BUTTON_LABEL; + public static String RESID_UDT_DELETE_BUTTON_TOOLTIP; + public static String RESID_UDT_IBM_VERBAGE; + public static String RESID_UDT_VENDOR_VERBAGE; + // Resource type shown in property sheet / delete confirmation dialog for + // UDTs + public static String RESID_UDT_RESOURCE_TYPE; + // UNIVERSAL FILE SYSTEM USER DEFINED ACTION SUPPORT... + public static String RESID_UDA_FILES_DOMAIN_FOLDER; + public static String RESID_UDA_FILES_DOMAIN_FILE; + public static String RESID_UDA_FILES_DOMAIN_NEWFOLDER; + public static String RESID_UDA_FILES_DOMAIN_NEWFILE; + public static String RESID_UDA_FILES_NEWNODE_LABEL; + // UNIVERSAL FILE SYSTEM USER DEFINED TYPE SUPPORT... + public static String RESID_UDT_FILES_DOMAIN_NEWFOLDER; + public static String RESID_UDT_FILES_DOMAIN_NEWFILE; + public static String RESID_UDT_FILES_TYPESGROUP_LABEL; + public static String RESID_UDT_FILES_TYPESGROUP_TOOLTIP; + public static String RESID_UDT_FILES_DEFINEDTYPES_LABEL; + public static String RESID_UDT_FILES_DEFINEDTYPES_TOOLTIP; + public static String RESID_UDT_FILES_USERTYPES_LABEL; + public static String RESID_UDT_FILES_USERTYPES_TOOLTIP; + // UNIVERSAL RUN COMMAND DIALOG + public static String RESID_UCMD_RUN_IN_NEW_SHELL; + public static String RESID_UCMD_RUN_COMMAND; + public static String RESID_UCMD_COMMAND; + public static String RESID_UCMD_COMAMND_SHELL; + public static String RESID_UCMD_RUN_IN_NEW_SHELL_LABEL; + public static String RESID_UCMD_RUN_IN_NEW_SHELL_TOOLTIP; + public static String RESID_UCMD_RUN_COMMAND_LABEL; + public static String RESID_UCMD_COMMAND_LABEL; + public static String RESID_UCMD_COMMAND_TOOLTIP; + public static String RESID_UCMD_COMAMND_SHELL_LABEL; + // UNIVERSAL FILE SYSTEM UDA SUPPORT... + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_DATE; + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_NAME; + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_PATH; + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_NAME_ROOT; + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_NAME_EXT; + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_PATH_ROOT; + public static String RESID_UDA_FILES_SUBVAR_RESOURCE_PATH_DRIVE; + public static String RESID_UDA_FILES_SUBVAR_CONTAINER_NAME; + public static String RESID_UDA_FILES_SUBVAR_CONTAINER_PATH; + // UNIVERSAL FILE SYSTEM COMPILE COMMAND SUPPORT... + public static String RESID_COMPILE_FILES_SUBVAR_ACTION_NAME; + public static String RESID_COMPILE_FILES_SUBVAR_CONNECTION_NAME; + public static String RESID_COMPILE_FILES_SUBVAR_LOCAL_HOSTNAME; + public static String RESID_COMPILE_FILES_SUBVAR_LOCAL_IP; + public static String RESID_COMPILE_FILES_SUBVAR_USER_ID; + public static String RESID_COMPILE_FILES_SUBVAR_SYSTEM_TEMPDIR; + public static String RESID_COMPILE_FILES_SUBVAR_SYSTEM_HOMEDIR; + public static String RESID_COMPILE_FILES_SUBVAR_SYSTEM_HOSTNAME; + public static String RESID_COMPILE_FILES_SUBVAR_SYSTEM_PATHSEP; + public static String RESID_COMPILE_FILES_SUBVAR_SYSTEM_FILESEP; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_DATE; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME_ROOT; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME_EXT; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH_ROOT; + public static String RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH_DRIVE; + public static String RESID_COMPILE_FILES_SUBVAR_CONTAINER_NAME; + public static String RESID_COMPILE_FILES_SUBVAR_CONTAINER_PATH; + // WORK WITH COMPILE COMMANDS DIALOG... + public static String RESID_WWCOMPCMDS_TITLE; + public static String RESID_WWCOMPCMDS_PROFILE_LABEL; + public static String RESID_WWCOMPCMDS_PROFILE_TOOLTIP; + public static String RESID_WWCOMPCMDS_TYPES_LABEL; + public static String RESID_WWCOMPCMDS_TYPES_TOOLTIP; + public static String RESID_WWCOMPCMDS_TYPES_BUTTON_ADD_LABEL; + public static String RESID_WWCOMPCMDS_TYPES_BUTTON_ADD_TOOLTIP; + public static String RESID_WWCOMPCMDS_TYPES_BUTTON_CHG_LABEL; + public static String RESID_WWCOMPCMDS_TYPES_BUTTON_CHG_TOOLTIP; + public static String RESID_WWCOMPCMDS_TYPES_BUTTON_RMV_LABEL; + public static String RESID_WWCOMPCMDS_TYPES_BUTTON_RMV_TOOLTIP; + public static String RESID_WWCOMPCMDS_LIST_LABEL; + public static String RESID_WWCOMPCMDS_LIST_TOOLTIP; + public static String RESID_WWCOMPCMDS_LIST_NEWITEM; + public static String RESID_WWCOMPCMDS_EDITCMD_LABEL; + public static String RESID_WWCOMPCMDS_EDITCMD_TOOLTIP; + public static String RESID_WWCOMPCMDS_NEWCMD_LABEL; + public static String RESID_WWCOMPCMDS_NEWCMD_TOOLTIP; + public static String RESID_WWCOMPCMDS_CMDLABEL_LABEL; + public static String RESID_WWCOMPCMDS_CMDLABEL_TOOLTIP; + public static String RESID_WWCOMPCMDS_CMD_LABEL; + public static String RESID_WWCOMPCMDS_CMD_TOOLTIP; + public static String RESID_WWCOMPCMDS_BUTTON_CREATE_LABEL; + public static String RESID_WWCOMPCMDS_BUTTON_CREATE_TOOLTIP; + public static String RESID_WWCOMPCMDS_BUTTON_APPLY_LABEL; + public static String RESID_WWCOMPCMDS_BUTTON_APPLY_TOOLTIP; + public static String RESID_WWCOMPCMDS_BUTTON_REVERT_LABEL; + public static String RESID_WWCOMPCMDS_BUTTON_REVERT_TOOLTIP; + // Popup menu actions within this dialog + public static String RESID_WWCOMPCMDS_COPY_NAME_1; + public static String RESID_WWCOMPCMDS_COPY_NAME_N; + // PROMPT COMPILE COMMAND DIALOG... + public static String RESID_COMPILE_PROMPTCMD_TITLE; + public static String RESID_COMPILE_PROMPTCMD_VERBAGE_LABEL; + public static String RESID_COMPILE_PROMPTCMD_PROMPT_LABEL; + public static String RESID_COMPILE_PROMPTCMD_PROMPT_TOOLTIP; + public static String RESID_COMPILE_PROMPTCMD_OKBUTTON_LABEL; + public static String RESID_COMPILE_PROMPTCMD_OKBUTTON_TOOLTIP; + public static String RESID_COMPILE_PROMPTCMD_CANCELBUTTON_TOOLTIP; + // ADD COMPILABLE SOURCE TYPE DIALOG... + public static String RESID_COMPILE_NEWSRCTYPE_TITLE; + public static String RESID_COMPILE_NEWSRCTYPE_VERBAGE_LABEL; + public static String RESID_COMPILE_NEWSRCTYPE_PROMPT_LABEL; + public static String RESID_COMPILE_NEWSRCTYPE_PROMPT_TOOLTIP; + // EDIT COMPILABLE SOURCE TYPE DIALOG... + public static String RESID_COMPILE_EDITSRCTYPED_TITLE; + public static String RESID_COMPILE_EDITSRCTYPE_VERBAGE_LABEL; + public static String RESID_COMPILE_EDITSRCTYPE_PROMPT_LABEL; + public static String RESID_COMPILE_EDITSRCTYPE_PROMPT_TOOLTIP; + public static String RESID_UDA_ACTION_DELETE_LABEL; + public static String RESID_UDA_ACTION_DELETE_TOOLTIP; + public static String RESID_UDA_ACTION_COPY_LABEL; + public static String RESID_UDA_ACTION_COPY_TOOLTIP; + public static String RESID_UDA_ACTION_PASTE_LABEL; + public static String RESID_UDA_ACTION_PASTE_TOOLTIP; + public static String RESID_UDA_ACTION_MOVEUP_LABEL; + public static String RESID_UDA_ACTION_MOVEUP_TOOLTIP; + public static String RESID_UDA_ACTION_MOVEDOWN_LABEL; + public static String RESID_UDA_ACTION_MOVEDOWN_TOOLTIP; + public static String RESID_UDA_ACTION_RESTORE_LABEL; + public static String RESID_UDA_ACTION_RESTORE_TOOLTIP; + public static String RESID_WWCOMPCMDS_ACTION_DELETE_LABEL; + public static String RESID_WWCOMPCMDS_ACTION_DELETE_TOOLTIP; + public static String RESID_WWCOMPCMDS_ACTION_COPY_LABEL; + public static String RESID_WWCOMPCMDS_ACTION_COPY_TOOLTIP; + public static String RESID_WWCOMPCMDS_ACTION_PASTE_LABEL; + public static String RESID_WWCOMPCMDS_ACTION_PASTE_TOOLTIP; + public static String RESID_WWCOMPCMDS_ACTION_MOVEUP_LABEL; + public static String RESID_WWCOMPCMDS_ACTION_MOVEUP_TOOLTIP; + public static String RESID_WWCOMPCMDS_ACTION_MOVEDOWN_LABEL; + public static String RESID_WWCOMPCMDS_ACTION_MOVEDOWN_TOOLTIP; + public static String RESID_WWCOMPCMDS_ACTION_RESTORE_LABEL; + public static String RESID_WWCOMPCMDS_ACTION_RESTORE_TOOLTIP; + public static String ACTION_WORKWITH_UDAS_LABEL; + public static String ACTION_WORKWITH_UDAS_TOOLTIP; + public static String ACTION_WORKWITH_WWUDAS_LABEL; + public static String ACTION_WORKWITH_WWUDAS_TOOLTIP; + public static String ACTION_WORKWITH_NAMEDTYPES_LABEL; + public static String ACTION_WORKWITH_NAMEDTYPES_TOOLTIP; + public static String ACTION_WORKWITH_COMPILE_CMDS_LABEL; + public static String ACTION_WORKWITH_COMPILE_CMDS_TOOLTIP; + public static String ACTION_WORKWITH_WWCOMPILE_CMDS_LABEL; + public static String ACTION_WORKWITH_WWCOMPILE_CMDS_TOOLTIP; + public static String ACTION_UDA_CASCADE_LABEL; + public static String ACTION_UDA_CASCADE_TOOLTIP; + public static String RESID_PREF_UDAS_CASCADEBYPROFILE_LABEL; + public static String RESID_PREF_UDAS_CASCADEBYPROFILE_TOOLTIP; + public static String SystemCompileManager_0; + static { + // load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, SystemUDAResources.class); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.properties b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.properties new file mode 100644 index 00000000000..55ab87eb963 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAResources.properties @@ -0,0 +1,438 @@ +############################################################################### +# Copyright (c) 2002, 2007 IBM Corporation and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### + +# NLS_MESSAGEFORMAT_NONE +# NLS_ENCODING=UTF-8 + +#============================================================= +# WORK WITH USER-DEFINED ACTIONS DIALOG... +#============================================================= +RESID_WORKWITH_UDAS_TITLE=Work With User Actions +RESID_UDA_TREE_TIP=Existing user actions. Press F1 for details. +RESID_UDA_ACTION_DELETE_LABEL=Delete... +RESID_UDA_ACTION_DELETE_TOOLTIP=Delete selected action or type. Will be asked to confirm +RESID_UDA_ACTION_COPY_LABEL=Copy +RESID_UDA_ACTION_COPY_TOOLTIP=Copy selected action or type to clipboard so it can be pasted for a duplication operation +RESID_UDA_ACTION_PASTE_LABEL=Paste +RESID_UDA_ACTION_PASTE_TOOLTIP=Paste action or type from clipboard +RESID_UDA_ACTION_MOVEUP_LABEL=Move up +RESID_UDA_ACTION_MOVEUP_TOOLTIP=Move selected action or type up in the list +RESID_UDA_ACTION_MOVEDOWN_LABEL=Move down +RESID_UDA_ACTION_MOVEDOWN_TOOLTIP=Move selected action or type down in the list +RESID_UDA_ACTION_RESTORE_LABEL=Restore defaults +RESID_UDA_ACTION_RESTORE_TOOLTIP=Restore to original state as supplied by IBM +RESID_UDA_COPY_NAME_1=Copy of %1 +RESID_UDA_COPY_NAME_N=Copy (%2) of %1 +RESID_UDA_IBM_VERBAGE=This action is supplied by IBM and is not editable. +RESID_UDA_VENDOR_VERBAGE=This action is supplied by vendor %1 and is not editable. + +RESID_WORKWITH_UDAS_ACTION_LABEL=Work With User Actions... +RESID_WORKWITH_UDAS_ACTION_TOOLTIP=Work with your user action definitions + + +#============================================================= +# USER-DEFINED ACTION NEW/EDIT PANE... +#============================================================= + +#============================================================= +# USER-DEFINED ACTION RESOURCE TYPE (FOR DELETE CONFIRM DIALOG) +#============================================================= +RESID_UDA_RESOURCE_TYPE= User-defined action + +#============================================================= +# WORK WITH USER-DEFINED (File) Types DIALOG... +#============================================================= +RESID_WORKWITH_UDT_TITLE=Work With Named Types +RESID_UDT_TREE_TIP=Existing named types. Press F1 for details. +RESID_UDT_IBM_VERBAGE=This named type is supplied by IBM and is not editable. +RESID_UDT_VENDOR_VERBAGE=This named type is supplied by vendor %1 and is not editable. + +#============================================================= +# USER-DEFINED ACTION RESOURCE TYPE (FOR DELETE CONFIRM DIALOG) +#============================================================= +RESID_UDT_RESOURCE_TYPE= User-defined file type + +#============================================================= +# PROMPT USER-DEFINED-ACTION COMMAND DIALOG... +#============================================================= +RESID_UDA_PROMPTCMD_TITLE=Prompt User Action Command + +#============================================================= +# PROMPT COMPILE COMMAND DIALOG... +#============================================================= +RESID_COMPILE_PROMPTCMD_TITLE=Prompt Compile Command + + +#============================================================= +# COMMON USER-DEFINED ACTIONS SUBSTITUTION VARIABLES... +#============================================================= +RESID_UDA_SUBVAR_ACTION_NAME = This user action's name +RESID_UDA_SUBVAR_CONNECTION_NAME = The name of the connection expanded to see these resources +RESID_UDA_SUBVAR_LOCAL_HOSTNAME = Local workstation host name +RESID_UDA_SUBVAR_LOCAL_IP = Local workstation IP address +RESID_UDA_SUBVAR_USER_ID = User ID used to make the connection +RESID_UDA_SUBVAR_SYSTEM_TEMPDIR = Temporary directory on the target system +RESID_UDA_SUBVAR_SYSTEM_HOMEDIR = Home directory on the target system, for the connection's user ID +RESID_UDA_SUBVAR_SYSTEM_HOSTNAME = Remote system host name +RESID_UDA_SUBVAR_SYSTEM_PATHSEP = Path separator. ";" on Windows, ":" on Unix and Linux +RESID_UDA_SUBVAR_SYSTEM_FILESEP = File separator. "\\" on Windows, "/" on Unix and Linux + + + +#============================================================= +# UNIVERSAL FILE SUBSYSTEM USER-DEFINED ACTIONS MRI... +#============================================================= +RESID_UDA_FILES_DOMAIN_FOLDER= Folder +RESID_UDA_FILES_DOMAIN_FILE= File +RESID_UDA_FILES_DOMAIN_NEWFOLDER= Folder action +RESID_UDA_FILES_DOMAIN_NEWFILE= File action +RESID_UDA_FILES_NEWNODE_LABEL= New named type... + +#================================================================= +# UNIVERSAL FILE SUBSYSTEM SUBSTITUTION VARIABLES FOR USER ACTIONS +#================================================================= +RESID_UDA_FILES_SUBVAR_RESOURCE_DATE = Last modified date of selected resource +RESID_UDA_FILES_SUBVAR_RESOURCE_NAME = Name of selected resource, unqualified +RESID_UDA_FILES_SUBVAR_RESOURCE_PATH = Path of selected resource, including name +RESID_UDA_FILES_SUBVAR_RESOURCE_NAME_ROOT=Name of selected resource without the extension +RESID_UDA_FILES_SUBVAR_RESOURCE_NAME_EXT=Extension part of the name of the selected resource +RESID_UDA_FILES_SUBVAR_RESOURCE_PATH_ROOT=Root of selected file's path. "c:\\" on Windows, or "/" on others +RESID_UDA_FILES_SUBVAR_RESOURCE_PATH_DRIVE=Drive letter on Windows, empty string on others +RESID_UDA_FILES_SUBVAR_CONTAINER_NAME=Name of folder containing selected resource, unqualified +RESID_UDA_FILES_SUBVAR_CONTAINER_PATH=Path of folder containing selected resource, including name + +#================================================================= +# UNIVERSAL FILE SUBSYSTEM SUBSTITUTION VARIABLES FOR COMPILE ACTIONS +#================================================================= +RESID_COMPILE_FILES_SUBVAR_CONNECTION_NAME = The name of the connection expanded to see these resources +RESID_COMPILE_FILES_SUBVAR_LOCAL_HOSTNAME = Local workstation host name +RESID_COMPILE_FILES_SUBVAR_LOCAL_IP = Local workstation IP address +RESID_COMPILE_FILES_SUBVAR_USER_ID = User ID used to make the connection +RESID_COMPILE_FILES_SUBVAR_SYSTEM_TEMPDIR = Temporary directory on the target system +RESID_COMPILE_FILES_SUBVAR_SYSTEM_HOMEDIR = Home directory on the target system, for the connection's user ID +RESID_COMPILE_FILES_SUBVAR_SYSTEM_HOSTNAME = Remote system host name +RESID_COMPILE_FILES_SUBVAR_SYSTEM_PATHSEP = Path separator. ";" on Windows, ":" on Unix and Linux +RESID_COMPILE_FILES_SUBVAR_SYSTEM_FILESEP = File separator. "\\" on Windows, "/" on Unix and Linux +RESID_COMPILE_FILES_SUBVAR_RESOURCE_DATE = Last modified date of selected resource +RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME = Name of selected resource, unqualified +RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH = Path of selected resource, including name +RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME_ROOT=Name of selected resource without the extension +RESID_COMPILE_FILES_SUBVAR_RESOURCE_NAME_EXT=Extension part of the name of the selected resource +RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH_ROOT=Root of selected file's path. "c:\\" on Windows, or "/" on others +RESID_COMPILE_FILES_SUBVAR_RESOURCE_PATH_DRIVE=Drive letter on Windows, empty string on others +RESID_COMPILE_FILES_SUBVAR_CONTAINER_NAME=Name of folder containing selected resource, unqualified +RESID_COMPILE_FILES_SUBVAR_CONTAINER_PATH=Path of folder containing selected resource, including name + + +#============================================================= +# UNIVERSAL FILE SUBSYSTEM USER-DEFINED TYPES MRI... +#============================================================= +RESID_UDT_FILES_DOMAIN_NEWFOLDER= Folder type +RESID_UDT_FILES_DOMAIN_NEWFILE= File type + +#============================================================= +# SELECT REMOTE FILES RE-USABLE WIDGET... +#============================================================= + +#============================================================= +# WORK WITH COMPILE COMMANDS DIALOG... +#============================================================= +RESID_WWCOMPCMDS_TITLE=Work With Compile Commands +RESID_WWCOMPCMDS_LIST_NEWITEM=New command +# POPUP-MENU ITEMS WITHIN THIS DIALOG +RESID_WWCOMPCMDS_COPY_NAME_1=Copy of %1 +RESID_WWCOMPCMDS_COPY_NAME_N=Copy (%2) of %1 +#============================================================= +# PROMPT FOR NEW COMPILE SOURCE TYPE... +#============================================================= +RESID_COMPILE_NEWSRCTYPE_TITLE=Add Source Type +#============================================================= +# PROMPT FOR EDITING COMPILE SOURCE TYPE... +#============================================================= +RESID_COMPILE_EDITSRCTYPED_TITLE=Edit Source Type +#================================================================= +# UNIVERSAL FILE SUBSYSTEM SUBSTITUTION VARIABLES FOR USER ACTIONS +#================================================================= +ACTION_WORKWITH_UDAS_LABEL=User Actions... +ACTION_WORKWITH_UDAS_TOOLTIP=Create or manage user-defined actions for remote objects + +ACTION_WORKWITH_WWUDAS_LABEL=Work With User Actions... +ACTION_WORKWITH_WWUDAS_TOOLTIP=Create or manage user-defined actions for remote objects + +ACTION_WORKWITH_NAMEDTYPES_LABEL=Named Types... +ACTION_WORKWITH_NAMEDTYPES_TOOLTIP=Create or manage named lists of pre-defined resource types + +ACTION_WORKWITH_COMPILE_CMDS_LABEL=Compile Commands... +ACTION_WORKWITH_COMPILE_CMDS_TOOLTIP=Create or manage commands used to compile selected resources + +ACTION_WORKWITH_WWCOMPILE_CMDS_LABEL=Work With Compile Commands... +ACTION_WORKWITH_WWCOMPILE_CMDS_TOOLTIP=Create or manage commands used to compile selected resources + + +ACTION_UDA_CASCADE_LABEL=User Actions +ACTION_UDA_CASCADE_TOOLTIP=User defined actions for the selected resources + +RESID_PREF_UDAS_CASCADEBYPROFILE_LABEL=Cascade user actions and compile commands by profile +RESID_PREF_UDAS_CASCADEBYPROFILE_TOOLTIP=Cascade the User Actions and Compile pop-up menus by active profile, for remote objects + + + +#============================================================= +# WORK WITH USER-DEFINED ACTIONS DIALOG... +#============================================================= +RESID_UDA_PROFILE_LABEL=Parent profile +RESID_UDA_PROFILE_TOOLTIP=Select profile whose user actions you wish to work with + +RESID_UDA_APPLY_BUTTON_LABEL=Apply +RESID_UDA_APPLY_BUTTON_TOOLTIP=Apply changes + +RESID_UDA_RESET_BUTTON_LABEL=Reset +RESID_UDA_RESET_BUTTON_TOOLTIP=Reset settings + +RESID_UDA_REVERT_BUTTON_LABEL=Revert +RESID_UDA_REVERT_BUTTON_TOOLTIP=Revert changes + +RESID_UDA_DELETE_BUTTON_LABEL=Delete... +RESID_UDA_DELETE_BUTTON_TOOLTIP=Delete selected action + +RESID_UDA_COPY_BUTTON_LABEL=Copy +RESID_UDA_COPY_BUTTON_TOOLTIP=Duplicate this action in the same or different profile + +#============================================================= +# USER-DEFINED ACTION NEW/EDIT PANE... +#============================================================= + +RESID_UDA_NAME_LABEL=Action name +RESID_UDA_NAME_TOOLTIP=Unique name for the action + +RESID_UDA_COMMENT_LABEL=Comment +RESID_UDA_COMMENT_TOOLTIP=Enter a comment to describe this action in more detail + +RESID_UDA_COMMAND_LABEL=Command +RESID_UDA_COMMAND_TOOLTIP=The command string which will be run when the action is invoked + +RESID_UDA_INSERTVAR_BUTTON_LABEL=Insert variable... +RESID_UDA_INSERTVAR_BUTTON_TOOLTIP=Insert a substitution variable into the command, at the cursor + +RESID_UDA_EDIT_BUTTON_LABEL=Edit... +RESID_UDA_EDIT_BUTTON_TOOLTIP=Edit the command string + +RESID_UDA_OPTION_PROMPT_LABEL=Prompt first +RESID_UDA_OPTION_PROMPT_TOOLTIP=Prompt for command parameter changes when the action is invoked + +RESID_UDA_OPTION_SHOW_LABEL=Show action +RESID_UDA_OPTION_SHOW_TOOLTIP=Show this action when it applies + +RESID_UDA_OPTION_REFRESH_LABEL=Refresh after +RESID_UDA_OPTION_REFRESH_TOOLTIP=Refresh information on the selected resources after the action is invoked + +RESID_UDA_OPTION_COLLECT_LABEL=Invoke once +RESID_UDA_OPTION_COLLECT_TOOLTIP=Invoke the action once for all selected objects, versus once for each. The name substitution variable holds the quoted full name of each object, delimited by blanks + +RESID_UDA_OPTION_SINGLESEL_LABEL=Single selection only +RESID_UDA_OPTION_SINGLESEL_TOOLTIP=Show action only if a single object is selected + +RESID_UDA_OPTION_REMOTE_LABEL=Remote command +RESID_UDA_OPTION_REMOTE_TOOLTIP=Command is a remote command versus a local command + +RESID_UDA_TYPE_LIST_LABEL=Resource types for which this action will appear +RESID_UDA_TYPE_LIST_TOOLTIP=Select types to scope this action to + +RESID_UDA_TYPE_LIST_MASTER_LABEL=Defined Types +RESID_UDA_TYPE_LIST_MASTER_TOOLTIP=Master list of all previously defined types + +RESID_UDA_TYPE_LIST_SELECTED_LABEL=Selected Types +RESID_UDA_TYPE_LIST_SELECTED_TOOLTIP=Select list of types to scope this action to + +RESID_UDA_TYPE_EDIT_BUTTON_LABEL=Edit... +RESID_UDA_TYPE_EDIT_BUTTON_TOOLTIP=Edit master list of file types + +RESID_UDA_TYPE_ADD_BUTTON_LABEL=Add> +RESID_UDA_TYPE_ADD_BUTTON_TOOLTIP=Add selected type from master list to the selected list + +RESID_UDA_TYPE_RMV_BUTTON_LABEL= + * It is used to restore shipped defaults of the selected IBM-supplied user action + */ +public class SystemUDARestoreDefaultsActions extends SystemBaseAction { + private SystemUDBaseTreeView parentTree; + + /** + * Constructor + */ + public SystemUDARestoreDefaultsActions(SystemUDBaseTreeView parentTree) { + super(SystemUDAResources.RESID_UDA_ACTION_RESTORE_LABEL, SystemUDAResources.RESID_UDA_ACTION_RESTORE_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptorFromIDE( + ISystemIconConstants.ICON_IDE_REFRESH_ID), null); + allowOnMultipleSelection(false); + this.parentTree = parentTree; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_CHANGE); + setHelp(RSEUIPlugin.HELPPREFIX + "udrd0000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is an IBM-supplied compile command + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentTree.canRestore(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentTree.doRestore(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDASubstVarListCommon.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDASubstVarListCommon.java new file mode 100644 index 00000000000..16b5056d6e7 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDASubstVarListCommon.java @@ -0,0 +1,46 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; + +/** + * @author coulthar + * + * Encapsulation of the substitution variables that are typically common for + * absolutely every subsystem. + */ +public class SystemUDASubstVarListCommon extends SystemCmdSubstVarList { + private static final String[] COMMON_VARNAMES = { "action_name", "connection_name", "local_hostname", "local_ip", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + "system_filesep", "system_homedir", "system_hostname", "system_pathsep", "system_tempdir", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + "user_id" }; //$NON-NLS-1$ + private static final String[] COMMON_VARNAME_DESCRIPTIONS = { SystemUDAResources.RESID_UDA_SUBVAR_ACTION_NAME, SystemUDAResources.RESID_UDA_SUBVAR_CONNECTION_NAME, + SystemUDAResources.RESID_UDA_SUBVAR_LOCAL_HOSTNAME, SystemUDAResources.RESID_UDA_SUBVAR_LOCAL_IP, SystemUDAResources.RESID_UDA_SUBVAR_SYSTEM_FILESEP, + SystemUDAResources.RESID_UDA_SUBVAR_SYSTEM_HOMEDIR, SystemUDAResources.RESID_UDA_SUBVAR_SYSTEM_HOSTNAME, SystemUDAResources.RESID_UDA_SUBVAR_SYSTEM_PATHSEP, + SystemUDAResources.RESID_UDA_SUBVAR_SYSTEM_TEMPDIR, SystemUDAResources.RESID_UDA_SUBVAR_USER_ID }; + private static SystemUDASubstVarListCommon inst = null; + + /** + * Constructor . + * Not to be used directly. Rather, use getSingleton(). + */ + SystemUDASubstVarListCommon() { + super(COMMON_VARNAMES, COMMON_VARNAME_DESCRIPTIONS); + } + + /** + * Return the singleton of this object. No need ever for more than one instance + */ + public static SystemUDASubstVarListCommon getSingleton() { + if (inst == null) inst = new SystemUDASubstVarListCommon(); + return inst; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionEditPane.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionEditPane.java new file mode 100644 index 00000000000..37127f00290 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionEditPane.java @@ -0,0 +1,1213 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.shells.ui.view.ISystemCommandTextModifyListener; +import org.eclipse.rse.ui.ISystemMassager; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.validators.ISystemValidator; +import org.eclipse.rse.ui.validators.ISystemValidatorUniqueString; +import org.eclipse.rse.ui.validators.ValidatorUserActionComment; +import org.eclipse.rse.ui.validators.ValidatorUserActionName; +import org.eclipse.rse.ui.widgets.SystemEditPaneStateMachine; +import org.eclipse.rse.useractions.ui.ISystemCommandTextAdditionalGUIProvider; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.rse.useractions.ui.SystemCommandTextField; +import org.eclipse.rse.useractions.ui.SystemCommandViewerConfiguration; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * This is the default edit pane shown on the right, when + * an action is selected on the left. It is also used when + * "new..." is selected on the left, so there are three states + * for this class: new, edit and not-set. + */ +public class SystemUDActionEditPane implements SelectionListener, // for the checkboxes + ISelectionChangedListener, Listener, ISystemUDSelectTypeListener, ISystemCommandTextAdditionalGUIProvider, ISystemCommandTextModifyListener, MouseListener, KeyListener { + // gui widgets + protected Text textName, textComment; + //protected SourceViewer textCommand; + protected SystemCommandTextField commandField; + //protected SystemUDASourceViewerConfiguration sourceViewerConfiguration; + protected Button promptCB, refreshCB, showCB, singleSelCB, collectCB; + protected Button resetButton; + //protected Button insertVariableButton; + protected Label typesSeparator; + protected SystemUDSelectTypesForm selectTypesForm; + protected boolean menuListenerAdded; + protected String testActionName; + // actions for popup of command SourceViewer + // private Map fGlobalActions= new HashMap(10); + // private List fSelectionActions = new ArrayList(3); + // Current selection not valid if errorMessage not null + protected SystemMessage errorMessage; + protected ISubSystem subsystem; + protected ISubSystemConfiguration subsystemFactory; + protected ISystemProfile profile; + public SystemUDActionElement currentAction; + protected ISystemValidator nameValidator; + //protected ISystemValidator cmdValidator; + protected ISystemValidator cmtValidator; + //protected ISystemMassager cmdMassager; + private boolean isEnabled = false; + private boolean recursiveCall = false; + private boolean ignoreChanges = false; + // entry fields enabled from last selection + private NameModifyListener nameML = new NameModifyListener(); + private NameFocusListener nameFL = new NameFocusListener(); + private CommentModifyListener commentML = new CommentModifyListener(); + //protected SystemWorkWithUDAsDialog parentDialog; + protected ISystemUDAEditPaneHoster parentDialog; + protected ISystemUDTreeView treeView; + // Switch to trigger a tree view refresh when the item's name is changed. + private boolean nameChanged = false; + protected boolean newMode = false; + private int newModeDomain = -1; + private SystemUDTreeViewNewItem newModeNewItem; + private Vector EMPTY_VECTOR = new Vector(); + // state + private boolean grabFocus = true; // grab the focus away from the tree when processing selection events + // state machine + private SystemEditPaneStateMachine stateMachine; + + /** + * Constructor when we have a subsystem or a subsystemconfiguration/profile pair. + */ + public SystemUDActionEditPane(ISubSystem subsys, ISubSystemConfiguration ssf, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + super(); + this.subsystem = subsys; + this.subsystemFactory = (ssf == null) ? subsys.getSubSystemConfiguration() : ssf; + this.profile = (profile == null) ? subsys.getSystemProfile() : profile; + parentDialog = parent; + treeView = tv; + commandField = new SystemCommandTextField(getCommandTextViewerConfiguration()); + testActionName = getUDActionSubsystem().getTestActionName().toLowerCase(); + } + + /** + * Return the user defined action subsystem + */ + protected SystemUDActionSubsystem getUDActionSubsystem() { + // FIXME - uda can't be coupled to subsystem api + // if (subsystem!=null) + // return subsystem.getUDActionSubsystem(); + // else + // { + // ISubsystemFactoryAdapter adapter = (ISubsystemFactoryAdapter)subsystemFactory.getAdapter(ISubsystemFactoryAdapter.class); + // return adapter.getActionSubSystem(subsystemFactory, null); + // } + return null; + } + + /** + * For child classes to return their own subclasses of the default configurator + * used to enable proposal support in the command entry field. + */ + protected SystemCommandViewerConfiguration getCommandTextViewerConfiguration() { + return new SystemCommandViewerConfiguration(); + } + + /** + * For child classes (such as iSeries IFS) that need to dynamically change the command + * entry field configuration, on the fly. + */ + protected void setCommandTextViewerConfiguration(SystemCommandViewerConfiguration cmdAssistant) { + commandField.setCommandTextViewerConfiguration(cmdAssistant); + } + + /** + * For child classes to access current subsystem. If null, use getSubSystemFactory and getProfile + */ + protected ISubSystem getSubSystem() { + return subsystem; + } + + /** + * For child classes to access current subsystem factory. + */ + protected ISubSystemConfiguration getSubSystemFactory() { + return subsystemFactory; + } + + /** + * For child classes to access current profile + */ + protected ISystemProfile getProfile() { + return profile; + } + + /** + * For child classes to access current shell + */ + protected Shell getShell() { + return parentDialog.getShell(); + } + + // ------------------------------ + // CONFIGURATION/INPUT METHODS... + // ------------------------------ + /** + * Set the state machine. + * Called by the UDA dialog + */ + public void setStateMachine(SystemEditPaneStateMachine sm) { + this.stateMachine = sm; + } + + /** + * Set the action name validator + */ + public void setNameValidator(ISystemValidator validator) { + this.nameValidator = validator; + } + + /** + * Set the action comment validator + */ + public void setCommentValidator(ISystemValidator validator) { + this.cmtValidator = validator; + } + + /** + * Set the action command validator. This is called per keystroke as + * the user types the command. + */ + public void setCommandValidator(ISystemValidator validator) { + commandField.setCommandValidator(validator); + } + + /** + * Set the action command massager. This is called before saving the + * command to the persistent store, to allow for massaging what the + * user typed, such as doing intelligent uppercasing. + */ + public void setCommandMassager(ISystemMassager massager) { + commandField.setCommandMassager(massager); + } + + /** + * Set the substitution variable list that Insert Variable will use. + */ + public void setSubstitutionVariableList(SystemCmdSubstVarList varList) { + commandField.setSubstitutionVariableList(varList); + } + + // ------------------------------ + // DATA EXTRACTION METHODS + // ------------------------------ + // ------------------------------ + // EXTERNAL LIFECYCLE METHODS... + // ------------------------------ + /** + * Method createContents. + * @param parent + * @return Control + */ + public Control createContents(Composite parent) { + if (nameValidator == null) nameValidator = new ValidatorUserActionName(); + if (cmtValidator == null) cmtValidator = new ValidatorUserActionComment(); + //Composite composite_prompts = SystemWidgetHelpers.createComposite(parent, 1); // why??? + // Inner composite + final int nbrColumns = 3; // 2 + Composite comp = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // Action name + textName = SystemWidgetHelpers.createLabeledTextField(comp, null, SystemUDAResources.RESID_UDA_NAME_LABEL, SystemUDAResources.RESID_UDA_NAME_TOOLTIP); + ((GridData) textName.getLayoutData()).horizontalSpan = nbrColumns - 1; + // Comment + textComment = SystemWidgetHelpers.createLabeledTextField(comp, null, SystemUDAResources.RESID_UDA_COMMENT_LABEL, SystemUDAResources.RESID_UDA_COMMENT_TOOLTIP); + ((GridData) textComment.getLayoutData()).horizontalSpan = nbrColumns - 1; + // Re-usable command field... + commandField.setMRI(SystemUDAResources.RESID_UDA_COMMAND_LABEL, SystemUDAResources.RESID_UDA_COMMAND_TOOLTIP, SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_LABEL, + SystemUDAResources.RESID_UDA_INSERTVAR_BUTTON_TOOLTIP); + commandField.createContents(comp, nbrColumns, this); + // old way... + /* + Label labelCommand = SystemWidgetHelpers.createLabel(comp,rb,RESID_UDA_COMMAND_ROOT); + String s = labelCommand.getText(); + if (!s.endsWith(":")) + labelCommand.setText(s+":"); + if (!createCommandLabelLineControls(comp, nbrColumns-1)) + ((GridData)labelCommand.getLayoutData()).horizontalSpan = nbrColumns; + + int cmdSpan = nbrColumns; + textCommand = createEditor(comp, cmdSpan, sourceViewerConfiguration); + textCommand.getControl().setToolTipText(rb.getString(RESID_UDA_COMMAND_ROOT_TOOLTIP); + // Insert Variable... button + insertVariableButton = SystemWidgetHelpers.createPushButton(comp, null, rb, ISystemConstants.RESID_UDA_INSERTVAR_BUTTON_ROOT); + // SUBCLASS-SUPPLIED BUTTONS + if (!createExtraButtons(comp, nbrColumns-1)) + addFillerLine(comp, nbrColumns-1); + */ + //Label filler = SystemWidgetHelpers.createLabel(comp, ""); + //((GridData)filler.getLayoutData()).horizontalSpan = nbrColumns; + // SEPARATOR BEFORE OPTIONS + /* + SystemWidgetHelpers.createLabel(comp, ""); + addSeparatorLine(comp, 1); + SystemWidgetHelpers.createLabel(comp, ""); + */ + addFillerLine(comp, nbrColumns); + // OPTION CHECKBOXES + Composite options_composite = SystemWidgetHelpers.createTightComposite(comp, 3); + ((GridData) options_composite.getLayoutData()).horizontalSpan = nbrColumns; + // Prompt before + promptCB = SystemWidgetHelpers.createCheckBox(options_composite, 1, null, SystemUDAResources.RESID_UDA_OPTION_PROMPT_LABEL, SystemUDAResources.RESID_UDA_OPTION_PROMPT_TOOLTIP); + // Refresh after + refreshCB = SystemWidgetHelpers.createCheckBox(options_composite, 1, null, SystemUDAResources.RESID_UDA_OPTION_REFRESH_LABEL, SystemUDAResources.RESID_UDA_OPTION_REFRESH_TOOLTIP); + // Show action + showCB = SystemWidgetHelpers.createCheckBox(options_composite, 1, null, SystemUDAResources.RESID_UDA_OPTION_SHOW_LABEL, SystemUDAResources.RESID_UDA_OPTION_SHOW_TOOLTIP); + // Single selection only + singleSelCB = SystemWidgetHelpers.createCheckBox(options_composite, 1, null, SystemUDAResources.RESID_UDA_OPTION_SINGLESEL_LABEL, SystemUDAResources.RESID_UDA_OPTION_SINGLESEL_TOOLTIP); + // Collect names of selected object into delimited string + collectCB = SystemWidgetHelpers.createCheckBox(options_composite, 1, null, getInvokeOnceLabel(), getInvokeOnceTooltip()); + // SUBCLASS-SUPPLIED OPTION CHECKBOXES + Control[] extraOptions = createExtraOptionCheckBoxes(options_composite); + // SEPARATOR BEFORE TYPES + if (getUDActionSubsystem().supportsTypes()) { + //SystemWidgetHelpers.createLabel(comp, ""); + //typesSeparator = addSeparatorLine(comp, 1); + //SystemWidgetHelpers.createLabel(comp, ""); + addFillerLine(comp, nbrColumns); + } + //Label filler2 = SystemWidgetHelpers.createLabel(comp, ""); + //((GridData)filler2.getLayoutData()).horizontalSpan = nbrColumns; + // TYPE SELECTION FORM + if (subsystem != null) + selectTypesForm = createSelectTypesForm(parentDialog.getShell(), subsystem); + else + selectTypesForm = createSelectTypesForm(parentDialog.getShell(), subsystemFactory, profile); + if (selectTypesForm != null) { + selectTypesForm.createContents(comp, nbrColumns); + } + // CONFIGURE THE WIDGETS... + //resetButton = SystemWidgetHelpers.createPushButton(comp,this,rb,"com.ibm.etools.systems.core.ui.uda.ResetButton."); + //((GridData)resetButton.getLayoutData()).horizontalAlignment = GridData.BEGINNING; + textName.setTextLimit(ValidatorUserActionName.MAX_UDANAME_LENGTH); + textComment.setTextLimit(ValidatorUserActionComment.MAX_UDACMT_LENGTH); + //textName.setEditable(false); + //textComment.setEditable(false); + promptCB.addSelectionListener(this); + refreshCB.addSelectionListener(this); + showCB.addSelectionListener(this); + singleSelCB.addSelectionListener(this); + collectCB.addSelectionListener(this); + if (extraOptions != null) for (int idx = 0; idx < extraOptions.length; idx++) + if (extraOptions[idx] instanceof Button) + ((Button) extraOptions[idx]).addSelectionListener(this); + else if (extraOptions[idx] instanceof Combo) + ((Combo) extraOptions[idx]).addSelectionListener(this); + else if (extraOptions[idx] instanceof org.eclipse.swt.widgets.List) ((org.eclipse.swt.widgets.List) extraOptions[idx]).addSelectionListener(this); + if (selectTypesForm != null) selectTypesForm.addSelectionListener(this); + // ??? id ??? + // SystemWidgetHelpers.setHelp(comp, this, RSEUIPlugin.HELPPREFIX+"cprf0000"); + textName.addModifyListener(nameML); + textName.addFocusListener(nameFL); + textComment.addModifyListener(commentML); + commandField.addModifyListener(this); + return comp; + } + + protected String getInvokeOnceLabel() { + return SystemUDAResources.RESID_UDA_OPTION_COLLECT_LABEL; + } + + protected String getInvokeOnceTooltip() { + return SystemUDAResources.RESID_UDA_OPTION_COLLECT_TOOLTIP; + } + + /** + * Are errors pending? If so, don't allow user to change selection + * or profile or anything! + */ + public boolean areErrorsPending() { + return ((errorMessage != null) && ((currentAction != null) || newMode)); + } + + /** + * This is called when user changes their selection in the left-side tree view + */ + public void selectionChanged(SelectionChangedEvent se) { + if (recursiveCall) return; // ignore! + IStructuredSelection ss = (IStructuredSelection) se.getSelection(); + Object so = ss.getFirstElement(); + if (areErrorsPending()) { + if (newMode || SystemUDBaseManager.inCurrentTree(currentAction.getElement())) { + if (!newMode && (so != currentAction)) + treeView.setSelection(new StructuredSelection(currentAction)); + else if (newMode && (so != newModeNewItem)) treeView.setSelection(new StructuredSelection(newModeNewItem)); + return; + } + } + // We need to test for pending changes, and if any are pending, prompt + // user to continue (and lose changes) or cancel... + if ((stateMachine != null) && stateMachine.isSaveRequired()) { + saveData(); + if (newMode) { + // interesting problem! The save of the new data resulted in a new node, + // but this is not visible in the tree view. To make it visible means we + // we will lose focus, and this method will be recalled recursively... + recursiveCall = true; + treeView.refreshElementParent(currentAction); // show new item in tree view + recursiveCall = false; + if (so instanceof SystemUDActionElement) // if user was selecting an action, it might have a new binary address after the refresh + treeView.selectElement((SystemUDActionElement) so); + else if (so != null) treeView.setSelection(new StructuredSelection(so)); // restore what user selected + return; // avoid recursion! + } + } + recursiveCall = false; + // Clear any page-valid errors remaining from previous selection + // (Since validation on the new selection is only run if editing + // changes are made + errorMessage = null; + resetPageValidation(); + newMode = ((so instanceof SystemUDTreeViewNewItem) && ((SystemUDTreeViewNewItem) so).isExecutable()); + if (newMode) newModeDomain = ((SystemUDTreeViewNewItem) so).getDomain(); + // Refresh tree view if name changed on last item + if (nameChanged) { + nameChanged = false; + if (currentAction != null) treeView.refresh(currentAction); + } + SystemUDActionElement sn = null; + //temp = null; + if ((null != so) && (so instanceof SystemUDActionElement)) sn = (SystemUDActionElement) so; + currentAction = sn; + setIgnoreChanges(true); + boolean changeMode = false; + // entering un-selected mode? we turn invisible for this... + if (!newMode && ((null == sn) || sn.isDomain())) { + isEnabled = false; + textName.setText(""); //$NON-NLS-1$ + textComment.setText(""); //$NON-NLS-1$ + setCommandText(""); //$NON-NLS-1$ + enableExtraButtons(false); + } + // entering new or selected mode? we turn visible for this... + else if (newMode) { + isEnabled = true; + SystemCmdSubstVarList varList = null; + /* + if (!newMode) // existing action selected + { + textName.setText(sn.toString()); + textComment.setText(sn.getComment()); + setCommandText(sn.getCommand()); + + promptCB.setSelection(sn.getPrompt()); + refreshCB.setSelection(sn.getRefresh()); + showCB.setSelection(sn.getShow()); + singleSelCB.setSelection(sn.getSingleSelection()); + collectCB.setSelection( sn.getCollect()); + //if (singleSelCB.getSelection()) + collectCB.setEnabled(!singleSelCB.getSelection()); + resetExtraOptions(sn); + + varList = getActionSubstVarList(sn.getDomain()); + //setEditable(!parentDialog.isSelectionVendorSupplied(), parentDialog.getVendorOfSelection()); todo + } + else // new mode + {*/ + textName.setText(""); //$NON-NLS-1$ + textComment.setText(""); //$NON-NLS-1$ + setCommandText(""); //$NON-NLS-1$ + promptCB.setSelection(false); + refreshCB.setSelection(false); + showCB.setSelection(true); + singleSelCB.setSelection(false); + collectCB.setSelection(false); + resetExtraOptionsForNewMode(); + if (so != null) { + varList = getActionSubstVarList(((SystemUDTreeViewNewItem) so).getDomain()); + } + /*}*/ + // update the substitution variable list + //sourceViewerConfiguration.setSubstVarList(varList); + commandField.setSubstitutionVariableList(varList); + //varList.printDisplayStrings(); // temp. todo - remove + enableExtraButtons(true); + } + // existing action + else { + isEnabled = true; + changeMode = true; + setAction(sn); + } + setIgnoreChanges(false); // re-enable modify listeners + if (newMode) { + //System.out.println("entering New mode"); + stateMachine.setNewMode(); // resets Apply/Reset button status + newModeNewItem = (SystemUDTreeViewNewItem) so; + //System.out.println("newModeDomain = " + newModeDomain); + } else if ((sn == null) || sn.isDomain()) { + //System.out.println("entering Unset mode"); + stateMachine.setUnsetMode(); // resets Apply/Reset button status + } else { + //System.out.println("entering Edit mode"); + stateMachine.setEditMode(); // resets Apply/Reset button status } + } + if (isEnabled && (typesSeparator != null)) { + int domain = getDomain(); + if (domain == -1) + typesSeparator.setVisible(getUDActionSubsystem().supportsTypes()); + else + typesSeparator.setVisible(getUDActionSubsystem().supportsTypes(domain)); + } + if (!changeMode && (selectTypesForm != null)) // already done for change mode + reConfigureSelectTypesForm(selectTypesForm); + if (isEnabled && newMode) // we have already done it for new mode + { + if (grabFocus) { + textName.setFocus(); + } + //if (!wasEnabled) + if (nameValidator instanceof ISystemValidatorUniqueString) { + ((ISystemValidatorUniqueString) nameValidator).setExistingNamesList(getExistingActionNames()); + /* + System.out.println("...got existing names: "); + Vector v = getExistingActionNames(); + for (int idx=0; idx + * The user has added or removed a type. + * Call getTypes() on given form to get the new list. + */ + public void selectedTypeListChanged(SystemUDSelectTypesForm form) { + setChangesMade(); + setPageComplete(); + validateInput(false, null); + } + + /** + * From ISystemUDSelectTypeListener interface, called from + * SystemUDSelectTypesFrom widget. + *

+ * The user has edited the master list of types. It needs to be refreshed. + * We must call setMasterTypes() to update the form's master type list + */ + public void masterTypeListChanged(SystemUDSelectTypesForm form) { + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDTypeManager udtm = udas.getUDTypeManager(); + // Re-populate the master listbox + if (currentAction != null) { + form.setMasterTypes(udtm.getTypeNames(currentAction.getDomain())); + } else if (newMode) { + form.setMasterTypes(udtm.getTypeNames(newModeDomain)); + } + } + + // ------------------------------ + // INTERNAL VALIDATION METHODS... + // ------------------------------ + /** + * Scenario: User edits an item, producing a syntax error. + * (eg. clear action name field) Gets error msg, OK button disabled. + * then changes selection to another item. + * Current Problem: Error msg stays, OK remains disabled, until + * they edit a field. (ValidateInput isnt re-reun until + * another field is changed.) + *

+ * Solution: When changing selection, reset the errorMessage and + * page-valid status. Can get away with this because we + * do not propagate invalid field changes to the UDA data in memory. + */ + private void resetPageValidation() { + // setMessage( null); + errorMessage = null; + parentDialog.clearErrorMessage(); + parentDialog.setPageComplete(true); + } + + /** + * Check all input for errors. + * Subclasses should not override. Rather, they should override + * doAdditionalValidation(boolean) which this method calls. + * @param setFocus - true if to set focus on offending control + * @param skipControl - control to skip since already checked + * @return true if no errors + */ + protected final boolean validateInput(boolean setFocus, Control skipControl) { + Control errCtl = null; + errorMessage = null; + if (skipControl != textName) errorMessage = validateName(textName.getText().trim()); + errCtl = textName; + if ((errorMessage == null) && (skipControl != textComment)) { + errorMessage = validateComment(textComment.getText().trim()); + errCtl = textComment; + } + if ((errorMessage == null) && (skipControl != getCommandWidget())) { + errorMessage = validateCommand(); + errCtl = getCommandWidget(); + } + if (errorMessage == null) errorMessage = doAdditionalValidation(setFocus); // let child classes try + if (errorMessage != null) { + parentDialog.setErrorMessage(errorMessage); + if (setFocus) errCtl.setFocus(); + } else + parentDialog.clearErrorMessage(); + setPageComplete(); + return (errorMessage == null); + } + + /** + * Overridable extension point for subclasses to do validation of options and + * such when Apply is pressed. If you do report an error, consider setting the + * focus to the appropriate widget, if setFocus is set. + * @return error message if an error detected, else null + */ + protected SystemMessage doAdditionalValidation(boolean doSetFocus) { + return null; + } + + /** + * Validate name input + */ + protected SystemMessage validateName(String input) { + return nameValidator.validate(input); + } + + /** + * Validate comment input + */ + protected SystemMessage validateComment(String input) { + return cmtValidator.validate(input); + } + + /** + * Validate command input + */ + protected SystemMessage validateCommand() { + return commandField.validateCommand(); + } + + // ------------------------------------------- + // METHODS FOR USE BY US AND OUR CHILD CLASSES + // ------------------------------------------- + /** + * Return the control widget for the command prompt + */ + protected Control getCommandWidget() { + return commandField.getCommandWidget(); + } + + /** + * Set the text contents of the command widget + */ + protected void setCommandText(String text) { + commandField.setCommandText(text); + } + + /** + * Enable/disable command widget + */ + protected void enableCommandWidget(boolean enable) { + commandField.enableCommandWidget(enable); + } + + /** + * Get the contents of the command field + */ + protected String getCommandText() { + return commandField.getCommandText(); + } + + /** + * Turn on or off event ignoring flag + */ + protected void setIgnoreChanges(boolean ignore) { + ignoreChanges = ignore; + commandField.setIgnoreChanges(ignore); + } + + // ------------------------------ + // INTERNAL METHODS... + // ------------------------------ + /** + * Return true if the page is complete, so to enable Finish. + * Called by setPageComplete + */ + protected boolean isPageComplete() { + return ((errorMessage == null) && (textName.getText().trim().length() > 0) && (getCommandText().length() > 0)); + } + + /** + * Set page complete... enables/disables Apply button + */ + protected void setPageComplete() { + boolean complete = isPageComplete(); + parentDialog.setPageComplete(complete); + } + + /** + * When user presses Apply, commit all pending changes... + */ + protected void processChanges() { + currentAction.setComment(textComment.getText().trim()); + currentAction.setName(textName.getText().trim()); + String cmd = commandField.getMassagedCommandText(); + if (commandField.getCommandMassager() != null) { + if (!newMode) { + setIgnoreChanges(true); // disable modify listeners + setCommandText(cmd); + setIgnoreChanges(false); // re-enable modify listeners + } + } + currentAction.setCommand(cmd); + currentAction.setPrompt(promptCB.getSelection()); + currentAction.setRefresh(refreshCB.getSelection()); + currentAction.setShow(showCB.getSelection()); + currentAction.setSingleSelection(singleSelCB.getSelection()); + currentAction.setCollect(collectCB.getSelection()); + processExtraOptionsChanges(currentAction); + if (selectTypesForm != null) currentAction.setFileTypes(selectTypesForm.getTypes()); + } //process changes + + /** + * Save current state to disk + */ + protected void saveData() { + if (newMode) { + currentAction = createNewAction(textName.getText().trim(), newModeDomain); + } + processChanges(); + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDActionManager udam = udas.getUDActionManager(); + ISystemProfile currentProfile = udam.getCurrentProfile(); + if (currentProfile == null) // shouldn't! + currentProfile = profile; + //subsystem.getUDActionSubsystem().getUDActionManager().saveUserData(); + udam.saveUserData(currentProfile); + // inform anybody registered as listeners that we have created/changed model object... + if (newMode) + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_ADDED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_USERACTION, currentAction, null); + else + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_CHANGED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_USERACTION, currentAction, null); + } + + /** + * Call this whenever the user makes ANY changes. + * Used to enable/disable apply/revert buttons + */ + protected void setChangesMade() { + if (stateMachine != null) stateMachine.setChangesMade(); + } + + /** + * In "new" mode, create a new action when Apply is pressed. + * This only creates the action. It does not populate the attributes + * @return The new action + */ + protected SystemUDActionElement createNewAction(String actionName, int domain) { + // code was originally in SystemNewUDAsWizardMainPage + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDActionManager udam = udas.getUDActionManager(); + ISystemProfile currentProfile = udam.getCurrentProfile(); + if (currentProfile == null) // shouldn't! + currentProfile = profile; + SystemUDActionElement na = udam.addAction(currentProfile, actionName, domain); + // ??? handle failure ??? check for ??? + if (null != na) { + // Set default types to ALL, if ALL is not a type we create it with types string * + if (domain != SystemUDActionSubsystem.DOMAIN_NONE) { + SystemUDTypeManager typeManager = getUDActionSubsystem().getUDTypeManager(); + if (typeManager.findChildByName(currentProfile, SystemUDTypeManager.ALL_TYPE, domain) == null) { + SystemUDTypeElement nt = typeManager.addType(domain, SystemUDTypeManager.ALL_TYPE); + nt.setTypes("*"); //$NON-NLS-1$ + typeManager.saveUserData(currentProfile); + } + // Add the ALL type to the action + String[] types = new String[1]; + types[0] = SystemUDTypeManager.ALL_TYPE; + na.setFileTypes(types); + } + // Now update tree view to show new item, and set selection to it. + //SystemUDActionElement parentEl = (SystemUDActionElement) udas.getUDActionManager().getParent(na); + //treeView.internalRefresh(parentEl); + } + return na; + } + + /** + * For uniqueness checking, get the list of existing action names + */ + protected Vector getExistingActionNames() { + if (newMode) { + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDActionManager udam = udas.getUDActionManager(); + ISystemProfile currentProfile = udam.getCurrentProfile(); + if (currentProfile == null) // shouldn't! + currentProfile = profile; + //System.out.println("Asking for existing names for newModeDomain " + newModeDomain); + return udam.getExistingNames(currentProfile, newModeDomain); + } else if (currentAction != null) + return currentAction.getExistingNames(); + else + return EMPTY_VECTOR; + } + + /** + * Callback from SystemCommandTextField when the user modifies the command. + * @param cmdText - current contents of the field + * @param errorMessage - potential error detected by the default validator + */ + public void commandModified(String cmdText, SystemMessage errorMessage) { + this.errorMessage = errorMessage; + setChangesMade(); + if (errorMessage != null) { + parentDialog.setErrorMessage(errorMessage); + setPageComplete(); + } else + validateInput(false, getCommandWidget()); + processCommandTextChange(cmdText, (errorMessage != null)); + } + + /** + * Method called as user types into the command field + * Encapsulated out so that it can be called from various types of listeners. + * Further, it is easily overridden + */ + protected void processCommandTextChange(String newText, boolean hasError) { + } + + // ----------------------------- + // Helper methods... + // ----------------------------- + /** + * Add a separator line. This is a physically visible line. + */ + protected Label addSeparatorLine(Composite parent, int nbrColumns) { + Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + separator.setLayoutData(data); + return separator; + } + + /** + * Add a spacer line + */ + protected Label addFillerLine(Composite parent, int nbrColumns) { + Label filler = new Label(parent, SWT.LEFT); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + filler.setLayoutData(data); + return filler; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionElement.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionElement.java new file mode 100644 index 00000000000..08189e17f62 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionElement.java @@ -0,0 +1,255 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.StringTokenizer; + +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; + +/** + * Represents a single user defined action, as an adaptable + * eclipse-friendly object + */ +public class SystemUDActionElement extends SystemXMLElementWrapper { + private final static String ACTION_TAG = "Action"; //$NON-NLS-1$ + private final static String COMMENT_TAG = "Comment"; //$NON-NLS-1$ + private final static String COMMAND_TAG = "Command"; //$NON-NLS-1$ + private final static String FILETYPES_TAG = "FileTypes"; //$NON-NLS-1$ + private final static String PROMPT_ATTR = "Prompt"; //$NON-NLS-1$ + private final static String REFRESH_ATTR = "Refresh"; //$NON-NLS-1$ + private final static String COLLECT_ATTR = "Collect"; //$NON-NLS-1$ + private final static String SINGLESEL_ATTR = "SingleSelection"; //$NON-NLS-1$ + private final static String SHOW_ATTR = "Enable"; //$NON-NLS-1$ + //for reseting + private String initCommand; + private Object data; + + /** + * Constructor + * @param e - The actual xml document element for this action + * @param am - The subsystemFactory-specific manager of actions + * @param profile - The system profile which owns this action + * @param domainType - The integer representation of the domain this is in (or this is, for a domain element) + */ + public SystemUDActionElement(Element e, SystemUDActionManager am, ISystemProfile profile, int domainType) { + super(e, am, profile, domainType); + } + + /** + * Return the value of this node's "Name" attribute, but with "..." appended if + * the action is a prompting action. This is used for popup menu labels. + */ + public String getLabel() { + String name = getName(); + if (getPrompt()) name = name + "..."; //$NON-NLS-1$ + return name; + } + + /** + * Return image to use for this item, in tree views + */ + public Image getImage() { + if (isIBM()) { + if (isUserChanged()) + return UserActionsIcon.USERACTION_IBMUSR.getImage(); + else + return UserActionsIcon.USERACTION_IBM.getImage(); + } else + return UserActionsIcon.USERACTION_USR.getImage(); + } + + /** + * Return our tag name + */ + public String getTagName() { + return ACTION_TAG; + } + + /** + * Return value of the "Comment" sub-tag + */ + public String getComment() { + return getTextNode(COMMENT_TAG); + } + + /** + * Return value of the "Command" sub-tag, which is the current command value + */ + public String getCommand() { + return getTextNode(COMMAND_TAG); + } + + /** + * Return value of the "Prompt" attribute + */ + public boolean getPrompt() { + return getBooleanAttribute(PROMPT_ATTR, false); + } + + /** + * Return value of the "Refresh" attribute + */ + public boolean getRefresh() { + return getBooleanAttribute(REFRESH_ATTR, false); + } + + /** + * Return value of the "Show" attribute + */ + public boolean getShow() { + return getBooleanAttribute(SHOW_ATTR, true); + } + + /** + * Return value of the "Collect" attribute + */ + public boolean getCollect() { + return getBooleanAttribute(COLLECT_ATTR, false); + } + + /** + * Return value of the "Single Selection" attribute + */ + public boolean getSingleSelection() { + return getBooleanAttribute(SINGLESEL_ATTR, false); + } + + /** + * Return value of the "FileTypes" sub-tag + */ + public String[] getFileTypes() { + String fts = getTextNode(FILETYPES_TAG); + // returns an empty string if no attribute + StringTokenizer st = new StringTokenizer(fts); + int n = st.countTokens(); + String sa[] = new String[n]; + for (int i = 0; i < n; i++) { + sa[i] = st.nextToken(); + } + return sa; + } + + /** + * Set the value of the "Comment" sub-tag + */ + public void setComment(String s) { + setTextNode(COMMENT_TAG, s); + setUserChanged(true); + } + + /** + * Set the value of the "Command" sub-tag. + */ + public void setCommand(String s) { + setTextNode(COMMAND_TAG, s); + setUserChanged(true); + } + + /** + * Set the value of the "Prompt" attribute + */ + public void setPrompt(boolean b) { + setBooleanAttribute(PROMPT_ATTR, b); + setUserChanged(true); + } + + /** + * Set the value of the "Refresh" attribute + */ + public void setRefresh(boolean b) { + setBooleanAttribute(REFRESH_ATTR, b); + setUserChanged(true); + } + + /** + * Set the value of the "Show" attribute + */ + public void setShow(boolean b) { + setBooleanAttribute(SHOW_ATTR, b); + setUserChanged(true); + } + + /** + * Set the value of the "Collect" attribute + */ + public void setCollect(boolean b) { + setBooleanAttribute(COLLECT_ATTR, b); + setUserChanged(true); + } + + /** + * Set the value of the "Single Selection Only" attribute + */ + public void setSingleSelection(boolean b) { + setBooleanAttribute(SINGLESEL_ATTR, b); + setUserChanged(true); + } + + /** + * Set the value of the "FileTypes" sub-tag + */ + public void setFileTypes(String sa[]) { + String s = ""; //$NON-NLS-1$ + for (int i = 0; i < sa.length; i++) { + s = s + " " + sa[i]; //$NON-NLS-1$ + } + setTextNode(FILETYPES_TAG, s); + setUserChanged(true); + } + + // *************************************** + // Determing file type matches + // *************************************** + /** + * Is this action's file types a generic value + */ + public boolean isGeneric() { + // ?? may not be optimal + String fts[] = getFileTypes(); + if (0 == fts.length) return true; + for (int i = 0; i < fts.length; i++) { + if ("*".equals(fts[i])) //$NON-NLS-1$ + return true; + } + return true; + } + + /** + * Set the initial command value + */ + public void setInitCommand(String s) { + this.initCommand = s; + } + + /** + * Get the initial command value + */ + public String getInitCommand() { + return this.initCommand; + } + + /** + * Set data. Useful when used in context like trees. + */ + public void setData(Object data) { + this.data = data; + } + + /** + * Return data as set by setData + */ + public Object getData() { + return data; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionManager.java new file mode 100644 index 00000000000..b6f0f971189 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionManager.java @@ -0,0 +1,225 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.File; +import java.util.Vector; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.rse.core.SystemResourceManager; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; + +/** + * Instances of this class hold the UDA definitions unique to: + *

    + *
  1. The SystemProfile - according to the subsystem + *
  2. The SubSystem type - according to the subclassed SystemUDActionSubsystem + *
+ * Instances of this class will be linked to a SubSystem instance + * + * + * Eventually, would hope to create a factory method for this class which will + * return existing instances common to the subsystems of different connections + * within the same profile. + */ +public class SystemUDActionManager extends SystemUDBaseManager +// implements ErrorHandler, + implements ITreeContentProvider { + private static final String XE_ROOT = "Actions"; //$NON-NLS-1$ + private static final String XE_ACTION = "Action"; //$NON-NLS-1$ + private final static String UDA_FILENAME = "uda.xml"; //$NON-NLS-1$ + + /** + * Constructor + */ + public SystemUDActionManager(SystemUDActionSubsystem udas) { + super(udas); + } + + /** + * Return true if this is user actions, false if this is named types. + */ + protected boolean isUserActionsManager() { + return true; + } + + /** + * Get the icon to show in the tree views, for the "new" expandable item + */ + public Image getNewImage() { + return UserActionsIcon.USERACTION_NEW.getImage(); + } + + /** + * Parent method override for returning the "New" icon label for the Work With dialog tree view. + * For us, we defer to the getActionSubSystem().{@link SystemUDActionSubsystem#getNewNodeActionLabel() getNewNodeActionLabel()}. + * Do not override this. + * @return translated value for "New" in new icon for WW action and type dialogs. Default is "New" + */ + protected String getNewNodeLabel() { + return getActionSubSystem().getNewNodeActionLabel(); + } + + /** + * Overridable method for child classes to do migration of their document. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done + */ + protected boolean doMigration(ISystemProfile profile, String oldRelease) { + return getActionSubSystem().doActionsMigration(profile, oldRelease); + } + + /** + * Get name of the xml file used to persist the actions. + */ + public String getFileName() { + return UDA_FILENAME; + } + + /** + * Get the document root tag name. + * We return "Actions" + */ + public String getDocumentRootTagName() { + return XE_ROOT; // "Actions" + } + + /** + * Do we uppercase the value of the "Name" attribute? + * No, we don't for actions. + */ + protected boolean uppercaseName() { + return false; + } + + /** + * Return true if the elements managed by this class are scoped by + * profile. Usually true for actions, false for types + */ + public boolean supportsProfiles() { + return true; + } + + /** + * Prime the given document with any default actions/types + * Should be overridden! + */ + public SystemXMLElementWrapper[] primeDocument(ISystemProfile profile) { + if (profile.isDefaultPrivate()) // we only prime the user's private profile with default actions + return getActionSubSystem().primeDefaultActions(this, profile); + else + return null; + } + + /** + * Get the folder containing the xml file used to persist the actions, + * for the given profile + */ + protected IFolder getDocumentFolder(ISubSystemConfiguration subsystemFactory, ISystemProfile profile) { + return SystemResourceManager.getUserActionsFolder(profile.getName(), subsystemFactory); + } + + /** + * Intended for IMPORT actions only, where no Subsystem instance available: + */ + public void setFolder(String profileName, String factoryId) { + importCaseFolder = SystemResourceManager.getUserActionsFolder(profileName, factoryId); + } + + /** + * Add a user-defined action + */ + public SystemUDActionElement addAction(ISystemProfile profile, String name, int domain) { + return (SystemUDActionElement) super.addElement(profile, domain, name); + } + + /** + * Return true if there are any actions, currently. + */ + public boolean hasActions(ISystemProfile profile, ISubSystemConfiguration ssFactory) { + boolean hasActions = false; + boolean folderExists = SystemResourceManager.testUserActionsFolder(profile.getName(), ssFactory); + if (folderExists) { + String fileName = getFilePath(profile); + if (fileName != null) { + File file = new File(fileName); + if (file.canRead()) hasActions = true; + } + } + //System.out.println("Inside hasActions for SystemUDActionManager, for ssFactory "+ssFactory.getId()+": "+hasActions); + return hasActions; + } + + /** + * Return xml element wrapper objects for all actions, for the + * given domain, or for the whole document if domain is -1 (iff + * domains not supported). + * @param v - existing vector to populate. If null passed, it is + * not populated. + * @param profile - the profile to limit the search to + * @param domain - the integer representation of the given domain, + * or -1 iff supportsDomains() is false + * @return array of action objects + */ + public SystemUDActionElement[] getActions(Vector v, ISystemProfile profile, int domain) { + v = super.getXMLWrappers(v, domain, profile); + if (v == null) return new SystemUDActionElement[0]; + SystemUDActionElement[] actions = new SystemUDActionElement[v.size()]; + for (int idx = 0; idx < actions.length; idx++) + actions[idx] = (SystemUDActionElement) v.elementAt(idx); + return actions; + } + + /** + * Return all the actions for the given profile, in all domains. + * @param v - existing vector to populate. If null passed, it is not populated. + * @param profile - the profile to limit the search to + * @return array of action objects + */ + public SystemUDActionElement[] getAllActions(Vector v, ISystemProfile profile) { + if (!getActionSubSystem().supportsDomains()) return getActions(v, profile, -1); + if (v == null) v = new Vector(); + int nbrDomains = getActionSubSystem().getMaximumDomain() + 1; + for (int domain = 0; domain < nbrDomains; domain++) { + super.getXMLWrappers(v, domain, profile); + } + SystemUDActionElement[] actions = new SystemUDActionElement[v.size()]; + for (int idx = 0; idx < actions.length; idx++) + actions[idx] = (SystemUDActionElement) v.elementAt(idx); + return actions; + } + + // ----------------------------------------------------------- + // ISystemXMLElementWrapperFactory + // ----------------------------------------------------------- + /** + * Return the tag name for our managed elements. + * Eg: will be "Action" for user actions, and "Type" for file types. + */ + public String getTagName() { + return XE_ACTION; + } + + /** + * Given an xml element node, create an instance of the appropriate + * subclass of SystemXMLElementWrapper to represent it. + */ + public SystemXMLElementWrapper createElementWrapper(Element xmlElementToWrap, ISystemProfile profile, int domain) { + SystemUDActionElement elementWrapper = new SystemUDActionElement(xmlElementToWrap, this, profile, domain); + return elementWrapper; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionSubsystem.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionSubsystem.java new file mode 100644 index 00000000000..bc1d320c61f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionSubsystem.java @@ -0,0 +1,1143 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.core.RSECorePlugin; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.internal.ui.view.SystemTableViewProvider; +import org.eclipse.rse.model.ISystemResourceChangeEvents; +import org.eclipse.rse.model.ISystemResourceChangeListener; +import org.eclipse.rse.model.SystemRegistry; +import org.eclipse.rse.model.SystemResourceChangeEvent; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.shells.ui.RemoteCommandHelpers; +import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem; +import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem; +import org.eclipse.rse.ui.GenericMessages; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.rse.ui.view.ISystemEditableRemoteObject; +import org.eclipse.rse.ui.view.ISystemRemoteElementAdapter; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.rse.useractions.ui.ISystemSubstitutor; +import org.eclipse.rse.useractions.ui.SystemCmdSubstVarList; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.ListSelectionDialog; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.WorkbenchContentProvider; + +/** + * Provide the interface to customize and implement the user-defined actions support + * for the subsystems which implement it. Subsystems are expected to override + * these methods as required. + *

+ * For some subsystem factories, actions and types can be partitioned/scoped by + * "domain". Eg, for iSeries actions are scoped by object and member, and each + * has unique lists of actions and types. + * This base class offers all the support for supporting domains, but it is triggered + * by the method supportsDomains() which is overridden by child classes appropriately. + *

+ * Some subsystems will support named types by which actions can be scoped. This + * support is triggered by supportsTypes(), which returns true by default but can + * be overridden by childclasses. + */ +public abstract class SystemUDActionSubsystem implements ISystemSubstitutor { + public final static int DOMAIN_NONE = -1; + protected ISubSystem _subsystem; // May be null for an import action + protected ISubSystemConfiguration subsystemFactory; // for use in Team view where we show user actions per SSF. + protected SystemUDActionManager udActionManager; + protected SystemUDTypeManager udTypeManager; + protected SystemUDAResolvedTypes udaResolvedTypes; + protected SystemUDActionElement currentAction; // current action being processed + protected boolean testAction; // is current action the test action? + + /** + * Constructor + */ + public SystemUDActionSubsystem() { + super(); + //this._subsystem = subsys; + } + + /** + * Overridable method for child classes to do migration of their actions. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done + */ + protected abstract boolean doActionsMigration(ISystemProfile profile, String oldRelease); + + /** + * Overridable method for child classes to do migration of their types. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done + */ + protected abstract boolean doTypesMigration(ISystemProfile profile, String oldRelease); + + /** + * Overridable method for child classes to supply the label to display in the + * "New" node for actions. Typically only overridden if domains are not supported, + * as otherwise the child nodes of "New" have the specific labels.
+ * If not overridden, then "New" is used. + * @return translated label + */ + protected String getNewNodeActionLabel() { + return SystemResources.ACTION_CASCADING_NEW_LABEL; + } + + /** + * Overridable method for child classes to supply the label to display in the + * "New" node for type. Typically only overridden if domains are not supported, + * as otherwise the child nodes of "New" have the specific labels.
+ * If not overridden, then "New" is used. + * @return translated label + */ + protected String getNewNodeTypeLabel() { + return SystemResources.ACTION_CASCADING_NEW_LABEL; + } + + /** + * Get the singleton manager of user-defined actions for this subsystem factory + */ + public SystemUDActionManager getUDActionManager() { + if (udActionManager == null) udActionManager = new SystemUDActionManager(this); + return udActionManager; + } + + /** + * Get the singleton manager of named file types for this subsystem factory + */ + public SystemUDTypeManager getUDTypeManager() { + if ((udTypeManager == null) && supportsTypes()) udTypeManager = new SystemUDTypeManager(this); + return udTypeManager; + } + + /** + * Return the list of substitution variables for the given domain type. + * Called from edit pane in work with dialog. + * This must be overridden! + */ + public abstract SystemCmdSubstVarList getActionSubstVarList(int actionDomainType); + + /** + * Retrieve current subsystem + */ + public ISubSystem getSubsystem() { + return _subsystem; + } + + /** + * Set current subsystem + */ + public void setSubsystem(ISubSystem ss) { + _subsystem = ss; + if (ss != null) setSubSystemFactory(ss.getSubSystemConfiguration()); + } + + /** + * Retrieve current subsystem factory. Useful when we don't have a subsystem + */ + public ISubSystemConfiguration getSubSystemFactory() { + return subsystemFactory; + } + + /** + * Set current subsystem factory. Useful when we don't have a subsystem + */ + public void setSubSystemFactory(ISubSystemConfiguration ssf) { + subsystemFactory = ssf; + } + + /** + * Return true if actions can be scoped by file types + * Default is true + */ + public boolean supportsTypes() { + return true; + } + + /** + * Return true if actions can be scoped by file types for the given domain. + * Default is supportsTypes() + */ + public boolean supportsTypes(int domain) { + return supportsTypes(); + } + + /** + * Return true if the action/type manager supports domains. + * Default is false + */ + public boolean supportsDomains() { + return false; + } + + /** + * In some cases, we supports domains in general, but only want to expose + * one of those domains to the user. For example, for file subsystems, + * we support folder and file domains, but for named types we really only + * support the file domain. + *

+ * Default is -1 + */ + public int getSingleDomain(SystemUDBaseManager docManager) { + return -1; + } + + // ************************************************************** + // User Interface: Adding Menu Actions, etc. + // ************************************************************** + /** + * Return the action's edit pane. + * Subclasses should override if they want to return their own edit pane. + * @param ss - the subsystem if you have it. If you don't have it, pass null. + * @param ssFactory - the subsystem factory, if you don't have the subsystem. + * @param profile - the subsystem factory, if you don't have the subsystem. + * @param parent - the hosting dialog/property page + * @param tv - the tree view if the parent is a dialog. + * */ + public SystemUDActionEditPane getCustomUDActionEditPane(ISubSystem ss, ISubSystemConfiguration ssFactory, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return new SystemUDActionEditPane(ss, ssFactory, profile, parent, tv); + } + + /** + * Historical. + * Now replaced with {@link #getCustomUDActionEditPane(ISubSystem, ISubSystemConfiguration, ISystemProfile, ISystemUDAEditPaneHoster, ISystemUDTreeView)} + */ + protected final SystemUDActionEditPane getCustomUDActionEditPane(ISubSystem ss, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return getCustomUDActionEditPane(ss, null, null, parent, tv); + } + + /** + * Historical. + * Now replaced with {@link #getCustomUDActionEditPane(ISubSystem, ISubSystemConfiguration, ISystemProfile, ISystemUDAEditPaneHoster, ISystemUDTreeView)} + */ + protected final SystemUDActionEditPane getCustomUDActionEditPane(ISubSystemConfiguration ssFactory, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return getCustomUDActionEditPane(null, ssFactory, profile, parent, tv); + } + + /** + * Subclasses may override to provide a custom type edit pane subclass. + * Subclasses should override if they want to return their own types pane. + * @param ss - the subsystem if you have it. If you don't have it, pass null. + * @param ssconfig - the subsystem factory, if you don't have the subsystem. + * @param profile - the subsystem factory, if you don't have the subsystem. + * @param parent - the hosting dialog/property page + * @param tv - the tree view if the parent is a dialog. + */ + public SystemUDTypeEditPane getCustomUDTypeEditPane(ISubSystem ss, ISubSystemConfiguration ssconfig, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return new SystemUDTypeEditPane(ss, ssconfig, profile, parent, tv); + } + + /** + * Historical. + * Now replaced with {@link #getCustomUDTypeEditPane(ISubSystem, ISubSystemConfiguration, ISystemProfile, ISystemUDAEditPaneHoster, ISystemUDTreeView)} + */ + protected final SystemUDTypeEditPane getCustomUDTypeEditPane(ISubSystem ss, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return getCustomUDTypeEditPane(ss, null, null, parent, tv); + } + + /** + * Historical. + * Now replaced with {@link #getCustomUDTypeEditPane(ISubSystem, ISubSystemConfiguration, ISystemProfile, ISystemUDAEditPaneHoster, ISystemUDTreeView)} + */ + public SystemUDTypeEditPane getCustomUDTypeEditPane(ISubSystemConfiguration ssFactory, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + return getCustomUDTypeEditPane(null, ssFactory, profile, parent, tv); + } + + // ************************************************************** + // Accessing UDA/UDT's in memory/storage: + // ************************************************************** + /** + * Prime the user data with the default types. + */ + public abstract SystemUDTypeElement[] primeDefaultTypes(SystemUDTypeManager udtd); + + /** + * Prime the user data with the default actions. Subsystem and profile specific + */ + public abstract SystemUDActionElement[] primeDefaultActions(SystemUDActionManager udad, ISystemProfile profile); + + /** + * Given this IBM-supplied user action, restore it to its IBM-supplied state. + * @return true if all went well, false if it wasn't restore for some reason + */ + public boolean restoreDefaultAction(SystemUDActionElement element, int domain, String actionName) { + return false; + } + + /** + * Given this IBM-supplied named type, restore it to its IBM-supplied state + * @return true if all went well, false if it wasn't restore for some reason + */ + public boolean restoreDefaultType(SystemUDTypeElement element, int domain, String typeName) { + return false; + } + + // ************************************************************** + // Running commands: + // ************************************************************** + /** + * Return the command name that tells us this is an action for testing substitution variables. + *

+ * Returns "ibm test action" + */ + public String getTestActionName() { + return "ibm test action"; //$NON-NLS-1$ + } + + /** + * Return the default name of the test file in test mode. + * The test file is generated at action run-time when the action name is {@link #getTestActionName()}. + *

+ * Returns "TESTUSERACTION.TXT" + */ + public String getTestFileName() { + return "TESTUSERACTION.TXT"; //$NON-NLS-1$ + } + + /** + * Return the default path of the test file in test mode + * The test file is generated at action run-time when the action name is {@link #getTestActionName()}. + *

+ * Returns "c:\\Test_RSE_User_Actions" + */ + public String getTestFilePath() { + return "c:\\Test_RSE_User_Actions"; //$NON-NLS-1$ + } + + /** + * Overriddable method for printing out information about the collected names + * for "invoke once" actions, when in test mode. + */ + protected void printTestActionInvokeOnceInformation(Shell shell, PrintWriter writer) { + } + + /** + * When the user selects one or more objects in the RSE, then right clicks + * and selects a user action, this method is called (by the SystemUDAsBaseAction + * class). + *

+ * For each selected object, the action's command is resolved (variable substitution done) + * by calling doCommandSubstitution, and then run by calling runCommand(...). + * @param shell - the shell to use for display the prompt, if appropriate + * @param action - the user action to run + * @param selection - the currently selected objects + * @param viewer - the viewer we are running this from. Used to do the refresh if requested in this action. Can be null. + */ + public void run(Shell shell, SystemUDActionElement action, IStructuredSelection selection, ISystemResourceChangeListener viewer) { + Assert.isLegal(shell != null, "shell argument is null"); //$NON-NLS-1$ + processingSelection(true); + Iterator elements = selection.iterator(); + this.currentAction = action; + IRemoteCmdSubSystem cmdSubSystem = null; + boolean runOnce = action.getCollect(); + boolean actionRunEvenOnce = false; + boolean cancelled = false; + /* + * DKM - I've taken the linebreak stripping out. Now we intend to support + * batches of commands. The interpreting of line breaks is now + * delegated to implementors of runCommand() + */ + String command = action.getCommand(); + // what is test action? For testing purposes, creating an action with this name means + // generating a local file to prove the variable substitution works... + testAction = action.getName().toLowerCase().startsWith(getTestActionName()); + File testFile = null; + PrintWriter testWriter = null; + if (testAction) { + this.currentAction = action; + try { + String testFileDir = action.getComment(); + if ((testFileDir == null) || (testFileDir.trim().length() == 0)) testFileDir = getTestFilePath(); + File testDir = new File(testFileDir); + if (!testDir.exists()) { + testDir.mkdir(); + } + String testFileName = command; + if ((testFileName == null) || (testFileName.trim().length() == 0)) testFileName = getTestFileName(); + testFile = new File(testDir, testFileName); + String message = "In test action mode. Output file is: {0}"; //$NON-NLS-1$ + message = MessageFormat.format(message, new Object[] { testFile.getAbsolutePath() }); + SystemBasePlugin.logInfo(message); + testWriter = new PrintWriter(new FileOutputStream(testFile)); + getActionSubstVarList(action.getDomain()).printDisplayStrings(testWriter); + } catch (Exception exc) { + if (testFile != null) { + String message = "Error creating test file {0} for user actions:"; //$NON-NLS-1$ + message = MessageFormat.format(message, new Object[] { testFile.getAbsolutePath() }); + SystemBasePlugin.logError(message, exc); + } + return; + } + } + // ------------------------------------------------------------ + // THIS ACTION IS TO BE RUN ONCE PER SELECTED OBJECT + // ------------------------------------------------------------ + try { + if (checkDirtyEditors(selection)) { + if (!runOnce) { + Object selectedObject = null; + while (!cancelled && elements.hasNext()) { + selectedObject = elements.next(); + //cmdSubSystemContext = selectedObject; + if (cmdSubSystem == null) { + cmdSubSystem = getCommandSubSystem(selectedObject); + } + if (testAction) { + SystemCmdSubstVarList supportedVariables = getActionSubstVarList(action.getDomain()); + String[] substitutedVariables = supportedVariables.doAllSubstitutions(selectedObject, this); + if (testWriter != null) { + testWriter.println("Selected Object: " + getRemoteAdapter(selectedObject).getAbsoluteName(selectedObject)); //$NON-NLS-1$ + for (int idx = 0; idx < substitutedVariables.length; idx++) { + testWriter.println("....." + substitutedVariables[idx]); //$NON-NLS-1$ + } + } + } else { + String cmd = doCommandSubstitutions(action, command, selectedObject); + // Prompt support + if (action.getPrompt()) { + // Prompt user and allow to edit the command. Honor their request to cancel + cmd = promptCommand(shell, cmd); + if (cmd == null) cancelled = true; + } + if (!cancelled) cancelled = !runCommand(shell, action, cmd, cmdSubSystem, selectedObject, (Viewer) viewer); + if (!cancelled && !actionRunEvenOnce) actionRunEvenOnce = true; + } // end else !testAction + } // end while loop + } // end if !runOnce + // ------------------------------------------------------------ + // THIS ACTION IS TO BE RUN ONCE ONLY, FOR ALL SELECTED OBJECTS + // ------------------------------------------------------------ + else { + StringBuffer collectedNames = new StringBuffer(); + Object firstSelectedObject = collectNames(shell, elements, collectedNames); + if (firstSelectedObject == null) // happens when something goes wrong. Msg already shown to user + return; + String nameVar = getAllNamesSubstitutionVariable(); + String cmd = command; + if (nameVar != null) { + if (testAction) cmd = nameVar; + int nameVarIdx = cmd.indexOf(nameVar); + if (nameVarIdx >= 0) { + cmd = cmd.substring(0, nameVarIdx) + collectedNames.toString() + cmd.substring(nameVarIdx + nameVar.length()); + } + } + if (testAction && testWriter != null) { + SystemCmdSubstVarList supportedVariables = getActionSubstVarList(action.getDomain()); + String[] substitutedVariables = supportedVariables.doAllSubstitutions(firstSelectedObject, this); + testWriter.println("First Selected Object: " + getRemoteAdapter(firstSelectedObject).getAbsoluteName(firstSelectedObject)); //$NON-NLS-1$ + if (nameVar != null) testWriter.println("....." + nameVar + " = " + cmd); //$NON-NLS-1$ //$NON-NLS-2$ + for (int idx = 0; idx < substitutedVariables.length; idx++) + testWriter.println("....." + substitutedVariables[idx]); //$NON-NLS-1$ + printTestActionInvokeOnceInformation(shell, testWriter); + } else { + cmd = doCommandSubstitutions(action, cmd, firstSelectedObject); + // Prompt support + if (action.getPrompt()) { + // Prompt user and allow to edit the command. Honor their request to cancel + cmd = promptCommand(shell, cmd); + if (cmd == null) cancelled = true; + } + if (!cancelled) { + cmdSubSystem = getCommandSubSystem(firstSelectedObject); + cancelled = !runCommand(shell, action, cmd, cmdSubSystem, firstSelectedObject, (Viewer) viewer); + } + if (!cancelled) actionRunEvenOnce = true; + } // end else !testAction + } // end else runOnce + // ANYTHING GO WRONG?? + } + } catch (Exception exc) { + SystemMessageDialog.displayExceptionMessage(shell, exc); + System.out.println("Error running user action " + command + ": " + exc.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } + // ------------------------------------------------------------ + // REFRESH VIEW IF REQUESTED IN ACTION + // ------------------------------------------------------------ + if (actionRunEvenOnce && action.getRefresh() && (viewer != null)) { + SystemRegistry sr = RSEUIPlugin.getTheSystemRegistry(); + try { + Thread.sleep(500L); + } catch (Exception exc) { + } // defect 46380: give action's command time to run? I don't know, but this works! + sr.fireEvent(viewer, new SystemResourceChangeEvent(sr, ISystemResourceChangeEvents.EVENT_REFRESH_SELECTED_PARENT, null)); + // todo! verify we are sending the right event! ok, done... its the right one. + } + if (testWriter != null && testFile != null) { + testWriter.flush(); + testWriter.close(); + SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_GENERIC_I_HELP); + msg.makeSubstitution("Test file " + testFile.getName() + " generated successfully", "The file was generated in directory " + testFile.getParent()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + SystemMessageDialog dlg = new SystemMessageDialog(shell, msg); + dlg.openWithDetails(); + } + processingSelection(false); + } // end method + + /** + * After an action's command has been resolved (vars substituted) this method + * is called to actually do the remote command execution + * @param shell - the shell to use if need to prompt for password or show msg dialog + * @param action - the action being processed, in case attributes of it need to be queried + * @param cmdString - the resolved command + * @param cmdSubSystem - this connection's command subsystem, which will run the command + * @param context - any context information the subsystem's runCommand might need + * @return true if we should continue, false if something went wrong + */ + protected boolean runCommand(Shell shell, SystemUDActionElement action, String cmdString, IRemoteCmdSubSystem cmdSubSystem, Object context, Viewer viewer) { + boolean ok = false; + if (cmdSubSystem != null) { + ok = true; + try { + cmdSubSystem.runCommand(new NullProgressMonitor(), cmdString, context); + } catch (Exception e) { + SystemBasePlugin.logError("RunUserAction", e); //$NON-NLS-1$ + SystemMessageDialog.displayExceptionMessage(shell, e); + ok = false; + } + } // end if + return ok; + } // end method + + /** + * Called when user selects a user action to run, from the base user + * action class. Called by our run(...) method + */ + protected String doCommandSubstitutions(SystemUDActionElement action, String cmd, Object selectedObject) { + this.currentAction = action; + SystemCmdSubstVarList supportedVariables = getActionSubstVarList(action.getDomain()); + return supportedVariables.doSubstitutions(cmd, selectedObject, this); + } // end method + + /** + * When processing an action that has elected to be invoked only once, versus + * once per selected object, we call this method to collect the names of the + * selected objects into a single string buffer. + *

+ * This can be overridden if need be. The default behaviour is to concatenate + * the quoted absolute name of each selected object. + * + * @return first selected object, or null if something went wrong (msg will have been issued) + */ + protected Object collectNames(Shell shell, Iterator elements, StringBuffer collectedNames) { + return collectNamesDefaultMethod(shell, elements, collectedNames); + } // end method + + /** + * Allows subclasses to call it even if their immediate parent overrides + */ + protected Object collectNamesDefaultMethod(Shell shell, Iterator elements, StringBuffer collectedNames) { + Object firstSelectedObject = null; + while (elements.hasNext()) { + Object selectedObject = elements.next(); + if (firstSelectedObject == null) + firstSelectedObject = selectedObject; + else + collectedNames.append(" "); //$NON-NLS-1$ + collectedNames.append(getNameDelimiter()); + collectedNames.append(getRemoteAdapter(selectedObject).getAbsoluteName(selectedObject)); + collectedNames.append(getNameDelimiter()); + } // end while loop + return firstSelectedObject; + } // end method + + /** + * When processing an action that has elected to be invoked only once, versus + * once per selected object, we call this method to get the "all names" + * substitution variable so that we can substitute it with the collection + * of names of all selected objects. + *

+ * The default is "${resource_name}", but can be overridden. + */ + protected String getAllNamesSubstitutionVariable() { + return "${resource_name}"; //$NON-NLS-1$ + } + + /** + * When processing an action that has elected to be invoked only once, versus + * once per selected object, we call this method to get the delimiter + * character to surround each name in. + *

+ * The default is a double quote, but can be overridden. For example, for iSeries + * native file systems, this is overridden with a single quote. + */ + protected char getNameDelimiter() { + return '\"'; + } + + /** + * Called when processing user action that has the "prompt" attribute set. + * By default, puts up dialog allowing user to see and edit the fully resolved command. + * @param shell - the shell to host the modal dialog + * @param command - the fully resolved (variables substituted) command + * @return the edited command string, or null if the user pressed cancel + */ + protected String promptCommand(Shell shell, String command) { + return promptCommandDefault(shell, command); + } + + /** + * This allows child classes to call this directly + */ + protected String promptCommandDefault(Shell shell, String command) { + SystemPromptUDADialog dialog = new SystemPromptUDADialog(shell, command); + dialog.open(); + if (!dialog.wasCancelled()) + return dialog.getCommand(); + else + return null; + } + + /** + * Get the command subsystem associated the given remote object + */ + protected static IRemoteCmdSubSystem getCommandSubSystem(Object selectedObject) { + return RemoteCommandHelpers.getCmdSubSystem(getRemoteAdapter(selectedObject).getSubSystem(selectedObject).getHost()); + } + + /** + * Get the first file subsystem associated the given remote object. + * May return null! + */ + protected static IRemoteFileSubSystem getFileSubSystem(Object selectedObject) { + IRemoteFileSubSystem[] rfsss = RemoteFileUtility.getFileSubSystems(getCommandSubSystem(selectedObject).getHost()); + if ((rfsss != null) && (rfsss.length > 0)) + return rfsss[0]; + else + return null; + } + + /** + * Returns the implementation of ISystemRemoteElement for the given + * object. Returns null if this object does not adaptable to this. + */ + protected static ISystemRemoteElementAdapter getRemoteAdapter(Object o) { + if (!(o instanceof IAdaptable)) + return (ISystemRemoteElementAdapter) Platform.getAdapterManager().getAdapter(o, ISystemRemoteElementAdapter.class); + else + return (ISystemRemoteElementAdapter) ((IAdaptable) o).getAdapter(ISystemRemoteElementAdapter.class); + } + + /** + * From the interface ISystemSubstitutor. + *

+ * Return the string to substitute for the given substitution + * variable, given the current context object. This object will + * be passed whatever was passed into the doSubstitution method. + *

It is VERY IMPORTANT to return null if you can't do the + * substitution for some reason! This is a clue to the algorithm + * that no change was made and increases performance. + *

+ * We try to handle common substitutions here in the base class, and + * pass on any other requests to the child classes via a call to + * internalGetSubstitutionValue(String var, Object context) + */ + public String getSubstitutionValue(String subvar, Object context) { + return getCommonSubstitutionValues(subvar, context); + } + + /** + * This abstraction allows child subclasses to override getSubstitutionValues, yet + * grandchild subclasses to still call this common class if needed. + */ + public String getCommonSubstitutionValues(String subvar, Object context) { + // ${action_name} = This user defined action name + if (subvar.equals("${action_name}")) //$NON-NLS-1$ + return currentAction.toString(); + // ${connection_name} = The connection in which this action is launched + if (subvar.equals("${connection_name}")) //$NON-NLS-1$ + return getCommandSubSystem(context).getHost().getAliasName(); + // ${user_id} = The user ID that was used to signon with + else if (subvar.equals("${user_id}")) //$NON-NLS-1$ + return getCommandSubSystem(context).getConnectorService().getUserId(); + // ${system_tempdir} = The fully qualified temp directory in remote system + else if (subvar.equals("${system_tempdir}")) //$NON-NLS-1$ + return getCommandSubSystem(context).getConnectorService().getTempDirectory(); + // ${system_homedir} = The fully qualified home directory in remote system, for current user + else if (subvar.equals("${system_homedir}")) //$NON-NLS-1$ + return getCommandSubSystem(context).getConnectorService().getHomeDirectory(); + // ${system_pathsep} = The path separator. ';' on Windows, ':' on Unix and Linux + else if (subvar.equals("${system_pathsep}")) //$NON-NLS-1$ + { + IRemoteFileSubSystem rfss = getFileSubSystem(context); + if (rfss != null) + return rfss.getParentRemoteFileSubSystemConfiguration().getPathSeparator(); + else + return "system_pathsep not available"; // hopefully will never happen //$NON-NLS-1$ + } + // ${system_filesep} = The file separator. '\\' on Windows, '/' on Unix and Linux + else if (subvar.equals("${system_filesep}")) //$NON-NLS-1$ + { + IRemoteFileSubSystem rfss = getFileSubSystem(context); + if (rfss != null) + return rfss.getParentRemoteFileSubSystemConfiguration().getSeparator(); + else + return "system_filesep not available"; // hopefully will never happen //$NON-NLS-1$ + } + // ${system_hostname} = The host name of the remote system + else if (subvar.equals("${system_hostname}")) //$NON-NLS-1$ + return getCommandSubSystem(context).getHost().getHostName(); + // ${local_hostname} = The host name of the local system + else if (subvar.equals("${local_hostname}")) //$NON-NLS-1$ + return RSECorePlugin.getLocalMachineName(); + // ${local_ip} = The ip address of the local system + else if (subvar.equals("${local_ip}")) //$NON-NLS-1$ + return RSECorePlugin.getLocalMachineIPAddress(); + // ---------------------------------------------------------------------- + // We leave it to each subsystem plugin to define the following, as they + // will each define their own mri for the display text. However, we can + // do the substitutions right here as it generic code... + // ---------------------------------------------------------------------- + // ${resource_name} = The name of the selected object + else if (subvar.equals("${resource_name}")) //$NON-NLS-1$ + return getRemoteAdapter(context).getName(context); + // ${resource_path} = The fully qualified name of the selected resource + else if (subvar.equals("${resource_path}")) //$NON-NLS-1$ + return getRemoteAdapter(context).getAbsoluteName(context); + else + return internalGetSubstitutionValue(currentAction, subvar, context); + } + + /** + * Overridable extension point for child class to do variable substitution for variables unique to them. + * + */ + public abstract String internalGetSubstitutionValue(SystemUDActionElement currentAction, String substitutionVariable, Object context); + + /** + * + */ + public boolean hasUnsupportedSubstitutionVars(Object action, int domain) { + return false; + } + + /** + * Check to see it any actions will apply to this selection. + * Stop checking as soon as 1 action is found. + * This method is an optimized, find-1-only, version of addUserActions() below. + * May be overriden for subsystem specific filtering of actions + * CURRENTLY WE JUST RETURN TRUE + */ + public boolean eligibleUserActionsForSelection(IStructuredSelection selection, ISystemProfile profile) { + return true; // todo. Maybe ... doesn't seem worth it! + } + + /** + * Populate context menu ("User Actions->" cascading action) with user + * actions that meet their type-scoping criteria for given selection. + *

+ * If given a profile, the list is scoped to that, else it includes actions + * for all active profiles. + */ + public void addUserActions(IMenuManager menu, IStructuredSelection selection, ISystemProfile profile, Shell shell) { + // access UDA tree for this subsystem + SystemUDActionManager actMgr = getUDActionManager(); + // Go through each profile for this subsystem's factory + ISystemProfile[] profiles = null; + if (profile == null) + profiles = getActiveSystemProfiles(); + else + profiles = new ISystemProfile[] { profile }; + int domain = -1; + if (supportsDomains()) { + domain = getDomainFromSelection(selection); + if (domain == -1) return; + } + boolean multiSelection = (selection.size() != 1); + for (int idx = 0; idx < profiles.length; idx++) { + profile = profiles[idx]; + SystemUDActionElement[] actions = actMgr.getActions(null, profile, domain); + // Scan UDA's for matching types and add to menu. + // if any match, then create the initial UDA submenu cascade item + for (int i = 0; i < actions.length; i++) { + SystemUDActionElement action = actions[i]; + if (!action.getShow()) continue; + if (multiSelection && action.getSingleSelection()) continue; + if (supportsDomains() && (domain != action.getDomain())) continue; // newly added... we were getting file actions on folders + if (!supportsTypes() || meetsSelection(action, selection, domain)) { + SystemUDAsBaseAction uda = new SystemUDAsBaseAction(action, shell, this); + uda.setSelection(selection); + uda.setShell(shell); + uda.setEnabled(!getWorkingOfflineMode()); + menu.add(uda); + } + } // end for-loop + } // end for all profiles loop + } + + /** + * We disable user defined actions if we are in work-offline mode. + * Currently, how we determine this is dependent on the subsystem factory. + */ + public boolean getWorkingOfflineMode() { + return false; + } + + /** + * Determine domain, given the selection. + * Eg subsystem that supports domains has to do this via overriding this method. + * If domains not supported, return -1. + */ + protected abstract int getDomainFromSelection(IStructuredSelection selection); + + /** + * Given an action, and the currently selected remote objects, and the domain of those, + * return true if ALL of the selected remote objects matches any of the type criteria + * for this action + */ + protected boolean meetsSelection(SystemUDActionElement action, IStructuredSelection selection, int domainType) { + String unresolvedActionTypes[] = action.getFileTypes(); + // fastpath for "ALL"! + if ((unresolvedActionTypes == null) || (unresolvedActionTypes.length == 0)) + return true; // what else to do? + else if (unresolvedActionTypes[0].equals("ALL")) //$NON-NLS-1$ + return true; + Object actionTypes[] = resolveTypes(unresolvedActionTypes, domainType); + Iterator elements = selection.iterator(); + Object element = null; + while (elements.hasNext()) { + element = elements.next(); + // OK if matches any one of the file types for an action + boolean foundMatch = false; + for (int j = 0; !foundMatch && (j < actionTypes.length); j++) { + // compare current unnamed type to current selected object + if (isMatch(actionTypes[j], element, domainType)) { + foundMatch = true; + break; + } + } // for j + if (!foundMatch) return false; + } + return true; + } + + /** + * Given a list of names that represent named types, + * resolve that into a concatenated list of all types for + * the given type names. + *

+ * Basically, this concatenates all the subtypes together. + * However, it also weeds out any redundancies + */ + protected String[] resolveTypes(String[] p_types, int domainType) { + Vector types = new Vector(); + for (int i = 0; i < p_types.length; i++) { + String fileTypes = getFileTypesForTypeName(p_types[i], domainType); + if (fileTypes != null) { + StringTokenizer st = new StringTokenizer(fileTypes, getTypesDelimiter()); + int n = st.countTokens(); + for (int j = 0; j < n; j++) { + String token = st.nextToken().trim(); + if (types.indexOf(token) < 0) types.addElement(token); + } + } + } + String[] allTypes = new String[types.size()]; + for (int idx = 0; idx < allTypes.length; idx++) + allTypes[idx] = (String) types.elementAt(idx); + return allTypes; + } + + /** + * Given a named-type name and a domain, find that type element and + * return the types for that named type. + */ + private String getFileTypesForTypeName(String name, int domainType) { + if (udaResolvedTypes == null) udaResolvedTypes = getResolvedTypesHelper(); + return udaResolvedTypes.getFileTypesForTypeName(name, domainType, getUDTypeManager()); + } + + /** + * Compares a particular file type (not named, but actual scalar/generic type) + * to a specific user-selected remote object. + * Returns true if the object's information matches that of the given type + *

+ * Must be overridden, but only called if supportsTypes() returns true. + * Else, just return true! + * @param actionType - an unnamed file type, as in "*.cpp" + * @param selectedObject - one of the currently selected remote objects + * @param domainType - integer representation of current domain + */ + protected abstract boolean isMatch(Object actionType, Object selectedObject, int domainType); + + /** + * Get the delimiter used to delimiter the types in a type string. + * Default is " " + */ + protected String getTypesDelimiter() { + return " "; //$NON-NLS-1$ + } + + /** + * + */ + public void resetResolvedTypes() { + udaResolvedTypes = null; + } + + /** + * + */ + public SystemUDAResolvedTypes getResolvedTypesHelper() { + return new SystemUDAResolvedTypes(); + } + + // --------------------------------------------------------------------------- + // NEW METHODS MOVED DOWN TO ABSTRACT-OUT/ENCAPSULATE THE NOTION OF DOMAINS... + // DONE BY PHIL IN RELEASE 2. + // PREVIOUSLY DOMAINS ONLY INTRODUCED IN THE ISERIES SUBCLASS FOR NATIVE FILES + // XML SYNTAX FOR A DOMAIN: + // XML ATTRIBUTE SYNTAX FOR A DOMAIN: + * + * + * + * This maps the given integer to its domain name. + * Returns null by default. + * Needs to be overridden by children that support domains + */ + public String mapDomainName(int domainInteger) { + if ((domainInteger >= 0) && (domainInteger <= getMaximumDomain())) + return getDomainNames()[domainInteger]; + else + return null; + } + + /** + * Map a given untranslated domain name to its integer value + */ + public int mapDomainName(String domainName) { + String[] domainNames = getDomainNames(); + int match = -1; + if ((domainNames != null) && (domainNames.length > 0)) { + for (int idx = 0; (match == -1) && (idx < domainNames.length); idx++) + if (domainNames[idx].equals(domainName)) match = idx; + } + return match; + } + + /** + * For efficiency reasons, internally we use an integer to represent a domain. + * However, that has to be mapped to a translated name occasionally for the UI, + * and indeed the translated name is stored in the XML in the "Name" attribute. + *

XML ATTRIBUTE SYNTAX FOR A DOMAIN: + * + * + * + * This maps the given integer to its translated domain name. + * Returns null by default. + * Needs to be overridden by children that support domains + */ + public String mapDomainXlatedName(int domainInteger) { + if ((domainInteger >= 0) && (domainInteger <= getMaximumDomain())) + return getXlatedDomainNames()[domainInteger]; + else + return null; + } + + /** + * Same as above but specifically for what is shown in the work with user actions dialog for the new element + */ + public String mapDomainXlatedNewName(int domainInteger) { + if ((domainInteger >= 0) && (domainInteger <= getMaximumDomain())) + return getXlatedDomainNewNames()[domainInteger]; + else + return null; + } + + /** + * Same as above but specifically for what is shown in the work with named types dialog for the new element + */ + public String mapDomainXlatedNewTypeName(int domainInteger) { + if ((domainInteger >= 0) && (domainInteger <= getMaximumDomain())) + return getXlatedDomainNewTypeNames()[domainInteger]; + else + return null; + } + + /** + * Get the list of untranslated domain names + */ + public String[] getDomainNames() { + return null; + } + + /** + * Get the list of translated domain names + */ + public String[] getXlatedDomainNames() { + return null; + } + + /** + * Get the list of translated domain names for use in the tree view, for the "New" nodes, + * in the Work With User Actions dialog. + */ + public String[] getXlatedDomainNewNames() { + return null; + } + + /** + * Get the list of translated domain names for use in the tree view, for the "New" nodes, + * in the Work With User Types dialog. + */ + public String[] getXlatedDomainNewTypeNames() { + return null; + } + + /** + * Get the domain icon to show in the tree views + */ + public Image getDomainImage(int domain) { + return null; + } + + /** + * Get the domain icon to show in the tree views, for the new item for this domain + */ + public Image getDomainNewImage(int domain) { + return UserActionsIcon.USERACTION_NEW.getImage(); + } + + /** + * Get the domain icon to show in the named type tree view, for the new item for this domain + */ + public Image getDomainNewTypeImage(int domain) { + return UserActionsIcon.USERTYPE_NEW.getImage(); + } + + /** + * Get the active system profiles + */ + protected ISystemProfile[] getActiveSystemProfiles() { + return RSEUIPlugin.getTheSystemRegistry().getActiveSystemProfiles(); + } + + protected List getDirtyEditors(IStructuredSelection sel) { + List dirtyEditors = new ArrayList(); + List selection = sel.toList(); + for (int i = 0; i < selection.size(); i++) { + Object selected = selection.get(i); + if (selected instanceof IAdaptable) { + ISystemEditableRemoteObject editable = getEditableFor((IAdaptable) selected); + if (editable != null) { + try { + // is the file being edited? + if (editable.checkOpenInEditor() == 0) { + // reference the editing editor + editable.openEditor(); + // file is open in editor - prompt for save + if (editable.isDirty()) { + dirtyEditors.add(editable); + } + } + } catch (Exception e) { + } + } + } + } + return dirtyEditors; + } + + protected ISystemEditableRemoteObject getEditableFor(IAdaptable selected) { + ISystemRemoteElementAdapter adapter = (ISystemRemoteElementAdapter) selected.getAdapter(ISystemRemoteElementAdapter.class); + if (adapter.canEdit(selected)) { + ISystemEditableRemoteObject editable = adapter.getEditableRemoteObject(selected); + try { + editable.setLocalResourceProperties(); + } catch (Exception e) { + } + return editable; + } + return null; + } + + protected boolean checkDirtyEditors(IStructuredSelection selection) { + List dirtyEditors = getDirtyEditors(selection); + if (dirtyEditors.size() > 0) { + AdaptableList input = new AdaptableList(); + for (int i = 0; i < dirtyEditors.size(); i++) { + ISystemEditableRemoteObject rmtObj = (ISystemEditableRemoteObject) dirtyEditors.get(i); + input.add(rmtObj.getRemoteObject()); + } + WorkbenchContentProvider cprovider = new WorkbenchContentProvider(); + SystemTableViewProvider lprovider = new SystemTableViewProvider(); + // TODO: Cannot use WorkbenchMessages -- it's internal + ListSelectionDialog dlg = new ListSelectionDialog(SystemBasePlugin.getActiveWorkbenchShell(), input, cprovider, lprovider, GenericMessages.EditorManager_saveResourcesMessage); + dlg.setInitialSelections(input.getChildren()); + dlg.setTitle(GenericMessages.EditorManager_saveResourcesTitle); + int result = dlg.open(); + //Just return false to prevent the operation continuing + if (result == IDialogConstants.CANCEL_ID) return false; + Object[] filesToSave = dlg.getResult(); + for (int s = 0; s < filesToSave.length; s++) { + IAdaptable rmtObj = (IAdaptable) filesToSave[s]; + ISystemEditableRemoteObject editable = getEditableFor(rmtObj); + editable.doImmediateSaveAndUpload(); + } + } + return true; + } + + /** + * Method called at the start and end of running user actions + * This allows children a chance to perform some action before and after + * the actions are run by overriding this method. + * @param processingSelection true before proecssing, false after processing + */ + protected void processingSelection(boolean processingSelection) { + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionTreeView.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionTreeView.java new file mode 100644 index 00000000000..99f641579b4 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDActionTreeView.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.swt.widgets.Composite; + +/** + * In the Work With User Defined Actions dialog, this is the + * tree view for showing the existing actions. + */ +public class SystemUDActionTreeView extends SystemUDBaseTreeView { + /** + * Constructor when we have a subsystem + */ + public SystemUDActionTreeView(Composite parent, ISystemUDWorkWithDialog editPane, ISubSystem ss) { + // FIXME - UDA can't be coupled with subsystem API + super(parent, editPane, ss, /*ss.getUDActionSubsystem().getUDActionManager()*/null); + } + + /** + * Constructor when we have a subsystem factory + */ + public SystemUDActionTreeView(Composite parent, ISystemUDWorkWithDialog editPane, ISubSystemConfiguration ssFactory, ISystemProfile profile) { + super(parent, editPane, ssFactory, profile, + // FIXME - UDA can't be coupled with subsystem API + //((ISubsystemFactoryAdapter)ssFactory.getAdapter(ISubsystemFactoryAdapter.class)).getActionSubSystem(ssFactory, null).getUDActionManager() + null); + } + + /** + * Return the {@link org.eclipse.rse.core.model.ISystemModelChangeEvents} constant representing the resource type managed by this tree. + * This is a parent class override. + */ + protected int getResourceType() { + return ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_USERACTION; + } + + /** + * Parent override. + * Restore the selected action to its IBM-supplied default value. + */ + public void doRestore() { + SystemXMLElementWrapper selectedElement = getSelectedElement(); + if ((selectedElement == null) || !(selectedElement instanceof SystemUDActionElement)) return; + SystemUDActionElement action = (SystemUDActionElement) selectedElement; + boolean ok = getDocumentManager().getActionSubSystem().restoreDefaultAction(action, action.getDomain(), action.getOriginalName()); + if (ok) { + action.setUserChanged(false); + getDocumentManager().saveUserData(profile); + selectElement(selectedElement); + String[] allProps = { IBasicPropertyConstants.P_TEXT, IBasicPropertyConstants.P_IMAGE }; + update(selectedElement, allProps); + } + } + + // ------------------------------------ + // HELPER METHODS CALLED FROM EDIT PANE + // ------------------------------------ + /** + * Select the given action + */ + public void selectAction(SystemUDActionElement element) { + super.selectElement(element); + } + + /** + * Refresh the parent of the given action. + * That is, find the parent and refresh the children. + * If the parent is not found, assume it is because it is new too, + * so refresh the whole tree. + */ + public void refreshActionParent(SystemUDActionElement element) { + super.refreshElementParent(element); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAsBaseAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAsBaseAction.java new file mode 100644 index 00000000000..9eaf954c2cd --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDAsBaseAction.java @@ -0,0 +1,53 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.model.ISystemResourceChangeListener; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.swt.widgets.Shell; + +/** + * Base action for user-defined actions, shown in the "User actions->" menu. + * When one of these is run, it does variable substitution and runs the command. + */ +public class SystemUDAsBaseAction extends SystemBaseAction { + private SystemUDActionSubsystem udaSubsystem; + private SystemUDActionElement action; + + public SystemUDAsBaseAction(SystemUDActionElement action, Shell parent, SystemUDActionSubsystem udasubsys) { + super(action.getLabel(), action.isIBM() ? UserActionsIcon.USERACTION_IBM.getImageDescriptor() : UserActionsIcon.USERACTION_USR.getImageDescriptor(), parent); + this.udaSubsystem = udasubsys; + this.action = action; + allowOnMultipleSelection(true); + // yantzi: artemis60, set SystemConnection to enable the offline support to + // automatically disable UDA when the system connection is offline + setHost(udasubsys.getSubsystem().getHost()); + } + + /** + * This is the method called when the user selects this action. + * Child classes need to override this. If you need the parent shell, + * call getShell. If you need to know the current selection, call + * getSelection(), or getFirstSelection() followed by getNextSelection() + * until null is returned. + * @see Action#run() + */ + public void run() { + IStructuredSelection selection = getSelection(); + if (viewer instanceof ISystemResourceChangeListener) + udaSubsystem.run(getShell(), action, selection, (ISystemResourceChangeListener) viewer); + else + udaSubsystem.run(getShell(), action, selection, null); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseManager.java new file mode 100644 index 00000000000..581644fc095 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseManager.java @@ -0,0 +1,1414 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.Hashtable; +import java.util.Vector; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemResourceHelpers; +import org.eclipse.rse.core.SystemResourceManager; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Instances of this class hold the UDA definitions unique to + *

    + *
  1. The SystemProfile - according to the subsystem + *
  2. the SubSystem type - according to the SubSystemFactory + *
+ * Instances of this class will be linked to a SubSystem instance + * Eventually, would hope to create a factory method for this class which will + * return existing instances common to the subsystems of different connections + * within the same profile. + *

+ * When used for IMPORT: NO SubSystem instance available. Will be NULL! + *

+ * This is the base class for both action managers and types managers. + * Only action managers are actually scoped by profile. + *

+ * Architecturally, this class and the SystemXMLElementWrapper class + * encapsulate all knowledge of the fact the underlying store is a xml document. + */ +public abstract class SystemUDBaseManager implements ErrorHandler, IResourceChangeListener, ISystemXMLElementWrapperFactory, ITreeContentProvider, ISystemUDAConstants { + // state + protected SystemUDActionSubsystem _udas; + protected IFolder importCaseFolder; // Only set during Import processing + private SystemUDTreeViewNewItem[] newItemsPerDomain; + private boolean ignoreMyResourceChange = false; // avoid recursion + // profile-indexed state. + // Access to these is carefully guarded, for the case when + // a subclass does not support profiles. + private Hashtable udocsByProfile; + private Hashtable hasChangedByProfile; + private Hashtable dirPathByProfile; + // used by subclasses that are not profile-indexed + private Document udocNoProfile; + private boolean hasChangedNoProfile = false; + private Object[] dirPathNoProfile; + // Profile for which we are working for actions for... + private ISystemProfile currentlyActiveProfile; // set in UDA GUI + // Clipboard copy/paste support + private Element currentNodeClone = null; + private String currentNodeCloneID = ""; //$NON-NLS-1$ + // private String currentNodeCloneName = ""; //$NON-NLS-1$ + private int currentNodeCloneDomain = -1; + // constants + protected static final Object[] EMPTY_ARRAY = new Object[0]; + /** + * Current release as a string. Eg "5.0" + */ + private static final String CURRENT_RELEASE_NAME = SystemResources.CURRENT_RELEASE_NAME; //"5.1.2"; // Historical from when part of iSeries. + + /** + * Constructor + */ + public SystemUDBaseManager(SystemUDActionSubsystem udas) { + super(); + _udas = udas; + if (supportsProfiles()) { + udocsByProfile = new Hashtable(); + hasChangedByProfile = new Hashtable(); + dirPathByProfile = new Hashtable(); + } + addListener(); + } + + /** + * Return the action subsystem object + */ + public SystemUDActionSubsystem getActionSubSystem() { + return _udas; + } + + /** + * Get the icon to show in the tree views, for the "new" expandable item + */ + public Image getNewImage() { + return RSEUIPlugin.getDefault().getImage(ISystemIconConstants.ICON_SYSTEM_NEW_ID); + } + + // ----------------------------------------------------------- + // ISystemXMLElementWrapperFactory + // ----------------------------------------------------------- + /** + * Return the tag name for our managed elements. + * Eg: will be "Action" for user actions, and "Type" for file types. + */ + public abstract String getTagName(); + + /** + * Given an xml element node, create an instance of the appropriate + * subclass of SystemXMLElementWrapper to represent it. + */ + public abstract SystemXMLElementWrapper createElementWrapper(Element xmlElementToWrap, ISystemProfile profile, int domain); + + // ----------------------------------------------------------- + // ITREECONTENTPROVIDER METHODS... + // ----------------------------------------------------------- + /** + * Returns the implementation of IWorkbenchAdapter for the given + * object. Returns null if the adapter is not defined or the + * object is not adaptable. + */ + protected IWorkbenchAdapter getAdapter(Object o) { + if (!(o instanceof IAdaptable)) return null; + return (IWorkbenchAdapter) ((IAdaptable) o).getAdapter(IWorkbenchAdapter.class); + } + + public void dispose() { + // To be safe, we clear the parent profile name when the tree is disposed, + // so it doesn't linger. This will happen because we only instantiate ourselves + // once and then always re-use that instance. + setCurrentProfile(null); + } + + /** + * Method declared on ITreeContentProvider. + * We return null. + */ + public Object getParent(Object element) { + return null; + } + + /** + * Method declared on ITreeContentProvider. + */ + public boolean hasChildren(Object element) { + //return getChildren(element).length > 0; + if (element instanceof SystemUDTreeViewNewItem) { + if (getActionSubSystem().supportsDomains()) + return !((SystemUDTreeViewNewItem) element).isExecutable(); + else + return false; + } else if (element instanceof SystemXMLElementWrapper) { + if (getActionSubSystem().supportsDomains()) { + SystemXMLElementWrapper wrapper = (SystemXMLElementWrapper) element; + if (!wrapper.isDomain()) + return false; + else + return (wrapper.getElement().getFirstChild() != null); + } else + return false; + } else if (element == null) { + SystemBasePlugin.logError("Unexpected null input to hasChildren!"); //$NON-NLS-1$ + } else { + String message = "Unexpected input to hasChildren: " + element.getClass().getName(); //$NON-NLS-1$ + SystemBasePlugin.logError(message); + } + return false; + } + + /** + * Method declared on IContentProvider. + * Callen when input changed. We do nothing. + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + // ----------------------------------------------------------- + // THE FOLLOWING ABSTRACT OUT THE DIFFERENCES BETWEEN ACTIONS + // AND TYPES + // ----------------------------------------------------------- + /** + * Get the document root tag name. + * Will be "FileTypes" for types, and "Actions" for actions + */ + public abstract String getDocumentRootTagName(); + + /** + * Do we uppercase the value of the "Name" attribute? + * Yes, we do for types, and No, we don't for actions + */ + protected abstract boolean uppercaseName(); + + /** + * Retrieve the action/type tags for the given profile and domain, + * wrapped in appropriate xml wrapper objects + * @param children - existing vector to populate. Pass null to create and return new vector + * @param domain - the integer representation of the domain, or -1 iff domains not support + * @param profile - profile to determine the document to query. If profiles not supported, pass null. + * @return a vector of the action/type tags + */ + public Vector getXMLWrappers(Vector children, int domain, ISystemProfile profile) { + SystemXMLElementWrapper domainElement = null; + if (getActionSubSystem().supportsDomains()) { + domainElement = getDomainWrapper(profile, domain); + if (domainElement == null) // if parent domain not found, don't continue! + return children; + } + return getXMLWrappers(children, domainElement, profile); + } + + /** + * Retrieve the action/type tags for the given profile and domain, + * wrapped in appropriate xml wrapper objects + * @param children - existing vector to populate. Pass null to create and return new vector + * @param parentOrDomain - if domains supported, this must be the parent domain whose kids are being queried, or an Integer for single-domains, else null + * @param profile - profile to determine the document to query. If profiles not supported, pass null. + * @return a vector of the action/type tags + */ + public Vector getXMLWrappers(Vector children, Object parentOrDomain, ISystemProfile profile) { + int domain = -1; + Element parentElement = null; + if (parentOrDomain instanceof SystemXMLElementWrapper) { + parentElement = ((SystemXMLElementWrapper) parentOrDomain).getElement(); + domain = ((SystemXMLElementWrapper) parentOrDomain).getDomain(); + } else if (parentOrDomain instanceof Element) parentElement = (Element) parentOrDomain; + children = SystemXMLElementWrapper.getChildren(children, parentElement, getDocument(profile), profile, this, domain); + return children; + } + + /** + * Return true if the elements managed by this class are scoped by + * profile. Usually true for actions, false for types + */ + public boolean supportsProfiles() { + return true; + } + + // ------------------------------------- + // + // ------------------------------------- + /** + * + */ + private void addListener() { + // Team support + // Register a listener for resource change events on objects + // in our remote system project. + // Dont register multiple times, if already done once. + // (Since this load method may be repeated) + /* ADDED BY JOHN, BUT COMMENTED OUT BY PHIL. OUR MODEL FOR RECOVERING FROM A TEAM SYNCH + * IS TO REQUIRE THE USER TO RUN RELOADRSE. + if (!listening) + { + listening = true; + SystemResourceManager.addResourceChangeListener(this); + } + */ + } + + /** + * Return name of the xml file used to persist the actions + */ + public abstract String getFileName(); + + /** + * Initialize a new document + */ + public Document initializeDocument() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + Document doc = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + } + if (builder != null) { + doc = builder.newDocument(); + // Document doc= new DocumentImpl(); + // create root element. Eg or + Element root = doc.createElement(getDocumentRootTagName()); + // set current release as an attribute + root.setAttribute(RELEASE_ATTR, CURRENT_RELEASE_NAME); + // assign root + doc.appendChild(root); // Add Root to Document + } + return doc; + } + + /** + * Get the current subsystem. Will be null for import, or working in team view when + * no subsystems exist yet for a particular subsystem factory. + */ + protected ISubSystem getSubSystem() { + if (_udas != null) + return _udas.getSubsystem(); + else + return null; + } + + /** + * Get the current subsystem. Will be set in SystemProfileImpl's getUserActions method + * for cases when there are no subsystems created for a subsystemconfiguration yet. + */ + protected ISubSystemConfiguration getSubSystemFactory() { + if (_udas != null) + return _udas.getSubSystemFactory(); + else + return null; + } + + /** + * Get the path of the XML document containing the user actions, + * for the given profile (and current subsystem) + */ + protected String getFilePath(ISystemProfile profile) { + IFolder folder = getFolder(profile); + if (folder == null) return null; + String fn = folder.getLocation().toOSString() + File.separator + getFileName(); + // System.out.println("UD file: " + fn); + return fn; + } + + /** + * Build a vector of the folder names, in order, from workspace + * to our data file. Do once only. + * (To be used when resolving resource change events) + */ + private void resolveDirPath(ISystemProfile profile) { + // System.out.println("UD file:" ); + Vector dirFolder = new Vector(); + dirFolder.add(getFileName()); + IContainer folder = getFolder(profile); + while (folder != null) { + // Insert at start of vector + String s = folder.getName(); + // Workspace is empty string, dont add it + if (!"".equals(s)) //$NON-NLS-1$ + { + dirFolder.add(0, s); + // System.out.println("+" + s ); + } + folder = folder.getParent(); + } + Object[] dirPath = dirFolder.toArray(); + setProfileIndexedInstanceVariable_dirPath(profile, dirPath); + } + + /** + * loadAndParseXMLFile: + * tries to load and parse the specified XML file. + * @param fileName the name of xml file which will contain the messages + * @param profile the profile in which the user defined actions are kept + * @return the document containing the user defined actions + */ + protected Document loadAndParseXMLFile(String fileName, ISystemProfile profile) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder parser = null; + try { + parser = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + SystemBasePlugin.logError("SystemUDBaseManager: loadAndParseXMLFile, configuration not valid " + e.toString(), e); //$NON-NLS-1$ + return null; + } + // DOMParser parser = new DOMParser(); + parser.setErrorHandler(this); + try { + Document doc = parser.parse(fileName); + // verify the document is what we expect... + Element docroot = doc.getDocumentElement(); // get Root Element + // ?? Confirm root is XE_ROOT ?? + // ok, I took on the job of handling this. I also decided to put it + // here so we don't have this code scattered everywhere after calls to getDocument() + // Phil. 08/2002 + if ((null == docroot) || !docroot.getTagName().equals(getDocumentRootTagName())) { + Shell activeShell = getActiveShell(); + SystemMessage docRootMsg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_UDA_ROOTTAG_ERROR); + String oldFileName = getFilePath(profile); + String newFileName = getFileName() + ".bad"; //$NON-NLS-1$ + IFile file = getFolder(profile).getFile(getFileName()); + try { + SystemResourceHelpers.getResourceHelpers().renameFile(file, newFileName); + } catch (Exception exc) { + } + doc = createAndPrimeDocument(profile); + docRootMsg.makeSubstitution(oldFileName, getDocumentRootTagName(), newFileName); + SystemBasePlugin.logWarning(docRootMsg.getLevelOneText()); + if (activeShell != null) { + SystemMessageDialog.displayErrorMessage(activeShell, docRootMsg); + } + } + return doc; + } catch (Exception exc) { + // Provide a non-null value. Might as well prime + // with a "proper" doc structure. + Document doc = initializeDocument(); + SystemMessageDialog msgdlg = new SystemMessageDialog(SystemBasePlugin.getActiveWorkbenchShell(), RSEUIPlugin.getPluginMessage( + // ISystemMessages.MSG_RESTORE_FAILED).makeSubstitution(exc)); + ISystemMessages.MSG_UDA_LOAD_ERROR).makeSubstitution(fileName, exc)); + msgdlg.open(); + return doc; + } + } + + // ********************************************************** + // ErrorHandler Interface: (XML SAX parsing) + // ********************************************************** + /** Warning. */ + public void warning(SAXParseException ex) { + SystemBasePlugin.logWarning("SystemAbstractUDdata: XML Warning: " + ex.toString()); //$NON-NLS-1$ + } + + /** Error. */ + public void error(SAXParseException ex) { + SystemBasePlugin.logError("SystemAbstractUDdata: XML Error: " + ex.toString(), ex); //$NON-NLS-1$ + } + + /** Fatal error. */ + public void fatalError(SAXParseException ex) throws SAXException { + SystemBasePlugin.logError("SystemAbstractUDdata: Fatal XML error: " + ex.toString(), ex); //$NON-NLS-1$ + throw (ex); + } + + // ********************************************************** + // + // ********************************************************** + /** + * Interface org.eclipse.core.resources. IResourceChangeListener + */ + public void resourceChanged(IResourceChangeEvent event) { + //System.out.println( "SystemUDBaseManager.resourceChanged: flag=" + String.valueOf(ignoreMyResourceChange) ); + if (ignoreMyResourceChange) return; + if (IResourceChangeEvent.POST_CHANGE != event.getType()) return; + Object source = event.getSource(); + // if (ignoreEvents || !(event.getSource() instanceof IWorkspace)) + if (!(source instanceof IWorkspace)) return; + // int type = event.getType(); + // String sType = SystemResourceListener.getTypeString(type); + // System.out.println("RESOURCE CHANGED EVENT: eventType="+sType+", eventSource=" + source.toString() ); + // System.out.println("RESOURCE DELTA:"); //$NON-NLS-1$ + // IResource resource = event.getResource(); + IResourceDelta delta = event.getDelta(); + if (null == delta) return; + /* + if ((resource == null) && (delta != null)) + resource = delta.getResource(); + + if ( null != resource) + { + String rname = resource.getLocation().toOSString(); + + System.out.println("RESOURCE " + rname); + System.out.println("RESOURCE Name: " + resource.getName() ); + System.out.println("RESOURCE type: " + SystemResourceListener.getTypeString( resource.getType()) ); + + if ( null != resource.getProject() ) + System.out.println("RESOURCE Proj: " + resource.getProject().getName() ); + + } + + resource = delta.getResource(); + if ( null != resource) + { + String rname = resource.getLocation().toOSString(); + + System.out.println("RESOURCE DELTA: " + rname); + System.out.println("RESOURCE Name: " + resource.getName() ); + System.out.println("RESOURCE type: " + SystemResourceListener.getTypeString( resource.getType()) ); + + if ( null != resource.getProject() ) + System.out.println("RESOURCE Proj: " + resource.getProject().getName() ); + } + */ + //System.out.println("res UD file:" ); + if (supportsProfiles()) { + ISystemProfile[] activeProfiles = getActiveSystemProfiles(); + for (int idx = 0; idx < activeProfiles.length; idx++) { + ISystemProfile profile = activeProfiles[idx]; + ensureDirPathResolved(profile); + searchDelta(profile, delta, 0); + } + } else { + ensureDirPathResolved(null); + searchDelta(null, delta, 0); + } + } + + private void ensureDirPathResolved(ISystemProfile profile) { + Object[] dirPath = getProfileIndexedInstanceVariable_dirPath(profile); + if (dirPath == null) resolveDirPath(profile); + } + + private void searchDelta(ISystemProfile profile, IResourceDelta parent, int nestLevel) { + Object[] dirPath = getProfileIndexedInstanceVariable_dirPath(profile); + String target = (String) dirPath[nestLevel]; + // System.out.println("search for: "+String.valueOf( nestLevel)+ ": "+target); + IResourceDelta resdel[] = parent.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.ADDED | IResourceDelta.REMOVED); + for (int i = 0; i < resdel.length; i++) { + IResource resource = resdel[i].getResource(); + // System.out.println(" .. " + String.valueOf(i) + ": " + resource.getName()); + if ((null != resource) && target.equals(resource.getName())) { + // End of the search chain? + nestLevel++; + if (nestLevel < dirPath.length) + // Recurse + searchDelta(profile, resdel[i], nestLevel); + else { + // Matches !! + //System.out.println("Matches! " ); + processResourceChangeHit(profile); + } + // Stop further searching at this level + return; + } + } + } + + /** + * Get the active system profiles + */ + private ISystemProfile[] getActiveSystemProfiles() { + return RSEUIPlugin.getTheSystemRegistry().getActiveSystemProfiles(); + } + + // --------------------------------------------------------------------------- + // The GUI for working with user-defined actions sets the current profile + // as the user selects it. This becomes the default profile to work with until + // the user changes it again + // --------------------------------------------------------------------------- + /** + * Set the profile we are working with the actions for, until reset. + * Note, to reduce chance for errors, we do not implicitly use this profile + * anywhere! Rather, this is simply a convenient holding place for it, + * and the caller must explicitly call getCurrentProfile to retrieve it + * when it is needed as input to any of the other methods in this class + * or a child class. + */ + public void setCurrentProfile(ISystemProfile profile) { + this.currentlyActiveProfile = profile; + } + + /** + * Get the profile we are currently working with, as set by a call to setCurrentProfile + */ + public ISystemProfile getCurrentProfile() { + return currentlyActiveProfile; + } + + // ----------------------------------------------------------- + // THE FOLLOWING METHODS ARE ALL INDEXED BY SYSTEM PROFILE... + // ----------------------------------------------------------- + /** + * Prime the given document with any default actions/types + * Should be overridden! + */ + public SystemXMLElementWrapper[] primeDocument(ISystemProfile profile) { + return null; + } + + /** + * Get the release of the document. Eg, value of the "release"attribute of the root. + * If not set then we assume it is release "4.0" + */ + public String getDocumentRelease(ISystemProfile profile) { + Document doc = getDocument(profile); + Element root = doc.getDocumentElement(); + String rel = root.getAttribute(RELEASE_ATTR); + if (rel == null) + return "4.0"; //$NON-NLS-1$ + else + return rel; + } + + /** + * Load document for given SystemProfile only if not already done. + */ + public Document getDocument(ISystemProfile profile) { + Document doc = getProfileIndexedInstanceVariable_Document(profile); + if (doc == null) { + doc = loadUserData(profile); + setProfileIndexedInstanceVariable_Document(profile, doc); + // document is good. Now, check the release date stamped on it. + // if not the current release, then we must consider migration... + Element docroot = doc.getDocumentElement(); + String docRelease = docroot.getAttribute(RELEASE_ATTR); + if ((docRelease == null) || (docRelease.length() == 0)) docRelease = "4.0"; //$NON-NLS-1$ + if (!docRelease.equals(CURRENT_RELEASE_NAME)) { + //System.out.println("Doing migration from "+docRelease+" to " + ISystemConstants.CURRENT_RELEASE_NAME + "..."); + boolean migrationDone = doMigration(profile, docRelease); + docroot.setAttribute(RELEASE_ATTR, SystemResources.CURRENT_RELEASE_NAME); + if (migrationDone) { + setChanged(profile); // is this the right thing to do? + saveUserData(profile); + } + } + } else { + } + return doc; + } + + /** + * Overridable extension point for child classes to do migration of their document. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done + */ + protected abstract boolean doMigration(ISystemProfile profile, String oldRelease); + + /** + * Get the active shell so we can show an error message + */ + private Shell getActiveShell() { + return Display.getCurrent().getActiveShell(); + } + + /** + * Indicate the data has changed for the document for the given system profile + */ + public void setChanged(ISystemProfile profile) { + dataChanged(profile); + setProfileIndexedInstanceVariable_hasChanged(profile, true); + } + + /** + * Reload the User data for the given profile, from disk if it has been changed in memory + */ + public void resetUserData(ISystemProfile profile) { + //System.out.println("UD reset: " + getFileName() ); + if (!getProfileIndexedInstanceVariable_hasChanged(profile)) setProfileIndexedInstanceVariable_Document(profile, loadUserData(profile)); + } + + /** + * Force a re-load + */ + public void processResourceChangeHit(ISystemProfile profile) { + setProfileIndexedInstanceVariable_Document(profile, null); + dataChanged(profile); + } + + /** + * Get the folder containing the xml file used to persist the actions, + * for the given profile + */ + private IFolder getFolder(ISystemProfile profile) { + ISubSystem subsystem = getSubSystem(); + // Import action: no subsystem + if ((subsystem == null) && (getSubSystemFactory() == null)) + return importCaseFolder; + else { + if ((profile == null) && (subsystem != null)) profile = subsystem.getSystemProfile(); + return getDocumentFolder(getSubSystemFactory(), profile); + } + } + + /** + * Get the folder containing the xml file used to persist the actions, + * for the given profile + */ + protected abstract IFolder getDocumentFolder(ISubSystemConfiguration subsystemFactory, ISystemProfile profile); + + /** + * Intended for IMPORT actions only, where no Subsystem instance available: + */ + public abstract void setFolder(String profileName, String factoryId); + + /** + * Indicate data has changed for the given profile + */ + protected void dataChanged(ISystemProfile profile) { + } + + /** + * Load the user actions from the XML document, for the given profile + */ + protected Document loadUserData(ISystemProfile profile) { + //System.out.println("UD load: " + getFileName() ); + dataChanged(profile); // not sure why we call this, at this time!! Phil + setProfileIndexedInstanceVariable_hasChanged(profile, false); + String fn = getFilePath(profile); + Document doc = null; + if (!(new File(fn)).canRead()) + doc = createAndPrimeDocument(profile); + else + doc = loadAndParseXMLFile(fn, profile); + //addListener(); + return doc; + } + + /** + * Create and prime the XML document + */ + protected Document createAndPrimeDocument(ISystemProfile profile) { + Document doc = initializeDocument(); + setProfileIndexedInstanceVariable_Document(profile, doc); + SystemXMLElementWrapper[] primedElements = primeDocument(profile); + if (primedElements != null) { + for (int idx = 0; idx < primedElements.length; idx++) { + SystemXMLElementWrapper newElement = primedElements[idx]; + newElement.setIBM(true); + newElement.setUserChanged(false); + } + } + saveUserData(profile); + return doc; + } + + /** + * Save user data for the given system profile + */ + public void saveUserData(ISystemProfile profile) { + //System.out.println("UD save: " + getFileName() ); + if (!getProfileIndexedInstanceVariable_hasChanged(profile)) { + //System.out.println("UD save: No changes. " + getFileName() ); + return; + } + /* Old way of toggling off/on resource change monitoring wasnt working + for case of two connections with same subsystems with UDA data loaded, + and user changes UDA data in one. Change wasn't propagated to other, + which might later update the UDA file with old data. + + Better appraoch is to toggle my (ignoreMyResourceChange) flag around + my update, and check that flag in my resource change listener so that I + dont reload the data I just saved. (But other connection subsystem + instances do.) + */ + String fn = getFilePath(profile); + // Disable our resource change monitoring temporarily while we + // update the XML file + ignoreMyResourceChange = true; + SystemResourceManager.turnOffResourceEventListening(); + File xf = new File(fn); + if (!xf.getParentFile().exists()) // test added by Phil + { + xf.getParentFile().mkdirs(); // this is bad! Who refreshes from local? + try { // ok, now we do. I added this. Phil + getFolder(profile).getParent().refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (Exception exc) { + } + } + Document udoc = getProfileIndexedInstanceVariable_Document(profile); + try // address various file I/O exceptions + { + FileOutputStream fo = new FileOutputStream(xf); + try { + Source source = new DOMSource(udoc); + Result result = new StreamResult(fo); + Transformer t = TransformerFactory.newInstance().newTransformer(); + t.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + t.transform(source, result); + } catch (TransformerConfigurationException e) { + } catch (TransformerFactoryConfigurationError e) { + } catch (TransformerException e) { + } + // XMLSerializer xs = new XMLSerializer(fo, null); + // // Select "readable" format. (multiple lines) + // OutputFormat fmt = new OutputFormat(udoc); + // xs.setOutputFormat(fmt); + // fmt.setIndenting(true); + // fmt.setIndent(1); // 0 turns off indenting + // // Line width 300, so that we don't cut long comments/commands/actions at a certain length. + // fmt.setLineWidth(300); + // fmt.setPreserveSpace(true); + // xs.serialize(udoc); + // fo.close(); + // fo = null; + setProfileIndexedInstanceVariable_hasChanged(profile, false); + // Always refresh-from-local: + // If this saves, don't want next refresh-from-local to trigger + // a change event when we were the ones to change it. (and have the + // current data already loaded.) + // Refresh the workspace to recognise (new) file. + // getFolder().refreshLocal( IResource.DEPTH_ONE, null); + // A more specific refresh: + IFile file = getFolder(profile).getFile(getFileName()); + // file.touch(null); + file.refreshLocal(IResource.DEPTH_ONE, null); + } catch (Exception exc) { + // if (null != fo) + // fo.close(); + SystemMessageDialog msgdlg = new SystemMessageDialog(SystemBasePlugin.getActiveWorkbenchShell(), RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_SAVE_FAILED).makeSubstitution(exc)); + msgdlg.open(); + } + ignoreMyResourceChange = false; + SystemResourceManager.turnOnResourceEventListening(); + } + + /** + * Refresh the xml file from disk. Eg equivalent to use selecting Refresh. + */ + public void refreshLocal(ISystemProfile profile) { + try { + IFile file = getFolder(profile).getFile(getFileName()); + file.touch(null); + file.refreshLocal(IResource.DEPTH_ONE, null); + } catch (Exception e) { + SystemBasePlugin.logError("Error refreshing in SystemUDBaseManager.", e); //$NON-NLS-1$ + } + } + + /** + * Move given element down one in document, save document + * @return true if move successful + */ + public boolean moveElementDown(SystemXMLElementWrapper elementWrapper, SystemXMLElementWrapper nextNextElementWrapper) { + getDocument(elementWrapper.getProfile()); + Element element = elementWrapper.getElement(); + try { + Node parentElement = element.getParentNode(); + //Node nextElement = element.getNextSibling(); + //Node nextNextElement = nextElement.getNextSibling(); + if (nextNextElementWrapper != null) + parentElement.insertBefore(element, nextNextElementWrapper.getElement()); + else + parentElement.insertBefore(element, null); + } catch (Exception exc) { + SystemBasePlugin.logError("Error moving user action/type down", exc); //$NON-NLS-1$ + return false; + } + saveUserData(elementWrapper.getProfile()); + return true; + } + + /** + * Move given element up one in document, save document + * @return true if move successful + */ + public boolean moveElementUp(SystemXMLElementWrapper elementWrapper, SystemXMLElementWrapper previousElementWrapper) { + getDocument(elementWrapper.getProfile()); + Element element = elementWrapper.getElement(); + try { + Node parentElement = element.getParentNode(); + //Node previousElement = element.getPreviousSibling(); + parentElement.insertBefore(element, previousElementWrapper.getElement()); + } catch (Exception exc) { + SystemBasePlugin.logError("Error moving user action/type up", exc); //$NON-NLS-1$ + return false; + } + saveUserData(elementWrapper.getProfile()); + return true; + } + + /** + * Prepares a given element for the clipboard. + * This clones the element in transient memory, and returns a reference to the clone + * that can be placed in a local clipboard instance. Subsequently, paste is only enabled + * if the reference in the clipboard corresponds to a node clone in this object. + * @return an id that uniquely identifies the cloned node, or null if it failed. + */ + public String prepareClipboardCopy(SystemXMLElementWrapper elementWrapper) { + getDocument(elementWrapper.getProfile()); + Element element = elementWrapper.getElement(); + currentNodeClone = null; + try { + currentNodeClone = (Element) element.cloneNode(true); // true=>deep clone, including text vs just attributes + } catch (Exception exc) { + SystemBasePlugin.logError("Error cloning user action/type element for clipboard", exc); //$NON-NLS-1$ + return null; + } + currentNodeCloneID = getActionSubSystem().getClass().getName() + "." + //$NON-NLS-1$ + getFileName() + "." + //$NON-NLS-1$ + elementWrapper.getName(); + currentNodeCloneDomain = elementWrapper.getDomain(); + // currentNodeCloneName = elementWrapper.getName(); + return currentNodeCloneID; + } + + /** + * Test if the given ID, read from the clipboard, matches a node we prepared for + * the clipboard. It also ensure that domains match. + *

+ * This decides if the paste action will be enabled or not + */ + public boolean enablePaste(SystemXMLElementWrapper selectedElementWrapper, String id) { + if (id == null) return false; + int selectedElementDomain = selectedElementWrapper.getDomain(); + return (id.equals(currentNodeCloneID) && (selectedElementDomain == currentNodeCloneDomain)); + } + + /** + * After a successful call to enablePaste, this is called to do the paste operation. + * The new object is inserted before the current selection if appropriate, else to the end of the domain + * @return SystemXMLElementWrapper wrapper object of pasted element, or null if it failed + */ + public SystemXMLElementWrapper pasteClipboardCopy(SystemXMLElementWrapper selectedElementWrapper, String id) { + getDocument(selectedElementWrapper.getProfile()); + Element selectedElement = selectedElementWrapper.getElement(); + SystemXMLElementWrapper pastedElementWrapper = null; + try { + Node parentElement = null; + Element pastedElement = null; + if (selectedElementWrapper.isDomain()) { + parentElement = selectedElement; + pastedElement = (Element) parentElement.appendChild(currentNodeClone); + } else { + parentElement = selectedElement.getParentNode(); + pastedElement = (Element) parentElement.insertBefore(currentNodeClone, selectedElement); + } + pastedElementWrapper = createElementWrapper(pastedElement, selectedElementWrapper.getProfile(), selectedElementWrapper.getDomain()); + pastedElementWrapper.setName(getUniqueCloneName(pastedElementWrapper)); + pastedElementWrapper.setIBM(false); // not an IBM action, even if source was + } catch (Exception exc) { + SystemBasePlugin.logError("Error pasting user action/type", exc); //$NON-NLS-1$ + return null; + } + saveUserData(selectedElementWrapper.getProfile()); + return pastedElementWrapper; + } + + /** + * Return a new unique name to assign to a pastable element node clone + */ + private String getUniqueCloneName(SystemXMLElementWrapper elementWrapper) { + String newName = SystemUDAResources.RESID_UDA_COPY_NAME_1; + newName = SystemMessage.sub(newName, "%1", elementWrapper.getName()); //$NON-NLS-1$ + Vector existingNames = getExistingNames(elementWrapper.getProfile(), elementWrapper.getDomain()); + boolean nameInUse = (existingNames.indexOf(newName) >= 0); + int nbr = 2; + while (nameInUse) { + newName = SystemUDAResources.RESID_UDA_COPY_NAME_N; + newName = SystemMessage.sub(newName, "%1", elementWrapper.getName()); //$NON-NLS-1$ + newName = SystemMessage.sub(newName, "%2", Integer.toString(nbr)); //$NON-NLS-1$ + nameInUse = (existingNames.indexOf(newName) >= 0); + ++nbr; + } + return newName; + } + + // ---------------------------------------------------------------------- + // THE FOLLOWING WERE PULLED DOWN FROM VARIOUS SUBCLASSES, AND ABSTRACTED + // TO BE USABLE AS IS FOR ALL SCENARIOS: + // ACTIONS VS TYPES + // PROFILE-SCOPED VS NOT-PROFILE-SCOPED + // SUPPORTS-DOMAINS VS DOESN'T-SUPPORT DOMAINS + // ---------------------------------------------------------------------- + /** + * Method declared on IStructuredContentProvider. + * Returns root elements for the currently set profile (see setCurrentProfile). + * If this is null, returns root elements for all active profiles + */ + public Object[] getElements(Object element) { + if (!supportsProfiles()) + return getElements((ISystemProfile) null, element); + else { + ISystemProfile currProfile = getCurrentProfile(); + if (currProfile != null) + return getElements(currProfile, element); + else + return getElements(getActiveSystemProfiles(), element); + } + } + + /** + * Return root elements for given profile. + */ + public Object[] getElements(ISystemProfile profile, Object element) { + return getElements(new ISystemProfile[] { profile }, element); + } + + /** + * Return the root elements. + *

+ * If domains are supported, returns a root "New" item plus element wrappers for + * any existing domain tags in the xml + * If domains are not supported, returns a non-root "New" item plus element + * wrappers for all action/type xml tags found under the root of the xml document + */ + public Object[] getElements(ISystemProfile[] profiles, Object input) { + /* + if (input == null) + System.out.println("Inside getElements. input is null"); + else + System.out.println("Inside getElements. input is of type " + input.getClass().getName()); + */ + if ((input != null) && !(input instanceof String)) return EMPTY_ARRAY; + Vector v = new Vector(); + // if domains supported, return "New" root item, plus wrappers of + // any domain xml elements found... + int onlyDomain = getActionSubSystem().getSingleDomain(this); + if (getActionSubSystem().supportsDomains() && (onlyDomain == -1)) { + v.add(SystemUDTreeViewNewItem.getRootNewItem(isUserActionsManager(), getNewNodeLabel())); + if (supportsProfiles()) { + // get domain elements per given profile + for (int idx = 0; idx < profiles.length; idx++) { + ISystemProfile profile = profiles[idx]; + v = createExistingDomainElementWrappers(v, profile); + } + } else { + // get domain elements + v = createExistingDomainElementWrappers(v, null); + } + } + // if domains not supported, return singleton New item, plus wrappers + // of any action/type elements found + else { + Element parentDomainElement = null; + if (onlyDomain == -1) + v.add(SystemUDTreeViewNewItem.getOnlyNewItem(isUserActionsManager(), getNewNodeLabel())); + else + v.add(SystemUDTreeViewNewItem.getOnlyNewItem(onlyDomain, isUserActionsManager(), getNewNodeLabel())); + if (supportsProfiles()) { + // get actual elements (actions/types) per given profile + for (int idx = 0; idx < profiles.length; idx++) { + ISystemProfile profile = profiles[idx]; + if (onlyDomain != -1) parentDomainElement = findDomainElement(getDocument(profile), onlyDomain); + v = getXMLWrappers(v, parentDomainElement, profile); + } + } else { + // get actual elements (actions/types) + if (onlyDomain != -1) parentDomainElement = findDomainElement(getDocument(null), onlyDomain); + v = getXMLWrappers(v, parentDomainElement, null); + } + } + return v.toArray(); + } + + /** + * Overridable method for returning the label for the "New" nodes in the tree view. + * Will usually be different for actions versus types. + * @return translated value for "New" in new icon. Default is "New" + */ + protected String getNewNodeLabel() { + return SystemResources.ACTION_CASCADING_NEW_LABEL; + } + + /** + * Return true if this is user actions, false if this is named types. + */ + protected abstract boolean isUserActionsManager(); + + /** + * Return all the user actions/types under the given node. + * If input is a New item, return New items per domain + * If input is a Domain element wrapper, return wrappers of all child actions/types under that domain, + * for that domain's profile. + */ + public Object[] getChildren(Object element) { + /* + if (element == null) + System.out.println("Inside getElements. input is null"); + else + System.out.println("Inside getElements. input is of type " + element.getClass().getName()); + */ + if (element instanceof SystemUDTreeViewNewItem) { + // Only on the (parent) cascade item. + // Will only happen if we support domains + if (!((SystemUDTreeViewNewItem) element).isExecutable()) { + boolean isUserActionDialog = ((SystemUDTreeViewNewItem) element).isWorkWithActionsDialog(); + if (newItemsPerDomain == null) { + int nbrDomains = getActionSubSystem().getMaximumDomain() + 1; + newItemsPerDomain = new SystemUDTreeViewNewItem[nbrDomains]; + for (int idx = 0; idx < newItemsPerDomain.length; idx++) { + if (isUserActionDialog) + newItemsPerDomain[idx] = new SystemUDTreeViewNewItem(true, getActionSubSystem().mapDomainXlatedNewName(idx), idx, isUserActionDialog); + else + newItemsPerDomain[idx] = new SystemUDTreeViewNewItem(true, getActionSubSystem().mapDomainXlatedNewTypeName(idx), idx, isUserActionDialog); + } + } + return newItemsPerDomain; + } + return EMPTY_ARRAY; + } + // getElements() is called to get roots, so we should never be + // called here unless we have been given a domain element wrapper + if (!(element instanceof SystemXMLElementWrapper) || !((SystemXMLElementWrapper) element).isDomain()) return EMPTY_ARRAY; + SystemXMLElementWrapper parent = (SystemXMLElementWrapper) element; + Vector v = new Vector(); + ISystemProfile profile = parent.getProfile(); + getXMLWrappers(v, parent, profile); + return v.toArray(); + } + + /** + * Find a child element of a given name. + * Returns the xml node element or null + */ + public Element findChildByName(ISystemProfile profile, String name, int domain) { + Document xdoc = getDocument(profile); + if (getActionSubSystem().supportsDomains() && (domain >= 0)) { + Element domainElement = findDomainElement(xdoc, domain); + return SystemXMLElementWrapper.findChildByName(domainElement, xdoc, getTagName(), name); + } else { + return SystemXMLElementWrapper.findChildByName(null, xdoc, getTagName(), name); + } + } + + /** + * Find a child element of a given name. + * Returns the wrapper of the xml node element or null + */ + public SystemXMLElementWrapper findByName(ISystemProfile profile, String name, int domain) { + Element element = findChildByName(profile, name, domain); + if (element == null) + return null; + else + return createElementWrapper(element, profile, domain); + } + + /** + * Get a list of existing names, for unique-name checking. + */ + public Vector getExistingNames(ISystemProfile profile, int domain) { + Document xdoc = getDocument(profile); + if (getActionSubSystem().supportsDomains() && (domain >= 0)) { + Element domainElement = findDomainElement(xdoc, domain); + if (domainElement == null) return new Vector(); // defect 46147 + return SystemXMLElementWrapper.getExistingNames(domainElement, xdoc, getTagName()); + } else { + return SystemXMLElementWrapper.getExistingNames(null, xdoc, getTagName()); + } + } + + /** + * Add a new user action or type. + * Creates the new XML node in the document, + * and creates and returns a wrapper object for it. + */ + public SystemXMLElementWrapper addElement(ISystemProfile profile, int domain, String name) { + Document xdoc = getDocument(profile); + SystemXMLElementWrapper newElementWrapper = null; + Element newtag = xdoc.createElement(getTagName()); + newtag.setAttribute("Name", uppercaseName() ? name.toUpperCase() : name); //$NON-NLS-1$ + // Get domain element, create if necessary + if (getActionSubSystem().supportsDomains()) { + Element se = findOrCreateDomainElement(xdoc, domain); + se.appendChild(newtag); + } else + xdoc.getDocumentElement().appendChild(newtag); + newElementWrapper = createElementWrapper(newtag, profile, domain); + setChanged(profile); + return newElementWrapper; + } + + /** + * Delete a give user action or type, given its wrapper. + * Deletes the xml node from the document. + */ + public void delete(ISystemProfile profile, SystemXMLElementWrapper elementWrapper) { + elementWrapper.deleteElement(); + setChanged(profile); + } + + // ----------------------------------------------------------- + // ISOLATE READING AND WRITING OF PROFILE-INDEXED VARIABLES... + // ----------------------------------------------------------- + /** + * Set the profile-indexed document instance variable + */ + private void setProfileIndexedInstanceVariable_Document(ISystemProfile profile, Document doc) { + if (!supportsProfiles()) + udocNoProfile = doc; + else + udocsByProfile.put(profile, doc); + } + + /** + * Get the profile-indexed document instance variable + */ + private Document getProfileIndexedInstanceVariable_Document(ISystemProfile profile) { + if (!supportsProfiles()) + return udocNoProfile; + else + return (Document) udocsByProfile.get(profile); + } + + /** + * Set the profile-indexed has-changed instance variable + */ + private void setProfileIndexedInstanceVariable_hasChanged(ISystemProfile profile, boolean hasChanged) { + if (!supportsProfiles()) + hasChangedNoProfile = hasChanged; + else { + if (hasChanged) + hasChangedByProfile.put(profile, Boolean.TRUE); + else + hasChangedByProfile.put(profile, Boolean.FALSE); + } + } + + /** + * Get the profile-indexed has-changed instance variable + */ + private boolean getProfileIndexedInstanceVariable_hasChanged(ISystemProfile profile) { + if (!supportsProfiles()) + return hasChangedNoProfile; + else { + Boolean b = (Boolean) hasChangedByProfile.get(profile); + if (b == null) + return false; + else + return (b == Boolean.TRUE); + } + } + + /** + * Set the profile-indexed dir-path instance variable + */ + private void setProfileIndexedInstanceVariable_dirPath(ISystemProfile profile, Object[] dirPath) { + if (!supportsProfiles()) + dirPathNoProfile = dirPath; + else + dirPathByProfile.put(profile, dirPath); + } + + /** + * Get the dir-path has-changed instance variable + */ + private Object[] getProfileIndexedInstanceVariable_dirPath(ISystemProfile profile) { + if (!supportsProfiles()) + return dirPathNoProfile; + else + return (Object[]) dirPathByProfile.get(profile); + } + + // ------------------------------------- + // METHODS RELATED TO DOMAIN ELEMENTS... + // ------------------------------------- + /** + * Given a domain's integer representation, find its element in + * xml document and return the wrapper for it. If not found, + * returns null + */ + protected SystemXMLElementWrapper getDomainWrapper(ISystemProfile profile, int domain) { + Element element = findDomainElement(getDocument(profile), domain); + if (element != null) + return createDomainElementWrapper(element, profile, domain); + else + return null; + } + + /** + * Find all existing domain XML elements that are children of the root, + * and create wrapper objects for them, and add them to the given vector. + *

+ * It is important to note these are returned in the pre-determined order, + * not the order they are found in the document! + */ + protected Vector createExistingDomainElementWrappers(Vector v, ISystemProfile profile) { + Document xdoc = getDocument(profile); + Element docroot = xdoc.getDocumentElement(); + // get the "domain" children of the root, in the pre-determined order of domains + NodeList subList = docroot.getChildNodes(); + if ((subList == null) || (subList.getLength() == 0)) return v; + String[] domains = getActionSubSystem().getDomainNames(); + int subListLen = subList.getLength(); + for (int idx = 0; idx < domains.length; idx++) { + Element match = null; + for (int jdx = 0; (match == null) && (jdx < subListLen); jdx++) { + Node currNode = subList.item(jdx); + if ((currNode instanceof Element) && + // is "Domain" tag, and "Type" attr value matches domains[idx]? + isDomainElement((Element) currNode, domains[idx])) { + //Element currElement = (Element)currNode; + //if (currElement.getAttribute(XE_DOMTYPE).equals(domains[idx])) + match = (Element) currNode; + } + } + if (match != null) v.add(createDomainElementWrapper(match, profile, idx)); + } + return v; + } + + /** + * Create a domain element wrapper + */ + protected SystemXMLElementWrapper createDomainElementWrapper(Element xmlDomainElementToWrap, ISystemProfile profile, int domain) { + return createElementWrapper(xmlDomainElementToWrap, profile, domain); + } + + /** + * Given an xml action/type document, try to find a domain element ("Domain" tag) + * of the given domain type. If not found, do NOT create it. + */ + protected Element findDomainElement(Document xdoc, int domain) { + return findOrCreateDomainElement(xdoc, domain, false); + } + + /** + * Given an xml action/type document, try to find a domain element ("Domain" tag) + * of the given untranslated name ("Type" attribute). If not found, create it. + */ + protected Element findOrCreateDomainElement(Document xdoc, int domain) { + return findOrCreateDomainElement(xdoc, domain, true); + } + + /** + * Given an xml action/type document, try to find a domain element ("Domain" tag) + * of the given untranslated name ("Type" attribute). If not found, optionally create it. + */ + protected Element findOrCreateDomainElement(Document xdoc, int domain, boolean create) { + NodeList subList = xdoc.getDocumentElement().getChildNodes(); + String domainName = getActionSubSystem().mapDomainName(domain); // unxlated name. Eg "Type" parm + Element domainElement = null; + if (subList != null) { + for (int idx = 0; (domainElement == null) && (idx < subList.getLength()); idx++) { + Node sn = subList.item(idx); + if (sn instanceof Element) { + if (isDomainElement((Element) sn, domainName)) domainElement = (Element) sn; + } + } + } + if (create && (domainElement == null)) domainElement = createDomainElement(xdoc, domain); + return domainElement; + } + + /** + * Create a new xml domain element. That, an element of tag name "Domain". + * @param xdoc - the document to add it to. Will be added as child of root + * @param domain - the integer representation of the domain, used to get its name and translated name + */ + protected Element createDomainElement(Document xdoc, int domain) { + Element element = xdoc.createElement(XE_DOMAIN); + xdoc.getDocumentElement().appendChild(element); + element.setAttribute(XE_DOMTYPE, getActionSubSystem().mapDomainName(domain)); + element.setAttribute(XE_DOMNAME, getActionSubSystem().mapDomainXlatedName(domain)); + return element; + } + + // ------------------------------------------- + // STATIC HELPER METHODS RELATED TO DOMAINS... + // ------------------------------------------- + /** + * Given an xml Element object, return true if it is a Domain + * element. That is, if its tag name is "Domain" + */ + public static boolean isDomainElement(Element element) { + return (element.getTagName().equals(XE_DOMAIN)); + } + + /** + * Given an xml Element object, return true if it is a Domain + * element and its "Type" attribute matches the given name. + */ + public static boolean isDomainElement(Element element, String domainName) { + return isDomainElement(element) && domainTypeEquals(element, domainName); + } + + /** + * Given an xml Domain element, return true if it's "type" attribute matches + * the given untranslated domain name + */ + public static boolean domainTypeEquals(Element element, String domainName) { + return (element.getAttribute(XE_DOMTYPE).equals(domainName)); + } + + /** + * Checking not deleted. Still in document tree? + * (for Actions and Types). + * Needed by tree view/ Edit pane selection change processing. + * If current selection has validation errors, & user tries to + * change selection, want to set view back to the old selection, + * but have to confirm it hasn't been deleted, first. + * + * Do so by traversing the tree backwards, back to the Document root, + * then forwards again to verify the child links are in place. + */ + public static boolean inCurrentTree(Node n) { + if (n instanceof Document) return true; + Node parent = n.getParentNode(); + if (null == parent) return false; + // Recursive, walk tree back to root, then finally Document. + if (!inCurrentTree(parent)) return false; + // Finally, check this is still a child of the parent + Node sibling = parent.getFirstChild(); + while (null != sibling) { + if (n == sibling) return true; + sibling = sibling.getNextSibling(); + } + return false; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeView.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeView.java new file mode 100644 index 00000000000..cc4abea988b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeView.java @@ -0,0 +1,803 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +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.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.internal.ui.view.SystemViewMenuListener; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.ISystemAction; +import org.eclipse.rse.ui.messages.SystemMessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Base class for tree views for both actions and types. + */ +public class SystemUDBaseTreeView extends TreeViewer implements IMenuListener, IDoubleClickListener, ISystemMessages, ISystemUDTreeView { + protected Composite parent; + protected MenuManager menuMgr; + protected SystemUDBaseManager docManager; + protected ISubSystem subsystem; + protected ISubSystemConfiguration subsystemFactory; + protected ISystemProfile profile; + protected ISystemUDWorkWithDialog wwDialog; + protected SystemUDTreeActionCopy copyAction; + protected SystemUDTreeActionPaste pasteAction; + protected SystemUDTreeActionDelete deleteAction; + protected SystemUDTreeActionMoveUp moveUpAction; + protected SystemUDTreeActionMoveDown moveDownAction; + protected SystemUDARestoreDefaultsActions restoreAction; + protected Clipboard clipboard; + protected boolean menuListenerAdded; + + /** + * Constructor when we have a subsystem + */ + public SystemUDBaseTreeView(Composite parent, ISystemUDWorkWithDialog editPane, ISubSystem ss, SystemUDBaseManager docManager) { + //super(parent); + // I don't think multi-selection makes sense for this tree! Phil + super(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); // no SWT_MULTI + // this.shell = shell; + this.parent = parent; + this.subsystem = ss; + this.subsystemFactory = subsystem.getSubSystemConfiguration(); + this.profile = subsystem.getSystemProfile(); + this.docManager = docManager; + this.wwDialog = editPane; + init(); + getTree().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + if (clipboard != null) clipboard.dispose(); + } + }); + } + + /** + * Constructor when we have a subsystem factory and profile + */ + public SystemUDBaseTreeView(Composite parent, ISystemUDWorkWithDialog editPane, ISubSystemConfiguration ssFactory, ISystemProfile profile, SystemUDBaseManager docManager) { + //super(parent); + // I don't think multi-selection makes sense for this tree! Phil + super(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); // no SWT_MULTI + // this.shell = shell; + this.parent = parent; + this.subsystemFactory = ssFactory; + this.profile = profile; + this.docManager = docManager; + this.wwDialog = editPane; + init(); + getTree().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + if (clipboard != null) clipboard.dispose(); + } + }); + } + + protected void init() { + setContentProvider(docManager); + setLabelProvider(new SystemUDBaseTreeViewLabelProvider(docManager)); + // For double-click on "New..." items in tree + addDoubleClickListener(this); + //setAutoExpandLevel(2); // does not work!! + // ----------------------------- + // Enable right-click popup menu + // ----------------------------- + menuMgr = new MenuManager("#UDTreePopupMenu"); //$NON-NLS-1$ + // menuMgr = new SystemSubMenuManager("#UDTreePopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(this); + Menu menu = menuMgr.createContextMenu(getTree()); + getTree().setMenu(menu); + /**/ + setInput("0"); // this should trigger displaying the roots //$NON-NLS-1$ + } + + /** + * Expand the non-new domain (parent) nodes + */ + public void expandDomainNodes() { + // for usability we try to auto-expand the domain (parent) nodes... + if (docManager.getActionSubSystem().supportsDomains()) { + TreeItem[] rootItems = getTree().getItems(); + for (int idx = 0; idx < rootItems.length; idx++) { + if (rootItems[idx].getData() instanceof SystemXMLElementWrapper) // assume a domain node + { + setExpandedState(rootItems[idx].getData(), true); + } else if (rootItems[idx].getData() instanceof SystemUDTreeViewNewItem) { + SystemUDTreeViewNewItem newNode = (SystemUDTreeViewNewItem) rootItems[idx].getData(); + if (!newNode.isExecutable()) setExpandedState(rootItems[idx].getData(), true); + } + } + } + } + + /** + * Expand the given domain (parent) node, named by its + * translatable name. + */ + public void expandDomainNode(String displayName) { + // for usability we try to auto-expand the domain (parent) nodes... + if (docManager.getActionSubSystem().supportsDomains()) { + TreeItem[] rootItems = getTree().getItems(); + for (int idx = 0; idx < rootItems.length; idx++) { + if (rootItems[idx].getData() instanceof SystemXMLElementWrapper) // assume a domain node + { + //System.out.println(rootItems[idx].getText()); + if (rootItems[idx].getText().equals(displayName)) { + setExpandedState(rootItems[idx].getData(), true); + return; + } + } + } + } + } + + /** + * Called when the context menu is about to open. + * Calls {@link #fillContextMenu(IMenuManager)} + */ + public void menuAboutToShow(IMenuManager menu) { + fillContextMenu(menu); + if (!menuListenerAdded) { + if (menu instanceof MenuManager) { + Menu m = ((MenuManager) menu).getMenu(); + if (m != null) { + menuListenerAdded = true; + SystemViewMenuListener ml = new SystemViewMenuListener(); + //ml.setShowToolTipText(true, wwDialog.getMessageLine()); does not work for some reason + m.addMenuListener(ml); + } + } + } + } + + /** + * This is method is called to populate the popup menu + */ + public void fillContextMenu(IMenuManager menu) { + IStructuredSelection selection = (IStructuredSelection) getSelection(); + // this code assumes single select. if we ever change to allow multiple selection, + // this code will have to change + int selectionCount = selection.size(); + if (selectionCount > 0) // something selected + { + Object firstSelection = selection.getFirstElement(); + if ((firstSelection instanceof SystemXMLElementWrapper) && !((SystemXMLElementWrapper) firstSelection).isDomain()) { + // Partition into groups... + createStandardGroups(menu); + ISystemAction action = getDeleteAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getCopyAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getPasteAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getMoveUpAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getMoveDownAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + action = getRestoreAction(selection); + if (action != null) menu.appendToGroup(action.getContextMenuGroup(), action); + } else if ((firstSelection instanceof SystemXMLElementWrapper) && ((SystemXMLElementWrapper) firstSelection).isDomain()) { + // Partition into groups... + createStandardGroups(menu); + ISystemAction action = getPasteAction(selection); + menu.appendToGroup(action.getContextMenuGroup(), action); + } + } + } + + /** + * Creates the Systems plugin standard groups in a context menu. + */ + public void createStandardGroups(IMenuManager menu) { + if (!menu.isEmpty()) return; + menu.add(new Separator(ISystemContextMenuConstants.GROUP_REORGANIZE)); // rename,move,copy,delete,bookmark,refactoring + menu.add(new Separator(ISystemContextMenuConstants.GROUP_REORDER)); // move up, move down + menu.add(new Separator(ISystemContextMenuConstants.GROUP_CHANGE)); // restore + menu.add(new Separator(ISystemContextMenuConstants.GROUP_ADDITIONS)); // user or BP/ISV additions + } + + /** + * Get the delete action + */ + private SystemUDTreeActionDelete getDeleteAction(ISelection selection) { + if (deleteAction == null) deleteAction = new SystemUDTreeActionDelete(this); + deleteAction.setInputs(getShell(), this, selection); + return deleteAction; + } + + /** + * Get the move up action + */ + private SystemUDTreeActionMoveUp getMoveUpAction(ISelection selection) { + if (moveUpAction == null) moveUpAction = new SystemUDTreeActionMoveUp(this); + moveUpAction.setInputs(getShell(), this, selection); + return moveUpAction; + } + + /** + * Get the move down action + */ + private SystemUDTreeActionMoveDown getMoveDownAction(ISelection selection) { + if (moveDownAction == null) moveDownAction = new SystemUDTreeActionMoveDown(this); + moveDownAction.setInputs(getShell(), this, selection); + return moveDownAction; + } + + /** + * Get the copy action + */ + private SystemUDTreeActionCopy getCopyAction(ISelection selection) { + if (copyAction == null) copyAction = new SystemUDTreeActionCopy(this); + copyAction.setInputs(getShell(), this, selection); + return copyAction; + } + + /** + * Get the paste action + */ + private SystemUDTreeActionPaste getPasteAction(ISelection selection) { + if (pasteAction == null) pasteAction = new SystemUDTreeActionPaste(this); + pasteAction.setInputs(getShell(), this, selection); + return pasteAction; + } + + /** + * Get the restore defaults action + */ + protected SystemUDARestoreDefaultsActions getRestoreAction(ISelection selection) { + if (restoreAction == null) restoreAction = new SystemUDARestoreDefaultsActions(this); + restoreAction.setShell(getShell()); + if (selection != null) restoreAction.setSelection(selection); + return restoreAction; + } + + /** + * Convenience method for returning the shell of this viewer. + */ + public Shell getShell() { + return getTree().getShell(); + } + + /** + * Clear the clipboard + */ + public void clearClipboard() { + if (clipboard != null) { + clipboard.dispose(); + clipboard = null; + } + } + + // ---------------------------------- + // METHODS USED BY POPUP MENU ACTIONS + // ---------------------------------- + /** + * Decide if we can do the delete or not. + * Decision deferred to work-with dialog hosting this tree + */ + public boolean canDelete() { + return wwDialog.canDelete(((IStructuredSelection) getSelection()).getFirstElement()); + } + + /** + * Return true if the currently selected item can be moved up or not. + * Called by the SystemUDTreeActionMoveUp action class. + */ + public boolean canMoveUp() { + return wwDialog.canMoveUp(((IStructuredSelection) getSelection()).getFirstElement()); + } + + /** + * Return true if the currently selected item can be moved down or not. + * Called by the SystemUDTreeActionMoveDown action class. + */ + public boolean canMoveDown() { + return wwDialog.canMoveDown(((IStructuredSelection) getSelection()).getFirstElement()); + } + + /** + * Return true if the currently selected item can be copied to the clipboard or not. + * Called by the SystemChangeFilterActionCopyString action class. + */ + public boolean canCopy() { + return wwDialog.canCopy(((IStructuredSelection) getSelection()).getFirstElement()); + } + + /** + * Return true if the current contents of the clipboard apply to us or not. + * Called by the SystemUDTreeActionPaste action class. + */ + public boolean canPaste() { + if (clipboard == null) return false; + IStructuredSelection selection = (IStructuredSelection) getSelection(); + if (!(selection.getFirstElement() instanceof SystemXMLElementWrapper)) return false; + SystemXMLElementWrapper firstSelect = (SystemXMLElementWrapper) selection.getFirstElement(); + TextTransfer textTransfer = TextTransfer.getInstance(); + String textData = (String) clipboard.getContents(textTransfer); + return docManager.enablePaste(firstSelect, textData); + } + + /** + * Actually do the delete of currently selected item. + * Return true if it worked. Return false if it didn't (eg, user cancelled confirm) + * Called by the SystemUDTreeActionDelete action class. + */ + public boolean doDelete() { + IStructuredSelection selection = (IStructuredSelection) getSelection(); + boolean deleted = false; + SystemMessage confirmDlt = getDeleteConfirmationMessage(); + SystemMessageDialog msgDlg = new SystemMessageDialog(getShell(), confirmDlt); + try { + deleted = msgDlg.openQuestion(); + if (deleted) { + docManager.delete(docManager.getCurrentProfile(), (SystemXMLElementWrapper) selection.getFirstElement()); + docManager.saveUserData(docManager.getCurrentProfile()); + deleted = true; + } + } catch (Exception exc) { + SystemBasePlugin.logError("Error deleting user actions", exc); //$NON-NLS-1$ + } + if (deleted) { + remove(selection.getFirstElement()); + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REMOVED, getResourceType(), selection.getFirstElement(), null); + } + return deleted; + } + + /** + * Return the {@link org.eclipse.rse.core.model.ISystemModelChangeEvents} constant representing the resource type managed by this tree. + * This must be overridden. + */ + protected int getResourceType() { + return -1; + } + + /** + * Return message for delete confirmation + */ + protected SystemMessage getDeleteConfirmationMessage() { + return RSEUIPlugin.getPluginMessage(MSG_CONFIRM_DELETE_USERACTION); + } + + /** + * Actually do the move up of currently selected item. + * Return true if all went well. + * Called by the SystemUDTreeActionMoveUp action class. + */ + public boolean doMoveUp() { + IStructuredSelection selection = (IStructuredSelection) getSelection(); + SystemXMLElementWrapper firstSelect = (SystemXMLElementWrapper) selection.getFirstElement(); + SystemXMLElementWrapper previousElement = (SystemXMLElementWrapper) getSelectedPreviousTreeItem().getData(); + boolean moved = docManager.moveElementUp(firstSelect, previousElement); + if (moved) { + refreshElementParent(firstSelect); + selectElement(firstSelect); + docManager.saveUserData(docManager.getCurrentProfile()); + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REORDERED, getResourceType(), firstSelect, null); + } + return true; + } + + /** + * Actually do the move down of currently selected item. + * Return true if all went well. + * Called by the SystemUDTreeActionMoveDown action class. + */ + public boolean doMoveDown() { + IStructuredSelection selection = (IStructuredSelection) getSelection(); + SystemXMLElementWrapper firstSelect = (SystemXMLElementWrapper) selection.getFirstElement(); + TreeItem nextNextItem = getSelectedNextNextTreeItem(); + SystemXMLElementWrapper nextElement = null; + if (nextNextItem != null) nextElement = (SystemXMLElementWrapper) nextNextItem.getData(); + boolean moved = docManager.moveElementDown(firstSelect, nextElement); + if (moved) { + refreshElementParent(firstSelect); + selectElement(firstSelect); + docManager.saveUserData(docManager.getCurrentProfile()); + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_REORDERED, getResourceType(), firstSelect, null); + } + return true; + } + + /** + * Actually do the copy of currently selected item to the clipboard. + * Return true if all went well. + * Called by the SystemChangeFilterActionCopyString action class. + */ + public boolean doCopy() { + IStructuredSelection selection = (IStructuredSelection) getSelection(); + SystemXMLElementWrapper firstSelect = (SystemXMLElementWrapper) selection.getFirstElement(); + if (clipboard == null) clipboard = new Clipboard(getShell().getDisplay()); + String id = docManager.prepareClipboardCopy(firstSelect); + if (id == null) return false; + TextTransfer transfer = TextTransfer.getInstance(); + clipboard.setContents(new Object[] { id }, new Transfer[] { transfer }); + return true; + } + + /** + * Actually do the paste of clipboard contents relative to currently selected object. + * Return true if all went well. + * Called by the SystemUDTreeActionPaste action class. + */ + public boolean doPaste() { + if (clipboard == null) return false; + IStructuredSelection selection = (IStructuredSelection) getSelection(); + SystemXMLElementWrapper firstSelect = (SystemXMLElementWrapper) selection.getFirstElement(); + TextTransfer textTransfer = TextTransfer.getInstance(); + String textData = (String) clipboard.getContents(textTransfer); + SystemXMLElementWrapper pastedElementWrapper = docManager.pasteClipboardCopy(firstSelect, textData); + if (pastedElementWrapper != null) { + if (firstSelect.isDomain()) { + refresh(firstSelect); + setExpandedState(firstSelect, true); // force expansion, just in case + } else + refreshElementParent(firstSelect); + selectElement(pastedElementWrapper); + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_ADDED, getResourceType(), pastedElementWrapper, null); + } + clipboard.dispose(); + clipboard = null; + return (pastedElementWrapper != null); + } + + /** + * Return true if we are to enable the Restore Defaults actions + */ + public boolean canRestore() { + if (wwDialog.areChangesPending()) return false; + SystemXMLElementWrapper selectedElement = getSelectedElement(); + if ((selectedElement == null) || !((selectedElement instanceof SystemUDActionElement) || (selectedElement instanceof SystemUDTypeElement))) return false; + return selectedElement.isIBM() && selectedElement.isUserChanged(); + } + + /** + * Restore the selected action/type to its IBM-supplied default value. + * Needs to be overridden by children that want to support it. + */ + public void doRestore() { + } + + // -------------- + // Miscellaneous + // -------------- + /** + * Return the action or type manager + */ + public SystemUDBaseManager getDocumentManager() { + return docManager; + } + + // For Interface IDoubleClickListener + // For double-click on "New..." items in tree + public void doubleClick(DoubleClickEvent event) { + } + + /** + * Get the selected action or type name. + * Returns "" if nothing selected + */ + public String getSelectedElementName() { + String seldName = ""; //$NON-NLS-1$ + IStructuredSelection sel = (IStructuredSelection) getSelection(); + if ((sel != null) && (sel.getFirstElement() != null)) { + Object selObj = sel.getFirstElement(); + if (selObj instanceof SystemXMLElementWrapper) seldName = ((SystemXMLElementWrapper) selObj).toString(); + } + return seldName; + } + + /** + * Return true if currently selected element is "ALL" + */ + public boolean isElementAllSelected() { + return getSelectedElementName().equals("ALL"); //$NON-NLS-1$ + } + + /** + * Return true if currently selected element is vendor supplied + */ + public boolean isSelectionVendorSupplied() { + SystemXMLElementWrapper selectedElement = getSelectedElement(); + if (selectedElement != null) { + String vendor = selectedElement.getVendor(); + //System.out.println("Vendor value: '"+vendor+"'"); + return ((vendor != null) && (vendor.length() > 0)); + } + return false; + } + + /** + * Return the vendor that is responsible for pre-supplying this existing type, + * or null if not applicable. + */ + public String getVendorOfSelection() { + SystemXMLElementWrapper selectedElement = getSelectedElement(); + if (selectedElement != null) { + String vendor = selectedElement.getVendor(); + if ((vendor != null) && (vendor.length() > 0)) return vendor; + } + return null; + } + + /** + * Get the selected action or type domain. + * Returns -1 if nothing selected or domains not supported + */ + public int getSelectedElementDomain() { + int seldDomain = -1; + IStructuredSelection sel = (IStructuredSelection) getSelection(); + if ((sel != null) && (sel.getFirstElement() != null)) { + Object selObj = sel.getFirstElement(); + if (selObj instanceof SystemXMLElementWrapper) seldDomain = ((SystemXMLElementWrapper) selObj).getDomain(); + } + return seldDomain; + } + + // ------------------------------------ + // HELPER METHODS CALLED FROM EDIT PANE + // ------------------------------------ + /** + * Return the selected non-domain element, or null if an existing element + * is not currently selected + */ + public SystemXMLElementWrapper getSelectedElement() { + IStructuredSelection sel = (IStructuredSelection) getSelection(); + if ((sel != null) && (sel.getFirstElement() != null)) { + Object selObj = sel.getFirstElement(); + if (selObj instanceof SystemXMLElementWrapper) { + SystemXMLElementWrapper selEle = (SystemXMLElementWrapper) selObj; + if (!selEle.isDomain()) return selEle; + } + } + return null; + } + + /** + * Select the given type + */ + public void selectElement(SystemXMLElementWrapper element) { + //System.out.println("Inside selectElement of tree for action: " + element); + // here is our problem: + // We are given an element object that wrappers an xml node object. + // These wrappers are re-created on the fly, whenever the tree is refreshed. + // So, we might not find a binary match on the wrapper. + // Hence, we need to see if there is such a match, and if not, then + // we have to walk the tree comparing the xml node objects. + // The assumption is that we are always given something that is in fact + // in the tree. + Widget w = findItem(element); + if (w != null) // we found it! + super.setSelection(new StructuredSelection(element), true); // select it + else { + //start walking! + TreeItem matchingItem = findElement(element.getElement()); + if (matchingItem != null) + super.setSelection(new StructuredSelection(matchingItem.getData()), true); // select it + else + super.setSelection((ISelection) null); // deselect what is currently selected + } + } + + /** + * Find the parent tree item of the given type. + * If it is not currently shown in the tree, or there is no parent, returns null. + */ + public TreeItem findParentItem(SystemXMLElementWrapper element) { + Element parentElement = element.getParentDomainElement(); + TreeItem parentItem = null; + if (parentElement != null) + parentItem = findElement(parentElement); + else { + //System.out.println("asked to find parent item, yet there is no parent element"); + } + return parentItem; + } + + /** + * Refresh the parent of the given action. + * That is, find the parent and refresh the children. + * If the parent is not found, assume it is because it is new too, + * so refresh the whole tree. + */ + public void refreshElementParent(SystemXMLElementWrapper element) { + TreeItem parentItem = findParentItem(element); + if (parentItem == null) // parent not found? + { + //System.out.println("parentItem null. Refreshing tree"); + refresh(); // refresh whole tree + // now, try again to find parent to ensure it is expanded... + parentItem = findParentItem(element); + } else { + //System.out.println("parentItem not null. Refreshing it"); + refresh(parentItem.getData()); // refresh this element + } + if (parentItem != null) // should not happen + { + //System.out.println("parentItem not null. Expanded? " + parentItem.getExpanded()); + if (!parentItem.getExpanded()) // not expanded yet? + { + //System.out.println(" expanding parent... " + parentItem.getExpanded()); + setExpandedState(parentItem.getData(), true); // expand it now + } + } + } + + /** + * Given an xml node, find the wrapper for the element in the tree, + * scanning entire tree. + */ + private TreeItem findElement(Node searchNode) { + TreeItem match = null; + TreeItem[] roots = getTree().getItems(); + for (int idx = 0; (match == null) && (idx < roots.length); idx++) + match = findElement(roots[idx], searchNode); + return match; + } + + /** + * Given an xml node and parent tree item, find the wrapper for the element in the tree + * under the given parent. + */ + private TreeItem findElement(TreeItem parentItem, Node searchNode) { + TreeItem match = null; + // first, check for match on the given parent itself... + Object itemData = parentItem.getData(); + Element itemNode = null; + if ((itemData != null) && (itemData instanceof SystemXMLElementWrapper)) { + itemNode = ((SystemXMLElementWrapper) itemData).getElement(); + if (itemNode == searchNode) return parentItem; + } + // no match on parent, check kids... + TreeItem[] kids = parentItem.getItems(); + if (kids != null) for (int idx = 0; (match == null) && (idx < kids.length); idx++) + match = findElement(kids[idx], searchNode); + return match; + } + + /** + * Returns the tree item of the first selected object. + */ + public TreeItem getSelectedTreeItem() { + TreeItem[] selectedItems = getTree().getSelection(); + if ((selectedItems != null) && (selectedItems.length > 0)) + return selectedItems[0]; + else + return null; + } + + /** + * Returns the tree item of the sibling before the first selected object. + */ + public TreeItem getSelectedPreviousTreeItem() { + TreeItem selectedItem = getSelectedTreeItem(); + if (selectedItem == null) return null; + TreeItem[] siblings = null; + if (selectedItem.getParentItem() != null) + siblings = selectedItem.getParentItem().getItems(); + else + siblings = selectedItem.getParent().getItems(); + for (int idx = 0; idx < siblings.length; idx++) { + if (siblings[idx] == selectedItem) { + if (idx == 0) + return null; + else + return siblings[idx - 1]; + } + } + return null; + } + + /** + * Returns the tree item of the sibling after the first selected object. + */ + public TreeItem getSelectedNextTreeItem() { + TreeItem selectedItem = getSelectedTreeItem(); + if (selectedItem == null) return null; + TreeItem[] siblings = null; + if (selectedItem.getParentItem() != null) + siblings = selectedItem.getParentItem().getItems(); + else + siblings = selectedItem.getParent().getItems(); + for (int idx = 0; idx < siblings.length; idx++) { + if (siblings[idx] == selectedItem) { + if (idx >= (siblings.length - 1)) + return null; + else + return siblings[idx + 1]; + } + } + return null; + } + + /** + * Returns the tree item of the sibling two after the first selected object. + */ + public TreeItem getSelectedNextNextTreeItem() { + TreeItem selectedItem = getSelectedTreeItem(); + if (selectedItem == null) return null; + TreeItem[] siblings = null; + if (selectedItem.getParentItem() != null) + siblings = selectedItem.getParentItem().getItems(); + else + siblings = selectedItem.getParent().getItems(); + for (int idx = 0; idx < siblings.length; idx++) { + if (siblings[idx] == selectedItem) { + if (idx >= (siblings.length - 2)) + return null; + else + return siblings[idx + 2]; + } + } + return null; + } + + /** + * Move one tree item to a new location + */ + protected void moveTreeItem(Widget parentItem, Item item, Object src, int newPosition) { + if (getExpanded(item)) { + setExpanded(item, false); + refresh(src); // flush items from memory + } + createTreeItem(parentItem, src, newPosition); + //createTreeItem(parentItem, (new String("New")), newPosition); + //remove(src); + disassociate(item); + item.dispose(); + } + + /** + * Get the position of a tree item within its parent + */ + protected int getTreeItemPosition(Widget parentItem, Item childItem) { + int pos = -1; + Item[] children = null; + if (parentItem instanceof Item) + children = getItems((Item) parentItem); + else + children = getChildren(parentItem); + for (int idx = 0; (pos == -1) && (idx < children.length); idx++) { + if (children[idx] == childItem) pos = idx; + } + return pos; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeViewLabelProvider.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeViewLabelProvider.java new file mode 100644 index 00000000000..6223e35585d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDBaseTreeViewLabelProvider.java @@ -0,0 +1,54 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +//import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +/** + * Label provider for our user actions and named types tree views + */ +public class SystemUDBaseTreeViewLabelProvider extends LabelProvider { + private SystemUDBaseManager docManager; + + /** + * Constructor + */ + public SystemUDBaseTreeViewLabelProvider(SystemUDBaseManager docManager) { + super(); + this.docManager = docManager; + } + + /** + * Override of parent so we can supply an image, if we desire. + */ + public Image getImage(Object element) { + if (element instanceof SystemUDTreeViewNewItem) { + if (!((SystemUDTreeViewNewItem) element).isExecutable()) { + //System.out.println("Calling docManager.getNewImage..."); + return docManager.getNewImage(); + } else { + //System.out.println("Calling actionss.getDomainNewImage..."); + if (!docManager.isUserActionsManager()) + return docManager.getActionSubSystem().getDomainNewTypeImage(((SystemUDTreeViewNewItem) element).getDomain()); + else + return docManager.getActionSubSystem().getDomainNewImage(((SystemUDTreeViewNewItem) element).getDomain()); + } + } else if (element instanceof SystemXMLElementWrapper) { + if (((SystemXMLElementWrapper) element).isDomain()) + return docManager.getActionSubSystem().getDomainImage(((SystemXMLElementWrapper) element).getDomain()); + else + return ((SystemXMLElementWrapper) element).getImage(); + } + return null; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSelectTypesForm.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSelectTypesForm.java new file mode 100644 index 00000000000..3774cf51d4a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSelectTypesForm.java @@ -0,0 +1,478 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.useractions.ui.uda.actions.SystemWorkWithFileTypesAction; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +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.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; + +/** + * This is a subclassable and configurable encapsulation of a + * composite that allows users to select file types from a master + * list, as well as edit that master list. + *

+ * It is used in the edit pane of the Work With User Actions + * dialog, to allow the user to indicate which file types this + * action is scoped to. + */ +public class SystemUDSelectTypesForm implements SelectionListener { + // inputs + protected Shell shell; + protected ISubSystem subsystem = null; + protected ISubSystemConfiguration subsystemFactory = null; + protected ISystemProfile profile; + protected SystemUDTypeManager udtm; + protected int domain; + protected String groupLabel, groupTooltip; + protected String masterListLabel, masterListTooltip; + protected String ourListLabel, ourListTooltip; + protected String ALL_TYPE = "ALL"; //$NON-NLS-1$ + protected String[] inpMasterTypes = { ALL_TYPE }; + protected String[] inpSelectedTypes = { ALL_TYPE }; + protected Vector listeners = new Vector(); + // widgets + protected Composite composite_prompts; + protected List masterList; + protected List ourList; + protected Button addButton, rmvButton, editButton; + protected Label verbageLabel; + protected Label msgLine; + // static + protected String[] ALL_TYPE_ARRAY = { ALL_TYPE }; + + /** + * Constructor for SystemUDSelectTypesForm, when we have a subsystem. + */ + public SystemUDSelectTypesForm(Shell shell, ISubSystem subsystem, SystemUDTypeManager mgr) { + super(); + this.shell = shell; + this.subsystem = subsystem; + this.subsystemFactory = subsystem.getSubSystemConfiguration(); + this.profile = subsystem.getSystemProfile(); + this.udtm = mgr; + setGroupLabel(SystemUDAResources.RESID_UDA_TYPE_LIST_LABEL, SystemUDAResources.RESID_UDA_TYPE_LIST_TOOLTIP); + setMasterListLabel(SystemUDAResources.RESID_UDA_TYPE_LIST_MASTER_LABEL, SystemUDAResources.RESID_UDA_TYPE_LIST_MASTER_TOOLTIP); + setSelectedListLabel(SystemUDAResources.RESID_UDA_TYPE_LIST_SELECTED_LABEL, SystemUDAResources.RESID_UDA_TYPE_LIST_SELECTED_TOOLTIP); + } + + /** + * Constructor for SystemUDSelectTypesForm, when we have a subsystem factory and profile + */ + public SystemUDSelectTypesForm(Shell shell, ISubSystemConfiguration subsystemFactory, ISystemProfile profile, SystemUDTypeManager mgr) { + super(); + this.shell = shell; + this.subsystemFactory = subsystemFactory; + this.profile = profile; + this.udtm = mgr; + setGroupLabel(SystemUDAResources.RESID_UDA_TYPE_LIST_LABEL, SystemUDAResources.RESID_UDA_TYPE_LIST_TOOLTIP); + setMasterListLabel(SystemUDAResources.RESID_UDA_TYPE_LIST_MASTER_LABEL, SystemUDAResources.RESID_UDA_TYPE_LIST_MASTER_TOOLTIP); + setSelectedListLabel(SystemUDAResources.RESID_UDA_TYPE_LIST_SELECTED_LABEL, SystemUDAResources.RESID_UDA_TYPE_LIST_SELECTED_TOOLTIP); + } + + // ------------------------ + // CONFIGURATION METHODS... + // ------------------------ + /** + * Set what type string represents "all". + * The default is "ALL" + */ + public void setAllType(String allType) { + this.ALL_TYPE = allType; + ALL_TYPE_ARRAY = new String[] { allType }; + } + + /** + * Configuration method. + *

+ * Set the verbage and tooltip for the overall group + *

+ */ + public void setGroupLabel(String label, String tooltip) { + this.groupLabel = label; + this.groupTooltip = tooltip; + } + + /** + * Configuration method. + * Set the label and tooltip for the master list of all defined types + */ + public void setMasterListLabel(String label, String tooltip) { + this.masterListLabel = label; + this.masterListTooltip = tooltip; + } + + /** + * Configuration method. + * Set the label and tooltip for the user-select list of types for this action, + */ + public void setSelectedListLabel(String label, String tooltip) { + this.ourListLabel = label; + this.ourListTooltip = tooltip; + } + + /** + * Set the whole form to be visible or not + */ + public void setVisible(boolean visible) { + if (composite_prompts != null) { + verbageLabel.setVisible(visible); + composite_prompts.setVisible(visible); + } + } + + /** + * Set the domain of the action we are creating or editing. + */ + public void setDomain(int domain) { + this.domain = domain; + } + + // --------------------------------- + // LISTENER CONFIGURATION METHODS... + // --------------------------------- + public void addSelectionListener(ISystemUDSelectTypeListener l) { + listeners.add(l); + } + + // ----------------------------- + // DATA CONFIGURATION METHODS... + // ----------------------------- + /** + * Set the initial master list of all defined types + */ + public void setMasterTypes(String[] types) { + this.inpMasterTypes = types; + if (masterList != null) { + masterList.removeAll(); + if (types != null) { + masterList.setItems(types); + if (types.length > 0) { + masterList.select(0); + addButton.setEnabled(true); + } + } + setMessage(masterList); + } + } + + /** + * Set the initial list of all types selected for this action. + * For "new" actions, you don't have to call this to insert ALL, + * as that is done for you + */ + public void setTypes(String[] types) { + this.inpSelectedTypes = types; + if (ourList != null) { + ourList.removeAll(); + if (types != null) { + ourList.setItems(types); + if (types.length > 0) { + ourList.select(0); + } + } + enableDisableRmvButton(); + setMessage(ourList); + } + } + + /** + * Reset the master types list to just "ALL" + */ + public void resetMasterTypes() { + setMasterTypes(ALL_TYPE_ARRAY); + } + + /** + * Reset the user-selected types to just "ALL" + */ + public void resetTypes() { + setTypes(ALL_TYPE_ARRAY); + } + + /** + * Reset state (like when now working on a new action) + */ + public void reset() { + resetMasterTypes(); + resetTypes(); + /* + masterList.removeAll(); + inpMasterTypes = ALL_TYPE_ARRAY; + masterList.setItems(inpMasterTypes); + + inpSelectedTypes = ALL_TYPE_ARRAY; + ourList.removeAll(); + ourList.setItems(inpSelectedTypes); + */ + } + + // -------------------------- + // DATA EXTRACTION METHODS... + // -------------------------- + /** + * Return the master list of defined types. + * This may have changed by way of the user pressing Edit + */ + public String[] getMasterTypes() { + return masterList.getItems(); + } + + /** + * Return the list of user-selected types, as an array of strings. + * Never an empty list! Enforced to select at least one type, which is defaulted to + */ + public String[] getTypes() { + return ourList.getItems(); + } + + // ------------------------ + // INTERNAL METHODS... + // ------------------------ + /** + * Create the widgets and populate the composite. + * @param parent - the parent composite these widgets will be added to (actually we create our own composite to hold the widgets) + * @param span - the number of columns within the parent composite that our widgets are to span + */ + public Composite createContents(Composite parent, int span) { + verbageLabel = SystemWidgetHelpers.createVerbiage(parent, groupLabel, span, false, -1); + //addFillerLine(parent, span); + int nbrColumns = 3; + //composite_prompts = SystemWidgetHelpers.createGroupComposite(parent, nbrColumns, groupLabel); + composite_prompts = SystemWidgetHelpers.createFlushComposite(parent, nbrColumns); + composite_prompts.setToolTipText(groupTooltip); + ((GridData) composite_prompts.getLayoutData()).horizontalSpan = span; + ((GridLayout) composite_prompts.getLayout()).marginHeight = 0; + ((GridLayout) composite_prompts.getLayout()).marginWidth = 2; + masterList = createListBox(composite_prompts, masterListLabel, masterListTooltip); + Composite middle_composite = SystemWidgetHelpers.createComposite(composite_prompts, 1); + ((GridLayout) middle_composite.getLayout()).marginWidth = 0; + SystemWidgetHelpers.createLabel(middle_composite, ""); //$NON-NLS-1$ + Composite button_composite = SystemWidgetHelpers.createTightComposite(middle_composite, 1); + addButton = SystemWidgetHelpers.createPushButton(button_composite, null, SystemUDAResources.RESID_UDA_TYPE_ADD_BUTTON_LABEL, SystemUDAResources.RESID_UDA_TYPE_ADD_BUTTON_TOOLTIP); + rmvButton = SystemWidgetHelpers.createPushButton(button_composite, null, SystemUDAResources.RESID_UDA_TYPE_RMV_BUTTON_LABEL, SystemUDAResources.RESID_UDA_TYPE_RMV_BUTTON_TOOLTIP); + editButton = SystemWidgetHelpers.createPushButton(button_composite, null, SystemUDAResources.RESID_UDA_TYPE_EDIT_BUTTON_LABEL, SystemUDAResources.RESID_UDA_TYPE_EDIT_BUTTON_TOOLTIP); + Label bottomFiller = SystemWidgetHelpers.createLabel(button_composite, ""); //$NON-NLS-1$ + ((GridData) bottomFiller.getLayoutData()).grabExcessVerticalSpace = true; + ((GridData) bottomFiller.getLayoutData()).verticalAlignment = GridData.FILL; + ourList = createListBox(composite_prompts, ourListLabel, ourListTooltip); + msgLine = SystemWidgetHelpers.createLabel(composite_prompts, "");//, 1, true); //$NON-NLS-1$ + ((GridData) msgLine.getLayoutData()).horizontalSpan = nbrColumns; + ((GridData) msgLine.getLayoutData()).widthHint = 150; + // add our own listeners to our own widgets + masterList.addSelectionListener(this); + ourList.addSelectionListener(this); + addButton.addSelectionListener(this); + rmvButton.addSelectionListener(this); + editButton.addSelectionListener(this); + boolean enableAdd = false; + boolean enableRmv = false; + // prefill data + if (inpMasterTypes != null) { + masterList.setItems(inpMasterTypes); + if (inpMasterTypes.length > 0) { + masterList.select(0); + enableAdd = true; + } + } + if (inpSelectedTypes != null) { + ourList.setItems(inpSelectedTypes); + if (inpSelectedTypes.length > 0) { + ourList.select(0); + enableRmv = !inpSelectedTypes[0].equals(ALL_TYPE); + } + } + setMessage(ourList); + // initially disable buttons + addButton.setEnabled(enableAdd); + rmvButton.setEnabled(enableRmv); + return composite_prompts; + } + + /** + * create list box + */ + private List createListBox(Composite c, String label, String tooltip) { + List listbox = SystemWidgetHelpers.createListBox(c, null, false, label, tooltip); + ((GridData) listbox.getLayoutData()).widthHint = 50; + ((GridData) listbox.getLayoutData()).heightHint = 78; // 120 + return listbox; + } + + /** + * enable/disable rmv button + */ + private void enableDisableRmvButton() { + int selIdx = ourList.getSelectionIndex(); + rmvButton.setEnabled((selIdx >= 0) && !((ourList.getItemCount() == 1) && (ourList.getItem(0).equals(ALL_TYPE)))); + } + + /** + * SelectionListener interface. + * Called when button selected + */ + public void widgetSelected(SelectionEvent event) { + Object src = event.getSource(); + boolean fireEvent = false; + if (src == masterList) { + int selIdx = masterList.getSelectionIndex(); + addButton.setEnabled(selIdx >= 0); + enableDisableRmvButton(); + setMessage(masterList); + } else if (src == ourList) { + enableDisableRmvButton(); + setMessage(ourList); + } else if (src == rmvButton) { + int selIdx = ourList.getSelectionIndex(); + if (selIdx < 0) return; + ourList.remove(selIdx); + if (ourList.getItemCount() == 0) ourList.add(ALL_TYPE); + enableDisableRmvButton(); + fireEvent = true; + } else // add or edit + { + String[] selected = masterList.getSelection(); + String selection = null; + if ((selected != null) && (selected.length > 0)) { + selection = selected[0]; + } + int selIdx = -1; + if (src == addButton) { + if (selected == null || selection == null) // should never happen if our enablement is correct + { + addButton.setEnabled(false); + return; + } + // is the selected type already in the selected-list? + selIdx = ourList.indexOf(selection); + if (selIdx < 0) // no, not already in list + { + if (selection.equals(ALL_TYPE)) // adding ALL? + ourList.removeAll(); + else { + try { + ourList.remove(ALL_TYPE); + } catch (Exception exc) { + } + } + ourList.add(selection); + enableDisableRmvButton(); + fireEvent = true; + } + } else if (src == editButton) { + SystemWorkWithFileTypesAction editTypesAction = null; + if (subsystem != null) + editTypesAction = new SystemWorkWithFileTypesAction(shell, subsystem); + else + editTypesAction = new SystemWorkWithFileTypesAction(shell, subsystemFactory, profile); + if (selection != null) { + editTypesAction.preSelectType(domain, selection); + } + editTypesAction.run(); + String outputSelectedTypeName = editTypesAction.getSelectedTypeName(); + int outputSelectedTypeDomain = editTypesAction.getSelectedTypeDomain(); + //System.out.println("outputSelectedTypeName = " + outputSelectedTypeName); + // the following will result in a callback to us to refresh the master list + fireSelectedListChange(false, true); + // now, select something in master list + if ((outputSelectedTypeName != null) && (outputSelectedTypeDomain == domain)) { + masterList.setSelection(new String[] { outputSelectedTypeName }); + masterList.showSelection(); + } else if (selection != null) masterList.setSelection(new String[] { selection }); + } + } + if (fireEvent) fireSelectedListChange(true, false); + } + + /** + * SelectionListener interface. + * Called when enter pressed on widget we are listening to + */ + public void widgetDefaultSelected(SelectionEvent event) { + } + + /** + * Set the text in the message line below the lists + */ + private void setMessage(List listbox) { + int selIdx = listbox.getSelectionIndex(); + if (selIdx < 0) + msgLine.setText(""); //$NON-NLS-1$ + else { + String type = listbox.getItem(selIdx); + String types = udtm.getTypesForTypeName(type, domain); + if (types == null) { + msgLine.setText(""); //$NON-NLS-1$ + msgLine.setToolTipText(""); //$NON-NLS-1$ + } else { + String msg = null; + if (types.length() > 35) + msg = type + ": " + types.substring(0, 34) + "..."; //$NON-NLS-1$ //$NON-NLS-2$ + else + msg = type + ": " + types; //$NON-NLS-1$ + //System.out.println(msg); + msgLine.setText(msg); + msgLine.setToolTipText(types); + } + } + } + + /** + * The user has changed the selected-types list. + * Inform all listeners + */ + private void fireSelectedListChange(boolean selectedListChanged, boolean masterListChanged) { + for (int idx = 0; idx < listeners.size(); idx++) { + if (selectedListChanged) ((ISystemUDSelectTypeListener) listeners.elementAt(idx)).selectedTypeListChanged(this); + if (masterListChanged) ((ISystemUDSelectTypeListener) listeners.elementAt(idx)).masterTypeListChanged(this); + } + } + + // ----------------------------- + // Helper methods... + // ----------------------------- + /** + * Add a separator line. This is a physically visible line. + */ + protected Label addSeparatorLine(Composite parent, int nbrColumns) { + Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + separator.setLayoutData(data); + return separator; + } + + /** + * Add a spacer line + */ + protected Label addFillerLine(Composite parent, int nbrColumns) { + Label filler = new Label(parent, SWT.LEFT); + GridData data = new GridData(); + data.horizontalSpan = nbrColumns; + data.horizontalAlignment = GridData.FILL; + filler.setLayoutData(data); + return filler; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSimpleTypesListEditor.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSimpleTypesListEditor.java new file mode 100644 index 00000000000..1ab1ef84a01 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDSimpleTypesListEditor.java @@ -0,0 +1,192 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.messages.ISystemMessageLine; +import org.eclipse.rse.ui.validators.ISystemValidator; +import org.eclipse.rse.ui.validators.ValidatorUserTypeTypes; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +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; + +/** + * Default implementation of ISystemUDTypeEditPaneTypesSelector, which is + * simply a labeled text field. + * These editors are used in the Named Types dialog, to prompt for the list of + * constituent types. + */ +public class SystemUDSimpleTypesListEditor implements ISystemUDTypeEditPaneTypesSelector { + protected Text textTypes; + protected Label typesLabel, nonEditableVerbage; + private boolean autoUpperCase = false; + private ISystemValidator typesValidator; + private int currentDomain = -1; + protected ISystemMessageLine msgLine; + protected Shell shell; + + /** + * constructor + */ + public SystemUDSimpleTypesListEditor(Composite parent, int nbrColumns) { + shell = parent.getShell(); + createContents(parent, nbrColumns); + setValidator(new ValidatorUserTypeTypes()); + } + + /** + * Set the msg line in case this composite widget needs to issue an error msg + */ + public void setMessageLine(ISystemMessageLine msgLine) { + this.msgLine = msgLine; + } + + /** + * Create and populate widgets + */ + protected void createContents(Composite parent, int nbrColumns) { + textTypes = SystemWidgetHelpers.createLabeledTextField(parent, null, SystemUDAResources.RESID_UDT_TYPES_LABEL, SystemUDAResources.RESID_UDT_TYPES_TOOLTIP); + typesLabel = SystemWidgetHelpers.getLastLabel(); + ((GridData) textTypes.getLayoutData()).horizontalSpan = nbrColumns - 1; + textTypes.setTextLimit(ValidatorUserTypeTypes.MAX_UDTTYPES_LENGTH); + nonEditableVerbage = SystemWidgetHelpers.createVerbiage(parent, "", nbrColumns, false, 200); //$NON-NLS-1$ + nonEditableVerbage.setVisible(false); + } + + /** + * Set domain. + * The edit pane may possibly appear differently, depending on the domain. + * When the domain changes (either in "new" or "edit" mode) this method is called. + */ + public void setDomain(int domain) { + this.currentDomain = domain; + } + + /** + * Get the domain of the currently selected existing new type, or "new" node. + */ + public int getDomain() { + return currentDomain; + } + + /** + * Set the validator to use for the types + */ + public void setValidator(ISystemValidator validator) { + typesValidator = validator; + } + + /** + * Initialize the types. These are stored as a single string using + * a subsystem-decidable delimiter character. + */ + public void setTypes(String types) { + textTypes.setText(types); + } + + /** + * Clear the types. That is, make sure none are selected. This is + * called when entering "new" mode. + */ + public void clearTypes() { + textTypes.setText(""); //$NON-NLS-1$ + } + + /** + * Retrieve the types as a single string. The delimiter used is up to + * the implementor, as long as it knows how to parse and assemble the + * types list as a single string. + */ + public String getTypes() { + if (autoUpperCase) + return textTypes.getText().trim().toUpperCase(); + else + return textTypes.getText().trim(); + } + + /** + * Allow the edit pane (or any consumer) to be informed as + * changes are made to the list. When events are fired, the consumer + * will call getTypes() to get the new list. + */ + public void addModifyListener(ModifyListener listener) { + textTypes.addModifyListener(listener); + } + + /** + * Allow the edit pane (or any consumer) to stop listening as + * changes are made to the list. + */ + public void removeModifyListener(ModifyListener listener) { + textTypes.removeModifyListener(listener); + } + + /** + * Validate input, and return the error message if an error is found. + * This is called by the consumer upon receipt of a modify event, to + * show any error messages and to know if there are errors pending or + * not. + */ + public SystemMessage validate() { + return typesValidator.validate(getTypes()); + } + + /** + * Return primary control for setting focus, among other things + */ + public Control getControl() { + return textTypes; + } + + /** + * Enable or disable the input-capability of the constituent controls + */ + public void setEnabled(boolean enable) { + textTypes.setEnabled(enable); + } + + /** + * We want to disable editing of IBM or vendor-supplied + * types, so when one of these is selected, this method is + * called to enter non-editable mode. + * @param editable Whether to disable editing of this type or not + * @param vendor When disabling, it contains the name of the vendor for substitution purposes + */ + public void setEditable(boolean editable, String vendor) { + textTypes.setEditable(editable); + if (editable) + nonEditableVerbage.setVisible(false); + else { + nonEditableVerbage.setVisible(true); + if (vendor.equals("IBM")) + nonEditableVerbage.setText(SystemUDAResources.RESID_UDT_IBM_VERBAGE); + else { + String verbage = SystemUDAResources.RESID_UDT_VENDOR_VERBAGE; + verbage = SystemMessage.sub(verbage, "%1", vendor); //$NON-NLS-1$ + nonEditableVerbage.setText(verbage); + } + } + } + + /** + * Not from interface. + * Specify if the types are to be auto-uppercased or not. + * Default is false. + */ + public void setAutoUpperCase(boolean autoUpperCase) { + this.autoUpperCase = autoUpperCase; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionCopy.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionCopy.java new file mode 100644 index 00000000000..789fc4782af --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionCopy.java @@ -0,0 +1,52 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * The action allows users to copy the currently selected user action or type to the clipboard + */ +public class SystemUDTreeActionCopy extends SystemBaseAction { + private SystemUDBaseTreeView parentTreeView; + + /** + * Constructor + */ + public SystemUDTreeActionCopy(SystemUDBaseTreeView parentTreeView) { + super(SystemUDAResources.RESID_UDA_ACTION_COPY_LABEL, SystemUDAResources.RESID_UDA_ACTION_COPY_TOOLTIP, PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( + ISharedImages.IMG_TOOL_COPY), null); + allowOnMultipleSelection(false); + this.parentTreeView = parentTreeView; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "udac0000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the last action/type + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentTreeView.canCopy(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentTreeView.doCopy(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionDelete.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionDelete.java new file mode 100644 index 00000000000..61c442076e8 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionDelete.java @@ -0,0 +1,52 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * The action allows users to delete the currently selected user action or type + */ +public class SystemUDTreeActionDelete extends SystemBaseAction { + private SystemUDBaseTreeView parentTreeView; + + /** + * Constructor + */ + public SystemUDTreeActionDelete(SystemUDBaseTreeView parentTreeView) { + super(SystemUDAResources.RESID_UDA_ACTION_DELETE_LABEL, SystemUDAResources.RESID_UDA_ACTION_DELETE_TOOLTIP, PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( + ISharedImages.IMG_TOOL_DELETE), null); + allowOnMultipleSelection(false); + this.parentTreeView = parentTreeView; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "udad0000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the last action/type + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentTreeView.canDelete(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentTreeView.doDelete(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveDown.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveDown.java new file mode 100644 index 00000000000..e13f704ea63 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveDown.java @@ -0,0 +1,51 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; + +/** + * The action allows users to move the currently selected user action or type down in the list + */ +public class SystemUDTreeActionMoveDown extends SystemBaseAction { + private SystemUDBaseTreeView parentTreeView; + + /** + * Constructor + */ + public SystemUDTreeActionMoveDown(SystemUDBaseTreeView parentTreeView) { + super(SystemUDAResources.RESID_UDA_ACTION_MOVEDOWN_LABEL, SystemUDAResources.RESID_UDA_ACTION_MOVEDOWN_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_MOVEDOWN_ID), null); + allowOnMultipleSelection(false); + this.parentTreeView = parentTreeView; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORDER); + setHelp(RSEUIPlugin.HELPPREFIX + "udmd0000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the last action/type + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentTreeView.canMoveDown(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentTreeView.doMoveDown(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveUp.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveUp.java new file mode 100644 index 00000000000..55121bf3d3c --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionMoveUp.java @@ -0,0 +1,51 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; + +/** + * The action allows users to move the currently selected user action or type up in the list + */ +public class SystemUDTreeActionMoveUp extends SystemBaseAction { + private SystemUDBaseTreeView parentTreeView; + + /** + * Constructor + */ + public SystemUDTreeActionMoveUp(SystemUDBaseTreeView parentTreeView) { + super(SystemUDAResources.RESID_UDA_ACTION_MOVEUP_LABEL, SystemUDAResources.RESID_UDA_ACTION_MOVEUP_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_MOVEUP_ID), null); + allowOnMultipleSelection(false); + this.parentTreeView = parentTreeView; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORDER); + setHelp(RSEUIPlugin.HELPPREFIX + "udmu0000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the fist action/type + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentTreeView.canMoveUp(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentTreeView.doMoveUp(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionPaste.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionPaste.java new file mode 100644 index 00000000000..781a76dacd9 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeActionPaste.java @@ -0,0 +1,52 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseAction; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * The action allows users to paste a user action or type from the clipboard + */ +public class SystemUDTreeActionPaste extends SystemBaseAction { + private SystemUDBaseTreeView parentTreeView; + + /** + * Constructor + */ + public SystemUDTreeActionPaste(SystemUDBaseTreeView parentTreeView) { + super(SystemUDAResources.RESID_UDA_ACTION_PASTE_LABEL, SystemUDAResources.RESID_UDA_ACTION_PASTE_TOOLTIP, PlatformUI.getWorkbench().getSharedImages().getImageDescriptor( + ISharedImages.IMG_TOOL_PASTE), null); + allowOnMultipleSelection(false); + this.parentTreeView = parentTreeView; + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "udap0000"); //$NON-NLS-1$ + } + + /** + * We override from parent to do unique checking. + * We intercept to ensure this is isn't the last action/type + */ + public boolean updateSelection(IStructuredSelection selection) { + return parentTreeView.canPaste(); + } + + /** + * This is the method called when the user selects this action. + */ + public void run() { + parentTreeView.doPaste(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeViewNewItem.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeViewNewItem.java new file mode 100644 index 00000000000..3458ecf6b6a --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTreeViewNewItem.java @@ -0,0 +1,118 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +//import com.ibm.etools.systems.core.*; +/** + * This represent a tree-node for "New" items + */ +public class SystemUDTreeViewNewItem { + // state + private String label; + private boolean executable; // cascading or not? + private int domain = -1; + private boolean wwActionsDialog; // true for ww user actions, false for ww user types + // constants + private static SystemUDTreeViewNewItem rootActionInst, rootTypeInst; + private static SystemUDTreeViewNewItem rootActionOnlyInst, rootTypeOnlyInst; + + /** + * Constructor + * @param _executable -> true if this is a leaf node + * @param _label -> label to show the user, in the tre + * @param _domain -> domain this represents + * @param _wwActionsDialog -> true if this is for the ww user actions dialog, false for the ww named types dialog + */ + public SystemUDTreeViewNewItem(boolean _executable, String _label, int _domain, boolean _wwActionsDialog) { + super(); + label = _label; + executable = _executable; + domain = _domain; + wwActionsDialog = _wwActionsDialog; + } + + /** + * Return the label + */ + public String toString() { + return label; + } + + /** + * Is this executable? Ie, should it launch a "New" wizard? + */ + public boolean isExecutable() { + return executable; + } + + /** + * Is this the work with actions dialog (true) or the work with types dialog (false) + */ + public boolean isWorkWithActionsDialog() { + return wwActionsDialog; + } + + /** + * Get the domain this represents + */ + public int getDomain() { + return domain; + } + + /** + * Return singleon instance of new item that does have children. + * This is used for the first element when domains are supported. + * @param wwActionsDialog true if called from dialog + * @param newNodeLabel the translated label for the node. + */ + public static SystemUDTreeViewNewItem getRootNewItem(boolean wwActionsDialog, String newNodeLabel) { + if (wwActionsDialog) { + if (rootActionInst == null) rootActionInst = new SystemUDTreeViewNewItem(false, // this item is not executable + newNodeLabel, 0, wwActionsDialog); + return rootActionInst; + } else { + if (rootTypeInst == null) rootTypeInst = new SystemUDTreeViewNewItem(false, // this item is not executable + newNodeLabel, 0, wwActionsDialog); + return rootTypeInst; + } + } + + /** + * Return singleton instance of root new item that does not have children. + * This is used for the first element when domains are not supported. + * @param wwActionsDialog true if called from dialog + * @param newNodeLabel the translated label for the node. + */ + public static SystemUDTreeViewNewItem getOnlyNewItem(boolean wwActionsDialog, String newNodeLabel) { + if (wwActionsDialog) { + if (rootActionOnlyInst == null) rootActionOnlyInst = new SystemUDTreeViewNewItem(true, // this item is executable + newNodeLabel, -1, wwActionsDialog); + return rootActionOnlyInst; + } else { + if (rootTypeOnlyInst == null) rootTypeOnlyInst = new SystemUDTreeViewNewItem(true, // this item is executable + newNodeLabel, -1, wwActionsDialog); + return rootTypeOnlyInst; + } + } + + /** + * Return non-singleton instance of root new item that does not have children. + * This is used for the first element when domains are supported internally, but externally + * only one is used. + * @param domain - the domain to use + * @param wwActionsDialog - true if called from dialog + * @param newNodeLabel - the translated label for the node + */ + public static SystemUDTreeViewNewItem getOnlyNewItem(int domain, boolean wwActionsDialog, String newNodeLabel) { + return new SystemUDTreeViewNewItem(true, // this item is executable + newNodeLabel, domain, wwActionsDialog); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeEditPane.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeEditPane.java new file mode 100644 index 00000000000..b702ebfd0cc --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeEditPane.java @@ -0,0 +1,527 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.validators.ValidatorUserTypeName; +import org.eclipse.rse.ui.widgets.SystemEditPaneStateMachine; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; + +/** + * This is the eidt pane on the right, when a named type is selected + * on the left (or "New" is selected). It is used to create or edit + * a named type definition, which is nothing more than a name associated + * with one or more file types. + */ +public class SystemUDTypeEditPane implements ISelectionChangedListener { + // gui + private Composite comp; + private Text textName; + private ISystemUDTypeEditPaneTypesSelector typesEditor; + // input + protected ISubSystem subsystem; + protected ISubSystemConfiguration subsystemFactory; + protected ISystemProfile profile; + protected ISystemUDTreeView treeView; + protected ISystemUDAEditPaneHoster parentDialog; + // validators + private ValidatorUserTypeName nameValidator; + // listeners + private NameModifyListener nameML = new NameModifyListener(); + private TypesModifyListener typesML = new TypesModifyListener(); + // current error message + private SystemMessage errorMessage; + // state related to current selection or state + private boolean newMode = false; + private boolean recursiveCall = false; + private int newModeDomain = -1; + private SystemUDTreeViewNewItem newModeNewItem; + private SystemEditPaneStateMachine stateMachine; + private int currentDomain = -1; + private SystemUDTypeElement currentType; + // misc state + private boolean nameChanged = false; + private boolean isEnabled = false; + private boolean ignoreChanges = false; + // constants + private static final Vector EMPTY_VECTOR = new Vector(); + + /** + * Constructor + */ + public SystemUDTypeEditPane(ISubSystem ss, ISubSystemConfiguration ssf, ISystemProfile profile, ISystemUDAEditPaneHoster parent, ISystemUDTreeView tv) { + super(); + subsystem = ss; + subsystemFactory = (ssf == null) ? ss.getSubSystemConfiguration() : ssf; + this.profile = (profile == null) ? ss.getSystemProfile() : profile; + //this.subsystemFactory = ss.getParentSubSystemFactory(); + //this.profile = ss.getSystemProfile(); + treeView = tv; + parentDialog = parent; + } + + /** + * Set domain. + * The edit pane may possibly appear differently, depending on the domain. + * When the domain changes (either in "new" or "edit" mode) this method is called. + */ + public void setDomain(int domain) { + this.currentDomain = domain; + if (typesEditor != null) typesEditor.setDomain(domain); + } + + /** + * Get the current domain. + * This is equivalent to newModeDomain in "new" mode, and currentType.getDomain() in "edit" mode + */ + public int getDomain() { + if (currentDomain == -1) { + if (newMode) + return newModeDomain; + else if (currentType != null) + return currentType.getDomain(); + else + return -1; + } else + return currentDomain; + } + + /** + * Set the state machine. + * Called by the UDA dialog + */ + public void setStateMachine(SystemEditPaneStateMachine sm) { + this.stateMachine = sm; + } + + /** + * Create widgets and populate/return composite + */ + public Control createContents(Composite parent) { + nameValidator = new ValidatorUserTypeName(); + // Inner composite + int nbrColumns = 2; + comp = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // Action name + textName = SystemWidgetHelpers.createLabeledTextField(comp, null, SystemUDAResources.RESID_UDT_NAME_LABEL, SystemUDAResources.RESID_UDT_NAME_TOOLTIP); + // List of selected types as a single string... + typesEditor = createTypesListEditor(comp, nbrColumns); + typesEditor.setMessageLine(parentDialog); + // configuration of widgets... + textName.setTextLimit(ValidatorUserTypeName.MAX_UDTNAME_LENGTH); + return comp; + } + + /** + * Overridable exit point. + * Create the edit widgets that will allow the user to see and + * edit the list of file types that constitute this named type. + *

+ * To better facilitate this, the only requirement is that this + * "editor" meet the minimal interface + * {@link org.eclipse.rse.useractions.ui.uda.ISystemUDTypeEditPaneTypesSelector} + *

+ * The default implementation is simply a labeled entry field! + * + * @param parent - the parent composite where the widgets are to go + * @param nbrColumns - the number of columns in the parent composite, which these + * widgets should span + * @return a class implementing the required interface + */ + protected ISystemUDTypeEditPaneTypesSelector createTypesListEditor(Composite parent, int nbrColumns) { + SystemUDSimpleTypesListEditor simpleEditor = new SystemUDSimpleTypesListEditor(parent, nbrColumns); + simpleEditor.setAutoUpperCase(getAutoUpperCaseTypes()); + return simpleEditor; + } + + /** + * Overridable exit point. + * Return true if the types are to be auto-uppercased. + * Default is true. + * Only used if not supplying your own types editor. + */ + protected boolean getAutoUpperCaseTypes() { + return true; + } + + /** + * Enable/disable entire pane + */ + public void setEnabled(boolean enable) { + textName.setEnabled(enable); + typesEditor.setEnabled(enable); + } + + /** + * Check all input for errors + * @param setFocus - true if to set focus on offending control + * @param skipControl - control to skip since already checked + * @return true if no errors + */ + protected boolean validateInput(boolean setFocus, Control skipControl) { + Control errCtl = null; + errorMessage = null; + if (skipControl != textName) errorMessage = nameValidator.validate(textName.getText().trim()); + errCtl = textName; + if ((errorMessage == null) && (skipControl != typesEditor.getControl())) { + errorMessage = typesEditor.validate(); + if (errorMessage == null) errorMessage = doTypesStringValidation(setFocus); + errCtl = typesEditor.getControl(); + } + if (errorMessage == null) errorMessage = doAdditionalValidation(setFocus); // let child classes try + if (errorMessage != null) { + parentDialog.setErrorMessage(errorMessage); + if (setFocus) errCtl.setFocus(); + } else + parentDialog.clearErrorMessage(); + setPageComplete(); + return (errorMessage == null); + } + + /** + * Overridable entry point for doing validation of the type string. + * Called by validateInput. + * If setFocus is true, set the focus at the appropriate widget that is in error. + * If setFocus is true, you can assume we are doing OK processing vs keystroke processor. + * @return error message if an error detected, else null + */ + protected SystemMessage doTypesStringValidation(boolean doSetFocus) { + return null; + } + + /** + * Overridable entry point for doing validation of input. + * Called by validateInput. + * If setFocus is true, set the focus at the appropriate widget that is in error. + * If setFocus is true, you can assume we are doing OK processing vs keystroke processor. + * @return error message if an error detected, else null + */ + protected SystemMessage doAdditionalValidation(boolean doSetFocus) { + return null; + } + + // Scenario: User edits an item, producing a syntax error. + // (eg. clear action name field) Gets error msg, OK button disabled. + // then changes selection to another item. + // Current Problem: Error msg stays, OK remains disabled, until + // they edit a field. (ValidateInput isnt re-reun until + // another field is changed.) + // Solution: When changing selection, reset the errorMessage and + // page-valid status. Can get away with this because we + // do not propagate invalid field changes to the UDA data in memory. + private void resetPageValidation() { + errorMessage = null; + parentDialog.clearErrorMessage(); + parentDialog.setPageComplete(true); + } + + /** + * Return true if the page is complete, so to enable Finish. + * Called by setPageComplete + */ + protected boolean isPageComplete() { + return ((errorMessage == null) && (textName.getText().trim().length() > 0) && (typesEditor.getTypes().length() > 0)); + } + + /** + * Set page complete... enables/disables Apply button + */ + protected void setPageComplete() { + boolean complete = isPageComplete(); + parentDialog.setPageComplete(complete); + } + + /** + * Call this whenever the user makes ANY changes. + * Used to enable/disable apply/revert buttons + */ + protected void setChangesMade() { + if (stateMachine != null) stateMachine.setChangesMade(); + } + + /** + * Are errors pending? If so, don't allow user to change selection + * or profile or anything! + */ + public boolean areErrorsPending() { + return ((errorMessage != null) && ((currentType != null) || newMode)); + } + + /** + * This is called when user changes their selection in the left-side tree view + */ + public void selectionChanged(SelectionChangedEvent se) { + if (recursiveCall) return; // ignore! + // Calling the setText() methods here was causing Modify events + // when just switching the selection, even on Domain items, leading + // to setComment(), etc calls on the Action item, caausing these tags to + // even be written in the saved XML. Even for Domain items! + // So, turning off/on the modifyListeners around the selection change, + // based on the isEnabled switch + IStructuredSelection ss = (IStructuredSelection) se.getSelection(); + Object so = ss.getFirstElement(); + // if old selection has validation errors, don't allow selection to be changed. + if (areErrorsPending()) { + // Verify old selection has not been deleted from tree + if (newMode || SystemUDBaseManager.inCurrentTree(currentType.getElement())) { + if (!newMode && (so != currentType)) + treeView.setSelection(new StructuredSelection(currentType)); + else if (newMode && (so != newModeNewItem)) treeView.setSelection(new StructuredSelection(newModeNewItem)); + return; + } + } + // We need to test for pending changes, and if any are pending, prompt + // user to continue (and lose changes) or cancel... + if ((stateMachine != null) && stateMachine.isSaveRequired()) { + saveData(); + if (newMode) { + // interesting problem! The save of the new data resulted in a new node, + // but this is not visible in the tree view. To make it visible means we + // we will lose focus, and this method will be recalled recursively... + recursiveCall = true; + treeView.refreshElementParent(currentType); // show new item in tree view + recursiveCall = false; + if (so instanceof SystemUDTypeElement) // if user was selecting a type, it might have a new binary address after the refresh + treeView.selectElement((SystemUDTypeElement) so); + else if (so != null) treeView.setSelection(new StructuredSelection(so)); // restore what user selected + return; // avoid recursion! + } + } + recursiveCall = false; + // Clear any page-valid errors remaining from previous selection + // (Since validation on the new selection is only run if editing + // changes are made + errorMessage = null; + resetPageValidation(); + newMode = ((so instanceof SystemUDTreeViewNewItem) && ((SystemUDTreeViewNewItem) so).isExecutable()); + // Refresh tree view if name changed on last item + if (nameChanged) { + nameChanged = false; + if (null != currentType) treeView.refresh(currentType); + } + SystemUDTypeElement sn = null; + if ((null != so) && (so instanceof SystemUDTypeElement)) sn = (SystemUDTypeElement) so; + currentType = sn; + // Disable modifyListeners prior to resetting fields + if (isEnabled) { + textName.removeModifyListener(nameML); + typesEditor.removeModifyListener(typesML); + } + // Clear all fields if not a file type entry. Could be a domain node + //boolean prevEnabledState = isEnabled; + //boolean newEnabledState = false; + // domain node selected. Note we will be hidden in this case, by the + // state machine + if (!newMode && ((null == sn) || sn.isDomain())) { + isEnabled = false; + //newEnabledState = false; + textName.setText(""); //$NON-NLS-1$ + typesEditor.clearTypes(); + } + // "new" node or existing node selected + else { + isEnabled = true; + //newEnabledState = true; + if (!newMode && sn != null) { + textName.setText(sn.toString()); + typesEditor.setTypes(sn.getTypes()); + //setEnabled(!treeView.isElementAllSelected() && !treeView.isSelectionVendorSupplied()); + //typesEditor.setEditable(!treeView.isSelectionVendorSupplied(), treeView.getVendorOfSelection()); + setEnabled(!treeView.isElementAllSelected()); + typesEditor.setEditable(!treeView.isElementAllSelected(), treeView.isElementAllSelected() ? treeView.getVendorOfSelection() : null); + } else { + textName.setText(""); //$NON-NLS-1$ + typesEditor.clearTypes(); + typesEditor.setEditable(true, null); + setEnabled(true); + } + // isEnabled will = true when leaving this logic branch + // Will always need to re-add the listeners + textName.addModifyListener(nameML); + typesEditor.addModifyListener(typesML); + } + //System.out.println("selection changed: " + (testCounter++) + ", new? " + newMode + ", enabled? " + isEnabled); + // update state machine + if (newMode) { + stateMachine.setNewMode(); // resets Apply/Reset button status + newModeNewItem = (SystemUDTreeViewNewItem) so; + newModeDomain = newModeNewItem.getDomain(); + if (newModeDomain != currentDomain) setDomain(newModeDomain); //indicate domain change + } else if ((sn == null) || sn.isDomain()) { + stateMachine.setUnsetMode(); // resets Apply/Reset button status + } else { + stateMachine.setEditMode(); // resets Apply/Reset button status } + if (sn.getDomain() != currentDomain) setDomain(sn.getDomain()); //indicate domain change + } + nameValidator.setExistingNamesList(getExistingNames()); + setPageComplete(); + } + + /** + * Need to add/remove listeners around selection changes, so + * I can set text fields without triggering modify event. + * So listeners implemented as internal classes + */ + private class NameModifyListener implements ModifyListener { + public void modifyText(ModifyEvent e) { + if (ignoreChanges) return; + setChangesMade(); + String s = textName.getText().trim().toUpperCase(); + errorMessage = nameValidator.validate(s); + if (errorMessage != null) { + parentDialog.setErrorMessage(errorMessage); + setPageComplete(); + } else { + validateInput(false, textName); + if (currentType != null) { + nameChanged = true; + } + } + } + } //class + + private class TypesModifyListener implements ModifyListener { + public void modifyText(ModifyEvent e) { + if (ignoreChanges) return; + setChangesMade(); + errorMessage = typesEditor.validate(); + if (errorMessage != null) { + parentDialog.setErrorMessage(errorMessage); + setPageComplete(); + } else { + validateInput(false, typesEditor.getControl()); + } + } + } //class + + /** + * For uniqueness checking, get the list of existing type names + */ + protected Vector getExistingNames() { + if (newMode) { + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDTypeManager udtm = udas.getUDTypeManager(); + return udtm.getExistingNames(null, newModeDomain); + } else if (currentType != null) + return currentType.getExistingNames(); + else + return EMPTY_VECTOR; + } + + /** + * Return the user defined action subsystem + */ + protected SystemUDActionSubsystem getUDActionSubsystem() { + /* FIXME - UDA not coupled with subsystem API anymore + if (subsystem!=null) + return subsystem.getUDActionSubsystem(); + else + { + ISubsystemFactoryAdapter adapter = (ISubsystemFactoryAdapter)subsystemFactory.getAdapter(ISubsystemFactoryAdapter.class); + return adapter.getActionSubSystem(subsystemFactory, null); + } + */ + return null; + } + + /** + * When user presses Apply, commit all pending changes... + */ + protected void processChanges() { + currentType.setName(textName.getText().trim()); + currentType.setTypes(typesEditor.getTypes()); + } //process changes + + /** + * Save current state to disk + */ + protected void saveData() { + if (newMode) { + currentType = createNewType(textName.getText().trim(), newModeDomain); + } + processChanges(); + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDTypeManager udtm = udas.getUDTypeManager(); + udtm.saveUserData(); + // inform anybody registered as listeners that we have created/changed model object... + if (newMode) + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_ADDED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_NAMEDTYPE, currentType, null); + else + RSEUIPlugin.getTheSystemRegistry().fireModelChangeEvent(ISystemModelChangeEvents.SYSTEM_RESOURCE_CHANGED, ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_NAMEDTYPE, currentType, null); + } + + /** + * In "new" mode, create a new type when Apply is pressed. + * This only creates the type. It does not populate the attributes + * @return The new action + */ + protected SystemUDTypeElement createNewType(String typeName, int domain) { + // code was originally in SystemNewUDAsWizardMainPage + SystemUDActionSubsystem udas = getUDActionSubsystem(); + SystemUDTypeManager udtm = udas.getUDTypeManager(); + SystemUDTypeElement nt = udtm.addType(domain, typeName); + return nt; + } + + /** + * Revert button pressed + */ + public void revertPressed() { + ignoreChanges = true; + resetPageValidation(); + if ((currentType != null) && !currentType.isDomain()) { + textName.setText(currentType.toString()); + typesEditor.setTypes(currentType.getTypes()); + if (stateMachine != null) stateMachine.resetPressed(); + } else if (newMode) { + textName.setText(""); //$NON-NLS-1$ + typesEditor.clearTypes(); + if (stateMachine != null) stateMachine.resetPressed(); + } + ignoreChanges = false; + setPageComplete(); + } + + /** + * Process the apply button + */ + public void applyPressed() { + if ((newMode || ((currentType != null) && !currentType.isDomain())) && validateInput(true, null)) { + saveData(); + if (stateMachine != null) stateMachine.applyPressed(); + if (newMode) { + // Now update tree view to show new item + recursiveCall = true; + treeView.refreshElementParent(currentType); + recursiveCall = false; + treeView.selectElement(currentType); + } else + treeView.refresh(currentType); + } + setPageComplete(); + } //apply +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeElement.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeElement.java new file mode 100644 index 00000000000..556afa6439f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeElement.java @@ -0,0 +1,72 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; + +/** + * Wraps a "Type" XML tag + */ +public class SystemUDTypeElement extends SystemXMLElementWrapper { + private final static String TYPES_TAG = "Types"; //$NON-NLS-1$ + private final static String TYPE_TAG = "Type"; //$NON-NLS-1$ + + /** + * Constructor + * @param element The actual xml document element for this action + * @param tm The subsystemFactory-specific manager of actions + * @param domainType - The integer representation of the domain this is in (or this is, for a domain element) + */ + public SystemUDTypeElement(Element element, SystemUDTypeManager tm, int domainType) { + super(element, tm, null, domainType); + } + + /** + * Return image to use for this item, in tree views + */ + public Image getImage() { + //System.out.println("in getImage(): isIBM()="+isIBM()+", isUserChanged()="+isUserChanged()); + Image image = null; + if (isIBM()) { + if (isUserChanged()) + image = UserActionsIcon.USERTYPE_IBMUSR.getImage(); + else + image = UserActionsIcon.USERTYPE_IBM.getImage(); + } else + image = UserActionsIcon.USERTYPE_USR.getImage(); + //System.out.println("... image returned = "+image); + return image; + } + + /** + * Return our tag name + */ + public String getTagName() { + return TYPE_TAG; + } + + /** + * Return the list of types + */ + public String getTypes() { + return getTextNode(TYPES_TAG); + } + + /** + * Set the list of types + */ + public void setTypes(String s) { + setUserChanged(true); + setTextNode(TYPES_TAG, s); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeManager.java new file mode 100644 index 00000000000..bb50323b5d6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeManager.java @@ -0,0 +1,321 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.io.File; +import java.util.Vector; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.rse.core.SystemBasePlugin; +import org.eclipse.rse.core.SystemResourceHelpers; +import org.eclipse.rse.core.SystemResourceManager; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.useractions.UserActionsIcon; +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Element; + +/** + * Instances of this class hold the UDA Type definitions unique to + * the SubSystem type - according to the SubSystemFactory + * + * Note that unlike user actions, types are not scoped by profile. + * For each subsystem factory there is but a single master list of types. + * + * Instances of this class will be linked to a SubSystem instance for + * now, but should be linked to a subsystem factory instance in the future. + * + */ +public class SystemUDTypeManager extends SystemUDBaseManager { + private static final String XE_ROOT = "FileTypes"; //$NON-NLS-1$ + public static final String XE_TYPE = "Type"; //$NON-NLS-1$ + public static final String ALL_TYPE = "ALL"; //$NON-NLS-1$ + public final static String UDT_FILENAME = "udtype.xml"; //$NON-NLS-1$ + private boolean oldFolderChecked = false; + + /** + * Constructor + */ + public SystemUDTypeManager(SystemUDActionSubsystem udas) { + super(udas); + } + + /** + * Return true if this is user actions, false if this is named types. + */ + protected boolean isUserActionsManager() { + return false; + } + + /** + * Get the icon to show in the tree views, for the "new" expandable item + */ + public Image getNewImage() { + return UserActionsIcon.USERTYPE_NEW.getImage(); + } + + /** + * Get the name of the file to persist to: udtype.xml + */ + public String getFileName() { + return UDT_FILENAME; + } + + /** + * Overridable extension point for child classes to do migration of their document. + * This is called on first load of a document, which has a release stamp other than + * the current release + * @return true if any migration was done + */ + protected boolean doMigration(ISystemProfile profile, String oldRelease) { + return getActionSubSystem().doTypesMigration(profile, oldRelease); + } + + /** + * Parent method override for returning the "New" icon label for the Work With dialog tree view. + * For us, we defer to the getActionSubSystem().{@link SystemUDActionSubsystem#getNewNodeTypeLabel() getNewNodeTypeLabel()}. + * Do not override this. + * @return translated value for "New" in new icon for WW action and type dialogs. Default is "New" + */ + protected String getNewNodeLabel() { + return getActionSubSystem().getNewNodeTypeLabel(); + } + + // ----------------------------------------------------------- + // ISystemXMLElementWrapperFactory + // ----------------------------------------------------------- + /** + * Return the tag name for our managed elements. + * Eg: will be "Action" for user actions, and "Type" for file types. + */ + public String getTagName() { + return XE_TYPE; + } + + /** + * Given an xml element node, create an instance of the appropriate + * subclass of SystemXMLElementWrapper to represent it. + */ + public SystemXMLElementWrapper createElementWrapper(Element xmlElementToWrap, ISystemProfile profile, int domain) { + SystemUDTypeElement elementWrapper = new SystemUDTypeElement(xmlElementToWrap, this, domain); + return elementWrapper; + } + + // ----------------------------------------------------------- + // THE FOLLOWING ARE PARENT METHODS THAT ABSTRACT OUT THE + // DIFFERENCES BETWEEN ACTIONS AND TYPES + // ----------------------------------------------------------- + /** + * Get the document root tag name. + * We return "FileTypes" + */ + public String getDocumentRootTagName() { + return XE_ROOT; // "FileTypes" + } + + /** + * Do we uppercase the value of the "Name" attribute? + * Yes, we do for types + */ + protected boolean uppercaseName() { + return true; + } + + /** + * Return true if the elements managed by this class are scoped by + * profile. Usually true for actions, false for types + */ + public boolean supportsProfiles() { + return false; + } + + /** + * Prime the given document with any default types + * Calls primeDefaultTypes in action subsystem. + */ + public SystemXMLElementWrapper[] primeDocument(ISystemProfile profile) { + return getActionSubSystem().primeDefaultTypes(this); + } + + // ------------------------------------------------------------------- + // OVERRIDE OF PARENT METHODS TO ACCOUNT FOR THE FACT TYPES ARE STORED + // ONLY BY SUBSYSTEM FACTORY, NOT PROFILE + // ------------------------------------------------------------------- + /** + * Get the folder containing the xml file used to persist the actions, + * for the given profile + */ + protected IFolder getDocumentFolder(ISubSystemConfiguration subsystemFactory, ISystemProfile profile) { + // return new location, as of R2 + IFolder typesFolder = SystemResourceManager.getTypeFiltersFolder(subsystemFactory); + // we check here for any residual old types files from R1. If found, we move it + // to the new location right away! + // TODO: DELETE THIS EXPENSIVE LOGIC AFTER A FEW RELEASES. + if (!oldFolderChecked && (profile != null)) { + //if (profile == null) + // profile = subsystem.getSystemProfile(); + //System.out.println("Is profile null? " + (profile==null)); + IFolder oldFolder = SystemResourceManager.getUserActionsFolder(profile.getName(), subsystemFactory); + IFile oldFile = oldFolder.getFile(getFileName()); + if (exists(oldFile)) { + //System.out.println("Attempt to move old types folder..."); + try { + if (!typesFolder.exists()) // if new folder location does not exist yet, create it... + { + SystemResourceHelpers.getResourceHelpers().createFolder(typesFolder); + } + SystemResourceHelpers.getResourceHelpers().moveFile(typesFolder, oldFile); // now move old file to new folder + } catch (Exception exc) { + SystemBasePlugin.logError("Exception moving old types file! ", exc); //$NON-NLS-1$ + } + } + oldFolderChecked = true; + } + return typesFolder; + } + + /** + * For some reason the exists() method on IResource is fundamentally not reliable. + * Because of this, we resort to looking ourselves at the file system. + */ + protected boolean exists(IResource resource) { + boolean exists = true; + IPath localOSLocation = resource.getLocation(); + if (localOSLocation == null) { + //System.out.println("Testing if old file exists, and localOSLocation is null"); + exists = false; // what else? + } else { + File osFile = new File(localOSLocation.toOSString()); + //System.out.println("Testing if old file exists : " + localOSLocation.toOSString() + "... " + osFile.exists() ); + exists = osFile.exists(); + } + return exists; + } + + /** + * Intended for IMPORT actions only, where no Subsystem instance available: + */ + public void setFolder(String profileName, String factoryId) { + //importCaseFolder = SystemResourceManager.getUserActionsFolder(profileName, factoryId); + importCaseFolder = SystemResourceManager.getTypeFiltersFolder(factoryId); + } + + /** + * Indicate data has changed for the given profile + */ + protected void dataChanged(ISystemProfile profile) { + // ADDED THIS LINE TO RESET THE RESOLVED TYPES WHEN A TYPE IS ADDED + _udas.resetResolvedTypes(); + } + + // ----------------------------------------------------------- + // TYPE-MANAGER UNIQUE METHODS... + // ----------------------------------------------------------- + /** + * Given a type name and domain, find the named type and return + * its types, or null if not found + */ + public String getTypesForTypeName(String typeName, int domain) { + SystemUDTypeElement element = (SystemUDTypeElement) findByName(null, typeName, domain); + if (element != null) + return element.getTypes(); + else + return null; + } + + /** + * Return xml element wrapper objects for all types, for the + * given domain, or for the whole document if domain is -1 (iff + * domains not supported). + * @param v - existing vector to populate. If null passed, it is + * not populated. + * @param domain - the integer representation of the given domain, + * or -1 iff supportsDomains() is false + * @return array of type objects + */ + public SystemUDTypeElement[] getTypes(Vector v, int domain) { + v = super.getXMLWrappers(v, domain, null); + if (v == null) return new SystemUDTypeElement[0]; + SystemUDTypeElement[] types = new SystemUDTypeElement[v.size()]; + for (int idx = 0; idx < types.length; idx++) + types[idx] = (SystemUDTypeElement) v.elementAt(idx); + return types; + } + + /** + * Return list of names of types in the given domain, or in doc + * if domain is -1 (which must only happen if supportsDomains() is false!) + */ + public String[] getTypeNames(int domain) { + Vector v = new Vector(); + // step 1: find the parent domain object, if any... + if (domain != -1) { + SystemUDTypeElement parentDomainElement = (SystemUDTypeElement) getDomainWrapper(null, domain); + // step 1a: ask that parent to return its children names... + v = parentDomainElement.getExistingNames(); + String[] names = new String[v.size()]; + for (int idx = 0; idx < names.length; idx++) + names[idx] = (String) v.elementAt(idx); + return names; + } + // step 2: no domain name given, so assume document roots are the types so find them and return their names + else { + v = SystemXMLElementWrapper.getExistingNames(null, getDocument(null), XE_TYPE); + String[] names = new String[v.size()]; + for (int idx = 0; idx < names.length; idx++) + names[idx] = (String) v.elementAt(idx); + return names; + } + } + + /** + * Add a new user type. + * Creates the new XML node in the document, + * and creates and returns a wrapper object for it. + *

+ * Optimized flavour of addElement that does not require a profile, + * and is typed to return SystemUDTypeElement + */ + public SystemUDTypeElement addType(int domain, String name) { + return (SystemUDTypeElement) super.addElement(null, domain, name); + } + + /** + * Delete a give user action or type, given its wrapper. + * Deletes the xml node from the document. + *

+ * Optimized flavour of delete that does not require a profile, + * and is typed to take SystemUDTypeElement + */ + public void delete(SystemUDTypeElement typeElement) { + super.delete(null, typeElement); + } + + // ------------------------------------------------------------------------- + // SPECIAL FLAVOURS OF PARENT METHODS, THAT DON'T REQUIRE A PROFILE PARM... + // ------------------------------------------------------------------------- + /** + * Save user data + */ + public void saveUserData() { + super.saveUserData(null); + } + /* + * Get our xml document + * + protected Document getDocument() + { + return super.getDocument(null); + }*/ +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeTreeView.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeTreeView.java new file mode 100644 index 00000000000..5eb8bd5bfde --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUDTypeTreeView.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.rse.useractions.ui.uda; + +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.rse.core.model.ISystemModelChangeEvents; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.services.clientserver.messages.SystemMessage; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.swt.widgets.Composite; + +/** + * In the Work With User Defined File Types dialog, this is the + * tree view for showing the existing types. + */ +public class SystemUDTypeTreeView extends SystemUDBaseTreeView { + /** + * Constructor when we have a subsystem + */ + public SystemUDTypeTreeView(Composite parent, ISystemUDWorkWithDialog editPane, ISubSystem ss) { + /* FIXME - UDA not coupled with subsystem API anymore */ + super(parent, editPane, ss, /*ss.getUDActionSubsystem().getUDTypeManager()*/null); + } + + /** + * Constructor when we have a subsystem factory and profile + */ + public SystemUDTypeTreeView(Composite parent, ISystemUDWorkWithDialog editPane, ISubSystemConfiguration ssFactory, ISystemProfile profile) { + super(parent, editPane, ssFactory, profile, + /* FIXME - UDA not coupled with subsystem API anymore + ((ISubsystemFactoryAdapter)ssFactory.getAdapter(ISubsystemFactoryAdapter.class)).getActionSubSystem(ssFactory, null).getUDTypeManager() + */ + null); + } + + /** + * Return types manager + */ + public SystemUDTypeManager getTypeManager() { + return (SystemUDTypeManager) super.getDocumentManager(); + } + + /** + * Get the selected type name. + * Returns "" if nothing selected + */ + public String getSelectedTypeName() { + return super.getSelectedElementName(); + } + + /** + * Get the selected type domain. + * Returns -1 if nothing selected or domains not supported + */ + public int getSelectedTypeDomain() { + return super.getSelectedElementDomain(); + } + + /** + * Return message for delete confirmation + */ + protected SystemMessage getDeleteConfirmationMessage() { + return RSEUIPlugin.getPluginMessage(MSG_CONFIRM_DELETE_USERTYPE); + } + + /** + * Return the {@link org.eclipse.rse.core.model.ISystemModelChangeEvents} constant representing the resource type managed by this tree. + * This is a parent class override. + */ + protected int getResourceType() { + return ISystemModelChangeEvents.SYSTEM_RESOURCETYPE_NAMEDTYPE; + } + + /** + * Parent override. + * Restore the selected type to its IBM-supplied default value. + */ + public void doRestore() { + SystemXMLElementWrapper selectedElement = getSelectedElement(); + if ((selectedElement == null) || !(selectedElement instanceof SystemUDTypeElement)) return; + SystemUDTypeElement type = (SystemUDTypeElement) selectedElement; + boolean ok = getDocumentManager().getActionSubSystem().restoreDefaultType(type, type.getDomain(), type.getOriginalName()); + if (ok) { + type.setUserChanged(false); + getDocumentManager().saveUserData(profile); + selectElement(selectedElement); + String[] allProps = { IBasicPropertyConstants.P_TEXT, IBasicPropertyConstants.P_IMAGE }; + update(selectedElement, allProps); + } + } + + // ------------------------------------ + // HELPER METHODS CALLED FROM EDIT PANE + // ------------------------------------ + /** + * Select the given type + */ + public void selectType(SystemUDTypeElement element) { + super.selectElement(element); + } + + /** + * Refresh the parent of the given action. + * That is, find the parent and refresh the children. + * If the parent is not found, assume it is because it is new too, + * so refresh the whole tree. + */ + public void refreshTypeParent(SystemUDTypeElement element) { + super.refreshElementParent(element); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtension.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtension.java new file mode 100644 index 00000000000..06cf901459f --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtension.java @@ -0,0 +1,61 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * This class represents a user action read from a user action extension point + *

+ * THIS CLASS IS THE BEGINNING OF SUPPORT FOR USER ACTION EXTENSION POINTS. + * IT IS NOT COMPLETE YET AND NOT SUPPORTED YET. + */ +public class SystemUserActionExtension { + private String types, id, vendor; + private boolean allTypes; + + // SEE FILE plugin.xml.udaExtensionPoint.notused + /** + * Constructor + */ + public SystemUserActionExtension(IConfigurationElement element) { + types = element.getAttribute("systemTypes"); //$NON-NLS-1$ + if ((types == null) || types.equals("*")) //$NON-NLS-1$ + allTypes = true; + id = element.getAttribute("id"); //$NON-NLS-1$ + vendor = element.getAttribute("vendor"); //$NON-NLS-1$ + } + + /** + * Return the value of the "vendor" attribute + */ + public String getVendor() { + return vendor; + } + + /** + * Return the value of the "id" attribute + */ + public String getId() { + return id; + } + + /** + * Return true if this extension's systemTypes attribute matches the given system type + */ + public boolean appliesToSystemType(String type) { + //System.out.println("INSIDE APPLIESTO FOR " + type + ". allTypes = " + allTypes + ". types = " + types); + if (allTypes) + return true; + else + return (types.indexOf(type) >= 0); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtensionManager.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtensionManager.java new file mode 100644 index 00000000000..3dcc9c4e9ba --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemUserActionExtensionManager.java @@ -0,0 +1,103 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; + +/** + * This class manages reading user action extension points. + * Each subsystem is responsible for defining their own extension points + * to allow BPs and ISVs to pre-supply user actions, if desired. + *

+ * Further, the extension points must all support a common set of subtags: + * userActionContribution, + * namedType and userAction. + *

+ * This class is the base class for the reader for parsing these + * extension points. + * + *

+ * THIS CLASS IS THE BEGINNING OF SUPPORT FOR USER ACTION EXTENSION POINTS. + * IT IS NOT COMPLETE YET AND NOT SUPPORTED YET. + */ +public class SystemUserActionExtensionManager { + private String pluginID, extensionID; + private boolean read; + private Vector elements; + + // SEE FILE plugin.xml.udaExtensionPoint.notused + /** + * Constructor + * @param pluginID - the ID of the plugin which defined this extension + * @param extensionID - the ID of the extension + */ + public SystemUserActionExtensionManager(String pluginID, String extensionID) { + this.pluginID = pluginID; + this.extensionID = extensionID; + } + + /** + * Return list of user-actions defined by the given extension point, for the given + * system type. + */ + public SystemUserActionExtension[] getUserActionExtensions(String systemType) { + int count = 0; + if (!read) readExtensions(); + if ((elements == null) || (elements.size() == 0)) return null; + for (int idx = 0; idx < elements.size(); idx++) { + SystemUserActionExtension currAction = (SystemUserActionExtension) elements.elementAt(idx); + if (currAction.appliesToSystemType(systemType)) ++count; + } + if (count == 0) return null; + SystemUserActionExtension[] actions = new SystemUserActionExtension[count]; + count = 0; + for (int idx = 0; idx < elements.size(); idx++) { + SystemUserActionExtension currAction = (SystemUserActionExtension) elements.elementAt(idx); + if (currAction.appliesToSystemType(systemType)) actions[count++] = currAction; + } + return actions; + } + + /** + * Return true if the extensions have been read in yet from the registry + */ + protected boolean hasBeenRead() { + return read; + } + + /** + * Read list of extensions from registry + */ + protected void readExtensions() { + // Get reference to the plug-in registry + IExtensionRegistry registry = Platform.getExtensionRegistry(); + // Get configured extenders + IConfigurationElement[] userActionExtensions = registry.getConfigurationElementsFor(pluginID, extensionID); + if (userActionExtensions != null) { + elements = new Vector(); + for (int idx = 0; idx < userActionExtensions.length; idx++) { + elements.add(createUserActionExtension(userActionExtensions[idx])); + } + } + read = true; + } + + /** + * Overridable method for instantiating a new SystemUserActionExtension object + */ + protected SystemUserActionExtension createUserActionExtension(IConfigurationElement element) { + return new SystemUserActionExtension(element); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDAsDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDAsDialog.java new file mode 100644 index 00000000000..ff2361016b0 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDAsDialog.java @@ -0,0 +1,453 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.model.SystemStartHere; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.dialogs.SystemPromptDialog; +import org.eclipse.rse.ui.widgets.ISystemEditPaneStates; +import org.eclipse.rse.ui.widgets.SystemEditPaneStateMachine; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; + +/** + * A dialog that allows the user to manipulate their user defined actions for a + * given subsystem factory. + */ +public class SystemWorkWithUDAsDialog extends SystemPromptDialog implements ISystemUDWorkWithDialog, ISystemIconConstants, ISystemMessages, ISystemUDAEditPaneHoster, Listener, SelectionListener, + Runnable { + // Changes: + // June 2002, Phil Coulthard: Added prompt for parent profile, similar to New Connection and New Filter Pool wizards. + // Similar to SystemConnectionForm + protected Shell shell; // shell hosting this viewer + // GUI widgets + protected Label labelProfile, labelProfileValue; + protected Combo profileCombo; + protected SystemUDActionTreeView treeView; + protected int prevProfileComboSelection = 0; + // inputs + protected ISubSystem subsystem; + protected ISubSystemConfiguration subsystemFactory; + //protected String defaultProfileName; + //protected String[] defaultProfileNames; + protected ISystemProfile[] systemProfiles; + protected ISystemProfile currentProfile; + // state + protected SystemUDActionEditPane editpane; + protected Button applyButton, revertButton; + protected SystemEditPaneStateMachine sm; + + /** + * Constructor when we have a subsystem + */ + public SystemWorkWithUDAsDialog(Shell shell, ISubSystem ss) { + super(shell, SystemUDAResources.RESID_WORKWITH_UDAS_TITLE); + setCancelButtonLabel(SystemResources.BUTTON_CLOSE); + setShowOkButton(false); + this.shell = shell; + this.subsystem = ss; + this.subsystemFactory = ss.getSubSystemConfiguration(); + setProfiles(SystemStartHere.getSystemProfileManager().getActiveSystemProfiles(), subsystem.getSystemProfile()); + //setMinimumSize(600, 520); // x, y + //pack(); + setHelp(); + } + + /** + * Constructor when we have a subsystem factory + */ + public SystemWorkWithUDAsDialog(Shell shell, ISubSystemConfiguration ssFactory, ISystemProfile profile) { + super(shell, SystemUDAResources.RESID_WORKWITH_UDAS_TITLE); + setCancelButtonLabel(SystemResources.BUTTON_CLOSE); + setShowOkButton(false); + this.shell = shell; + this.subsystemFactory = ssFactory; + setProfiles(SystemStartHere.getSystemProfileManager().getActiveSystemProfiles(), profile); + //setMinimumSize(600, 520); // x, y + //pack(); + setHelp(); + } + + /** + * Overridable extension point for setting dialog help + */ + protected void setHelp() { + setHelp(RSEUIPlugin.HELPPREFIX + "wwua0000"); //$NON-NLS-1$ + } + + /** + * Set the profiles to show in the combo. + * @param profiles array of profiles to show + * @param profile the profile to pre-select + */ + public void setProfiles(ISystemProfile[] profiles, ISystemProfile profile) { + if (profiles == null) profiles = new ISystemProfile[0]; + this.systemProfiles = profiles; + this.currentProfile = profile; + initProfileCombo(); + } + + /** + * @see SystemPromptDialog#getInitialFocusControl() + */ + protected Control getInitialFocusControl() { + return null; + } + + /** + * Return the user defined action subsystem + */ + protected SystemUDActionSubsystem getUDActionSubsystem() { + /* FIXME - UDA not coupled with subsystem API anymore + if (subsystem!=null) + return subsystem.getUDActionSubsystem(); + else + { + return ((ISubsystemFactoryAdapter)subsystemFactory.getAdapter(ISubsystemFactoryAdapter.class)).getActionSubSystem(subsystemFactory, null); + } + */ + return null; + } + + /** + * @see SystemPromptDialog#createInner(Composite) + */ + protected Control createInner(Composite parent) { + // 2 columns + int nbrColumns = 2; + Composite composite = SystemWidgetHelpers.createComposite(parent, nbrColumns); + Composite profileComposite = SystemWidgetHelpers.createFlushComposite(composite, 2); + ((GridData) profileComposite.getLayoutData()).horizontalSpan = nbrColumns; + String temp = SystemWidgetHelpers.appendColon(SystemUDAResources.RESID_UDA_PROFILE_LABEL); + labelProfile = SystemWidgetHelpers.createLabel(profileComposite, temp); + labelProfile.setToolTipText(SystemUDAResources.RESID_UDA_PROFILE_TOOLTIP); + profileCombo = SystemWidgetHelpers.createReadonlyCombo(profileComposite, null, SystemUDAResources.RESID_UDA_PROFILE_TOOLTIP); + //SystemWidgetHelpers.setHelp(profileCombo, RSEUIPlugin.HELPPREFIX + "ccon0001", parentHelpId); + if (currentProfile != null) // important to set this before instantiating action tree + getUDActionSubsystem().getUDActionManager().setCurrentProfile(currentProfile); + // create tree view on left + if (subsystem != null) + treeView = new SystemUDActionTreeView(composite, this, subsystem); + else + treeView = new SystemUDActionTreeView(composite, this, subsystemFactory, currentProfile); + Control c = treeView.getControl(); + //c.setToolTipText(RSEUIPlugin.getString(RESID_UDA_TREE_TIP)); + GridData data = (GridData) c.getLayoutData(); + if (data == null) data = new GridData(); + data.grabExcessHorizontalSpace = false; + data.horizontalAlignment = GridData.FILL; + data.grabExcessVerticalSpace = true; + data.verticalAlignment = GridData.FILL; + data.widthHint = 140; // 170 + data.heightHint = publicConvertHeightInCharsToPixels(12); // high enough to show 12 entries + c.setLayoutData(data); + // we want the tree view on the left to extend to the bottom of the page, so on the right + // we create a 1-column composite that will hold the edit pane on top, and the apply/revert + // buttons on the bottom... + Composite rightSideComposite = SystemWidgetHelpers.createFlushComposite(composite, 1); + // now populate top of right-side composite with edit pane... + if (subsystem != null) + editpane = getUDActionSubsystem().getCustomUDActionEditPane(subsystem, this, treeView); + else + editpane = getUDActionSubsystem().getCustomUDActionEditPane(subsystemFactory, currentProfile, this, treeView); + editpane.createContents(rightSideComposite); + // now add a visual separator line + addSeparatorLine(rightSideComposite, 1); + // now populate bottom of right-side composite with apply/revert buttons within their own composite + int nbrColumns_buttonComposite = 4; + Composite applyResetButtonComposite = SystemWidgetHelpers.createFlushComposite(rightSideComposite, nbrColumns_buttonComposite); + //((GridData)applyResetButtonComposite.getLayoutData()).horizontalIndent = 200; // shift buttons to the right + // now populate the buttons composite with apply and revert buttons + Label filler = SystemWidgetHelpers.createLabel(applyResetButtonComposite, ""); //$NON-NLS-1$ + ((GridData) filler.getLayoutData()).grabExcessHorizontalSpace = true; + ((GridData) filler.getLayoutData()).horizontalAlignment = GridData.FILL; + applyButton = SystemWidgetHelpers.createPushButton(applyResetButtonComposite, this, SystemUDAResources.RESID_UDA_APPLY_BUTTON_LABEL, SystemUDAResources.RESID_UDA_APPLY_BUTTON_TOOLTIP); + revertButton = SystemWidgetHelpers.createPushButton(applyResetButtonComposite, this, SystemUDAResources.RESID_UDA_REVERT_BUTTON_LABEL, SystemUDAResources.RESID_UDA_REVERT_BUTTON_TOOLTIP); + // now add a spacer to soak up left-over height... + addGrowableFillerLine(rightSideComposite, 1); + // populate profile dropdown + initProfileCombo(); + // add state machine to edit pane + sm = new SystemEditPaneStateMachine(rightSideComposite, applyButton, revertButton); + editpane.setStateMachine(sm); + // add listeners... + profileCombo.addSelectionListener(this); + treeView.addSelectionChangedListener(editpane); + getShell().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + //System.out.println("Inside dispose for SystemWorkWithUDAsDialog"); + getUDActionSubsystem().getUDActionManager().setCurrentProfile(null); + } + }); + treeView.getControl().addMouseListener(editpane); + treeView.getControl().addKeyListener(editpane); + composite.layout(true); + rightSideComposite.setVisible(false); + treeView.expandDomainNodes(); + return composite; + } + + /** + * Intercept of parent so we can reset the default button + */ + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + getShell().setDefaultButton(applyButton); // defect 46129 + } + + /** + * Initialize contents and selection of profile combo + */ + private void initProfileCombo() { + if (profileCombo != null) { + if ((systemProfiles != null) && (systemProfiles.length > 0)) { + String[] names = new String[systemProfiles.length]; + int selIdx = 0; + for (int idx = 0; idx < names.length; idx++) { + names[idx] = systemProfiles[idx].getName(); + if ((currentProfile != null) && (currentProfile == systemProfiles[idx])) selIdx = idx; + } + profileCombo.setItems(names); + profileCombo.setText(names[selIdx]); + prevProfileComboSelection = selIdx; + } + } + } + + /** + * Intercept of parent method so we can direct it to the Apply button versus the OK button + */ + public void setPageComplete(boolean complete) { + if (applyButton != null) { + if (!complete) applyButton.setEnabled(false); + // else: we never enable it because the state machine does that anyway on any user-input change + } + } + + /** + * Parent override. + * Called when user presses CLOSE button. + * We simply close the dialog (since we save as we go), unless there are pending changes. + */ + protected boolean processCancel() { + if (sm.isSaveRequired()) { + if (!editpane.validateInput(true, null)) { + sm.setChangesMade(); // defect 45773 + return false; // pending errors. Cannot save, so cannot close! + } + editpane.saveData(); + } + return super.processCancel(); + } + + // --------------------------------- + // METHODS FOR INTERFACES... + // --------------------------------- + /** + * Handles events generated by controls on this page. + */ + public void handleEvent(Event e) { + clearMessage(); + Widget source = e.widget; + if (source == applyButton) { + processApply(); + } else if (source == revertButton) { + processRevert(); + } + } + + /** + * Process the apply button + */ + public void processApply() { + editpane.applyPressed(); + } + + /** + * Process the revert button + */ + public void processRevert() { + editpane.revertPressed(); + } + + /** + * Combo selection listener method + */ + public void widgetDefaultSelected(SelectionEvent event) { + } + + /** + * Combo selection listener method + */ + public void widgetSelected(SelectionEvent event) { + Object src = event.getSource(); + if (src == profileCombo) { + if (editpane.areErrorsPending()) { + profileCombo.getDisplay().asyncExec(this); + return; + } + // SystemUDActionManager udam = getUDActionSubsystem().getUDActionManager(); + if (sm.isSaveRequired()) { + if (!editpane.validateInput(true, null)) // errors in pending input? + { + sm.setChangesMade(); + profileCombo.getDisplay().asyncExec(this); + return; + } + //udam.saveUserData(udam.getCurrentProfile()); + editpane.saveData(); // defect 45771 + } + sm.applyPressed(); + int idx = profileCombo.getSelectionIndex(); + if (idx < 0) // should never happen? + idx = 0; + prevProfileComboSelection = idx; + currentProfile = systemProfiles[idx]; + getUDActionSubsystem().getUDActionManager().setCurrentProfile(currentProfile); + treeView.clearClipboard(); + treeView.setInput("0"); //$NON-NLS-1$ + treeView.expandDomainNodes(); + } + } + + // ------------------------------------------------------- + // METHOD REQUIRED BY RUNNABLE, USED IN CALL TO ASYNCEXEC + // ------------------------------------------------------- + /** + * Run asynchronously verification of data when user changes profile + * selection. If errors pending, re-select previous profile + */ + public void run() { + profileCombo.select(prevProfileComboSelection); + super.run(); + } + + // --------------- + // HELPER METHODS + // --------------- + // ----------------------------------- + // ISystemUDWorkWithDialog methods... + // ----------------------------------- + /** + * Decide if we can do the delete or not. + * Will decide the enabled state of the delete action. + */ + public boolean canDelete(Object selectedObject) { + return (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isSelectionVendorSupplied(); + } + + /** + * Decide if we can do the move up or not. + * Will decide the enabled state of the move up action. + */ + public boolean canMoveUp(Object selectedObject) { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending(); + if (can) { + TreeItem selectedItem = treeView.getSelectedTreeItem(); + TreeItem parentItem = selectedItem.getParentItem(); + if (parentItem != null) + can = (parentItem.getItems()[0] != selectedItem); + else // this means we don't have domains + { + TreeItem[] roots = treeView.getTree().getItems(); + for (int idx = 0; idx < roots.length; idx++) { + if (roots[idx].getData() instanceof SystemXMLElementWrapper) { + can = (roots[idx] != selectedItem); + break; + } + } + } + } + return can; + } + + /** + * Decide if we can do the move down or not. + * Will decide the enabled state of the move down action. + */ + public boolean canMoveDown(Object selectedObject) { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending(); + if (can) { + TreeItem selectedItem = treeView.getSelectedTreeItem(); + TreeItem parentItem = selectedItem.getParentItem(); + if (parentItem != null) + can = (parentItem.getItems()[parentItem.getItemCount() - 1] != selectedItem); + else // this means we don't have domains + { + TreeItem[] roots = treeView.getTree().getItems(); + can = (roots[roots.length - 1] != selectedItem); + } + } + return can; + } + + /** + * Decide if we can do the copy or not. + * Will decide the enabled state of the copy action. + */ + public boolean canCopy(Object selectedObject) { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending(); + return can; + } + + /** + * Return true if currently selected type is vendor supplied + */ + protected boolean isSelectionVendorSupplied() { + SystemXMLElementWrapper selectedElement = treeView.getSelectedElement(); + if (selectedElement != null) { + String vendor = selectedElement.getVendor(); + //System.out.println("Vendor value: '"+vendor+"'"); + return ((vendor != null) && (vendor.length() > 0)); + } + return false; + } + + /** + * Return the vendor that is responsible for pre-supplying this existing type, + * or null if not applicable. + */ + protected String getVendorOfSelection() { + SystemXMLElementWrapper selectedElement = treeView.getSelectedElement(); + if (selectedElement != null) { + String vendor = selectedElement.getVendor(); + if ((vendor != null) && (vendor.length() > 0)) return vendor; + } + return null; + } + + /** + * Return true if changes are pending in the edit pane + */ + public boolean areChangesPending() { + return sm.areChangesPending(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDTypeDialog.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDTypeDialog.java new file mode 100644 index 00000000000..fcb293bf345 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemWorkWithUDTypeDialog.java @@ -0,0 +1,432 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.ResourceBundle; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.ui.ISystemMessages; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.SystemResources; +import org.eclipse.rse.ui.SystemWidgetHelpers; +import org.eclipse.rse.ui.dialogs.SystemPromptDialog; +import org.eclipse.rse.ui.widgets.ISystemEditPaneStates; +import org.eclipse.rse.ui.widgets.SystemEditPaneStateMachine; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; + +/** + * A dialog that allows the user to manipulate their user defined actions for a given subsystem factory. + *

+ */ +public class SystemWorkWithUDTypeDialog extends SystemPromptDialog implements ISystemUDWorkWithDialog, ISystemMessages, Listener, Runnable, ISystemUDAEditPaneHoster { + protected Shell shell; // shell hosting this viewer + protected ResourceBundle rb; + protected ISubSystem subsystem; + protected ISubSystemConfiguration subsystemFactory; + protected ISystemProfile profile; + protected SystemUDTypeEditPane editpane; + protected Button applyButton, revertButton; + protected SystemEditPaneStateMachine sm; + protected SystemUDTypeTreeView treeView; + private String typeToPreSelect; + private String currentType; + private int preSelectTypeDomain; + private int currentDomain = -1; + private Object objectToPreSelect; + private String domainToPreExpand; + + /** + * Constructor when we have a subsystem + */ + public SystemWorkWithUDTypeDialog(Shell shell, ISubSystem ss) { + super(shell, SystemUDAResources.RESID_WORKWITH_UDT_TITLE); + setCancelButtonLabel(SystemResources.BUTTON_CLOSE); + setShowOkButton(false); + this.shell = shell; + this.subsystem = ss; + this.subsystemFactory = subsystem.getSubSystemConfiguration(); + this.profile = subsystem.getSystemProfile(); + setOutputObject(null); + //setMinimumSize(550, 300); // x, y + setHelp(); + } + + /** + * Constructor when we have a subsystem factory and profile + */ + public SystemWorkWithUDTypeDialog(Shell shell, ISubSystemConfiguration ssFactory, ISystemProfile profile) { + super(shell, SystemUDAResources.RESID_WORKWITH_UDT_TITLE); + setCancelButtonLabel(SystemResources.BUTTON_CLOSE); + setShowOkButton(false); + this.shell = shell; + this.subsystemFactory = ssFactory; + this.profile = profile; + setOutputObject(null); + //setMinimumSize(550, 300); // x, y + setHelp(); + } + + /** + * Overridable extension point for setting dialog help + */ + protected void setHelp() { + setHelp(RSEUIPlugin.HELPPREFIX + "wwnt0000"); //$NON-NLS-1$ + } + + /** + * Set a type to preselect in the dialog. + * If domains are supported, specify the domain number, else + * pass -1. + */ + public void preSelectType(int domain, String type) { + this.preSelectTypeDomain = domain; + this.typeToPreSelect = type; + } + + /** + * @see SystemPromptDialog#getInitialFocusControl() + */ + protected Control getInitialFocusControl() { + return treeView.getControl(); + } + + /** + * @see SystemPromptDialog#createInner(Composite) + */ + protected Control createInner(Composite parent) { + // Inner composite + int nbrColumns = 2; + Composite composite = SystemWidgetHelpers.createComposite(parent, nbrColumns); + // create tree view on left + if (subsystem != null) + treeView = new SystemUDTypeTreeView(composite, this, subsystem); + else + treeView = new SystemUDTypeTreeView(composite, this, subsystemFactory, profile); + Control c = treeView.getControl(); + //c.setToolTipText(SystemUDAResources.RESID_UDA_TREE_TIP)); it is too annoying + GridData data = (GridData) c.getLayoutData(); + if (data == null) data = new GridData(); + data.grabExcessHorizontalSpace = false; + data.horizontalAlignment = GridData.FILL; + data.grabExcessVerticalSpace = true; + data.verticalAlignment = GridData.FILL; + data.widthHint = 140; // 150, or 170 + data.heightHint = publicConvertHeightInCharsToPixels(12); // high enough to show 12 entries + c.setLayoutData(data); + // we want the tree view on the left to extend to the bottom of the page, so on the right + // we create a 1-column composite that will hold the edit pane on top, and the apply/revert + // buttons on the bottom... + Composite rightSideComposite = SystemWidgetHelpers.createFlushComposite(composite, 1); + // now populate top of right-side composite with edit pane... + //editpane = new SystemUDTypeEditPane( subsystem, this, treeView); + //if (subsystem!=null) + // editpane = getUDActionSubsystem().getCustomUDTypeEditPane( subsystem, this, treeView); + //else + // editpane = getUDActionSubsystem().getCustomUDTypeEditPane( subsystemFactory, profile, this, treeView); + editpane = getUDActionSubsystem().getCustomUDTypeEditPane(subsystem, subsystemFactory, profile, this, treeView); + editpane.createContents(rightSideComposite); + // now add a visual separator line + addSeparatorLine(rightSideComposite, 1); + // now populate bottom of right-side composite with apply/revert buttons within their own composite + int nbrColumns_buttonComposite = 4; + Composite applyResetButtonComposite = SystemWidgetHelpers.createFlushComposite(rightSideComposite, nbrColumns_buttonComposite); + //((GridData)applyResetButtonComposite.getLayoutData()).horizontalIndent = 200; // shift buttons to the right + // now populate the buttons composite with apply and revert buttons + Label filler = SystemWidgetHelpers.createLabel(applyResetButtonComposite, ""); //$NON-NLS-1$ + ((GridData) filler.getLayoutData()).grabExcessHorizontalSpace = true; + ((GridData) filler.getLayoutData()).horizontalAlignment = GridData.FILL; + applyButton = SystemWidgetHelpers.createPushButton(applyResetButtonComposite, this, SystemUDAResources.RESID_UDA_APPLY_BUTTON_LABEL, SystemUDAResources.RESID_UDA_APPLY_BUTTON_TOOLTIP); + //applyButton.setImage(RSEUIPlugin.getDefault().getImage(ISystemConstants.ICON_SYSTEM_OK_ID)); + revertButton = SystemWidgetHelpers.createPushButton(applyResetButtonComposite, this, SystemUDAResources.RESID_UDA_REVERT_BUTTON_LABEL, SystemUDAResources.RESID_UDA_REVERT_BUTTON_TOOLTIP); + // now add a spacer to soak up left-over height... + addGrowableFillerLine(rightSideComposite, 1); + // add state machine to edit pane + sm = new SystemEditPaneStateMachine(rightSideComposite, applyButton, revertButton); + editpane.setStateMachine(sm); + composite.layout(true); + rightSideComposite.setVisible(false); + // if we have been given a type to preselect, do so now... + //System.out.println("typeToPreSelect = " + typeToPreSelect); + if (typeToPreSelect != null) { + SystemUDTypeManager udtm = getUDActionSubsystem().getUDTypeManager(); + SystemUDTypeElement type = null; + if (preSelectTypeDomain >= 0) { + domainToPreExpand = getUDActionSubsystem().mapDomainXlatedName(preSelectTypeDomain); + //treeView.expandDomainNode(domainToPreExpand); + } + // add listeners, after expansion... + treeView.addSelectionChangedListener(editpane); + type = (SystemUDTypeElement) udtm.findByName(null, typeToPreSelect, preSelectTypeDomain); + if (type != null) objectToPreSelect = type; + } else { + //treeView.expandDomainNodes(); + // add listeners, after expansion... + treeView.addSelectionChangedListener(editpane); + } + //System.out.println("Test1"); + treeView.getShell().getDisplay().asyncExec(this); + //System.out.println("Test2"); + return composite; + } + + /** + * Intercept of parent so we can reset the default button + */ + protected void createButtonsForButtonBar(Composite parent) { + super.createButtonsForButtonBar(parent); + getShell().setDefaultButton(applyButton); // defect 46129 + } + + /** + * Return the user defined action subsystem + */ + protected SystemUDActionSubsystem getUDActionSubsystem() { + /* FIXME - UDA not coupled with subsystem API anymore + if (subsystem!=null) + return subsystem.getUDActionSubsystem(); + else + { + return ((ISubsystemFactoryAdapter)subsystemFactory.getAdapter(ISubsystemFactoryAdapter.class)).getActionSubSystem(subsystemFactory, null); + + } + */ + return null; + } + + /** + * Parent override. + * Called when user presses CLOSE button. + * If we exit, then we set the dialog's output object to be the + * name of the selected type. + */ + protected boolean processCancel() { + if (sm.isSaveRequired()) { + if (!editpane.validateInput(true, null)) { + sm.setChangesMade(); // defect 45773 + return false; // pending errors. Cannot save, so cannot close! + } + editpane.saveData(); + } + currentType = treeView.getSelectedTypeName(); + if (currentType.length() > 0) setOutputObject(currentType); + currentDomain = treeView.getSelectedTypeDomain(); + return super.processCancel(); + } + + /** + * Get the name of the type that was selected at the time we left + */ + public String getSelectedTypeName() { + return currentType; + } + + /** + * Get the domain of the type that was selected at the time we left + */ + public int getSelectedTypeDomain() { + return currentDomain; + } + + /** + * Override of parent method so we can direct it to the Apply button versus the OK button + */ + public void setPageComplete(boolean complete) { + if (applyButton != null) { + if (!complete) applyButton.setEnabled(false); + // else: we never enable it because the state machine does that anyway on any user-input change + } + } + + /** + * Return true if currently selected type is "ALL" + */ + protected boolean isAllTypeSelected() { + return treeView.getSelectedTypeName().equals("ALL"); //$NON-NLS-1$ + } + + /** + * Return true if currently selected type is vendor supplied + */ + protected boolean isSelectionVendorSupplied() { + return treeView.isSelectionVendorSupplied(); + } + + /** + * Return the vendor that is responsible for pre-supplying this existing type, + * or null if not applicable. + */ + protected String getVendorOfSelection() { + return treeView.getVendorOfSelection(); + } + + /** + * Handles events generated by controls on this page. + */ + public void handleEvent(Event e) { + clearMessage(); + Widget source = e.widget; + if (source == applyButton) { + processApply(); + } else if (source == revertButton) { + processRevert(); + } + } + + /** + * Process the apply button + */ + public void processApply() { + editpane.applyPressed(); + } + + /** + * Process the revert button + */ + public void processRevert() { + editpane.revertPressed(); + } + + // --------------- + // HELPER METHODS + // --------------- + /** + * Expose inherited protected method convertWidthInCharsToPixels as a publicly + * excessible method + */ + public int publicConvertWidthInCharsToPixels(int chars) { + return convertWidthInCharsToPixels(chars); + } + + /** + * Expose inherited protected method convertHeightInCharsToPixels as a publicly + * excessible method + */ + public int publicConvertHeightInCharsToPixels(int chars) { + return convertHeightInCharsToPixels(chars); + } + + // ----------------------------------- + // ISystemUDWorkWithDialog methods... + // ----------------------------------- + /** + * Decide if we can do the delete or not. + * Will decide the enabled state of the delete action. + */ + public boolean canDelete(Object selectedObject) { + return (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isSelectionVendorSupplied(); + } + + /** + * Decide if we can do the move up or not. + * Will decide the enabled state of the move up action. + */ + public boolean canMoveUp(Object selectedObject) { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isAllTypeSelected(); + if (can) { + TreeItem selectedItem = treeView.getSelectedTreeItem(); + TreeItem parentItem = selectedItem.getParentItem(); + if (parentItem != null) + can = (parentItem.getItems()[0] != selectedItem); + else // this means we don't have domains + { + TreeItem[] roots = treeView.getTree().getItems(); + for (int idx = 0; idx < roots.length; idx++) { + if (roots[idx].getData() instanceof SystemXMLElementWrapper) { + can = (roots[idx] != selectedItem); + break; + } + } + } + } + return can; + } + + /** + * Decide if we can do the move down or not. + * Will decide the enabled state of the move down action. + */ + public boolean canMoveDown(Object selectedObject) { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isAllTypeSelected(); + if (can) { + TreeItem selectedItem = treeView.getSelectedTreeItem(); + TreeItem parentItem = selectedItem.getParentItem(); + if (parentItem != null) + can = (parentItem.getItems()[parentItem.getItemCount() - 1] != selectedItem); + else // this means we don't have domains + { + TreeItem[] roots = treeView.getTree().getItems(); + can = (roots[roots.length - 1] != selectedItem); + } + } + return can; + } + + /** + * Decide if we can do the copy or not. + * Will decide the enabled state of the copy action. + */ + public boolean canCopy(Object selectedObject) { + boolean can = (sm.getMode() == ISystemEditPaneStates.MODE_EDIT) && !sm.areChangesPending() && !isAllTypeSelected(); + return can; + } + + /** + * For AsyncExec. + * Do selection, after tree is created + */ + public void run() { + // check it out! This run method executes multiple times even though it is only called once!!! + //System.out.println("Test1"); + if (domainToPreExpand != null) + treeView.expandDomainNode(domainToPreExpand); + else + treeView.expandDomainNodes(); + //System.out.println("Test2"); + //if (true) + // return; // for debugging + if (objectToPreSelect != null) { + if (objectToPreSelect instanceof SystemXMLElementWrapper) + treeView.selectElement((SystemXMLElementWrapper) objectToPreSelect); + else { + ISelection selection = new StructuredSelection(objectToPreSelect); + treeView.setSelection(selection, true); + } + } else + //else if (treeView.getTree().getSelectionCount() == 0) + { + objectToPreSelect = (treeView.getTree().getItems()[0]).getData(); + ISelection selection = new StructuredSelection(objectToPreSelect); + //System.out.println("Test5"); + treeView.setSelection(selection, true); + //System.out.println("Test6"); + } + } + + /** + * Return true if changes are pending in the edit pane + */ + public boolean areChangesPending() { + return sm.areChangesPending(); + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemXMLElementWrapper.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemXMLElementWrapper.java new file mode 100644 index 00000000000..a8b29da43e3 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/SystemXMLElementWrapper.java @@ -0,0 +1,524 @@ +package org.eclipse.rse.useractions.ui.uda; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.swt.graphics.Image; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +/** + * This is a base class for classes that wrapper xml elements. + * Eg, there are child classes to represent action xml elements, and + * type xml elements. + */ +public abstract class SystemXMLElementWrapper implements IAdaptable, ISystemUDAConstants { + //parameters + protected Element elm; + private boolean isDomainElement; + private SystemUDBaseManager database; // For setChanged() + private ISystemProfile profile; + private int domainType; + // constants + /** + * What we store in XML document for TRUE + */ + private static final String XML_TRUE = "True"; //$NON-NLS-1$ + /** + * What we store in XML document for FALSE + */ + private static final String XML_FALSE = "False"; //$NON-NLS-1$ + /** + * The XML attribute name for the "IBM-Supplied" attribute + */ + private static final String XML_ATTR_VENDOR = "Vendor"; //$NON-NLS-1$ + /** + * The XML attribute name for the "User-Changed" attribute + */ + private static final String XML_ATTR_CHANGED = "UserChanged"; //$NON-NLS-1$ + /** + * The value we place in the Vendor attribute for IBM-supplied actions/types + */ + private static final String VENDOR_IBM = "IBM"; + + /** + * Constructor + * @param elm - The actual xml document element for this action/type + * @param mgr - The parent manager of these actions/types + * @param profile - The system profile which owns this action + * @param domainType - The integer representation of the domain this is in (or this is, for a domain element) + */ + public SystemXMLElementWrapper(Element elm, SystemUDBaseManager mgr, ISystemProfile profile, int domainType) { + super(); + this.elm = elm; + this.isDomainElement = elm.getTagName().equals(XE_DOMAIN); + this.domainType = domainType; + database = mgr; + this.profile = profile; + } + + // ---------------------------------- + // METHODS THAT MUST BE OVERRIDDEN... + // ---------------------------------- + protected abstract String getTagName(); + + public abstract Image getImage(); + + // ------------------------------------- + // + // ------------------------------------- + /** + * Convert to a string + * Same as calling getName + */ + public String toString() { + return getName(); + } + + /** + * As required by the IAdaptable interface. + * @see IAdaptable#getAdapter(Class) + */ + public Object getAdapter(Class adapterType) { + return Platform.getAdapterManager().getAdapter(this, adapterType); + } + + /** + * Get the profile this is associated with + */ + public ISystemProfile getProfile() { + return profile; + } + + /** + * Get the manager that manages the document this element is part of. + */ + public SystemUDBaseManager getManager() { + return database; + } + + /** + * Get the XML document element this node wraps + */ + public Element getElement() { + return elm; + } + + /** + * Get the document this element is a part of + */ + public Document getDocument() { + // this method added by phil. + // this allows getChildren in xxxmanager classes to avoid deducing the document + return elm.getOwnerDocument(); + } + + /** + * Get the parent xml domain element of this element. + * If domains aren't supported, this will return null + */ + public Element getParentDomainElement() { + Element parent = getParentElement(); + if ((parent != null) && parent.getTagName().equals(XE_DOMAIN)) + return parent; + else + return null; + } + + /** + * Get the parent xml element of this element. + * Only returns null if this is the root, which should never happen. + */ + public Element getParentElement() { + Node parent = elm.getParentNode(); + if (parent instanceof Element) + return (Element) parent; + else + return null; + } + + /** + * Is this a "Domain" tag? + */ + public boolean isDomain() { + return isDomainElement; + } + + /** + * Return the domain this element is in, or represents if it is a domain element itself. + * This is the integer representation used internally. + * Will be -1 if domains not supported for this subsystem. + */ + public int getDomain() { + return domainType; + } + + /** + * Return the value of this node's "Name" attribute + */ + public String getName() { + return elm.getAttribute(NAME_ATTR); + } + + /** + * Set the value of this tag's "Name" attribute. + * If this is an IBM-supplied user action, then it will cause an addition attribute to + * be created named "OriginalName", containing the IBM-supplied name. + */ + public void setName(String s) { + if (isIBM()) { + String orgName = elm.getAttribute(ORIGINAL_NAME_ATTR); + if ((orgName != null) && (orgName.length() > 0)) { + // no need to do anything, as its already set. + } else + elm.setAttribute(ORIGINAL_NAME_ATTR, getName()); + } + setAttribute(NAME_ATTR, s); + setUserChanged(true); + } + + /** + * For IBM-supplied elements that have been edited, returns the original IBM-supplied name + */ + public String getOriginalName() { + String s = elm.getAttribute(ORIGINAL_NAME_ATTR); + if ((s == null) || (s.length() == 0)) + return getName(); + else + return s; + } + + /** + * Return the value of this node's "IBM" attribute. + * That is, is this an IBM-supplied tag? + */ + public boolean isIBM() { + String vendor = elm.getAttribute(XML_ATTR_VENDOR); + if (vendor == null) + return false; + else + return vendor.equals(VENDOR_IBM); + } + + /** + * Set the name of the vendor who supplied this user action or type + */ + public void setVendor(String vendor) { + setAttribute(XML_ATTR_VENDOR, vendor); + } + + /** + * Get the name of the vendor who supplied this user action or type. + * May be null, if created by a user + */ + public String getVendor() { + return elm.getAttribute(XML_ATTR_VENDOR); + } + + /** + * Set the value of this tag's "Vendor" attribute to "IBM", + * or clear the IBM attribute (after a duplication action for example). + */ + public void setIBM(boolean isFromIBM) { + if (isFromIBM) + setAttribute(XML_ATTR_VENDOR, VENDOR_IBM); + else + setAttribute(XML_ATTR_VENDOR, null); + } + + /** + * Return the value of this node's "user-changed" attribute. + * That is, if this an IBM-supplied tag, has the user changed it? + */ + public boolean isUserChanged() { + boolean changed = false; + if (!isIBM()) + changed = true; + else if (isDomainElement) + changed = false; + else + changed = getBooleanAttribute(XML_ATTR_CHANGED, false); + //System.out.println("Inside isUserChanged, returning "+changed+": isIBM()="+isIBM()+", isDomainElement="+isDomainElement); + return changed; + } + + /** + * Set the value of this tag's "user-changed" attribute + */ + public void setUserChanged(boolean isUserChanged) { + if (isIBM() && !isDomainElement) setBooleanAttribute(XML_ATTR_CHANGED, isUserChanged); + } + + /** + * Delete this element from the document + */ + public void deleteElement() { + // Not intended for root. Only for Actions + elm.getParentNode().removeChild(elm); + } + + // -------------------------- + // INTERNAL HELPER METHODS... + // -------------------------- + /** + * Given the name of a child xml tag, return the data for that tag + */ + protected String getTextNode(String tagname) { + Element tag = getChildTag(tagname, false); + if (null != tag) { + Node n = tag.getFirstChild(); + if (null != n) { + if (n instanceof Text) { + Text tn = (Text) n; + return tn.getData(); + } + } + } + return ""; //$NON-NLS-1$ + } + + /** + * Given the name of a child xml tag and a data value, + * update the data of that tag + */ + protected void setTextNode(String tagname, String val) { + Element tag = getChildTag(tagname, true); + if (null != tag) { + database.setChanged(profile); + // ?? Loop on all children, removing? + Node n = tag.getFirstChild(); + if (null != n) { + if (n instanceof Text) { + Text tn = (Text) n; + tn.setData(val); + return; + } + // ?? Loop on all children, removing? + tag.removeChild(n); + } + tag.appendChild(elm.getOwnerDocument().createTextNode(val)); + return; + } + } + + /** + * Given a tag name, return the xml node for that child tag + * @param tagname - the name of the tag to find + * @param create - true if tag is to be created if not found + */ + protected Element getChildTag(String tagname, boolean create) { + NodeList subList = elm.getChildNodes(); + if (null != subList) { + for (int i = 0; i < subList.getLength(); i++) { + Node sn = subList.item(i); + if (sn instanceof Element) { + Element se = (Element) sn; + if (tagname.equals(se.getTagName())) return se; + } + } + } + if (create) { + Element newchild = elm.getOwnerDocument().createElement(tagname); + elm.appendChild(newchild); + return newchild; + } + return null; + } + + /** + * Set the value of a boolean attribute + */ + public void setBooleanAttribute(String attr, boolean b) { + elm.setAttribute(attr, (b) ? XML_TRUE : XML_FALSE); + database.setChanged(profile); + } + + /** + * Return the boolean value of a given attribute. It must exist! + * @param attr - name of the attribute to query + */ + public boolean getBooleanAttribute(String attr) { + String val = elm.getAttribute(attr); + if (XML_TRUE.equals(val)) return true; + return false; + } + + /** + * Return the boolean value of a given attribute. + * @param attr - name of the attribute to query + * @param defaultValue - value to return if the attribute is not found + */ + public boolean getBooleanAttribute(String attr, boolean defaultValue) { + String val = elm.getAttribute(attr); + if (val == null) return defaultValue; + if (XML_TRUE.equals(val)) return true; + return false; + } + + /** + * Set the text value of the given attribute. + * Specify a default value to return if the attribute is not found + */ + public String getAttribute(String attr, String defaultValue) { + String value = elm.getAttribute(attr); + if (value == null) value = defaultValue; + return value; + } + + /** + * Set the text value of the given attribute to a given value + */ + public void setAttribute(String attr, String value) { + if (value != null) + elm.setAttribute(attr, value); + else + elm.removeAttribute(attr); + database.setChanged(profile); + } + + /** + * For unique-name checking. + * If this is a domain element, returns all child action names. + * If this is an action/tag element, returns all sibling action names, minus this one. + * Always returns a non-null vector, although it may be empty + */ + public Vector getExistingNames() { + Element parentElement = null; + String currName = null; + if (isDomain()) + parentElement = this.getElement(); + else { + parentElement = getParentElement(); + currName = getName(); + } + Vector nameList = getExistingNames(parentElement, getDocument()); + if (currName != null) nameList.remove(currName); + return nameList; + } + + /** + * For unique-name checking. + * Given a parent element XML node, returns all child action names. + * Always returns a non-null vector, although it may be empty + */ + public Vector getExistingNames(Element parentElement, Document xdoc) { + return getExistingNames(parentElement, xdoc, getTagName()); + } + + /** + * For unique-name checking. + * Given a parent element XML node, returns all child action names. + * Always returns a non-null vector of Strings, although it may be empty + */ + public static Vector getExistingNames(Element parentElement, Document xdoc, String tagName) { + Vector nameList = new Vector(); + Element se = null; + NodeList subList = null; + if (parentElement != null) + subList = parentElement.getChildNodes(); + else + subList = xdoc.getElementsByTagName(tagName); + if (subList != null) { + for (int idx = 0; idx < subList.getLength(); idx++) { + Node sn = subList.item(idx); + if (sn instanceof Element) { + se = (Element) sn; + if (se.getTagName().equals(tagName)) { + nameList.add(se.getAttribute(NAME_ATTR)); + } + } + } // end for all subnodes + } // end if sublist != null + return nameList; + } + + /** + * Returns element wrappers of children (if this is a domain) or siblings + */ + public Vector getChildren(Vector children, ISystemProfile profile) { + Element parentElement = null; + if (isDomain()) + parentElement = this.getElement(); + else + parentElement = getParentElement(); + children = getChildren(children, parentElement, getDocument(), profile); + return children; + } + + /** + * Given a parent element XML node, returns wrappers of all child tags of which we are interested + * Always returns a non-null vector, although it may be empty + */ + public Vector getChildren(Vector children, Element parentElement, Document xdoc, ISystemProfile profile) { + return getChildren(children, parentElement, xdoc, profile, database, getDomain()); + } + + /** + * Given a parent element XML node, returns wrappers all child tag elements with the given tag name + * Always returns a non-null vector, although it may be empty. + * If the parentElement is null, uses the roots of the given document. Should only be true if domains not supported! + * @return Vector of SystemXMLElementWrapper objects + */ + public static Vector getChildren(Vector children, Element parentElement, Document xdoc, ISystemProfile profile, ISystemXMLElementWrapperFactory factory, int domain) { + if (children == null) children = new Vector(); + String tagName = factory.getTagName(); + Element se = null; + NodeList subList = null; + if (parentElement != null) + subList = parentElement.getChildNodes(); + else + subList = xdoc.getElementsByTagName(tagName); + if (subList != null) { + for (int idx = 0; idx < subList.getLength(); idx++) { + Node sn = subList.item(idx); + if (sn instanceof Element) { + se = (Element) sn; + if (se.getTagName().equals(tagName)) { + children.add(factory.createElementWrapper(se, profile, domain)); + } + } + } // end for all subnodes + } // end if sublist != null + return children; + } + + /** + * For unique-name checking. + * Given a parent element XML node, returns the xml Element node with the given name attribute, + * or null if not found. + */ + public static Element findChildByName(Element parentElement, Document xdoc, String tagName, String searchName) { + Element match = null; + NodeList subList = null; + if (parentElement != null) + subList = parentElement.getChildNodes(); + else + subList = xdoc.getElementsByTagName(tagName); + if (subList != null) { + for (int idx = 0; (match == null) && (idx < subList.getLength()); idx++) { + Node sn = subList.item(idx); + if (sn instanceof Element) { + if (((Element) sn).getTagName().equals(tagName)) { + if (((Element) sn).getAttribute(NAME_ATTR).equals(searchName)) match = (Element) sn; + } + } + } // end for all subnodes + } // end if sublist != null + return match; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithFileTypesAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithFileTypesAction.java new file mode 100644 index 00000000000..c75825266e4 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithFileTypesAction.java @@ -0,0 +1,156 @@ +package org.eclipse.rse.useractions.ui.uda.actions; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.internal.ui.view.team.SystemTeamViewSubSystemConfigurationNode; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseDialogAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.rse.useractions.ui.uda.SystemWorkWithUDTypeDialog; +import org.eclipse.swt.widgets.Shell; + +/** + * The action that displays the Work With File Types GUI + */ +public class SystemWorkWithFileTypesAction extends SystemBaseDialogAction { + private ISubSystem subsystem = null; + private ISubSystemConfiguration subsystemFactory = null; + private ISystemProfile profile; + private SystemWorkWithUDTypeDialog ourDlg = null; + private String typeToPreSelect = null; + private int preSelectTypeDomain; + private String outputSelectedType; + private int outputSelectedDomain = -1; + + /** + * Constructor when we have a subsystem + * @param parent The Shell of the parent UI for this dialog + * @param subSystem The subsystem we are launching this from/for + */ + public SystemWorkWithFileTypesAction(Shell parent, ISubSystem subSystem) { + this(parent); + this.subsystem = subSystem; + if (subsystem != null) { + this.subsystemFactory = subsystem.getSubSystemConfiguration(); + this.profile = subsystem.getSystemProfile(); + } + setAvailableOffline(true); + } + + /** + * Constructor when we have a subsystem factory and profile + * @param parent The Shell of the parent UI for this dialog + * @param subSystemFactory The subsystem factory we are launching this from/for + * @param profile The profile we are launching this from/for + */ + public SystemWorkWithFileTypesAction(Shell parent, ISubSystemConfiguration subSystemFactory, ISystemProfile profile) { + this(parent); + this.subsystemFactory = subSystemFactory; + this.profile = profile; + } + + /** + * Constructor when we don't have anything + * At run time, the input is deduced from the first selected object. + * @param parent The Shell of the parent UI for this dialog + */ + public SystemWorkWithFileTypesAction(Shell parent) { + super(SystemUDAResources.ACTION_WORKWITH_NAMEDTYPES_LABEL, SystemUDAResources.ACTION_WORKWITH_NAMEDTYPES_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_WORKWITHNAMEDTYPES_ID), parent); + allowOnMultipleSelection(false); + setContextMenuGroup(ISystemContextMenuConstants.GROUP_WORKWITH); + setHelp(RSEUIPlugin.HELPPREFIX + "actn0046"); //$NON-NLS-1$ + } + + /** + * Set a type to preselect in the dialog. + * If domains are supported, specify the domain number, else + * pass -1. + */ + public void preSelectType(int domain, String type) { + this.typeToPreSelect = type; + this.preSelectTypeDomain = domain; + } + + /** + * Called by SystemBaseAction when selection is set. + * Our opportunity to verify we are allowed for this selected type. + */ + public boolean checkObjectType(Object selectedObject) { + return true; + } + + /** + * If you decide to use the supplied run method as is, + * then you must override this method to create and return + * the dialog that is displayed by the default run method + * implementation. + *

+ * If you override run with your own, then + * simply implement this to return null as it won't be used. + * @see #run() + */ + protected Dialog createDialog(Shell parent) { + if ((subsystem == null) && (getFirstSelection() instanceof ISubSystem)) + subsystem = (ISubSystem) getFirstSelection(); + else if (getFirstSelection() instanceof SystemTeamViewSubSystemConfigurationNode) { + SystemTeamViewSubSystemConfigurationNode ssfNode = (SystemTeamViewSubSystemConfigurationNode) getFirstSelection(); + subsystemFactory = ssfNode.getSubSystemConfiguration(); + profile = ssfNode.getProfile(); + } + if (subsystem != null) + ourDlg = new SystemWorkWithUDTypeDialog(parent, subsystem); + else + ourDlg = new SystemWorkWithUDTypeDialog(parent, subsystemFactory, profile); + if (typeToPreSelect != null) ourDlg.preSelectType(preSelectTypeDomain, typeToPreSelect); + return ourDlg; + } + + /** + * Required by parent. After the dialog closes, its output + * object contains the type that was selected at the time + * of the close. This might be of interest to someone, so + * we scoop it out here, and return it in the + * getSelectedTypeName() method. + */ + protected Object getDialogValue(Dialog dlg) { + outputSelectedType = ((SystemWorkWithUDTypeDialog) dlg).getSelectedTypeName(); + if ((outputSelectedType != null) && (outputSelectedType.length() == 0)) outputSelectedType = null; + return outputSelectedType; + } + + /** + * Return the name of the type that was selected at the + * time of exiting the dialog. Might be null! + */ + public String getSelectedTypeName() { + outputSelectedType = ourDlg.getSelectedTypeName(); + //System.out.println("outputSelectedType = " + outputSelectedType); + if ((outputSelectedType != null) && (outputSelectedType.length() == 0)) outputSelectedType = null; + return outputSelectedType; + } + + /** + * Return the domain of the type that was selected at the + * time of exiting the dialog. Might be -1! + */ + public int getSelectedTypeDomain() { + outputSelectedDomain = ourDlg.getSelectedTypeDomain(); + //System.out.println("outputSelectedDomain = " + outputSelectedDomain); + return outputSelectedDomain; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithUDAsAction.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithUDAsAction.java new file mode 100644 index 00000000000..c25a0bd4aa2 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/actions/SystemWorkWithUDAsAction.java @@ -0,0 +1,170 @@ +package org.eclipse.rse.useractions.ui.uda.actions; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +//import java.util.Iterator; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.core.model.ISystemProfile; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.core.subsystems.ISubSystemConfiguration; +import org.eclipse.rse.internal.ui.view.team.SystemTeamViewSubSystemConfigurationNode; +import org.eclipse.rse.ui.ISystemContextMenuConstants; +import org.eclipse.rse.ui.ISystemIconConstants; +import org.eclipse.rse.ui.RSEUIPlugin; +import org.eclipse.rse.ui.actions.SystemBaseDialogAction; +import org.eclipse.rse.useractions.ui.uda.SystemUDAResources; +import org.eclipse.rse.useractions.ui.uda.SystemWorkWithUDAsDialog; +import org.eclipse.swt.widgets.Shell; + +/** + * The action that displays the Work With User-Defined Actions GUI + */ +public class SystemWorkWithUDAsAction extends SystemBaseDialogAction { + private ISubSystem subsystem = null; + private ISubSystemConfiguration subsystemFactory = null; + private ISystemProfile profile; + + /** + * Constructor when starting with a subsystem (such as in RS view) + * @param parent The Shell of the parent UI for this dialog + * @param subSystem The subsystem we are launching this from/for + */ + public SystemWorkWithUDAsAction(Shell parent, ISubSystem subSystem) { + this(parent); + setSubSystem(subSystem); + setAvailableOffline(true); + } + + /** + * Constructor when starting with a subsystem factory (such as in Team view) + * @param parent The Shell of the parent UI for this dialog + * @param subSystemFactory The subsystem factory we are launching this from/for + */ + public SystemWorkWithUDAsAction(Shell parent, ISubSystemConfiguration subSystemFactory, ISystemProfile profile) { + this(parent); + setSubSystemFactory(subsystemFactory, profile); + } + + /** + * Constructor when we don't have anything. + * At run time, the input is deduced from the first selected object. + * @param parent The Shell of the parent UI for this dialog + */ + public SystemWorkWithUDAsAction(Shell parent) { + super(SystemUDAResources.ACTION_WORKWITH_UDAS_LABEL, SystemUDAResources.ACTION_WORKWITH_UDAS_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_WORKWITHUSERACTIONS_ID), parent); + allowOnMultipleSelection(false); + setContextMenuGroup(ISystemContextMenuConstants.GROUP_WORKWITH); + setHelp(RSEUIPlugin.HELPPREFIX + "actn0045"); //$NON-NLS-1$ + } + + /** + * Constructor when we don't have anything, and we want to choose between "Work with->User Actions" and "Work With User Actions". + * At run time, the input is deduced from the first selected object. + * @param parent The Shell of the parent UI for this dialog + * @param fromCascadingCompileAction true to get "Work with Compile Commands" label, false to get "Compile Commands" label. + */ + public SystemWorkWithUDAsAction(Shell parent, boolean fromCascadingCompileAction) { + super(fromCascadingCompileAction ? SystemUDAResources.ACTION_WORKWITH_WWUDAS_LABEL : SystemUDAResources.ACTION_WORKWITH_UDAS_LABEL, + fromCascadingCompileAction ? SystemUDAResources.ACTION_WORKWITH_WWUDAS_TOOLTIP : SystemUDAResources.ACTION_WORKWITH_UDAS_TOOLTIP, RSEUIPlugin.getDefault().getImageDescriptor( + ISystemIconConstants.ICON_SYSTEM_WORKWITHUSERACTIONS_ID), parent); + allowOnMultipleSelection(false); + if (!fromCascadingCompileAction) + setContextMenuGroup(ISystemContextMenuConstants.GROUP_WORKWITH); + else + setContextMenuGroup(ISystemContextMenuConstants.GROUP_REORGANIZE); + setHelp(RSEUIPlugin.HELPPREFIX + "actn0045"); //$NON-NLS-1$ + } + + /** + * Reset between runs + */ + public void reset() { + subsystem = null; + subsystemFactory = null; + profile = null; + } + + /** + * Set the subsystem which is the input to this action. You either call this, + * or setSubSystemFactory, or the input is deduced from the selection when the action is run. + */ + public void setSubSystem(ISubSystem subsystem) { + this.subsystem = subsystem; + if (subsystem != null) { + this.subsystemFactory = subsystem.getSubSystemConfiguration(); + this.profile = subsystem.getSystemProfile(); + } + } + + /** + * Set the subsystem factory and profile, which are the input to this action. You either call this, + * or setSubSystem, or the input is deduced from the selection when the action is run. + */ + public void setSubSystemFactory(ISubSystemConfiguration subsystemFactory, ISystemProfile profile) { + this.subsystemFactory = subsystemFactory; + this.profile = profile; + } + + /** + * Called by SystemBaseAction when selection is set. + * Our opportunity to verify we are allowed for this selected type. + */ + public boolean updateSelection(IStructuredSelection selection) { + boolean enable = true; + Object firstSelection = selection.getFirstElement(); + if (firstSelection instanceof SystemTeamViewSubSystemConfigurationNode) { + SystemTeamViewSubSystemConfigurationNode ssfNode = (SystemTeamViewSubSystemConfigurationNode) firstSelection; + subsystemFactory = ssfNode.getSubSystemConfiguration(); + profile = ssfNode.getProfile(); + enable = profile.isActive(); + } + return enable; + } + + /** + * If you decide to use the supplied run method as is, + * then you must override this method to create and return + * the dialog that is displayed by the default run method + * implementation. + *

+ * If you override run with your own, then + * simply implement this to return null as it won't be used. + * @see #run() + */ + protected Dialog createDialog(Shell parent) { + Object element = getFirstSelection(); + //System.out.println("First selection: "+element); + if ((subsystem == null) && (element instanceof ISubSystem)) { + subsystem = (ISubSystem) element; + } else if ((subsystemFactory == null) && (element instanceof SystemTeamViewSubSystemConfigurationNode)) { + SystemTeamViewSubSystemConfigurationNode ssfNode = (SystemTeamViewSubSystemConfigurationNode) element; + subsystemFactory = ssfNode.getSubSystemConfiguration(); + profile = ssfNode.getProfile(); + //System.out.println("Profile is: "+profile); + } + SystemWorkWithUDAsDialog dlg = null; + if (subsystem != null) + dlg = new SystemWorkWithUDAsDialog(parent, subsystem); + else + dlg = new SystemWorkWithUDAsDialog(parent, subsystemFactory, profile); + return dlg; + } + + /** + * Required by parent. We use it to return the new name. + * In our case, we don't need it, so we return null. + */ + protected Object getDialogValue(Dialog dlg) { + return null; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/MatchStr.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/MatchStr.java new file mode 100644 index 00000000000..9148336c476 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/MatchStr.java @@ -0,0 +1,97 @@ +package org.eclipse.rse.useractions.ui.uda.util; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.StringTokenizer; +import java.util.Vector; + +public class MatchStr { + private String matchStr; + private Vector mStrTokens; + private boolean splatAtEnd; + + public MatchStr(String p_matchStr) { + matchStr = p_matchStr; + StringTokenizer st = new StringTokenizer(matchStr, "*"); //$NON-NLS-1$ + int n = st.countTokens(); + mStrTokens = new Vector(); + for (int i = 0; i < n; i++) { + mStrTokens.addElement(st.nextToken()); + } + splatAtEnd = matchStr.charAt(matchStr.length() - 1) == '*'; + } + + public boolean isMatch(String str) { + if (str.indexOf("*") == 0) //$NON-NLS-1$ + { + str = str.substring(1); + } + if (mStrTokens.size() == 0) { + return true; + } + if (!str.startsWith((String) mStrTokens.elementAt(0))) { + return false; + } + if (!splatAtEnd) { + if (mStrTokens.size() == 1) { + return str.equals(mStrTokens.elementAt(0)); + } else if (!str.endsWith((String) mStrTokens.elementAt(mStrTokens.size() - 1))) { + return false; + } + } + int i = ((String) mStrTokens.elementAt(0)).length(); + int j = 1; + while (i < str.length() && j < mStrTokens.size()) { + String tempStr = str.substring(i); + if (tempStr.startsWith((String) mStrTokens.elementAt(j))) { + i = i + tempStr.length(); + j++; + } + i++; + } + return mStrTokens.size() == j; + } + /* public static void main(String[] args) + { + MatchStr matchStr = new MatchStr("AB*"); + + if (matchStr.isMatch("ABaasBdddd")) + { + System.out.println("true"); + } + else + { + System.out.println("false"); + } + + matchStr = new MatchStr("*"); + boolean one = matchStr.isMatch("lskda"); + boolean two = matchStr.isMatch(""); + boolean three = matchStr.isMatch("1"); + + + matchStr = new MatchStr("abc"); + boolean four = matchStr.isMatch("abcdabc"); + boolean five = matchStr.isMatch("abc"); + + + matchStr = new MatchStr("abc*"); + boolean six = matchStr.isMatch("abcdabc"); + boolean seven = matchStr.isMatch("abc"); + + + try { + System.in.read(); + } catch (Exception e) + { + } + }*/ +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAFileTypesForName.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAFileTypesForName.java new file mode 100644 index 00000000000..6854d6abf3d --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAFileTypesForName.java @@ -0,0 +1,29 @@ +package org.eclipse.rse.useractions.ui.uda.util; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +public class UDAFileTypesForName { + String name; + String types; + + public UDAFileTypesForName(String p_name, String p_types) { + name = p_name; + types = p_types; + } + + public String getName() { + return name; + } + + public String getTypes() { + return types; + } +} diff --git a/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAResolvedTypes.java b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAResolvedTypes.java new file mode 100644 index 00000000000..269c97c426b --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/src/org/eclipse/rse/useractions/ui/uda/util/UDAResolvedTypes.java @@ -0,0 +1,76 @@ +package org.eclipse.rse.useractions.ui.uda.util; + +/******************************************************************************* + * Copyright (c) 2002, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +import java.util.Vector; + +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeElement; +import org.eclipse.rse.useractions.ui.uda.SystemUDTypeManager; + +public class UDAResolvedTypes { + protected Vector previousTypes = null; + + public UDAResolvedTypes() { + previousTypes = null; + } + + protected void addTypesToVector(Vector v, Object[] objElems) { + for (int i = 0; i < objElems.length; i++) { + SystemUDTypeElement typeElem = (SystemUDTypeElement) objElems[i]; + String name = typeElem.toString(); + resolveType(name, v, objElems); + } + } + + protected String resolveTypes(String types, Vector v, Object[] objElems) { + int i = types.indexOf("<"); //$NON-NLS-1$ + if (i < 0) return types; + int j = types.indexOf(">"); //$NON-NLS-1$ + if (i >= j) return types; + String type = types.substring(i + 1, j); + String resolvedType = resolveType(type, v, objElems); + return types.substring(0, i) + " " + resolvedType + " " + resolveTypes(types.substring(j + 1), v, objElems); //$NON-NLS-1$ //$NON-NLS-2$ + } + + protected String resolveType(String type, Vector v, Object[] objElems) { + if (previousTypes.contains(type)) { + return ""; //$NON-NLS-1$ + } + String resolvedTypes = resolveType(type, v); + if (resolvedTypes != null) return resolvedTypes; + for (int i = 0; i < objElems.length; i++) { + SystemUDTypeElement typeElem = (SystemUDTypeElement) objElems[i]; + if (type.equals(typeElem.toString())) { + previousTypes.addElement(type); + resolvedTypes = resolveTypes(typeElem.getTypes(), v, objElems); + previousTypes.remove(type); + v.addElement(new UDAFileTypesForName(type, resolvedTypes)); + return resolvedTypes; + } + } + return ""; //$NON-NLS-1$ + } + + protected String resolveType(String type, Vector v) { + for (int i = 0; i < v.size(); i++) { + UDAFileTypesForName typesForName = (UDAFileTypesForName) v.elementAt(i); + if (type.equals(typesForName.getName())) { + return typesForName.getTypes(); + } + } + return null; + } + + public String getFileTypesForTypeName(String name, int type, SystemUDTypeManager typeMgr) { + // ?? Implement for non NFS types??? + return null; + } +}