summaryrefslogtreecommitdiff
path: root/java/management/eclipse-plugin/src
diff options
context:
space:
mode:
authorRafael H. Schloming <rhs@apache.org>2009-12-26 12:42:57 +0000
committerRafael H. Schloming <rhs@apache.org>2009-12-26 12:42:57 +0000
commit248f1fe188fe2307b9dcf2c87a83b653eaa1920c (patch)
treed5d0959a70218946ff72e107a6c106e32479a398 /java/management/eclipse-plugin/src
parent3c83a0e3ec7cf4dc23e83a340b25f5fc1676f937 (diff)
downloadqpid-python-248f1fe188fe2307b9dcf2c87a83b653eaa1920c.tar.gz
synchronized with trunk except for ruby dir
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/qpid.rnr@893970 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/management/eclipse-plugin/src')
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApiVersion.java110
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java76
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java2
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java25
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java68
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java19
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java131
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java63
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java144
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java89
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/BackAction.java (renamed from java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java)54
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java69
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java2
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java5
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java9
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java1
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java226
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java144
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java12
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java60
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java54
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java56
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java203
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java73
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java82
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java98
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java60
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java464
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java336
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java583
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java380
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java241
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java53
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java296
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java1
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java172
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java551
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/connection/ConnectionOperationsTabControl.java547
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/ExchangeOperationsTabControl.java641
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/HeadersExchangeOperationsTabControl.java713
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/ConfigurationFileTabControl.java591
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableContentProvider.java52
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableLabelProvider.java59
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableSorter.java90
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/RuntimeTabControl.java595
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java1114
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/ConnectionTypeTabControl.java (renamed from java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ConnectionTypeTabControl.java)35
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/ExchangeTypeTabControl.java (renamed from java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java)28
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/MBeanTypeTabControl.java458
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/QueueTypeTabControl.java764
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java915
-rw-r--r--java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/vhost/VHostTabControl.java871
-rw-r--r--java/management/eclipse-plugin/src/main/resources/eclipse.exebin180224 -> 0 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/jmxremote.sasl-plugin/MANIFEST.MF19
-rw-r--r--java/management/eclipse-plugin/src/main/resources/license.eclipse.txt88
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini (renamed from java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini)37
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/libcairo-swt.sobin0 -> 266168 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmcbin0 -> 52576 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini (renamed from java/management/eclipse-plugin/src/main/resources/eclipse.ini)22
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini (renamed from java/management/eclipse-plugin/src/main/resources/unix/configuration/config.ini)38
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.sobin0 -> 335360 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmcbin0 -> 67927 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini37
-rw-r--r--java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini49
-rw-r--r--java/management/eclipse-plugin/src/main/resources/macosx/Contents/Info.plist35
-rwxr-xr-xjava/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmcbin0 -> 59200 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini42
-rw-r--r--java/management/eclipse-plugin/src/main/resources/macosx/Contents/Resources/Console.icnsbin0 -> 51007 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF8
-rw-r--r--java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini49
-rw-r--r--java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm311
-rw-r--r--java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm295
-rw-r--r--java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm287
-rw-r--r--java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm279
-rwxr-xr-xjava/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmcbin0 -> 31668 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini40
-rw-r--r--java/management/eclipse-plugin/src/main/resources/startup.jarbin33049 -> 0 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini49
-rw-r--r--java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.exebin0 -> 57344 bytes
-rw-r--r--java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini36
-rw-r--r--java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApiVersionTest.java177
-rw-r--r--java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApplicationRegistryTest.java43
-rw-r--r--java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java3
83 files changed, 12005 insertions, 2424 deletions
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApiVersion.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApiVersion.java
new file mode 100644
index 0000000000..a8eda3f3d1
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApiVersion.java
@@ -0,0 +1,110 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+public class ApiVersion
+{
+ private int major;
+ private int minor;
+
+ public ApiVersion(int major, int minor)
+ {
+ this.major = major;
+ this.minor = minor;
+ }
+
+ public int getMajor()
+ {
+ return major;
+ }
+
+ public int getMinor()
+ {
+ return minor;
+ }
+
+ public boolean greaterThanOrEqualTo(int major, int minor)
+ {
+ if((this.major == major) && (this.minor >= minor))
+ {
+ return true;
+ }
+ else if (this.major > major)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean lessThanOrEqualTo(int major, int minor)
+ {
+ if((this.major == major) && (this.minor <= minor))
+ {
+ return true;
+ }
+ else if (this.major < major)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean greaterThan(int major, int minor)
+ {
+ if(this.major > major)
+ {
+ return true;
+ }
+ else if ((this.major == major) && (this.minor > minor))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean lessThan(int major, int minor)
+ {
+ if(this.major < major)
+ {
+ return true;
+ }
+ else if ((this.major == major) && (this.minor < minor))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean equals(int major, int minor)
+ {
+ return (this.major == major) && (this.minor == minor);
+ }
+
+ public String toString()
+ {
+ return new String("major=" + major + ",minor=" + minor);
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
index 0ad85dbf33..f3fc135efb 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
@@ -20,8 +20,9 @@
*/
package org.apache.qpid.management.ui;
-import java.util.HashMap;
+import java.io.File;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jface.resource.FontRegistry;
@@ -42,12 +43,20 @@ public abstract class ApplicationRegistry
private static ImageRegistry imageRegistry = new ImageRegistry();
private static FontRegistry fontRegistry = new FontRegistry();
public static final boolean debug = Boolean.getBoolean("eclipse.consoleLog");
- public static final String securityMechanism = System.getProperty("security", null);
- public static final String connectorClass = System.getProperty("jmxconnector");
- public static final long timeout = Long.parseLong(System.getProperty("timeout", "5000"));
+ public static final long timeout = Long.parseLong(System.getProperty("timeout", "15000"));
+
+ //max supported broker management interface supported by this release of the management console
+ public static final int SUPPORTED_QPID_JMX_API_MAJOR_VERSION = 1;
+ public static final int SUPPORTED_QPID_JMX_API_MINOR_VERSION = 6;
+
+ public static final String DATA_DIR = System.getProperty("user.home") + File.separator + ".qpidmc";
static
{
+ imageRegistry.put(Constants.SUCCESS_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/success.gif"));
+ imageRegistry.put(Constants.FAILURE_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/failure.gif"));
imageRegistry.put(Constants.CONSOLE_IMAGE,
org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/qpidmc.gif"));
imageRegistry.put(Constants.CLOSED_FOLDER_IMAGE,
@@ -58,6 +67,16 @@ public abstract class ApplicationRegistry
PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT));
imageRegistry.put(Constants.NOTIFICATION_IMAGE,
org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/notifications.gif"));
+ imageRegistry.put(Constants.LOGGING_MANAGEMENT_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/logging_management.gif"));
+ imageRegistry.put(Constants.USER_MANAGEMENT_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/user_management.gif"));
+ imageRegistry.put(Constants.CONFIGURATION_MANAGEMENT_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/configuration_management.gif"));
+ imageRegistry.put(Constants.SERVER_INFO_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/server_information.gif"));
+ imageRegistry.put(Constants.VHOST_MANAGER_IMAGE,
+ org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/virtualhost_manager.gif"));
}
static
@@ -71,9 +90,8 @@ public abstract class ApplicationRegistry
/*
* This maps all the managed servers to the respective server registry.
- * Server can be JMX MBeanServer or a C++ server
*/
- private static HashMap<ManagedServer, ServerRegistry> _serverRegistryMap = new HashMap<ManagedServer, ServerRegistry>();
+ private static ConcurrentHashMap<ManagedServer, ServerRegistry> _serverRegistryMap = new ConcurrentHashMap<ManagedServer, ServerRegistry>();
// This map gets updated when a server connection closes.
private static List<ManagedServer> _closedServerList = new CopyOnWriteArrayList<ManagedServer>();
@@ -111,7 +129,19 @@ public abstract class ApplicationRegistry
public static boolean isServerConnected(ManagedServer server)
{
- return _serverRegistryMap.containsKey(server);
+ if(server == null)
+ {
+ //checking for null is not permitted in a CHM
+ return false;
+ }
+
+ ServerRegistry reg = _serverRegistryMap.get(server);
+ if(reg !=null)
+ {
+ return !reg.isServerConnectionClosed();
+ }
+
+ return false;
}
// remove the server from the registry
@@ -121,6 +151,27 @@ public abstract class ApplicationRegistry
removeServer(server);
}
+ // remove the server from the registry
+ public static void serverConnectionClosedRemotely(ManagedServer server)
+ {
+ ServerRegistry reg = _serverRegistryMap.get(server);
+ if(reg !=null)
+ {
+ synchronized(server)
+ {
+ if(reg.isServerConnectionClosed())
+ {
+ //the connection closure was already processed
+ return;
+ }
+
+ reg.serverConnectionClosed();
+ }
+ }
+
+ serverConnectionClosed(server);
+ }
+
/*
* Returns the lis of closed servers. The Thread in GUI, which keeps checking for closed connection
* will check this and will remove the server links from the GUI.
@@ -134,14 +185,5 @@ public abstract class ApplicationRegistry
_closedServerList.clear();
return list;
}
-
- public static String getSecurityMechanism()
- {
- return securityMechanism;
- }
-
- public static String getJMXConnectorClass()
- {
- return connectorClass;
- }
+
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
index e3aedef28e..00574440c5 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java
@@ -51,7 +51,7 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor
int y = Display.getDefault().getBounds().height;
configurer.setInitialSize(new Point(9*x/10, 8*y/10));
configurer.setShowCoolBar(true);
- configurer.setShowStatusLine(false);
+ configurer.setShowStatusLine(true);
configurer.setTitle(Constants.APPLICATION_NAME);
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
index d6f895b64a..cec9c8a83c 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
@@ -27,13 +27,14 @@ package org.apache.qpid.management.ui;
*/
public class Constants
{
- public final static String APPLICATION_NAME = "Qpid Management Console";
+ public final static String APPLICATION_NAME = "Qpid JMX Management Console";
+ public static final String DEFAULT_DOMAIN = "org.apache.qpid";
public final static String ACTION_REMOVE_MBEANNODE = "Remove from list";
public final static String VALUE = "value";
public final static String TYPE = "type";
+ public final static String VERSION = "version";
public final static String NODE_TYPE_SERVER = "server";
- public final static String NODE_TYPE_DOMAIN = "domain";
public final static String NODE_TYPE_MBEANTYPE = "mbeantype";
// currently used only for virtual host instances, but will work as general also
public final static String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance";
@@ -77,11 +78,9 @@ public class Constants
public final static String CONNECTION ="Connection";
public final static String EXCHANGE = "Exchange";
public final static String EXCHANGE_TYPE = "ExchangeType";
- public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "fanout", "headers", "topic"};
+ public final static String[] DEFAULT_EXCHANGE_TYPE_VALUES = {"direct", "fanout", "headers", "topic"};
public final static String[] BOOLEAN_TYPE_VALUES = {"false", "true"};
public final static String[] ATTRIBUTE_TABLE_TITLES = {"Attribute Name", "Value"};
- public static final String[] CONNECTION_PROTOCOLS ={"RMI"};
- public static final String DEFAULT_PROTOCOL = CONNECTION_PROTOCOLS[0];
public final static String ACTION_ADDSERVER = "New Connection";
public final static String ACTION_RECONNECT = "Reconnect";
@@ -97,11 +96,19 @@ public class Constants
public final static String SUBSCRIBE_BUTTON = "Subscribe";
public final static String UNSUBSCRIBE_BUTTON = "Unsubscribe";
- public final static String CONSOLE_IMAGE = "ConsoelImage";
+
+ public final static String SUCCESS_IMAGE = "SuccessImage";
+ public final static String FAILURE_IMAGE = "FailureImage";
+ public final static String CONSOLE_IMAGE = "ConsoleImage";
public final static String CLOSED_FOLDER_IMAGE = "ClosedFolderImage";
public final static String OPEN_FOLDER_IMAGE = "OpenFolderImage";
public final static String MBEAN_IMAGE = "MBeanImage";
public final static String NOTIFICATION_IMAGE = "NotificationImage";
+ public final static String LOGGING_MANAGEMENT_IMAGE = "LoggingManagementImage";
+ public final static String USER_MANAGEMENT_IMAGE = "UserManagementImage";
+ public final static String CONFIGURATION_MANAGEMENT_IMAGE = "ConfigurationManagementImage";
+ public final static String SERVER_INFO_IMAGE = "ServerInfoImage";
+ public final static String VHOST_MANAGER_IMAGE = "VhostManagerImage";
public final static String FONT_BUTTON = "ButtonFont";
public final static String FONT_BOLD = "BoldFont";
@@ -110,7 +117,7 @@ public class Constants
public final static String FONT_NORMAL = "Normal";
public final static String BUTTON_DETAILS = "Details";
- public final static String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute";
+ public final static String BUTTON_EDIT_ATTRIBUTE = "Edit";
public final static String BUTTON_REFRESH = "Refresh";
public final static String BUTTON_GRAPH = "Graph";
public final static int TIMER_INTERVAL = 5000;
@@ -133,8 +140,4 @@ public class Constants
public final static String INFO_USERNAME = "Please enter the " + USERNAME;
public final static String INFO_PASSWORD = "Please enter the " + PASSWORD;
- public final static String MECH_CRAMMD5 = "CRAM-MD5";
- public final static String MECH_PLAIN = "PLAIN";
- public final static String SASL_CRAMMD5 = "SASL/CRAM-MD5";
- public final static String SASL_PLAIN = "SASL/PLAIN";
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
index 31825e925d..8ded3f35c6 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
@@ -20,13 +20,19 @@
*/
package org.apache.qpid.management.ui;
-import static org.apache.qpid.management.ui.Constants.*;
+import static org.apache.qpid.management.ui.Constants.ADMIN_MBEAN_TYPE;
+import static org.apache.qpid.management.ui.Constants.CONNECTION;
+import static org.apache.qpid.management.ui.Constants.DEFAULT_VH;
+import static org.apache.qpid.management.ui.Constants.EXCHANGE;
+import static org.apache.qpid.management.ui.Constants.QUEUE;
+import static org.apache.qpid.management.ui.Constants.VIRTUAL_HOST;
+
import java.util.HashMap;
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+
/**
* Class representing a managed bean on the managed server
- * @author Bhupendra Bhardwaj
- *
*/
public abstract class ManagedBean extends ManagedObject
{
@@ -36,27 +42,50 @@ public abstract class ManagedBean extends ManagedObject
private String _virtualHostName = null;
private ManagedServer _server = null;
private HashMap _properties = null;
-
+ private int _version;
+
public String getProperty(String key)
{
- return (String)_properties.get(key);
+ return (String) _properties.get(key);
}
-
+
public HashMap getProperties()
{
return _properties;
}
+
public void setProperties(HashMap properties)
{
this._properties = properties;
setName(getProperty("name"));
setType(getProperty("type"));
+ setVersion(getProperty("version"));
_virtualHostName = getProperty(VIRTUAL_HOST);
}
+
+ public void setVersion(String version)
+ {
+ try
+ {
+ _version = Integer.parseInt(version);
+ }
+ catch (NumberFormatException nfe)
+ {
+ _version = 1;
+ }
+
+ }
+
+ public int getVersion()
+ {
+ return _version;
+ }
+
public String getDomain()
{
return _domain;
}
+
public void setDomain(String domain)
{
this._domain = domain;
@@ -66,65 +95,80 @@ public abstract class ManagedBean extends ManagedObject
{
return _server;
}
+
public void setServer(ManagedServer server)
{
this._server = server;
}
+
public String getType()
{
return _type;
}
+
public void setType(String type)
{
this._type = type;
}
+
public String getUniqueName()
{
return _uniqueName;
}
+
public void setUniqueName(String uniqueName)
{
this._uniqueName = uniqueName;
}
-
+
public String getVirtualHostName()
{
// To make it work with the broker with no virtual host implementation
return _virtualHostName == null ? DEFAULT_VH : _virtualHostName;
}
-
+
/**
* Returns mbean instance name. MBeans which have only one instance, the type attribute will be returned
+ *
* @return
*/
public String getInstanceName()
{
if (getName() != null)
+ {
return getName();
+ }
else
+ {
return getType();
+ }
}
-
+
public boolean isQueue()
{
return _type.endsWith(QUEUE);
}
-
+
public boolean isConnection()
{
return _type.endsWith(CONNECTION);
}
-
+
public boolean isExchange()
{
return _type.endsWith(EXCHANGE);
}
+
+ public boolean isVirtualHostManager()
+ {
+ return _type.endsWith(ManagedBroker.TYPE);
+ }
public boolean isTempQueue()
{
return (isQueue() && getName().startsWith("tmp_"));
}
-
+
public boolean isAdmin()
{
return _type.endsWith(ADMIN_MBEAN_TYPE);
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
index 480fdb429a..9ca8787bb5 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
@@ -20,20 +20,16 @@
*/
package org.apache.qpid.management.ui;
-import static org.apache.qpid.management.ui.Constants.DEFAULT_PROTOCOL;
/**
* Class representing a server being managed eg. MBeanServer
- * @author Bhupendra Bhardwaj
*/
public class ManagedServer extends ManagedObject
{
private String _host;
private int _port;
- private String _url;
private String _domain;
private String _user;
private String _password;
- private String _protocol = DEFAULT_PROTOCOL;
public ManagedServer(String host, int port, String domain)
{
@@ -46,7 +42,6 @@ public class ManagedServer extends ManagedObject
_host = host;
_port = port;
_domain = domain;
- _url = getRMIURL(host, port);
_user = user;
_password = password;
}
@@ -65,17 +60,7 @@ public class ManagedServer extends ManagedObject
{
return _port;
}
-
- public String getUrl()
- {
- return _url;
- }
- public String getProtocol()
- {
- return _protocol;
- }
-
public String getPassword()
{
return _password;
@@ -96,8 +81,4 @@ public class ManagedServer extends ManagedObject
_user = user;
}
- private String getRMIURL(String host, int port)
- {
- return "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
- }
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java
new file mode 100644
index 0000000000..ae60467bf5
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/RefreshIntervalComboPanel.java
@@ -0,0 +1,131 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
+
+public class RefreshIntervalComboPanel extends WorkbenchWindowControlContribution
+{
+ private Display _display = null;
+ private RefreshTask _refreshTask = null;
+
+ private static int DEFAULT_INDEX = 2; //15seconds
+ private static final int[] INTERVALS = new int[]{5,10,15,30,60,120,300,600};
+
+ public RefreshIntervalComboPanel()
+ {
+ super();
+ }
+
+ public RefreshIntervalComboPanel(String id)
+ {
+ super(id);
+ }
+
+ @Override
+ public Control createControl(Composite parent)
+ {
+ _display = parent.getDisplay();
+
+ Composite holder = new Composite(parent,SWT.NONE);
+ holder.setLayout(new GridLayout(2,false));
+ holder.setLayoutData(new GridData(SWT.LEFT,SWT.TOP,false,false));
+
+ Label refreshLabel = new Label(holder,SWT.NONE);
+ refreshLabel.setLayoutData(new GridData(SWT.LEFT,SWT.TOP,false,true));
+ refreshLabel.setText("Refresh Interval: ");
+
+ final Combo combo = new Combo(holder, SWT.NONE | SWT.DROP_DOWN | SWT.READ_ONLY);
+ combo.setLayoutData(new GridData(SWT.LEFT,SWT.TOP,false,false));
+ for(int i=0; i< INTERVALS.length ; i++)
+ {
+ combo.add(String.valueOf(INTERVALS[i]) + " seconds");
+ }
+ combo.select(DEFAULT_INDEX);
+
+ _refreshTask = new RefreshTask(INTERVALS[DEFAULT_INDEX]);
+ _display.timerExec(1000 * INTERVALS[DEFAULT_INDEX], _refreshTask);
+
+ combo.addModifyListener(
+ new ModifyListener()
+ {
+ public void modifyText(final ModifyEvent e)
+ {
+ _display.timerExec(-1, _refreshTask); //cancels existing refresh runnable
+ _refreshTask = new RefreshTask(INTERVALS[combo.getSelectionIndex()]);
+ _display.timerExec(0, _refreshTask); //immediately refresh and begin new schedule
+ }
+ });
+
+ return holder;
+ }
+
+
+ private class RefreshTask implements Runnable
+ {
+ private int seconds;
+
+ public RefreshTask(int secs)
+ {
+ this.seconds = secs;
+ }
+
+ @Override
+ public void run()
+ {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if(window != null)
+ {
+ final MBeanView mbView = (MBeanView)window.getActivePage().findView(MBeanView.ID);
+
+ final NavigationView navView = (NavigationView)window.getActivePage().findView(NavigationView.ID);
+ try
+ {
+ mbView.refresh();
+ navView.refresh();
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(ex);
+ }
+
+ _display.timerExec(1000 * seconds, this);
+ }
+ }
+
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
index 313e143df5..027a555360 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.qpid.management.ui.jmx.ClientListener;
import org.apache.qpid.management.ui.model.ManagedAttributeModel;
@@ -35,6 +36,9 @@ public abstract class ServerRegistry
{
private ManagedServer _managedServer = null;
+ // API version for the management interface on the broker
+ private ApiVersion _managementApiVersion = new ApiVersion(0,0);
+
// list of virtual hosts for this server
private List<String> _virtualHosts = new ArrayList<String>();
// map of all Connection mbeans
@@ -43,6 +47,10 @@ public abstract class ServerRegistry
private ConcurrentMap<String,List<ManagedBean>> _exchanges = new ConcurrentHashMap<String,List<ManagedBean>>();
// map of all queue mbenas
private ConcurrentMap<String,List<ManagedBean>> _queues = new ConcurrentHashMap<String,List<ManagedBean>>();
+ // map of all virtual host manager mbeans
+ private ConcurrentMap<String,ManagedBean> _vhostManagers = new ConcurrentHashMap<String,ManagedBean>();
+
+ private AtomicBoolean _serverConnectionClosed = new AtomicBoolean(false);
public ServerRegistry()
{
@@ -54,6 +62,26 @@ public abstract class ServerRegistry
_managedServer = server;
}
+ public void serverConnectionClosed()
+ {
+ _serverConnectionClosed.set(true);
+ }
+
+ public boolean isServerConnectionClosed()
+ {
+ return _serverConnectionClosed.get();
+ }
+
+ public void setManagementApiVersion(ApiVersion mgmtApiVersion)
+ {
+ _managementApiVersion = mgmtApiVersion;
+ }
+
+ public ApiVersion getManagementApiVersion()
+ {
+ return _managementApiVersion;
+ }
+
public ManagedServer getManagedServer()
{
return _managedServer;
@@ -85,6 +113,22 @@ public abstract class ServerRegistry
_queues.get(vHost).add(mbean);
}
+ protected void addVirtualHostManagerMBean(ManagedBean mbean)
+ {
+ String vHost = mbean.getVirtualHostName();
+ _vhostManagers.put(vHost, mbean);
+ }
+
+ protected void removeVirtualHostManagerMBean(ManagedBean mbean)
+ {
+ _vhostManagers.remove(mbean);
+ }
+
+ public ManagedBean getVirtualHostManagerMBean(String virtualHost)
+ {
+ return _vhostManagers.get(virtualHost);
+ }
+
protected void removeConnectionMBean(ManagedBean mbean)
{
_connections.get(mbean.getVirtualHostName()).remove(mbean);
@@ -115,6 +159,23 @@ public abstract class ServerRegistry
return _queues.get(virtualHost);
}
+ //returns the requested ManagedBean, or null if it cant be found
+ public ManagedBean getQueue(String queueName, String virtualHost)
+ {
+ ManagedBean requestedQueue = null;
+
+ for(ManagedBean queue : _queues.get(virtualHost))
+ {
+ if(queueName.equals(queue.getName()))
+ {
+ requestedQueue = queue;
+ break;
+ }
+ }
+
+ return requestedQueue;
+ }
+
public void addVirtualHost(String name)
{
if (!_virtualHosts.contains(name))
@@ -156,6 +217,8 @@ public abstract class ServerRegistry
public abstract List<NotificationObject> getNotifications(ManagedBean mbean);
+ public abstract List<NotificationObject> getNotifications(String virtualhost);
+
public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type);
public abstract void clearNotifications(ManagedBean mbean, List<NotificationObject> list);
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java
index 53aa927299..5d892f5503 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AbstractAction.java
@@ -24,9 +24,15 @@ import static org.apache.qpid.management.ui.Constants.ERROR_SERVER_CONNECTION;
import java.io.IOException;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLKeyException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
import org.apache.qpid.management.ui.Constants;
+import org.apache.qpid.management.ui.exceptions.ManagementConsoleException;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.views.NavigationView;
import org.eclipse.core.runtime.IStatus;
@@ -43,10 +49,13 @@ public class AbstractAction
protected IWorkbenchWindow _window;
- public static final String RMI_SASL_ERROR = "non-JRMP server";
- public static final String SECURITY_FAILURE = "User authentication has failed";
- public static final String SERVER_UNAVAILABLE = "Qpid server is not running";
-
+ public static final String INVALID_PERSPECTIVE = "Invalid Perspective";
+ public static final String CHANGE_PERSPECTIVE = "Please use the Qpid Management Perspective";
+
+ private static final String SSL_EMPTY_TRUSTANCHORS = "the trustAnchors parameter must be non-empty";
+ private static final String SSL_UNABLE_TO_FIND_CERTPATH = "sun.security.provider.certpath.SunCertPathBuilderException: " +
+ "unable to find valid certification path to requested target";
+
/**
* We will cache window object in order to
* be able to provide parent shell for the message dialog.
@@ -71,52 +80,127 @@ public class AbstractAction
return _navigationView;
}
-
protected void handleException(Throwable ex, String title, String msg)
{
- MBeanUtility.printStackTrace(ex);
+ //ensure first that the exception is not due to running in the wrong eclipse perspective
+ NavigationView view = (NavigationView)_window.getActivePage().findView(NavigationView.ID);
+ if (view == null)
+ {
+ IStatus status = new Status(IStatus.WARNING, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, CHANGE_PERSPECTIVE, null);
+ ErrorDialog.openError(_window.getShell(), "Warning", INVALID_PERSPECTIVE, status);
+ return;
+ }
+
+ //default title if none given
+ if (title == null)
+ {
+ title = ERROR_SERVER_CONNECTION;
+ }
+
+ //determine the error message to display
if (msg == null)
{
- if (ex instanceof IOException)
+ if (ex instanceof SSLException)
{
- if ((ex.getMessage() != null) && (ex.getMessage().indexOf(RMI_SASL_ERROR) != -1))
+ if (ex instanceof SSLKeyException)
{
- msg = SECURITY_FAILURE;
+ msg = "SSL key was invalid, please check the certificate configuration.";
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ else if (ex instanceof SSLPeerUnverifiedException)
+ {
+ msg = "SSL peer identity could not be verified, please ensure valid certificate configuration.";
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ else if (ex instanceof SSLHandshakeException)
+ {
+ if (ex.getMessage().contains(SSL_UNABLE_TO_FIND_CERTPATH))
+ {
+ msg = "Unable to certify the provided SSL certificate using the current SSL trust store.";
+ }
+ else
+ {
+ //cause unknown, provide a trace too
+ MBeanUtility.printStackTrace(ex);
+ msg = "SSL handhshake error.";
+ }
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
}
else
{
- msg = SERVER_UNAVAILABLE;
+ //general SSL Exception.
+ if (ex.getMessage().contains(SSL_EMPTY_TRUSTANCHORS))
+ {
+ msg = "Unable to locate the specified SSL certificate trust store, please check the configuration.";
+ }
+ else
+ {
+ //cause unknown, print stack trace
+ MBeanUtility.printStackTrace(ex);
+ msg = "SSL connection error.";
+ }
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
}
}
- else if (ex instanceof SecurityException)
+ else if (ex instanceof IOException || ex instanceof SecurityException )
{
- msg = SECURITY_FAILURE;
+ msg = ex.getMessage();
+
+ //if msg is still null, try reporting the cause.
+ if ((msg == null) && (ex.getCause() != null))
+ {
+ msg = ex.getCause().getMessage();
+ }
+
+ //Display error dialogue and return
+ displayErrorDialogue(msg, title);
+ return;
+ }
+ else if (ex instanceof ManagementConsoleException)
+ {
+ msg = ex.getMessage();
+ displayErrorDialogue(msg, title);
+ return;
}
else
{
+ //Unknown exception type/reason.
msg = ex.getMessage();
}
+
+ //if msg is still null, try reporting the cause.
+ if ((msg == null) && (ex.getCause() != null))
+ {
+ msg = ex.getCause().getMessage();
+ }
+
+ //failing all else, default non-descript error message.
+ if (msg == null)
+ {
+ msg = "An unknown error has occured.";
+ }
}
-
- if ((msg == null) && (ex.getCause() != null))
- {
- msg = ex.getCause().getMessage();
- }
-
- if (msg == null)
- {
- msg = ERROR_SERVER_CONNECTION;
- }
-
- if (title == null)
- {
- title = ERROR_SERVER_CONNECTION;
- }
- IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
- IStatus.OK, msg, null);
- ErrorDialog.openError(_window.getShell(), "Error", title, status);
+
+ //Display error dialogue and print the exception stack trace
+ MBeanUtility.printStackTrace(ex);
+ displayErrorDialogue(msg, title);
}
+ private void displayErrorDialogue(String msg, String title)
+ {
+ IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
+ IStatus.OK, msg, null);
+ ErrorDialog.openError(_window.getShell(), "Error", title, status);
+ }
/**
* Selection in the workbench has been changed. We can change the state of the 'real' action here
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
index 7a36ca6160..e487c02a67 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
@@ -28,13 +28,15 @@ import org.apache.qpid.management.ui.views.NumberVerifyListener;
import org.apache.qpid.management.ui.views.ViewUtility;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
@@ -43,12 +45,9 @@ import org.eclipse.ui.IWorkbenchWindowActionDelegate;
public class AddServer extends AbstractAction implements IWorkbenchWindowActionDelegate
{
- private static final String[] _domains ={"org.apache.qpid"};
-
- private String _transport = DEFAULT_PROTOCOL;
private String _host;
private String _port;
- private String _domain;
+ private String _domain = DEFAULT_DOMAIN;
private String _user;
private String _password;
@@ -70,7 +69,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
{
if (_addServer)
{
- getNavigationView().addNewServer(_transport, _host, Integer.parseInt(_port), _domain, _user, _password);
+ getNavigationView().addNewServer(_host, Integer.parseInt(_port), _domain, _user, _password);
}
}
catch(InfoRequiredException ex)
@@ -88,7 +87,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
_addServer = false;
_host = null;
_port = null;
- _domain = null;
_user = null;
_password = null;
}
@@ -100,17 +98,34 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
*/
private void createAddServerPopup()
{
+ final Shell appShell = _window.getShell();
+
Display display = Display.getCurrent();
final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE);
shell.setText(ACTION_ADDSERVER);
shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
shell.setLayout(new GridLayout());
- int x = display.getBounds().width;
- int y = display.getBounds().height;
- shell.setBounds(x/3, y/3, 425, 275);
-
createWidgets(shell);
+ shell.pack();
+
+ //get current size dialog, and application window size and location
+ int appWidth = appShell.getBounds().width;
+ int appHeight = appShell.getBounds().height;
+ int appLocX = appShell.getBounds().x;
+ int appLocY = appShell.getBounds().y;
+ int currentShellWidth = shell.getSize().x;
+ int currentShellHeight = shell.getSize().y;
+
+ //default sizes for the dialog
+ int minShellWidth = 425;
+ int minShellHeight= 265;
+ //ensure this is large enough, increase it if its not
+ int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth;
+ int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight;
+
+ //set the final size and centre the dialog within the app window
+ shell.setBounds((appWidth - newShellWidth)/2 + appLocX, (appHeight - newShellHeight)/2 + appLocY, newShellWidth, newShellHeight);
shell.open();
_window.getShell().setEnabled(false);
@@ -173,17 +188,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
// Verify if the value entered is numeric
textPort.addVerifyListener(new NumberVerifyListener());
-
- Label domain = new Label(composite, SWT.NONE);
- domain.setText("Domain");
- domain.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
-
- final Combo comboDomain = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
- comboDomain.setItems(_domains);
- comboDomain.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- comboDomain.select(0);
-
-
Label user = new Label(composite, SWT.NONE);
user.setText(USERNAME);
user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
@@ -201,11 +205,27 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
//textPwd.setEchoChar('*');
textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ //Get the text widgets
+ Control[] widgets = composite.getChildren();
+ for (int i=0; i < widgets.length; i++)
+ {
+ widgets[i].addKeyListener(new KeyAdapter()
+ {
+ public void keyPressed(KeyEvent event)
+ {
+ if (event.character == SWT.ESC)
+ {
+ //Escape key acts as cancel on all widgets
+ shell.dispose();
+ }
+ }
+ });
+ }
+
Composite buttonsComposite = new Composite(composite, SWT.NONE);
buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
buttonsComposite.setLayout(new GridLayout(2, true));
-
final Button connectButton = new Button(buttonsComposite, SWT.PUSH | SWT.CENTER);
connectButton.setText(BUTTON_CONNECT);
GridData gridData = new GridData (SWT.TRAIL, SWT.BOTTOM, true, true);
@@ -251,7 +271,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
return;
}
- _domain = comboDomain.getText();
_addServer = true;
shell.dispose();
}
@@ -263,12 +282,32 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
gridData.widthHint = 100;
cancelButton.setLayoutData(gridData);
cancelButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- cancelButton.addSelectionListener(new SelectionAdapter(){
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
public void widgetSelected(SelectionEvent event)
{
shell.dispose();
}
});
+
+ //Get the ok/cancel button widgets and add a new key listener
+ widgets = buttonsComposite.getChildren();
+ for (int i=0; i < widgets.length; i++)
+ {
+ widgets[i].addKeyListener(new KeyAdapter()
+ {
+ public void keyPressed(KeyEvent event)
+ {
+ if (event.character == SWT.ESC)
+ {
+ //Escape key acts as cancel on all widgets
+ shell.dispose();
+ }
+ }
+ });
+ }
+
+ shell.setDefaultButton(connectButton);
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/BackAction.java
index d3af3661b0..2998c5db53 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/EditAttribute.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/BackAction.java
@@ -20,32 +20,40 @@
*/
package org.apache.qpid.management.ui.actions;
-import static org.apache.qpid.management.ui.Constants.ACTION_EDITATTRIBUTE;
-import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.views.MBeanView;
-import org.apache.qpid.management.ui.views.ViewUtility;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
-public class EditAttribute extends AbstractAction implements IWorkbenchWindowActionDelegate
-{
- public void run(IAction action)
+
+public class BackAction extends Action implements IWorkbenchAction
+{
+ private static final String ID = "org.apache.qpid.management.ui.actions.back";
+
+ public BackAction()
+ {
+ setText("Back");
+ setImageDescriptor(org.apache.qpid.management.ui.Activator.getImageDescriptor("/icons/back.gif"));
+ setId(ID);
+ }
+
+ public void run()
{
- if(_window != null)
- {
- MBeanView view = (MBeanView)_window.getActivePage().findView(MBeanView.ID);
- try
- {
- view.editAttribute();
- }
- catch(InfoRequiredException ex)
- {
- ViewUtility.popupInfoMessage(ACTION_EDITATTRIBUTE, ex.getMessage());
- }
- catch(Exception ex)
- {
- handleException(ex, "Attribute could not be edited", null);
- }
+ MBeanView mbeanview = (MBeanView)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(MBeanView.ID);
+ try
+ {
+ mbeanview.back();
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(ex);
}
+
+ }
+
+ public void dispose()
+ {
+
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
index dd9e792912..5eb9d9a168 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
@@ -34,12 +34,15 @@ import org.apache.qpid.management.ui.views.TreeObject;
import org.apache.qpid.management.ui.views.ViewUtility;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
@@ -96,17 +99,34 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
// Create the login popup fot th user to enter usernaem and password
private void createLoginPopup()
{
+ final Shell appShell = _window.getShell();
+
Display display = Display.getCurrent();
final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE);
shell.setText(_title);
shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
shell.setLayout(new GridLayout());
- int x = display.getBounds().width;
- int y = display.getBounds().height;
- shell.setBounds(x/3, y/3, 350, 200);
-
- createWidgets(shell);
+ createWidgets(shell);
+ shell.pack();
+
+ //get current size dialog, and application window size and location
+ int appWidth = appShell.getBounds().width;
+ int appHeight = appShell.getBounds().height;
+ int appLocX = appShell.getBounds().x;
+ int appLocY = appShell.getBounds().y;
+ int currentShellWidth = shell.getSize().x;
+ int currentShellHeight = shell.getSize().y;
+
+ //default sizes for the dialog
+ int minShellWidth = 350;
+ int minShellHeight= 200;
+ //ensure this is large enough, increase it if its not
+ int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth;
+ int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight;
+
+ //set the final size and centre the dialog within the app window
+ shell.setBounds((appWidth - newShellWidth)/2 + appLocX, (appHeight - newShellHeight)/2 + appLocY, newShellWidth, newShellHeight);
shell.open();
_window.getShell().setEnabled(false);
@@ -155,11 +175,27 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
textPwd.setText("");
textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ //Get the text widgets
+ Control[] widgets = composite.getChildren();
+ for (int i=0; i < widgets.length; i++)
+ {
+ widgets[i].addKeyListener(new KeyAdapter()
+ {
+ public void keyPressed(KeyEvent event)
+ {
+ if (event.character == SWT.ESC)
+ {
+ //Escape key acts as cancel on all widgets
+ shell.dispose();
+ }
+ }
+ });
+ }
+
Composite buttonsComposite = new Composite(composite, SWT.NONE);
buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
buttonsComposite.setLayout(new GridLayout(2, true));
-
final Button connectButton = new Button(buttonsComposite, SWT.PUSH | SWT.CENTER);
connectButton.setText(Constants.BUTTON_CONNECT);
GridData gridData = new GridData (SWT.TRAIL, SWT.BOTTOM, true, true);
@@ -203,7 +239,26 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
{
shell.dispose();
}
- });
+ });
+
+ //Get the ok/cancel button widgets and add a new key listener
+ widgets = buttonsComposite.getChildren();
+ for (int i=0; i < widgets.length; i++)
+ {
+ widgets[i].addKeyListener(new KeyAdapter()
+ {
+ public void keyPressed(KeyEvent event)
+ {
+ if (event.character == SWT.ESC)
+ {
+ //Escape key acts as cancel on all widgets
+ shell.dispose();
+ }
+ }
+ });
+ }
+
+ shell.setDefaultButton(connectButton);
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java
index 34251c12d7..dd4cbffd84 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/Refresh.java
@@ -42,7 +42,7 @@ public class Refresh extends AbstractAction implements IWorkbenchWindowActionDel
MBeanView mbeanview = (MBeanView)_window.getActivePage().findView(MBeanView.ID);
try
{
- mbeanview.refreshMBeanView();
+ mbeanview.refresh();
}
catch (Exception ex)
{
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java
index 11db02f5a2..be69fadbe8 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/VersionAction.java
@@ -57,6 +57,11 @@ public class VersionAction extends Action
_text = "Build Version : " + _buildVersion + "\n" +
"Release Version : " + _releaseVersion;
}
+ else
+ {
+ _text = "Build Version : \n" +
+ "Release Version : ";
+ }
}
catch (Exception ex)
{
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
index 2be0ddbebf..694f7ba86b 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
@@ -45,7 +45,6 @@ public class ClientListener implements NotificationListener
{
ObjectName objName = null;
String type = notification.getType();
- MBeanUtility.printOutput(type + ":" + objName);
if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type))
{
@@ -59,7 +58,13 @@ public class ClientListener implements NotificationListener
}
else if (JMXConnectionNotification.FAILED.equals(type))
{
- ApplicationRegistry.serverConnectionClosed(server);
+ ApplicationRegistry.serverConnectionClosedRemotely(server);
+ MBeanUtility.printOutput("JMX Connection to " + server.getName() + " failed.");
+ }
+ else if (JMXConnectionNotification.CLOSED.equals(type))
+ {
+ ApplicationRegistry.serverConnectionClosedRemotely(server);
+ MBeanUtility.printOutput("JMX Connection to " + server.getName() + " was closed.");
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
index c6ecda4b4c..2af8e681ae 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
@@ -35,7 +35,6 @@ public class ClientNotificationListener extends ClientListener
public void handleNotification(Notification notification, Object handback)
{
ObjectName objName = (ObjectName)notification.getSource();
- //String type = notification.getType();
getServerRegistry().addNotification(objName, notification);
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
index f671a1dc9a..717f781334 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
@@ -20,29 +20,23 @@
*/
package org.apache.qpid.management.ui.jmx;
-import static org.apache.qpid.management.ui.Constants.*;
+import static org.apache.qpid.management.ui.Constants.ALL;
-import java.lang.reflect.Constructor;
-import java.security.Security;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
-import javax.management.ListenerNotFoundException;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.Notification;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.SaslClientFactory;
+import org.apache.qpid.management.common.JMXConnnectionFactory;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ManagedServer;
@@ -51,21 +45,14 @@ import org.apache.qpid.management.ui.model.ManagedAttributeModel;
import org.apache.qpid.management.ui.model.NotificationInfoModel;
import org.apache.qpid.management.ui.model.NotificationObject;
import org.apache.qpid.management.ui.model.OperationDataModel;
-import org.apache.qpid.management.ui.sasl.JCAProvider;
-import org.apache.qpid.management.ui.sasl.SaslProvider;
-import org.apache.qpid.management.ui.sasl.UserPasswordCallbackHandler;
-import org.apache.qpid.management.ui.sasl.UsernameHashedPasswordCallbackHandler;
public class JMXServerRegistry extends ServerRegistry
{
- private boolean _connected = false;
private ObjectName _serverObjectName = null;
- private Map<String, Object> _env = null;
- private JMXServiceURL _jmxUrl = null;
private JMXConnector _jmxc = null;
private MBeanServerConnection _mbsc = null;
- private Exception _connectionException = null;
+ private String _securityMechanism = null;
private List<String> _usersList;
// When an mbean gets removed from mbean server, then the notification listener
@@ -98,140 +85,94 @@ public class JMXServerRegistry extends ServerRegistry
public JMXServerRegistry(ManagedServer server) throws Exception
{
super(server);
- String securityMechanism = ApplicationRegistry.getSecurityMechanism();
- String connectorClassName = ApplicationRegistry.getJMXConnectorClass();
-
- if ((securityMechanism != null) && (connectorClassName != null))
- {
- createSASLConnector(securityMechanism, connectorClassName);
- }
- else
- {
- _jmxUrl = new JMXServiceURL(server.getUrl());
- _jmxc = JMXConnectorFactory.connect(_jmxUrl, null);
- }
- _mbsc = _jmxc.getMBeanServerConnection();
+ _jmxc = JMXConnnectionFactory.getJMXConnection(
+ ApplicationRegistry.timeout, server.getHost(),
+ server.getPort(), server.getUser(), server.getPassword());
+ _mbsc = _jmxc.getMBeanServerConnection();
+
_clientListener = new ClientListener(server);
_notificationListener = new ClientNotificationListener(server);
-
- _jmxc.addConnectionNotificationListener(_clientListener, null, null);
+
+ _jmxc.addConnectionNotificationListener(_clientListener, null, null);
_serverObjectName = new ObjectName("JMImplementation:type=MBeanServerDelegate");
_mbsc.addNotificationListener(_serverObjectName, _clientListener, null, null);
+
}
-
+
public MBeanServerConnection getServerConnection()
{
return _mbsc;
}
-
- private void createSASLConnector(String mech, String className) throws Exception
- {
- String text = "Security mechanism " + mech + " is not supported.";
- // Check if the given connector, which supports SASL is available
- Class connectorClass = Class.forName(className);
-
- _jmxUrl = new JMXServiceURL("jmxmp", getManagedServer().getHost(), getManagedServer().getPort());
- _env = new HashMap<String, Object>();
- CallbackHandler handler;
- if (MECH_CRAMMD5.equals(mech))
- {
- // For SASL/CRAM-MD5
- Map<String, Class<? extends SaslClientFactory>> map = new HashMap<String, Class<? extends SaslClientFactory>>();
- Class<?> clazz = Class.forName("org.apache.qpid.management.ui.sasl.CRAMMD5HashedSaslClientFactory");
- map.put("CRAM-MD5-HASHED", (Class<? extends SaslClientFactory>) clazz);
-
- Security.addProvider(new JCAProvider(map));
- handler = new UsernameHashedPasswordCallbackHandler(getManagedServer().getUser(),
- getManagedServer().getPassword());
- _env.put("jmx.remote.profiles", SASL_CRAMMD5);
- _env.put("jmx.remote.sasl.callback.handler", handler);
-
- }
- else if (MECH_PLAIN.equals(mech))
- {
- // For SASL/PLAIN
- Security.addProvider(new SaslProvider());
- handler = new UserPasswordCallbackHandler(getManagedServer().getUser(), getManagedServer().getPassword());
- _env.put("jmx.remote.profiles", SASL_PLAIN);
- _env.put("jmx.remote.sasl.callback.handler", handler);
- }
- else
- {
- MBeanUtility.printOutput(text);
- throw new Exception(text);
- }
- // Now create the instance of JMXMPConnector
- Class[] paramTypes = {JMXServiceURL.class, Map.class};
- Constructor cons = connectorClass.getConstructor(paramTypes);
- Object[] args = {_jmxUrl, _env};
- Object theObject = cons.newInstance(args);
- _jmxc = (JMXConnector)theObject;
-
- Thread connectorThread = new Thread(new ConnectorThread());
- connectorThread.start();
- long timeNow = System.currentTimeMillis();
- connectorThread.join(ApplicationRegistry.timeout);
-
- if (_connectionException != null)
- {
- throw _connectionException;
- }
- if (!_connected)
- {
- if (System.currentTimeMillis() - timeNow >= ApplicationRegistry.timeout)
- throw new Exception("Qpid server connection timed out");
- else
- throw new Exception("Qpid server connection failed");
- }
- }
-
- private class ConnectorThread implements Runnable
+ public String getSecurityMechanism()
{
- public void run()
- {
- try
- {
- _connected = false;
- _connectionException = null;
-
- _jmxc.connect();
- _connected = true;
- }
- catch (Exception ex)
- {
- _connectionException = ex;
- MBeanUtility.printStackTrace(ex);
- }
- }
+ return _securityMechanism;
}
+
/**
* removes all listeners from the mbean server. This is required when user
* disconnects the Qpid server connection
*/
- public void closeServerConnection() throws Exception
+ public void closeServerConnection() throws IOException
{
+ if(isServerConnectionClosed())
+ {
+ //connection was already closed
+ return;
+ }
+
try
{
+ //remove the listener from the JMXConnector
if (_jmxc != null && _clientListener != null)
+ {
_jmxc.removeConnectionNotificationListener(_clientListener);
+ }
+ }
+ catch (Exception e)
+ {
+ //ignore
+ }
+ try
+ {
+ //remove the listener from the MBeanServerDelegate MBean
if (_mbsc != null && _clientListener != null)
+ {
_mbsc.removeNotificationListener(_serverObjectName, _clientListener);
+ }
+ }
+ catch (Exception e)
+ {
+ //ignore
+ }
- // remove mbean notification listeners
+ if (_mbsc != null && _clientListener != null)
+ {
+ //remove any listeners from the Qpid MBeans
for (String mbeanName : _subscribedNotificationMap.keySet())
{
- _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener);
+ try
+ {
+ _mbsc.removeNotificationListener(new ObjectName(mbeanName), _notificationListener);
+ }
+ catch (Exception e)
+ {
+ //ignore
+ }
}
}
- catch (ListenerNotFoundException ex)
+
+ //close the JMXConnector
+ if (_jmxc != null)
{
- MBeanUtility.printOutput(ex.toString());
+ _jmxc.close();
}
+
+ serverConnectionClosed();
}
public ManagedBean getManagedObject(String uniqueName)
@@ -253,6 +194,10 @@ public class JMXServerRegistry extends ServerRegistry
{
addConnectionMBean(mbean);
}
+ else if (mbean.isVirtualHostManager())
+ {
+ addVirtualHostManagerMBean(mbean);
+ }
addVirtualHost(mbean.getVirtualHostName());
_mbeansMap.put(mbean.getUniqueName(), mbean);
@@ -260,7 +205,12 @@ public class JMXServerRegistry extends ServerRegistry
public void removeManagedObject(ManagedBean mbean)
{
- MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName());
+ if (mbean == null)
+ {
+ return;
+ }
+
+ _mbeansMap.remove(mbean.getUniqueName());
if (mbean.isQueue())
{
@@ -274,8 +224,10 @@ public class JMXServerRegistry extends ServerRegistry
{
removeConnectionMBean(mbean);
}
-
- _mbeansMap.remove(mbean.getUniqueName());
+ else if (mbean.isVirtualHostManager())
+ {
+ removeVirtualHostManagerMBean(mbean);
+ }
}
public void putMBeanInfo(ManagedBean mbean, MBeanInfo mbeanInfo)
@@ -341,6 +293,38 @@ public class JMXServerRegistry extends ServerRegistry
}
}
+ public List<NotificationObject> getNotifications(String virtualhost)
+ {
+ List<NotificationObject> vhostNotificationsList = new ArrayList<NotificationObject>();
+
+ //iterate over all the notification lists for mbeans with subscribed notifications
+ for (List<NotificationObject> list : _notificationsMap.values())
+ {
+ if(list == null || list.isEmpty())
+ {
+ continue;
+ }
+
+ //Check the source vhost of the first notification
+ NotificationObject notification = list.get(0);
+
+ if (notification != null)
+ {
+ String sourceVhost = notification.getSourceVirtualHost();
+ if(sourceVhost != null)
+ {
+ if(sourceVhost.equalsIgnoreCase(virtualhost))
+ {
+ //If it matches, add the entire list as they are from the same vhost (same source mbean)
+ vhostNotificationsList.addAll(list);
+ }
+ }
+ }
+ }
+
+ return vhostNotificationsList;
+ }
+
public void clearNotifications(ManagedBean mbean, List<NotificationObject> list)
{
if (mbean == null)
@@ -520,11 +504,11 @@ public class JMXServerRegistry extends ServerRegistry
public void unregisterManagedObject(ObjectName objName)
{
ManagedBean mbean = _mbeansMap.get(objName.toString());
- removeManagedObject(mbean);
// Check if mbean was not available in the map. It can happen if mbean unregistration
// notification is received and the mbean is not added in the map.
if (mbean != null)
{
+ removeManagedObject(mbean);
_mbeansToBeRemoved.add(mbean);
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
index 2d1883533b..2f5752db9b 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
@@ -20,9 +20,10 @@
*/
package org.apache.qpid.management.ui.jmx;
+import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -37,10 +38,14 @@ import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
+import org.apache.qpid.management.common.mbeans.ServerInformation;
+import org.apache.qpid.management.ui.ApiVersion;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ManagedServer;
@@ -173,6 +178,10 @@ public class MBeanUtility
{
ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage());
}
+ else if (ex instanceof SecurityException)
+ {
+ ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage());
+ }
else
{
if (ex.getCause() != null)
@@ -267,6 +276,72 @@ public class MBeanUtility
return value;
}
+
+ /**
+ * Returns a List of Object arrays containing the requested attribute values (in the same sequence requested) for each queue in the virtualhost.
+ * If a particular attribute cant be found or raises an mbean/reflection exception whilst being gathered its value is substituted with the String "-".
+ */
+ public static List<List<Object>> getQueueAttributes(List<ManagedBean> mbeans, String[] attributes)
+ {
+ List<List<Object>> results = new ArrayList<List<Object>>();
+
+ MBeanServerConnection mbsc = null;
+ if(mbeans.isEmpty())
+ {
+ return results;
+ }
+ else
+ {
+ ManagedBean mbean = mbeans.get(0);
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(mbean);
+ mbsc = serverRegistry.getServerConnection();
+ }
+
+ if(mbsc == null)
+ {
+ return results;
+ }
+
+ for(ManagedBean mbean : mbeans)
+ {
+ HashMap<String,Object> tempResults = new HashMap<String,Object>();
+
+ ObjectName objName = ((JMXManagedObject)mbean).getObjectName();
+ try
+ {
+ AttributeList list = mbsc.getAttributes(objName, attributes);
+
+ for (Attribute attr : list.toArray(new Attribute[0]))
+ {
+ tempResults.put(attr.getName(), attr.getValue());
+ }
+
+ List<Object> attributeValues = new ArrayList<Object>(attributes.length);
+
+ for(int i = 0; i <attributes.length; i++)
+ {
+ if(tempResults.containsKey(attributes[i]))
+ {
+ attributeValues.add(tempResults.get(attributes[i]));
+ }
+ else
+ {
+ attributeValues.add(new String("-"));
+ }
+ }
+
+ results.add(attributeValues);
+ }
+ catch (Exception ignore)
+ {
+ continue;
+ }
+ }
+
+ return results;
+ }
+
+
/**
* Retrieves the attribute values from MBeanSever and stores in the server registry.
* @param mbean
@@ -437,15 +512,70 @@ public class MBeanUtility
}
/**
- * Returns all the domains for the given server. This method can be removed as now this RCP is specific to
- * Qpid and domain is also fixed
+ * Classifies the management API version of the given server
+ * @return list of ManagedBeans
+ * @throws NullPointerException
+ * @throws ManagementConsoleException
+ * @throws MalformedObjectNameException
+ * @throws IOException
*/
- public static List<String> getAllDomains(ManagedServer server) throws Exception
+ public static void classifyManagementApiVersion(ManagedServer server, JMXServerRegistry serverRegistry)
+ throws MalformedObjectNameException, NullPointerException, IOException
{
- JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
MBeanServerConnection mbsc = serverRegistry.getServerConnection();
- String[] domains = mbsc.getDomains();
- return Arrays.asList(domains);
+
+ //Detect if the ServerInformation MBean is present, and use it to retrieve the API version.
+ ObjectName objName = new ObjectName(server.getDomain() + ":type="+ ServerInformation.TYPE + ",*");
+ Set<ObjectName> objectInstances = mbsc.queryNames(objName, null);
+
+ if(objectInstances.size() != 0)
+ {
+ for (Iterator<ObjectName> itr = objectInstances.iterator(); itr.hasNext();)
+ {
+ ObjectName instance = (ObjectName)itr.next();
+ ServerInformation simb = (ServerInformation)
+ MBeanServerInvocationHandler.newProxyInstance(mbsc,
+ instance, ServerInformation.class, false);
+
+ int major = simb.getManagementApiMajorVersion();
+ int minor = simb.getManagementApiMinorVersion();
+
+ serverRegistry.setManagementApiVersion(new ApiVersion(major, minor));
+ }
+
+ return;
+ }
+
+ //ServerInformation mbean was not present, so this is a older pre-v1.3 API server.
+
+ //Detect the value of the 'version' key property on the UserManagement MBean ObjectName.
+ //If present, we have a v1.2 API server. If null, we have a v1.1 API server.
+ //Use an ObjectName pattern (the ?) to match the 'type' and allow this to work for non-admin users
+ objName = new ObjectName(server.getDomain() + ":type="+ "UserManagemen?" + ",*");
+ objectInstances = mbsc.queryNames(objName, null);
+
+ if(objectInstances.size() != 0)
+ {
+ for (Iterator<ObjectName> itr = objectInstances.iterator(); itr.hasNext();)
+ {
+ ObjectName instance = (ObjectName)itr.next();
+ String version = instance.getKeyProperty("version");
+
+ if(version != null)
+ {
+ serverRegistry.setManagementApiVersion(new ApiVersion(1, 2));
+ }
+ else
+ {
+ serverRegistry.setManagementApiVersion(new ApiVersion(1, 1));
+ }
+ }
+ }
+ else
+ {
+ //UserManagement MBean wasnt present, connected to an old server: classify as v1.0 API
+ serverRegistry.setManagementApiVersion(new ApiVersion(1, 0));
+ }
}
public static void printOutput(String statement)
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
index 926e5f0a24..e42b3c53b6 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
@@ -26,6 +26,8 @@ import java.util.TimeZone;
import javax.management.ObjectName;
+import static org.apache.qpid.management.ui.Constants.VIRTUAL_HOST;
+
public class NotificationObject
{
@@ -65,6 +67,16 @@ public class NotificationObject
return null;
}
+ public String getSourceVirtualHost()
+ {
+ if (_source instanceof ObjectName)
+ {
+ return ((ObjectName)_source).getKeyProperty(VIRTUAL_HOST);
+ }
+
+ return null;
+ }
+
public String getMessage()
{
return _message;
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java
deleted file mode 100644
index 32a0c12344..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.sasl;
-
-import java.util.Map;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslClientFactory;
-import javax.security.sasl.SaslException;
-
-public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory
-{
- /** The name of this mechanism */
- public static final String MECHANISM = "CRAM-MD5-HASHED";
-
- public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol,
- String serverName, Map<String, ?> props, CallbackHandler cbh)
- throws SaslException
- {
- for (int i = 0; i < mechanisms.length; i++)
- {
- if (mechanisms[i].equals(MECHANISM))
- {
- if (cbh == null)
- {
- throw new SaslException("CallbackHandler must not be null");
- }
-
- String[] mechs = {"CRAM-MD5"};
- return Sasl.createSaslClient(mechs, authorizationId, protocol, serverName, props, cbh);
- }
- }
- return null;
- }
-
- public String[] getMechanismNames(Map props)
- {
- return new String[]{MECHANISM};
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java
deleted file mode 100644
index ce9a273eaa..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.sasl;
-
-import java.util.Map;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslClientFactory;
-import javax.security.sasl.SaslException;
-
-public class ClientSaslFactory implements SaslClientFactory
-{
- public SaslClient createSaslClient(String[] mechs, String authorizationId, String protocol,
- String serverName, Map props, CallbackHandler cbh)
- throws SaslException
- {
- for (int i = 0; i < mechs.length; i++)
- {
- if (mechs[i].equals("PLAIN"))
- {
- return new PlainSaslClient(authorizationId, cbh);
- }
- }
- return null;
- }
-
- /**
- * Simple-minded implementation that ignores props
- */
- public String[] getMechanismNames(Map props)
- {
- return new String[]{"PLAIN"};
- }
-
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java
deleted file mode 100644
index d8189f3ac3..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.sasl;
-
-import java.security.Provider;
-import java.util.Map;
-
-import javax.security.sasl.SaslClientFactory;
-
-public class JCAProvider extends Provider
-{
- private static final long serialVersionUID = 1L;
-
- /**
- * Creates the security provider with a map from SASL mechanisms to implementing factories.
- *
- * @param providerMap The map from SASL mechanims to implementing factory classes.
- */
- public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap)
- {
- super("AMQSASLProvider", 1.0, "A JCA provider that registers all "
- + "AMQ SASL providers that want to be registered");
- register(providerMap);
- }
-
- /**
- * Registers client factory classes for a map of mechanism names to client factory classes.
- *
- * @param providerMap The map from SASL mechanims to implementing factory classes.
- */
- private void register(Map<String, Class<? extends SaslClientFactory>> providerMap)
- {
- for (Map.Entry<String, Class<? extends SaslClientFactory>> me : providerMap.entrySet())
- {
- put("SaslClientFactory." + me.getKey(), me.getValue().getName());
- }
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java
deleted file mode 100644
index 22190f29eb..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.sasl;
-
-import java.io.*;
-import javax.security.auth.callback.*;
-import javax.security.sasl.*;
-
-public class PlainSaslClient implements SaslClient
-{
-
- private boolean completed;
- private CallbackHandler cbh;
- private String authorizationID;
- private String authenticationID;
- private byte password[];
- private static byte SEPARATOR = 0;
-
- public PlainSaslClient(String authorizationID, CallbackHandler cbh) throws SaslException
- {
- completed = false;
- this.cbh = cbh;
- Object[] userInfo = getUserInfo();
- this.authorizationID = authorizationID;
- this.authenticationID = (String) userInfo[0];
- this.password = (byte[]) userInfo[1];
- if (authenticationID == null || password == null)
- {
- throw new SaslException("PLAIN: authenticationID and password must be specified");
- }
- }
-
- public byte[] evaluateChallenge(byte[] challenge) throws SaslException
- {
- if (completed)
- {
- throw new IllegalStateException("PLAIN: authentication already " +
- "completed");
- }
- completed = true;
- try
- {
- byte authzid[] =
- authorizationID == null ? null : authorizationID.getBytes("UTF8");
- byte authnid[] = authenticationID.getBytes("UTF8");
- byte response[] =
- new byte[
- password.length +
- authnid.length +
- 2 + // SEPARATOR
- (authzid != null ? authzid.length : 0)
- ];
- int size = 0;
- if (authzid != null) {
- System.arraycopy(authzid, 0, response, 0, authzid.length);
- size = authzid.length;
- }
- response[size++] = SEPARATOR;
- System.arraycopy(authnid, 0, response, size, authnid.length);
- size += authnid.length;
- response[size++] = SEPARATOR;
- System.arraycopy(password, 0, response, size, password.length);
- clearPassword();
- return response;
- } catch (UnsupportedEncodingException e) {
- throw new SaslException("PLAIN: Cannot get UTF-8 encoding of ids",
- e);
- }
- }
-
- public String getMechanismName()
- {
- return "PLAIN";
- }
-
- public boolean hasInitialResponse()
- {
- return true;
- }
-
- public boolean isComplete()
- {
- return completed;
- }
-
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- if (completed) {
- throw new IllegalStateException("PLAIN: this mechanism supports " +
- "neither integrity nor privacy");
- } else {
- throw new IllegalStateException("PLAIN: authentication not " +
- "completed");
- }
- }
-
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- if (completed)
- {
- throw new IllegalStateException("PLAIN: this mechanism supports " +
- "neither integrity nor privacy");
- }
- else
- {
- throw new IllegalStateException("PLAIN: authentication not " +
- "completed");
- }
- }
-
- public Object getNegotiatedProperty(String propName)
- {
- if (completed)
- {
- if (propName.equals(Sasl.QOP))
- {
- return "auth";
- }
- else
- {
- return null;
- }
- }
- else
- {
- throw new IllegalStateException("PLAIN: authentication not " +
- "completed");
- }
- }
-
- private void clearPassword()
- {
- if (password != null)
- {
- for (int i = 0 ; i < password.length ; i++)
- {
- password[i] = 0;
- }
- password = null;
- }
- }
-
- public void dispose() throws SaslException
- {
- clearPassword();
- }
-
- protected void finalize()
- {
- clearPassword();
- }
-
- private Object[] getUserInfo() throws SaslException
- {
- try
- {
- final String userPrompt = "PLAIN authentication id: ";
- final String pwPrompt = "PLAIN password: ";
- NameCallback nameCb = new NameCallback(userPrompt);
- PasswordCallback passwordCb = new PasswordCallback(pwPrompt, false);
- cbh.handle(new Callback[] { nameCb, passwordCb });
- String userid = nameCb.getName();
- char pwchars[] = passwordCb.getPassword();
- byte pwbytes[];
- if (pwchars != null)
- {
- pwbytes = (new String(pwchars)).getBytes("UTF8");
- passwordCb.clearPassword();
- }
- else
- {
- pwbytes = null;
- }
- return (new Object[] { userid, pwbytes });
- }
- catch (IOException e)
- {
- throw new SaslException("Cannot get password", e);
- }
- catch (UnsupportedCallbackException e)
- {
- throw new SaslException("Cannot get userid/password", e);
- }
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java
deleted file mode 100644
index 1602229c85..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.sasl;
-
-import java.io.*;
-import javax.security.auth.callback.*;
-
-public class UserPasswordCallbackHandler implements CallbackHandler
-{
- private String user;
- private char[] pwchars;
-
- public UserPasswordCallbackHandler(String user, String password)
- {
- this.user = user;
- this.pwchars = password.toCharArray();
- }
-
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- for (int i = 0; i < callbacks.length; i++)
- {
- if (callbacks[i] instanceof NameCallback)
- {
- NameCallback ncb = (NameCallback) callbacks[i];
- ncb.setName(user);
- }
- else if (callbacks[i] instanceof PasswordCallback)
- {
- PasswordCallback pcb = (PasswordCallback) callbacks[i];
- pcb.setPassword(pwchars);
- }
- else
- {
- throw new UnsupportedCallbackException(callbacks[i]);
- }
- }
- }
-
- private void clearPassword()
- {
- if (pwchars != null)
- {
- for (int i = 0 ; i < pwchars.length ; i++)
- {
- pwchars[i] = 0;
- }
- pwchars = null;
- }
- }
-
- protected void finalize()
- {
- clearPassword();
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java
deleted file mode 100644
index f4e3d2661e..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.sasl;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.apache.qpid.management.ui.views.ViewUtility;
-
-public class UsernameHashedPasswordCallbackHandler implements CallbackHandler
-{
- private String user;
- private char[] pwchars;
-
- public UsernameHashedPasswordCallbackHandler(String user, String password) throws Exception
- {
- this.user = user;
- this.pwchars = ViewUtility.getHash(password);
- }
-
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- for (int i = 0; i < callbacks.length; i++)
- {
- if (callbacks[i] instanceof NameCallback)
- {
- NameCallback ncb = (NameCallback) callbacks[i];
- ncb.setName(user);
- }
- else if (callbacks[i] instanceof PasswordCallback)
- {
- PasswordCallback pcb = (PasswordCallback) callbacks[i];
- pcb.setPassword(pwchars);
- }
- else
- {
- throw new UnsupportedCallbackException(callbacks[i]);
- }
- }
- }
-
-
- private void clearPassword()
- {
- if (pwchars != null)
- {
- for (int i = 0 ; i < pwchars.length ; i++)
- {
- pwchars[i] = 0;
- }
- pwchars = null;
- }
- }
-
- protected void finalize()
- {
- clearPassword();
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
index 3234503fb5..f21647b2d2 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java
@@ -74,8 +74,8 @@ import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
/**
@@ -85,10 +85,10 @@ import org.eclipse.ui.forms.widgets.FormToolkit;
public class AttributesTabControl extends TabControl
{
private FormToolkit _toolkit;
- private Form _form;
+ private ScrolledForm _form;
private Table _table = null;
private TableViewer _tableViewer = null;
- private static final int[] tableWidths = new int[] {300, 300};
+ private int[] tableWidths = new int[] {275, 275};
private Composite _tableComposite = null;
private Composite _buttonsComposite = null;
@@ -98,7 +98,6 @@ public class AttributesTabControl extends TabControl
private Button _detailsButton = null;
private Button _editButton = null;
private Button _graphButton = null;
- private Button _refreshButton = null;
private boolean disableEditing = false;
private static final String MAX_VALUE = "MaxValue";
@@ -113,7 +112,7 @@ public class AttributesTabControl extends TabControl
{
super(tabFolder);
_toolkit = new FormToolkit(_tabFolder.getDisplay());
- _form = _toolkit.createForm(_tabFolder);
+ _form = _toolkit.createScrolledForm(_tabFolder);
GridLayout gridLayout = new GridLayout(2, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
@@ -122,7 +121,7 @@ public class AttributesTabControl extends TabControl
_tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
_tableComposite.setLayout(new GridLayout());
_buttonsComposite = _toolkit.createComposite(_form.getBody());
- _buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
+ _buttonsComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, true));
_buttonsComposite.setLayout(new GridLayout());
image = Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION);
@@ -162,7 +161,7 @@ public class AttributesTabControl extends TabControl
final TableColumn column = new TableColumn(_table, SWT.NONE);
column.setText(ATTRIBUTE_TABLE_TITLES[i]);
column.setWidth(tableWidths[i]);
- column.setResizable(false);
+ column.setResizable(true);
}
_table.setLinesVisible (true);
@@ -187,7 +186,6 @@ public class AttributesTabControl extends TabControl
addDetailsButton();
addEditButton();
addGraphButton();
- addRefreshButton();
}
private void addDetailsButton()
@@ -195,7 +193,7 @@ public class AttributesTabControl extends TabControl
// Create and configure the button for attribute details
_detailsButton = _toolkit.createButton(_buttonsComposite, BUTTON_DETAILS, SWT.PUSH | SWT.CENTER);
_detailsButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false);
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
gridData.widthHint = 80;
_detailsButton.setLayoutData(gridData);
_detailsButton.addSelectionListener(new SelectionAdapter()
@@ -220,7 +218,7 @@ public class AttributesTabControl extends TabControl
// Create and configure the button for editing attribute
_editButton = _toolkit.createButton(_buttonsComposite, BUTTON_EDIT_ATTRIBUTE, SWT.PUSH | SWT.CENTER);
_editButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false);
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
gridData.widthHint = 80;
_editButton.setLayoutData(gridData);
_editButton.addSelectionListener(new SelectionAdapter()
@@ -242,7 +240,7 @@ public class AttributesTabControl extends TabControl
{
_graphButton = _toolkit.createButton(_buttonsComposite, BUTTON_GRAPH, SWT.PUSH | SWT.CENTER);
_graphButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false);
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
gridData.widthHint = 80;
_graphButton.setLayoutData(gridData);
_graphButton.addSelectionListener(new SelectionAdapter()
@@ -256,35 +254,6 @@ public class AttributesTabControl extends TabControl
}
});
}
-
- /**
- * Creates the "Refresh" button
- */
- private void addRefreshButton()
- {
- _refreshButton = _toolkit.createButton(_buttonsComposite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
-
- _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- GridData gridData = new GridData(SWT.CENTER, SWT.TOP, false, false);
- gridData.widthHint = 80;
- _refreshButton.setLayoutData(gridData);
- _refreshButton.addSelectionListener(new SelectionAdapter()
- {
- public void widgetSelected(SelectionEvent e)
- {
- try
- {
- // refresh the attributes list
- refresh(_mbean);
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(_mbean, ex);
- }
-
- }
- });
- }
private void addTableListeners()
{
@@ -509,10 +478,24 @@ public class AttributesTabControl extends TabControl
{
if (!isSimpleType(attribute.getValue()))
{
- Composite composite = new Composite(parent, SWT.BORDER);
- composite.setLayout(new GridLayout());
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- ViewUtility.populateCompositeWithData(_toolkit, composite, attribute.getValue());
+ if (attribute.getValue() instanceof String[])
+ {
+ String result = new String("");
+ for(String val : (String[]) attribute.getValue()){
+ result = result.concat(val+ "; ");
+ }
+ value = _toolkit.createText(parent, "", textStyle);
+
+ value.setText(result);
+ value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ }
+ else
+ {
+ Composite composite = new Composite(parent, SWT.BORDER);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ ViewUtility.populateCompositeWithData(_toolkit, composite, attribute.getValue());
+ }
}
else
{
@@ -574,7 +557,7 @@ public class AttributesTabControl extends TabControl
AttributeData data = (AttributeData)button.getParent().getData();
MBeanUtility.updateAttribute(_mbean, data, text.getText());
button.getShell().close();
- refresh();
+ refresh(_mbean);
}
catch (Exception ex)
{
@@ -586,14 +569,6 @@ public class AttributesTabControl extends TabControl
return updateButton;
}
- // Refresh from the server registry
- public void refresh()
- {
- JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean);
- ManagedAttributeModel attributesList = serverRegistry.getAttributeModel(_mbean);
- _tableViewer.setInput(attributesList);
- }
-
/**
* Refreshes the attribute tab by querying the mbean server for latest values
*/
@@ -642,12 +617,10 @@ public class AttributesTabControl extends TabControl
_detailsButton.setEnabled(false);
_editButton.setEnabled(false);
_graphButton.setEnabled(false);
- _refreshButton.setEnabled(false);
return;
}
_detailsButton.setEnabled(true);
- _refreshButton.setEnabled(true);
if (attribute.isWritable())
{
_editButton.setEnabled(true);
@@ -877,7 +850,16 @@ public class AttributesTabControl extends TabControl
break;
case 1 : // attribute value column
if (attribute.getValue() != null)
- result = String.valueOf(attribute.getValue());
+ if (attribute.getValue() instanceof String[])
+ {
+ for(String val : (String[]) attribute.getValue()){
+ result = result.concat(val+ "; ");
+ }
+ }
+ else
+ {
+ result = String.valueOf(attribute.getValue());
+ }
break;
default :
result = "";
@@ -900,7 +882,7 @@ public class AttributesTabControl extends TabControl
{
attribute = (AttributeData) element;
if (attribute.isWritable())
- return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE);
+ return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
else
return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
}
@@ -933,4 +915,4 @@ public class AttributesTabControl extends TabControl
return collator.compare(attribtue1.getName(), attribtue2.getName());
}
}
-} \ No newline at end of file
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java
deleted file mode 100644
index ee55b251ee..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ExchangeTypeTabControl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-package org.apache.qpid.management.ui.views;
-
-import org.apache.qpid.management.ui.ApplicationRegistry;
-import org.apache.qpid.management.ui.Constants;
-import org.apache.qpid.management.ui.ManagedBean;
-import org.apache.qpid.management.ui.ServerRegistry;
-import org.eclipse.swt.widgets.TabFolder;
-
-/**
- * Controller class, which takes care of displaying appropriate information and widgets for Exchanges.
- * This allows user to select Exchanges and add those to the navigation view
- * @author Bhupendra Bhardwaj
- */
-public class ExchangeTypeTabControl extends MBeanTypeTabControl
-{
-
- public ExchangeTypeTabControl(TabFolder tabFolder)
- {
- super(tabFolder, Constants.EXCHANGE);
- createWidgets();
- }
-
- protected void createWidgets()
- {
- createHeaderComposite(getFormComposite());
- createButtonsComposite(getFormComposite());
- createListComposite(getFormComposite());
- }
-
- protected void populateList() throws Exception
- {
- // map should be cleared before populating it with new values
- getMBeansMap().clear();
-
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
- java.util.List<ManagedBean> list = serverRegistry.getExchanges(MBeanView.getVirtualHost());
- getListWidget().setItems(getItems(list));
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
new file mode 100644
index 0000000000..1fef89d6b5
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
@@ -0,0 +1,464 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views;
+
+import static org.apache.qpid.management.ui.Constants.ATTRIBUTES;
+import static org.apache.qpid.management.ui.Constants.CONNECTION;
+import static org.apache.qpid.management.ui.Constants.EXCHANGE;
+import static org.apache.qpid.management.ui.Constants.EXCHANGE_TYPE;
+import static org.apache.qpid.management.ui.Constants.NOTIFICATIONS;
+import static org.apache.qpid.management.ui.Constants.QUEUE;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.model.NotificationInfoModel;
+import org.apache.qpid.management.ui.model.OperationData;
+import org.apache.qpid.management.ui.model.OperationDataModel;
+import org.apache.qpid.management.ui.views.queue.QueueOperationsTabControl;
+import org.apache.qpid.management.ui.views.type.ConnectionTypeTabControl;
+import org.apache.qpid.management.ui.views.type.ExchangeTypeTabControl;
+import org.apache.qpid.management.ui.views.type.QueueTypeTabControl;
+import org.apache.qpid.management.ui.views.users.UserManagementTabControl;
+import org.apache.qpid.management.ui.views.vhost.VHostTabControl;
+import org.apache.qpid.management.ui.views.connection.ConnectionOperationsTabControl;
+import org.apache.qpid.management.ui.views.exchange.ExchangeOperationsTabControl;
+import org.apache.qpid.management.ui.views.exchange.HeadersExchangeOperationsTabControl;
+import org.apache.qpid.management.ui.views.logging.ConfigurationFileTabControl;
+import org.apache.qpid.management.ui.views.logging.RuntimeTabControl;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+public class MBeanTabFolderFactory
+{
+ private static final String MBEANTYPE_QUEUE = "VirtualHost.Queue";
+ private static final String MBEANTYPE_CONNECTION = "VirtualHost.Connection";
+ private static final String MBEANTYPE_EXCHANGE = "VirtualHost.Exchange";
+ private static final String MBEANTYPE_VHOST_MANAGER = "VirtualHost.VirtualHostManager";
+ private static final String MBEANTYPE_LOGGING_MANAGEMENT = "LoggingManagement";
+ private static final String MBEANTYPE_USER_MANAGEMENT = "UserManagement";
+ private static final String MBEANTYPE_CONFIGURATION_MANAGEMENT = "ConfigurationManagement";
+
+ private MBeanTabFolderFactory()
+ {
+ //no instances
+ }
+
+ public static TabFolder generateMBeanTabFolder(final Composite parent, final JMXManagedObject mbean, final MBeanServerConnection mbsc)
+ {
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ tabFolder.setLayoutData(layoutData);
+
+ TabItem tab;
+ TabControl controller;
+ QpidMBeanType mbeanType = QpidMBeanType.get(mbean.getType());
+
+ switch(mbeanType)
+ {
+ case QUEUE:
+ createAttributesTab(tabFolder, mbean);
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Operations");
+ controller = new QueueOperationsTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ break;
+ case CONNECTION:
+ createAttributesTab(tabFolder, mbean);
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Operations");
+ controller = new ConnectionOperationsTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ break;
+ case EXCHANGE:
+ createAttributesTab(tabFolder, mbean);
+
+ if (mbean.getProperty(EXCHANGE_TYPE).equalsIgnoreCase("headers"))
+ {
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Operations");
+ controller = new HeadersExchangeOperationsTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ }
+ else
+ {
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Operations");
+ controller = new ExchangeOperationsTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ }
+ break;
+ case VHOST_MANAGER:
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Operations");
+ controller = new VHostTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ break;
+ case LOGGING_MANAGEMENT:
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Runtime Options");
+ controller = new RuntimeTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("ConfigurationFile Options");
+ controller = new ConfigurationFileTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ break;
+ case USER_MANAGEMENT:
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText("Operations");
+ controller = new UserManagementTabControl(tabFolder, mbean, mbsc);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ break;
+ case CONFIGURATION_MANAGEMENT:
+ createGenericTabFolder(tabFolder, mbean);
+ break;
+ case UNKNOWN:
+ createGenericTabFolder(tabFolder, mbean);
+ break;
+ }
+
+ createNotificationsTabIfNecessary(tabFolder, mbean);
+
+ tabFolder.addListener(SWT.Selection, new Listener()
+ {
+ public void handleEvent(Event evt)
+ {
+ TabItem tab = (TabItem)evt.item;
+ TabControl controller = (TabControl)tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(mbean);
+ }
+ }
+ });
+
+ return tabFolder;
+ }
+
+ private static void createGenericTabFolder(TabFolder tabFolder, JMXManagedObject mbean)
+ {
+ createAttributesTab(tabFolder, mbean);
+ createOperationTabs(tabFolder, mbean);
+ }
+
+ private static void createAttributesTab(TabFolder tabFolder, JMXManagedObject mbean)
+ {
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(mbean);
+ if(serverRegistry.getAttributeModel(mbean).getCount() == 0)
+ {
+ return;
+ }
+
+ TabItem tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(ATTRIBUTES);
+ AttributesTabControl controller = new AttributesTabControl(tabFolder);
+ tab.setControl(controller.getControl());
+ tab.setData(TabControl.CONTROLLER, controller);
+ }
+
+ private static void createOperationTabs(TabFolder tabFolder, JMXManagedObject mbean)
+ {
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(mbean);
+ int operationsCount = serverRegistry.getOperationModel(mbean).getCount();
+ if(operationsCount == 0)
+ {
+ return;
+ }
+
+ OperationDataModel operationModel = serverRegistry.getOperationModel(mbean);
+ for(OperationData operationData : operationModel.getOperations())
+ {
+ TabItem operationTab = new TabItem(tabFolder, SWT.NONE);
+ operationTab.setText(ViewUtility.getDisplayText(operationData.getName()));
+ operationTab.setData(operationData);
+ OperationTabControl control = new OperationTabControl(tabFolder, operationData);
+ operationTab.setData(TabControl.CONTROLLER, control);
+ operationTab.setControl(control.getControl());
+ }
+ }
+
+ private static void createNotificationsTabIfNecessary(TabFolder tabFolder, JMXManagedObject mbean)
+ {
+ NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(mbean);
+ if(items == null || items.length == 0)
+ {
+ //the mbean has no notifications to subscribe for, do not create the tab.
+ return;
+ }
+
+ NotificationsTabControl controller = new NotificationsTabControl(tabFolder, mbean);
+
+ TabItem tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(NOTIFICATIONS);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+ }
+
+ /**
+ * Creates TabFolder and tabs for all mbeantype (Connection, Queue, and Exchange)
+ */
+ public static TabFolder generateMBeanTypeTabFolder(final Composite parent, ManagedServer server, String virtualHost)
+ {
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ tabFolder.setLayoutData(layoutData);
+
+
+ TabItem tab;
+ TabControl controller;
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(CONNECTION);
+ controller = new ConnectionTypeTabControl(tabFolder,server,virtualHost);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(EXCHANGE);
+ controller = new ExchangeTypeTabControl(tabFolder,server,virtualHost);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(QUEUE);
+ controller = new QueueTypeTabControl(tabFolder,server,virtualHost);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+
+ tabFolder.addListener(SWT.Selection, new Listener()
+ {
+ public void handleEvent(Event evt)
+ {
+ TabItem tab = (TabItem)evt.item;
+ TabControl controller = (TabControl)tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(null);
+ }
+ }
+ });
+
+ return tabFolder;
+ }
+
+ /**
+ * Creates TabFolder and tab for the Connection selection view
+ */
+ public static TabFolder generateConnectionTypeTabFolder(final Composite parent, ManagedServer server, String virtualHost)
+ {
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ tabFolder.setLayoutData(layoutData);
+
+ TabItem tab;
+ TabControl controller;
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(CONNECTION);
+ controller = new ConnectionTypeTabControl(tabFolder,server,virtualHost);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+
+ tabFolder.addListener(SWT.Selection, new Listener()
+ {
+ public void handleEvent(Event evt)
+ {
+ TabItem tab = (TabItem)evt.item;
+ TabControl controller = (TabControl)tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(null);
+ }
+ }
+ });
+
+ return tabFolder;
+ }
+
+ /**
+ * Creates TabFolder and tab for the Exchange selection view
+ */
+ public static TabFolder generateExchangeTypeTabFolder(final Composite parent, ManagedServer server, String virtualHost)
+ {
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ tabFolder.setLayoutData(layoutData);
+
+ TabItem tab;
+ TabControl controller;
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(EXCHANGE);
+ controller = new ExchangeTypeTabControl(tabFolder,server,virtualHost);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+
+ tabFolder.addListener(SWT.Selection, new Listener()
+ {
+ public void handleEvent(Event evt)
+ {
+ TabItem tab = (TabItem)evt.item;
+ TabControl controller = (TabControl)tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(null);
+ }
+ }
+ });
+
+ return tabFolder;
+ }
+
+ /**
+ * Creates TabFolder and tab for the Queue selection view
+ */
+ public static TabFolder generateQueueTypeTabFolder(final Composite parent, ManagedServer server, String virtualHost)
+ {
+ TabFolder tabFolder = new TabFolder(parent, SWT.NONE);
+ FormData layoutData = new FormData();
+ layoutData.left = new FormAttachment(0);
+ layoutData.top = new FormAttachment(0);
+ layoutData.right = new FormAttachment(100);
+ layoutData.bottom = new FormAttachment(100);
+ tabFolder.setLayoutData(layoutData);
+
+ TabItem tab;
+ TabControl controller;
+
+ tab = new TabItem(tabFolder, SWT.NONE);
+ tab.setText(QUEUE);
+ controller = new QueueTypeTabControl(tabFolder,server,virtualHost);
+ tab.setData(TabControl.CONTROLLER, controller);
+ tab.setControl(controller.getControl());
+
+ tabFolder.addListener(SWT.Selection, new Listener()
+ {
+ public void handleEvent(Event evt)
+ {
+ TabItem tab = (TabItem)evt.item;
+ TabControl controller = (TabControl)tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(null);
+ }
+ }
+ });
+
+ return tabFolder;
+ }
+
+ private enum QpidMBeanType
+ {
+ QUEUE (MBEANTYPE_QUEUE),
+ CONNECTION (MBEANTYPE_CONNECTION),
+ EXCHANGE (MBEANTYPE_EXCHANGE),
+ VHOST_MANAGER (MBEANTYPE_VHOST_MANAGER),
+ LOGGING_MANAGEMENT (MBEANTYPE_LOGGING_MANAGEMENT),
+ USER_MANAGEMENT (MBEANTYPE_USER_MANAGEMENT),
+ CONFIGURATION_MANAGEMENT (MBEANTYPE_CONFIGURATION_MANAGEMENT),
+ UNKNOWN (null);
+
+ private static final Map<String,QpidMBeanType> lookup = new HashMap<String,QpidMBeanType>();
+
+ static
+ {
+ for(QpidMBeanType m : EnumSet.allOf(QpidMBeanType.class))
+ {
+ lookup.put(m.getType(), m);
+ }
+ }
+
+ private String type;
+
+ private QpidMBeanType()
+ {
+
+ }
+
+ private QpidMBeanType(String type)
+ {
+ this.type = type;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public static QpidMBeanType get(String type)
+ {
+ QpidMBeanType t= lookup.get(type);
+ if (t != null)
+ {
+ return t;
+ }
+ else
+ {
+ return UNKNOWN;
+ }
+
+ }
+ }
+
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java
deleted file mode 100644
index 24dfb519fd..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-package org.apache.qpid.management.ui.views;
-
-import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
-import static org.apache.qpid.management.ui.Constants.FONT_BOLD;
-import static org.apache.qpid.management.ui.Constants.FONT_ITALIC;
-import static org.apache.qpid.management.ui.Constants.FONT_NORMAL;
-
-import java.util.Collections;
-import java.util.HashMap;
-
-import org.apache.qpid.management.ui.ApplicationRegistry;
-import org.apache.qpid.management.ui.ManagedBean;
-import org.apache.qpid.management.ui.jmx.MBeanUtility;
-import org.apache.qpid.management.ui.model.AttributeData;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.List;
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.forms.widgets.Form;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-
-/**
- * Abstract class to be extended by the Controller classes for different MBean types (Connection, Queue, Exchange)
- */
-public abstract class MBeanTypeTabControl
-{
- private FormToolkit _toolkit = null;
- private Form _form = null;
- private TabFolder _tabFolder = null;
- private Composite _composite = null;
- private Composite _headerComposite = null;
- private Composite _listComposite = null;
- private Label _labelName = null;
- private Label _labelDesc = null;
- private Label _labelList = null;
-
- private org.eclipse.swt.widgets.List _list = null;
- private Button _refreshButton = null;
- private Button _addButton = null;
-
- private String _type = null;
-
- // maps an mbean name with the mbean object. Required to get mbean object when an mbean
- // is to be added to the navigation view.
- private HashMap<String, ManagedBean> _objectsMap = new HashMap<String, ManagedBean>();
- private Sorter _sorterByName = new Sorter();
-
- public MBeanTypeTabControl(TabFolder tabFolder, String type)
- {
- _type = type;
- _tabFolder = tabFolder;
- _toolkit = new FormToolkit(_tabFolder.getDisplay());
- _form = _toolkit.createForm(_tabFolder);
- createFormComposite();
- }
-
- public FormToolkit getToolkit()
- {
- return _toolkit;
- }
-
- public Control getControl()
- {
- return _form;
- }
-
- public String getType()
- {
- return _type;
- }
-
- protected List getListWidget()
- {
- return _list;
- }
-
- protected HashMap<String, ManagedBean> getMBeansMap()
- {
- return _objectsMap;
- }
-
- public Sorter getMBeanNameSorter()
- {
- return _sorterByName;
- }
-
- public Button getAddButton()
- {
- return _addButton;
- }
-
- public Button getRefreshButton()
- {
- return _refreshButton;
- }
-
- /**
- * Creates the main Composite, which will contain all other Composites and Widgets
- */
- protected void createFormComposite()
- {
- _form.getBody().setLayout(new GridLayout());
- _composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
- _composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- GridLayout layout = new GridLayout();
- layout.verticalSpacing = 10;
- layout.horizontalSpacing = 0;
- _composite.setLayout(layout);
- }
-
- protected Composite getFormComposite()
- {
- return _composite;
- }
-
- /**
- * Creates the header composite, which has MBean type name and description
- * @param parentComposite
- */
- protected void createHeaderComposite(Composite parentComposite)
- {
- _headerComposite = _toolkit.createComposite(parentComposite);
- _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- GridLayout layout = new GridLayout();
- layout.verticalSpacing = 10;
- layout.horizontalSpacing = 0;
- _headerComposite.setLayout(layout);
-
- _labelName = _toolkit.createLabel(_headerComposite, "Type:", SWT.NONE);
- GridData gridData = new GridData(SWT.CENTER, SWT.TOP, true, false);
- _labelName.setLayoutData(gridData);
- _labelName.setFont(ApplicationRegistry.getFont(FONT_BOLD));
-
- _labelDesc = _toolkit.createLabel(_headerComposite, " ", SWT.NONE);
- _labelDesc.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false));
- _labelDesc.setFont(ApplicationRegistry.getFont(FONT_ITALIC));
-
- _headerComposite.layout();
- }
-
- /**
- * Creates Composite, which contains the common buttons - Add and Refresh.
- * @param parentComposite
- */
- protected void createButtonsComposite(Composite parentComposite)
- {
- Composite composite = _toolkit.createComposite(parentComposite);
- composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- GridLayout layout = new GridLayout(2, true);
- layout.verticalSpacing = 10;
- layout.horizontalSpacing = 20;
- composite.setLayout(layout);
-
- createAddButton(composite);
- createRefreshButton(composite);
- }
-
- /**
- * Creates the Add button, which adds the selected item to the navigation view
- * @param parentComposite
- */
- protected void createAddButton(Composite parentComposite)
- {
- Button _addButton = _toolkit.createButton(parentComposite, "<- Add to Navigation", SWT.PUSH);
- GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false);
- _addButton.setLayoutData(gridData);
- _addButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e)
- {
- if (_list.getSelectionCount() == 0)
- return;
-
- String[] selectedItems = _list.getSelection();
- for (int i = 0; i < selectedItems.length; i++)
- {
- String name = selectedItems[i];
- // pass the ManagedBean to the navigation view to be added
- ManagedBean mbean = _objectsMap.get(name);
- IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
- NavigationView view = (NavigationView)window.getActivePage().findView(NavigationView.ID);
- try
- {
- view.addManagedBean(mbean);
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(mbean, ex);
- }
- }
- }
- });
- }
-
- /**
- * Creates the Refresh button, which gets syncs the items with the broker server
- * @param parentComposite
- */
- protected void createRefreshButton(Composite parentComposite)
- {
- Button _refreshButton = _toolkit.createButton(parentComposite, BUTTON_REFRESH, SWT.PUSH);
- GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false);
- gridData.widthHint = 120;
- _refreshButton.setLayoutData(gridData);
- _refreshButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e)
- {
- try
- {
- // refresh the list from the broker server
- populateList();
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(ex);
- }
- }
- });
- }
-
- /**
- * Creates the Composite, which contains the items ( Connections, Exchanges or Queues)
- * @param parentComposite
- */
- protected void createListComposite(Composite parentComposite)
- {
- // Composite to contain the item list
- _listComposite = _toolkit.createComposite(parentComposite);
- GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
- _listComposite.setLayoutData(gridData);
- GridLayout layout = new GridLayout();
- layout.verticalSpacing = 0;
- _listComposite.setLayout(layout);
-
- // Label for item name
- _labelList = _toolkit.createLabel(_listComposite, " ", SWT.CENTER);
- gridData = new GridData(SWT.CENTER, SWT.TOP, true, false, 1, 1);
- _labelList.setLayoutData(gridData);
- _labelList.setFont(ApplicationRegistry.getFont(FONT_NORMAL));
-
- _list = new List(_listComposite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- gridData = new GridData(SWT.FILL, SWT.FILL, true, true,1, 1);
- _list.setLayoutData(gridData);
-
- }
-
- /**
- * This is called from MBean View to refresh the tab contents
- * @throws Exception
- */
- public void refresh() throws Exception
- {
- setLabelValues();
- populateList();
- layout();
- }
-
- protected void setLabelValues()
- {
- _labelName.setText("Type : " + _type);
- _labelDesc.setText("Select the " + _type + "(s) to add in the Navigation View");
- _labelList.setText("-- List of " + _type + "s --");
- }
-
- protected abstract void populateList() throws Exception;
-
- public void layout()
- {
- _form.layout(true);
- _form.getBody().layout(true, true);
- }
-
- // sets the map with appropriate mbean and name
- protected String[] getItems(java.util.List<ManagedBean> list)
- {
- if (list == null)
- return new String[0];
-
- Collections.sort(list, _sorterByName);
- String[] items = new String[list.size()];
- int i = 0;
- for (ManagedBean mbean : list)
- {
- items[i++] = mbean.getName();
- _objectsMap.put(mbean.getName(), mbean);
- }
- return items;
- }
-
- protected class ComparatorImpl implements java.util.Comparator<AttributeData>
- {
- public int compare(AttributeData data1, AttributeData data2)
- {
- Integer int1 = Integer.parseInt(data1.getValue().toString());
- Integer int2 = Integer.parseInt(data2.getValue().toString());
- return int1.compareTo(int2) * -1;
- }
- }
-
- protected class Sorter implements java.util.Comparator<ManagedBean>
- {
- public int compare(ManagedBean mbean1, ManagedBean mbean2)
- {
- return mbean1.getName().compareTo(mbean2.getName());
- }
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
index 344c3c4e7f..9763c799d7 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
@@ -20,29 +20,32 @@
*/
package org.apache.qpid.management.ui.views;
-import java.util.HashMap;
+import java.util.LinkedList;
+
+import javax.management.MBeanServerConnection;
import static org.apache.qpid.management.ui.Constants.*;
+
+import org.apache.qpid.management.ui.ApiVersion;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
import org.apache.qpid.management.ui.ManagedServer;
import org.apache.qpid.management.ui.ServerRegistry;
-import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.actions.BackAction;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
-import org.apache.qpid.management.ui.model.AttributeData;
-import org.apache.qpid.management.ui.model.OperationData;
-import org.apache.qpid.management.ui.model.OperationDataModel;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.forms.widgets.Form;
@@ -51,14 +54,10 @@ import org.eclipse.ui.part.ViewPart;
/**
* MBean View create appropriate view based on the user selection on the Navigation View.
- * Create TabFolder for all MBeans and displays the attribtues and method tabs.
- * @author Bhupendra Bhardwaj
- *
*/
public class MBeanView extends ViewPart
{
public static final String ID = "org.apache.qpid.management.ui.mbeanView";
- private static final String CONTROLLER = "CONTROLLER";
private FormToolkit _toolkit = null;
private Form _form = null;
@@ -67,15 +66,18 @@ public class MBeanView extends ViewPart
private TreeObject _selectedNode = null;
private ManagedBean _mbean = null;
private static String _virtualHostName = null;
- // This map contains a TabFolder for each kind of MBean.
- // TabFolder is mapped with mbeantype(Connection, Queue and Exchange)
- private HashMap<String, TabFolder> tabFolderMap = new HashMap<String, TabFolder>();
- private ISelectionListener selectionListener = new SelectionListenerImpl();
+ private static MBeanServerConnection _mbsc = null;
+ private TabFolder _tabFolder = null;
+ private ISelectionListener _selectionListener = new SelectionListenerImpl();
// TabFolder to list all the mbeans for a given mbeantype(eg Connection, Queue, Exchange)
- private TabFolder typeTabFolder = null;
+ private TabFolder _typeTabFolder = null;
+
+ private TabFolder _notificationTabFolder = null;
+
+ private LinkedList<Object> _backHistory;
+ private BackAction _backAction;
- private TabFolder notificationTabFolder = null;
/*
* Listener for the selection events in the navigation view
*/
@@ -93,16 +95,84 @@ public class MBeanView extends ViewPart
// mbean should be set to null. A selection done on the navigation view can be either an mbean or
// an mbeantype. For mbeantype selection(eg Connection, Queue, Exchange) _mbean will remain null.
_mbean = null;
- setInvisible();
+ clearView();
+
+ //clear the back history, it is only for use when opening subsequent mbeans not in the nav tree
+ _backHistory.clear();
+ _backAction.setEnabled(false);
// If a selected node(mbean) gets unregistered from mbean server, mbeanview should
// make the tabfolber for that mbean invisible
- if (_selectedNode == null)
+ if (_selectedNode == null)
+ {
return;
+ }
setServer();
- refreshMBeanView();
- setFormTitle();
+
+ if(!ApplicationRegistry.isServerConnected(_server))
+ {
+ return;
+ }
+
+ if (MBEAN.equals(_selectedNode.getType()))
+ {
+ _mbean = (ManagedBean)_selectedNode.getManagedObject();
+ }
+
+ setFormTitle();
+ showRelevantTabView();
+ }
+ }
+
+ public void openMBean(ManagedBean mbean)
+ {
+ openMBean(mbean, false);
+ }
+
+ private void openMBean(ManagedBean mbean, boolean undoing)
+ {
+ if(mbean == null)
+ {
+ return;
+ }
+
+ //if an mbean is about to be opened (but not returning to using back) from the mbean view,
+ //then record the current viewed area/object as a means of back history
+ if(!undoing)
+ {
+ if(_backHistory.isEmpty())
+ {
+ //ensure the button is enabled if this is to be the first history item
+ _backAction.setEnabled(true);
+ }
+
+ if(_mbean == null)
+ {
+ //queue etc selection area is open, record the tree object
+ _backHistory.addLast(_selectedNode);
+ }
+ else
+ {
+ _backHistory.addLast(_mbean);
+ }
+ }
+
+ _mbean = mbean;
+
+ try
+ {
+ clearView();
+
+ setFormTitle();
+ showMBean(mbean);
+
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+ catch(Exception ex)
+ {
+ MBeanUtility.handleException(mbean, ex);
}
}
@@ -131,32 +201,58 @@ public class MBeanView extends ViewPart
_form.setText(_formText);
}
- public void refreshMBeanView()
+ public void showRelevantTabView()
{
try
{
- if (NODE_TYPE_SERVER.equals(_selectedNode.getType()) ||
- NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) )
+ if (_selectedNode == null)
{
return;
}
- else if (NODE_TYPE_TYPEINSTANCE.equals(_selectedNode.getType()))
+
+ String mbeanType = _selectedNode.getType();
+
+ if (NODE_TYPE_TYPEINSTANCE.equals(mbeanType))
{
// An virtual host instance is selected
- refreshTypeTabFolder(typeTabFolder.getItem(0));
+ generateTypeTabFolder();
}
- else if (NODE_TYPE_MBEANTYPE.equals(_selectedNode.getType()))
+ else if (NODE_TYPE_MBEANTYPE.equals(mbeanType))
{
- refreshTypeTabFolder(_selectedNode.getName());
+ showTypeTabFolder(_selectedNode.getName());
}
- else if (NOTIFICATIONS.equals(_selectedNode.getType()))
+ else if (NOTIFICATIONS.equals(mbeanType))
{
refreshNotificationPage();
}
- else if (MBEAN.equals(_selectedNode.getType()))
+ else if (MBEAN.equals(mbeanType))
+ {
+ showMBean(_mbean);
+ }
+ else if(NODE_TYPE_SERVER.equals(mbeanType))
+ {
+ ServerRegistry serverReg = ApplicationRegistry.getServerRegistry(_server);
+
+ //check the server is connected
+ if(serverReg != null)
+ {
+ //post a message if the server supports a newer API version.
+ ApiVersion serverAPI = serverReg.getManagementApiVersion();
+ int supportedMajor = ApplicationRegistry.SUPPORTED_QPID_JMX_API_MAJOR_VERSION;
+ int supportedMinor = ApplicationRegistry.SUPPORTED_QPID_JMX_API_MINOR_VERSION;
+
+ if(serverAPI.greaterThan(supportedMajor, supportedMinor))
+ {
+ _form.setText("The server supports an updated management API and may offer " +
+ "functionality not available with this console. " +
+ "Please check for an updated console release.");
+ }
+
+ }
+ }
+ else
{
- _mbean = (ManagedBean)_selectedNode.getManagedObject();
- showSelectedMBean();
+ return;
}
_form.layout(true);
@@ -176,8 +272,7 @@ public class MBeanView extends ViewPart
*/
private void setServer()
{
- if (NODE_TYPE_SERVER.equals(_selectedNode.getType()) ||
- NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) )
+ if (NODE_TYPE_SERVER.equals(_selectedNode.getType()))
{
_server = (ManagedServer)_selectedNode.getManagedObject();
_virtualHostName = null;
@@ -195,6 +290,11 @@ public class MBeanView extends ViewPart
_virtualHostName = _selectedNode.getVirtualHost();
}
+
+ JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_server);
+ if(serverRegistry != null){
+ _mbsc = serverRegistry.getServerConnection();
+ }
}
public static ManagedServer getServer()
@@ -207,45 +307,36 @@ public class MBeanView extends ViewPart
return _virtualHostName;
}
- private void showSelectedMBean() throws Exception
+ private void showMBean(ManagedBean mbean) throws Exception
{
try
{
- MBeanUtility.getMBeanInfo(_mbean);
+ MBeanUtility.getMBeanInfo(mbean);
}
catch(Exception ex)
{
- MBeanUtility.handleException(_mbean, ex);
+ MBeanUtility.handleException(mbean, ex);
return;
}
- TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
- /*
- * This solution can be used if there are many versions of Qpid running. Otherwise
- * there is no need to create a tabFolder everytime a bean is selected.
- if (tabFolder != null && !tabFolder.isDisposed())
- {
- tabFolder.dispose();
- }
- tabFolder = createTabFolder();
- */
- if (tabFolder == null)
+ if (_tabFolder != null && !_tabFolder.isDisposed())
{
- tabFolder = createMBeanTabFolder();
+ _tabFolder.dispose();
}
+ _tabFolder = MBeanTabFolderFactory.generateMBeanTabFolder(_form.getBody(),(JMXManagedObject)mbean,_mbsc);
+
int tabIndex = 0;
if (NOTIFICATIONS.equals(_selectedNode.getType()))
{
- tabIndex = tabFolder.getItemCount() -1;
+ tabIndex = _tabFolder.getItemCount() -1;
}
- TabItem tab = tabFolder.getItem(tabIndex);
+ TabItem tab = _tabFolder.getItem(tabIndex);
// If folder is being set as visible after tab refresh, then the tab
// doesn't have the focus.
- tabFolder.setSelection(tabIndex);
+ _tabFolder.setSelection(tabIndex);
refreshTab(tab);
- setVisible(tabFolder);
}
public void createPartControl(Composite parent)
@@ -257,57 +348,30 @@ public class MBeanView extends ViewPart
_form.setText(APPLICATION_NAME);
// Add selection listener for selection events in the Navigation view
- getSite().getPage().addSelectionListener(NavigationView.ID, selectionListener);
-
- // Add mbeantype TabFolder. This will list all the mbeans under a mbeantype (eg Queue, Exchange).
- // Using this list mbeans will be added in the navigation view
- createMBeanTypeTabFolder();
-
+ getSite().getPage().addSelectionListener(NavigationView.ID, _selectionListener);
+
createNotificationsTabFolder();
- }
-
- private TabFolder createMBeanTabFolder()
- {
- TabFolder tabFolder = new TabFolder(_form.getBody(), SWT.NONE);
- FormData layoutData = new FormData();
- layoutData.left = new FormAttachment(0);
- layoutData.top = new FormAttachment(0);
- layoutData.right = new FormAttachment(100);
- layoutData.bottom = new FormAttachment(100);
- tabFolder.setLayoutData(layoutData);
- tabFolder.setVisible(false);
-
- createAttributesTab(tabFolder);
- createOperationTabs(tabFolder);
- createNotificationsTab(tabFolder);
- tabFolder.addListener(SWT.Selection, new Listener()
- {
- public void handleEvent(Event evt)
- {
- TabItem tab = (TabItem)evt.item;
- refreshTab(tab);
- }
- });
+ ViewUtility.setMBeanView(this);
- tabFolderMap.put(_mbean.getType(), tabFolder);
- return tabFolder;
+ _backAction = new BackAction();
+ getViewSite().getActionBars().getToolBarManager().add(_backAction);
+ _backAction.setEnabled(false);
+ _backHistory = new LinkedList<Object>();
}
private void refreshTab(TabItem tab)
{
- // We can avoid refreshing the attributes tab because it's control
- // already contains the required values. But it is added for now and
- // will remove if there is any performance issue or any other issue.
- // The operations control should be refreshed because there is only one
- // controller for all operations tab.
- // The Notifications control needs to refresh with latest set of notifications
-
if (tab == null)
+ {
return;
+ }
- TabControl controller = (TabControl)tab.getData(CONTROLLER);
- controller.refresh(_mbean);
+ TabControl controller = (TabControl)tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(_mbean);
+ }
}
public void setFocus()
@@ -321,225 +385,216 @@ public class MBeanView extends ViewPart
super.dispose();
}
- private void createAttributesTab(TabFolder tabFolder)
- {
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
- if (serverRegistry.getAttributeModel(_mbean).getCount() == 0)
- {
- return;
- }
-
- TabItem tab = new TabItem(tabFolder, SWT.NONE);
- tab.setText(ATTRIBUTES);
- AttributesTabControl controller = new AttributesTabControl(tabFolder);
- tab.setControl(controller.getControl());
- tab.setData(CONTROLLER, controller);
- }
-
- private void createOperationTabs(TabFolder tabFolder)
- {
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
- int operationsCount = serverRegistry.getOperationModel(_mbean).getCount();
- if (operationsCount == 0)
- {
- return;
- }
-
- OperationDataModel operationModel = serverRegistry.getOperationModel(_mbean);
- for (OperationData operationData : operationModel.getOperations())
- {
- TabItem operationTab = new TabItem(tabFolder, SWT.NONE);
- operationTab.setText(ViewUtility.getDisplayText(operationData.getName()));
- operationTab.setData(operationData);
- OperationTabControl control = new OperationTabControl(tabFolder, operationData);
- operationTab.setData(CONTROLLER, control);
- operationTab.setControl(control.getControl());
- }
- }
-
- private void createNotificationsTab(TabFolder tabFolder)
- {
- NotificationsTabControl controller = new NotificationsTabControl(tabFolder);
-
- TabItem tab = new TabItem(tabFolder, SWT.NONE);
- tab.setText(NOTIFICATIONS);
- tab.setData(CONTROLLER, controller);
- tab.setControl(controller.getControl());
- }
-
- /**
- * For the EditAttribtue Action. Invoking this from action is same as clicking
- * "EditAttribute" button from Attribute tab.
- */
- public void editAttribute() throws Exception
- {
- if (_mbean == null)
- throw new InfoRequiredException("Please select the managed object and then attribute to be edited");
-
- String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType();
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
- if (serverRegistry.getAttributeModel(_mbean).getCount() == 0)
- {
- throw new InfoRequiredException("There are no attributes to be edited for " + name);
- }
-
- TabFolder tabFolder = tabFolderMap.get(_mbean.getType());
- int index = tabFolder.getSelectionIndex();
- if (index != 0)
- {
- tabFolder.setSelection(0);
- throw new InfoRequiredException("Please select the attribute to be edited");
- }
-
- TabItem tab = tabFolder.getItem(0);
- AttributesTabControl tabControl = (AttributesTabControl)tab.getData(CONTROLLER);
- AttributeData attribute = tabControl.getSelectionAttribute();
- if (attribute == null)
- throw new InfoRequiredException("Please select the attribute to be edited");
-
- tabControl.createDetailsPopup(attribute);
- }
-
- /**
- * Creates TabFolder and tabs for each mbeantype (eg Connection, Queue, Exchange)
- */
- private void createMBeanTypeTabFolder()
- {
- typeTabFolder = new TabFolder(_form.getBody(), SWT.NONE);
- FormData layoutData = new FormData();
- layoutData.left = new FormAttachment(0);
- layoutData.top = new FormAttachment(0);
- layoutData.right = new FormAttachment(100);
- layoutData.bottom = new FormAttachment(100);
- typeTabFolder.setLayoutData(layoutData);
- typeTabFolder.setVisible(false);
-
- TabItem tab = new TabItem(typeTabFolder, SWT.NONE);
- tab.setText(CONNECTION);
- MBeanTypeTabControl controller = new ConnectionTypeTabControl(typeTabFolder);
- tab.setData(CONTROLLER, controller);
- tab.setControl(controller.getControl());
-
- tab = new TabItem(typeTabFolder, SWT.NONE);
- tab.setText(EXCHANGE);
- controller = new ExchangeTypeTabControl(typeTabFolder);
- tab.setData(CONTROLLER, controller);
- tab.setControl(controller.getControl());
-
- tab = new TabItem(typeTabFolder, SWT.NONE);
- tab.setText(QUEUE);
- controller = new QueueTypeTabControl(typeTabFolder);
- tab.setData(CONTROLLER, controller);
- tab.setControl(controller.getControl());
-
- typeTabFolder.addListener(SWT.Selection, new Listener()
- {
- public void handleEvent(Event evt)
- {
- TabItem tab = (TabItem)evt.item;
- try
- {
- refreshTypeTabFolder(tab);
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(ex);
- }
- }
- });
- }
private void createNotificationsTabFolder()
{
- notificationTabFolder = new TabFolder(_form.getBody(), SWT.NONE);
+ _notificationTabFolder = new TabFolder(_form.getBody(), SWT.NONE);
FormData layoutData = new FormData();
layoutData.left = new FormAttachment(0);
layoutData.top = new FormAttachment(0);
layoutData.right = new FormAttachment(100);
layoutData.bottom = new FormAttachment(100);
- notificationTabFolder.setLayoutData(layoutData);
- notificationTabFolder.setVisible(false);
+ _notificationTabFolder.setLayoutData(layoutData);
+ _notificationTabFolder.setVisible(false);
- VHNotificationsTabControl controller = new VHNotificationsTabControl(notificationTabFolder);
- TabItem tab = new TabItem(notificationTabFolder, SWT.NONE);
+ VHNotificationsTabControl controller = new VHNotificationsTabControl(_notificationTabFolder);
+ TabItem tab = new TabItem(_notificationTabFolder, SWT.NONE);
tab.setText(NOTIFICATIONS);
- tab.setData(CONTROLLER, controller);
+ tab.setData(TabControl.CONTROLLER, controller);
tab.setControl(controller.getControl());
}
private void refreshNotificationPage()
{
- TabItem tab = notificationTabFolder.getItem(0);
- VHNotificationsTabControl controller = (VHNotificationsTabControl)tab.getData(CONTROLLER);
+ TabItem tab = _notificationTabFolder.getItem(0);
+ VHNotificationsTabControl controller = (VHNotificationsTabControl)tab.getData(TabControl.CONTROLLER);
controller.refresh();
- notificationTabFolder.setVisible(true);
+ _notificationTabFolder.setVisible(true);
}
- /**
- * Refreshes the Selected mbeantype tab. The control lists all the available mbeans
- * for an mbeantype(eg Queue, Exchange etc)
- * @param tab
- * @throws Exception
- */
- private void refreshTypeTabFolder(TabItem tab) throws Exception
+
+
+ private void generateTypeTabFolder() throws Exception
{
- if (tab == null)
+ if (_typeTabFolder != null && !_typeTabFolder.isDisposed())
{
- return;
+ _typeTabFolder.dispose();
}
- typeTabFolder.setSelection(tab);
- MBeanTypeTabControl controller = (MBeanTypeTabControl)tab.getData(CONTROLLER);
- controller.refresh();
- typeTabFolder.setVisible(true);
+
+ //Generates the full Queue/Connection/Exchange selection tab set
+ _typeTabFolder = MBeanTabFolderFactory.generateMBeanTypeTabFolder(
+ _form.getBody(), getServer(), getVirtualHost());
+ refreshTab(_typeTabFolder.getItem(0));
}
- private void refreshTypeTabFolder(String type) throws Exception
+ private void showTypeTabFolder(String type) throws Exception
{
+ if (_typeTabFolder != null && !_typeTabFolder.isDisposed())
+ {
+ _typeTabFolder.dispose();
+ }
+
if (CONNECTION.equals(type))
{
- refreshTypeTabFolder(typeTabFolder.getItem(0));
+ //Generates the Connection selection tab
+ _typeTabFolder = MBeanTabFolderFactory.generateConnectionTypeTabFolder(
+ _form.getBody(), getServer(), getVirtualHost());
+ refreshTab(_typeTabFolder.getItem(0));
}
else if (EXCHANGE.equals(type))
{
- refreshTypeTabFolder(typeTabFolder.getItem(1));
+ //Generates the Exchange selection tab
+ _typeTabFolder = MBeanTabFolderFactory.generateExchangeTypeTabFolder(
+ _form.getBody(), getServer(), getVirtualHost());
+ refreshTab(_typeTabFolder.getItem(0));
}
else if (QUEUE.equals(type))
{
- refreshTypeTabFolder(typeTabFolder.getItem(2));
+ //Generates the Queue selection tab
+ _typeTabFolder = MBeanTabFolderFactory.generateQueueTypeTabFolder(
+ _form.getBody(), getServer(), getVirtualHost());
+ refreshTab(_typeTabFolder.getItem(0));
+ }
+ }
+
+ private void clearView()
+ {
+ if (_tabFolder != null && !_tabFolder.isDisposed())
+ {
+ _tabFolder.setVisible(false);
+ }
+
+ if (_typeTabFolder != null && !_typeTabFolder.isDisposed())
+ {
+ _typeTabFolder.setVisible(false);
+ }
+
+ if (_notificationTabFolder != null && !_notificationTabFolder.isDisposed())
+ {
+ _notificationTabFolder.setVisible(false);
}
+
+ _form.setText(APPLICATION_NAME);
+ populateStatusBar("");
}
- /**
- * hides other folders and makes the given one visible.
- * @param tabFolder
- */
- private void setVisible(TabFolder tabFolder)
+ public void mbeanUnregistered(ManagedBean mbean)
{
- for (TabFolder folder : tabFolderMap.values())
+ //if the mbean is actually open, clear the view and empty the Back history
+ if(mbean == _mbean)
{
- if (folder == tabFolder)
- folder.setVisible(true);
- else
- folder.setVisible(false);
+ clearView();
+ _backHistory.clear();
+ _backAction.setEnabled(false);
+ ViewUtility.popupInfoMessage("MBean Unregistered",
+ "The open MBean was unregistered from the server.");
}
}
- private void setInvisible()
+ public void refresh()
{
- for (TabFolder folder : tabFolderMap.values())
+ if(!ApplicationRegistry.isServerConnected(_server))
{
- folder.setVisible(false);
+ return;
}
- if (typeTabFolder != null)
+ if (_tabFolder != null && !_tabFolder.isDisposed())
{
- typeTabFolder.setVisible(false);
+ if(_tabFolder.getVisible())
+ {
+ int selectedTab = _tabFolder.getSelectionIndex();
+ TabItem tab = _tabFolder.getItem(selectedTab);
+ TabControl controller = (TabControl) tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(_mbean);
+ }
+ return;
+ }
}
- if (notificationTabFolder != null)
+ if (_typeTabFolder != null && !_typeTabFolder.isDisposed())
{
- notificationTabFolder.setVisible(false);
+
+ if(_typeTabFolder.getVisible())
+ {
+ int selectedTab = _typeTabFolder.getSelectionIndex();
+ TabItem tab = _typeTabFolder.getItem(selectedTab);
+ TabControl controller = (TabControl) tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(_mbean);
+ }
+ return;
+ }
+ }
+
+ if (_notificationTabFolder != null && !_notificationTabFolder.isDisposed())
+ {
+ if(_notificationTabFolder.getVisible())
+ {
+ int selectedTab = _notificationTabFolder.getSelectionIndex();
+ TabItem tab = _notificationTabFolder.getItem(selectedTab);
+ TabControl controller = (TabControl) tab.getData(TabControl.CONTROLLER);
+ if(controller != null)
+ {
+ controller.refresh(_mbean);
+ }
+ return;
+ }
}
}
+ public void populateStatusBar(Image icon, String message)
+ {
+ IActionBars bars = getViewSite().getActionBars();
+ bars.getStatusLineManager().setMessage(icon, message);
+ }
+
+ public void populateStatusBar(String message)
+ {
+ IActionBars bars = getViewSite().getActionBars();
+ bars.getStatusLineManager().setMessage(message);
+ }
+
+ public void back() throws Exception
+ {
+ if(_backHistory.isEmpty())
+ {
+ return;
+ }
+
+ Object previous = _backHistory.removeLast();
+ if(_backHistory.isEmpty())
+ {
+ //if this is the last history item, disable the action button
+ _backAction.setEnabled(false);
+ }
+
+ if(previous instanceof ManagedBean)
+ {
+ openMBean((ManagedBean)previous, true);
+ }
+ else if (previous instanceof TreeObject)
+ {
+ _mbean = null;
+ clearView();
+ setFormTitle();
+
+ TreeObject node = (TreeObject) previous;
+ String mbeanType = node.getType();
+
+ if (NODE_TYPE_TYPEINSTANCE.equals(mbeanType))
+ {
+ generateTypeTabFolder();
+ }
+ else if (NODE_TYPE_MBEANTYPE.equals(mbeanType))
+ {
+ showTypeTabFolder(node.getName());
+ }
+ }
+
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
index 1da13a9b56..1ca6c2b71d 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
@@ -21,18 +21,28 @@
package org.apache.qpid.management.ui.views;
import static org.apache.qpid.management.ui.Constants.*;
+import static org.apache.qpid.management.ui.ApplicationRegistry.DATA_DIR;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.apache.qpid.management.common.mbeans.ServerInformation;
+import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.qpid.management.ui.ApiVersion;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedObject;
import org.apache.qpid.management.ui.ManagedServer;
import org.apache.qpid.management.ui.ServerRegistry;
import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
+import org.apache.qpid.management.ui.exceptions.ManagementConsoleException;
import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.eclipse.jface.preference.PreferenceStore;
@@ -62,6 +72,8 @@ import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
/**
@@ -72,7 +84,7 @@ import org.eclipse.ui.part.ViewPart;
public class NavigationView extends ViewPart
{
public static final String ID = "org.apache.qpid.management.ui.navigationView";
- public static final String INI_FILENAME = System.getProperty("user.home") + File.separator + "qpidManagementConsole.ini";
+ public static final String INI_FILENAME = DATA_DIR + File.separator + "qpidmc_navigation.ini";
private static final String INI_SERVERS = "Servers";
private static final String INI_QUEUES = QUEUE + "s";
@@ -80,12 +92,19 @@ public class NavigationView extends ViewPart
private static final String INI_EXCHANGES = EXCHANGE + "s";
private TreeViewer _treeViewer = null;
- private TreeObject _rootNode = null;
private TreeObject _serversRootNode = null;
private PreferenceStore _preferences;
// Map of connected servers
- private HashMap<ManagedServer, TreeObject> _managedServerMap = new HashMap<ManagedServer, TreeObject>();
+ private ConcurrentHashMap<ManagedServer, TreeObject> _managedServerMap = new ConcurrentHashMap<ManagedServer, TreeObject>();
+
+ private static HashSet<String> _serverTopLevelMBeans = new HashSet<String>();
+ {
+ _serverTopLevelMBeans.add(UserManagement.TYPE);
+ _serverTopLevelMBeans.add(LoggingManagement.TYPE);
+ _serverTopLevelMBeans.add(ConfigurationManagement.TYPE);
+ _serverTopLevelMBeans.add(ServerInformation.TYPE);
+ }
private void createTreeViewer(Composite parent)
{
@@ -131,16 +150,26 @@ public class NavigationView extends ViewPart
{
public void treeExpanded(TreeExpansionEvent event)
{
- _treeViewer.setExpandedState(event.getElement(), true);
- // Following will cause the selection event to be sent, so commented
- // _treeViewer.setSelection(new StructuredSelection(event.getElement()));
- _treeViewer.refresh();
+ getSite().getShell().getDisplay().asyncExec(
+ new Runnable()
+ {
+ public void run()
+ {
+ _treeViewer.refresh();
+ }
+ });
}
public void treeCollapsed(TreeExpansionEvent event)
{
- _treeViewer.setExpandedState(event.getElement(), false);
- _treeViewer.refresh();
+ getSite().getShell().getDisplay().asyncExec(
+ new Runnable()
+ {
+ public void run()
+ {
+ _treeViewer.refresh();
+ }
+ });
}
});
@@ -180,7 +209,7 @@ public class NavigationView extends ViewPart
{
public void handleEvent(Event e)
{
- removeManagedObject(parentNode, (ManagedBean) selectedNode.getManagedObject());
+ removeManagedObject(parentNode, (ManagedBean) selectedNode.getManagedObject(), true);
_treeViewer.refresh();
// set the selection to the parent node
_treeViewer.setSelection(new StructuredSelection(parentNode));
@@ -202,14 +231,41 @@ public class NavigationView extends ViewPart
}
/**
- * Creates Qpid Server connection using JMX RMI protocol
+ * Creates Qpid Server connection
* @param server
* @throws Exception
*/
- private void createRMIServerConnection(ManagedServer server) throws Exception
+ private void createJMXServerConnection(ManagedServer server) throws Exception
{
// Currently Qpid Management Console only supports JMX MBeanServer
- ServerRegistry serverRegistry = new JMXServerRegistry(server);
+ JMXServerRegistry serverRegistry = new JMXServerRegistry(server);
+
+ try
+ {
+ //determine the management API version of the server just connected to
+ MBeanUtility.classifyManagementApiVersion(server, serverRegistry);
+ }
+ catch (Exception e)
+ {
+ //Exception classifying the server API, clean up the connection and rethrow
+ serverRegistry.closeServerConnection();
+ throw e;
+ }
+
+ //check that the console supports the API major version encountered, otherwise abort.
+ ApiVersion serverAPI = serverRegistry.getManagementApiVersion();
+
+ int serverMajor = serverAPI.getMajor();
+ int supportedMajor = ApplicationRegistry.SUPPORTED_QPID_JMX_API_MAJOR_VERSION;
+
+ if(serverMajor > supportedMajor)
+ {
+ serverRegistry.closeServerConnection();
+ throw new ManagementConsoleException("The server management API version encountered is not supported"
+ + " by this console release. Please check for an updated console release.");
+ }
+
+ //connection succeeded, add the ServerRegistry to the ApplicationRegistry
ApplicationRegistry.addServer(server, serverRegistry);
}
@@ -221,42 +277,32 @@ public class NavigationView extends ViewPart
* @param domain
* @throws Exception
*/
- public void addNewServer(String transportProtocol, String host, int port, String domain, String user, String pwd)
+ public void addNewServer(String host, int port, String domain, String user, String pwd)
throws Exception
{
- String serverAddress = host + ":" + port;
- String url = null;
ManagedServer managedServer = new ManagedServer(host, port, domain, user, pwd);
- if ("RMI".equals(transportProtocol))
+ String server = managedServer.getName();
+ List<TreeObject> list = _serversRootNode.getChildren();
+ for (TreeObject node : list)
{
- url = managedServer.getUrl();
- List<TreeObject> list = _serversRootNode.getChildren();
- for (TreeObject node : list)
+ ManagedServer nodeServer = (ManagedServer)node.getManagedObject();
+ if (server.equals(nodeServer.getName()))
{
- ManagedServer nodeServer = (ManagedServer)node.getManagedObject();
- if (url.equals(nodeServer.getUrl()))
- {
- // Server is already in the list of added servers, so now connect it.
- // Set the server node as selected and then connect it.
- _treeViewer.setSelection(new StructuredSelection(node));
- reconnect(user, pwd);
+ // Server is already in the list of added servers, so now connect it.
+ // Set the server node as selected and then connect it.
+ _treeViewer.setSelection(new StructuredSelection(node));
+ reconnect(user, pwd);
- return;
- }
+ return;
}
-
- // The server is not in the list of already added servers, so now connect and add it.
- managedServer.setName(serverAddress);
- createRMIServerConnection(managedServer);
- }
- else
- {
- throw new InfoRequiredException(transportProtocol + " transport is not supported");
}
+ // The server is not in the list of already added servers, so now connect and add it.
+ createJMXServerConnection(managedServer);
+
// Server connection is successful. Now add the server in the tree
- TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER);
+ TreeObject serverNode = new TreeObject(server, NODE_TYPE_SERVER);
serverNode.setManagedObject(managedServer);
_serversRootNode.addChild(serverNode);
@@ -278,9 +324,15 @@ public class NavigationView extends ViewPart
addConfiguredItems(managedServer);
_treeViewer.refresh();
+
+ expandInitialMBeanView(serverNode);
+
+ //(re)select the server node now that it is connected to force a selectionEvent
+ _treeViewer.setSelection(new StructuredSelection(serverNode));
+ _treeViewer.refresh();
// save server address in file
- addServerInConfigFile(serverAddress);
+ addServerInConfigFile(server);
}
/**
@@ -289,6 +341,16 @@ public class NavigationView extends ViewPart
*/
private void createConfigFile()
{
+ File dir = new File(DATA_DIR);
+ if (!dir.exists())
+ {
+ if(!dir.mkdir())
+ {
+ System.out.println("Could not create application data directory " + DATA_DIR);
+ System.exit(1);
+ }
+ }
+
File file = new File(INI_FILENAME);
try
{
@@ -406,51 +468,33 @@ public class NavigationView extends ViewPart
}
}
- /**
- * Queries the qpid server for MBeans and populates the navigation view with all MBeans for
- * the given server node.
- * @param serverNode
- */
- private void populateServer(TreeObject serverNode) throws Exception
+ //check if the MBeanInfo can be retrieved.
+ private boolean haveAccessPermission(ManagedBean mbean)
{
- ManagedServer server = (ManagedServer) serverNode.getManagedObject();
- String domain = server.getDomain();
- if (!domain.equals(ALL))
- {
- TreeObject domainNode = new TreeObject(domain, NODE_TYPE_DOMAIN);
- domainNode.setParent(serverNode);
-
- populateDomain(domainNode);
+ try
+ {
+ MBeanUtility.getMBeanInfo(mbean);
}
- else
+ catch(Exception ex)
{
- List<TreeObject> domainList = new ArrayList<TreeObject>();
- List<String> domains = MBeanUtility.getAllDomains(server);
-
- for (String domainName : domains)
- {
- TreeObject domainNode = new TreeObject(domainName, NODE_TYPE_DOMAIN);
- domainNode.setParent(serverNode);
-
- domainList.add(domainNode);
- populateDomain(domainNode);
- }
+ return false;
}
+
+ return true;
}
-
+
/**
- * Queries the Qpid Server and populates the given domain node with all MBeans undser that domain.
- * @param domain
- * @throws IOException
+ * Queries the qpid server for MBeans and populates the navigation view with all MBeans for
+ * the given server node.
+ * @param serverNode
* @throws Exception
*/
- @SuppressWarnings("unchecked")
- private void populateDomain(TreeObject domain) throws IOException, Exception
+ private void populateServer(TreeObject serverNode) throws Exception
{
- ManagedServer server = (ManagedServer) domain.getParent().getManagedObject();
+ ManagedServer server = (ManagedServer) serverNode.getManagedObject();
+ String domain = server.getDomain();
- // Now populate the mbenas under those types
- List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain.getName());
+ List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain);
for (ManagedBean mbean : mbeans)
{
mbean.setServer(server);
@@ -461,19 +505,27 @@ public class NavigationView extends ViewPart
// manually by selecting from MBeanView
if (!(mbean.isConnection() || mbean.isExchange() || mbean.isQueue()))
{
- addManagedBean(domain, mbean);
+ //if we cant get the MBeanInfo then we cant display the mbean, so dont add it to the tree
+ if (haveAccessPermission(mbean))
+ {
+ addManagedBean(serverNode, mbean);
+ }
}
}
// To make it work with the broker without virtual host implementation.
// This will add the default nodes to the domain node
- for (TreeObject child : domain.getChildren())
+ boolean hasVirtualHost = false;
+ for (TreeObject child : serverNode.getChildren())
{
- if (!child.getName().startsWith(VIRTUAL_HOST))
+ if (child.getName().startsWith(VIRTUAL_HOST))
{
- addDefaultNodes(domain);
+ hasVirtualHost = true;
+ break;
}
-
- break;
+ }
+
+ if (!hasVirtualHost){
+ addDefaultNodes(serverNode);
}
}
@@ -538,15 +590,14 @@ public class NavigationView extends ViewPart
}
/**
- * Adds the given MBean to the given domain node. Creates Notification node for the MBean.
+ * Adds the given MBean to the given domain node.
* sample ObjectNames -
* org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=localhost
* org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping_1
- * @param domain
- * @param mbean
- * @throws Exception
+ * @param parent parent tree node to add the mbean to
+ * @param mbean mbean to add
*/
- private void addManagedBean(TreeObject domain, ManagedBean mbean) // throws Exception
+ private void addManagedBean(TreeObject parent, ManagedBean mbean)
{
String name = mbean.getName();
// Split the mbean type into array of Strings, to create hierarchy
@@ -556,13 +607,21 @@ public class NavigationView extends ViewPart
// test->Queue->ping
String[] types = mbean.getType().split("\\.");
TreeObject typeNode = null;
- TreeObject parentNode = domain;
+ TreeObject parentNode = parent;
// Run this loop till all nodes(hierarchy) for this mbean are created. This loop only creates
// all the required parent nodes for the mbean
for (int i = 0; i < types.length; i++)
{
String type = types[i];
+
+ if(types.length == 1 && _serverTopLevelMBeans.contains(type))
+ {
+ //This mbean is not to be contained in a type hierarchy
+ //Just add it as a child of the server node.
+ break;
+ }
+
String valueOftype = mbean.getProperty(type);
// If value is not null, then there will be a parent node for this mbean
// eg. for type=VirtualHost the value is "test"
@@ -629,6 +688,7 @@ public class NavigationView extends ViewPart
// Add the mbean node now
TreeObject mbeanNode = new TreeObject(mbean);
+ mbeanNode.setVirtualHost(mbean.getVirtualHostName());
mbeanNode.setParent(typeNode);
// Add the mbean to the config file
@@ -636,11 +696,6 @@ public class NavigationView extends ViewPart
{
addItemInConfigFile(mbeanNode);
}
-
- // Add notification node
- // TODO: show this only if the mbean sends any notification
- //TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION);
- //notificationNode.setParent(mbeanNode);
}
private TreeObject createTypeNode(TreeObject parent, String name)
@@ -665,6 +720,11 @@ public class NavigationView extends ViewPart
*/
private void removeManagedObject(TreeObject parent)
{
+ if(parent == null)
+ {
+ return;
+ }
+
List<TreeObject> list = parent.getChildren();
for (TreeObject child : list)
{
@@ -679,7 +739,7 @@ public class NavigationView extends ViewPart
* @param parent
* @param mbean
*/
- private void removeManagedObject(TreeObject parent, ManagedBean mbean)
+ private void removeManagedObject(TreeObject parent, ManagedBean mbean, boolean removeFromConfigFile)
{
List<TreeObject> list = parent.getChildren();
TreeObject objectToRemove = null;
@@ -697,14 +757,17 @@ public class NavigationView extends ViewPart
}
else
{
- removeManagedObject(child, mbean);
+ removeManagedObject(child, mbean, removeFromConfigFile);
}
}
if (objectToRemove != null)
{
list.remove(objectToRemove);
- removeItemFromConfigFile(objectToRemove);
+ if(removeFromConfigFile)
+ {
+ removeItemFromConfigFile(objectToRemove);
+ }
}
}
@@ -733,9 +796,11 @@ public class NavigationView extends ViewPart
return;
}
- serverRegistry.closeServerConnection();
// Add server to the closed server list and the worker thread will remove the server from required places.
ApplicationRegistry.serverConnectionClosed(managedServer);
+
+ //close the connection
+ serverRegistry.closeServerConnection();
}
/**
@@ -753,8 +818,8 @@ public class NavigationView extends ViewPart
managedServer.setUser(user);
managedServer.setPassword(password);
- createRMIServerConnection(managedServer);
-
+ createJMXServerConnection(managedServer);
+
// put the server in the managed server map
_managedServerMap.put(managedServer, selectedNode);
@@ -773,8 +838,33 @@ public class NavigationView extends ViewPart
// Add the Queue/Exchanges/Connections from config file into the navigation tree
addConfiguredItems(managedServer);
+ expandInitialMBeanView(selectedNode);
+
+ //(re)select the server node now that it is connected to force a selectionEvent
+ _treeViewer.setSelection(new StructuredSelection(selectedNode));
_treeViewer.refresh();
}
+
+ private void expandInitialMBeanView(TreeObject serverNode)
+ {
+ if (serverNode.getChildren().size() == 0 )
+ {
+ return;
+ }
+ else
+ {
+ _treeViewer.setExpandedState(serverNode , true);
+ }
+
+ List<TreeObject> children = serverNode.getChildren();
+ for (TreeObject child : children)
+ {
+ if (child.getChildren().size() > 0)
+ {
+ _treeViewer.setExpandedState(child, true);
+ }
+ }
+ }
/**
* Adds the items(queues/exchanges/connectins) from config file to the server tree
@@ -954,11 +1044,9 @@ public class NavigationView extends ViewPart
composite.setLayout(gridLayout);
createTreeViewer(composite);
- _rootNode = new TreeObject("ROOT", "ROOT");
_serversRootNode = new TreeObject(NAVIGATION_ROOT, "ROOT");
- _serversRootNode.setParent(_rootNode);
- _treeViewer.setInput(_rootNode);
+ _treeViewer.setInput(_serversRootNode);
// set viewer as selection event provider for MBeanView
getSite().setSelectionProvider(_treeViewer);
@@ -1074,7 +1162,42 @@ public class NavigationView extends ViewPart
}
else
{
- return ApplicationRegistry.getImage(MBEAN_IMAGE);
+ ManagedObject obj = node.getManagedObject();
+ if(obj instanceof ManagedBean)
+ {
+ ManagedBean mbean = (ManagedBean) obj;
+ String mbeanType = mbean.getType();
+
+ if(mbeanType.equals(LoggingManagement.TYPE))
+ {
+ return ApplicationRegistry.getImage(LOGGING_MANAGEMENT_IMAGE);
+ }
+ else if(mbeanType.equals(UserManagement.TYPE))
+ {
+ return ApplicationRegistry.getImage(USER_MANAGEMENT_IMAGE);
+ }
+ else if(mbeanType.equals(ConfigurationManagement.TYPE))
+ {
+ return ApplicationRegistry.getImage(CONFIGURATION_MANAGEMENT_IMAGE);
+ }
+ else if(mbeanType.equals(ServerInformation.TYPE))
+ {
+ return ApplicationRegistry.getImage(SERVER_INFO_IMAGE);
+ }
+ else if(mbeanType.equals("VirtualHost.VirtualHostManager"))
+ {
+ return ApplicationRegistry.getImage(VHOST_MANAGER_IMAGE);
+ }
+ else
+ {
+ return ApplicationRegistry.getImage(MBEAN_IMAGE);
+ }
+
+ }
+ else
+ {
+ return ApplicationRegistry.getImage(MBEAN_IMAGE);
+ }
}
}
@@ -1146,7 +1269,7 @@ public class NavigationView extends ViewPart
try
{
- Thread.sleep(3000);
+ Thread.sleep(2000);
}
catch (Exception ex)
{ }
@@ -1157,25 +1280,12 @@ public class NavigationView extends ViewPart
/**
* Adds the mbean to the navigation tree
- * @param mbean
- * @throws Exception
+ * @param mbean mbean to add to the tree
*/
- public void addManagedBean(ManagedBean mbean) // throws Exception
+ public void addManagedBean(ManagedBean mbean)
{
TreeObject treeServerObject = _managedServerMap.get(mbean.getServer());
- List<TreeObject> domains = treeServerObject.getChildren();
- TreeObject domain = null;
- for (TreeObject child : domains)
- {
- if (child.getName().equals(mbean.getDomain()))
- {
- domain = child;
-
- break;
- }
- }
-
- addManagedBean(domain, mbean);
+ addManagedBean(treeServerObject, mbean);
_treeViewer.refresh();
}
@@ -1197,23 +1307,20 @@ public class NavigationView extends ViewPart
{
public void run()
{
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ final MBeanView view = (MBeanView)window.getActivePage().findView(MBeanView.ID);
+
for (ManagedBean mbean : removalList)
{
TreeObject treeServerObject = _managedServerMap.get(mbean.getServer());
- List<TreeObject> domains = treeServerObject.getChildren();
- TreeObject domain = null;
- for (TreeObject child : domains)
- {
- if (child.getName().equals(mbean.getDomain()))
- {
- domain = child;
- break;
- }
+ if(view != null)
+ {
+ //notify the MBeanView in case the unregistered mbean is being viewed
+ view.mbeanUnregistered(mbean);
}
-
- removeManagedObject(domain, mbean);
- // serverRegistry.removeManagedObject(mbean);
+
+ removeManagedObject(treeServerObject, mbean, false);
}
_treeViewer.refresh();
@@ -1239,7 +1346,18 @@ public class NavigationView extends ViewPart
{
for (ManagedServer server : closedServers)
{
- removeManagedObject(_managedServerMap.get(server));
+ if(server == null)
+ {
+ continue;
+ }
+
+ TreeObject node = _managedServerMap.get(server);
+ if(node ==null)
+ {
+ continue;
+ }
+
+ removeManagedObject(node);
_managedServerMap.remove(server);
ApplicationRegistry.removeServer(server);
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
index 6894080859..ea49a5c006 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java
@@ -21,7 +21,6 @@
package org.apache.qpid.management.ui.views;
import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR;
-import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
import static org.apache.qpid.management.ui.Constants.DESCRIPTION;
import static org.apache.qpid.management.ui.Constants.FONT_BOLD;
import static org.apache.qpid.management.ui.Constants.FONT_BUTTON;
@@ -29,6 +28,7 @@ import static org.apache.qpid.management.ui.Constants.FONT_ITALIC;
import static org.apache.qpid.management.ui.Constants.SUBSCRIBE_BUTTON;
import static org.apache.qpid.management.ui.Constants.UNSUBSCRIBE_BUTTON;
+import java.util.ArrayList;
import java.util.List;
import org.apache.qpid.management.ui.ApplicationRegistry;
@@ -50,7 +50,6 @@ 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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
@@ -65,23 +64,25 @@ public class NotificationsTabControl extends VHNotificationsTabControl
private SelectionListener selectionListener;
private SelectionListener comboListener;
- private Combo notificationNameCombo = null;
- private Combo typesCombo = null;
- private Label descriptionLabel = null;
- private Button _subscribeButton = null;
- private Button _unsubscribeButton = null;
+ private Combo _notificationNameCombo;
+ private Combo _typesCombo;
+ private Label _descriptionLabel;
+ private Button _subscribeButton;
+ private Button _unsubscribeButton;
- public NotificationsTabControl(TabFolder tabFolder)
+ public NotificationsTabControl(TabFolder tabFolder, ManagedBean mbean)
{
super(tabFolder);
+ _mbean = mbean;
+
+ populateNotificationInfo();
}
protected void createWidgets()
- {
+ {
selectionListener = new SelectionListenerImpl();
comboListener = new ComboSelectionListener();
createNotificationInfoComposite();
- //addFilterComposite();
addButtons();
createTableViewer();
}
@@ -103,21 +104,21 @@ public class NotificationsTabControl extends VHNotificationsTabControl
formData.left = new FormAttachment(0, 10);
label.setLayoutData(formData);
- notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ _notificationNameCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
formData = new FormData();
formData.top = new FormAttachment(label, 10);
formData.left = new FormAttachment(0, 10);
formData.right = new FormAttachment(40);
- notificationNameCombo.setLayoutData(formData);
- notificationNameCombo.addSelectionListener(comboListener);
+ _notificationNameCombo.setLayoutData(formData);
+ _notificationNameCombo.addSelectionListener(comboListener);
- typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ _typesCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN);
formData = new FormData();
formData.top = new FormAttachment(label, 10);
- formData.left = new FormAttachment(notificationNameCombo, 5);
+ formData.left = new FormAttachment(_notificationNameCombo, 5);
formData.right = new FormAttachment(65);
- typesCombo.setLayoutData(formData);
- typesCombo.addSelectionListener(comboListener);
+ _typesCombo.setLayoutData(formData);
+ _typesCombo.addSelectionListener(comboListener);
_subscribeButton = new Button(composite, SWT.PUSH | SWT.CENTER);
_subscribeButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
@@ -141,30 +142,30 @@ public class NotificationsTabControl extends VHNotificationsTabControl
Label fixedLabel = _toolkit.createLabel(composite, "");
formData = new FormData();
- formData.top = new FormAttachment(notificationNameCombo, 5);
+ formData.top = new FormAttachment(_notificationNameCombo, 5);
formData.left = new FormAttachment(0, 10);
fixedLabel.setLayoutData(formData);
fixedLabel.setText(DESCRIPTION + " : ");
fixedLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD));
- descriptionLabel = _toolkit.createLabel(composite, "");
+ _descriptionLabel = _toolkit.createLabel(composite, "");
formData = new FormData();
- formData.top = new FormAttachment(notificationNameCombo, 5);
+ formData.top = new FormAttachment(_notificationNameCombo, 5);
formData.left = new FormAttachment(fixedLabel, 10);
formData.right = new FormAttachment(100);
- descriptionLabel.setLayoutData(formData);
- descriptionLabel.setText(" ");
- descriptionLabel.setFont(ApplicationRegistry.getFont(FONT_ITALIC));
+ _descriptionLabel.setLayoutData(formData);
+ _descriptionLabel.setText(" ");
+ _descriptionLabel.setFont(ApplicationRegistry.getFont(FONT_ITALIC));
}
/**
- * Creates clear buttin and refresh button
+ * Creates clear button
*/
protected void addButtons()
{
Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
- composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- composite.setLayout(new GridLayout(2, true));
+ composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
+ composite.setLayout(new GridLayout(2,false));
// Add Clear Button
_clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER);
@@ -173,83 +174,53 @@ public class NotificationsTabControl extends VHNotificationsTabControl
gridData.widthHint = 80;
_clearButton.setLayoutData(gridData);
_clearButton.addSelectionListener(new SelectionAdapter()
- {
- public void widgetSelected(SelectionEvent e)
- {
- if (_mbean == null)
- return;
-
- IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_mbean == null)
+ {
+ return;
+ }
+
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
+ IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
+ if(!ss.isEmpty())
+ {
+ //clear selected Notifications
serverRegistry.clearNotifications(_mbean, ss.toList());
- refresh();
}
- });
-
- // Add Refresh Button
- _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
- _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false);
- gridData.widthHint = 80;
- _refreshButton.setLayoutData(gridData);
- _refreshButton.addSelectionListener(new SelectionAdapter()
- {
- public void widgetSelected(SelectionEvent e)
- {
- if (_mbean == null)
+ else if(_notifications != null)
+ {
+ //clear all the notifications, if there are any
+
+ //check the user is certain of this clear-all operation
+ int response = ViewUtility.popupOkCancelConfirmationMessage(
+ "Clear Notifications", "Clear all Notifications for this MBean?");
+ if(response != SWT.OK)
+ {
return;
+ }
- refresh();
+ synchronized(this)
+ {
+ List<NotificationObject> newList = new ArrayList<NotificationObject>();
+ newList.addAll(_notifications);
+ serverRegistry.clearNotifications(_mbean, newList);
+ }
}
- });
+
+ refresh();
+ }
+ });
+ //add description
+ Label desc = _toolkit.createLabel(composite,"Clears the selected Notifications, or all if none are selected");
+ desc.setLayoutData(new GridData(SWT.LEFT,SWT.CENTER, false, false));
}
-
+
@Override
public void refresh(ManagedBean mbean)
{
- _mbean = mbean;
- _notifications = null;
- _table.deselectAll();
- _tableViewer.getTable().clearAll();
-
- if (_mbean == null)
- {
- _tableViewer.getTable().clearAll();
- _subscribeButton.setEnabled(false);
- _unsubscribeButton.setEnabled(false);
- return;
- }
-
- if (!doesMBeanSendsNotification())
- {
- Control[] children = _form.getBody().getChildren();
- for (int i = 0; i < children.length; i++)
- {
- children[i].setVisible(false);
- }
-
- String name = (_mbean.getName() != null) ? _mbean.getName() : _mbean.getType();
- _form.setText(name + " does not send any notification");
- return;
- }
-
- Control[] children = _form.getBody().getChildren();
- for (int i = 0; i < children.length; i++)
- {
- children[i].setVisible(true);
- }
-
- populateNotificationInfo();
- workerRunning = true;
- _form.layout(true);
- _form.getBody().layout(true, true);
- }
-
- public void refresh()
- {
- _notifications = null;
- _table.deselectAll();
- _tableViewer.getTable().clearAll();
+ refresh();
}
/**
@@ -257,26 +228,26 @@ public class NotificationsTabControl extends VHNotificationsTabControl
*/
private void populateNotificationInfo()
{
- notificationNameCombo.removeAll();
+ _notificationNameCombo.removeAll();
NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
if (items.length > 1)
{
- notificationNameCombo.add(SELECT_NOTIFICATIONNAME);
+ _notificationNameCombo.add(SELECT_NOTIFICATIONNAME);
}
for (int i = 0; i < items.length; i++)
{
- notificationNameCombo.add(items[i].getName());
- notificationNameCombo.setData(items[i].getName(), items[i]);
+ _notificationNameCombo.add(items[i].getName());
+ _notificationNameCombo.setData(items[i].getName(), items[i]);
}
- notificationNameCombo.select(0);
+ _notificationNameCombo.select(0);
- typesCombo.removeAll();
- typesCombo.add("Select Type", 0);
- typesCombo.select(0);
- typesCombo.setEnabled(false);
+ _typesCombo.removeAll();
+ _typesCombo.add("Select Type", 0);
+ _typesCombo.select(0);
+ _typesCombo.setEnabled(false);
- populateNotificationType(notificationNameCombo.getItem(0));
+ populateNotificationType(_notificationNameCombo.getItem(0));
checkForEnablingButtons();
}
@@ -285,18 +256,18 @@ public class NotificationsTabControl extends VHNotificationsTabControl
*/
private void checkForEnablingButtons()
{
- int nameIndex = notificationNameCombo.getSelectionIndex();
- int itemCount = notificationNameCombo.getItems().length;
+ int nameIndex = _notificationNameCombo.getSelectionIndex();
+ int itemCount = _notificationNameCombo.getItems().length;
if ((itemCount > 1) && (nameIndex == 0))
{
_subscribeButton.setEnabled(false);
_unsubscribeButton.setEnabled(false);
- descriptionLabel.setText("");
+ _descriptionLabel.setText("");
return;
}
- int typeIndex = typesCombo.getSelectionIndex();
- itemCount = typesCombo.getItems().length;
+ int typeIndex = _typesCombo.getSelectionIndex();
+ itemCount = _typesCombo.getItems().length;
if ((itemCount > 1) && (typeIndex == 0))
{
_subscribeButton.setEnabled(false);
@@ -304,8 +275,8 @@ public class NotificationsTabControl extends VHNotificationsTabControl
return;
}
- String type = typesCombo.getItem(typeIndex);
- String name = notificationNameCombo.getItem(nameIndex);
+ String type = _typesCombo.getItem(typeIndex);
+ String name = _notificationNameCombo.getItem(nameIndex);
ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
if (serverRegistry.hasSubscribedForNotifications(_mbean, name, type))
@@ -320,15 +291,6 @@ public class NotificationsTabControl extends VHNotificationsTabControl
}
}
- private boolean doesMBeanSendsNotification()
- {
- NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
- if (items == null || items.length == 0)
- return false;
- else
- return true;
- }
-
/**
* Selection listener for subscribing or unsubscribing the notifications
*/
@@ -340,8 +302,8 @@ public class NotificationsTabControl extends VHNotificationsTabControl
return;
Button source = (Button)e.getSource();
- String type = typesCombo.getItem(typesCombo.getSelectionIndex());
- String name = notificationNameCombo.getItem(notificationNameCombo.getSelectionIndex());
+ String type = _typesCombo.getItem(_typesCombo.getSelectionIndex());
+ String name = _notificationNameCombo.getItem(_notificationNameCombo.getSelectionIndex());
if (source == _unsubscribeButton)
{
try
@@ -380,7 +342,7 @@ public class NotificationsTabControl extends VHNotificationsTabControl
return;
Combo combo = (Combo)e.getSource();
- if (combo == notificationNameCombo)
+ if (combo == _notificationNameCombo)
{
String selectedItem = combo.getItem(combo.getSelectionIndex());
populateNotificationType(selectedItem);
@@ -391,23 +353,23 @@ public class NotificationsTabControl extends VHNotificationsTabControl
private void populateNotificationType(String notificationName)
{
- NotificationInfoModel data = (NotificationInfoModel)notificationNameCombo.getData(notificationName);
+ NotificationInfoModel data = (NotificationInfoModel)_notificationNameCombo.getData(notificationName);
if (data == null)
{
- descriptionLabel.setText("");
- typesCombo.select(0);
- typesCombo.setEnabled(false);
+ _descriptionLabel.setText("");
+ _typesCombo.select(0);
+ _typesCombo.setEnabled(false);
return;
}
- descriptionLabel.setText(data.getDescription());
- typesCombo.removeAll();
- typesCombo.setItems(data.getTypes());
- if (typesCombo.getItemCount() > 1)
+ _descriptionLabel.setText(data.getDescription());
+ _typesCombo.removeAll();
+ _typesCombo.setItems(data.getTypes());
+ if (_typesCombo.getItemCount() > 1)
{
- typesCombo.add(SELECT_NOTIFICATIONTYPE, 0);
+ _typesCombo.add(SELECT_NOTIFICATIONTYPE, 0);
}
- typesCombo.select(0);
- typesCombo.setEnabled(true);
+ _typesCombo.select(0);
+ _typesCombo.setEnabled(true);
}
/**
@@ -417,11 +379,10 @@ public class NotificationsTabControl extends VHNotificationsTabControl
{
ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
List<NotificationObject> newList = serverRegistry.getNotifications(_mbean);
- if (newList == null)
- return;
-
- _notifications = newList;
- _tableViewer.setInput(_notifications);
- _tableViewer.refresh();
+ synchronized(this)
+ {
+ _notifications = newList;
+ _tableViewer.setInput(_notifications);
+ }
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
index f2cd594684..ff2005e4bb 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
@@ -22,7 +22,6 @@ package org.apache.qpid.management.ui.views;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
@@ -68,7 +67,6 @@ import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* Control class for the MBean operations tab. It creates the required widgets
* for the selected MBean.
- * @author Bhupendra Bhardwaj
*/
public class OperationTabControl extends TabControl
{
@@ -223,7 +221,7 @@ public class OperationTabControl extends TabControl
// Customised parameter widgets
if (_mbean.isExchange() &&
- EXCHANGE_TYPE_VALUES[2].equals(_mbean.getProperty(EXCHANGE_TYPE)) &&
+ DEFAULT_EXCHANGE_TYPE_VALUES[2].equals(_mbean.getProperty(EXCHANGE_TYPE)) &&
_opData.getName().equalsIgnoreCase(OPERATION_CREATE_BINDING))
{
customCreateNewBinding();
@@ -276,7 +274,7 @@ public class OperationTabControl extends TabControl
}
else if (param.getName().equals(EXCHANGE_TYPE))
{
- items = EXCHANGE_TYPE_VALUES;
+ items = DEFAULT_EXCHANGE_TYPE_VALUES;
}
else if (isUserListParameter(param))
{
@@ -519,7 +517,7 @@ public class OperationTabControl extends TabControl
private void populateResults(Object result)
{
Display display = Display.getCurrent();
- int width = 600;
+ int width = 610;
int height = 400;
Shell shell = ViewUtility.createPopupShell(RESULT, width, height);
shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
@@ -603,21 +601,37 @@ public class OperationTabControl extends TabControl
return;
}
- // customized for passwords
- String securityMechanism = ApplicationRegistry.getSecurityMechanism();
- if ((MECH_CRAMMD5.equals(securityMechanism)) && PASSWORD.equalsIgnoreCase(param.getName()))
+ //Custom handling for the PASSWORD field
+ if (param.getName().equalsIgnoreCase(PASSWORD))
{
- try
+ //Convert the String value to a character array if that is what is required.
+ if (param.getType().equals("[C"))
{
- param.setValue(ViewUtility.getMD5HashedCharArray(param.getValue()));
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(_mbean, ex);
- return;
+ // Retreive the mBean type and version.
+ // If we have a version 1 UserManagement class mbean then it expects the password
+ // to be sent as the hashed version.
+ if (_mbean.getType().equals("UserManagement") && _mbean.getVersion() == 1)
+ {
+ try
+ {
+ param.setValue(ViewUtility.getHash((String) param.getValue()));
+ }
+ catch (Exception hashException)
+ {
+ ViewUtility.popupErrorMessage(_form.getText(),
+ "Unable to calculate hash for Password:"
+ + hashException.getMessage());
+ return;
+ }
+ }
+ else
+ {
+ param.setValue(((String) param.getValue()).toCharArray());
+ }
}
}
// end of customization
+
}
}
@@ -721,7 +735,14 @@ public class OperationTabControl extends TabControl
{
boolean success = Boolean.parseBoolean(result.toString());
String message = success ? OPERATION_SUCCESSFUL : OPERATION_UNSUCCESSFUL;
- ViewUtility.popupInfoMessage(title, message);
+ if(success)
+ {
+ ViewUtility.popupInfoMessage(title, message);
+ }
+ else
+ {
+ ViewUtility.popupErrorMessage(title, message);
+ }
}
else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty())
{
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java
deleted file mode 100644
index 31a0bc857b..0000000000
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-package org.apache.qpid.management.ui.views;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.apache.qpid.management.ui.ApplicationRegistry;
-import org.apache.qpid.management.ui.Constants;
-import org.apache.qpid.management.ui.ManagedBean;
-import org.apache.qpid.management.ui.ServerRegistry;
-import org.apache.qpid.management.ui.jmx.MBeanUtility;
-import org.apache.qpid.management.ui.model.AttributeData;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-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.Group;
-import org.eclipse.swt.widgets.TabFolder;
-
-/**
- * Controller class, which takes care of displaying appropriate information and widgets for Queues.
- * This allows user to select Queues and add those to the navigation view
- */
-public class QueueTypeTabControl extends MBeanTypeTabControl
-{
- private boolean _showTempQueues = false;
- private Button _sortBySizeButton = null;
- private Button _sortByConsumercountButton = null;
- private Button _sortByNameButton = null;
- private Button _showTempQueuesButton = null;
-
- private ComparatorImpl _sorterByAttribute = new ComparatorImpl();
-
- // Map required for sorting queues based on attribute values
- private Map<AttributeData, ManagedBean> _queueDepthMap = new LinkedHashMap<AttributeData, ManagedBean>();
- // Map used for sorting Queues based on consumer count
- private Map<AttributeData, ManagedBean> _queueConsumerCountMap = new LinkedHashMap<AttributeData, ManagedBean>();
-
-
- public QueueTypeTabControl(TabFolder tabFolder)
- {
- super(tabFolder, Constants.QUEUE);
- createWidgets();
- }
-
- protected void createWidgets()
- {
- createHeaderComposite(getFormComposite());
- createButtonsComposite(getFormComposite());
- createListComposite();
- }
-
- @Override
- public void refresh() throws Exception
- {
- setLabelValues();
- selectDefaultSortingButton();
- populateList();
- layout();
- }
-
- /**
- * populates the map with mbean name and the mbean object.
- * @throws Exception
- */
- protected void populateList() throws Exception
- {
- // map should be cleared before populating it with new values
- getMBeansMap().clear();
- _queueDepthMap.clear();
- _queueConsumerCountMap.clear();
-
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
- String[] items = null;
- java.util.List<ManagedBean> list = null;
-
- // populate the map and list with appropriate mbeans
- list = serverRegistry.getQueues(MBeanView.getVirtualHost());
- items = getQueueItems(list);
- // sort the refreshed list in the selected order
- if (_sortBySizeButton.getSelection())
- {
- sortQueuesByQueueDepth();
- }
- else if (_sortByConsumercountButton.getSelection())
- {
- sortQueuesByConsumerCount();
- }
- else
- {
- getListWidget().setItems(items);
- }
- }
-
- private void selectDefaultSortingButton()
- {
- _sortByNameButton.setSelection(true);
- _sortBySizeButton.setSelection(false);
- _sortByConsumercountButton.setSelection(false);
-
- _showTempQueues = false;
- _showTempQueuesButton.setSelection(_showTempQueues);
- }
-
- protected void createListComposite()
- {
- // Composite to contain the item list
- Composite composite = getToolkit().createComposite(getFormComposite());
- GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
- composite.setLayoutData(gridData);
- GridLayout layout = new GridLayout(2, true);
- layout.verticalSpacing = 0;
- composite.setLayout(layout);
-
- createListComposite(composite);
-
- // Composite to contain buttons like - Sort by size
- Composite _sortingComposite = getToolkit().createComposite(composite);
- gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
- _sortingComposite.setLayoutData(gridData);
- GridLayout gridLayout = new GridLayout();
- gridLayout.verticalSpacing = 20;
- _sortingComposite.setLayout(gridLayout);
-
- Group sortingGroup = new Group(_sortingComposite, SWT.SHADOW_NONE);
- sortingGroup.setBackground(_sortingComposite.getBackground());
- sortingGroup.setText(" Sort List By ");
- sortingGroup.setFont(ApplicationRegistry.getFont(Constants.FONT_BOLD));
- gridData = new GridData(SWT.CENTER, SWT.TOP, true, false);
- sortingGroup.setLayoutData(gridData);
- sortingGroup.setLayout(new GridLayout());
-
- _sortByNameButton = getToolkit().createButton(sortingGroup, Constants.QUEUE_SORT_BY_NAME, SWT.RADIO);
- gridData = new GridData(SWT.LEAD, SWT.CENTER, true, false);
- _sortByNameButton.setLayoutData(gridData);
- _sortByNameButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e)
- {
- try
- {
- // sort the stored list of items
- java.util.List<String> list = new ArrayList<String>(getMBeansMap().keySet());
- Collections.sort(list);
- getListWidget().setItems(list.toArray(new String[0]));
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(ex);
- }
- }
- });
-
- _sortBySizeButton = getToolkit().createButton(sortingGroup, Constants.QUEUE_SORT_BY_DEPTH, SWT.RADIO);
- gridData = new GridData(SWT.LEAD, SWT.CENTER, true, false);
- _sortBySizeButton.setLayoutData(gridData);
- _sortBySizeButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e)
- {
- try
- {
- // sort the stored list of items
- sortQueuesByQueueDepth();
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(ex);
- }
- }
- });
-
- _sortByConsumercountButton = getToolkit().createButton(sortingGroup, Constants.QUEUE_SORT_BY_CONSUMERCOUNT, SWT.RADIO);
- gridData = new GridData(SWT.LEAD, SWT.CENTER, true, false);
- _sortByConsumercountButton.setLayoutData(gridData);
- _sortByConsumercountButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e)
- {
- try
- {
- sortQueuesByConsumerCount();
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(ex);
- }
- }
- });
-
- _showTempQueuesButton = getToolkit().createButton(_sortingComposite, Constants.QUEUE_SHOW_TEMP_QUEUES, SWT.CHECK);
- _showTempQueuesButton.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false));
- _showTempQueuesButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e)
- {
- Button button = (Button)e.widget;
- _showTempQueues = button.getSelection();
- try
- {
- populateList();
- }
- catch (Exception ex)
- {
- MBeanUtility.handleException(ex);
- }
- }
- });
- }
-
-
- private String[] getQueueItems(java.util.List<ManagedBean> list) throws Exception
- {
- if (list == null)
- return new String[0];
-
- // Sort the list. It will keep the mbeans in sorted order in the _queueMap, which is required for
- // sorting the queue according to size etc
- Collections.sort(list, getMBeanNameSorter());
- java.util.List<String> items = new ArrayList<String>();;
- int i = 0;
- for (ManagedBean mbean : list)
- {
- if ((!_showTempQueues && mbean.isTempQueue()))
- {
- continue;
- }
- AttributeData data = MBeanUtility.getAttributeData(mbean, Constants.ATTRIBUTE_QUEUE_DEPTH);
- String value = mbean.getName() + " (" + data.getValue().toString() + " KB)";
- items.add(value);
- //items[i] = mbean.getName() + " (" + value + " KB)";
- getMBeansMap().put(value, mbean);
- _queueDepthMap.put(data, mbean);
- data = MBeanUtility.getAttributeData(mbean, Constants.ATTRIBUTE_QUEUE_CONSUMERCOUNT);
- _queueConsumerCountMap.put(data, mbean);
- i++;
- }
-
- return items.toArray(new String[0]);
- }
-
-
- private void sortQueuesByQueueDepth()
- {
- // Queues are already in the alphabetically sorted order in _queueMap, now sort for queueDepth
- java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueDepthMap.keySet());
- Collections.sort(list, _sorterByAttribute);
-
- String[] items = new String[list.size()];
- int i = 0;
- for (AttributeData data : list)
- {
- ManagedBean mbean = _queueDepthMap.get(data);
- String value = data.getValue().toString();
- items[i++] = mbean.getName() + " (" + value + " KB)";
- }
- getListWidget().setItems(items);
- }
-
- private void sortQueuesByConsumerCount()
- {
- java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueConsumerCountMap.keySet());
- Collections.sort(list, _sorterByAttribute);
-
- String[] items = new String[list.size()];
- int i = 0;
- for (AttributeData data : list)
- {
- ManagedBean mbean = _queueConsumerCountMap.get(data);
- String value = data.getValue().toString();
- items[i++] = mbean.getName() + " (" + value + " )";
- }
- getListWidget().setItems(items);
- }
-}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
index c13c92066c..156543d603 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java
@@ -33,6 +33,7 @@ import org.eclipse.swt.widgets.TabFolder;
*/
public abstract class TabControl
{
+ public static final String CONTROLLER = "controller";
protected ManagedBean _mbean = null;
protected TabFolder _tabFolder = null;
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java
index be25707bd3..4e21e9e865 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java
@@ -22,7 +22,6 @@
package org.apache.qpid.management.ui.views;
import static org.apache.qpid.management.ui.Constants.BUTTON_CLEAR;
-import static org.apache.qpid.management.ui.Constants.BUTTON_REFRESH;
import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE;
import static org.apache.qpid.management.ui.Constants.FONT_BUTTON;
@@ -35,7 +34,6 @@ import org.apache.qpid.management.ui.model.NotificationObject;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
@@ -68,7 +66,8 @@ public class VHNotificationsTabControl extends TabControl
protected Table _table = null;
protected TableViewer _tableViewer = null;
- protected Thread worker = null;
+ protected Thread _worker = null;
+ protected boolean _workerRunning = false;
protected List<NotificationObject> _notifications = null;
@@ -86,7 +85,6 @@ public class VHNotificationsTabControl extends TabControl
};
protected Button _clearButton = null;
- protected Button _refreshButton = null;
public VHNotificationsTabControl(TabFolder tabFolder)
{
@@ -98,8 +96,7 @@ public class VHNotificationsTabControl extends TabControl
gridLayout.marginHeight = 0;
_form.getBody().setLayout(gridLayout);
- worker = new Thread(new Worker());
- worker.start();
+ createWidgets();
}
protected void createWidgets()
@@ -113,10 +110,6 @@ public class VHNotificationsTabControl extends TabControl
*/
public Control getControl()
{
- if (_table == null)
- {
- createWidgets();
- }
return _form;
}
@@ -126,8 +119,8 @@ public class VHNotificationsTabControl extends TabControl
protected void addButtons()
{
Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
- composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- composite.setLayout(new GridLayout(2, true));
+ composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
+ composite.setLayout(new GridLayout(2,false));
// Add Clear Button
_clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER);
@@ -136,30 +129,40 @@ public class VHNotificationsTabControl extends TabControl
gridData.widthHint = 80;
_clearButton.setLayoutData(gridData);
_clearButton.addSelectionListener(new SelectionAdapter()
- {
- public void widgetSelected(SelectionEvent e)
- {
- //TODO : Get selected rows and clear those
- IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
+ IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection();
+ if(!ss.isEmpty())
+ {
+ //clear selected Notifications
serverRegistry.clearNotifications(null, ss.toList());
- refresh();
}
- });
-
- // Add Refresh Button
- _refreshButton = _toolkit.createButton(composite, BUTTON_REFRESH, SWT.PUSH | SWT.CENTER);
- _refreshButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON));
- gridData = new GridData(SWT.TRAIL, SWT.TOP, true, false);
- gridData.widthHint = 80;
- _refreshButton.setLayoutData(gridData);
- _refreshButton.addSelectionListener(new SelectionAdapter()
- {
- public void widgetSelected(SelectionEvent e)
- {
- refresh();
+ else if(_notifications != null)
+ {
+ //clear all the notifications, if there are any
+
+ //check the user is certain of this clear-all operation
+ int response = ViewUtility.popupOkCancelConfirmationMessage(
+ "Clear Notifications", "Clear all Notifications for this VirtualHost?");
+ if(response != SWT.OK)
+ {
+ return;
+ }
+
+ synchronized(this)
+ {
+ serverRegistry.clearNotifications(null, _notifications);
+ }
}
- });
+
+ refresh();
+ }
+ });
+ //add description
+ Label desc = _toolkit.createLabel(composite,"Clears the selected Notifications, or all if none are selected");
+ desc.setLayoutData(new GridData(SWT.LEFT,SWT.CENTER, false, false));
}
/**
@@ -201,36 +204,12 @@ public class VHNotificationsTabControl extends TabControl
{
createTable();
_tableViewer = new TableViewer(_table);
- //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
_tableViewer.setUseHashlookup(true);
_tableViewer.setContentProvider(new ContentProviderImpl());
_tableViewer.setLabelProvider(new LabelProviderImpl());
_tableViewer.setColumnProperties(_tableTitles);
- /*
- CellEditor[] cellEditors = new CellEditor[_tableTitles.length];
- TextCellEditor textEditor = new TextCellEditor(table);
- cellEditors[0] = textEditor;
- textEditor = new TextCellEditor(table);
- cellEditors[1] = textEditor;
- textEditor = new TextCellEditor(table);
- cellEditors[2] = textEditor;
- textEditor = new TextCellEditor(table);
- cellEditors[3] = textEditor;
-
- // Assign the cell editors to the viewer
- _tableViewer.setCellEditors(cellEditors);
- _tableViewer.setCellModifier(new TableCellModifier());
- */
addTableListeners();
-
- //_tableViewer.addSelectionChangedListener(new );
-
- //_notificationDetails = new Composite(_tabControl, SWT.BORDER);
- //_notificationDetails.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- //_tabControl.layout();
- //viewerComposite.layout();
}
/**
@@ -311,17 +290,19 @@ public class VHNotificationsTabControl extends TabControl
public void refresh()
{
- _notifications = null;
- _table.deselectAll();
- _tableViewer.getTable().clearAll();
-
- Control[] children = _form.getBody().getChildren();
- for (int i = 0; i < children.length; i++)
+ if(_workerRunning)
+ {
+ //perform an single immediate-update
+ updateTableViewer();
+ }
+ else
{
- children[i].setVisible(true);
+ //start a worker to do the update and keep going as required
+ _workerRunning = true;
+ _worker = new Thread(new Worker());
+ _worker.start();
}
-
- workerRunning = true;
+
_form.layout(true);
_form.getBody().layout(true, true);
}
@@ -413,10 +394,10 @@ public class VHNotificationsTabControl extends TabControl
}
} // end of LabelProviderImpl
- protected boolean workerRunning = false;
+
protected void setWorkerRunning(boolean running)
{
- workerRunning = running;
+ _workerRunning = running;
}
/**
@@ -424,15 +405,18 @@ public class VHNotificationsTabControl extends TabControl
*/
private class Worker implements Runnable
{
+ private boolean keepGoing = true;
+
public void run()
{
- Display display = _tabFolder.getDisplay();
- while(true)
+ final Display display = _tabFolder.getDisplay();
+
+ while(keepGoing)
{
- if (!workerRunning || display == null)
+ if (display == null || display.isDisposed())
{
- sleep();
- continue;
+ setWorkerRunning(false);
+ break; //stop the thread
}
display.syncExec(new Runnable()
@@ -440,15 +424,27 @@ public class VHNotificationsTabControl extends TabControl
public void run()
{
if (_form == null || _form.isDisposed())
- return;
- setWorkerRunning(_form.isVisible());
- if (!workerRunning) return;
-
- updateTableViewer();
+ {
+ setWorkerRunning(false);
+ keepGoing = false; //exit the loop and stop the thread
+ }
+ else
+ {
+ keepGoing = _form.isVisible();
+ setWorkerRunning(keepGoing);
+ }
+
+ if (keepGoing)
+ {
+ updateTableViewer();
+ }
}
- });
+ });
- sleep();
+ if (keepGoing)
+ {
+ sleep();
+ }
}
}
@@ -466,18 +462,20 @@ public class VHNotificationsTabControl extends TabControl
}
/**
- * Updates the table with new notifications received from mbean server for all mbeans
+ * Updates the table with new notifications received from mbean server for all mbeans in this virtual host
*/
protected void updateTableViewer()
{
+ String virtualhost = MBeanView.getVirtualHost();
+
ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
- List<NotificationObject> newList = serverRegistry.getNotifications(null);
- if (newList == null)
- return;
+ List<NotificationObject> newList = serverRegistry.getNotifications(virtualhost);
- _notifications = newList;
- _tableViewer.setInput(_notifications);
- _tableViewer.refresh();
+ synchronized(this)
+ {
+ _notifications = newList;
+ _tableViewer.setInput(_notifications);
+ }
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
index 4f2b70f869..eb34f6c51c 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
@@ -39,29 +39,36 @@ import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
-import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.ErrorDialog;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import static org.apache.qpid.management.ui.Constants.FAILURE_IMAGE;
+import static org.apache.qpid.management.ui.Constants.SUCCESS_IMAGE;
+
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
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.Display;
+import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* Utility Class for displaying OpenMbean data types by creating required SWT widgets
- * @author Bhupendra Bhardwaj
*/
public class ViewUtility
{
@@ -77,6 +84,8 @@ public class ViewUtility
private static final Comparator tabularDataComparator = new TabularDataComparator();
+ private static MBeanView _mbeanView = null;
+
private static List<String> SUPPORTED_ARRAY_DATATYPES = new ArrayList<String>();
static
{
@@ -89,6 +98,10 @@ public class ViewUtility
SUPPORTED_ARRAY_DATATYPES.add("java.util.Date");
}
+ private static final int DEFAULT_CONTENT_SIZE = 198;
+ static Button _firstButton, _nextButton, _previousButton, _lastButton;
+ static Text _hexNumTextToEnd, _hexNumTextToStart;
+
/**
* Populates the composite with given openmbean data type (TabularType or CompositeType)
* @param toolkit
@@ -190,15 +203,15 @@ public class ViewUtility
layoutData.widthHint = 80;
firstRecordButton.setLayoutData(layoutData);
- final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH);
+ final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END);
layoutData.widthHint = 80;
- nextRecordButton.setLayoutData(layoutData);
+ previousRecordButton.setLayoutData(layoutData);
- final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH);
+ final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 80;
- previousRecordButton.setLayoutData(layoutData);
+ nextRecordButton.setLayoutData(layoutData);
final Button lastRecordButton = toolkit.createButton(dataHolder, LAST, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
@@ -352,7 +365,7 @@ public class ViewUtility
}
else
{
- setNotSupportedDataType(toolkit, compositeHolder);
+ handleBinaryMessageContent(toolkit, compositeHolder, data, itemName, encoding);
}
}
// If array of any other supported type, show as a list of String array
@@ -411,86 +424,413 @@ public class ViewUtility
ex.printStackTrace();
}
}
-
- public static int popupInfoMessage(String title, String message)
+
+ private static Shell getShell()
{
- MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(), SWT.ICON_INFORMATION | SWT.OK);
- messageBox.setMessage(message);
- messageBox.setText(title);
- int response = messageBox.open();
-
- return response;
+ Shell shell = Display.getCurrent().getActiveShell();
+
+ // Under linux GTK getActiveShell returns null so we need to make a new shell for display.
+ // Under windows this is fine.
+ if (shell == null)
+ {
+ // This occurs under linux gtk
+ shell = new Shell(Display.getCurrent(), SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX);
+ }
+
+ return shell;
}
-
- public static int popupErrorMessage(String title, String message)
+
+ private static int showBox(String title, String message, int icon)
{
- MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(), SWT.ICON_ERROR | SWT.OK);
+ MessageBox messageBox = new MessageBox(getShell(), icon);
messageBox.setMessage(message);
messageBox.setText(title);
- int response = messageBox.open();
-
- return response;
+
+ return messageBox.open();
+ }
+
+ /**
+ * Creates widgets for object messages and populates the content in hexadecimal format.
+ * @param toolkit
+ * @param compositeHolder
+ * @param data
+ * @param itemName
+ * @param encoding
+ */
+ private static void handleBinaryMessageContent(FormToolkit toolkit, Composite compositeHolder, CompositeData data, String itemName, String encoding)
+ {
+ final String thisEncoding = encoding;
+ final Byte[] arrayItems = (Byte[]) data.get(itemName);
+ final byte[] byteArray = new byte[arrayItems.length];
+
+ for (int i = 0; i < arrayItems.length; i++)
+ {
+ byteArray[i] = arrayItems[i];
+ }
+
+ try
+ {
+ //create a new composite to contain the widgets required to display object messages.
+ final Composite localComposite = toolkit.createComposite(compositeHolder, SWT.NONE);
+ localComposite.setData("currentBytePos", 0);
+ localComposite.setData("startingBytePos", 0);
+ GridLayout layout = new GridLayout(2, true);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ localComposite.setLayout(layout);
+ localComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+
+ int startContentSize = DEFAULT_CONTENT_SIZE;
+
+ if (byteArray.length < DEFAULT_CONTENT_SIZE)
+ {
+ startContentSize = byteArray.length;
+ }
+
+ //create a text to display the hexadecimal views of object messages, it takes more space than ascii view as
+ //a hex uses 2 chars and 1 space, while ascii only uses 1 char and 1 space.
+ final Text hexText = toolkit.createText(localComposite,
+ new String(displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", true)),
+ SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+ gridData.widthHint = 144; //set to 222 if not using any fonts
+ gridData.heightHint = 200;
+ hexText.setLayoutData(gridData);
+
+ final Text asciiText = toolkit.createText(localComposite,
+ new String(displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", false)),
+ SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
+
+
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+ gridData.widthHint = 52;//set to 98 if not using any fonts
+ gridData.heightHint = 200;
+ asciiText.setLayoutData(gridData);
+
+ //use a monospaced font for a better layout
+ Font font = new Font(compositeHolder.getDisplay(), "Courier", 10, SWT.NORMAL);
+ hexText.setFont(font);
+ asciiText.setFont(font);
+
+ final ScrollBar hexScrollBar = hexText.getVerticalBar();
+ final ScrollBar asciiScrollBar = asciiText.getVerticalBar();
+
+ //create a sub composite to contain all the buttons
+ final Composite buttonComposite = toolkit.createComposite(localComposite, SWT.NONE);
+ layout = new GridLayout(7, false);
+ layout.marginWidth = 0;
+ buttonComposite.setLayout(layout);
+ buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
+
+ _firstButton = toolkit.createButton(buttonComposite, "<<", SWT.PUSH);
+ GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _firstButton.setLayoutData(layoutData);
+ _firstButton.setToolTipText("See the first n bytes");
+
+ _previousButton = toolkit.createButton(buttonComposite, "<", SWT.PUSH);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _previousButton.setLayoutData(layoutData);
+ _previousButton.setToolTipText("See the previous n bytes");
+ _previousButton.setEnabled(false);
+
+ _hexNumTextToStart = toolkit.createText(buttonComposite, "0");
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _hexNumTextToStart.setLayoutData(layoutData);
+ _hexNumTextToStart.setEditable(false);
+
+ final Text hexNumText = toolkit.createText(buttonComposite, "" + startContentSize);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ hexNumText.setLayoutData(layoutData);
+
+ _hexNumTextToEnd = toolkit.createText(buttonComposite, "" + (byteArray.length - startContentSize));
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _hexNumTextToEnd.setLayoutData(layoutData);
+ _hexNumTextToEnd.setEditable(false);
+
+ _nextButton = toolkit.createButton(buttonComposite, ">", SWT.PUSH);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _nextButton.setLayoutData(layoutData);
+ _nextButton.setToolTipText("See the next n bytes");
+ _nextButton.setEnabled(true);
+
+ _lastButton = toolkit.createButton(buttonComposite, ">>", SWT.PUSH);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _lastButton.setToolTipText("See the last n bytes");
+ _lastButton.setLayoutData(layoutData);
+
+ SelectionListener listener = new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (e.widget instanceof Button)
+ {
+ String numOfBytes = hexNumText.getText();
+ try
+ {
+ int n = Integer.parseInt(numOfBytes);
+
+ //Reset range display if user requests a large value
+ if (n > byteArray.length)
+ {
+ n = (byteArray.length > DEFAULT_CONTENT_SIZE) ? DEFAULT_CONTENT_SIZE : byteArray.length;
+ hexNumText.setText("" + n);
+ }
+
+ //rest if the user requests 0
+ if (n < 1)
+ {
+ n = DEFAULT_CONTENT_SIZE;
+ hexNumText.setText("" + n);
+ }
+
+ Button button = (Button) e.widget;
+ hexText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding,
+ button.getText(), true));
+ asciiText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding,
+ button.getText(), false));
+ }
+ catch (NumberFormatException exp)
+ {
+ popupErrorMessage("Error", "Please input the number of bytes you wish to look at");
+ }
+ }
+ if (e.widget instanceof ScrollBar)
+ {
+ //synchronize the movements of the two scrollbars
+ ScrollBar sb = (ScrollBar) e.widget;
+ if (sb.getParent().equals(hexText))
+ {
+ asciiScrollBar.setIncrement(sb.getIncrement());
+ asciiScrollBar.setSelection(sb.getSelection());
+ }
+ else if (sb.getParent().equals(asciiText))
+ {
+ hexScrollBar.setSelection(sb.getSelection());
+ hexScrollBar.setIncrement(sb.getIncrement());
+ }
+ }
+ }
+ };
+ localComposite.addControlListener(new ControlAdapter()
+ {
+ public void controlResized(ControlEvent e)
+ {
+ //if the control is resized, set different parameters to make a single line displays the same contents.
+ if (((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth)
+ {
+ ((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = false;
+ ((GridLayout) localComposite.getLayout()).numColumns = 2;
+ ((GridData) hexText.getLayoutData()).horizontalSpan = 1;
+ ((GridData) hexText.getLayoutData()).widthHint = 144;
+ ((GridData) asciiText.getLayoutData()).horizontalSpan = 1;
+ ((GridData) asciiText.getLayoutData()).widthHint = 52;
+ ((GridData) buttonComposite.getLayoutData()).horizontalSpan = 2;
+ }
+ else
+ {
+ ((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = true;
+ ((GridLayout) localComposite.getLayout()).numColumns = 42; //set to 47 if not using any fonts
+ ((GridData) hexText.getLayoutData()).horizontalSpan = 25; // set to 30 if not using any fonts
+ ((GridData) asciiText.getLayoutData()).horizontalSpan = 17; // set to 17 if not using any fonts
+ ((GridData) buttonComposite.getLayoutData()).horizontalSpan = 42;
+ }
+ }
+ });
+
+ _firstButton.addSelectionListener(listener);
+ _previousButton.addSelectionListener(listener);
+ _nextButton.addSelectionListener(listener);
+ _lastButton.addSelectionListener(listener);
+ hexScrollBar.addSelectionListener(listener);
+ asciiScrollBar.addSelectionListener(listener);
+ //f.dispose();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Format object messages to have a hexadecimal view and a ascii view.
+ * @param numOfBytes
+ * @param encoding
+ * @return
+ */
+ private static String displayByteFormat(Composite localComposite, byte[] byteArray, int numOfBytes,
+ String encoding, String direction, boolean isHex)
+ {
+ final Hex hexeconder = new Hex();
+ final byte[] encoded = hexeconder.encode(byteArray);
+
+ int hexLength = byteArray.length * 2;
+ StringBuilder sb = new StringBuilder();
+ int currentBytePos = (Integer) localComposite.getData("currentBytePos");
+ int startingBytePos = (Integer) localComposite.getData("startingBytePos");
+
+ int strLength = 0;
+ int offset = 0;
+ String encStr;
+ if (isHex)
+ {
+ if (direction.equals("<<"))
+ {
+ strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes;
+ offset = 0;
+ }
+ else if (direction.equals("<"))
+ {
+ strLength = (startingBytePos - numOfBytes < 0) ? startingBytePos : numOfBytes;
+ offset = (startingBytePos - numOfBytes < 0) ? 0 : startingBytePos - numOfBytes;
+ }
+ else if (direction.equals(">"))
+ {
+ strLength = (numOfBytes > (hexLength - currentBytePos)) ? hexLength - currentBytePos : numOfBytes;
+ offset = currentBytePos;
+ }
+ else if (direction.equals(">>"))
+ {
+ strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes;
+ offset = (hexLength - numOfBytes > 0) ? hexLength - numOfBytes : 0;
+ }
+ else
+ {
+ strLength = hexLength;
+ offset = 0;
+ }
+ localComposite.setData("strLength", strLength);
+ localComposite.setData("currentBytePos", offset + strLength);
+ localComposite.setData("startingBytePos", offset);
+
+ if (_lastButton != null && !_lastButton.isDisposed())
+ {
+ //Set button state
+ _previousButton.setEnabled(offset != 0);
+ _nextButton.setEnabled(offset + strLength != hexLength);
+
+ //set the text fields
+ _hexNumTextToStart.setText("" + offset / 2);
+ _hexNumTextToEnd.setText("" + (hexLength - (offset + strLength)) / 2);
+ }
+ }
+
+ try
+ {
+ if (isHex)
+ {
+ encStr = new String(encoded, offset, strLength, encoding);
+ for (int c = 0; c < strLength; c++)
+ {
+ sb.append(encStr.charAt(c));
+ if (c % 2 == 1)
+ {
+ sb.append(" ");
+ }
+ }
+ return sb.toString().toUpperCase();
+ }
+ else
+ {
+ strLength = (Integer) localComposite.getData("strLength");
+ sb = new StringBuilder();
+ encStr = new String(byteArray, startingBytePos / 2, strLength / 2, encoding);
+ for (int c = 0; c < encStr.length(); c++)
+ {
+ char ch = encStr.charAt(c);
+ if (ch > 31 && ch < 127)
+ {
+ sb.append(ch);
+ }
+ else
+ {
+ sb.append("?");
+ }
+
+ sb.append(" ");
+ }
+ }
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ e.printStackTrace();
+ }
+ return sb.toString();
}
- public static int popupConfirmationMessage(String title, String message)
+ public static int popupInfoMessage(String title, String message)
{
- MessageBox messageBox = new MessageBox(Display.getCurrent().getActiveShell(),
- SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL);
- messageBox.setMessage(message);
- messageBox.setText(title);
- int response = messageBox.open();
-
- return response;
+ return showBox(title, message, SWT.ICON_INFORMATION | SWT.OK);
}
- public static void popupError(String title, String message, Throwable ex)
+ public static int popupErrorMessage(String title, String message)
{
- IStatus status = new Status(IStatus.ERROR, ApplicationWorkbenchAdvisor.PERSPECTIVE_ID,
- IStatus.ERROR, ex.toString(), ex);
- ErrorDialog.openError(Display.getCurrent().getActiveShell(), title, message, status);
+ return showBox(title, message, SWT.ICON_ERROR | SWT.OK);
+ }
+ public static int popupConfirmationMessage(String title, String message)
+ {
+ return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO);
}
- public static void popupError(String errorMsg)
+ public static int popupOkCancelConfirmationMessage(String title, String message)
{
- Display display = Display.getCurrent();
- Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX);
- shell.setText("Attribute");
- shell.setLayout(new GridLayout());
- int x = display.getBounds().width;
- int y = display.getBounds().height;
- int width = 500;
- int height = 250;
- shell.setBounds(x/4, y/4, width, height);
-
- Label label = new Label(shell, SWT.NONE);
- label.setText(errorMsg);
- label.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
-
- shell.open();
- while (!shell.isDisposed())
- {
- if (!display.readAndDispatch())
- {
- display.sleep();
- }
- }
- shell.dispose();
+ return showBox(title, message,SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
}
+
public static Shell createPopupShell(String title, int width, int height)
{
Display display = Display.getCurrent();
- Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |SWT.MAX);
+ final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |SWT.MAX);
shell.setText(title);
shell.setLayout(new GridLayout());
int x = display.getBounds().width;
int y = display.getBounds().height;
shell.setBounds(x/4, y/4, width, height);
+ shell.addListener(SWT.Traverse, new Listener () {
+ public void handleEvent (Event event) {
+ switch (event.detail) {
+ case SWT.TRAVERSE_ESCAPE:
+ shell.close ();
+ event.detail = SWT.TRAVERSE_NONE;
+ event.doit = false;
+ break;
+ }
+ }
+ });
+
return shell;
}
+ public static Shell createModalDialogShell(Shell parent, String title)
+ {
+ final Shell shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+ shell.setText(title);
+ shell.setLayout(new GridLayout());
+
+ shell.addListener(SWT.Traverse, new Listener () {
+ public void handleEvent (Event event) {
+ switch (event.detail) {
+ case SWT.TRAVERSE_ESCAPE:
+ shell.close ();
+ event.detail = SWT.TRAVERSE_NONE;
+ event.doit = false;
+ break;
+ }
+ }
+ });
+
+ return shell;
+ }
+
/**
* Creates a List widget for displaying array of strings
* @param compositeHolder
@@ -562,29 +902,7 @@ public class ViewUtility
{
oldControls[i].dispose();
}
- }
-
- public static char[] getMD5HashedCharArray(Object text) throws NoSuchAlgorithmException, UnsupportedEncodingException
- {
- byte[] data = ((String)text).getBytes("utf-8");
-
- MessageDigest md = MessageDigest.getInstance("MD5");
-
- for (byte b : data)
- {
- md.update(b);
- }
-
- byte[] digest = md.digest();
-
- char[] byteArray = new char[digest.length];
- int index = 0;
- for (byte b : digest)
- {
- byteArray[index++] = (char)b;
- }
- return byteArray;
- }
+ }
public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
{
@@ -638,4 +956,69 @@ public class ViewUtility
return -1;
}
}
+
+ public static void setMBeanView(MBeanView mbeanView)
+ {
+ _mbeanView = mbeanView;
+ }
+
+ /**
+ * Report feedback for the operation
+ * @param result true if success, false if unsuccessful, null if invoked but void result type.
+ * @param successMessage
+ * @param failureMessage
+ */
+ public static void operationResultFeedback(Boolean result, String successMessage, String failureMessage)
+ {
+ Image icon;
+
+ if(_mbeanView != null)
+ {
+ if(result == null)
+ {
+ icon = ApplicationRegistry.getImage(SUCCESS_IMAGE);
+ _mbeanView.populateStatusBar(icon, successMessage);
+ }
+ else if(result)
+ {
+ icon = ApplicationRegistry.getImage(SUCCESS_IMAGE);
+ _mbeanView.populateStatusBar(icon, successMessage);
+ }
+ else
+ {
+ icon = ApplicationRegistry.getImage(FAILURE_IMAGE);
+ _mbeanView.populateStatusBar(icon, failureMessage);
+ popupErrorMessage("Operation Failed", failureMessage);
+ }
+ }
+ }
+
+ public static void operationFailedStatusBarMessage(String failureMessage)
+ {
+ Image icon = ApplicationRegistry.getImage(FAILURE_IMAGE);
+
+ if(_mbeanView != null)
+ {
+ _mbeanView.populateStatusBar(icon, failureMessage);
+ }
+ }
+
+ public static void centerChildInParentShell(Shell parent, Shell child)
+ {
+ //get current parent shell size and location
+ int parentLocX = parent.getBounds().x;
+ int parentLocY = parent.getBounds().y;
+ int parentWidth = parent.getBounds().width;
+ int parentHeight = parent.getBounds().height;
+
+ //get current child size
+ int childWidth = child.getSize().x;
+ int childHeight = child.getSize().y;
+
+ //centre the child within/over the parent
+ child.setBounds((parentWidth - childWidth)/2 + parentLocX,
+ (parentHeight - childHeight)/2 + parentLocY,
+ childWidth, childHeight);
+ }
+
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/connection/ConnectionOperationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/connection/ConnectionOperationsTabControl.java
new file mode 100644
index 0000000000..3281757526
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/connection/ConnectionOperationsTabControl.java
@@ -0,0 +1,547 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.connection;
+
+import java.util.Collection;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Group;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * Control class for the Connection mbean Operations tab.
+ */
+public class ConnectionOperationsTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private Form _form;
+ private Table _table = null;
+ private TableViewer _tableViewer = null;
+ private Composite _paramsComposite = null;
+
+ private TabularDataSupport _channels = null;
+ private ManagedConnection _cmb;
+ private ApiVersion _ApiVersion;
+
+ static final String CHAN_ID = ManagedConnection.COMPOSITE_ITEM_NAMES[0];
+ static final String TRANSACTIONAL = ManagedConnection.COMPOSITE_ITEM_NAMES[1];
+ static final String DEFAULT_QUEUE = ManagedConnection.COMPOSITE_ITEM_NAMES[2];
+ static final String UNACKED_COUNT = ManagedConnection.COMPOSITE_ITEM_NAMES[3];
+ static final String FLOW_BLOCKED = ManagedConnection.COMPOSITE_ITEM_NAMES[4];
+
+ public ConnectionOperationsTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
+ _cmb = (ManagedConnection) MBeanServerInvocationHandler.newProxyInstance(mbsc,
+ mbean.getObjectName(), ManagedConnection.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout());
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _channels = null;
+ try
+ {
+ //gather a list of all channels on the connection for display and selection
+ _channels = (TabularDataSupport) _cmb.channels();
+ }
+ catch (Exception e)
+ {
+ MBeanUtility.handleException(mbean,e);
+ }
+
+ _tableViewer.setInput(_channels);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ Group viewChannelsGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ viewChannelsGroup.setBackground(_paramsComposite.getBackground());
+ viewChannelsGroup.setText("Channels");
+ viewChannelsGroup.setLayout(new GridLayout());
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.heightHint = 250;
+ gridData.minimumHeight = 250;
+
+ viewChannelsGroup.setLayoutData(gridData);
+
+ _table = new Table (viewChannelsGroup, SWT.SINGLE | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(data);
+
+ _tableViewer = new TableViewer(_table);
+ final TableSorter tableSorter = new TableSorter();
+
+ String[] titles;
+ if(_ApiVersion.greaterThanOrEqualTo(1, 5))
+ {
+ titles = new String[]{"Id", "Transactional", "Num Unacked Msg", "Default Queue", "Flow Blocked"};
+ }
+ else
+ {
+ titles = new String[]{"Id", "Transactional", "Num Unacked Msg", "Default Queue"};
+ }
+ int[] bounds = { 50, 110, 145, 200, 110 };
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_table, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new ContentProviderImpl());
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+
+ Composite buttonsComposite = _toolkit.createComposite(viewChannelsGroup);
+ gridData = new GridData(SWT.RIGHT, SWT.BOTTOM, false, false);
+ buttonsComposite.setLayoutData(gridData);
+ buttonsComposite.setLayout(new GridLayout(2,false));
+
+ final Button commitButton = _toolkit.createButton(buttonsComposite, "Commit Transactions", SWT.PUSH);
+ commitButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ commitButton.setEnabled(false);
+ commitButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ final CompositeData selectedChannel = (CompositeData)_table.getItem(selectionIndex).getData();
+ Integer id = (Integer) selectedChannel.get(CHAN_ID);
+
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Commit Transactions",
+ "Commit transactions for channel:" + id + " ?");
+
+ if (response == SWT.OK)
+ {
+ try
+ {
+ _cmb.commitTransactions(id);
+ ViewUtility.operationResultFeedback(null, "Commited transactions", null);
+ }
+ catch (Exception e1)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error commiting transactions");
+ MBeanUtility.handleException(_mbean, e1);
+ }
+
+ refresh(_mbean);;
+ }
+ }
+ }
+ });
+
+ final Button rollbackButton = _toolkit.createButton(buttonsComposite, "Rollback Transactions", SWT.PUSH);
+ rollbackButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ rollbackButton.setEnabled(false);
+ rollbackButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ final CompositeData selectedChannel = (CompositeData)_table.getItem(selectionIndex).getData();
+ Integer id = (Integer) selectedChannel.get(CHAN_ID);
+
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Rollback Transactions",
+ "Rollback transactions for channel:" + id + " ?");
+
+ if (response == SWT.OK)
+ {
+ try
+ {
+ _cmb.rollbackTransactions(id);
+ ViewUtility.operationResultFeedback(null, "Rolled back transactions", null);
+ }
+ catch (Exception e1)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error rolling back transactions");
+ MBeanUtility.handleException(_mbean, e1);
+ }
+
+ refresh(_mbean);;
+ }
+ }
+
+ }
+ });
+
+ //listener for double clicking to open the selection mbean
+ _table.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ openMBean(_table);
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ final CompositeData selectedChannel = (CompositeData)_table.getItem(selectionIndex).getData();
+ Boolean transactional = (Boolean) selectedChannel.get(TRANSACTIONAL);
+
+ if(transactional)
+ {
+ rollbackButton.setEnabled(true);
+ commitButton.setEnabled(true);
+ }
+ else
+ {
+ rollbackButton.setEnabled(false);
+ commitButton.setEnabled(false);
+ }
+ }
+ else
+ {
+ rollbackButton.setEnabled(false);
+ commitButton.setEnabled(true);
+ }
+ }
+ });
+
+ Composite opsComposite = _toolkit.createComposite(_paramsComposite);
+ gridData = new GridData(SWT.LEFT, SWT.FILL, false, true);
+ opsComposite.setLayoutData(gridData);
+ opsComposite.setLayout(new GridLayout(3,false));
+
+ Group closeConnectionGroup = new Group(opsComposite, SWT.SHADOW_NONE);
+ closeConnectionGroup.setBackground(opsComposite.getBackground());
+ closeConnectionGroup.setText("Close Connection");
+ gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
+ closeConnectionGroup.setLayoutData(gridData);
+ closeConnectionGroup.setLayout(new GridLayout());
+
+ final Button closeConnectionButton = _toolkit.createButton(closeConnectionGroup, "Close Connection", SWT.PUSH);
+ closeConnectionButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Close Connection",
+ "Are you sure you wish to close the Connection?");
+
+ if (response == SWT.OK)
+ {
+ try
+ {
+ _cmb.closeConnection();
+ }
+ catch (Exception e1)
+ {
+ MBeanUtility.handleException(_mbean, e1);
+ }
+ }
+ }
+ });
+ }
+
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ Collection<Object> rowCollection = ((TabularDataSupport) parent).values();
+
+ return rowCollection.toArray();
+ }
+ }
+
+ /**
+ * Label Provider class for the table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // id column
+ return String.valueOf(((CompositeDataSupport) element).get(CHAN_ID));
+ case 1 : // transactional column
+ return String.valueOf(((CompositeDataSupport) element).get(TRANSACTIONAL));
+ case 2 : // num unacked msgs column
+ return String.valueOf(((CompositeDataSupport) element).get(UNACKED_COUNT));
+ case 3 : // default queue column
+ return String.valueOf(((CompositeDataSupport) element).get(DEFAULT_QUEUE));
+ case 4 : // flow blocked column
+ return String.valueOf(((CompositeDataSupport) element).get(FLOW_BLOCKED));
+ default :
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ public class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction = DESCENDING;
+
+ public TableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if (column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ CompositeData chan1 = (CompositeData) e1;
+ CompositeData chan2 = (CompositeData) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ case 0:
+ comparison = ((Integer) chan1.get(CHAN_ID)).compareTo((Integer)chan2.get(CHAN_ID));
+ break;
+ case 1:
+ comparison = String.valueOf(chan1.get(TRANSACTIONAL)).compareTo(
+ String.valueOf(chan2.get(TRANSACTIONAL)));
+ break;
+ case 2:
+ comparison = ((Long) chan1.get(UNACKED_COUNT)).compareTo((Long)chan2.get(UNACKED_COUNT));
+ break;
+ case 3:
+ comparison = String.valueOf(chan1.get(DEFAULT_QUEUE)).compareTo(
+ String.valueOf(chan2.get(DEFAULT_QUEUE)));
+ break;
+ case 4:
+ comparison = String.valueOf(chan1.get(FLOW_BLOCKED)).compareTo(
+ String.valueOf(chan2.get(FLOW_BLOCKED)));
+ break;
+ default:
+ comparison = 0;
+ }
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ private void openMBean(Table table)
+ {
+ int selectionIndex = table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ CompositeData channelResult = (CompositeData) table.getItem(selectionIndex).getData();
+ String queueName = (String) channelResult.get(DEFAULT_QUEUE);
+
+ if(queueName == null)
+ {
+ return;
+ }
+
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ ManagedBean selectedMBean = serverRegistry.getQueue(queueName, _mbean.getVirtualHostName());
+
+ if(selectedMBean == null)
+ {
+ ViewUtility.popupErrorMessage("Error", "Unable to retrieve the selected MBean to open it");
+ return;
+ }
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MBeanView view = (MBeanView) window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.openMBean(selectedMBean);
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(selectedMBean, ex);
+ }
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/ExchangeOperationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/ExchangeOperationsTabControl.java
new file mode 100644
index 0000000000..e3dea6e96b
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/ExchangeOperationsTabControl.java
@@ -0,0 +1,641 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.exchange;
+
+import static org.apache.qpid.management.ui.Constants.EXCHANGE_TYPE;
+import static org.apache.qpid.management.ui.Constants.DEFAULT_EXCHANGE_TYPE_VALUES;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * Control class for the Exchange mbean Operations tab.
+ */
+public class ExchangeOperationsTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private ScrolledForm _form;
+ private Table _keysTable = null;
+ private TableViewer _keysTableViewer = null;
+ private Table _queuesTable = null;
+ private TableViewer _queuesTableViewer = null;
+ private Composite _paramsComposite = null;
+
+ private TabularDataSupport _bindings = null;
+ private ManagedExchange _emb;
+ private ApiVersion _ApiVersion;
+
+ static final String BINDING_KEY = ManagedExchange.COMPOSITE_ITEM_NAMES[0];
+ static final String QUEUES = ManagedExchange.COMPOSITE_ITEM_NAMES[1];
+
+ public ExchangeOperationsTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
+ _emb = (ManagedExchange) MBeanServerInvocationHandler.newProxyInstance(mbsc,
+ mbean.getObjectName(), ManagedExchange.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createScrolledForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout());
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _keysTable.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _bindings = null;
+ try
+ {
+ //gather a list of all keys and queues for display and selection
+ _bindings = (TabularDataSupport) _emb.bindings();
+ }
+ catch (Exception e)
+ {
+ MBeanUtility.handleException(_mbean,e);
+ }
+
+ _keysTableViewer.setInput(_bindings);
+
+ //if we have a Qpid JMX API 1.3+ server
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ {
+ //if it is a fanout exchange
+ if(isFanoutExchange())
+ {
+ //if there are any queue bindings, there is a single wildcard binding key
+ //auto-select it to show all the queues bound to the exchange
+ if (_keysTable.getItemCount() == 1)
+ {
+ _keysTable.setSelection(0);
+ updateQueuesTable();
+ }
+ }
+ }
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ Group bindingsGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ bindingsGroup.setBackground(_paramsComposite.getBackground());
+ bindingsGroup.setText("Bindings");
+ bindingsGroup.setLayout(new GridLayout(2,false));
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ bindingsGroup.setLayoutData(gridData);
+
+ Composite tablesComposite = _toolkit.createComposite(bindingsGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.minimumHeight = 250;
+ gridData.heightHint = 250;
+ tablesComposite.setLayoutData(gridData);
+ tablesComposite.setLayout(new GridLayout(2,false));
+
+ _keysTable = new Table (tablesComposite, SWT.SINGLE | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _keysTable.setLinesVisible(true);
+ _keysTable.setHeaderVisible(true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _keysTable.setLayoutData(data);
+
+ _keysTableViewer = new TableViewer(_keysTable);
+ final TableSorter tableSorter = new TableSorter(BINDING_KEY);
+
+ String[] titles = {"Binding Key"};
+ int[] bounds = {200};
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_keysTable, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _keysTableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _keysTableViewer.setContentProvider(new ContentProviderImpl(BINDING_KEY));
+ _keysTableViewer.setLabelProvider(new LabelProviderImpl(BINDING_KEY));
+ _keysTableViewer.setSorter(tableSorter);
+ _keysTable.setSortColumn(_keysTable.getColumn(0));
+ _keysTable.setSortDirection(SWT.UP);
+
+
+ _queuesTable = new Table (tablesComposite, SWT.SINGLE | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _queuesTable.setLinesVisible (true);
+ _queuesTable.setHeaderVisible (true);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _queuesTable.setLayoutData(data);
+
+ _queuesTableViewer = new TableViewer(_queuesTable);
+ final TableSorter queuesTableSorter = new TableSorter(QUEUES);
+
+ titles = new String[]{"Queue Names"};
+ bounds = new int[]{225};
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_queuesTable, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ queuesTableSorter.setColumn(index);
+ final TableViewer viewer = _queuesTableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _queuesTableViewer.setContentProvider(new ContentProviderImpl(QUEUES));
+ _queuesTableViewer.setLabelProvider(new LabelProviderImpl(QUEUES));
+ _queuesTableViewer.setSorter(queuesTableSorter);
+ _queuesTable.setSortColumn(_queuesTable.getColumn(0));
+ _queuesTable.setSortDirection(SWT.UP);
+ _queuesTableViewer.setInput(new String[]{"Select a binding key to view queues"});
+
+ //listener for double clicking to open the selection mbean
+ _queuesTable.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ openMBean(_queuesTable);
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ _keysTableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ updateQueuesTable();
+ }
+ });
+
+ //Side Buttons
+ Composite buttonsComposite = _toolkit.createComposite(bindingsGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ buttonsComposite.setLayoutData(gridData);
+ buttonsComposite.setLayout(new GridLayout());
+
+ final Button createBindingButton = _toolkit.createButton(buttonsComposite, "Create ...", SWT.PUSH);
+ createBindingButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ createNewBinding(createBindingButton.getShell());
+ }
+ });
+
+ }
+
+ private void updateQueuesTable()
+ {
+ int selectionIndex = _keysTable.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ final CompositeData selectedMsg = (CompositeData)_keysTable.getItem(selectionIndex).getData();
+
+ String[] queues = (String[]) selectedMsg.get(QUEUES);
+ _queuesTableViewer.setInput(queues);
+ }
+ else
+ {
+ _queuesTableViewer.setInput(new String[]{"Select a binding key to view queues"});
+ }
+ }
+
+ private boolean isFanoutExchange()
+ {
+ return _mbean.getProperty(EXCHANGE_TYPE).equalsIgnoreCase(DEFAULT_EXCHANGE_TYPE_VALUES[1]);
+
+ }
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+ String type;
+
+ public ContentProviderImpl(String type)
+ {
+ this.type = type;
+ }
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ if(type.equals(BINDING_KEY))
+ {
+ Collection<Object> rowCollection = ((TabularDataSupport) parent).values();
+
+ return rowCollection.toArray();
+ }
+ else
+ {
+ //we have the list of queues, return directly
+ return (String[]) parent;
+ }
+ }
+ }
+
+ /**
+ * Label Provider class for the routing key table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ String type;
+
+ public LabelProviderImpl(String type)
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ if(type.equals(BINDING_KEY)) //binding num and queue name table
+ {
+ switch (columnIndex)
+ {
+ case 0 : // key column
+ return String.valueOf(((CompositeDataSupport) element).get(BINDING_KEY));
+ default :
+ return "";
+ }
+ }
+ else //binding key-value pair table
+ {
+ switch (columnIndex)
+ {
+ case 0 : //queue name column
+ return String.valueOf(element);
+ default :
+ return "";
+ }
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ public class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction = DESCENDING;
+
+ private String type;
+
+ public TableSorter(String type)
+ {
+ this.type = type;
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if (column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ int comparison = 0;
+
+ if(type.equals(BINDING_KEY))//binding num and queue name table
+ {
+ CompositeData binding1 = (CompositeData) e1;
+ CompositeData binding2 = (CompositeData) e2;
+
+ switch(column)
+ {
+ case 0:
+ comparison = ((String) binding1.get(BINDING_KEY)).compareTo((String) binding2.get(BINDING_KEY));
+ break;
+ default:
+ comparison = 0;
+ }
+ }
+ else //binding key-value pair table
+ {
+ switch(column)
+ {
+ case 0:
+ comparison = ((String)e1).compareTo((String) e2);
+ break;
+ default:
+ comparison = 0;
+ }
+ }
+
+
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ private void createNewBinding(Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Create New Binding");
+
+ Composite destinationComposite = _toolkit.createComposite(shell, SWT.NONE);
+ destinationComposite.setBackground(shell.getBackground());
+ destinationComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ destinationComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(destinationComposite,"Queue:").setBackground(shell.getBackground());
+ final Combo destinationCombo = new Combo(destinationComposite,SWT.NONE | SWT.READ_ONLY);
+ destinationCombo.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Composite bindingComposite = _toolkit.createComposite(shell, SWT.NONE);
+ bindingComposite.setBackground(shell.getBackground());
+ bindingComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ bindingComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(bindingComposite,"Binding:").setBackground(shell.getBackground());
+ final Text bindingText = new Text(bindingComposite, SWT.BORDER);
+ bindingText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ if(isFanoutExchange())
+ {
+ bindingText.setText("*");
+ }
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ List<String> queueList = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(_mbean.getVirtualHostName());
+
+ if(queueList.size() == 0)
+ {
+ destinationCombo.setItems(new String[]{"No queues available"});
+ okButton.setEnabled(false);
+ }
+ else
+ {
+ Collections.sort(queueList);
+ destinationCombo.setItems(queueList.toArray(new String[0]));
+ }
+ destinationCombo.select(0);
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String binding = bindingText.getText();
+
+ if (!isFanoutExchange() && (binding == null || binding.length() == 0))
+ {
+ ViewUtility.popupErrorMessage("Create New Binding", "Please enter a valid binding");
+ return;
+ }
+
+ String destQueue = destinationCombo.getItem(destinationCombo.getSelectionIndex()).toString();
+
+ shell.dispose();
+
+ try
+ {
+ _emb.createNewBinding(destQueue, binding);
+ ViewUtility.operationResultFeedback(null, "Created new Binding", null);
+ }
+ catch (Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error creating new Binding");
+ MBeanUtility.handleException(_mbean, e4);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void openMBean(Table table)
+ {
+ int selectionIndex = table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ String queueName = (String) table.getItem(selectionIndex).getData();
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ ManagedBean selectedMBean = serverRegistry.getQueue(queueName, _mbean.getVirtualHostName());
+
+ if(selectedMBean == null)
+ {
+ ViewUtility.popupErrorMessage("Error", "Unable to retrieve the selected MBean to open it");
+ return;
+ }
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MBeanView view = (MBeanView) window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.openMBean(selectedMBean);
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(selectedMBean, ex);
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/HeadersExchangeOperationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/HeadersExchangeOperationsTabControl.java
new file mode 100644
index 0000000000..fcce0e67b6
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/exchange/HeadersExchangeOperationsTabControl.java
@@ -0,0 +1,713 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.exchange;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * Control class for the Headers Exchange mbean Operations tab.
+ */
+public class HeadersExchangeOperationsTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private ScrolledForm _form;
+ private Table _bindingNumberTable = null;
+ private TableViewer _bindingNumberTableViewer = null;
+ private Table _headersTable = null;
+ private TableViewer _headersTableViewer = null;
+ private Composite _paramsComposite = null;
+
+ private TabularDataSupport _bindings = null;
+ private ManagedExchange _emb;
+
+ static final String BINDING_NUM = ManagedExchange.HEADERS_COMPOSITE_ITEM_NAMES[0];
+ static final String QUEUE_NAME = ManagedExchange.HEADERS_COMPOSITE_ITEM_NAMES[1];
+ static final String HEADER_BINDINGS = ManagedExchange.HEADERS_COMPOSITE_ITEM_NAMES[2];
+
+ public HeadersExchangeOperationsTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _emb = (ManagedExchange) MBeanServerInvocationHandler.newProxyInstance(mbsc,
+ mbean.getObjectName(), ManagedExchange.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createScrolledForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout());
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _bindingNumberTable.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+
+ _bindings = null;
+ try
+ {
+ //gather a list of all keys and queues for display and selection
+ _bindings = (TabularDataSupport) _emb.bindings();
+ }
+ catch (Exception e)
+ {
+ MBeanUtility.handleException(_mbean,e);
+ }
+
+ _bindingNumberTableViewer.setInput(_bindings);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ Group bindingsGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ bindingsGroup.setBackground(_paramsComposite.getBackground());
+ bindingsGroup.setText("Bindings");
+ bindingsGroup.setLayout(new GridLayout(2,false));
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ bindingsGroup.setLayoutData(gridData);
+
+ Composite tablesComposite = _toolkit.createComposite(bindingsGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.minimumHeight = 250;
+ gridData.heightHint = 250;
+ tablesComposite.setLayoutData(gridData);
+ tablesComposite.setLayout(new GridLayout(2,false));
+
+ //table of bindings for the exchange
+ _bindingNumberTable = new Table (tablesComposite, SWT.SINGLE | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _bindingNumberTable.setLinesVisible(true);
+ _bindingNumberTable.setHeaderVisible(true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.minimumHeight = 300;
+ data.heightHint = 300;
+ _bindingNumberTable.setLayoutData(data);
+
+ _bindingNumberTableViewer = new TableViewer(_bindingNumberTable);
+ final TableSorter tableSorter = new TableSorter(BINDING_NUM);
+
+ String[] titles = {"Binding Number", "Queue Name"};
+ int[] bounds = {135, 175};
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_bindingNumberTable, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _bindingNumberTableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _bindingNumberTableViewer.setContentProvider(new ContentProviderImpl(BINDING_NUM));
+ _bindingNumberTableViewer.setLabelProvider(new LabelProviderImpl(BINDING_NUM));
+ _bindingNumberTableViewer.setSorter(tableSorter);
+ _bindingNumberTable.setSortColumn(_bindingNumberTable.getColumn(0));
+ _bindingNumberTable.setSortDirection(SWT.UP);
+
+ //table of header bindings
+ _headersTable = new Table (tablesComposite, SWT.SINGLE | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _headersTable.setLinesVisible (true);
+ _headersTable.setHeaderVisible (true);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.minimumHeight = 300;
+ data.heightHint = 300;
+ _headersTable.setLayoutData(data);
+
+ _headersTableViewer = new TableViewer(_headersTable);
+ final TableSorter queuesTableSorter = new TableSorter(HEADER_BINDINGS);
+
+ titles = new String[]{"Header Bindings"};
+ bounds = new int[]{225};
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_headersTable, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ queuesTableSorter.setColumn(index);
+ final TableViewer viewer = _headersTableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _headersTableViewer.setContentProvider(new ContentProviderImpl(HEADER_BINDINGS));
+ _headersTableViewer.setLabelProvider(new LabelProviderImpl(HEADER_BINDINGS));
+ _headersTableViewer.setSorter(queuesTableSorter);
+ _headersTable.setSortColumn(_headersTable.getColumn(0));
+ _headersTable.setSortDirection(SWT.UP);
+ _headersTableViewer.setInput(new String[]{"Select a binding to view key-value pairs"});
+
+ _bindingNumberTableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _bindingNumberTable.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ final CompositeData selectedMsg = (CompositeData)_bindingNumberTable.getItem(selectionIndex).getData();
+
+ String[] bindings = (String[]) selectedMsg.get(HEADER_BINDINGS);
+ _headersTableViewer.setInput(bindings);
+ }
+ else
+ {
+ _headersTableViewer.setInput(new String[]{"Select a binding to view key-value pairs"});
+ }
+ }
+ });
+
+ //listener for double clicking to open the selection mbean
+ _bindingNumberTable.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ openMBean(_bindingNumberTable);
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ //Side Buttons
+ Composite buttonsComposite = _toolkit.createComposite(bindingsGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ buttonsComposite.setLayoutData(gridData);
+ buttonsComposite.setLayout(new GridLayout());
+
+ final Button createBindingButton = _toolkit.createButton(buttonsComposite, "Create ...", SWT.PUSH);
+ createBindingButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ createNewBinding(createBindingButton.getShell());
+ }
+ });
+
+ }
+
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+ String type;
+
+ public ContentProviderImpl(String type)
+ {
+ this.type = type;
+ }
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ if(type.equals(BINDING_NUM))
+ {
+ Collection<Object> rowCollection = ((TabularDataSupport) parent).values();
+
+ return rowCollection.toArray();
+ }
+ else
+ {
+ //we have the list of bindings, return directly
+ return (String[]) parent;
+ }
+ }
+ }
+
+ /**
+ * Label Provider class for the routing key table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ String type;
+
+ public LabelProviderImpl(String type)
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ if(type.equals(BINDING_NUM)) //binding num and queue name table
+ {
+ switch (columnIndex)
+ {
+ case 0 : // binding number column
+ return String.valueOf(((CompositeDataSupport) element).get(BINDING_NUM));
+ case 1 : // queue name column
+ return (String) ((CompositeDataSupport) element).get(QUEUE_NAME);
+ default :
+ return "";
+ }
+ }
+ else //binding key-value pair table
+ {
+ switch (columnIndex)
+ {
+ case 0 : //header binding column
+ return String.valueOf(element);
+ default :
+ return "";
+ }
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ public class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction = DESCENDING;
+
+ private String type;
+
+ public TableSorter(String type)
+ {
+ this.type = type;
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if (column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ int comparison = 0;
+
+ if(type.equals(BINDING_NUM)) //binding num and queue name table
+ {
+ CompositeData binding1 = (CompositeData) e1;
+ CompositeData binding2 = (CompositeData) e2;
+
+ switch(column)
+ {
+ case 0: // binding number column
+ comparison = ((Integer) binding1.get(BINDING_NUM)).compareTo((Integer) binding2.get(BINDING_NUM));
+ break;
+ case 1: // queue name column
+ comparison = ((String) binding1.get(QUEUE_NAME)).compareTo((String) binding2.get(QUEUE_NAME));
+ break;
+ default:
+ comparison = 0;
+ }
+ }
+ else //binding key-value pair table
+ {
+ switch(column)
+ {
+ case 0: //header binding column
+ comparison = ((String)e1).compareTo((String) e2);
+ break;
+ default:
+ comparison = 0;
+ }
+ }
+
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ private void createNewBinding(Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Create New Binding");
+
+ Composite queueNameComposite = _toolkit.createComposite(shell, SWT.NONE);
+ queueNameComposite.setBackground(shell.getBackground());
+ GridData layoutData = new GridData(SWT.CENTER, SWT.TOP, true, false);
+ layoutData.minimumWidth = 300;
+ queueNameComposite.setLayoutData(layoutData);
+ queueNameComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(queueNameComposite,"Queue:").setBackground(shell.getBackground());
+ final Combo destinationCombo = new Combo(queueNameComposite,SWT.NONE | SWT.READ_ONLY);
+ destinationCombo.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ final ScrolledComposite scrolledComposite = new ScrolledComposite(shell, SWT.V_SCROLL);
+ scrolledComposite.setExpandHorizontal(true);
+ scrolledComposite.setLayout(new GridLayout());
+ scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ scrolledComposite.setBackground(shell.getBackground());
+
+ final Composite bindingComposite = _toolkit.createComposite(scrolledComposite, SWT.NONE);
+ bindingComposite.setBackground(scrolledComposite.getBackground());
+ bindingComposite.setLayout(new GridLayout(2,true));
+ layoutData = new GridData(SWT.FILL, SWT.TOP, true, false);
+ bindingComposite.setLayoutData(layoutData);
+ scrolledComposite.setContent(bindingComposite);
+
+ Composite addMoreButtonComp = _toolkit.createComposite(shell);
+ addMoreButtonComp.setBackground(shell.getBackground());
+ addMoreButtonComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ addMoreButtonComp.setLayout(new GridLayout());
+
+ final Button addMoreButton = _toolkit.createButton(addMoreButtonComp, "Add additional field", SWT.PUSH);
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ List<String> queueList = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(_mbean.getVirtualHostName());
+
+ if(queueList.size() == 0)
+ {
+ destinationCombo.setItems(new String[]{"No queues available"});
+ okButton.setEnabled(false);
+ }
+ else
+ {
+ Collections.sort(queueList);
+ destinationCombo.setItems(queueList.toArray(new String[0]));
+ }
+ destinationCombo.select(0);
+
+ final HashMap<Text, Text> headerBindingHashMap = new HashMap<Text, Text>();
+
+ //add headings
+ Label keyLabel = _toolkit.createLabel(bindingComposite,"Key:");
+ keyLabel.setBackground(bindingComposite.getBackground());
+ keyLabel.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false));
+
+ Label valueLabel = _toolkit.createLabel(bindingComposite,"Value:");
+ valueLabel.setBackground(bindingComposite.getBackground());
+ valueLabel.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false));
+
+ //add the x-match key by default and offer a comobo to select its value
+ final Text xmatchKeyText = new Text(bindingComposite, SWT.BORDER);
+ xmatchKeyText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ xmatchKeyText.setText("x-match");
+ xmatchKeyText.setEditable(false);
+
+ final Combo xmatchValueCombo = new Combo(bindingComposite,SWT.NONE | SWT.READ_ONLY);
+ xmatchValueCombo.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ xmatchValueCombo.setItems(new String[]{"any", "all"});
+ xmatchValueCombo.select(0);
+
+ //make some empty key-value fields
+ for(int i=0; i < 4; i++)
+ {
+ Text keyText = new Text(bindingComposite, SWT.BORDER);
+ Text valueText = new Text(bindingComposite, SWT.BORDER);
+ keyText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ headerBindingHashMap.put(keyText, valueText);
+ }
+ bindingComposite.setSize(bindingComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+
+ //allow adding more fields for additional key-value pairs
+ addMoreButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ Text keyText = new Text(bindingComposite, SWT.BORDER);
+ Text valueText = new Text(bindingComposite, SWT.BORDER);
+ keyText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ headerBindingHashMap.put(keyText, valueText);
+
+ bindingComposite.setSize(bindingComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ bindingComposite.layout(true);
+ scrolledComposite.layout(true);
+ }
+ });
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String xMatchString = xmatchValueCombo.getText();
+
+ String destQueue = destinationCombo.getItem(destinationCombo.getSelectionIndex()).toString();
+
+ StringBuffer bindingValue = new StringBuffer();
+
+ //insert the x-match key-value pair
+ if (xMatchString.equalsIgnoreCase("any"))
+ {
+ bindingValue.append("x-match=any");
+ }
+ else
+ {
+ bindingValue.append("x-match=all");
+ }
+
+ //insert the other key-value pairs
+ for (Text keyText : headerBindingHashMap.keySet())
+ {
+
+ String key = keyText.getText();
+ if(key == null || key.length() == 0)
+ {
+ continue;
+ }
+
+ Text valueText = headerBindingHashMap.get(keyText);
+ String value = valueText.getText();
+
+ bindingValue.append(",");
+ bindingValue.append(key + "=");
+ //empty values are permitted, signalling only key-presence is required
+ if(value != null && value.length() > 0)
+ {
+ bindingValue.append(value);
+ }
+ }
+
+ shell.dispose();
+
+ try
+ {
+ _emb.createNewBinding(destQueue, bindingValue.toString());
+ ViewUtility.operationResultFeedback(null, "Created new Binding", null);
+ }
+ catch (Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error creating new Binding");
+ MBeanUtility.handleException(_mbean, e4);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void openMBean(Table table)
+ {
+ int selectionIndex = table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ CompositeData bindingResult = (CompositeData) table.getItem(selectionIndex).getData();
+ String queueName = (String) bindingResult.get(QUEUE_NAME);
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean);
+ ManagedBean selectedMBean = serverRegistry.getQueue(queueName, _mbean.getVirtualHostName());
+
+ if(selectedMBean == null)
+ {
+ ViewUtility.popupErrorMessage("Error", "Unable to retrieve the selected MBean to open it");
+ return;
+ }
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MBeanView view = (MBeanView) window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.openMBean(selectedMBean);
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(selectedMBean, ex);
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/ConfigurationFileTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/ConfigurationFileTabControl.java
new file mode 100644
index 0000000000..536033368f
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/ConfigurationFileTabControl.java
@@ -0,0 +1,591 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.logging;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+
+import static org.apache.qpid.management.ui.Constants.FONT_BOLD;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * Control class for the LoggingManagement mbean ConfigFile Options tab.
+ */
+public class ConfigurationFileTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private ScrolledForm _form;
+ private Table _table = null;
+ private TableViewer _tableViewer = null;
+ private Composite _headerComposite = null;
+ private Composite _paramsComposite = null;
+
+ private Label _configFileRootLoggerLevelLabel = null;
+ private Label _logWatchIntervalLabel = null;
+ private String[] _availableLoggerLevels;
+ private TabularDataSupport _configFileLoggerLevels = null;
+ private LoggingManagement _lmmb;
+ private ApiVersion _ApiVersion;
+
+ static final String LOGGER_NAME = LoggingManagement.COMPOSITE_ITEM_NAMES[0];
+ static final String LOGGER_LEVEL = LoggingManagement.COMPOSITE_ITEM_NAMES[1];
+
+ public ConfigurationFileTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _lmmb = (LoggingManagement)
+ MBeanServerInvocationHandler.newProxyInstance(mbsc, mbean.getObjectName(),
+ LoggingManagement.class, false);
+ _ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createScrolledForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+
+ _headerComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ _headerComposite.setLayout(new GridLayout());
+
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout());
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ String configFileRootLoggerLevel = "-";
+ try
+ {
+ configFileRootLoggerLevel = _lmmb.getConfigFileRootLoggerLevel();
+ }
+ catch (Exception e1)
+ {
+ MBeanUtility.handleException(_mbean, e1);
+ }
+
+ int log4jLogWatchInterval = -1;
+ try
+ {
+ log4jLogWatchInterval = _lmmb.getLog4jLogWatchInterval();
+ }
+ catch (Exception e2)
+ {
+ MBeanUtility.handleException(_mbean, e2);
+ }
+
+ _configFileLoggerLevels = null;
+ try
+ {
+ _configFileLoggerLevels = (TabularDataSupport) _lmmb.viewConfigFileLoggerLevels();
+ }
+ catch (Exception e3)
+ {
+ MBeanUtility.handleException(_mbean, e3);
+ }
+
+ _configFileRootLoggerLevelLabel.setText(String.valueOf(configFileRootLoggerLevel));
+ if (log4jLogWatchInterval == 0)
+ {
+ _logWatchIntervalLabel.setText("Disabled (0 sec)");
+ }
+ else
+ {
+ _logWatchIntervalLabel.setText(String.valueOf(log4jLogWatchInterval) + " seconds");
+ }
+ _tableViewer.setInput(_configFileLoggerLevels);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ try
+ {
+ _availableLoggerLevels = _lmmb.getAvailableLoggerLevels();
+ }
+ catch(Exception e)
+ {
+ _availableLoggerLevels = new String[]{"ALL","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","OFF"};
+ }
+
+ Label noteLabel = _toolkit.createLabel(_headerComposite,
+ "NOTE: These options modify the configuration file. " +
+ "Changes only take effect automatically if LogWatch is enabled.");
+ Label noteLabel2 = _toolkit.createLabel(_headerComposite,
+ "A child Logger set to a non-inherited Level in the Runtime tab " +
+ "will retain that value after the file is reloaded.");
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ noteLabel.setLayoutData(gridData);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ noteLabel2.setLayoutData(gridData);
+
+ Group configFileLoggerLevelsGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ configFileLoggerLevelsGroup.setBackground(_paramsComposite.getBackground());
+ configFileLoggerLevelsGroup.setText("Configuration File Logger Levels");
+ configFileLoggerLevelsGroup.setLayout(new GridLayout());
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ configFileLoggerLevelsGroup.setLayoutData(gridData);
+
+ Composite tableComposite = _toolkit.createComposite(configFileLoggerLevelsGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.heightHint = 250;
+ gridData.minimumHeight = 250;
+ tableComposite.setLayoutData(gridData);
+ GridLayout gridLayout = new GridLayout();
+
+ tableComposite.setLayout(gridLayout);
+
+ _table = new Table (tableComposite, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(data);
+
+ _tableViewer = new TableViewer(_table);
+ final LoggingTableSorter tableSorter = new LoggingTableSorter();
+
+ String[] titles = { LOGGER_NAME, LOGGER_LEVEL };
+ int[] bounds = { 600, 75 };
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableViewerColumn viewerColumn = new TableViewerColumn(_tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new LoggingTableContentProvider());
+ _tableViewer.setLabelProvider(new LoggingTableLabelProvider());
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+ _table.addMouseListener(new MouseListener()
+ {
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ editLoggerLevel(_table.getShell());
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ final Button logLevelEditButton = _toolkit.createButton(configFileLoggerLevelsGroup, "Edit Selected Logger(s)...", SWT.PUSH);
+ logLevelEditButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ logLevelEditButton.setEnabled(false);
+ logLevelEditButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ editLoggerLevel(logLevelEditButton.getShell());
+ }
+ });
+
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if(selectionIndex != -1)
+ {
+ logLevelEditButton.setEnabled(true);
+ }
+ else
+ {
+ logLevelEditButton.setEnabled(false);
+ }
+ }
+ });
+
+
+ Composite attributesComposite = _toolkit.createComposite(_paramsComposite);
+ gridData = new GridData(SWT.LEFT, SWT.FILL, false, true);
+ attributesComposite.setLayoutData(gridData);
+ gridLayout = new GridLayout(3,false);
+ attributesComposite.setLayout(gridLayout);
+
+ Group configFileRootLoggerLevelGroup = new Group(attributesComposite, SWT.SHADOW_NONE);
+ configFileRootLoggerLevelGroup.setBackground(attributesComposite.getBackground());
+ configFileRootLoggerLevelGroup.setText("Config File RootLogger Level");
+ gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
+ configFileRootLoggerLevelGroup.setLayoutData(gridData);
+ configFileRootLoggerLevelGroup.setLayout(new GridLayout(2,false));
+
+ _configFileRootLoggerLevelLabel = _toolkit.createLabel(configFileRootLoggerLevelGroup, "-");
+ _configFileRootLoggerLevelLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD));
+ _configFileRootLoggerLevelLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+
+ final Button configFileRootLoggerLevelButton = _toolkit.createButton(configFileRootLoggerLevelGroup, "Edit ...", SWT.PUSH);
+ configFileRootLoggerLevelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false));
+ configFileRootLoggerLevelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ editRootLoggerLevel(configFileRootLoggerLevelButton.getShell());
+ }
+ });
+
+
+ Group logWatchIntervalGroup = new Group(attributesComposite, SWT.SHADOW_NONE);
+ logWatchIntervalGroup.setBackground(attributesComposite.getBackground());
+ logWatchIntervalGroup.setText("LogWatch Interval");
+ gridData = new GridData(SWT.LEFT, SWT.FILL, true, false);
+ logWatchIntervalGroup.setLayoutData(gridData);
+ logWatchIntervalGroup.setLayout(new GridLayout());
+
+ _logWatchIntervalLabel = _toolkit.createLabel(logWatchIntervalGroup, "-");
+ _logWatchIntervalLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD));
+ _logWatchIntervalLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true));
+
+ if(_ApiVersion.greaterThanOrEqualTo(1, 4))
+ {
+ Group reloadConfigFileGroup = new Group(attributesComposite, SWT.SHADOW_NONE);
+ reloadConfigFileGroup.setBackground(attributesComposite.getBackground());
+ reloadConfigFileGroup.setText("Reload Configuration File");
+ gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
+ reloadConfigFileGroup.setLayoutData(gridData);
+ reloadConfigFileGroup.setLayout(new GridLayout());
+
+ final Button reloadConfigFileButton = _toolkit.createButton(reloadConfigFileGroup, "Reload Config File", SWT.PUSH);
+ reloadConfigFileButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
+ reloadConfigFileButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Reload",
+ "Reload Logging Configuration File?");
+ if (response == SWT.OK)
+ {
+ try
+ {
+ _lmmb.reloadConfigFile();
+ ViewUtility.operationResultFeedback(null, "Reloaded Logging Configuration File", null);
+
+ }
+ catch (Exception ex)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error Reloading Logging Configuration File");
+ MBeanUtility.handleException(_mbean, ex);
+ }
+
+ refresh(_mbean);;
+ }
+ }
+ });
+ }
+ }
+
+
+
+ private void editLoggerLevel(Shell parent)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ int[] selectedIndices = _table.getSelectionIndices();
+
+ final ArrayList<String> selectedLoggers = new ArrayList<String>();
+
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ CompositeData selectedLogger = (CompositeData)_table.getItem(selectedIndices[index]).getData();
+ String user = (String) selectedLogger.get(LOGGER_NAME);
+ selectedLoggers.add(user);
+ }
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Set Config File Logger Level(s)");
+
+ _toolkit.createLabel(shell, "Logger(s): ").setBackground(shell.getBackground());
+
+ final Text headerText = new Text(shell, SWT.WRAP | SWT.V_SCROLL | SWT.BORDER );
+ headerText.setEditable(false);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ data.minimumHeight = 125;
+ data.heightHint = 125;
+ data.minimumWidth = 575;
+ data.widthHint = 575;
+ headerText.setLayoutData(data);
+
+ String lineSeperator = System.getProperty("line.separator");
+ for(String loggerName : selectedLoggers)
+ {
+ headerText.append(loggerName + lineSeperator);
+ }
+ headerText.setSelection(0);
+
+ Composite levelComp = _toolkit.createComposite(shell);
+ levelComp.setBackground(shell.getBackground());
+ levelComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ levelComp.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(levelComp,"Level: ").setBackground(levelComp.getBackground());
+ final Combo levelCombo = new Combo (levelComp, SWT.READ_ONLY );
+ levelCombo.setItems(_availableLoggerLevels);
+ levelCombo.select(0);
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String level = levelCombo.getItem(levelCombo.getSelectionIndex()).toString();
+
+ shell.close();
+
+ try
+ {
+ HashMap<String,Boolean> results = new HashMap<String,Boolean>();
+
+ //perform the updates, save the results.
+ for(String logger : selectedLoggers)
+ {
+ boolean result = _lmmb.setConfigFileLoggerLevel(logger, level);
+ results.put(logger, result);
+ }
+
+ //categorise the overall result
+ boolean overallResult = true;
+ for(boolean result : results.values())
+ {
+ if (!result)
+ {
+ overallResult = false;
+ }
+ }
+
+ //output the result to status bar if all succeed, and dialogue if not
+ if(overallResult)
+ {
+ ViewUtility.operationResultFeedback(overallResult, "Updated ConfigFile Logger Level(s)", null);
+ }
+ else
+ {
+ String failedToSetLevelOfLoggers = "";
+ for(String logger : results.keySet())
+ {
+ if(!results.get(logger))
+ {
+ failedToSetLevelOfLoggers = failedToSetLevelOfLoggers.concat(logger + ", ");
+ }
+ }
+
+ //cut off last ", "
+ int lastIndex = failedToSetLevelOfLoggers.lastIndexOf(',');
+ if (lastIndex != -1)
+ {
+ failedToSetLevelOfLoggers = failedToSetLevelOfLoggers.substring(0, lastIndex);
+ }
+
+ ViewUtility.operationResultFeedback(overallResult, null,
+ "Failed to update ConfigFile Logger Level(s): "
+ + failedToSetLevelOfLoggers);
+ }
+ }
+ catch(Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error updating Config File Logger Level(s)");
+ MBeanUtility.handleException(_mbean, e4);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+ }
+
+ private void editRootLoggerLevel(Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "ConfigFile RootLogger Level");
+
+ Composite levelComp = _toolkit.createComposite(shell);
+ levelComp.setBackground(shell.getBackground());
+ levelComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ levelComp.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(levelComp,"RootLogger level: ").setBackground(levelComp.getBackground());
+ final Combo levelCombo = new Combo (levelComp, SWT.READ_ONLY );
+ levelCombo.setItems(_availableLoggerLevels);
+ levelCombo.select(0);
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String selection = levelCombo.getItem(levelCombo.getSelectionIndex()).toString();
+ shell.dispose();
+ try
+ {
+ boolean result = _lmmb.setConfigFileRootLoggerLevel(selection);
+ ViewUtility.operationResultFeedback(result,
+ "Updated ConfigFile RootLogger Level", "Failed to update ConfigFile RootLogger Level");
+ }
+ catch (Exception e5)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error updating ConfigFile RootLogger Level");
+ MBeanUtility.handleException(_mbean, e5);
+ }
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableContentProvider.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableContentProvider.java
new file mode 100644
index 0000000000..6ef3ab70a7
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableContentProvider.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.logging;
+
+import java.util.Collection;
+
+import javax.management.openmbean.TabularDataSupport;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content Provider class for theLogging Management table viewers
+ */
+public class LoggingTableContentProvider implements IStructuredContentProvider
+{
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ Collection<Object> rowCollection = ((TabularDataSupport) parent).values();
+
+ return rowCollection.toArray();
+ }
+} \ No newline at end of file
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableLabelProvider.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableLabelProvider.java
new file mode 100644
index 0000000000..27f6040d7d
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableLabelProvider.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.logging;
+
+import javax.management.openmbean.CompositeDataSupport;
+
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Label Provider class for the LoggingManagement table viewers
+ */
+public class LoggingTableLabelProvider extends LabelProvider implements ITableLabelProvider
+{
+ private static final String LOGGER_NAME = LoggingManagement.COMPOSITE_ITEM_NAMES[0];
+ private static final String LOGGER_LEVEL = LoggingManagement.COMPOSITE_ITEM_NAMES[1];
+
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // logger name column
+ return (String) ((CompositeDataSupport) element).get(LOGGER_NAME);
+ case 1 : // logger level column
+ return (String) ((CompositeDataSupport) element).get(LOGGER_LEVEL);
+ default :
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableSorter.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableSorter.java
new file mode 100644
index 0000000000..c1833148d7
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/LoggingTableSorter.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.logging;
+
+import javax.management.openmbean.CompositeData;
+
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+/**
+ * Sorter class for the Logging Management table viewers.
+ */
+public class LoggingTableSorter extends ViewerSorter
+{
+ private static final String LOGGER_NAME = LoggingManagement.COMPOSITE_ITEM_NAMES[0];
+ private static final String LOGGER_LEVEL = LoggingManagement.COMPOSITE_ITEM_NAMES[1];
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int column;
+ private int direction;
+
+ public LoggingTableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if (column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ CompositeData logger1 = (CompositeData) e1;
+ CompositeData logger2 = (CompositeData) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ case 0:
+ comparison = String.valueOf(logger1.get(LOGGER_NAME)).compareTo(
+ String.valueOf(logger2.get(LOGGER_NAME)));
+ break;
+ case 1:
+ comparison = String.valueOf(logger1.get(LOGGER_LEVEL)).compareTo(
+ String.valueOf(logger2.get(LOGGER_LEVEL)));
+ break;
+ default:
+ comparison = 0;
+ }
+ // If descending order, flip the direction
+ if (direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/RuntimeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/RuntimeTabControl.java
new file mode 100644
index 0000000000..9834cd729a
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/logging/RuntimeTabControl.java
@@ -0,0 +1,595 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.logging;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+import static org.apache.qpid.management.ui.Constants.FONT_BOLD;
+
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * Control class for the LoggingManagement mbean Runtime Options tab.
+ */
+public class RuntimeTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private ScrolledForm _form;
+ private Table _table = null;
+ private TableViewer _tableViewer = null;
+ private Composite _headerComposite = null;
+ private Composite _paramsComposite = null;
+
+ private Label _runtimeRootLoggerLevelLabel = null;
+ private String[] _availableLoggerLevels;
+ private TabularDataSupport _runtimeLoggerLevels = null;
+ private ArrayList<String> _configFileLoggerNames = new ArrayList<String>();
+ private LoggingManagement _lmmb;
+
+ private static final String LOGGER_NAME = LoggingManagement.COMPOSITE_ITEM_NAMES[0];
+ private static final String LOGGER_LEVEL = LoggingManagement.COMPOSITE_ITEM_NAMES[1];
+
+ public RuntimeTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _lmmb = (LoggingManagement)
+ MBeanServerInvocationHandler.newProxyInstance(mbsc, mbean.getObjectName(),
+ LoggingManagement.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createScrolledForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+
+ _headerComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ _headerComposite.setLayout(new GridLayout());
+
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout());
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ String runtimeRootLoggerLevel = "-";
+ try
+ {
+ runtimeRootLoggerLevel = _lmmb.getRuntimeRootLoggerLevel();
+ }
+ catch(Exception e1)
+ {
+ MBeanUtility.handleException(_mbean, e1);
+ }
+
+ _runtimeLoggerLevels = null;
+ try
+ {
+ _runtimeLoggerLevels = (TabularDataSupport) _lmmb.viewEffectiveRuntimeLoggerLevels();
+ }
+ catch(Exception e2)
+ {
+ MBeanUtility.handleException(_mbean, e2);
+ }
+
+
+ try
+ {
+ TabularDataSupport confLoggers = (TabularDataSupport) _lmmb.viewConfigFileLoggerLevels();
+ ArrayList<String> confLoggerNames = new ArrayList<String>();
+
+ for(Object obj : confLoggers.values())
+ {
+ CompositeData comp = (CompositeData) obj;
+ confLoggerNames.add((String) comp.get(LOGGER_NAME));
+ }
+
+ _configFileLoggerNames = confLoggerNames;
+ }
+ catch(Exception e2)
+ {
+ //dont signal the failure, just dont highlight the config file loggers, empty the existing list.
+ _configFileLoggerNames.clear();
+ }
+
+ _runtimeRootLoggerLevelLabel.setText(String.valueOf(runtimeRootLoggerLevel));
+ _tableViewer.setInput(_runtimeLoggerLevels);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ try
+ {
+ _availableLoggerLevels = _lmmb.getAvailableLoggerLevels();
+ }
+ catch(Exception e)
+ {
+ _availableLoggerLevels = new String[]{"ALL","TRACE","DEBUG","INFO","WARN","ERROR","FATAL","OFF"};
+ }
+
+ Label noteLabel = _toolkit.createLabel(_headerComposite,
+ "NOTE: These options modify only the live runtime settings. " +
+ "Non-default values will be lost following broker restart.");
+ Label noteLabel2 = _toolkit.createLabel(_headerComposite,
+ "Loggers currently defined in the configuration file are " +
+ "highlighted. The other Loggers inherit a Level by default.");
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ noteLabel.setLayoutData(gridData);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ noteLabel2.setLayoutData(gridData);
+
+ Group effectiveRuntimeLoggerLevelsGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ effectiveRuntimeLoggerLevelsGroup.setBackground(_paramsComposite.getBackground());
+ effectiveRuntimeLoggerLevelsGroup.setText("Effective Runtime Logger Levels");
+ effectiveRuntimeLoggerLevelsGroup.setLayout(new GridLayout());
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ effectiveRuntimeLoggerLevelsGroup.setLayoutData(gridData);
+
+ Composite tableComposite = _toolkit.createComposite(effectiveRuntimeLoggerLevelsGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.heightHint = 250;
+ gridData.minimumHeight = 250;
+ tableComposite.setLayoutData(gridData);
+ GridLayout gridLayout = new GridLayout();
+ tableComposite.setLayout(gridLayout);
+
+ _table = new Table (tableComposite, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(data);
+
+ _tableViewer = new TableViewer(_table);
+ final LoggingTableSorter tableSorter = new LoggingTableSorter();
+
+ String[] titles = { LOGGER_NAME, LOGGER_LEVEL };
+ int[] bounds = { 600, 75 };
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableViewerColumn viewerColumn = new TableViewerColumn(_tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer.getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = (dir == SWT.UP ? SWT.DOWN : SWT.UP);
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new LoggingTableContentProvider());
+ _tableViewer.setLabelProvider(new RuntimeLoggingTableLabelProvider());
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+ _table.addMouseListener(new MouseListener()
+ {
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ editLoggerLevel(_table.getShell());
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ final Button logLevelEditButton = _toolkit.createButton(effectiveRuntimeLoggerLevelsGroup, "Edit Selected Logger(s)...", SWT.PUSH);
+ logLevelEditButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ logLevelEditButton.setEnabled(false);
+ logLevelEditButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ editLoggerLevel(logLevelEditButton.getShell());
+ }
+ });
+
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ logLevelEditButton.setEnabled(true);
+ }
+ else
+ {
+ logLevelEditButton.setEnabled(false);
+ }
+ }
+ });
+
+ Composite attributesComposite = _toolkit.createComposite(_paramsComposite);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ attributesComposite.setLayoutData(gridData);
+ gridLayout = new GridLayout(3,false);
+ attributesComposite.setLayout(gridLayout);
+
+ Group runtimeRootLoggerGroup = new Group(attributesComposite, SWT.SHADOW_NONE);
+ runtimeRootLoggerGroup.setBackground(attributesComposite.getBackground());
+ runtimeRootLoggerGroup.setText("Runtime RootLogger Level");
+ gridData = new GridData(SWT.LEFT, SWT.TOP, true, false);
+ runtimeRootLoggerGroup.setLayoutData(gridData);
+ runtimeRootLoggerGroup.setLayout(new GridLayout(2,false));
+
+ _runtimeRootLoggerLevelLabel = _toolkit.createLabel(runtimeRootLoggerGroup, "-");
+ _runtimeRootLoggerLevelLabel.setFont(ApplicationRegistry.getFont(FONT_BOLD));
+ _runtimeRootLoggerLevelLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+
+ final Button runtimeRootLoggerLevelButton = _toolkit.createButton(runtimeRootLoggerGroup, "Edit ...", SWT.PUSH);
+ runtimeRootLoggerLevelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false));
+ runtimeRootLoggerLevelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ editRootLoggerLevel(runtimeRootLoggerLevelButton.getShell());
+ }
+ });
+ }
+
+ private void editLoggerLevel(Shell parent)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ int[] selectedIndices = _table.getSelectionIndices();
+
+ final ArrayList<String> selectedLoggers = new ArrayList<String>();
+
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ CompositeData selectedLogger = (CompositeData)_table.getItem(selectedIndices[index]).getData();
+ String user = (String) selectedLogger.get(LOGGER_NAME);
+ selectedLoggers.add(user);
+ }
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Set Runtime Logger Level(s)");
+
+ _toolkit.createLabel(shell, "Logger(s): ").setBackground(shell.getBackground());
+
+ final Text headerText = new Text(shell, SWT.WRAP | SWT.V_SCROLL | SWT.BORDER );
+ headerText.setEditable(false);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ data.minimumHeight = 125;
+ data.heightHint = 125;
+ data.minimumWidth = 575;
+ data.widthHint = 575;
+ headerText.setLayoutData(data);
+
+ String lineSeperator = System.getProperty("line.separator");
+ for(String loggerName : selectedLoggers)
+ {
+ headerText.append(loggerName + lineSeperator);
+ }
+ headerText.setSelection(0);
+
+ Composite levelComp = _toolkit.createComposite(shell);
+ levelComp.setBackground(shell.getBackground());
+ levelComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ levelComp.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(levelComp,"Level: ").setBackground(levelComp.getBackground());
+ final Combo levelCombo = new Combo (levelComp, SWT.READ_ONLY );
+ levelCombo.setItems(_availableLoggerLevels);
+ levelCombo.select(0);
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String level = levelCombo.getItem(levelCombo.getSelectionIndex()).toString();
+
+ shell.close();
+
+ try
+ {
+ HashMap<String,Boolean> results = new HashMap<String,Boolean>();
+
+ //perform the updates, save the results.
+ for(String logger : selectedLoggers)
+ {
+ boolean result = _lmmb.setRuntimeLoggerLevel(logger, level);
+ results.put(logger, result);
+ }
+
+ //categorise the overall result
+ boolean overallResult = true;
+ for(boolean result : results.values())
+ {
+ if (!result)
+ {
+ overallResult = false;
+ }
+ }
+
+ //output the result to status bar if all succeed, and dialogue if not
+ if(overallResult)
+ {
+ ViewUtility.operationResultFeedback(overallResult, "Updated Runtime Logger Level(s)", null);
+ }
+ else
+ {
+ String failedToSetLevelOfLoggers = "";
+ for(String logger : results.keySet())
+ {
+ if(!results.get(logger))
+ {
+ failedToSetLevelOfLoggers = failedToSetLevelOfLoggers.concat(logger + ", ");
+ }
+ }
+
+ //cut off last ", "
+ int lastIndex = failedToSetLevelOfLoggers.lastIndexOf(',');
+ if (lastIndex != -1)
+ {
+ failedToSetLevelOfLoggers = failedToSetLevelOfLoggers.substring(0, lastIndex);
+ }
+
+ ViewUtility.operationResultFeedback(overallResult, null,
+ "Failed to update Runtime Logger Level(s): "
+ + failedToSetLevelOfLoggers);
+ }
+ }
+ catch(Exception e3)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error updating Runtime Logger Level(s)");
+ MBeanUtility.handleException(_mbean, e3);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+ }
+
+ private void editRootLoggerLevel(Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Runtime RootLogger Level");
+
+ Composite levelComp = _toolkit.createComposite(shell);
+ levelComp.setBackground(shell.getBackground());
+ levelComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ levelComp.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(levelComp,"RootLogger level: ").setBackground(levelComp.getBackground());
+ final Combo levelCombo = new Combo (levelComp, SWT.READ_ONLY );
+ levelCombo.setItems(_availableLoggerLevels);
+ levelCombo.select(0);
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String selection = levelCombo.getItem(levelCombo.getSelectionIndex()).toString();
+ shell.dispose();
+
+ try
+ {
+ boolean result = _lmmb.setRuntimeRootLoggerLevel(selection);
+ ViewUtility.operationResultFeedback(result,
+ "Updated Runtime RootLogger Level", "Failed to update Runtime Logger Level");
+ }
+ catch(Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error updating Runtime Logger Level");
+ MBeanUtility.handleException(_mbean, e4);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ /**
+ * Label Provider class for the RuntimeLoggers table viewer
+ */
+ public class RuntimeLoggingTableLabelProvider extends LabelProvider implements ITableLabelProvider, IColorProvider
+ {
+
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // logger name column
+ return (String) ((CompositeDataSupport) element).get(LOGGER_NAME);
+ case 1 : // logger level column
+ return (String) ((CompositeDataSupport) element).get(LOGGER_LEVEL);
+ default :
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ @Override
+ public Color getBackground(Object element)
+ {
+ return null;
+ }
+
+ @Override
+ public Color getForeground(Object element)
+ {
+ String loggerName = (String) ((CompositeData) element).get(LOGGER_NAME);
+ if(_configFileLoggerNames.contains(loggerName))
+ {
+ return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java
new file mode 100644
index 0000000000..309b84f52b
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/queue/QueueOperationsTabControl.java
@@ -0,0 +1,1114 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.queue;
+
+import static org.apache.qpid.management.ui.Constants.CONSOLE_IMAGE;
+import static org.apache.qpid.management.ui.Constants.RESULT;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.NumberVerifyListener;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * Control class for the Queue mbean Operations tab.
+ */
+public class QueueOperationsTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private ScrolledForm _form;
+ private Table _table = null;
+ private TableViewer _tableViewer = null;
+ private Composite _paramsComposite = null;
+
+ private ApiVersion _ApiVersion;
+
+ private Text _fromMsgText;
+ private Text _toMsgText;
+ private static final String FROM_DEFAULT = "1";
+ private static final String TO_DEFAULT = "50";
+ private long _interval = 50; //(to-from)+1
+ private Long _fromMsg = new Long(FROM_DEFAULT);
+ private Long _toMsg = new Long(TO_DEFAULT);
+
+ private TabularDataSupport _messages = null;
+ private ManagedQueue _qmb;
+
+ private Button _previousButton;
+ private Button _nextButton;
+
+ private static final String MSG_AMQ_ID = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[0];
+ private static final String MSG_HEADER = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[1];
+ private static final String MSG_SIZE = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[2];
+ private static final String MSG_REDELIVERED = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[3];
+ private static final String MSG_QUEUE_POS = ManagedQueue.VIEW_MSGS_COMPOSITE_ITEM_NAMES[4];
+
+ public QueueOperationsTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
+ _qmb = (ManagedQueue) MBeanServerInvocationHandler.newProxyInstance(mbsc,
+ mbean.getObjectName(), ManagedQueue.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createScrolledForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout());
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _messages = null;
+ try
+ {
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ { //broker supports Qpid JMX API 1.3 and takes Long values
+
+ //gather a list of all messages on the queue for display and selection
+ _messages = (TabularDataSupport) _qmb.viewMessages(_fromMsg,_toMsg);
+ }
+ else
+ { //broker supports Qpid JMX API 1.2 or below and takes int values
+
+ if(_toMsg > Integer.MAX_VALUE || _toMsg > Integer.MAX_VALUE)
+ {
+ ViewUtility.popupErrorMessage("Error", "This broker only supports viewing up to message " + Integer.MAX_VALUE);
+ _tableViewer.setInput(null);
+ return;
+ }
+
+ //gather a list of all messages on the queue for display and selection
+ _messages = (TabularDataSupport) _qmb.viewMessages(_fromMsg.intValue(), _toMsg.intValue());
+ }
+ }
+ catch (Exception e)
+ {
+ MBeanUtility.handleException(mbean,e);
+ }
+
+ _tableViewer.setInput(_messages);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ Group messagesGroup = new Group(_paramsComposite, SWT.SHADOW_NONE | SWT.SCROLL_LINE);
+ messagesGroup.setBackground(_paramsComposite.getBackground());
+ messagesGroup.setText("Messages");
+ messagesGroup.setLayout(new GridLayout());
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ messagesGroup.setLayoutData(gridData);
+
+ //from and to fields for selecting the viewing range
+ Composite viewMessageRangeComposite = _toolkit.createComposite(messagesGroup);
+ gridData = new GridData(SWT.LEFT, SWT.FILL, false, false);
+ viewMessageRangeComposite.setLayoutData(gridData);
+ viewMessageRangeComposite.setLayout(new GridLayout(8,false));
+
+ _toolkit.createLabel(viewMessageRangeComposite, "Queue pos: ");
+ _fromMsgText = new Text(viewMessageRangeComposite, SWT.BORDER);
+ _fromMsgText.setText(FROM_DEFAULT);
+ gridData = new GridData(SWT.LEFT, SWT.FILL, false, false);
+ gridData.widthHint = 75;
+ _fromMsgText.setLayoutData(gridData);
+ _fromMsgText.addVerifyListener(new NumberVerifyListener());
+ _fromMsgText.addKeyListener(new KeyAdapter()
+ {
+ public void keyPressed(KeyEvent event)
+ {
+ if (event.character == SWT.CR)
+ {
+ updateMessageInterval();
+ }
+ }
+ });
+
+ _toolkit.createLabel(viewMessageRangeComposite, "to");
+
+ _toMsgText = new Text(viewMessageRangeComposite, SWT.BORDER);
+ _toMsgText.setText(TO_DEFAULT);
+ gridData = new GridData(SWT.LEFT, SWT.FILL, false, false);
+ gridData.widthHint = 75;
+ _toMsgText.setLayoutData(gridData);
+ _toMsgText.addVerifyListener(new NumberVerifyListener());
+ _toMsgText.addKeyListener(new KeyAdapter()
+ {
+ public void keyPressed(KeyEvent event)
+ {
+ if (event.character == SWT.CR)
+ {
+ updateMessageInterval();
+ }
+ }
+ });
+
+ final Button setButton = _toolkit.createButton(viewMessageRangeComposite, "Set", SWT.PUSH);
+ setButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
+ setButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ updateMessageInterval();
+ }
+ });
+
+ _toolkit.createLabel(viewMessageRangeComposite, " "); //spacer
+
+ _previousButton = _toolkit.createButton(viewMessageRangeComposite, "< Prev " + _interval, SWT.PUSH);
+ _previousButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
+ _previousButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ //make 'to' be 'from - 1' unless from is 1 (ie there are no previous messages)
+ if(_fromMsg > 1)
+ {
+ _toMsg = _fromMsg - 1;
+ _toMsgText.setText(_toMsg.toString());
+ }
+
+ //make 'from' be 'from - INTERVAL', or make it 1 if that would make it 0 or less
+ _fromMsg = (_fromMsg - _interval < 1) ? 1 : _fromMsg - _interval;
+ _fromMsgText.setText(_fromMsg.toString());
+
+ refresh(_mbean);
+ }
+ });
+
+ _nextButton = _toolkit.createButton(viewMessageRangeComposite, "Next " + _interval + " >", SWT.PUSH);
+ _nextButton.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false));
+ _nextButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ //make 'from' be 'to + 1' unless 'to' is already Long.MAX_VALUE
+ if(_toMsg != Long.MAX_VALUE)
+ {
+ _fromMsg = _toMsg + 1;
+ _fromMsgText.setText(_fromMsg.toString());
+ }
+
+ //make 'to' be 'to + INTERVAL', or make it Long.MAX_VALUE if that would too large
+ _toMsg = (Long.MAX_VALUE - _toMsg > _interval) ? _toMsg + _interval : Long.MAX_VALUE;
+ _toMsgText.setText(_toMsg.toString());
+
+ refresh(_mbean);
+ }
+ });
+
+ //message table
+ Composite tableAndButtonsComposite = _toolkit.createComposite(messagesGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.minimumHeight = 180;
+ gridData.heightHint = 180;
+ tableAndButtonsComposite.setLayoutData(gridData);
+ tableAndButtonsComposite.setLayout(new GridLayout(2,false));
+
+ _table = new Table (tableAndButtonsComposite, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(data);
+
+ _tableViewer = new TableViewer(_table);
+ final TableSorter tableSorter = new TableSorter();
+
+ String[] titles = {"AMQ ID", "Size(bytes)"};
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ {
+ //if server management API is >= 1.3, show message's queue position
+ titles = new String[]{"AMQ ID", "Size(bytes)", "Queue Position"};
+ }
+
+ int[] bounds = { 175, 175, 140 };
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_table, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new ContentProviderImpl());
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+
+ //Side Buttons
+ Composite buttonsComposite = _toolkit.createComposite(tableAndButtonsComposite);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ buttonsComposite.setLayoutData(gridData);
+ buttonsComposite.setLayout(new GridLayout());
+
+ final Button viewSelectedMsgButton = _toolkit.createButton(buttonsComposite, "View Message Content ...", SWT.PUSH);
+ viewSelectedMsgButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ viewSelectedMsgButton.setEnabled(false);
+ viewSelectedMsgButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_table.getSelectionIndex() == -1)
+ {
+ return;
+ }
+
+ viewMessageContent();
+ }
+ });
+
+ if(_ApiVersion.lessThan(1, 3)) //if the server predates Qpid JMX API 1.3
+ {
+ final Button deleteFirstMessageButton = _toolkit.createButton(buttonsComposite, "Delete 1st Unacquired Msg", SWT.PUSH);
+ deleteFirstMessageButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ deleteFirstMessageButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent se)
+ {
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Delete 1st unacquired message",
+ "Delete 1st unacquired message on the queue?\n\n"
+ + "NOTE: Any ongoing consumer activity may mean this is "
+ + "not the first message listed in the table.");
+ if (response == SWT.OK)
+ {
+ try
+ {
+ _qmb.deleteMessageFromTop();
+ ViewUtility.operationResultFeedback(null, "Deleted 1st unacquired message on the queue", null);
+ }
+ catch (Exception e)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error deleting 1st unacquired message on queue");
+ MBeanUtility.handleException(_mbean, e);
+ }
+
+ refresh(_mbean);;
+ }
+ }
+ });
+ }
+
+ final Button moveMessagesButton;
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ {
+ //If the server supports Qpid JMX API 1.3, show the move message button.
+ //This is being disabled for earlier brokers due to bugs affecting the result appearance
+ //and impacting on the ability of the source queues to deliver further messages.
+
+ moveMessagesButton = _toolkit.createButton(buttonsComposite, "Move Message(s) ...", SWT.PUSH);
+
+ moveMessagesButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ moveMessagesButton.setEnabled(false);
+ moveMessagesButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_table.getSelectionIndex() == -1)
+ {
+ return;
+ }
+
+ moveOrCopyMessages(moveMessagesButton.getShell(), QueueOperations.MOVE);
+ }
+ });
+ }
+ else
+ {
+ moveMessagesButton = null;
+ }
+
+ final Button copyMessagesButton;
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))//if the server supports Qpid JMX API 1.3
+ {
+ copyMessagesButton= _toolkit.createButton(buttonsComposite, "Copy Message(s) ...", SWT.PUSH);
+ copyMessagesButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ copyMessagesButton.setEnabled(false);
+ copyMessagesButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_table.getSelectionIndex() == -1)
+ {
+ return;
+ }
+
+ moveOrCopyMessages(copyMessagesButton.getShell(), QueueOperations.COPY);
+ }
+ });
+ }
+ else
+ {
+ copyMessagesButton = null;
+ }
+
+ final Button deleteMessagesButton;
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))//if the server supports Qpid JMX API 1.3
+ {
+ deleteMessagesButton = _toolkit.createButton(buttonsComposite, "Delete Message(s) ...", SWT.PUSH);
+ deleteMessagesButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ deleteMessagesButton.setEnabled(false);
+ deleteMessagesButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (_table.getSelectionIndex() == -1)
+ {
+ return;
+ }
+
+ deleteMessages(deleteMessagesButton.getShell());
+ }
+ });
+ }
+ else
+ {
+ deleteMessagesButton = null;
+ }
+
+ final Button clearQueueButton = _toolkit.createButton(buttonsComposite, "Clear Queue", SWT.PUSH);
+ clearQueueButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
+ clearQueueButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Clear Queue",
+ "Clear queue ?");
+ if (response == SWT.OK)
+ {
+ try
+ {
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ {
+ //Qpid JMX API 1.3+, returns the number of messages deleted
+ Long numDeleted = _qmb.clearQueue();
+ String message = "Queue cleared of " + numDeleted +
+ " non-acquired message" + (numDeleted == 1 ? "": "s");
+
+ ViewUtility.operationResultFeedback(null, message, null);
+ }
+ else
+ {
+ //Qpid JMX API 1.2 or below, void return
+ _qmb.clearQueue();
+ ViewUtility.operationResultFeedback(null, "Queue cleared of non-acquired messages", null);
+ }
+ }
+ catch (Exception e2)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error clearing Queue");
+ MBeanUtility.handleException(_mbean, e2);
+ }
+
+ refresh(_mbean);;
+ }
+ }
+ });
+
+ _toolkit.createLabel(messagesGroup, "Message Header: ");
+
+ //Redelivered status and header
+ Composite headerEtcComposite = _toolkit.createComposite(messagesGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
+ headerEtcComposite.setLayoutData(gridData);
+ headerEtcComposite.setLayout(new GridLayout());
+
+ final Text headerText = new Text(headerEtcComposite, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
+ headerText.setText("Select a message to view its header.");
+ headerText.setEditable(false);
+ data = new GridData(SWT.LEFT, SWT.TOP, false, false);
+ data.minimumHeight = 210;
+ data.heightHint = 210;
+ data.minimumWidth = 500;
+ data.widthHint = 500;
+ headerText.setLayoutData(data);
+
+ Composite redeliveryComposite = _toolkit.createComposite(headerEtcComposite);
+ redeliveryComposite.setLayout(new GridLayout(2,false));
+ data = new GridData(SWT.LEFT, SWT.FILL, false, false);
+ data.minimumWidth = 150;
+ data.widthHint = 150;
+ redeliveryComposite.setLayoutData(data);
+
+ _toolkit.createLabel(redeliveryComposite, "Redelivered: ");
+ final Text redeliveredText = new Text(redeliveryComposite, SWT.BORDER);
+ redeliveredText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ redeliveredText.setText("-");
+ redeliveredText.setEditable(false);
+
+ //listener for double clicking to view message content
+ _table.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ viewMessageContent();
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ //selection listener to enable and disable buttons, update header and redelivered info
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ headerText.setText("Select a message to view its header.");
+ redeliveredText.setText("-");
+ viewSelectedMsgButton.setEnabled(false);
+ if(moveMessagesButton != null)
+ {
+ moveMessagesButton.setEnabled(false);
+ }
+ if(copyMessagesButton != null)
+ {
+ copyMessagesButton.setEnabled(false);
+ }
+ if(deleteMessagesButton != null)
+ {
+ deleteMessagesButton.setEnabled(false);
+ }
+
+ return;
+ }
+ else
+ {
+ if(moveMessagesButton != null)
+ {
+ moveMessagesButton.setEnabled(true);
+ }
+ if(copyMessagesButton != null)
+ {
+ copyMessagesButton.setEnabled(true);
+ }
+ if(deleteMessagesButton != null)
+ {
+ deleteMessagesButton.setEnabled(true);
+ }
+
+ final CompositeData selectedMsg = (CompositeData)_table.getItem(selectionIndex).getData();
+ Boolean redelivered = (Boolean) selectedMsg.get(MSG_REDELIVERED);
+ redeliveredText.setText(redelivered.toString());
+
+ String[] msgHeader = (String[]) selectedMsg.get(MSG_HEADER);
+ headerText.setText("");
+ String lineSeperator = System.getProperty("line.separator");
+ int size = msgHeader.length;
+ for(int i=0; i < size; i++)
+ {
+ headerText.append(msgHeader[i]);
+ if(!(i == size - 1))
+ {
+ headerText.append(lineSeperator);
+ }
+ }
+ headerText.setSelection(0);
+ }
+
+ if (_table.getSelectionCount() > 1)
+ {
+ viewSelectedMsgButton.setEnabled(false);
+ }
+ else
+ {
+ viewSelectedMsgButton.setEnabled(true);
+ }
+
+ }
+ });
+
+ }
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ Collection<Object> rowCollection = ((TabularDataSupport) parent).values();
+
+ return rowCollection.toArray();
+ }
+ }
+
+ /**
+ * Label Provider class for the table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // msg id column
+ return String.valueOf(((CompositeDataSupport) element).get(MSG_AMQ_ID));
+ case 1 : // msg size column
+ return String.valueOf(((CompositeDataSupport) element).get(MSG_SIZE));
+ case 2 : // msg position in queue
+ return String.valueOf(((CompositeDataSupport) element).get(MSG_QUEUE_POS));
+ default :
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ public class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction = DESCENDING;
+
+ public TableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if (column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ CompositeData msg1 = (CompositeData) e1;
+ CompositeData msg2 = (CompositeData) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ case 0:
+ comparison = ((Long) msg1.get(MSG_AMQ_ID)).compareTo((Long)msg2.get(MSG_AMQ_ID));
+ break;
+ case 1:
+ comparison = ((Long) msg1.get(MSG_SIZE)).compareTo((Long)msg2.get(MSG_SIZE));
+ break;
+ case 2:
+ comparison = ((Long) msg1.get(MSG_QUEUE_POS)).compareTo((Long)msg2.get(MSG_QUEUE_POS));
+ break;
+ default:
+ comparison = 0;
+ }
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ private void updateMessageInterval()
+ {
+ Long from;
+ try
+ {
+ from = Long.valueOf(_fromMsgText.getText());
+ }
+ catch(Exception e1)
+ {
+ ViewUtility.popupErrorMessage("Invalid Value", "Please enter a valid 'from' number");
+ return;
+ }
+
+ Long to;
+ try
+ {
+ to = Long.valueOf(_toMsgText.getText());
+ }
+ catch(Exception e1)
+ {
+ ViewUtility.popupErrorMessage("Invalid Value", "Please enter a valid 'to' number");
+ return;
+ }
+
+ _fromMsg = from;
+ _toMsg = to;
+
+ _interval = (to - from) + 1;
+ _previousButton.setText("< Prev " + _interval);
+ _nextButton.setText("Next " + _interval + " >");
+
+ refresh(_mbean);
+ }
+
+ private void viewMessageContent()
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ try
+ {
+ final CompositeData selectedMsg = (CompositeData)_table.getItem(selectionIndex).getData();
+ Long msgId = (Long) selectedMsg.get(MSG_AMQ_ID);
+
+ Object result = _qmb.viewMessageContent(msgId);
+
+ populateResults(result);
+ }
+ catch (Exception e3)
+ {
+ MBeanUtility.handleException(_mbean, e3);
+ }
+ }
+ }
+
+ private void populateResults(Object result)
+ {
+ Display display = Display.getCurrent();
+ int width = 610;
+ int height = 400;
+ Shell shell = ViewUtility.createPopupShell(RESULT, width, height);
+ shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
+ ViewUtility.populateCompositeWithData(_toolkit, shell, result);
+
+ shell.open();
+ while (!shell.isDisposed())
+ {
+ if (!display.readAndDispatch())
+ {
+ display.sleep();
+ }
+ }
+ shell.dispose();
+ }
+
+ private void moveOrCopyMessages(final Shell parent, final QueueOperations op)
+ {
+ final ArrayList<Long> rangeStarts = new ArrayList<Long>();
+ final ArrayList<Long> rangeEnds = new ArrayList<Long>();
+
+ gatherSelectedAMQMsgIDRanges(rangeStarts,rangeEnds);
+ String rangeString = getRangesString(rangeStarts,rangeEnds);
+
+ String windowTitle;
+ String dialogueMessage;
+ final String feedBackMessage;
+ final String failureFeedBackMessage;
+
+ if(op.equals(QueueOperations.MOVE))
+ {
+ windowTitle = "Move Messages";
+ dialogueMessage = "Move message(s) with AMQ ID:";
+ feedBackMessage = "Messages moved";
+ failureFeedBackMessage = "Error moving messages";
+ }
+ else
+ {
+ windowTitle = "Copy Messages";
+ dialogueMessage = "Copy message(s) with AMQ ID:";
+ feedBackMessage = "Messages copied";
+ failureFeedBackMessage = "Error copying messages";
+ }
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, windowTitle);
+
+ Composite idComposite = _toolkit.createComposite(shell, SWT.NONE);
+ idComposite.setBackground(shell.getBackground());
+ idComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ idComposite.setLayout(new GridLayout());
+
+ _toolkit.createLabel(idComposite,dialogueMessage).setBackground(shell.getBackground());
+ _toolkit.createLabel(idComposite,rangeString).setBackground(shell.getBackground());
+
+ Composite destinationComposite = _toolkit.createComposite(shell, SWT.NONE);
+ destinationComposite.setBackground(shell.getBackground());
+ destinationComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ destinationComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(destinationComposite,"To Queue:").setBackground(shell.getBackground());
+ final Combo destinationCombo = new Combo(destinationComposite,SWT.NONE | SWT.READ_ONLY);
+ destinationCombo.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ List<String> queueList = ApplicationRegistry.getServerRegistry(_mbean).getQueueNames(_mbean.getVirtualHostName());
+ queueList.remove(_mbean.getName());
+
+ if(queueList.size() == 0)
+ {
+ destinationCombo.setItems(new String[]{"No other queues available"});
+ okButton.setEnabled(false);
+ }
+ else
+ {
+ Collections.sort(queueList);
+ destinationCombo.setItems(queueList.toArray(new String[0]));
+ }
+ destinationCombo.select(0);
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String destQueue = destinationCombo.getItem(destinationCombo.getSelectionIndex()).toString();
+ shell.dispose();
+
+ try
+ {
+ for(int i=0 ; i < rangeStarts.size() ; i++)
+ {
+ Long from = rangeStarts.get(i);
+ Long to = rangeEnds.get(i);
+
+ switch(op)
+ {
+ case COPY:
+ _qmb.copyMessages(Long.valueOf(from), Long.valueOf(to), destQueue);
+ break;
+ case MOVE:
+ _qmb.moveMessages(Long.valueOf(from), Long.valueOf(to), destQueue);
+ break;
+ }
+ }
+
+ ViewUtility.operationResultFeedback(null, feedBackMessage, null);
+ }
+ catch (Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage(failureFeedBackMessage);
+ MBeanUtility.handleException(_mbean, e4);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void deleteMessages(final Shell parent)
+ {
+ final ArrayList<Long> rangeStarts = new ArrayList<Long>();
+ final ArrayList<Long> rangeEnds = new ArrayList<Long>();
+
+ gatherSelectedAMQMsgIDRanges(rangeStarts,rangeEnds);
+ String rangeString = getRangesString(rangeStarts,rangeEnds);
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Delete Messages");
+
+ Composite idComposite = _toolkit.createComposite(shell, SWT.NONE);
+ idComposite.setBackground(shell.getBackground());
+ idComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ idComposite.setLayout(new GridLayout());
+
+ _toolkit.createLabel(idComposite,"Delete message(s) with AMQ ID:").setBackground(shell.getBackground());
+ _toolkit.createLabel(idComposite,rangeString).setBackground(shell.getBackground());
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+
+ try
+ {
+ for(int i=0 ; i < rangeStarts.size() ; i++)
+ {
+ Long from = rangeStarts.get(i);
+ Long to = rangeEnds.get(i);
+
+ _qmb.deleteMessages(Long.valueOf(from), Long.valueOf(to));
+ }
+
+ ViewUtility.operationResultFeedback(null, "Messages deleted", null);
+ }
+ catch (Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error deleting messages");
+ MBeanUtility.handleException(_mbean, e4);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void gatherSelectedAMQMsgIDRanges(ArrayList<Long> starts, ArrayList<Long> ends)
+ {
+ SortedSet<Long> amqIDs = new TreeSet<Long>();
+
+ for(Integer i : _table.getSelectionIndices())
+ {
+ CompositeData selectedMsg = (CompositeData)_table.getItem(i).getData();
+ amqIDs.add((Long)selectedMsg.get(MSG_AMQ_ID));
+ }
+
+ //initialise the first range
+ Long start = amqIDs.first();
+ Long end = amqIDs.first();
+
+ for(Long id : amqIDs)
+ {
+ if(id == amqIDs.first())
+ {
+ //skip first check, already initialised range
+ continue;
+ }
+
+ if(id == end +1)
+ {
+ //part of previous range, append
+ end = id;
+ }
+ else
+ {
+ //not in previous range, record existing start and end msg id values
+ starts.add(start);
+ ends.add(end);
+
+ //begin new range with this msg id
+ start = id;
+ end = id;
+ }
+ }
+
+ //record the last range created
+ starts.add(start);
+ ends.add(end);
+ }
+
+ private String getRangesString(ArrayList<Long> starts, ArrayList<Long> ends)
+ {
+ String idRangesString = new String("");
+
+ for(int i=0 ; i < starts.size() ; i++)
+ {
+ long start = starts.get(i);
+ long end = ends.get(i);
+
+ if(i != 0)
+ {
+ idRangesString = idRangesString.concat(", ");
+ }
+
+ if(start == end)
+ {
+ idRangesString = idRangesString.concat(String.valueOf(starts.get(i)));
+ }
+ else
+ {
+ idRangesString = idRangesString.concat(starts.get(i) + "-" + ends.get(i));
+ }
+ }
+
+ return idRangesString.concat(".");
+ }
+
+ private enum QueueOperations
+ {
+ MOVE,
+ COPY;
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ConnectionTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/ConnectionTypeTabControl.java
index d891a45210..f1f7b07b6f 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ConnectionTypeTabControl.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/ConnectionTypeTabControl.java
@@ -18,42 +18,33 @@
* under the License.
*
*/
+package org.apache.qpid.management.ui.views.type;
-package org.apache.qpid.management.ui.views;
+import java.util.List;
+
+import static org.apache.qpid.management.ui.Constants.CONNECTION;
-import org.apache.qpid.management.ui.ApplicationRegistry;
-import org.apache.qpid.management.ui.Constants;
import org.apache.qpid.management.ui.ManagedBean;
-import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.ui.ManagedServer;
import org.eclipse.swt.widgets.TabFolder;
/**
* Controller class, which takes care of displaying appropriate information and widgets for Connections.
* This allows user to select Connections and add those to the navigation view
*/
+
public class ConnectionTypeTabControl extends MBeanTypeTabControl
{
- public ConnectionTypeTabControl(TabFolder tabFolder)
- {
- super(tabFolder, Constants.CONNECTION);
- createWidgets();
- }
-
- protected void createWidgets()
+ public ConnectionTypeTabControl(TabFolder tabFolder, ManagedServer server, String virtualHost)
{
- createHeaderComposite(getFormComposite());
- createButtonsComposite(getFormComposite());
- createListComposite(getFormComposite());
+ super(tabFolder, server, virtualHost, CONNECTION);
}
-
- protected void populateList() throws Exception
+
+ @Override
+ protected List<ManagedBean> getMbeans()
{
- // map should be cleared before populating it with new values
- getMBeansMap().clear();
-
- ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
- java.util.List<ManagedBean> list = serverRegistry.getConnections(MBeanView.getVirtualHost());
- getListWidget().setItems(getItems(list));
+ return _serverRegistry.getConnections(_virtualHost);
}
+
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/ExchangeTypeTabControl.java
index 2917de8740..5d587c7158 100644
--- a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/ExchangeTypeTabControl.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,18 +18,28 @@
* under the License.
*
*/
-package org.apache.qpid.management.ui.sasl;
+package org.apache.qpid.management.ui.views.type;
+
+import java.util.List;
-import java.security.Provider;
+import static org.apache.qpid.management.ui.Constants.EXCHANGE;
-public class SaslProvider extends Provider
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.eclipse.swt.widgets.TabFolder;
+
+public class ExchangeTypeTabControl extends MBeanTypeTabControl
{
- private static final long serialVersionUID = -6978096016899676466L;
+
+ public ExchangeTypeTabControl(TabFolder tabFolder, ManagedServer server, String virtualHost)
+ {
+ super(tabFolder, server, virtualHost, EXCHANGE);
+ }
- public SaslProvider()
+ @Override
+ protected List<ManagedBean> getMbeans()
{
- super("SaslClientFactory", 1.0, "SASL PLAIN CLIENT MECHANISM");
- put("SaslClientFactory.PLAIN", "ClientSaslFactory");
+ return _serverRegistry.getExchanges(_virtualHost);
}
}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/MBeanTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/MBeanTypeTabControl.java
new file mode 100644
index 0000000000..cab9bc9f95
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/MBeanTypeTabControl.java
@@ -0,0 +1,458 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.type;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.apache.qpid.management.ui.views.TabControl;
+
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+public abstract class MBeanTypeTabControl extends TabControl
+{
+ protected FormToolkit _toolkit;
+ protected Form _form;
+ protected Table _table = null;
+ protected TableViewer _tableViewer = null;
+
+ protected List<ManagedBean> _mbeans = null;
+ protected String _type;
+ protected ApiVersion _ApiVersion;
+ protected JMXManagedObject _vhostMbean;
+ protected String _virtualHost;
+ protected JMXServerRegistry _serverRegistry;
+ protected Composite _tableComposite;
+ protected Button _favouritesButton;
+ protected Button _openButton;
+
+ public MBeanTypeTabControl(TabFolder tabFolder, ManagedServer server, String virtualHost, String type)
+ {
+ super(tabFolder);
+ _virtualHost = virtualHost;
+ _serverRegistry = (JMXServerRegistry) ApplicationRegistry.getServerRegistry(server);
+ _ApiVersion = _serverRegistry.getManagementApiVersion();
+ _vhostMbean = (JMXManagedObject) _serverRegistry.getVirtualHostManagerMBean(_virtualHost);
+ _type = type;
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ init();
+ createWidgets();
+ }
+
+ protected void init()
+ {
+
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ public void refresh()
+ {
+ refresh(null);
+ }
+
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _mbeans = getMbeans();
+
+ _tableViewer.setInput(_mbeans);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ protected abstract List<ManagedBean> getMbeans();
+
+ protected void createTable()
+ {
+ _table = new Table (_tableComposite, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(data);
+
+ _tableViewer = new TableViewer(_table);
+ final TableSorter tableSorter = new TableSorter();
+
+ String[] titles = { "Name"};
+ int[] bounds = { 310};
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableViewerColumn viewerColumn = new TableViewerColumn(_tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new ContentProviderImpl());
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+
+ addTableListeners();
+ }
+
+ protected void addTableListeners()
+ {
+ _favouritesButton.setEnabled(false);
+ _openButton.setEnabled(false);
+
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ _favouritesButton.setEnabled(false);
+ _openButton.setEnabled(false);
+ return;
+ }
+ else
+ {
+ _favouritesButton.setEnabled(true);
+ }
+
+ if(_table.getSelectionCount() > 1)
+ {
+ _openButton.setEnabled(false);
+ }
+ else
+ {
+ _openButton.setEnabled(true);
+ }
+ }
+ });
+
+ _table.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ openMBean();
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+ }
+
+
+ private void createWidgets()
+ {
+ Composite mainComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ mainComposite.setLayout(new GridLayout());
+
+ Composite buttonComposite = _toolkit.createComposite(mainComposite, SWT.NONE);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
+ buttonComposite.setLayoutData(gridData);
+ buttonComposite.setLayout(new GridLayout(2,true));
+
+ _favouritesButton = _toolkit.createButton(buttonComposite,
+ "<-- Add " + _type + "(s) to favourites", SWT.PUSH);
+ gridData = new GridData(SWT.LEFT, SWT.CENTER, true, false);
+ _favouritesButton.setLayoutData(gridData);
+ _favouritesButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ addMBeanToFavourites();
+ }
+ });
+
+ _openButton = _toolkit.createButton(buttonComposite, "Open selected " + _type, SWT.PUSH);
+ gridData = new GridData(SWT.RIGHT, SWT.CENTER, true, false);
+ _openButton.setLayoutData(gridData);
+ _openButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ openMBean();
+ }
+ });
+
+ _tableComposite = _toolkit.createComposite(mainComposite);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _tableComposite.setLayoutData(gridData);
+ _tableComposite.setLayout(new GridLayout(1,false));
+
+ createTable();
+
+ createLowerAreaButton(mainComposite);
+ }
+
+ protected void createLowerAreaButton(Composite parent)
+ {
+
+ }
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object[] getElements(Object parent)
+ {
+ return ((List<ManagedBean>) parent).toArray();
+ }
+ }
+
+ /**
+ * Label Provider class for the table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // name column
+ return ((ManagedBean) element).getName();
+ default:
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ private class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction;
+
+ public TableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if(column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ ManagedBean mbean1 = (ManagedBean) e1;
+ ManagedBean mbean2 = (ManagedBean) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ case 0:
+ comparison = mbean1.getName().compareTo(mbean2.getName());
+ break;
+ default:
+ comparison = 0;
+ }
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ protected void addMBeanToFavourites()
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ int[] selectedIndices = _table.getSelectionIndices();
+
+ ArrayList<ManagedBean> selectedMBeans = new ArrayList<ManagedBean>();
+
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ ManagedBean selectedMBean = (ManagedBean)_table.getItem(selectedIndices[index]).getData();
+ selectedMBeans.add(selectedMBean);
+ }
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ NavigationView view = (NavigationView)window.getActivePage().findView(NavigationView.ID);
+
+ ManagedBean bean = null;
+ try
+ {
+ for(ManagedBean mbean: selectedMBeans)
+ {
+ view.addManagedBean(mbean);
+ }
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(bean, ex);
+ }
+ }
+
+ protected void openMBean()
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ final ManagedBean selectedMBean = (ManagedBean)_table.getItem(selectionIndex).getData();
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MBeanView view = (MBeanView) window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.openMBean(selectedMBean);
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(selectedMBean, ex);
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/QueueTypeTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/QueueTypeTabControl.java
new file mode 100644
index 0000000000..df2a1eca59
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/type/QueueTypeTabControl.java
@@ -0,0 +1,764 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.type;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+
+import static org.apache.qpid.management.ui.ApplicationRegistry.DATA_DIR;
+import static org.apache.qpid.management.ui.Constants.QUEUE;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_NAME;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_ACTIVE_CONSUMER_COUNT;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_AUTODELETE;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_CONSUMER_COUNT;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_DURABLE;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_MAX_MSG_AGE;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_MAX_MSG_COUNT;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_MAX_MSG_SIZE;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_MAX_QUEUE_DEPTH;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_MSG_COUNT;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_OWNER;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_QUEUE_DEPTH;
+import static org.apache.qpid.management.common.mbeans.ManagedQueue.ATTR_RCVD_MSG_COUNT;
+
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ManagedServer;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.NavigationView;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+public class QueueTypeTabControl extends MBeanTypeTabControl
+{
+ private MBeanServerConnection _mbsc;
+ private ManagedBroker _vhmb;
+
+ private List<String> _selectedAttributes;
+ private PreferenceStore _preferences;
+ private Semaphore _tableViewerSemaphore = new Semaphore(1);
+
+ private static final String APP_DIR = ApplicationRegistry.DATA_DIR;
+ private static final String INI_FILENAME = APP_DIR + File.separator + "qpidmc_queue_attributes.ini";
+ private static final String INI_QUEUE_ATTRIBUES = "QueueAttributesSelection";
+
+ private static final ArrayList<String> FALLBACK_ATTRIBUTES_LIST = new ArrayList<String>();
+ static
+ {
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_NAME);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_ACTIVE_CONSUMER_COUNT);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_AUTODELETE);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_CONSUMER_COUNT);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_DURABLE);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_MAX_MSG_AGE);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_MAX_MSG_COUNT);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_MAX_MSG_SIZE);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_MAX_QUEUE_DEPTH);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_MSG_COUNT);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_OWNER);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_QUEUE_DEPTH);
+ FALLBACK_ATTRIBUTES_LIST.add(ATTR_RCVD_MSG_COUNT);
+ }
+
+ private static final Map<String, Integer> DEFAULT_COLUMN_WIDTHS = new HashMap<String,Integer>();
+ static
+ {
+ DEFAULT_COLUMN_WIDTHS.put(ATTR_NAME, 215);
+ DEFAULT_COLUMN_WIDTHS.put(ATTR_OWNER,125);
+ DEFAULT_COLUMN_WIDTHS.put(ATTR_QUEUE_DEPTH,125);
+ }
+
+ public QueueTypeTabControl(TabFolder tabFolder, ManagedServer server, String virtualHost)
+ {
+ super(tabFolder,server,virtualHost,QUEUE);
+ _mbsc = (MBeanServerConnection) _serverRegistry.getServerConnection();
+
+ //create a proxy for the VirtualHostManager mbean to use in retrieving the attribute names/values
+ _vhmb = MBeanServerInvocationHandler.newProxyInstance(_mbsc,
+ _vhostMbean.getObjectName(), ManagedBroker.class, false);
+
+ }
+
+ @Override
+ protected void init()
+ {
+ createIniFileIfNecessary();
+ loadAttributePreferences();
+ }
+
+ /**
+ * Create the ini file if it doesn't already exist.
+ */
+ public static void createIniFileIfNecessary()
+ {
+ File dir = new File(DATA_DIR);
+ if (!dir.exists())
+ {
+ if(!dir.mkdir())
+ {
+ System.err.println("Could not create application data directory " + DATA_DIR);
+ ViewUtility.popupErrorMessage("Error", "Fatal Error: Unable to create the application data directory: " + DATA_DIR);
+ System.exit(1);
+ }
+ }
+
+ File file = new File(INI_FILENAME);
+ try
+ {
+ if (!file.exists())
+ {
+ file.createNewFile();
+ }
+ }
+ catch (IOException ex)
+ {
+ System.err.println("Error creating the configuration file " + INI_FILENAME);
+ ViewUtility.popupErrorMessage("Error", "Fatal Error: Unable to create the configuration file: " + INI_FILENAME);
+ System.exit(1);
+ }
+ }
+
+ private void loadAttributePreferences()
+ {
+ _preferences = new PreferenceStore(INI_FILENAME);
+ List<String> attributesList = new ArrayList<String>();
+
+ //ensure the name is present, and first
+ attributesList.add(ManagedQueue.ATTR_NAME);
+
+ //add any others from the file
+ try
+ {
+ _preferences.load();
+
+ String selectedAttributes = _preferences.getString(INI_QUEUE_ATTRIBUES);
+ if (selectedAttributes.length() != 0)
+ {
+ String[] attributes = selectedAttributes.split(",");
+ for (String attr : attributes)
+ {
+ if(attr.equals(ManagedQueue.ATTR_NAME))
+ {
+ //the Name attribute is already present
+ continue;
+ }
+
+ attributesList.add(attr);
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ ViewUtility.popupErrorMessage("Error", "Unable to load previous attribute selections, defaulting to Name only");
+ System.err.println(e);
+ }
+
+ _selectedAttributes = attributesList;
+ }
+
+ private void saveAttributePreferences()
+ {
+ String chosenAttributes = new String();
+
+ for(String attr : _selectedAttributes)
+ {
+ chosenAttributes = chosenAttributes.concat(attr) + ",";
+ }
+ //cut off last ","
+ int lastIndex = chosenAttributes.lastIndexOf(',');
+ if (lastIndex != -1)
+ {
+ chosenAttributes = chosenAttributes.substring(0,lastIndex);
+ }
+
+ _preferences.putValue(INI_QUEUE_ATTRIBUES, chosenAttributes);
+
+ try
+ {
+ _preferences.save();
+ }
+ catch (IOException e)
+ {
+ ViewUtility.popupErrorMessage("Error", "Unable to save the attribute selection, choices will be lost at shutdown");
+ System.err.println(e);
+ }
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ //Try locking. If we cant aquire the lock, dont bother getting new values.
+ //Either the attributes are being changed and these values would be out of date,
+ //or another thread is still in the process of refreshing
+ if(_tableViewerSemaphore.tryAcquire())
+ {
+ try
+ {
+ List<List<Object>> values = null;
+
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ {
+ //Qpid JMX API 1.3+, use this virtualhosts VirtualHostManager MBean
+ //to retrieve the attributes values requested for all queues at once
+ try
+ {
+ values = _vhmb.retrieveQueueAttributeValues(_selectedAttributes.toArray(new String[0]));
+ }
+ catch(Exception e)
+ {
+ MBeanUtility.handleException(_vhostMbean, e);
+ }
+ }
+ else
+ {
+ //Qpid JMX API 1.2 or below, use the local ManagedBeans and look
+ //up the attribute values for each queue individually
+ _mbeans = getMbeans();
+ values = MBeanUtility.getQueueAttributes(_mbeans, _selectedAttributes.toArray(new String[0]));
+ }
+
+ _tableViewer.setInput(values);
+ layout();
+ }
+ finally
+ {
+ _tableViewerSemaphore.release();
+ }
+ }
+
+ }
+
+ @Override
+ protected List<ManagedBean> getMbeans()
+ {
+ return _serverRegistry.getQueues(_virtualHost);
+ }
+
+ private void clearTableComposite()
+ {
+ ViewUtility.disposeChildren(_tableComposite);
+ }
+
+ @Override
+ protected void createTable()
+ {
+ _table = new Table (_tableComposite, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(data);
+
+ _tableViewer = new TableViewer(_table);
+
+ final QueueTableSorter tableSorter = new QueueTableSorter();
+
+ for (int i = 0; i < _selectedAttributes.size(); i++)
+ {
+ final int index = i;
+ final TableViewerColumn viewerColumn = new TableViewerColumn(_tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+
+ String attrName = _selectedAttributes.get(i);
+ column.setMoveable(true);
+ column.setText(attrName);
+ column.pack();
+ if(DEFAULT_COLUMN_WIDTHS.containsKey(attrName))
+ {
+ //retrieve the desired default width
+ column.setWidth(DEFAULT_COLUMN_WIDTHS.get(attrName));
+ }
+ else
+ {
+ //add padding for sort direction indicator
+ column.setWidth(column.getWidth() + 15);
+ }
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new QueueContentProviderImpl());
+ _tableViewer.setLabelProvider(new QueueLabelProviderImpl());
+
+ _tableViewer.setUseHashlookup(true);
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+
+ addTableListeners();
+ }
+
+ protected void createLowerAreaButton(Composite parent)
+ {
+ Composite lowerButtonComposite = _toolkit.createComposite(parent, SWT.NONE);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
+ lowerButtonComposite.setLayoutData(gridData);
+ lowerButtonComposite.setLayout(new GridLayout());
+
+ final Button attributesButton = _toolkit.createButton(lowerButtonComposite, "Select Attributes ...", SWT.PUSH);
+ gridData = new GridData(SWT.RIGHT, SWT.CENTER, true, false);
+ attributesButton.setLayoutData(gridData);
+ attributesButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ chooseAttributes(attributesButton.getShell());
+ }
+ });
+ }
+
+ private void chooseAttributes(final Shell parent)
+ {
+
+ List<String> availableAttributes;
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))
+ {
+ //Qpid JMX API 1.3+, request the current queue attributes names from the broker
+ try
+ {
+ availableAttributes = _vhmb.retrieveQueueAttributeNames();
+ }
+ catch (IOException e)
+ {
+ availableAttributes = new ArrayList<String>(FALLBACK_ATTRIBUTES_LIST);
+ }
+ }
+ else
+ {
+ //Qpid JMX API 1.2 or below, use the falllback list of names.
+ availableAttributes = new ArrayList<String>(FALLBACK_ATTRIBUTES_LIST);
+ }
+
+
+ final List<String> chosenAttributes = new ArrayList<String>();
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Select Attributes");
+
+ Composite attributesComposite = _toolkit.createComposite(shell, SWT.NONE);
+ attributesComposite.setBackground(shell.getBackground());
+ attributesComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ attributesComposite.setLayout(new GridLayout(2,false));
+
+ //add a selected-but-disabled check box for the Name attribute (its a mandatory attribute)
+ final Button nameCheckbox = new Button(attributesComposite, SWT.CHECK);
+ nameCheckbox.setText(ManagedQueue.ATTR_NAME);
+ nameCheckbox.setSelection(true);
+ nameCheckbox.setEnabled(false);
+
+ for(String attr : availableAttributes)
+ {
+ if(attr.equals(ManagedQueue.ATTR_NAME))
+ {
+ //Name attribute is mandatory and gets added to the front of the list later
+ continue;
+ }
+
+ final Button attrButton = new Button(attributesComposite, SWT.CHECK);
+ attrButton.setText(attr);
+
+ //if it was checked before, select it again now
+ if(_selectedAttributes.contains(attr))
+ {
+ attrButton.setSelection(true);
+ chosenAttributes.add(attr);
+ }
+
+ //add a selection listener to update the selected attribute list
+ attrButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if(attrButton.getSelection())
+ {
+ chosenAttributes.add(attrButton.getText());
+ }
+ else
+ {
+ chosenAttributes.remove(attrButton.getText());
+ }
+ }
+ });
+ }
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+
+ //The Name attribute is mandatory, add it now, also
+ //ensuring it is left-most by placing it first in the list
+ List<String> newSelection = new ArrayList<String>();
+ newSelection.add(ManagedQueue.ATTR_NAME);
+
+ //now add all remaining choices in alphabetical order
+ Collections.sort(chosenAttributes);
+ newSelection.addAll(chosenAttributes);
+
+ _tableViewerSemaphore.acquireUninterruptibly();
+ try
+ {
+ _selectedAttributes = newSelection;
+
+ clearTableComposite();
+ createTable();
+ saveAttributePreferences();
+ }
+ finally
+ {
+ _tableViewerSemaphore.release();
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private String getQueueDepthString(Long value)
+ {
+ if(value == null)
+ {
+ return "-";
+ }
+
+ if (_ApiVersion.greaterThanOrEqualTo(1,2))
+ {
+ //Qpid JMX API 1.2 or above, returns Bytes
+ return convertLongBytesToText(value);
+ }
+ else
+ {
+ //Qpid JMX API 1.1 or below, returns KB
+ double mb = 1024.0;
+
+ if(value > mb) //MB
+ {
+ return String.format("%.3f", (Double)(value / mb)) + " MB";
+ }
+ else //KB
+ {
+ return value + " KB";
+ }
+ }
+ }
+
+ private String convertLongBytesToText(Long value)
+ {
+ if(value == null)
+ {
+ return "-";
+ }
+
+ double mb = 1024.0 * 1024.0;
+ double kb = 1024.0;
+
+ if(value >= mb) //MB
+ {
+ return String.format("%.3f", (Double)((double)value / mb)) + " MB";
+ }
+ else if (value >= kb) //KB
+ {
+ return String.format("%.3f", (Double)((double)value / kb)) + " KB";
+ }
+ else //Bytes
+ {
+ return value + " Bytes";
+ }
+ }
+
+ /**
+ * sorter class for the table viewer.
+ *
+ */
+ private class QueueTableSorter extends ViewerSorter
+ {
+ protected int column;
+ protected static final int ASCENDING = 0;
+ protected static final int DESCENDING = 1;
+
+ protected int direction;
+
+ public QueueTableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if(column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ List<Object> queue1 = (List<Object>) e1;
+ List<Object> queue2 = (List<Object>) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ default:
+ if(queue1.get(column) instanceof Comparable)
+ {
+ comparison = ((Comparable)queue1.get(column)).compareTo((Comparable) queue2.get(column));
+ }
+ }
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ /**
+ * Content Provider class for the table viewer for Qpid JMX API 1.3 and above.
+ */
+ private class QueueContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object[] getElements(Object parent)
+ {
+ return ((List<List<Object>>) parent).toArray();
+ }
+ }
+
+ /**
+ * Label Provider class for the table viewer for for Qpid JMX API 1.3 and above.
+ */
+ private class QueueLabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ @SuppressWarnings("unchecked")
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ List<Object> attributes = (List<Object>) element;
+
+ switch (columnIndex)
+ {
+ default :
+ String attrName = _selectedAttributes.get(columnIndex);
+
+ if(ATTR_QUEUE_DEPTH.equals(attrName))
+ {
+ return getQueueDepthString((Long) attributes.get(columnIndex));
+ }
+ else if(ATTR_MAX_QUEUE_DEPTH.equals(attrName) || ATTR_MAX_MSG_SIZE.equals(attrName))
+ {
+ Number val = (Number)attributes.get(columnIndex);
+ return convertLongBytesToText(val.longValue());
+ }
+ else if(ATTR_MAX_MSG_AGE.equals(attrName))
+ {
+ return String.valueOf(attributes.get(columnIndex) + "ms");
+ }
+
+ return String.valueOf(attributes.get(columnIndex));
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void addMBeanToFavourites()
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ int[] selectedIndices = _table.getSelectionIndices();
+
+ ArrayList<ManagedBean> selectedMBeans = new ArrayList<ManagedBean>();
+
+ //the entries are created from an List<Object> with the attribute values (name first)
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ List<Object> queueEntry = (List<Object>) _table.getItem(selectedIndices[index]).getData();
+ String queueName = (String) queueEntry.get(0);
+ selectedMBeans.add(_serverRegistry.getQueue(queueName, _virtualHost));
+ }
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ NavigationView view = (NavigationView)window.getActivePage().findView(NavigationView.ID);
+
+ ManagedBean bean = null;
+ try
+ {
+ for(ManagedBean mbean: selectedMBeans)
+ {
+ bean = mbean;
+ view.addManagedBean(mbean);
+ }
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(bean, ex);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void openMBean()
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ ManagedBean selectedMBean;
+
+ //the entries are created from an List<Object> with the attribute values (name first)
+ List<Object> queueEntry = (List<Object>) _table.getItem(selectionIndex).getData();
+ String queueName = (String) queueEntry.get(0);
+ selectedMBean = _serverRegistry.getQueue(queueName, _virtualHost);
+
+ if(selectedMBean == null)
+ {
+ ViewUtility.popupErrorMessage("Error", "Unable to retrieve the selected MBean to open it");
+ return;
+ }
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MBeanView view = (MBeanView) window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.openMBean(selectedMBean);
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(selectedMBean, ex);
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
new file mode 100644
index 0000000000..2051beafac
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
@@ -0,0 +1,915 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.users;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * Control class for the UserManagement mbean.
+ */
+public class UserManagementTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private ScrolledForm _form;
+ private Table _table = null;
+ private TableViewer _tableViewer = null;
+
+ private TabularDataSupport _userDetails = null;
+ private UserManagement _ummb;
+ private ApiVersion _ApiVersion;
+
+ static final String USERNAME = UserManagement.COMPOSITE_ITEM_NAMES[0];
+ static final String RIGHTS_READ_ONLY = UserManagement.COMPOSITE_ITEM_NAMES[1];
+ static final String RIGHTS_READ_WRITE = UserManagement.COMPOSITE_ITEM_NAMES[2];
+ static final String RIGHTS_ADMIN = UserManagement.COMPOSITE_ITEM_NAMES[3];
+
+ public UserManagementTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
+ _ummb = (UserManagement)
+ MBeanServerInvocationHandler.newProxyInstance(mbsc, mbean.getObjectName(),
+ UserManagement.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createScrolledForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createWidgets();
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+ _table.setFocus();
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ _userDetails = null;
+ try
+ {
+ _userDetails = (TabularDataSupport) _ummb.viewUsers();
+ }
+ catch(Exception e)
+ {
+ MBeanUtility.handleException(_mbean, e);
+
+ }
+
+ _tableViewer.setInput(_userDetails);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ Composite paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ paramsComposite.setLayout(new GridLayout());
+
+ Group viewUsersGroup = new Group(paramsComposite, SWT.SHADOW_NONE);
+ viewUsersGroup.setBackground(paramsComposite.getBackground());
+ viewUsersGroup.setText("Users");
+ viewUsersGroup.setLayout(new GridLayout(2,false));
+ viewUsersGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Composite tableComposite = _toolkit.createComposite(viewUsersGroup);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.heightHint = 250;
+ gridData.minimumHeight = 250;
+ tableComposite.setLayoutData(gridData);
+ tableComposite.setLayout(new GridLayout(2,false));
+
+ _table = new Table (tableComposite, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _table.setLinesVisible (true);
+ _table.setHeaderVisible (true);
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _table.setLayoutData(gridData);
+
+ _tableViewer = new TableViewer(_table);
+ final TableSorter tableSorter = new TableSorter();
+
+ String[] titles = { "Username", "JMX Management Rights" };
+ int[] bounds = { 310, 200 };
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableViewerColumn viewerColumn = new TableViewerColumn(_tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _tableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _tableViewer.setContentProvider(new ContentProviderImpl());
+ _tableViewer.setLabelProvider(new LabelProviderImpl());
+ _tableViewer.setSorter(tableSorter);
+ _table.setSortColumn(_table.getColumn(0));
+ _table.setSortDirection(SWT.UP);
+
+ Composite buttonsComposite = _toolkit.createComposite(tableComposite);
+ gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
+ gridData.heightHint = 165;
+ buttonsComposite.setLayoutData(gridData);
+ buttonsComposite.setLayout(new GridLayout());
+
+ final Button addUserButton = _toolkit.createButton(buttonsComposite, "Add New User ...", SWT.PUSH);
+ gridData = new GridData(SWT.CENTER, SWT.TOP, false, true);
+ gridData.widthHint = 125;
+ addUserButton.setLayoutData(gridData);
+ addUserButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ addUser(addUserButton.getShell());
+ }
+ });
+
+ final Button deleteUsersButton = _toolkit.createButton(buttonsComposite, "Delete User(s)", SWT.PUSH);
+ gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
+ gridData.widthHint = 125;
+ deleteUsersButton.setLayoutData(gridData);
+ deleteUsersButton.setEnabled(false);
+ deleteUsersButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ deleteUsers();
+ }
+ }
+ });
+
+ final Button setPasswordButton = _toolkit.createButton(buttonsComposite, "Set Password ...", SWT.PUSH);
+ gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
+ gridData.widthHint = 125;
+ setPasswordButton.setLayoutData(gridData);
+ setPasswordButton.setEnabled(false);
+ setPasswordButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ final CompositeData selectedLogger = (CompositeData)_table.getItem(
+ selectionIndex).getData();
+ String user = selectedLogger.get(USERNAME).toString();
+ InputDialog id = new InputDialog(setPasswordButton.getShell(),"Set Password",
+ "Please enter the new password for '" + user + "':",null,null){
+ @Override
+ protected Control createDialogArea(Composite parent)
+ {
+ Control control = super.createDialogArea(parent);
+ //set the Text field echo char to '*' to mask the password
+ getText().setEchoChar('*');
+ //return the normal result
+ return control;
+ }
+ };
+
+ int returnValue;
+ while((returnValue = id.open()) == InputDialog.OK)
+ {
+ if (id.getValue() == null || id.getValue().toString().length() == 0)
+ {
+ ViewUtility.popupErrorMessage("Set Password", "Please enter a valid password");
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (returnValue == InputDialog.OK)
+ {
+ char[] password = id.getValue().toCharArray();
+
+ // Qpid JMX API 1.1 and below expects the password to be sent as a hashed value.
+ if (_ApiVersion.lessThanOrEqualTo(1,1))
+ {
+ try
+ {
+ password = ViewUtility.getHash(id.getValue());
+ }
+ catch (Exception hashException)
+ {
+ ViewUtility.popupErrorMessage("Set Password",
+ "Unable to calculate hash for Password:"
+ + hashException.getMessage());
+ return;
+ }
+ }
+
+ try
+ {
+ boolean result = _ummb.setPassword(user, password);
+ ViewUtility.operationResultFeedback(result, "Updated user password", "Failed to update user password");
+ }
+ catch(Exception e2)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error updating user password");
+ MBeanUtility.handleException(_mbean, e2);
+ }
+ }
+ }
+ }
+ });
+
+ final Button setRightsButton = _toolkit.createButton(buttonsComposite, "Set Rights ...", SWT.PUSH);
+ gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
+ gridData.widthHint = 125;
+ setRightsButton.setLayoutData(gridData);
+ setRightsButton.setEnabled(false);
+ setRightsButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ setRights(setRightsButton.getShell());
+ }
+ }
+ });
+
+ _tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ deleteUsersButton.setEnabled(false);
+ setRightsButton.setEnabled(false);
+ setPasswordButton.setEnabled(false);
+ return;
+ }
+ else
+ {
+ deleteUsersButton.setEnabled(true);
+ setRightsButton.setEnabled(true);
+ }
+
+ if (_table.getSelectionCount() > 1)
+ {
+ setPasswordButton.setEnabled(false);
+ }
+ else
+ {
+ setPasswordButton.setEnabled(true);
+ }
+ }
+ });
+
+ Group miscGroup = new Group(paramsComposite, SWT.SHADOW_NONE);
+ miscGroup.setBackground(paramsComposite.getBackground());
+ miscGroup.setText("Misc");
+ gridData = new GridData(SWT.LEFT, SWT.TOP, true, true);
+ miscGroup.setLayoutData(gridData);
+ miscGroup.setLayout(new GridLayout(2,false));
+
+ final Button reloadUserDetails = _toolkit.createButton(miscGroup,
+ "Reload User Details", SWT.PUSH);
+ if(_ApiVersion.lessThan(1, 2))
+ {
+ //this only reloaded the JMX rights file before Qpid JMX API 1.2
+ _toolkit.createLabel(miscGroup, " Loads the current management rights file from disk");
+ }
+ else
+ {
+ //since Qpid JMX API 1.2 it also reloads the password file
+ _toolkit.createLabel(miscGroup, " Loads the current password and management rights files from disk");
+ }
+ reloadUserDetails.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ int response = ViewUtility.popupOkCancelConfirmationMessage("Reload User Data",
+ "Do you want to reload user data ?");
+ if (response == SWT.OK)
+ {
+ try
+ {
+ boolean result = _ummb.reloadData();
+ ViewUtility.operationResultFeedback(result, "Reloaded user data", "Failed to reload user data");
+ }
+ catch(Exception e3)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error reloading user data");
+ MBeanUtility.handleException(_mbean, e3);
+ }
+ refresh(_mbean);
+ }
+ }
+ });
+
+ }
+
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ public Object[] getElements(Object parent)
+ {
+ Collection<Object> rowCollection = ((TabularDataSupport) parent).values();
+
+ return rowCollection.toArray();
+ }
+ }
+
+ /**
+ * Label Provider class for the table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // username column
+ return (String) ((CompositeData) element).get(USERNAME);
+ case 1 : // rights column
+ return classifyUserRights((CompositeData) element);
+ default :
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ private class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction;
+
+ public TableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if(column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ CompositeData user1 = (CompositeData) e1;
+ CompositeData user2 = (CompositeData) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ case 0:
+ comparison = String.valueOf(user1.get(USERNAME)).compareTo(
+ String.valueOf(user2.get(USERNAME)));
+ break;
+ case 1:
+ comparison = classifyUserRights(user1).compareTo(classifyUserRights(user2));
+ break;
+ default:
+ comparison = 0;
+ }
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ private String classifyUserRights(CompositeData user)
+ {
+ Boolean read = (Boolean)user.get(RIGHTS_READ_ONLY);
+ Boolean write = (Boolean)user.get(RIGHTS_READ_WRITE);
+ Boolean admin = (Boolean)user.get(RIGHTS_ADMIN);
+
+ if(admin)
+ {
+ return "Admin";
+ }
+ else if(write)
+ {
+ return "Read & Write";
+ }
+ else if(read)
+ {
+ return "Read Only";
+ }
+ else
+ {
+ return "No Access";
+ }
+ }
+
+ private void setRights(final Shell parent)
+ {
+
+ int selectionIndex = _table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ int[] selectedIndices = _table.getSelectionIndices();
+
+ final ArrayList<String> selectedUsers = new ArrayList<String>();
+
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ CompositeData selectedUser = (CompositeData)_table.getItem(selectedIndices[index]).getData();
+ String user = selectedUser.get(USERNAME).toString();
+ selectedUsers.add(user);
+ }
+
+ String selectedUsersString = "";
+ for(String user : selectedUsers)
+ {
+ selectedUsersString = selectedUsersString.concat(user + ", ");
+ }
+ //cut off last ", "
+ int lastIndex = selectedUsersString.lastIndexOf(',');
+ if (lastIndex != -1)
+ {
+ selectedUsersString = selectedUsersString.substring(0,lastIndex);
+ }
+
+
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Set Rights");
+
+ Label overview = _toolkit.createLabel(shell,"Select rights for user(s): ");
+ overview.setBackground(shell.getBackground());
+ Label userNamesLabel= _toolkit.createLabel(shell,selectedUsersString);
+ userNamesLabel.setBackground(shell.getBackground());
+
+ Composite buttons = _toolkit.createComposite(shell, SWT.NONE);
+ buttons.setBackground(shell.getBackground());
+ buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ buttons.setLayout(new GridLayout(4,false));
+
+ final Button noneButton = new Button(buttons, SWT.RADIO);
+ noneButton.setText("No Access");
+ noneButton.setSelection(true);
+ final Button readButton = new Button(buttons, SWT.RADIO);
+ readButton.setText("Read Only");
+ final Button writeButton = new Button(buttons, SWT.RADIO);
+ writeButton.setText("Read + Write");
+ final Button adminButton = new Button(buttons, SWT.RADIO);
+ adminButton.setText("Admin");
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ boolean read = readButton.getSelection();
+ boolean write = writeButton.getSelection();
+ boolean admin = adminButton.getSelection();
+
+ shell.dispose();
+
+ HashMap<String,Boolean> results = new HashMap<String,Boolean>();
+ try
+ {
+ //perform the rights updates, save the results.
+ for(String user : selectedUsers)
+ {
+ boolean result = _ummb.setRights(user,read,write,admin);
+ results.put(user, result);
+ }
+
+ //categorise the overall result
+ boolean overallResult = true;
+ for(boolean result : results.values())
+ {
+ if (!result)
+ {
+ overallResult = false;
+ }
+ }
+
+ //output the result to status bar if all success, and dialogue if not
+ if(overallResult)
+ {
+ ViewUtility.operationResultFeedback(overallResult, "Updated user rights", null);
+ }
+ else
+ {
+ String failedToUpdateRightsUsers = "";
+ for(String user : results.keySet())
+ {
+ if(!results.get(user))
+ {
+ failedToUpdateRightsUsers = failedToUpdateRightsUsers.concat(user + ", ");
+ }
+ }
+
+ //cut off last ", "
+ int lastIndex2 = failedToUpdateRightsUsers.lastIndexOf(',');
+ if (lastIndex2 != -1)
+ {
+ failedToUpdateRightsUsers = failedToUpdateRightsUsers.substring(0, lastIndex2);
+ }
+
+ ViewUtility.operationResultFeedback(overallResult, null, "Failed to update user(s) rights: " + failedToUpdateRightsUsers);
+ }
+ }
+ catch(Exception e4)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error updating user rights");
+ MBeanUtility.handleException(_mbean, e4);
+ }
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void addUser(final Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Add New User");
+
+ Composite usernameComposite = _toolkit.createComposite(shell, SWT.NONE);
+ usernameComposite.setBackground(shell.getBackground());
+ usernameComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ usernameComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(usernameComposite,"Username:").setBackground(shell.getBackground());
+ final Text usernameText = new Text(usernameComposite, SWT.BORDER);
+ usernameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Composite passwordComposite = _toolkit.createComposite(shell, SWT.NONE);
+ passwordComposite.setBackground(shell.getBackground());
+ passwordComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ passwordComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(passwordComposite,"Password:").setBackground(shell.getBackground());
+ final Text passwordText = new Text(passwordComposite, SWT.BORDER | SWT.PASSWORD);
+ passwordText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Group buttonGroup = new Group(shell, SWT.NONE);
+ buttonGroup.setText("JMX Management Rights");
+ buttonGroup.setBackground(shell.getBackground());
+ buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ buttonGroup.setLayout(new GridLayout(4,false));
+
+ final Button noneButton = new Button(buttonGroup, SWT.RADIO);
+ noneButton.setText("No Access");
+ noneButton.setSelection(true);
+ final Button readButton = new Button(buttonGroup, SWT.RADIO);
+ readButton.setText("Read Only");
+ final Button writeButton = new Button(buttonGroup, SWT.RADIO);
+ writeButton.setText("Read + Write");
+ final Button adminButton = new Button(buttonGroup, SWT.RADIO);
+ adminButton.setText("Admin");
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String username = usernameText.getText();
+ String password = passwordText.getText();
+
+ if (username == null || username.length() == 0)
+ {
+ ViewUtility.popupErrorMessage("Add New User", "Please enter a valid username");
+ return;
+ }
+
+ if (password == null || password.length() == 0)
+ {
+ ViewUtility.popupErrorMessage("Add New User", "Please enter a valid password");
+ return;
+ }
+
+ char[] passwordChars = password.toCharArray();
+
+ // Qpid JMX API 1.1 and below expects the password to be sent as a hashed value.
+ if (_ApiVersion.lessThanOrEqualTo(1,1))
+ {
+ try
+ {
+ passwordChars = ViewUtility.getHash(password);
+ }
+ catch (Exception hashException)
+ {
+ ViewUtility.popupErrorMessage("Set Password",
+ "Unable to calculate hash for Password:"
+ + hashException.getMessage());
+ return;
+ }
+ }
+
+ boolean read = readButton.getSelection();
+ boolean write = writeButton.getSelection();
+ boolean admin = adminButton.getSelection();
+
+ shell.dispose();
+ try
+ {
+ boolean result = _ummb.createUser(username, passwordChars, read, write, admin);
+ ViewUtility.operationResultFeedback(result, "Created user", "Failed to create user");
+ }
+ catch(Exception e5)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error creating user");
+ MBeanUtility.handleException(_mbean, e5);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void deleteUsers()
+ {
+ int selectionIndex = _table.getSelectionIndex();
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ int[] selectedIndices = _table.getSelectionIndices();
+
+ ArrayList<String> selectedUsers = new ArrayList<String>();
+
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ CompositeData selectedUser = (CompositeData)_table.getItem(selectedIndices[index]).getData();
+ String user = selectedUser.get(USERNAME).toString();
+ selectedUsers.add(user);
+ }
+
+ String selectedUsersString = "";
+ for(String user : selectedUsers)
+ {
+ selectedUsersString = selectedUsersString.concat(user + ", ");
+ }
+ //cut off last ", "
+ int lastIndex = selectedUsersString.lastIndexOf(',');
+ if (lastIndex != -1)
+ {
+ selectedUsersString = selectedUsersString.substring(0,lastIndex);
+ }
+
+ int response = ViewUtility.popupOkCancelConfirmationMessage(
+ "User Management", "Delete user(s): " + selectedUsersString + " ?");
+
+ if (response == SWT.OK)
+ {
+ HashMap<String,Boolean> results = new HashMap<String,Boolean>();
+ try
+ {
+ //perform the deletes, save the results.
+ for(String user : selectedUsers)
+ {
+ boolean result = _ummb.deleteUser(user);
+ results.put(user, result);
+ }
+
+ //categorise the overall result
+ boolean overallResult = true;
+ for(boolean result : results.values())
+ {
+ if (!result)
+ {
+ overallResult = false;
+ }
+ }
+
+ //output the result to status bar if all success, and dialogue if not
+ if(overallResult)
+ {
+ ViewUtility.operationResultFeedback(overallResult, "Deleted user(s)", null);
+ }
+ else
+ {
+ String failedToDeleteUsers = "";
+ for(String user : results.keySet())
+ {
+ if(!results.get(user))
+ {
+ failedToDeleteUsers = failedToDeleteUsers.concat(user + ", ");
+ }
+ }
+
+ //cut off last ", "
+ lastIndex = failedToDeleteUsers.lastIndexOf(',');
+ if (lastIndex != -1)
+ {
+ failedToDeleteUsers = failedToDeleteUsers.substring(0, lastIndex);
+ }
+
+ ViewUtility.operationResultFeedback(overallResult, null, "Failed to delete user(s): " + failedToDeleteUsers);
+ }
+
+ }
+ catch(Exception e1)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error deleting user(s)");
+ MBeanUtility.handleException(_mbean, e1);
+ }
+
+ refresh(_mbean);;
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/vhost/VHostTabControl.java b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/vhost/VHostTabControl.java
new file mode 100644
index 0000000000..3b03aeaff1
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/vhost/VHostTabControl.java
@@ -0,0 +1,871 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui.views.vhost;
+
+import static org.apache.qpid.management.ui.Constants.DEFAULT_EXCHANGE_TYPE_VALUES;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerInvocationHandler;
+
+import org.apache.qpid.management.ui.ApiVersion;
+import org.apache.qpid.management.ui.ApplicationRegistry;
+import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.ui.ServerRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+import org.apache.qpid.management.ui.jmx.JMXManagedObject;
+import org.apache.qpid.management.ui.jmx.MBeanUtility;
+import org.apache.qpid.management.ui.views.MBeanView;
+import org.apache.qpid.management.ui.views.TabControl;
+import org.apache.qpid.management.ui.views.ViewUtility;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+
+/**
+ * Control class for the VirtualHostManager mbean operations tab.
+ */
+public class VHostTabControl extends TabControl
+{
+ private FormToolkit _toolkit;
+ private Form _form;
+ private Table _queueTable = null;
+ private TableViewer _queueTableViewer = null;
+ private Table _exchangeTable = null;
+ private TableViewer _exchangeTableViewer = null;
+
+ private Composite _paramsComposite = null;
+
+ private ManagedBroker _vhmb;
+ private ApiVersion _ApiVersion;
+ private List<ManagedBean> _queues;
+ private List<ManagedBean> _exchanges;
+ private ServerRegistry _serverRegistry;
+
+ public VHostTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
+ {
+ super(tabFolder);
+ _mbean = mbean;
+ _serverRegistry = ApplicationRegistry.getServerRegistry(mbean);
+ _ApiVersion = _serverRegistry.getManagementApiVersion();
+ _vhmb = (ManagedBroker) MBeanServerInvocationHandler.newProxyInstance(mbsc,
+ mbean.getObjectName(), ManagedBroker.class, false);
+ _toolkit = new FormToolkit(_tabFolder.getDisplay());
+ _form = _toolkit.createForm(_tabFolder);
+ _form.getBody().setLayout(new GridLayout());
+ createComposites();
+ createWidgets();
+ }
+
+ private void createComposites()
+ {
+ _paramsComposite = _toolkit.createComposite(_form.getBody(), SWT.NONE);
+ _paramsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ _paramsComposite.setLayout(new GridLayout(2, true));
+ }
+
+ /**
+ * @see TabControl#getControl()
+ */
+ public Control getControl()
+ {
+ return _form;
+ }
+
+ /**
+ * @see TabControl#setFocus()
+ */
+ public void setFocus()
+ {
+
+ }
+
+ @Override
+ public void refresh(ManagedBean mbean)
+ {
+ ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer());
+ _queues = serverRegistry.getQueues(MBeanView.getVirtualHost());
+ _exchanges = serverRegistry.getExchanges(MBeanView.getVirtualHost());
+
+ _queueTableViewer.setInput(_queues);
+ _exchangeTableViewer.setInput(_exchanges);
+
+ layout();
+ }
+
+ public void layout()
+ {
+ _form.layout(true);
+ _form.getBody().layout(true, true);
+ }
+
+ private void createWidgets()
+ {
+ Group queuesGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ queuesGroup.setBackground(_paramsComposite.getBackground());
+ queuesGroup.setText("Queues");
+ queuesGroup.setLayout(new GridLayout(2,false));
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ queuesGroup.setLayoutData(gridData);
+
+ _queueTable = new Table (queuesGroup, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _queueTable.setLinesVisible (true);
+ _queueTable.setHeaderVisible (true);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _queueTable.setLayoutData(data);
+
+ _queueTableViewer = new TableViewer(_queueTable);
+ final TableSorter tableSorter = new TableSorter();
+
+ String[] titles = {"Name"};
+ int[] bounds = { 250 };
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_queueTable, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ tableSorter.setColumn(index);
+ final TableViewer viewer = _queueTableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _queueTableViewer.setContentProvider(new ContentProviderImpl());
+ _queueTableViewer.setLabelProvider(new LabelProviderImpl());
+ _queueTableViewer.setSorter(tableSorter);
+ _queueTable.setSortColumn(_queueTable.getColumn(0));
+ _queueTable.setSortDirection(SWT.UP);
+
+ Composite queuesRightComposite = _toolkit.createComposite(queuesGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ queuesRightComposite.setLayoutData(gridData);
+ queuesRightComposite.setLayout(new GridLayout());
+
+ final Button createQueueButton = _toolkit.createButton(queuesRightComposite, "Create ...", SWT.PUSH);
+ createQueueButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ createQueueButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ createQueue(createQueueButton.getShell());
+ }
+ });
+
+ final Button deleteQueueButton = _toolkit.createButton(queuesRightComposite, "Delete", SWT.PUSH);
+ deleteQueueButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ deleteQueueButton.setEnabled(false);
+ deleteQueueButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ deleteQueuesOrExchanges(deleteQueueButton.getShell(), VhostOperations.DELETE_QUEUE);
+ }
+ });
+
+ _queueTableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _queueTable.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ deleteQueueButton.setEnabled(true);
+ }
+ else
+ {
+ deleteQueueButton.setEnabled(false);
+ }
+ }
+ });
+
+ //listener for double clicking to open the selection mbean
+ _queueTable.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ openMBean(_queueTable);
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+
+ Group exchangesGroup = new Group(_paramsComposite, SWT.SHADOW_NONE);
+ exchangesGroup.setBackground(_paramsComposite.getBackground());
+ exchangesGroup.setText("Exchanges");
+ exchangesGroup.setLayout(new GridLayout(2,false));
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ exchangesGroup.setLayoutData(gridData);
+
+ _exchangeTable = new Table (exchangesGroup, SWT.MULTI | SWT.SCROLL_LINE | SWT.BORDER | SWT.FULL_SELECTION);
+ _exchangeTable.setLinesVisible (true);
+ _exchangeTable.setHeaderVisible (true);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ _exchangeTable.setLayoutData(data);
+
+ _exchangeTableViewer = new TableViewer(_exchangeTable);
+ final TableSorter exchangeTableSorter = new TableSorter();
+
+ for (int i = 0; i < titles.length; i++)
+ {
+ final int index = i;
+ final TableColumn column = new TableColumn (_exchangeTable, SWT.NONE);
+
+ column.setText(titles[i]);
+ column.setWidth(bounds[i]);
+ column.setResizable(true);
+
+ //Setting the right sorter
+ column.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent e)
+ {
+ exchangeTableSorter.setColumn(index);
+ final TableViewer viewer = _exchangeTableViewer;
+ int dir = viewer .getTable().getSortDirection();
+ if (viewer.getTable().getSortColumn() == column)
+ {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }
+ else
+ {
+ dir = SWT.UP;
+ }
+ viewer.getTable().setSortDirection(dir);
+ viewer.getTable().setSortColumn(column);
+ viewer.refresh();
+ }
+ });
+
+ }
+
+ _exchangeTableViewer.setContentProvider(new ContentProviderImpl());
+ _exchangeTableViewer.setLabelProvider(new LabelProviderImpl());
+ _exchangeTableViewer.setSorter(exchangeTableSorter);
+ _exchangeTable.setSortColumn(_exchangeTable.getColumn(0));
+ _exchangeTable.setSortDirection(SWT.UP);
+
+ Composite exchangesRightComposite = _toolkit.createComposite(exchangesGroup);
+ gridData = new GridData(SWT.FILL, SWT.FILL, false, true);
+ exchangesRightComposite.setLayoutData(gridData);
+ exchangesRightComposite.setLayout(new GridLayout());
+
+ final Button createExchangeButton = _toolkit.createButton(exchangesRightComposite, "Create ...", SWT.PUSH);
+ createExchangeButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ createExchangeButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ createExchange(createQueueButton.getShell());
+ }
+ });
+
+ final Button deleteExchangeButton = _toolkit.createButton(exchangesRightComposite, "Delete", SWT.PUSH);
+ deleteExchangeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ deleteExchangeButton.setEnabled(false);
+ deleteExchangeButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ deleteQueuesOrExchanges(deleteExchangeButton.getShell(), VhostOperations.DELETE_EXCHANGE);
+ }
+ });
+
+ _exchangeTableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent evt)
+ {
+ int selectionIndex = _exchangeTable.getSelectionIndex();
+
+ if (selectionIndex != -1)
+ {
+ deleteExchangeButton.setEnabled(true);
+ }
+ else
+ {
+ deleteExchangeButton.setEnabled(false);
+ }
+ }
+ });
+
+ //listener for double clicking to open the selection mbean
+ _exchangeTable.addMouseListener(new MouseListener()
+ {
+ // MouseListener implementation
+ public void mouseDoubleClick(MouseEvent event)
+ {
+ openMBean(_exchangeTable);
+ }
+
+ public void mouseDown(MouseEvent e){}
+ public void mouseUp(MouseEvent e){}
+ });
+ }
+
+
+ /**
+ * Content Provider class for the table viewer
+ */
+ private class ContentProviderImpl implements IStructuredContentProvider
+ {
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput)
+ {
+
+ }
+
+ public void dispose()
+ {
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object[] getElements(Object parent)
+ {
+ return ((List<ManagedBean>) parent).toArray();
+ }
+ }
+
+ /**
+ * Label Provider class for the table viewer
+ */
+ private class LabelProviderImpl extends LabelProvider implements ITableLabelProvider
+ {
+ @Override
+ public String getColumnText(Object element, int columnIndex)
+ {
+ switch (columnIndex)
+ {
+ case 0 : // name column
+ return ((ManagedBean) element).getName();
+ default :
+ return "-";
+ }
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex)
+ {
+ return null;
+ }
+
+ }
+
+ /**
+ * Sorter class for the table viewer.
+ *
+ */
+ public class TableSorter extends ViewerSorter
+ {
+ private int column;
+ private static final int ASCENDING = 0;
+ private static final int DESCENDING = 1;
+
+ private int direction = DESCENDING;
+
+ public TableSorter()
+ {
+ this.column = 0;
+ direction = ASCENDING;
+ }
+
+ public void setColumn(int column)
+ {
+ if (column == this.column)
+ {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ }
+ else
+ {
+ // New column; do an ascending sort
+ this.column = column;
+ direction = ASCENDING;
+ }
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ ManagedBean mbean1 = (ManagedBean ) e1;
+ ManagedBean mbean2 = (ManagedBean ) e2;
+
+ int comparison = 0;
+ switch(column)
+ {
+ case 0:
+ comparison = mbean1.getName().compareTo(mbean2.getName());
+ break;
+ default:
+ comparison = 0;
+ }
+ // If descending order, flip the direction
+ if(direction == DESCENDING)
+ {
+ comparison = -comparison;
+ }
+ return comparison;
+ }
+ }
+
+ private void createQueue(final Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Create Queue");
+
+ Composite nameComposite = _toolkit.createComposite(shell, SWT.NONE);
+ nameComposite.setBackground(shell.getBackground());
+ nameComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ nameComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(nameComposite,"Name:").setBackground(shell.getBackground());
+ final Text nameText = new Text(nameComposite, SWT.BORDER);
+ nameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Composite ownerComposite = _toolkit.createComposite(shell, SWT.NONE);
+ ownerComposite.setBackground(shell.getBackground());
+ ownerComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ ownerComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(ownerComposite,"Owner (optional):").setBackground(shell.getBackground());
+ final Text ownerText = new Text(ownerComposite, SWT.BORDER);
+ ownerText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Composite durableComposite = _toolkit.createComposite(shell, SWT.NONE);
+ durableComposite.setBackground(shell.getBackground());
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
+ gridData.minimumWidth = 220;
+ durableComposite.setLayoutData(gridData);
+ durableComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(durableComposite,"Durable:").setBackground(shell.getBackground());
+ final Button durableButton = new Button(durableComposite, SWT.CHECK);
+ durableButton.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false));
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String name = nameText.getText();
+
+ if (name == null || name.length() == 0)
+ {
+ ViewUtility.popupErrorMessage("Create Queue", "Please enter a valid name");
+ return;
+ }
+
+ String owner = ownerText.getText();
+
+ if (owner != null && owner.length() == 0)
+ {
+ owner = null;
+ }
+
+ boolean durable = durableButton.getSelection();
+
+ shell.dispose();
+
+ try
+ {
+ _vhmb.createNewQueue(name, owner, durable);
+
+ ViewUtility.operationResultFeedback(null, "Created Queue", null);
+ try
+ {
+ //delay to allow mbean registration notification processing
+ Thread.sleep(250);
+ }
+ catch(InterruptedException ie)
+ {
+ //ignore
+ }
+ }
+ catch(Exception e5)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error creating Queue");
+ MBeanUtility.handleException(_mbean, e5);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void createExchange(final Shell parent)
+ {
+ final Shell shell = ViewUtility.createModalDialogShell(parent, "Create Exchange");
+
+ Composite nameComposite = _toolkit.createComposite(shell, SWT.NONE);
+ nameComposite.setBackground(shell.getBackground());
+ nameComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ nameComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(nameComposite,"Name:").setBackground(shell.getBackground());
+ final Text nameText = new Text(nameComposite, SWT.BORDER);
+ nameText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Composite typeComposite = _toolkit.createComposite(shell, SWT.NONE);
+ typeComposite.setBackground(shell.getBackground());
+ typeComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ typeComposite.setLayout(new GridLayout(2,false));
+
+ String[] exchangeTypes;
+ if(_ApiVersion.greaterThanOrEqualTo(1, 3))//if the server supports Qpid JMX API 1.3
+ {//request the current exchange types from the broker
+ try
+ {
+ exchangeTypes = _vhmb.getExchangeTypes();
+ }
+ catch (IOException e1)
+ {
+ exchangeTypes = DEFAULT_EXCHANGE_TYPE_VALUES;
+ }
+ }
+ else //use the fallback defaults.
+ {
+ exchangeTypes = DEFAULT_EXCHANGE_TYPE_VALUES;
+ }
+
+ _toolkit.createLabel(typeComposite,"Type:").setBackground(shell.getBackground());
+ final org.eclipse.swt.widgets.List typeList = new org.eclipse.swt.widgets.List(typeComposite, SWT.SINGLE | SWT.BORDER);
+ typeList.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ typeList.setItems(exchangeTypes);
+
+ Composite durableComposite = _toolkit.createComposite(shell, SWT.NONE);
+ durableComposite.setBackground(shell.getBackground());
+ GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
+ gridData.minimumWidth = 220;
+ durableComposite.setLayoutData(gridData);
+ durableComposite.setLayout(new GridLayout(2,false));
+
+ _toolkit.createLabel(durableComposite,"Durable:").setBackground(shell.getBackground());
+ final Button durableButton = new Button(durableComposite, SWT.CHECK);
+ durableButton.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false));
+
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ String name = nameText.getText();
+
+ if (name == null || name.length() == 0)
+ {
+ ViewUtility.popupErrorMessage("Create Exchange", "Please enter a valid name");
+ return;
+ }
+
+ int selectedTypeIndex = typeList.getSelectionIndex();
+
+ if (selectedTypeIndex == -1)
+ {
+ ViewUtility.popupErrorMessage("Create Exchange", "Please select an Exchange type");
+ return;
+ }
+
+ String type = typeList.getItem(selectedTypeIndex);
+
+ boolean durable = durableButton.getSelection();
+
+ shell.dispose();
+
+ try
+ {
+ _vhmb.createNewExchange(name, type, durable);
+
+ ViewUtility.operationResultFeedback(null, "Created Exchange", null);
+ try
+ {
+ //delay to allow mbean registration notification processing
+ Thread.sleep(250);
+ }
+ catch(InterruptedException ie)
+ {
+ //ignore
+ }
+ }
+ catch(Exception e5)
+ {
+ ViewUtility.operationFailedStatusBarMessage("Error creating Exchange");
+ MBeanUtility.handleException(_mbean, e5);
+ }
+
+ refresh(_mbean);
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private void deleteQueuesOrExchanges(Shell parent, final VhostOperations op)
+ {
+ Table table;
+ String windowTitle;
+ String dialogueMessage;
+ final String feedBackMessage;
+ final String failureFeedBackMessage;
+
+ if(op.equals(VhostOperations.DELETE_QUEUE))
+ {
+ table = _queueTable;
+ windowTitle = "Delete Queue(s)";
+ dialogueMessage = "Delete Queue(s): ";
+ feedBackMessage = "Queue(s) deleted";
+ failureFeedBackMessage = "Error deleting Queue(s)";
+ }
+ else
+ {
+ table = _exchangeTable;
+ windowTitle = "Delete Exchange(s)";
+ dialogueMessage = "Delete Exchange(s): ";
+ feedBackMessage = "Exchange(s) deleted";
+ failureFeedBackMessage = "Error deleting Exchange(s)";
+ }
+
+ int selectionIndex = table.getSelectionIndex();
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ int[] selectedIndices = table.getSelectionIndices();
+
+ final ArrayList<ManagedBean> selectedMBeans = new ArrayList<ManagedBean>();
+
+ for(int index = 0; index < selectedIndices.length ; index++)
+ {
+ ManagedBean selectedMBean = (ManagedBean)table.getItem(selectedIndices[index]).getData();
+ selectedMBeans.add(selectedMBean);
+ }
+
+
+ final Shell shell = ViewUtility.createModalDialogShell(parent, windowTitle);
+
+ _toolkit.createLabel(shell, dialogueMessage).setBackground(shell.getBackground());
+
+ final Text headerText = new Text(shell, SWT.WRAP | SWT.V_SCROLL | SWT.BORDER );
+ headerText.setEditable(false);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ data.minimumHeight = 150;
+ data.heightHint = 150;
+ data.minimumWidth = 400;
+ data.widthHint = 400;
+ headerText.setLayoutData(data);
+
+ String lineSeperator = System.getProperty("line.separator");
+ for(ManagedBean mbean : selectedMBeans)
+ {
+ headerText.append(mbean.getName() + lineSeperator);
+ }
+ headerText.setSelection(0);
+
+ Composite okCancelButtonsComp = _toolkit.createComposite(shell);
+ okCancelButtonsComp.setBackground(shell.getBackground());
+ okCancelButtonsComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
+ okCancelButtonsComp.setLayout(new GridLayout(2,false));
+
+ Button okButton = _toolkit.createButton(okCancelButtonsComp, "OK", SWT.PUSH);
+ okButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+ Button cancelButton = _toolkit.createButton(okCancelButtonsComp, "Cancel", SWT.PUSH);
+ cancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
+
+ okButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+
+ try
+ {
+ //perform the deletes
+ for(ManagedBean mbean : selectedMBeans)
+ {
+ switch(op)
+ {
+ case DELETE_QUEUE:
+ _vhmb.deleteQueue(mbean.getName());
+ _serverRegistry.removeManagedObject(mbean);
+ break;
+ case DELETE_EXCHANGE:
+ _vhmb.unregisterExchange(mbean.getName());
+ break;
+ }
+ //remove the mbean from the server registry now instead of
+ //waiting for an mbean Unregistration Notification to do it
+ _serverRegistry.removeManagedObject(mbean);
+ }
+
+ ViewUtility.operationResultFeedback(null, feedBackMessage, null);
+ }
+ catch(Exception e1)
+ {
+ ViewUtility.operationFailedStatusBarMessage(failureFeedBackMessage);
+ MBeanUtility.handleException(_mbean, e1);
+ }
+
+ refresh(_mbean);;
+ }
+ });
+
+ cancelButton.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ shell.dispose();
+ }
+ });
+
+ shell.setDefaultButton(okButton);
+ shell.pack();
+ ViewUtility.centerChildInParentShell(parent, shell);
+
+ shell.open();
+ }
+
+ private enum VhostOperations
+ {
+ DELETE_QUEUE,
+ DELETE_EXCHANGE;
+ }
+
+ private void openMBean(Table table)
+ {
+ int selectionIndex = table.getSelectionIndex();
+
+ if (selectionIndex == -1)
+ {
+ return;
+ }
+
+ ManagedBean selectedMBean = (ManagedBean) table.getItem(selectionIndex).getData();
+
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ MBeanView view = (MBeanView) window.getActivePage().findView(MBeanView.ID);
+ try
+ {
+ view.openMBean(selectedMBean);
+ }
+ catch (Exception ex)
+ {
+ MBeanUtility.handleException(selectedMBean, ex);
+ }
+ }
+}
diff --git a/java/management/eclipse-plugin/src/main/resources/eclipse.exe b/java/management/eclipse-plugin/src/main/resources/eclipse.exe
deleted file mode 100644
index 7826d1ed80..0000000000
--- a/java/management/eclipse-plugin/src/main/resources/eclipse.exe
+++ /dev/null
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/jmxremote.sasl-plugin/MANIFEST.MF b/java/management/eclipse-plugin/src/main/resources/jmxremote.sasl-plugin/MANIFEST.MF
new file mode 100644
index 0000000000..fa11bac2ea
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/jmxremote.sasl-plugin/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: jmx sasl Plug-in
+Bundle-SymbolicName: jmxremote.sasl
+Bundle-Version: 1.0.1
+Bundle-ClassPath: jmxremote_optional.jar
+Export-Package: com.sun.jmx.remote.generic,
+ com.sun.jmx.remote.opt.internal,
+ com.sun.jmx.remote.opt.security,
+ com.sun.jmx.remote.opt.util,
+ com.sun.jmx.remote.profile.sasl,
+ com.sun.jmx.remote.profile.tls,
+ com.sun.jmx.remote.protocol.jmxmp,
+ com.sun.jmx.remote.socket,
+ javax.management.remote.generic,
+ javax.management.remote.jmxmp,
+ javax.management.remote.message
+Bundle-Vendor:
+Bundle-Localization: plugin
diff --git a/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt b/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt
deleted file mode 100644
index da433e89f9..0000000000
--- a/java/management/eclipse-plugin/src/main/resources/license.eclipse.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-Eclipse Public License - v 1.0
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
-b) in the case of each subsequent Contributor:
-
-i) changes to the Program, and
-
-ii) additions to the Program;
-
-where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
-
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
-a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
-
-b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
-
-c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
-
-d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
-
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
-
-a) it complies with the terms and conditions of this Agreement; and
-
-b) its license agreement:
-
-i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
-
-ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
-
-iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
-
-iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
-
-When the Program is made available in source code form:
-
-a) it must be made available under this Agreement; and
-
-b) a copy of this Agreement must be included with each copy of the Program.
-
-Contributors may not remove or alter any copyright notices contained within the Program.
-
-Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
-
-
diff --git a/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini
index e83321e650..dc15366740 100644
--- a/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini
@@ -17,10 +17,33 @@
# under the License.
###############################################################################
-#Product Runtime Configuration File
-
-osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
-eclipse.product=org.apache.qpid.management.ui.product
-eclipse.application=org.apache.qpid.management.ui.application
-osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.win32.win32.x86,org.eclipse.ui,org.eclipse.ui.forms,jmxremote.sasl,org.eclipse.ui.workbench
-osgi.bundles.defaultStartLevel=4
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.gtk.linux.x86, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.gtk.linux.x86, \
+org.apache.commons.codec
diff --git a/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/libcairo-swt.so b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/libcairo-swt.so
new file mode 100644
index 0000000000..b66f95814e
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/libcairo-swt.so
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc
new file mode 100644
index 0000000000..0cc5c65455
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/eclipse.ini b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini
index f56524580d..19ceb6f717 100644
--- a/java/management/eclipse-plugin/src/main/resources/eclipse.ini
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/qpidmc.ini
@@ -17,7 +17,21 @@
# under the License.
###############################################################################
--vmargs
--Xms40m
--Xmx256m
--Declipse.consoleLog=true
+-vmargs
+-Xms40m
+-Xmx256m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
+
diff --git a/java/management/eclipse-plugin/src/main/resources/unix/configuration/config.ini b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini
index aa2d21fd48..f437e830b5 100644
--- a/java/management/eclipse-plugin/src/main/resources/unix/configuration/config.ini
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini
@@ -17,11 +17,33 @@
# under the License.
###############################################################################
-#Product Runtime Configuration File
-
-osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
-eclipse.product=org.apache.qpid.management.ui.product
-eclipse.application=org.apache.qpid.management.ui.application
-osgi.bundles=org.eclipse.equinox.common@2:start,org.eclipse.core.runtime@start,com.ibm.icu,org.apache.qpid.management.ui,org.eclipse.core.commands,org.eclipse.core.contenttype,org.eclipse.core.expressions,org.eclipse.core.jobs,org.eclipse.core.runtime.compatibility.auth,org.eclipse.core.runtime.compatibility.registry,org.eclipse.equinox.preferences,org.eclipse.equinox.registry,org.eclipse.help,org.eclipse.jface,org.eclipse.swt,org.eclipse.swt.motif.linux.x86,org.eclipse.swt.gtk.linux.x86_64,org.eclipse.swt.gtk.linux.x86,org.eclipse.swt.gtk.linux.ppc,org.eclipse.swt.motif.hpux.PA_RISC,org.eclipse.swt.gtk.solaris.sparc,org.eclipse.swt.motif.solaris.sparc,org.eclipse.swt.carbon.macocx,org.eclipse.ui,org.eclipse.ui.forms,org.eclipse.ui.workbench
-osgi.bundles.defaultStartLevel=4
-eof=eof \ No newline at end of file
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.gtk.linux.x86_64, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.gtk.linux.x86_64, \
+org.apache.commons.codec
diff --git a/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so
new file mode 100644
index 0000000000..5734427fb8
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc
new file mode 100644
index 0000000000..ff1f3a7507
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini
new file mode 100644
index 0000000000..19ceb6f717
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini
@@ -0,0 +1,37 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+-vmargs
+-Xms40m
+-Xmx256m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
+
diff --git a/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini b/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini
new file mode 100644
index 0000000000..3ac3aa20f3
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini
@@ -0,0 +1,49 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.carbon.macosx, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.carbon.macosx, \
+org.apache.commons.codec
diff --git a/java/management/eclipse-plugin/src/main/resources/macosx/Contents/Info.plist b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/Info.plist
new file mode 100644
index 0000000000..e06c8a6e60
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/Info.plist
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleExecutable</key>
+ <string>qpidmc</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Apache Qpid Management Console for Mac OS X</string>
+ <key>CFBundleIconFile</key>
+ <string>Console.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.apache.qpid.management.ui</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>Qpid Management Console</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>3.4</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>3.4</string>
+ <key>Qpid Management Console</key>
+ <array>
+ <string>-consoleLog</string>
+ <string>-showlocation</string>
+ <!-- WARNING:
+ If you try to add a single VM argument (-vmargs) here,
+ *all* vmargs specified in qpidmc.ini will be ignored.
+ We recommend to add all arguments in MacOS/qpidmc.ini -->
+ </array>
+</dict>
+</plist>
diff --git a/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc
new file mode 100755
index 0000000000..36247a08e4
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini
new file mode 100644
index 0000000000..2a31b9b2c7
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/MacOS/qpidmc.ini
@@ -0,0 +1,42 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+-startup
+../../plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar
+--launcher.library
+../../plugins/org.eclipse.equinox.launcher.carbon.macosx_1.0.101.R34x_v20080731
+-vmargs
+-XstartOnFirstThread
+-Xms40m
+-Xmx512m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+-Dorg.eclipse.swt.internal.carbon.smallFonts
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
diff --git a/java/management/eclipse-plugin/src/main/resources/macosx/Contents/Resources/Console.icns b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/Resources/Console.icns
new file mode 100644
index 0000000000..610976efab
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/macosx/Contents/Resources/Console.icns
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF b/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF
deleted file mode 100644
index d18b1a073d..0000000000
--- a/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF
+++ /dev/null
@@ -1,8 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: jmx sasl Plug-in
-Bundle-SymbolicName: jmxremote.sasl
-Bundle-Version: 1.0.1
-Bundle-ClassPath: .
-Bundle-Vendor:
-Bundle-Localization: plugin
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini
new file mode 100644
index 0000000000..a99a8b3f7d
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini
@@ -0,0 +1,49 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.gtk.solaris.sparc, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.gtk.solaris.sparc, \
+org.apache.commons.codec
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm
new file mode 100644
index 0000000000..995d7c9bb0
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm
@@ -0,0 +1,311 @@
+/* XPM */
+static char *ProductIcon48[] = {
+/* columns rows colors chars-per-pixel */
+"48 48 257 2",
+" c black",
+". c gray100",
+"X c #69695A5AE8E8",
+"o c #494949499191",
+"O c #CECE9292BFBF",
+"+ c #E7E7CACAE0E0",
+"@ c #C8C88C8CBBBB",
+"# c #C2C28A8ABABA",
+"$ c #EAEAD7D7E8E8",
+"% c #CFCFA9A9CCCC",
+"& c #D9D9BCBCD8D8",
+"* c #B6B68787B9B9",
+"= c #C3C39999C7C7",
+"- c #A7A77D7DB5B5",
+"; c #BDBDA3A3CDCD",
+": c #D8D8CACAE3E3",
+"> c #A8A88D8DC4C4",
+", c #92927575B2B2",
+"< c #87876C6CAAAA",
+"1 c #9A9A8383BABA",
+"2 c #7B7B6363A3A3",
+"3 c #666654549595",
+"4 c #73735F5FADAD",
+"5 c #626251519292",
+"6 c #7F7F7272A7A7",
+"7 c #6D6D5E5E9E9E",
+"8 c #64645454A9A9",
+"9 c #77776969B1B1",
+"0 c #49493E3E8282",
+"q c #7D7D7373B6B6",
+"w c #5B5B4E4EADAD",
+"e c #55554949BABA",
+"r c #56564949BABA",
+"t c #56564A4ABABA",
+"y c #56564949B9B9",
+"u c #55554949B8B8",
+"i c #4F4F4444ACAC",
+"p c #53534848B4B4",
+"a c #53534848B3B3",
+"s c #54544949B5B5",
+"d c #52524747B0B0",
+"f c #52524747AFAF",
+"g c #54544949B3B3",
+"h c #DEDEDCDCEEEE",
+"j c #3E3E36369898",
+"k c #43433B3B9F9F",
+"l c #33332C2C7777",
+"z c #42423A3A9C9C",
+"x c #4A4A4040A8A8",
+"c c #55554A4ABABA",
+"v c #55554A4AB9B9",
+"b c #54544949B7B7",
+"n c #52524848B1B1",
+"m c #51514747AEAE",
+"M c #4E4E4545A9A9",
+"N c #49494141A0A0",
+"B c #52524848AFAF",
+"V c #51514848AEAE",
+"C c #50504747ACAC",
+"Z c #4F4F4646AAAA",
+"A c #51514848ADAD",
+"S c #50504747ABAB",
+"D c #50504848ACAC",
+"F c #50504747A9A9",
+"G c #4E4E4646A7A7",
+"H c #4E4E4545A4A4",
+"J c #4D4D4545A4A4",
+"K c #4F4F4747A8A8",
+"L c #4E4E4646A5A5",
+"P c #4D4D4545A3A3",
+"I c #3B3B35357D7D",
+"U c #4E4E4646A3A3",
+"Y c #55554D4D9F9F",
+"T c #4A4A43438989",
+"R c #51514B4B9090",
+"E c #67676060A5A5",
+"W c #1D1D18186A6A",
+"Q c #272722227D7D",
+"! c #282823237D7D",
+"~ c #2B2B26268181",
+"^ c #33332C2C8989",
+"/ c #3B3B36368E8E",
+"( c #454540409797",
+") c #4D4D4646A4A4",
+"_ c #4C4C4545A1A1",
+"` c #4D4D4646A2A2",
+"' c #4B4B4545A0A0",
+"] c #4D4D4646A1A1",
+"[ c #4C4C45459F9F",
+"{ c #4B4B45459E9E",
+"} c #4A4A44449C9C",
+"| c #494944449898",
+" . c #484843439696",
+".. c #4A4A45459999",
+"X. c #4F4F4A4AA0A0",
+"o. c #68686363AAAA",
+"O. c #21211D1D7676",
+"+. c #242420207575",
+"@. c #2D2D2A2A7F7F",
+"#. c #2D2D2A2A7B7B",
+"$. c #3D3D39398F8F",
+"%. c #484844449696",
+"&. c #474743439393",
+"*. c #464643439191",
+"=. c #454542428E8E",
+"-. c #4D4D4A4A9C9C",
+";. c #57575454A3A3",
+":. c #5A5A58589797",
+">. c #5F5F5D5D9999",
+",. c #85858282C1C1",
+"<. c #95959292C9C9",
+"1. c #B8B8B6B6DCDC",
+"2. c #070705055353",
+"3. c #080807075555",
+"4. c #0A0A09095757",
+"5. c #0C0C0B0B5858",
+"6. c #0F0F0D0D5C5C",
+"7. c #10100F0F5C5C",
+"8. c #131311116464",
+"9. c #141413136060",
+"0. c #141413135F5F",
+"q. c #171715156767",
+"w. c #161615156262",
+"e. c #161615156161",
+"r. c #181817176464",
+"t. c #1A1A19196666",
+"y. c #1C1C1A1A6464",
+"u. c #1D1D1C1C6868",
+"i. c #1F1F1E1E6A6A",
+"p. c #222221216C6C",
+"a. c #242423236F6F",
+"s. c #272725257171",
+"d. c #272726267272",
+"f. c #272726267171",
+"g. c #292928287474",
+"h. c #2A2A29297474",
+"j. c #2C2C2B2B7777",
+"k. c #2F2F2E2E7C7C",
+"l. c #2E2E2D2D7979",
+"z. c #343433337E7E",
+"x. c #393937378686",
+"c. c #373736368181",
+"v. c #3A3A39398484",
+"b. c #3A3A39398383",
+"n. c #3D3D3B3B8686",
+"m. c #424241418C8C",
+"M. c #424241418B8B",
+"N. c #444442428B8B",
+"B. c #434341418989",
+"V. c #454544448E8E",
+"C. c #454544448D8D",
+"Z. c #424241418787",
+"A. c #434342428888",
+"S. c #444442428787",
+"D. c #424241418585",
+"F. c #414140408383",
+"G. c #484847479090",
+"H. c #434342428686",
+"J. c #4A4A49499393",
+"K. c #464645458A8A",
+"L. c #4D4D4C4C9595",
+"P. c #54545252A0A0",
+"I. c #50504F4F9898",
+"U. c #58585757A0A0",
+"Y. c #525250509393",
+"T. c #5B5B5959A2A2",
+"R. c #585857579F9F",
+"E. c #62626161A9A9",
+"W. c #64646363ACAC",
+"Q. c #6B6B6A6AB2B2",
+"!. c #6B6B6A6AB1B1",
+"~. c #75757474B8B8",
+"^. c #7F7F7D7DBDBD",
+"/. c #9C9C9B9BCFCF",
+"(. c #0B0B0B0B5858",
+"). c #0D0D0D0D5A5A",
+"_. c #111111115E5E",
+"`. c #131313136060",
+"'. c #212121216D6D",
+"]. c #242424246F6F",
+"[. c #2B2B2C2C7777",
+"{. c #2B2B2B2B7777",
+"}. c #2C2C2C2C7777",
+"|. c #2E2E2E2E7979",
+" X c #313131317C7C",
+".X c #313131317B7B",
+"XX c #343434347E7E",
+"oX c #3C3C3C3C8686",
+"OX c #3F3F3F3F8989",
+"+X c #414142428B8B",
+"@X c #424242428B8B",
+"#X c #474747479090",
+"$X c #414141418484",
+"%X c #404040408181",
+"&X c #4A4A4A4A9494",
+"*X c #4A4A4A4A9393",
+"=X c #4D4D4D4D9696",
+"-X c #4F4F4F4F9898",
+";X c #505050509898",
+":X c #525252529B9B",
+">X c #555555559E9E",
+",X c #555555559D9D",
+"<X c #57575858A0A0",
+"1X c #58585858A0A0",
+"2X c #575758589F9F",
+"3X c #575757579F9F",
+"4X c #5A5A5A5AA2A2",
+"5X c #5D5D5D5DA5A5",
+"6X c #5F5F5F5FA7A7",
+"7X c #61616262AAAA",
+"8X c #61616161A9A9",
+"9X c #61616262A9A9",
+"0X c #62626262AAAA",
+"qX c #64646464ACAC",
+"wX c #62626262A9A9",
+"eX c #64646464ABAB",
+"rX c #66666666AEAE",
+"tX c #66666666ADAD",
+"yX c #68686868B0B0",
+"uX c #69696969AFAF",
+"iX c #6D6D6D6DB4B4",
+"pX c #6F6F6F6FB5B5",
+"aX c #73737373BABA",
+"sX c #71717171B7B7",
+"dX c #76767676BCBC",
+"fX c #79797979BFBF",
+"gX c #77777777B9B9",
+"hX c #80808080C1C1",
+"jX c #8C8C8C8CC5C5",
+"kX c #90909090C9C9",
+"lX c #98989898CBCB",
+"zX c #A0A0A0A0CFCF",
+"xX c #A5A5A5A5D3D3",
+"cX c #ABABABABD6D6",
+"vX c #C4C4C4C4E3E3",
+"bX c #D1D1D1D1E9E9",
+"nX c #E5E5E5E5F3F3",
+"mX c #9F9FA0A0D1D1",
+"MX c #B6B6C5C5E5E5",
+"NX c #8E8EA6A6D6D6",
+"BX c #9090A7A7D7D7",
+"VX c #9191A9A9D7D7",
+"CX c #9595ABABD8D8",
+"ZX c #9999AFAFDADA",
+"AX c #9D9DB2B2DCDC",
+"SX c #A1A1B5B5DDDD",
+"DX c #A5A5B8B8DEDE",
+"FX c #A9A9BBBBE0E0",
+"GX c #ACACBDBDE1E1",
+"HX c #B0B0C1C1E3E3",
+"JX c #B4B4C4C4E4E4",
+"KX c #B8B8C7C7E5E5",
+"LX c #BBBBC9C9E6E6",
+"PX c #AEAEC0C0E2E2",
+"IX c #B2B2C3C3E3E3",
+"UX c gray100",
+"YX c None",
+/* pixels */
+"YXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X YX",
+"X %X%X%XF.F.F.F.$XD.Z.Z.Z.B.B.B.N.N.=.=.=.*.*.*.&.&. . .| ....} } { { _ _ P P H G G G K S S C o ",
+"X %X%X%X%XF.F.$XD.D.Z.Z.B.A.B.N.N.N.=.=.=.*.*.&.&.%.%.%.| | ..} { { [ _ _ ` U J L G K F Z S C o ",
+"X %X%X%X%XF.F.F.D.D.H.Z.Z.A.B.N.N.N.C.=.=.*.*.&.&. . .%.| | ..} } { [ [ _ P P H G G K F S S C o ",
+"X %XF.%XF.F.$XF.$XZ.Z.Z.B.A.K.Y.7 , - - 1 1 ^.^.~.aX~.q 9 6XY { } { ' _ ] P P H L G K F Z S C o ",
+"X %XF.F.F.F.F.D.D.Z.Z.Z.K.:.1 ; % ; <.hXfXfXdXaXaXsXpXiX!.yXrXo.;.X.[ _ _ ` H H G K K F S S C o ",
+"X F.F.F.F.F.D.D.D.Z.H.Y.1 & & 1.cXmX/.kXfXdXaXaXsXpXiXQ.yXtXeXE.6X5XP.X._ ` J L G G K F Z S C o ",
+"X D.$XF.$XD.D.Z.Z.S.>.% + : vX1.1.cXmX/.dXaXaXsXpXiXQ.uXrXqX8X6X5XT.R.P.X.P ) H G K K S S S m o ",
+"X D.$XD.D.D.D.D.S.6 & $ h bXvXvX1.xX/.kXfXaXsXpXiXQ.yXrXW.E.6X5X4XU.,X:XI.-.` L G G K F Z C C o ",
+"X D.D.D.D.D.Z.H.6 & $ h h h bXvX1.cXmXkX,.dXpXiXQ.yXtXqXwX6X5XT.U.,X:XI.=X*X..` G K K Z S S m o ",
+"X Z.D.Z.H.Z.Z.7 & $ h h nXh bXvX1.cXmXkX,.gXiXQ.uXrXW.E.6X5X4XU.,X:X-XL.J.#XV. .P G F S S C m o ",
+"X Z.Z.Z.H.Z.R % + : bXh h h bXvX1.cX/.kXhX~.Q.yXrXqX9X6X5X4X2X,X:X;X=X*X#XV.M.OX( K Z S S C m o ",
+"X Z.Z.Z.A.A.* & & vXvXbXbXbXvXvX1.xXlXjX^.pXuXrXeXwX6X5X4XU.,X:X-XL.*XG.V.@XOXoXb.( Z S C C V o ",
+"X B.B.B.A.2 % % 1.1.vXvXvXvXvX1.cXzX<.,.gXiXrXW.E.6X5X4XU.,X:XI.=X*X#XV.@XOXn.b.c.x.N S S C m o ",
+"X B.B.B.S.* % ; xX1.1.1.1.1.cXcXzXlXjX^.pXrXeX7X6X5X4XR.,X:X-XL.J.#XV.@XOXn.b.c.XX X$.S C C m o ",
+"X N.N.N.2 O = /.mXxXcXcXcXcXxXzXlXjXhX~.uXeXE.6X5X4XU.,X:X-XL.J.#XV.M.OXn.v.c.z. X|.k.N D V f o ",
+"X N.N.N.- @ > kX<././.mXzXzXlX<.jXhXgXuXeXE.6X5X4X1X,X:XI.L.*X#XV.m.OXn.b.c.z. Xl.j.g./ C m V o ",
+"X N.N.R @ # ,.,.jXkXkX<.kXkXjX,.^.~.uXwXE.6X5X4X1X,X:XI.=XJ.#XC.M.OXn.v.c.z..X|.j.g.d.#.M m B o ",
+"X =.M.< @ * fXfXhXhX,.,.,.hX^.gXpXuXqX9X6X5X4XU.,X:XI.L.*XG.V.+XOXn.b.c.z..X|.[.g.d.a.p.z V B o ",
+"X =.N.- @ NXNXBXBXBXVXCXCXCXCXZXZXZXZXAXAXSXSXSXDXDXDXFXFXFXGXPXPXHXHXIXJXMXMXMXKXKXLXLXLXB d o ",
+"X =.=.* @ 1 dXdXaXaXsXpXiX!.yXrXeXwX6X5X4X<X,X:XI.=X*XG.V.M.OXn.v.c.XX.X|.j.g.d.a.p.i.u.@.f d o ",
+"X *.=.# @ ^.dXaXaXsXpXiXQ.yXrXeXwX6X5XT.U.,X:X-XL.&XG.C.m.OXoXv.c.z..X|.j.g.f.a.p.i.u.t.+.d d o ",
+"X *.*.@ @ NXNXNXBXVXVXCXCXCXCXZXZXZXZXAXAXAXSXSXDXDXDXFXFXGXGXPXPXHXHXJXJXJXMXKXKXKXLXLXLXd n o ",
+"X &.*.@ @ dXaXsXpXiXQ.yXtXeXE.6X5X4XU.>X:XI.L.*XG.V.m.OXoXv.c.z. X|.j.g.d.a.'.i.u.t.r.w.9.d n o ",
+"X &.&.@ @ ~.sXpXiXQ.yXtXW.E.6X5X4X1X,X:XI.=X*X#XC.m.OXn.b.c.z. X|.[.g.f.a.p.i.u.t.r.w.9.0.n a o ",
+"X &.&.@ @ NXNXBXBXVXVXVXCXCXCXZXZXZXZXAXAXSXSXSXDXDXDXFXFXGXGXPXPXHXIXIXJXMXMXKXKXKXLXLXLXn n o ",
+"X %. .# @ q iXQ.yXrXW.0X6X5X4XU.>X:XI.L.*X#XV.@XOXn.b.c.XX.X|.{.g.f.].'.i.u.t.r.w.0._.7.W n a o ",
+"X %. .* # , Q.yXtXeX7X6X5X4XU.,X:X-XL.*X#XV.@XOXn.b.c.XX Xl.{.g.d.a.p.i.u.t.r.e.0._.7.).+.a a o ",
+"X | | - # NXNXNXBXVXVXCXCXCXCXZXZXZXAXAXAXAXSXSXDXDXDXFXFXGXGXPXPXHXHXIXJXMXMXMXKXKXLXLXLXa a o ",
+"X | | < # - rXeX9X6X5X4XU.,X:X-XL.*X#XC.@XOXoXb.c.z. X|.j.h.s.a.'.i.u.t.r.w.9._.7.).5.4.j a p o ",
+"X | } Y # * 9 8X6X5X4X3X,X:XI.=X*XG.V.@XOXn.v.c.XX X|.j.g.f.a.p.i.u.t.r.e.0._.7.).5.4.q.i g p o ",
+"X } } | - # , 6X5X4XR.,X:XI.=X*XG.V.m.OXoXb.c.XX X|.j.g.f.a.p.i.u.t.r.e.9._.7.).5.4.3.~ a s s o ",
+"X } } } 4 # - E 4XU.>X:X-X=XJ.#XV.M.OXoXb.c.XX X|.{.h.d.a.'.i.u.t.r.e.9._.7.).5.4.3.6.z p s s o ",
+"X { { } } - # < U.,X:XI.=X*XG.V.+XOXoXb.c.z. X|.}.g.d.a.'.i.u.t.r.w.0._.7.).5.4.3.2.! g p s s o ",
+"X [ { ' [ 4 * - E :X;XL.J.#XV.m.OXoXb.c.z..X|.j.h.f.a.'.i.u.t.r.w.9._.6.).(.4.3.2.8.k p s s s o ",
+"X [ [ ' _ [ , * , ;XL.J.#XV.@XOXoXv.c.z..X|.{.g.f.a.p.i.u.t.r.w.`._.7.).(.4.3.2.2.^ s p s s s o ",
+"X _ _ _ _ P ] - * 2 *X#XV.m.OXn.v.c.XX X|.j.h.f.a.p.i.u.t.r.w.`._.7.).(.4.3.2.2.Q p s s s b u o ",
+"X ` ` ` ` ` ` 8 - - 7 V.@XOXoXv.c.XX.X|.j.g.d.a.'.i.u.t.r.w.0._.7.).5.4.3.2.2.O.x p s s s u u o ",
+"X P P ) P U U ) 8 - - 7 OXn.v.c.XX X|.j.h.f.a.p.i.u.t.r.w.0._.7.).5.4.3.2.2.O.x s s s s b u u o ",
+"X L L ) H ) L L L 8 1 - 7 b.c.z. X|.j.h.f.a.'.i.u.t.r.w.0._.7.).5.4.3.2.2.Q x p s s s b b u e o ",
+"X L G L G G G G G G G , * 2 T .Xl.j.h.f.a.p.i.u.t.r.e.0._.7.).5.4.3.2.8.^ p p s s s s u u e e o ",
+"X G G G G G G G K K M M 4 , , 3 I g.d.a.p.i.u.t.r.e.`._.7.).5.4.3.7.! k p s p s s s u u u e v o ",
+"X K G K K K K K K Z Z M F F 4 , < 3 I p.i.u.t.r.w.9._.7.).5.4.W ~ z a p p s s b s u u u e e e o ",
+"X F Z F F F F Z Z F F S S S S S w 9 < 2 5 0 l p.e.9.y.a.l ^ j i a p p p s s b b b u e v y r e o ",
+"X S Z Z S Z S Z S S S S S C C C A m d V f m B m B d d n d a a a p s p s s b u u u u e v e r t o ",
+"X S S S S S S S S S S C C C m m A V V B B B d d d n n a a a p p s p s s b u u u e e e c t r t o ",
+"X C C C C C C C C m C A m A m f V f f B d d d n n n a a a a s s s s s u b u u u u v t t r t t o ",
+"YXo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o YX"
+};
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm
new file mode 100644
index 0000000000..e64aa0cc06
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm
@@ -0,0 +1,295 @@
+/* XPM */
+static char *ProductIcon32[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 257 2",
+" c black",
+". c gray100",
+"X c #69695A5AE8E8",
+"o c #494949499191",
+"O c #E8E8CBCBE0E0",
+"+ c #DDDDB3B3D2D2",
+"@ c #F0F0DDDDEBEB",
+"# c #CDCD9191BEBE",
+"$ c #C8C88B8BBBBB",
+"% c #CACA9898C2C2",
+"& c #C3C38A8ABBBB",
+"* c #BABA8787B9B9",
+"= c #DCDCC4C4DEDE",
+"- c #C5C5A3A3CACA",
+"; c #ADAD8181B8B8",
+": c #A3A37A7AB5B5",
+"> c #E2E2D6D6E9E9",
+", c #B3B39A9AC4C4",
+"< c #EBEBE3E3F0F0",
+"1 c #C9C9B6B6D6D6",
+"2 c #96967676B8B8",
+"3 c #8C8C7171ABAB",
+"4 c #A4A49292BEBE",
+"5 c #7D7D6565A6A6",
+"6 c #83836D6DABAB",
+"7 c #9A9A8787C2C2",
+"8 c #7B7B6464B7B7",
+"9 c #5E5E50509191",
+"0 c #646457579A9A",
+"q c #85857B7BBEBE",
+"w c #7C7C7373B6B6",
+"e c #62625353D5D5",
+"r c #61615353D4D4",
+"t c #60605252D1D1",
+"y c #5F5F5252D0D0",
+"u c #5F5F5151CFCF",
+"i c #60605353D2D2",
+"p c #5F5F5252CFCF",
+"a c #5E5E5151CDCD",
+"s c #5C5C4F4FC7C7",
+"d c #5F5F5252CDCD",
+"f c #5E5E5151CBCB",
+"g c #5B5B4F4FC4C4",
+"h c #5A5A4E4EC1C1",
+"j c #71716969B0B0",
+"k c #48483E3EADAD",
+"l c #5D5D5151CDCD",
+"z c #5C5C5050C9C9",
+"x c #5D5D5151CBCB",
+"c c #5C5C5050C7C7",
+"v c #5B5B4F4FC6C6",
+"b c #5B5B5050C6C6",
+"n c #59594E4EC1C1",
+"m c #58584D4DBFBF",
+"M c #59594F4FC2C2",
+"N c #5A5A4F4FC2C2",
+"B c #58584D4DBCBC",
+"V c #57574D4DBCBC",
+"C c #59594E4EBEBE",
+"Z c #58584E4EBDBD",
+"A c #58584D4DBBBB",
+"S c #57574D4DBABA",
+"D c #56564D4DB9B9",
+"F c #56564C4CB6B6",
+"G c #55554C4CB6B6",
+"H c #54544B4BB4B4",
+"J c #54544B4BB1B1",
+"K c #53534B4BB1B1",
+"L c #52524A4AAEAE",
+"P c #51514949ACAC",
+"I c #51514949ABAB",
+"U c #474741418787",
+"Y c #32322C2C8F8F",
+"T c #2B2B25257777",
+"R c #36362F2F9696",
+"E c #2B2B26266E6E",
+"W c #4D4D4545ACAC",
+"Q c #55554D4DB8B8",
+"! c #54544C4CB4B4",
+"~ c #54544C4CB3B3",
+"^ c #51514A4AACAC",
+"/ c #51514A4AABAB",
+"( c #50504949A9A9",
+") c #4F4F4949A6A6",
+"_ c #4C4C4747A1A1",
+"` c #4E4E4848A3A3",
+"' c #4D4D4848A1A1",
+"] c #4B4B46469C9C",
+"[ c #4C4C47479E9E",
+"{ c #51514C4CA6A6",
+"} c #A9A9A6A6D5D5",
+"| c #1E1E1A1A6666",
+" . c #292925258181",
+".. c #3D3D39399292",
+"X. c #4A4A46469B9B",
+"o. c #53534E4EABAB",
+"O. c #494945459797",
+"+. c #4A4A46469999",
+"@. c #474744449494",
+"#. c #484845459494",
+"$. c #474744449292",
+"%. c #464643439090",
+"&. c #464642428D8D",
+"*. c #54545050A9A9",
+"=. c #474744448F8F",
+"-. c #4C4C49499999",
+";. c #57575454A6A6",
+":. c #5B5B5757AAAA",
+">. c #545451519B9B",
+",. c #5A5A57579C9C",
+"<. c #65656262A7A7",
+"1. c #68686666A2A2",
+"2. c #CACAC9C9E5E5",
+"3. c #050504045151",
+"4. c #080807075454",
+"5. c #0A0A09095858",
+"6. c #0C0C0A0A5858",
+"7. c #10100E0E6262",
+"8. c #0E0E0D0D5A5A",
+"9. c #121211115D5D",
+"0. c #131312125D5D",
+"q. c #161615156161",
+"w. c #171716166161",
+"e. c #1A1A19196565",
+"r. c #20201E1E7070",
+"t. c #1E1E1D1D6969",
+"y. c #2A2A29297676",
+"u. c #2F2F2D2D7676",
+"i. c #3A3A39398787",
+"p. c #3A3A39398383",
+"a. c #3F3F3E3E8888",
+"s. c #414140408989",
+"d. c #454543438D8D",
+"f. c #444442428B8B",
+"g. c #444443438C8C",
+"h. c #434342428A8A",
+"j. c #434341418888",
+"k. c #434342428989",
+"l. c #424241418787",
+"z. c #434342428787",
+"x. c #424241418585",
+"c. c #41413F3F8181",
+"v. c #414140408282",
+"b. c #484846468D8D",
+"n. c #494948489090",
+"m. c #4B4B4A4A9191",
+"M. c #4B4B49498E8E",
+"N. c #525251519A9A",
+"B. c #525251519999",
+"V. c #565654549A9A",
+"C. c #545453539494",
+"Z. c #60605F5FA7A7",
+"A. c #64646363ABAB",
+"S. c #5A5A59599797",
+"D. c #68686767ADAD",
+"F. c #6C6C6B6BB2B2",
+"G. c #5E5E5D5D9A9A",
+"H. c #76767575BABA",
+"J. c #78787777BBBB",
+"K. c #76767474B5B5",
+"L. c #7E7E7D7DBABA",
+"P. c #A5A5A4A4D2D2",
+"I. c #040404045252",
+"U. c #070707075454",
+"Y. c #070708085353",
+"T. c #080808085454",
+"R. c #0A0A0B0B5757",
+"E. c #0E0E0E0E5A5A",
+"W. c #111112125E5E",
+"Q. c #111111115E5E",
+"!. c #111111115D5D",
+"~. c #111112125D5D",
+"^. c #161616166868",
+"/. c #151516166161",
+"(. c #151515156161",
+"). c #19191A1A6565",
+"_. c #191919196565",
+"`. c #1A1A1A1A6464",
+"'. c #1D1D1E1E6969",
+"]. c #1E1E1E1E6969",
+"[. c #222222226D6D",
+"{. c #272727277171",
+"}. c #2B2B2C2C7676",
+"|. c #2B2B2B2B7676",
+" X c #2B2B2B2B7575",
+".X c #303030307A7A",
+"XX c #303030307979",
+"oX c #353535357F7F",
+"OX c #393939398383",
+"+X c #3A3A3A3A8383",
+"@X c #3F3F3F3F8787",
+"#X c #434343438C8C",
+"$X c #434344448C8C",
+"%X c #424242428686",
+"&X c #414141418484",
+"*X c #484848489191",
+"=X c #484849499090",
+"-X c #4D4D4D4D9696",
+";X c #515151519D9D",
+":X c #4D4D4D4D9595",
+">X c #515152529A9A",
+",X c #515152529999",
+"<X c #525252529A9A",
+"1X c #525252529999",
+"2X c #565657579E9E",
+"3X c #575757579D9D",
+"4X c #5B5B5B5BA2A2",
+"5X c #5F5F6060A6A6",
+"6X c #5F5F5F5FA6A6",
+"7X c #63636464AAAA",
+"8X c #64646464AAAA",
+"9X c #67676767AEAE",
+"0X c #67676868AEAE",
+"qX c #68686868AEAE",
+"wX c #6F6F6F6FB5B5",
+"eX c #6C6C6C6CB1B1",
+"rX c #73737373B8B8",
+"tX c #82828282BEBE",
+"yX c #86868686C2C2",
+"uX c #89898989C4C4",
+"iX c #98989898CBCB",
+"pX c #A0A0A0A0CFCF",
+"aX c #A9A9A9A9D5D5",
+"sX c #B0B0B0B0D8D8",
+"dX c #B8B8B8B8DDDD",
+"fX c #BDBDBDBDE0E0",
+"gX c #D9D9D9D9EDED",
+"hX c #90909191C6C6",
+"jX c #71718989BCBC",
+"kX c #73738B8BBFBF",
+"lX c #72728989BCBC",
+"zX c #79799090C3C3",
+"xX c #7E7E9595C7C7",
+"cX c #81819898CACA",
+"vX c #84849B9BCCCC",
+"bX c #8C8CA3A3D4D4",
+"nX c #71718A8ABCBC",
+"mX c #73738B8BBDBD",
+"MX c #75758D8DBFBF",
+"NX c #74748C8CBEBE",
+"BX c #76768E8EC0C0",
+"VX c #7C7C9494C6C6",
+"CX c #7B7B9393C4C4",
+"ZX c #7F7F9797C9C9",
+"AX c #82829A9ACBCB",
+"SX c #85859E9ECECE",
+"DX c #8888A0A0D1D1",
+"FX c #87879F9FD0D0",
+"GX c #8B8BA4A4D4D4",
+"HX c #8B8BA3A3D4D4",
+"JX c #8989A1A1D2D2",
+"KX c #8D8DA5A5D6D6",
+"LX c #8B8BA3A3D3D3",
+"PX c #8E8EA6A6D6D6",
+"IX c #8D8DA5A5D5D5",
+"UX c gray100",
+"YX c None",
+/* pixels */
+"YXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X YX",
+"X v.v.v.v.&Xl.z.k.&.d.%.$.@.O.+.] [ _ ` ) ( ^ L K ! G D V m m o ",
+"X c.c.c.v.&Xx.z.f.f.d.%.$.#.O.+.X.[ _ ` ) ( / L K H F D V C n o ",
+"X v.c.v.v.x.x.z.k.f.n.V.,.>.-.+.] [ _ ` ) ( ^ L K H G D V C h o ",
+"X &Xv.&Xx.x.l.j.M.1.4 - - , 7 q J.H.K.j :.*.P L K H F S B C n o ",
+"X x.&Xx.x.z.j.S., = = 1 } iXuXH.rXwXF.qX7XZ.;.o.J ! F S B m n o ",
+"X x.l.z.%Xz.G.1 @ > 2.dXaXiXuXrXwXF.qX8X5X4X2X;X{ H F S V C n o ",
+"X z.j.j.j.C.1 @ < gX2.fXaXpXuXwXeX9X7X5X4X2XN.:X*X_ D S Z m h o ",
+"X k.k.h.b., O > gXgX2.dXaXiXyXF.D.A.Z.4X3X1X:Xn.g.a._ V B m N o ",
+"X f.f.f.3 + = 2.2.2.fXsXpXhXtXD.8XZ.4X2X1X:X*X$X@Xp.i.W C n N o ",
+"X d.&.%.% + 1 dXdXdXsXP.iXyXK.8X5X4X2X>X:X*Xg.a.+XoX.X..m n N o ",
+"X %.=.5 % - P.} aXP.pXiXyXK.D.Z.4X3X1X-Xn.$X@X+XoX.X Xy.W h g o ",
+"X $.$.: # PXIXGXGXLXJXFXFXSXvXAXcXZXxXVXCXzXzXBXMXkXmXnXjXh g o ",
+"X #.@.* $ 7 yXuXyXtXL.K.D.6X4X2X1X:Xo g.a.OXoX.X|.{.[.t. .g v o ",
+"X O.#.$ $ q H.rXwXF.0XA.6X4X2X1X:Xo $Xa.p.oX.X|.{.[.'.`.r.g b o ",
+"X X.+.$ $ PXKXbXbXLXJXDXFXSXvXAXcXZXxXCXCXzXBXBXMXNXmXlXjXb c o ",
+"X ] ] $ $ H.wXF.0X7X6X4X2X<X:Xo #Xa.+XoX.X|.{.[.].)./.~.Q.c z o ",
+"X [ [ & & w F.qX7XZ.4X2X,X:Xo #Xa.+XoX.X}.{.[.'.e./.9.E.^.c z o ",
+"X ' _ * & PXKXbXHXLXJXDXSXSXvXAXcXZXxXVXCXzXzXBXMXNXkXjXjXz x o ",
+"X ` ` : & 2 8XZ.4X2XB.:X*Xg.@Xp.oX.X|.{.[.].).q.!.E.R.U.Y z f o ",
+"X ) ) 5 & ; <.4X2X>X:Xo #Xa.+XoXXX|.{.[.t._.q.~.E.R.4.5.k x a o ",
+"X ( ( I ; * 6 2X>X:X=X$X@X+XoX.X|.{.[.t.e./.W.E.R.Y.3. .z a a o ",
+"X I ^ / 8 * : 0 :X*X#X@X+XoX.X|.{.[.'._.(.~.E.R.T.3.7.k x a p o ",
+"X L L L ^ 2 * 3 m.$Xa.p.oX.X}.{.[.t.).(.~.E.6.T.3.I.R x a a y o ",
+"X J K K K K 2 * 5 s.OXoX.X}.{.[.'._.(.9.8.R.4.3.I.Y x l a p t o ",
+"X ~ H H ! ! ! 2 ; 5 U XX}.{.[.].e.(.W.E.R.U.3.7.R x l u u y t o ",
+"X G F G G G Q Q 8 : 3 9 u.[.]._./.Q.E.R.T.6. .k x a a u t t t o ",
+"X D S D S D S S S V 8 2 6 9 c.E w.0.| T Y k z z a a p t t i r o ",
+"X A V B V V V B B m m n n h h g g g c z z z l l d p y t i r r o ",
+"X m C C C C C C C n n n M N g g b c z z x a a a u y t t r r e o ",
+"X n n n n n h h h N N g g v b s z z z x a p p u t t r r r e e o ",
+"YXo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o YX"
+};
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm
new file mode 100644
index 0000000000..e2b9379f3a
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm
@@ -0,0 +1,287 @@
+/* XPM */
+static char *ProductIcon24[] = {
+/* columns rows colors chars-per-pixel */
+"24 24 257 2",
+" c black",
+". c gray100",
+"X c #69695A5AE8E8",
+"o c #494949499191",
+"O c #F1F1DFDFECEC",
+"+ c #D7D7ACACCDCD",
+"@ c #DFDFBBBBD6D6",
+"# c #E2E2C4C4DBDB",
+"$ c #CECE9C9CC4C4",
+"% c #C4C48B8BBABA",
+"& c #C2C28A8ABABA",
+"* c #C4C48E8EBCBC",
+"= c #BFBF8A8AB9B9",
+"- c #EBEBD9D9E9E9",
+"; c #BFBF8888B9B9",
+": c #D8D8B9B9D6D6",
+"> c #B9B98686B9B9",
+", c #B8B88989B9B9",
+"< c #BBBB9393BFBF",
+"1 c #A9A97B7BB2B2",
+"2 c #E4E4D4D4E7E7",
+"3 c #C6C6AFAFCECE",
+"4 c #A6A68080B6B6",
+"5 c #A2A27E7EB4B4",
+"6 c #9E9E7E7EB1B1",
+"7 c #ABAB9090BBBB",
+"8 c #B7B7A0A0C5C5",
+"9 c #9D9D7C7CB2B2",
+"0 c #AAAA8B8BBEBE",
+"q c #AAAA9090BCBC",
+"w c #8C8C6B6BABAB",
+"e c #90907070B1B1",
+"r c #C4C4B3B3D7D7",
+"t c #CDCDBFBFDDDD",
+"y c #EAEAE4E4F1F1",
+"u c #88886A6AADAD",
+"i c #9E9E8585C1C1",
+"p c #84846A6AAFAF",
+"a c #81816B6BAAAA",
+"s c #D7D7CFCFE6E6",
+"d c #81816969B1B1",
+"f c #78786363A5A5",
+"g c #6E6E5D5D9C9C",
+"h c #717160609D9D",
+"j c #83837474AAAA",
+"k c #6A6A5757A3A3",
+"l c #6E6E5E5EA0A0",
+"z c #5E5E50509292",
+"x c #88887B7BBCBC",
+"c c #68685858ABAB",
+"v c #5A5A4D4DA2A2",
+"b c #7D7D7373B4B4",
+"n c #5A5A4E4EA6A6",
+"m c #5F5F56569595",
+"M c #56564A4ABBBB",
+"N c #56564949B9B9",
+"B c #55554949B8B8",
+"V c #53534848B3B3",
+"C c #54544949B4B4",
+"Z c #52524747B0B0",
+"A c #52524747AFAF",
+"S c #5B5B53539393",
+"D c #3E3E36369797",
+"F c #49494040A6A6",
+"G c #48484040A5A5",
+"H c #55554A4ABABA",
+"J c #54544949B7B7",
+"K c #53534949B4B4",
+"L c #51514747AFAF",
+"P c #52524848B1B1",
+"I c #51514848B0B0",
+"U c #51514848AEAE",
+"Y c #51514747ADAD",
+"T c #51514848ADAD",
+"R c #4F4F4747ABAB",
+"E c #50504747ABAB",
+"W c #50504646A9A9",
+"Q c #4F4F4646A8A8",
+"! c #4E4E4646A7A7",
+"~ c #4E4E4545A4A4",
+"^ c #4D4D4545A4A4",
+"/ c #4E4E4646A5A5",
+"( c #4D4D4545A1A1",
+") c #3D3D36367E7E",
+"_ c #4B4B44449C9C",
+"` c #2A2A25257F7F",
+"' c #3E3E37379898",
+"] c #474740409C9C",
+"[ c #4D4D4646A4A4",
+"{ c #4C4C4545A2A2",
+"} c #4D4D4646A2A2",
+"| c #4D4D4646A1A1",
+" . c #4B4B45459F9F",
+".. c #4C4C45459F9F",
+"X. c #4C4C46469F9F",
+"o. c #4B4B45459D9D",
+"O. c #494943439898",
+"+. c #494944449A9A",
+"@. c #4A4A45459A9A",
+"#. c #494944449898",
+"$. c #484843439696",
+"%. c #494944449797",
+"&. c #484843439595",
+"*. c #51514C4CA1A1",
+"=. c #6B6B6767AEAE",
+"-. c #95959191C9C9",
+";. c #23231F1F7676",
+":. c #21211E1E7070",
+">. c #292925257F7F",
+",. c #252521217070",
+"<. c #242421216D6D",
+"1. c #2B2B27278080",
+"2. c #393935358C8C",
+"3. c #444440409494",
+"4. c #3B3B38388282",
+"5. c #474743439494",
+"6. c #484844449595",
+"7. c #474743439393",
+"8. c #474744449393",
+"9. c #464643439191",
+"0. c #454542428F8F",
+"q. c #4A4A47479898",
+"w. c #464643438F8F",
+"e. c #454542428D8D",
+"r. c #444441418B8B",
+"t. c #484844449191",
+"y. c #444441418989",
+"u. c #494946469090",
+"i. c #4C4C48489393",
+"p. c #51514E4E9E9E",
+"a. c #73737070B6B6",
+"s. c #77777474BBBB",
+"d. c #A0A09E9ED1D1",
+"f. c #D6D6D5D5EBEB",
+"g. c #0E0E0D0D5A5A",
+"h. c #11110F0F5E5E",
+"j. c #121211115E5E",
+"k. c #131312125F5F",
+"l. c #171716166363",
+"z. c #1D1D1B1B6868",
+"x. c #1D1D1C1C6868",
+"c. c #222221216E6E",
+"v. c #222221216D6D",
+"b. c #282827277474",
+"n. c #282827277373",
+"m. c #292928287373",
+"M. c #2F2F2E2E7979",
+"N. c #353534347F7F",
+"B. c #363635358181",
+"V. c #3C3C3B3B8585",
+"C. c #424241418C8C",
+"Z. c #424241418B8B",
+"A. c #444442428B8B",
+"S. c #434341418989",
+"D. c #434342428989",
+"F. c #424241418787",
+"G. c #414140408484",
+"H. c #474745458D8D",
+"J. c #434342428787",
+"K. c #424241418585",
+"L. c #414140408282",
+"P. c #494948489191",
+"I. c #4F4F4E4E9797",
+"U. c #59595757A6A6",
+"Y. c #5F5F5D5DA4A4",
+"T. c #6C6C6B6BB3B3",
+"R. c #7C7C7B7BB9B9",
+"E. c #A8A8A7A7D3D3",
+"W. c #0D0D0D0D5A5A",
+"Q. c #1F1F1F1F6C6C",
+"!. c #222222226E6E",
+"~. c #3B3B3B3B8585",
+"^. c #414141418C8C",
+"/. c #414141418B8B",
+"(. c #424242428B8B",
+"). c #484848489292",
+"_. c #404040408181",
+"`. c #4E4E4E4E9898",
+"'. c #555555559E9E",
+"]. c #555555559D9D",
+"[. c #5B5B5B5BA3A3",
+"{. c #5C5C5C5CA3A3",
+"}. c #61616161A9A9",
+"|. c #66666666AEAE",
+" X c #66666666ADAD",
+".X c #6B6B6B6BB2B2",
+"XX c #70707070B7B7",
+"oX c #6A6A6A6AADAD",
+"OX c #74747474BBBB",
+"+X c #89898989C2C2",
+"@X c #90909090C8C8",
+"#X c #8F8F8F8FC6C6",
+"$X c #92929292C6C6",
+"%X c #9F9F9F9FCFCF",
+"&X c #A5A5A5A5D2D2",
+"*X c #B5B5B5B5DBDB",
+"=X c #B8B8B8B8DEDE",
+"-X c #B7B7B7B7DCDC",
+";X c #BBBBBBBBDEDE",
+":X c #BDBDBDBDDFDF",
+">X c #C9C9C9C9E5E5",
+",X c #D1D1D1D1EAEA",
+"<X c #7C7C7D7DBABA",
+"1X c #89898A8AC7C7",
+"2X c #8F8F9090C7C7",
+"3X c #A3A3A4A4D3D3",
+"4X c #A2A2B5B5DEDE",
+"5X c #ADADBDBDE1E1",
+"6X c #B9B9C7C7E5E5",
+"7X c #BABAC8C8E6E6",
+"8X c #8E8EA6A6D6D6",
+"9X c #9090A7A7D7D7",
+"0X c #9191A9A9D7D7",
+"qX c #9292A9A9D8D8",
+"wX c #9494ABABD8D8",
+"eX c #9898AEAED9D9",
+"rX c #9B9BB0B0DADA",
+"tX c #9E9EB3B3DCDC",
+"yX c #A1A1B5B5DDDD",
+"uX c #A5A5B8B8DEDE",
+"iX c #A8A8BBBBE0E0",
+"pX c #ACACBEBEE1E1",
+"aX c #AFAFC0C0E3E3",
+"sX c #B3B3C3C3E4E4",
+"dX c #B2B2C2C2E3E3",
+"fX c #B5B5C5C5E5E5",
+"gX c #B8B8C7C7E6E6",
+"hX c #B6B6C5C5E4E4",
+"jX c #9797AEAED9D9",
+"kX c #A1A1B6B6DDDD",
+"lX c #A8A8BBBBDFDF",
+"zX c gray100",
+"xX c black",
+"cX c black",
+"vX c black",
+"bX c black",
+"nX c black",
+"mX c black",
+"MX c black",
+"NX c black",
+"BX c black",
+"VX c black",
+"CX c black",
+"ZX c black",
+"AX c black",
+"SX c black",
+"DX c black",
+"FX c black",
+"GX c black",
+"HX c black",
+"JX c black",
+"KX c black",
+"LX c black",
+"PX c black",
+"IX c black",
+"UX c black",
+"YX c None",
+/* pixels */
+"YXX X X X X X X X X X X X X X X X X X X X X X YX",
+"X _._.L.G.K.F.D.A.e.0.9.&.$.%.+._ ..{ ^ ! W E o ",
+"X L.L.L.G.F.F.D.r.e.0.9.7.&.O.@.o. .{ ~ ! Q E o ",
+"X L.G.G.K.F.S.y.r.e.w.9.5.$.+.@.o...( ~ ! W E o ",
+"X G.K.K.F.J.D.h 6 0 i x s.a.=.U.*...} ~ ! W E o ",
+"X K.F.F.F.S 7 : r d.1XOXXX.X|.}.[.p.| / ! W E o ",
+"X F.F.F.m 3 - s =X3X@XXXT. X}.[.].I.q.{ Q E T o ",
+"X S.D.H.8 O y ,X;X&X2X.X|.}.[.].I.P.C.3.Q E Y o ",
+"X A.r.j # 2 f.>X*X%X+X|.}.[.].I.P.^.~.B.] E Y o ",
+"X e.u.q @ t :X-XE.$X<X}.[.].`.P.Z.V.N.M.2.Y L o ",
+"X 0.i.< + 8X8XqXwXeXrXtX4XuXlXpXaXsXfXgX7XY A o ",
+"X 9.t.* $ -.#X+XR.oX{.'.`.P.(.~.N.M.m.c.Q.T Z o ",
+"X 8.7.; % 8X9X0XwXeXrXtXyXuXiXpXaXdXfXgX7XL Z o ",
+"X 6.&.1 & b X}.[.'.I.P./.~.N.M.n.!.x.l.:.I P o ",
+"X #.#.w = 8X9XqXwXjXrXtXkXuXiX5XaXsXhX6X7XP V o ",
+"X +.+.k > 5 Y.].I.)./.~.N.M.b.v.x.l.k.h.' V C o ",
+"X o.o.o.u , a I.).Z.V.N.M.n.c.z.l.j.W.` P V C o ",
+"X .. .X.v e 4 l ^.V.N.M.m.!.x.l.j.g.;.F V C J o ",
+"X ( | ( ( n p 9 g 4.M.n.c.x.l.j.h.>.G V K C J o ",
+"X ~ [ [ ^ / / c d f z ) <.z.,.1.D P V C C B B o ",
+"X ! Q ! Q Q Q Q W E E Y T A Z P V V K C J B B o ",
+"X Q W Q W R W E E T T T L Z P V V K J J J B N o ",
+"X R E E E E E Y Y U L Z P P P C V J J B B H M o ",
+"YXo o o o o o o o o o o o o o o o o o o o o o YX"
+};
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm
new file mode 100644
index 0000000000..3f6b21f428
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm
@@ -0,0 +1,279 @@
+/* XPM */
+static char *ProductIcon16[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 257 2",
+" c black",
+". c gray100",
+"X c #E2E2C0C0D9D9",
+"o c #EDEDD9D9E8E8",
+"O c #D5D5ABABCDCD",
+"+ c #E2E2C3C3DCDC",
+"@ c #C5C58E8EBCBC",
+"# c #D4D4ABABCDCD",
+"$ c #CACA9F9FC6C6",
+"% c #D6D6B4B4D3D3",
+"& c #CACAA0A0C8C8",
+"* c #C6C69D9DC6C6",
+"= c #C5C59F9FC8C8",
+"- c #CCCCACACCECE",
+"; c #CCCCB0B0D3D3",
+": c #A6A68383B3B3",
+"> c #BABA9A9AC6C6",
+", c #B7B79A9AC2C2",
+"< c #E3E3D5D5E9E9",
+"1 c #B0B08E8EC0C0",
+"2 c #9F9F8080B8B8",
+"3 c #AFAF9898C1C1",
+"4 c #DBDBCFCFE5E5",
+"5 c #96967878B2B2",
+"6 c #9A9A7E7EBABA",
+"7 c #8E8E7878AFAF",
+"8 c #91917F7FBDBD",
+"9 c #D3D3CCCCE4E4",
+"0 c #535348488B8B",
+"q c #69695A5AE8E8",
+"w c #55554949B9B9",
+"e c #55554949B8B8",
+"r c #54544848B6B6",
+"t c #53534848B4B4",
+"y c #54544848B4B4",
+"u c #53534848B3B3",
+"i c #53534848B2B2",
+"p c #52524747AFAF",
+"a c #53534848B1B1",
+"s c #54544949B8B8",
+"d c #54544949B6B6",
+"f c #52524848B3B3",
+"g c #52524848B2B2",
+"h c #53534949B3B3",
+"j c #52524848B1B1",
+"k c #52524848B0B0",
+"l c #51514747AEAE",
+"z c #52524848AFAF",
+"x c #51514848AEAE",
+"c c #51514747ADAD",
+"v c #51514747ACAC",
+"b c #4F4F4646AAAA",
+"n c #51514848ADAD",
+"m c #50504747ABAB",
+"M c #50504747AAAA",
+"N c #4F4F4646A8A8",
+"B c #50504747A9A9",
+"V c #4E4E4646A7A7",
+"C c #4E4E4646A6A6",
+"Z c #4F4F4646A6A6",
+"A c #4F4F4747A7A7",
+"S c #4D4D4545A3A3",
+"D c #4D4D4545A2A2",
+"F c #4C4C45459E9E",
+"G c #74746E6EB3B3",
+"H c #2E2E29298383",
+"J c #383832329090",
+"K c #464640409999",
+"L c #4D4D4646A2A2",
+"P c #4E4E4747A3A3",
+"I c #4B4B45459F9F",
+"U c #4B4B45459E9E",
+"Y c #4C4C46469F9F",
+"T c #4A4A44449B9B",
+"R c #4A4A44449A9A",
+"E c #494943439797",
+"W c #494944449797",
+"Q c #484843439494",
+"! c #78787474B8B8",
+"~ c #272724247878",
+"^ c #2D2D2A2A7575",
+"/ c #484844449797",
+"( c #474743439393",
+") c #454542429090",
+"_ c #4B4B48489A9A",
+"` c #464643438F8F",
+"' c #464643438E8E",
+"] c #454542428C8C",
+"[ c #51514D4DA0A0",
+"{ c #5C5C5959A5A5",
+"} c #535350509090",
+"| c #C8C8C7C7E3E3",
+" . c #121211115D5D",
+".. c #1A1A19196565",
+"X. c #242422226D6D",
+"o. c #3F3F3E3E8888",
+"O. c #444442428D8D",
+"+. c #444442428989",
+"@. c #424241418787",
+"#. c #454543438A8A",
+"$. c #434342428888",
+"%. c #424241418686",
+"&. c #414140408484",
+"*. c #414140408383",
+"=. c #424240408383",
+"-. c #414140408282",
+";. c #474746468D8D",
+":. c #464644448989",
+">. c #525251519999",
+",. c #64646363AAAA",
+"<. c #61615F5FA2A2",
+"1. c #6E6E6C6CB2B2",
+"2. c #A5A5A4A4D3D3",
+"3. c #B0B0AFAFD6D6",
+"4. c #111112125D5D",
+"5. c #19191A1A6565",
+"6. c #1E1E1E1E6C6C",
+"7. c #222222226D6D",
+"8. c #2B2B2B2B7676",
+"9. c #2B2B2B2B7575",
+"0. c #2B2B2C2C7575",
+"q. c #343435357F7F",
+"w. c #343435357E7E",
+"e. c #353535357F7F",
+"r. c #3E3E3E3E8888",
+"t. c #3E3E3E3E8787",
+"y. c #414141418484",
+"u. c #404040408282",
+"i. c #484849499191",
+"p. c #494949499191",
+"a. c #484848489090",
+"s. c #484849499090",
+"d. c #404040408080",
+"f. c #525252529A9A",
+"g. c #525252529999",
+"h. c #5B5B5B5BA3A3",
+"j. c #5B5B5B5BA2A2",
+"k. c #64646464ABAB",
+"l. c #63636464AAAA",
+"z. c #6B6B6C6CB2B2",
+"x. c #72727373B9B9",
+"c. c #71717171A4A4",
+"v. c #78787878ABAB",
+"b. c #7F7F7F7FB1B1",
+"n. c #8C8C8C8CBEBE",
+"m. c #A5A5A5A5D2D2",
+"M. c #C9C9C9C9E5E5",
+"N. c #85858686B7B7",
+"B. c #91919292C4C4",
+"V. c #71718989BCBC",
+"C. c #73738B8BBEBE",
+"Z. c #75758D8DC0C0",
+"A. c #78789090C3C3",
+"S. c #7A7A9292C5C5",
+"D. c #71718A8ABDBD",
+"F. c #76768E8EC0C0",
+"G. c #78789090C2C2",
+"H. c #7B7B9393C5C5",
+"J. c #7D7D9595C7C7",
+"K. c #80809999CACA",
+"L. c #7E7E9696C7C7",
+"P. c #83839B9BCDCD",
+"I. c #83839B9BCCCC",
+"U. c #86869E9ECFCF",
+"Y. c #8888A1A1D1D1",
+"T. c #8A8AA2A2D3D3",
+"R. c #8989A1A1D1D1",
+"E. c #8B8BA3A3D3D3",
+"W. c gray100",
+"Q. c black",
+"!. c black",
+"~. c black",
+"^. c black",
+"/. c black",
+"(. c black",
+"). c black",
+"_. c black",
+"`. c black",
+"'. c black",
+"]. c black",
+"[. c black",
+"{. c black",
+"}. c black",
+"|. c black",
+" X c black",
+".X c black",
+"XX c black",
+"oX c black",
+"OX c black",
+"+X c black",
+"@X c black",
+"#X c black",
+"$X c black",
+"%X c black",
+"&X c black",
+"*X c black",
+"=X c black",
+"-X c black",
+";X c black",
+":X c black",
+">X c black",
+",X c black",
+"<X c black",
+"1X c black",
+"2X c black",
+"3X c black",
+"4X c black",
+"5X c black",
+"6X c black",
+"7X c black",
+"8X c black",
+"9X c black",
+"0X c black",
+"qX c black",
+"wX c black",
+"eX c black",
+"rX c black",
+"tX c black",
+"yX c black",
+"uX c black",
+"iX c black",
+"pX c black",
+"aX c black",
+"sX c black",
+"dX c black",
+"fX c black",
+"gX c black",
+"hX c black",
+"jX c black",
+"kX c black",
+"lX c black",
+"zX c black",
+"xX c black",
+"cX c black",
+"vX c black",
+"bX c black",
+"nX c black",
+"mX c black",
+"MX c black",
+"NX c black",
+"BX c black",
+"VX c black",
+"CX c black",
+"ZX c black",
+"AX c black",
+"SX c black",
+"DX c black",
+"FX c black",
+"GX c black",
+"HX c black",
+"JX c black",
+"KX c black",
+"LX c black",
+"PX c black",
+"IX c black",
+"UX c black",
+"YX c None",
+/* pixels */
+"YXq q q q q q q q q q q q q q YX",
+"q d.-.y.%.+.O.` ( E R U D C B p.",
+"q u.*.&.$.#.] ) Q W T F L V M p.",
+"q =.y.} , % ; 8 ! 1.{ [ S Z b p.",
+"q @.:.- o 4 2.x.z.,.j.>._ A m p.",
+"q +.: X < M.m.z.l.j.g.s.r.K v p.",
+"q ' $ + 9 | 3.B.n.N.b.v.c.<.n p.",
+"q ` O T.Y.U.P.K.L.S.G.F.C.D.l p.",
+"q ( # @ G k.h.g.i.t.e.9.7.6.z p.",
+"q / * E.R.U.I.K.J.H.A.Z.C.V.a p.",
+"q T 2 & 5 f.a.o.q.8.7...4.J u p.",
+"q I Y 1 = 7 ;.w.0.7.5. .H f y p.",
+"q L D P 6 > 3 0 ^ X.~ J i t d p.",
+"q C C V A N M m n p k g y r e p.",
+"q M b M m m c x p j h y d s w p.",
+"YXp.p.p.p.p.p.p.p.p.p.p.p.p.p.YX"
+};
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc
new file mode 100755
index 0000000000..b88ff49e8e
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini
new file mode 100644
index 0000000000..cfa715e5a8
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini
@@ -0,0 +1,40 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+-startup
+plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar
+--launcher.library
+plugins/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731
+-vmargs
+-Xms40m
+-Xmx256m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
+
diff --git a/java/management/eclipse-plugin/src/main/resources/startup.jar b/java/management/eclipse-plugin/src/main/resources/startup.jar
deleted file mode 100644
index 2f26eceece..0000000000
--- a/java/management/eclipse-plugin/src/main/resources/startup.jar
+++ /dev/null
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini b/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini
new file mode 100644
index 0000000000..a61bea2fa8
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini
@@ -0,0 +1,49 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.win32.win32.x86, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.win32.win32.x86, \
+org.apache.commons.codec
diff --git a/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.exe b/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.exe
new file mode 100644
index 0000000000..3999884bfb
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.exe
Binary files differ
diff --git a/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini b/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini
new file mode 100644
index 0000000000..312580769e
--- /dev/null
+++ b/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/qpidmc.ini
@@ -0,0 +1,36 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+-vmargs
+-Xms40m
+-Xmx256m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
diff --git a/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApiVersionTest.java b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApiVersionTest.java
new file mode 100644
index 0000000000..b4f6aea57b
--- /dev/null
+++ b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApiVersionTest.java
@@ -0,0 +1,177 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import junit.framework.TestCase;
+
+public class ApiVersionTest extends TestCase
+{
+
+ public void testGetMajor()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+ assertEquals(1, ver.getMajor());
+ }
+
+ public void testGetMinor()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+ assertEquals(3, ver.getMinor());
+ }
+
+ public void testGreaterThanOrEqualTo()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+
+ //equal
+ assertTrue(ver.greaterThanOrEqualTo(1, 3));
+ //same major, higher minor
+ assertFalse(ver.greaterThanOrEqualTo(1, 4));
+ //same major, lower minor
+ assertTrue(ver.greaterThanOrEqualTo(1, 2));
+
+ //higher major, lower minor
+ assertFalse(ver.greaterThanOrEqualTo(2, 0));
+ //higher major, same minor
+ assertFalse(ver.greaterThanOrEqualTo(2, 3));
+ //higher major, higher minor
+ assertFalse(ver.greaterThanOrEqualTo(2, 4));
+
+ //lower major, higher minor
+ assertTrue(ver.greaterThanOrEqualTo(0, 9));
+ //lower major, lower minor
+ assertTrue(ver.greaterThanOrEqualTo(0, 2));
+ //lower major, same minor
+ assertTrue(ver.greaterThanOrEqualTo(0, 3));
+ }
+
+ public void testLessThanOrEqualTo()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+
+ //equal
+ assertTrue(ver.lessThanOrEqualTo(1, 3));
+ //same major, higher minor
+ assertTrue(ver.lessThanOrEqualTo(1, 4));
+ //same major, lower minor
+ assertFalse(ver.lessThanOrEqualTo(1, 2));
+
+ //higher major, lower minor
+ assertTrue(ver.lessThanOrEqualTo(2, 0));
+ //higher major, same minor
+ assertTrue(ver.lessThanOrEqualTo(2, 3));
+ //higher major, higher minor
+ assertTrue(ver.lessThanOrEqualTo(2, 4));
+
+ //lower major, higher minor
+ assertFalse(ver.lessThanOrEqualTo(0, 9));
+ //lower major, lower minor
+ assertFalse(ver.lessThanOrEqualTo(0, 2));
+ //lower major, same minor
+ assertFalse(ver.lessThanOrEqualTo(0, 3));
+ }
+
+ public void testGreaterThan()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+
+ //equal
+ assertFalse(ver.greaterThan(1, 3));
+ //same major, higher minor
+ assertFalse(ver.greaterThan(1, 4));
+ //same major, lower minor
+ assertTrue(ver.greaterThan(1, 2));
+
+ //higher major, lower minor
+ assertFalse(ver.greaterThan(2, 0));
+ //higher major, same minor
+ assertFalse(ver.greaterThan(2, 3));
+ //higher major, higher minor
+ assertFalse(ver.greaterThan(2, 4));
+
+ //lower major, higher minor
+ assertTrue(ver.greaterThan(0, 9));
+ //lower major, lower minor
+ assertTrue(ver.greaterThan(0, 2));
+ //lower major, same minor
+ assertTrue(ver.greaterThan(0, 3));
+ }
+
+ public void testLessThan()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+
+ //equal
+ assertFalse(ver.lessThan(1, 3));
+ //same major, higher minor
+ assertTrue(ver.lessThan(1, 4));
+ //same major, lower minor
+ assertFalse(ver.lessThan(1, 2));
+
+ //higher major, lower minor
+ assertTrue(ver.lessThan(2, 0));
+ //higher major, same minor
+ assertTrue(ver.lessThan(2, 3));
+ //higher major, higher minor
+ assertTrue(ver.lessThan(2, 4));
+
+ //lower major, higher minor
+ assertFalse(ver.lessThan(0, 9));
+ //lower major, lower minor
+ assertFalse(ver.lessThan(0, 2));
+ //lower major, same minor
+ assertFalse(ver.lessThan(0, 3));
+ }
+
+ public void testEqualsIntInt()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+
+ //equal
+ assertTrue(ver.equals(1, 3));
+ //same major, higher minor
+ assertFalse(ver.equals(1, 4));
+ //same major, lower minor
+ assertFalse(ver.equals(1, 2));
+
+ //higher major, lower minor
+ assertFalse(ver.equals(2, 0));
+ //higher major, same minor
+ assertFalse(ver.equals(2, 3));
+ //higher major, higher minor
+ assertFalse(ver.equals(2, 4));
+
+ //lower major, higher minor
+ assertFalse(ver.equals(0, 9));
+ //lower major, lower minor
+ assertFalse(ver.equals(0, 2));
+ //lower major, same minor
+ assertFalse(ver.equals(0, 3));
+ }
+
+ public void testToString()
+ {
+ ApiVersion ver = new ApiVersion(1,3);
+
+ assertEquals("major=1,minor=3", ver.toString());
+ }
+
+}
diff --git a/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApplicationRegistryTest.java b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApplicationRegistryTest.java
new file mode 100644
index 0000000000..1a56ab69b6
--- /dev/null
+++ b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ApplicationRegistryTest.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.ui;
+
+import org.apache.qpid.management.common.mbeans.ServerInformation;
+
+import junit.framework.TestCase;
+
+public class ApplicationRegistryTest extends TestCase
+{
+ public void testSupportedManagementApiVersion()
+ {
+ //ensure that the console supported API version is kept in sync with the broker
+
+ assertEquals("The management console does not support the same major version of management API as the broker. " +
+ "Make any required changes and update the supported value.",
+ ServerInformation.QPID_JMX_API_MAJOR_VERSION,
+ ApplicationRegistry.SUPPORTED_QPID_JMX_API_MAJOR_VERSION);
+
+ assertEquals("The management console does not support the same minor version of management API as the broker. " +
+ "Make any required changes and update the supported value.",
+ ServerInformation.QPID_JMX_API_MINOR_VERSION,
+ ApplicationRegistry.SUPPORTED_QPID_JMX_API_MINOR_VERSION);
+ }
+}
diff --git a/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java
index 11ab6af064..5469bfad5f 100644
--- a/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java
+++ b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java
@@ -58,7 +58,8 @@ public class ManagementConsoleTest extends TestCase
@Override
protected void tearDown() throws Exception
{
- ApplicationRegistry.removeAll();
+ // Correctly Close the AR that we created above
+ ApplicationRegistry.remove();
}
/**