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 @@
+
+
June 5, 2006
+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 00000000000..a13e02f6b22 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_export.gif differ 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 00000000000..5709c2ec8e1 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.importexport/icons/full/etool16/file_import.gif differ 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 @@ + + +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 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. null
is returned.
+ */
+ public SystemMessage getSystemErrorMessage() {
+ if (msgLine != null)
+ return msgLine.getSystemErrorMessage();
+ else
+ return null;
+ }
+
+ /**
+ * ISystemMessageLine method. 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.
+ *
+ * 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.
+ *
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.
+ *
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.
+ *
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 FileSystemElement
s 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 FileSystemElement
s 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 null
is returned.
+ */
+ public SystemMessage getSystemErrorMessage() {
+ if (msgLine != null)
+ return msgLine.getSystemErrorMessage();
+ else
+ return null;
+ }
+
+ /**
+ * ISystemMessageLine method. + * 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, oritem
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 @@ + +June 5, 2006
+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 00000000000..c7a0c3fc2fa Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibm_obj.gif differ 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 00000000000..1c277194b21 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_ibmuser_obj.gif differ diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_new_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_new_obj.gif new file mode 100644 index 00000000000..cfcaaea0098 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_new_obj.gif differ diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_user_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_user_obj.gif new file mode 100644 index 00000000000..25692da4b46 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/compcmd_user_obj.gif differ 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 00000000000..802d0ebe890 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_obj.gif differ 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 00000000000..15d6f4ba853 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_ibm_user_obj.gif differ 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 00000000000..b595eb20bf2 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_new_obj.gif differ 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 00000000000..556c0283633 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_action_obj.gif differ diff --git a/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_new_obj.gif b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_new_obj.gif new file mode 100644 index 00000000000..8055a95decb Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_new_obj.gif differ 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 00000000000..8d1885ba6d4 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_obj.gif differ 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 00000000000..19ef4a224c6 Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_ibm_user_obj.gif differ 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 00000000000..823609da24a Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_new_obj.gif differ 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 00000000000..2ecef415faf Binary files /dev/null and b/rse/plugins/org.eclipse.rse.useractions/icons/full/obj16/user_type_obj.gif differ diff --git a/rse/plugins/org.eclipse.rse.useractions/plugin.properties b/rse/plugins/org.eclipse.rse.useractions/plugin.properties new file mode 100644 index 00000000000..f8be0756925 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/plugin.properties @@ -0,0 +1,15 @@ +############################################################################### +# 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 + +plugin.name = RSE User Actions diff --git a/rse/plugins/org.eclipse.rse.useractions/plugin.xml b/rse/plugins/org.eclipse.rse.useractions/plugin.xml new file mode 100644 index 00000000000..4ab27f2e581 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.useractions/plugin.xml @@ -0,0 +1,32 @@ + + ++ * 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: + *
+ * 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
+ * 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
+ * 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:
+ *
+ * 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
+ * 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?
+ *
+ * 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:
+ *
+ * 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:
+ *
+ * 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=
+ * 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:
+ *
+ * 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.
+ * 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:
+ *
+ * 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
+ * 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
+ * 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:
+ *
+ * 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;
+ }
+}
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.
+ *
+ */
+ 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.
+ *
+ * return compileCmd.doVariableSubstitution(firstSelection, substitutor);
+ *
+ *
+ */
+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.
+ *
+ *
+ * Contractually, here are the methods called by the main page of the new filter wizard:
+ *
+ *
+ */
+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.
+ *
+ *
+ * @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.
+ *
+ *
+ */
+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.
+ *
+ *
+ * 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.
+ *
+ * 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.
+ *
+ *
+ * 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.
+ *
+ *
+ * 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
+ *
+ *
+ * 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.
+ * userActionContribution
,
+ * namedType
and userAction
.
+ *