diff options
Diffstat (limited to 'qpid/java/management/eclipse-plugin/src')
31 files changed, 1697 insertions, 574 deletions
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java index 38a4d4561f..714f84ea49 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java @@ -41,7 +41,9 @@ public abstract class ApplicationRegistry { private static ImageRegistry imageRegistry = new ImageRegistry(); private static FontRegistry fontRegistry = new FontRegistry(); - + public static final boolean debug = Boolean.getBoolean("debug"); + public static final String securityMechanism = System.getProperty("security", null); + static { imageRegistry.put(Constants.CONSOLE_IMAGE, @@ -130,4 +132,9 @@ public abstract class ApplicationRegistry _closedServerList.clear(); return list; } + + public static String getSecurityMechanism() + { + return securityMechanism; + } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java index 3d163fb111..e3aedef28e 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationWorkbenchWindowAdvisor.java @@ -49,7 +49,7 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); int x = Display.getDefault().getBounds().width; int y = Display.getDefault().getBounds().height; - configurer.setInitialSize(new Point(4*x/5, 3*y/4)); + configurer.setInitialSize(new Point(9*x/10, 8*y/10)); configurer.setShowCoolBar(true); configurer.setShowStatusLine(false); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java index 91dec841cf..da70dc736c 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java @@ -1,3 +1,4 @@ +/* Copyright Rupert Smith, 2005 to 2006, all rights reserved. */ /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -7,9 +8,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 @@ -29,98 +30,110 @@ import static org.apache.qpid.management.ui.Constants.CONNECTION_PROTOCOLS; */ public class Constants { - public final static String APPLICATION_NAME = "Qpid Management Console"; - - 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 NODE_TYPE_SERVER = "server"; - public final static String NODE_TYPE_DOMAIN = "domain"; - public final static String NODE_TYPE_MBEANTYPE = "mbeantype"; + public static final String APPLICATION_NAME = "Qpid Management Console"; + + public static final String ACTION_REMOVE_MBEANNODE = "Remove from list"; + public static final String VALUE = "value"; + public static final String TYPE = "type"; + public static final String NODE_TYPE_SERVER = "server"; + public static final String NODE_TYPE_DOMAIN = "domain"; + public static final 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"; - public final static String MBEAN = "mbean"; - public final static String ATTRIBUTE = "Attribute"; - public final static String ATTRIBUTES = "Attributes"; - public final static String NOTIFICATION = "Notifications"; - public final static String RESULT = "Result"; - public final static String VIRTUAL_HOST = "VirtualHost"; - public final static String DEFAULT_VH = "Default"; - public final static String DEFAULT_USERNAME = "guest"; - public final static String DEFAULT_PASSWORD = "guest"; - - public final static String USERNAME = "Username"; - public final static String PASSWORD = "Password"; - + public static final String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance"; + public static final String MBEAN = "mbean"; + public static final String ATTRIBUTE = "Attribute"; + public static final String ATTRIBUTES = "Attributes"; + public static final String NOTIFICATIONS = "Notifications"; + public static final String RESULT = "Result"; + public static final String VIRTUAL_HOST = "VirtualHost"; + public static final String DEFAULT_VH = "Default"; + public static final String DEFAULT_USERNAME = "guest"; + public static final String DEFAULT_PASSWORD = "guest"; + + public static final String USERNAME = "Username"; + public static final String PASSWORD = "Password"; + // Attributes and operations are used to customize the GUI for Qpid. If these are changes in the // Qpid server, then these should be updated accordingly - public final static String ATTRIBUTE_QUEUE_OWNER = "owner"; - public final static String ATTRIBUTE_QUEUE_DEPTH = "QueueDepth"; - public final static String ATTRIBUTE_QUEUE_CONSUMERCOUNT = "ActiveConsumerCount"; - public final static String OPERATION_CREATE_QUEUE = "createNewQueue"; - public final static String OPERATION_CREATE_BINDING = "createNewBinding"; - public final static String OPERATION_MOVE_MESSAGES = "moveMessages"; - - public final static String ALL = "All"; - - public final static String NAVIGATION_ROOT = "Qpid Connections"; - public final static String DESCRIPTION = " Description"; - - public final static String QUEUE = "Queue"; - 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", "topic", "headers"}; - 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 ATTRIBUTE_QUEUE_OWNER = "owner"; + public static final String ATTRIBUTE_QUEUE_DEPTH = "QueueDepth"; + public static final String ATTRIBUTE_QUEUE_CONSUMERCOUNT = "ActiveConsumerCount"; + public static final String OPERATION_CREATE_QUEUE = "createNewQueue"; + public static final String OPERATION_CREATE_BINDING = "createNewBinding"; + public static final String OPERATION_MOVE_MESSAGES = "moveMessages"; + + public static final String OPERATION_CREATEUSER = "createUser"; + public static final String OPERATION_VIEWUSERS = "viewUsers"; + public static final String OPERATION_PARAM_USERNAME = "username"; + + public static final String OPERATION_SUCCESSFUL = "Operation successful"; + public static final String OPERATION_UNSUCCESSFUL = "Operation unsuccessful"; + + public static final String ALL = "All"; + + public static final String NAVIGATION_ROOT = "Qpid Connections"; + public static final String DESCRIPTION = " Description"; + + public static final String ADMIN_MBEAN_TYPE = "UserManagement"; + public static final String QUEUE = "Queue"; + public static final String CONNECTION = "Connection"; + public static final String EXCHANGE = "Exchange"; + public static final String EXCHANGE_TYPE = "ExchangeType"; + public static final String[] EXCHANGE_TYPE_VALUES = { "direct", "fanout", "headers", "topic" }; + public static final String[] BOOLEAN_TYPE_VALUES = { "false", "true" }; + public static final 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"; - public final static String ACTION_LOGIN = "Login"; - - public final static String QUEUE_SORT_BY_NAME = "Queue Name"; - public final static String QUEUE_SORT_BY_DEPTH = "Queue Depth"; - public final static String QUEUE_SORT_BY_CONSUMERCOUNT = "Consumer Count"; - public final static String QUEUE_SHOW_TEMP_QUEUES= "show temporary queues"; - - 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 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 FONT_BUTTON = "ButtonFont"; - public final static String FONT_BOLD = "BoldFont"; - public final static String FONT_ITALIC = "ItalicFont"; - public final static String FONT_TABLE_CELL = "TableCellFont"; - 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_REFRESH = "Refresh"; - public final static String BUTTON_GRAPH = "Graph"; - public final static int TIMER_INTERVAL = 5000; - public final static String BUTTON_EXECUTE = "Execute"; - public final static String BUTTON_CLEAR = "Clear"; - public final static String BUTTON_CONNECT = "Connect"; - public final static String BUTTON_CANCEL = "Cancel"; - public final static String BUTTON_UPDATE = "Update"; - - - public final static int OPERATION_IMPACT_INFO = 0; - public final static int OPERATION_IMPACT_ACTION = 1; - public final static int OPERATION_IMPACT_ACTIONINFO = 2; - public final static int OPERATION_IMPACT_UNKNOWN = 3; - - public final static String ERROR_SERVER_CONNECTION = "Server could not be connected"; - public final static String INFO_PROTOCOL = "Please select the protocol"; - public final static String INFO_HOST_ADDRESS = "Please enter the host address"; - public final static String INFO_HOST_PORT = "Please enter the port number"; - public final static String INFO_USERNAME = "Please enter the " + USERNAME; - public final static String INFO_PASSWORD = "Please enter the " + PASSWORD; + + public static final String ACTION_ADDSERVER = "New Connection"; + public static final String ACTION_RECONNECT = "Reconnect"; + public static final String ACTION_LOGIN = "Login"; + + public static final String QUEUE_SORT_BY_NAME = "Queue Name"; + public static final String QUEUE_SORT_BY_DEPTH = "Queue Depth"; + public static final String QUEUE_SORT_BY_CONSUMERCOUNT = "Consumer Count"; + public static final String QUEUE_SHOW_TEMP_QUEUES = "show temporary queues"; + + public static final String SUBSCRIBE_BUTTON = "Subscribe"; + public static final String UNSUBSCRIBE_BUTTON = "Unsubscribe"; + + public static final String CONSOLE_IMAGE = "ConsoelImage"; + public static final String CLOSED_FOLDER_IMAGE = "ClosedFolderImage"; + public static final String OPEN_FOLDER_IMAGE = "OpenFolderImage"; + public static final String MBEAN_IMAGE = "MBeanImage"; + public static final String NOTIFICATION_IMAGE = "NotificationImage"; + + public static final String FONT_BUTTON = "ButtonFont"; + public static final String FONT_BOLD = "BoldFont"; + public static final String FONT_ITALIC = "ItalicFont"; + public static final String FONT_TABLE_CELL = "TableCellFont"; + public static final String FONT_NORMAL = "Normal"; + + public static final String BUTTON_DETAILS = "Details"; + public static final String BUTTON_EDIT_ATTRIBUTE = "Edit Attribute"; + public static final String BUTTON_REFRESH = "Refresh"; + public static final String BUTTON_GRAPH = "Graph"; + public static final int TIMER_INTERVAL = 5000; + public static final String BUTTON_EXECUTE = "Execute"; + public static final String BUTTON_CLEAR = "Clear"; + public static final String BUTTON_CONNECT = "Connect"; + public static final String BUTTON_CANCEL = "Cancel"; + public static final String BUTTON_UPDATE = "Update"; + + public static final int OPERATION_IMPACT_INFO = 0; + public static final int OPERATION_IMPACT_ACTION = 1; + public static final int OPERATION_IMPACT_ACTIONINFO = 2; + public static final int OPERATION_IMPACT_UNKNOWN = 3; + + public static final String ERROR_SERVER_CONNECTION = "Server could not be connected"; + public static final String INFO_PROTOCOL = "Please select the protocol"; + public static final String INFO_HOST_ADDRESS = "Please enter the host address"; + public static final String INFO_HOST_PORT = "Please enter the port number"; + public static final String INFO_USERNAME = "Please enter the " + USERNAME; + public static final String INFO_PASSWORD = "Please enter the " + PASSWORD; + + public static final String MECH_CRAMMD5 = "CRAM-MD5"; + public static final String MECH_PLAIN = "PLAIN"; + public static final String SASL_CRAMMD5 = "SASL/CRAM-MD5"; + public static final String SASL_PLAIN = "SASL/PLAIN"; } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java index 38c3e8f413..31825e925d 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.management.ui; +import static org.apache.qpid.management.ui.Constants.*; import java.util.HashMap; /** @@ -50,7 +51,7 @@ public abstract class ManagedBean extends ManagedObject this._properties = properties; setName(getProperty("name")); setType(getProperty("type")); - _virtualHostName = getProperty(Constants.VIRTUAL_HOST); + _virtualHostName = getProperty(VIRTUAL_HOST); } public String getDomain() { @@ -89,7 +90,7 @@ public abstract class ManagedBean extends ManagedObject public String getVirtualHostName() { // To make it work with the broker with no virtual host implementation - return _virtualHostName == null ? Constants.DEFAULT_VH : _virtualHostName; + return _virtualHostName == null ? DEFAULT_VH : _virtualHostName; } /** @@ -106,21 +107,26 @@ public abstract class ManagedBean extends ManagedObject public boolean isQueue() { - return _type.endsWith(Constants.QUEUE); + return _type.endsWith(QUEUE); } public boolean isConnection() { - return _type.endsWith(Constants.CONNECTION); + return _type.endsWith(CONNECTION); } public boolean isExchange() { - return _type.endsWith(Constants.EXCHANGE); + return _type.endsWith(EXCHANGE); } public boolean isTempQueue() { return (isQueue() && getName().startsWith("tmp_")); } + + public boolean isAdmin() + { + return _type.endsWith(ADMIN_MBEAN_TYPE); + } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java index da49d70b88..f93200cadf 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Perspective.java @@ -37,8 +37,8 @@ public class Perspective implements IPerspectiveFactory layout.setEditorAreaVisible(false); // standalone view meaning it can't be docked or stacked with other views, and it doesn't have a title bar. - layout.addStandaloneView(NavigationView.ID, true, IPageLayout.LEFT, 0.25f, editorArea); - layout.addStandaloneView(MBeanView.ID, true, IPageLayout.RIGHT, 0.75f, editorArea); + layout.addStandaloneView(NavigationView.ID, true, IPageLayout.LEFT, 0.30f, editorArea); + layout.addStandaloneView(MBeanView.ID, true, IPageLayout.RIGHT, 0.70f, editorArea); layout.getViewLayout(NavigationView.ID).setCloseable(false); layout.getViewLayout(MBeanView.ID).setCloseable(false); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java index fa71ee9bc7..313e143df5 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ServerRegistry.java @@ -128,6 +128,10 @@ public abstract class ServerRegistry return _virtualHosts; } + public abstract void setUserList(List<String> list); + + public abstract List<String> getUsernames(); + public abstract void addManagedObject(ManagedBean key); public abstract List<ManagedBean> getMBeans(); @@ -154,7 +158,7 @@ public abstract class ServerRegistry public abstract boolean hasSubscribedForNotifications(ManagedBean mbean, String name, String type); - public abstract void clearNotifications(ManagedBean mbean); + public abstract void clearNotifications(ManagedBean mbean, List<NotificationObject> list); public ClientListener getNotificationListener() { diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java index 5a926e6474..0e12c59de4 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java @@ -194,9 +194,6 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg } } - //If you create it, you dispose it. - shell.dispose(); - // enable the main shell _window.getShell().setEnabled(true); _window.getShell().open(); @@ -263,7 +260,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); final Text textUser = new Text(composite, SWT.BORDER); - textUser.setText(DEFAULT_USERNAME); + textUser.setText(""); textUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Label password = new Label(composite, SWT.NONE); @@ -271,7 +268,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg password.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); final Text textPwd = new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD); - textPwd.setText(DEFAULT_PASSWORD); + textPwd.setText(""); //textPwd.setEchoChar('*'); textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); @@ -327,11 +324,7 @@ public class AddServer/* extends Action*/ implements IWorkbenchWindowActionDeleg _domain = comboDomain.getText(); _addServer = true; - - if (!connectButton.getShell().isDisposed()) - { - connectButton.getShell().dispose(); - } + shell.dispose(); } }); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java index 8fe08462cd..9aa265ab3c 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java @@ -168,9 +168,6 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate } } - //If you create it, you dispose it. - shell.dispose(); - // enable the main shell _window.getShell().setEnabled(true); _window.getShell().open(); @@ -194,7 +191,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); final Text textUser = new Text(composite, SWT.BORDER); - textUser.setText(DEFAULT_USERNAME); + textUser.setText(""); textUser.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); // Put cursor on this field textUser.setFocus(); @@ -204,7 +201,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate password.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false)); final Text textPwd = new Text(composite, SWT.BORDER | SWT.SINGLE | SWT.PASSWORD); - textPwd.setText(DEFAULT_PASSWORD); + textPwd.setText(""); textPwd.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Composite buttonsComposite = new Composite(composite, SWT.NONE); @@ -240,11 +237,7 @@ public class ReconnectServer implements IWorkbenchWindowActionDelegate } _connect = true; - - if (!connectButton.getShell().isDisposed()) - { - connectButton.getShell().dispose(); - } + shell.dispose(); } }); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java index 82447d645e..2be0ddbebf 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java @@ -45,10 +45,7 @@ public class ClientListener implements NotificationListener { ObjectName objName = null; String type = notification.getType(); - if (MBeanUtility.isDebug()) - { - System.out.println(type + ":" + objName); - } + MBeanUtility.printOutput(type + ":" + objName); if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) { diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java index b0f9928c38..816c479cf9 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java @@ -20,6 +20,10 @@ */ package org.apache.qpid.management.ui.jmx; +import static org.apache.qpid.management.ui.Constants.*; + +import java.lang.reflect.Constructor; +import java.security.Security; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -35,8 +39,9 @@ import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; +import javax.security.sasl.SaslClientFactory; -import org.apache.qpid.management.ui.Constants; +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; @@ -44,6 +49,10 @@ 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 @@ -52,11 +61,12 @@ public class JMXServerRegistry extends ServerRegistry private JMXConnector _jmxc = null; private MBeanServerConnection _mbsc = null; + private List<String> _usersList; // When an mbean gets removed from mbean server, then the notification listener // will add that mbean in this list. private List<ManagedBean> _mbeansToBeRemoved = new ArrayList<ManagedBean>(); - // Map containing all managed beans and ampped with unique mbean name + // Map containing all managed beans and mapped with unique mbean name private HashMap<String, ManagedBean> _mbeansMap = new HashMap<String, ManagedBean>(); // Map containing MBeanInfo for all mbeans and mapped with unique mbean name private HashMap<String, MBeanInfo> _mbeanInfoMap = new HashMap<String, MBeanInfo>(); @@ -83,11 +93,69 @@ public class JMXServerRegistry extends ServerRegistry { super(server); JMXServiceURL jmxUrl = new JMXServiceURL(server.getUrl()); - Map<String, Object> env = new HashMap<String, Object>(); - String[] creds = {server.getUser(), server.getPassword()}; - env.put(JMXConnector.CREDENTIALS, creds); - - _jmxc = JMXConnectorFactory.connect(jmxUrl, env); + Map<String, Object> env = null; + String securityMechanism = ApplicationRegistry.getSecurityMechanism(); + + if (securityMechanism != null) + { + try + { + // Check if the JMXMP connector is available + Class klass = Class.forName("javax.management.remote.jmxmp.JMXMPConnector"); + + jmxUrl = new JMXServiceURL("jmxmp", server.getHost(), server.getPort()); + env = new HashMap<String, Object>(); + + if (MECH_CRAMMD5.equals(securityMechanism)) + { + // 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)); + env.put("jmx.remote.profiles", SASL_CRAMMD5); + env.put("jmx.remote.sasl.callback.handler", + new UsernameHashedPasswordCallbackHandler(server.getUser(), server.getPassword())); + } + else if (MECH_PLAIN.equals(securityMechanism)) + { + // For SASL/PLAIN + Security.addProvider(new SaslProvider()); + env.put("jmx.remote.profiles", SASL_PLAIN); + env.put("jmx.remote.sasl.callback.handler", + new UserPasswordCallbackHandler(server.getUser(), server.getPassword())); + } + else + { + MBeanUtility.printOutput("Security mechanism " + securityMechanism + " is not supported."); + } + + // Now create the instance of JMXMPConnector + Class[] paramTypes = {JMXServiceURL.class, Map.class}; + Constructor cons = klass.getConstructor(paramTypes); + + Object[] args = {jmxUrl, env}; + Object theObject = cons.newInstance(args); + + _jmxc = (JMXConnector)theObject; + _jmxc.connect(); + MBeanUtility.printOutput("Starting JMXConnector with SASL. Server=" + server.getName()); + } + catch (Exception ex) + { + // When JMXMPConnector is not available + MBeanUtility.printOutput("Starting JMXConnector. Server=" + server.getName()); + jmxUrl = new JMXServiceURL(server.getUrl()); + _jmxc = JMXConnectorFactory.connect(jmxUrl, null); + } + } + else + { + jmxUrl = new JMXServiceURL(server.getUrl()); + _jmxc = JMXConnectorFactory.connect(jmxUrl, null); + } + _mbsc = _jmxc.getMBeanServerConnection(); _clientListener = new ClientListener(server); @@ -155,10 +223,7 @@ public class JMXServerRegistry extends ServerRegistry public void removeManagedObject(ManagedBean mbean) { - if (MBeanUtility.isDebug()) - { - System.out.println("Removing MBean:" + mbean.getUniqueName()); - } + MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName()); if (mbean.isQueue()) { @@ -218,17 +283,78 @@ public class JMXServerRegistry extends ServerRegistry list.add(obj); } + /** + * Returns all the notification objects for a given mbean. If mbean is null, it returns + * notification objects for all the mbeans. + */ public List<NotificationObject> getNotifications(ManagedBean mbean) { - return _notificationsMap.get(mbean.getUniqueName()); + if (mbean == null) + { + List<NotificationObject> totalList = new ArrayList<NotificationObject>(); + for (List<NotificationObject> list : _notificationsMap.values()) + { + totalList.addAll(list); + } + return totalList; + } + else + { + return _notificationsMap.get(mbean.getUniqueName()); + } } - public void clearNotifications(ManagedBean mbean) + public void clearNotifications(ManagedBean mbean, List<NotificationObject> list) { - if (_notificationsMap.containsKey(mbean.getUniqueName())) - _notificationsMap.get(mbean.getUniqueName()).clear(); + if (mbean == null) + { + if (list == null || list.isEmpty()) + { + // All notifications of all mbeans to be cleared + _notificationsMap.clear(); + } + else + { + // Clear the selected notifications + for (NotificationObject obj : list) + { + mbean = _mbeansMap.get(obj.getSource().toString()); + List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName()); + if (nList != null && !nList.isEmpty()) + { + nList.remove(obj); + } + } + } + } + else + { + if (list == null || list.isEmpty()) + { + // All notifications of this mbean to be cleared + List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName()); + if (nList != null && !nList.isEmpty()) + { + nList.clear(); + } + } + else + { + // Clear the selected notifications + for (NotificationObject obj : list) + { + List<NotificationObject> nList = _notificationsMap.get(mbean.getUniqueName()); + if (nList != null && !nList.isEmpty()) + { + nList.remove(obj); + } + } + } + } } + + /** * Adds notification name and type to the map. The map contains all the notification names, * subscribed for an mbean. @@ -254,7 +380,7 @@ public class JMXServerRegistry extends ServerRegistry map.put(name, list); } // Now add the notification type to the list - if (Constants.ALL.equals(type)) + if (ALL.equals(type)) { List<NotificationInfoModel> infoList = _notificationInfoMap.get(mbean.getUniqueName()); for (NotificationInfoModel model : infoList) @@ -313,7 +439,7 @@ public class JMXServerRegistry extends ServerRegistry HashMap<String, List<String>> map = _subscribedNotificationMap.get(mbean.getUniqueName()); if (map.containsKey(name)) { - if (Constants.ALL.equals(type)) + if (ALL.equals(type)) { map.remove(name); } @@ -441,6 +567,16 @@ public class JMXServerRegistry extends ServerRegistry } return connections; } + + public void setUserList(List<String> list) + { + _usersList = list; + } + + public List<String> getUsernames() + { + return _usersList; + } public ClientNotificationListener getNotificationListener() { diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java index 5ceeb879b4..41db11c10e 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java @@ -60,13 +60,6 @@ import org.apache.qpid.management.ui.views.ViewUtility; */ public class MBeanUtility { - private static boolean _debug; - static - { - String debug = System.getProperty("debug"); - _debug = "true".equalsIgnoreCase(debug) ? true : false; - } - public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE); /** @@ -149,27 +142,27 @@ public class MBeanUtility * @param mbean managed bean * @param ex Exception */ - public static void handleException(ManagedBean mbean, Exception ex) + public static void handleException(ManagedBean mbean, Throwable ex) { if (mbean == null) { ViewUtility.popupErrorMessage("Error", "Managed Object is null \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof IOException) { ViewUtility.popupErrorMessage(mbean.getInstanceName(), "IO Error occured \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof ReflectionException) { ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Server has thrown error \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof InstanceNotFoundException) { ViewUtility.popupErrorMessage(mbean.getInstanceName(), "Managed Object Not Found \n" + ex.toString()); - ex.printStackTrace(); + printStackTrace(ex); } else if (ex instanceof MBeanException) { @@ -188,8 +181,20 @@ public class MBeanUtility } else { - ViewUtility.popupErrorMessage(mbean.getInstanceName(), ex.getMessage()); - ex.printStackTrace(); + if (ex.getCause() != null) + { + handleException(mbean, ex.getCause()); + } + else + { + String msg = ex.getMessage(); + if (msg == null) + { + msg = ex.toString(); + } + ViewUtility.popupErrorMessage(mbean.getInstanceName(), msg); + printStackTrace(ex); + } } } @@ -449,12 +454,19 @@ public class MBeanUtility return Arrays.asList(domains); } - /** - * return true if System property is set to true -Ddebug=true - * @return - */ - public static boolean isDebug() + public static void printOutput(String statement) { - return _debug; + if (ApplicationRegistry.debug) + { + System.out.println(statement); + } + } + + private static void printStackTrace(Throwable ex) + { + if (ApplicationRegistry.debug) + { + ex.printStackTrace(); + } } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java index 8ba74b3ce8..926e5f0a24 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java @@ -24,10 +24,12 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; +import javax.management.ObjectName; + public class NotificationObject { - private long _sequenceNo; + private long _sequenceNo; private Date _timeStamp; private String _message; private Object _source; @@ -52,6 +54,17 @@ public class NotificationObject { this._source = _source; } + + public String getSourceName() + { + if (_source instanceof ObjectName) + { + return ((ObjectName)_source).getKeyProperty("name"); + } + + return null; + } + public String getMessage() { return _message; diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java index 9b6750c21a..2b83645942 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/OperationData.java @@ -80,5 +80,13 @@ public class OperationData this._returnType = returnType; } + public boolean isReturnTypeBoolean() + { + return (_returnType.equals("boolean") || _returnType.equals("java.lang.Boolean")); + } + public boolean isReturnTypeVoid() + { + return (_returnType.equals("void") || _returnType.equals("java.lang.Void")); + } }
\ No newline at end of file diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java new file mode 100644 index 0000000000..32a0c12344 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/CRAMMD5HashedSaslClientFactory.java @@ -0,0 +1,60 @@ +/* + * + * 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/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java new file mode 100644 index 0000000000..ce9a273eaa --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/ClientSaslFactory.java @@ -0,0 +1,54 @@ +/* + * + * 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/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java new file mode 100644 index 0000000000..d8189f3ac3 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/JCAProvider.java @@ -0,0 +1,56 @@ +/* + * + * 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/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java new file mode 100644 index 0000000000..22190f29eb --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/PlainSaslClient.java @@ -0,0 +1,203 @@ +/* + * + * 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/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java new file mode 100644 index 0000000000..2917de8740 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/SaslProvider.java @@ -0,0 +1,35 @@ +/* + * + * 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; + +public class SaslProvider extends Provider +{ + private static final long serialVersionUID = -6978096016899676466L; + + public SaslProvider() + { + super("SaslClientFactory", 1.0, "SASL PLAIN CLIENT MECHANISM"); + put("SaslClientFactory.PLAIN", "ClientSaslFactory"); + } + +} diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java new file mode 100644 index 0000000000..1602229c85 --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UserPasswordCallbackHandler.java @@ -0,0 +1,73 @@ +/* + * 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/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java new file mode 100644 index 0000000000..f4e3d2661e --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/sasl/UsernameHashedPasswordCallbackHandler.java @@ -0,0 +1,82 @@ +/* + * + * 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/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java index 437afeeda1..a7e8bbfc4c 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/AttributesTabControl.java @@ -596,7 +596,7 @@ public class AttributesTabControl extends TabControl } // Refresh from the server registry - private void refresh() + public void refresh() { JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(_mbean); ManagedAttributeModel attributesList = serverRegistry.getAttributeModel(_mbean); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java index 59b9fe3aaa..344c3c4e7f 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java @@ -62,6 +62,7 @@ public class MBeanView extends ViewPart private FormToolkit _toolkit = null; private Form _form = null; + private String _formText = APPLICATION_NAME; private static ManagedServer _server = null; private TreeObject _selectedNode = null; private ManagedBean _mbean = null; @@ -73,6 +74,8 @@ public class MBeanView extends ViewPart // TabFolder to list all the mbeans for a given mbeantype(eg Connection, Queue, Exchange) private TabFolder typeTabFolder = null; + + private TabFolder notificationTabFolder = null; /* * Listener for the selection events in the navigation view */ @@ -91,16 +94,41 @@ public class MBeanView extends ViewPart // an mbeantype. For mbeantype selection(eg Connection, Queue, Exchange) _mbean will remain null. _mbean = null; setInvisible(); - _form.setText(APPLICATION_NAME); - // If a selected node(mbean) gets unregistered from mbena server, mbenaview should should + // If a selected node(mbean) gets unregistered from mbean server, mbeanview should // make the tabfolber for that mbean invisible if (_selectedNode == null) return; setServer(); refreshMBeanView(); + setFormTitle(); + } + } + + private void setFormTitle() + { + if (_mbean != null) + { + _formText = _mbean.getType(); + if ((_mbean.getVirtualHostName() != null) && (!DEFAULT_VH.equals(_mbean.getVirtualHostName())) ) + { + _formText = _formText.replaceFirst(VIRTUAL_HOST, _mbean.getVirtualHostName()); + if (_mbean.getName() != null && _mbean.getName().length() != 0) + { + _formText = _formText + ": " + _mbean.getName(); + } + } + } + else if ((_selectedNode.getVirtualHost() != null) && (!DEFAULT_VH.equals(_selectedNode.getVirtualHost()))) + { + _formText = _selectedNode.getVirtualHost(); } + else + { + _formText = APPLICATION_NAME; + } + _form.setText(_formText); } public void refreshMBeanView() @@ -121,10 +149,16 @@ public class MBeanView extends ViewPart { refreshTypeTabFolder(_selectedNode.getName()); } - else + else if (NOTIFICATIONS.equals(_selectedNode.getType())) + { + refreshNotificationPage(); + } + else if (MBEAN.equals(_selectedNode.getType())) { + _mbean = (ManagedBean)_selectedNode.getManagedObject(); showSelectedMBean(); } + _form.layout(true); _form.getBody().layout(true, true); } @@ -174,20 +208,7 @@ public class MBeanView extends ViewPart } private void showSelectedMBean() throws Exception - { - if (NOTIFICATION.equals(_selectedNode.getType())) - { - _mbean = (ManagedBean)_selectedNode.getParent().getManagedObject(); - } - else if (MBEAN.equals(_selectedNode.getType())) - { - _mbean = (ManagedBean)_selectedNode.getManagedObject(); - } - else - { - return; - } - + { try { MBeanUtility.getMBeanInfo(_mbean); @@ -213,14 +234,8 @@ public class MBeanView extends ViewPart tabFolder = createMBeanTabFolder(); } - String text = _mbean.getType(); - if (_mbean.getName() != null && _mbean.getName().length() != 0) - { - text = text + ": " + _mbean.getName(); - } - _form.setText(text); int tabIndex = 0; - if (NOTIFICATION.equals(_selectedNode.getType())) + if (NOTIFICATIONS.equals(_selectedNode.getType())) { tabIndex = tabFolder.getItemCount() -1; } @@ -247,6 +262,8 @@ public class MBeanView extends ViewPart // 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(); + + createNotificationsTabFolder(); } private TabFolder createMBeanTabFolder() @@ -345,7 +362,7 @@ public class MBeanView extends ViewPart NotificationsTabControl controller = new NotificationsTabControl(tabFolder); TabItem tab = new TabItem(tabFolder, SWT.NONE); - tab.setText(NOTIFICATION); + tab.setText(NOTIFICATIONS); tab.setData(CONTROLLER, controller); tab.setControl(controller.getControl()); } @@ -432,6 +449,32 @@ public class MBeanView extends ViewPart }); } + private void createNotificationsTabFolder() + { + 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); + + VHNotificationsTabControl controller = new VHNotificationsTabControl(notificationTabFolder); + TabItem tab = new TabItem(notificationTabFolder, SWT.NONE); + tab.setText(NOTIFICATIONS); + tab.setData(CONTROLLER, controller); + tab.setControl(controller.getControl()); + } + + private void refreshNotificationPage() + { + TabItem tab = notificationTabFolder.getItem(0); + VHNotificationsTabControl controller = (VHNotificationsTabControl)tab.getData(CONTROLLER); + controller.refresh(); + notificationTabFolder.setVisible(true); + } + /** * Refreshes the Selected mbeantype tab. The control lists all the available mbeans * for an mbeantype(eg Queue, Exchange etc) @@ -492,6 +535,11 @@ public class MBeanView extends ViewPart { typeTabFolder.setVisible(false); } + + if (notificationTabFolder != null) + { + notificationTabFolder.setVisible(false); + } } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java index a861405d30..68f95e01f0 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java @@ -244,7 +244,8 @@ public class NavigationView extends ViewPart List<TreeObject> list = _serversRootNode.getChildren(); for (TreeObject node : list) { - if (url.equals(node.getUrl())) + 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. @@ -266,7 +267,6 @@ public class NavigationView extends ViewPart // Server connection is successful. Now add the server in the tree TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER); - serverNode.setUrl(url); serverNode.setManagedObject(managedServer); _serversRootNode.addChild(serverNode); @@ -504,6 +504,11 @@ public class NavigationView extends ViewPart typeChild = new TreeObject(QUEUE, NODE_TYPE_MBEANTYPE); typeChild.setParent(parent); typeChild.setVirtualHost(parent.getVirtualHost()); + + // Add common notification node for virtual host + TreeObject notificationNode = new TreeObject(NOTIFICATIONS, NOTIFICATIONS); + notificationNode.setParent(parent); + notificationNode.setVirtualHost(parent.getVirtualHost()); } /** @@ -585,7 +590,10 @@ public class NavigationView extends ViewPart // create a node for "type" typeNode = createTypeNode(parentNode, type); - typeNode.setVirtualHost(mbean.getVirtualHostName()); + if (!type.equals(VIRTUAL_HOST)) + { + typeNode.setVirtualHost(mbean.getVirtualHostName()); + } } // now type node create becomes the parent node for next node in hierarchy @@ -641,8 +649,8 @@ public class NavigationView extends ViewPart // Add notification node // TODO: show this only if the mbean sends any notification - TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION); - notificationNode.setParent(mbeanNode); + //TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION); + //notificationNode.setParent(mbeanNode); } private TreeObject createTypeNode(TreeObject parent, String name) @@ -1044,7 +1052,7 @@ public class NavigationView extends ViewPart public Image getImage(Object element) { TreeObject node = (TreeObject) element; - if (node.getType().equals(NOTIFICATION)) + if (node.getType().equals(NOTIFICATIONS)) { return ApplicationRegistry.getImage(NOTIFICATION_IMAGE); } @@ -1107,8 +1115,11 @@ public class NavigationView extends ViewPart { return 1; } - - return 2; + if (node.getType().equals(NOTIFICATIONS)) + { + return 2; + } + return 3; } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java index 4f0acde1b4..6894080859 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NotificationsTabControl.java @@ -20,29 +20,28 @@ */ package org.apache.qpid.management.ui.views; -import java.util.ArrayList; +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; +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.List; -import static org.apache.qpid.management.ui.Constants.*; 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.ui.jmx.MBeanUtility; import org.apache.qpid.management.ui.model.NotificationInfoModel; 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.IStructuredContentProvider; -import org.eclipse.jface.viewers.ITableLabelProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; @@ -52,71 +51,35 @@ 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; 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.Form; -import org.eclipse.ui.forms.widgets.FormToolkit; /** * Creates control composite for Notifications tab * @author Bhupendra Bhardwaj */ -public class NotificationsTabControl extends TabControl -{ - private FormToolkit _toolkit; - private Form _form; - private Table table = null; - private TableViewer _tableViewer = null; - - private IStructuredContentProvider contentProvider = new ContentProviderImpl(); - private SelectionListener selectionListener = new SelectionListenerImpl(); - private SelectionListener comboListener = new ComboSelectionListener(); - - private Thread worker = null; - - private List<NotificationObject> _notifications = null; - private static final String COLUMN_SEQ = "Sequence No"; - private static final String COLUMN_TIME = "TimeStamp"; - private static final String COLUMN_TYPE = "Type"; - private static final String COLUMN_MSG = "Notification Message"; - private static final String[] _tableTitles = new String [] { - COLUMN_SEQ, - COLUMN_TIME, - COLUMN_TYPE, - COLUMN_MSG - }; +public class NotificationsTabControl extends VHNotificationsTabControl +{ + private static final String SELECT_NOTIFICATIONNAME = "Select Notification"; + private static final String SELECT_NOTIFICATIONTYPE = "Select Type"; + 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 Button _clearButton = null; - private Button _refreshButton = null; - public NotificationsTabControl(TabFolder tabFolder) { super(tabFolder); - _toolkit = new FormToolkit(_tabFolder.getDisplay()); - _form = _toolkit.createForm(_tabFolder); - GridLayout gridLayout = new GridLayout(); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - _form.getBody().setLayout(gridLayout); - - createWidgets(); - worker = new Thread(new Worker()); - worker.start(); } - private void createWidgets() + protected void createWidgets() { + selectionListener = new SelectionListenerImpl(); + comboListener = new ComboSelectionListener(); createNotificationInfoComposite(); //addFilterComposite(); addButtons(); @@ -124,14 +87,6 @@ public class NotificationsTabControl extends TabControl } /** - * @see TabControl#getControl() - */ - public Control getControl() - { - return _form; - } - - /** * Creates composite and populates for displaying Notification Information (name, type, description) * and creates buttons for subscribing or unsubscribing for notifications */ @@ -205,7 +160,7 @@ public class NotificationsTabControl extends TabControl /** * Creates clear buttin and refresh button */ - private void addButtons() + protected void addButtons() { Composite composite = _toolkit.createComposite(_form.getBody(), SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); @@ -224,8 +179,9 @@ public class NotificationsTabControl extends TabControl if (_mbean == null) return; + IStructuredSelection ss = (IStructuredSelection)_tableViewer.getSelection(); ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); - serverRegistry.clearNotifications(_mbean); + serverRegistry.clearNotifications(_mbean, ss.toList()); refresh(); } }); @@ -247,155 +203,13 @@ public class NotificationsTabControl extends TabControl } }); } - - /** - * Creates table to display notifications - */ - private void createTable() - { - table = _toolkit.createTable(_form.getBody(), SWT.FULL_SELECTION); - table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - TableColumn column = new TableColumn(table, SWT.NONE); - column.setText(_tableTitles[0]); - column.pack(); //column.setWidth(200); - - column = new TableColumn(table, SWT.NONE); - column.setText(_tableTitles[1]); - column.setWidth(150); - - column = new TableColumn(table, SWT.NONE); - column.setText(_tableTitles[2]); - column.setWidth(100); - - column = new TableColumn(table, SWT.NONE); - column.setText(_tableTitles[3]); - column.setWidth(500); - - table.setHeaderVisible(true); - table.setLinesVisible(true); - } - - /** - * Creates JFace viewer for the notifications table - */ - protected void createTableViewer() - { - createTable(); - _tableViewer = new TableViewer(table); - //_tableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - _tableViewer.setUseHashlookup(true); - _tableViewer.setContentProvider(contentProvider); - _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(); - } - - /** - * Adds listeners to the viewer for displaying notification details - */ - private void addTableListeners() - { - _tableViewer.addDoubleClickListener(new IDoubleClickListener() - { - Display display = null; - Shell shell = null; - public void doubleClick(DoubleClickEvent event) - { - display = Display.getCurrent(); - shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | - SWT.MAX | SWT.RESIZE); - shell.setText("Notification"); - - int x = display.getBounds().width; - int y = display.getBounds().height; - shell.setBounds(x/4, y/4, x/2, y/3); - StructuredSelection selection = (StructuredSelection)event.getSelection(); - createPopupContents((NotificationObject)selection.getFirstElement()); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - //If you create it, you dispose it. - shell.dispose(); - } - - private void createPopupContents(NotificationObject obj) - { - shell.setLayout(new GridLayout()); - - Composite parent = new Composite(shell, SWT.NONE); - parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - GridLayout layout = new GridLayout(4, true); - parent.setLayout(layout); - - Label key = new Label(parent, SWT.TRAIL); - key.setText(COLUMN_SEQ); - GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1); - key.setLayoutData(layoutData); - Text value = new Text(parent, SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); - value.setText(""+obj.getSequenceNo()); - value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); - - // Time row - key = new Label(parent, SWT.TRAIL); - key.setText(COLUMN_TIME); - key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); - value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); - value.setText(""+obj.getTimeStamp()); - value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); - - key = new Label(parent, SWT.TRAIL); - key.setText(COLUMN_TYPE); - key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); - value = new Text(parent, SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); - value.setText(""+obj.getType()); - value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); - - key = new Label(parent, SWT.TRAIL); - key.setText(COLUMN_MSG); - key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); - value = new Text(parent, SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); - value.setText(""+obj.getMessage()); - GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); - gridData.heightHint = 100; - value.setLayoutData(gridData); - } - }); - } - + @Override public void refresh(ManagedBean mbean) { _mbean = mbean; _notifications = null; + _table.deselectAll(); _tableViewer.getTable().clearAll(); if (_mbean == null) @@ -431,9 +245,10 @@ public class NotificationsTabControl extends TabControl _form.getBody().layout(true, true); } - private void refresh() + public void refresh() { _notifications = null; + _table.deselectAll(); _tableViewer.getTable().clearAll(); } @@ -444,7 +259,11 @@ public class NotificationsTabControl extends TabControl { notificationNameCombo.removeAll(); NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean); - notificationNameCombo.add("Select Notification"); + if (items.length > 1) + { + notificationNameCombo.add(SELECT_NOTIFICATIONNAME); + } + for (int i = 0; i < items.length; i++) { notificationNameCombo.add(items[i].getName()); @@ -457,6 +276,7 @@ public class NotificationsTabControl extends TabControl typesCombo.select(0); typesCombo.setEnabled(false); + populateNotificationType(notificationNameCombo.getItem(0)); checkForEnablingButtons(); } @@ -466,7 +286,8 @@ public class NotificationsTabControl extends TabControl private void checkForEnablingButtons() { int nameIndex = notificationNameCombo.getSelectionIndex(); - if (nameIndex == 0) + int itemCount = notificationNameCombo.getItems().length; + if ((itemCount > 1) && (nameIndex == 0)) { _subscribeButton.setEnabled(false); _unsubscribeButton.setEnabled(false); @@ -475,7 +296,8 @@ public class NotificationsTabControl extends TabControl } int typeIndex = typesCombo.getSelectionIndex(); - if (typeIndex == 0) + itemCount = typesCombo.getItems().length; + if ((itemCount > 1) && (typeIndex == 0)) { _subscribeButton.setEnabled(false); _unsubscribeButton.setEnabled(false); @@ -560,164 +382,38 @@ public class NotificationsTabControl extends TabControl Combo combo = (Combo)e.getSource(); if (combo == notificationNameCombo) { - if (combo.getSelectionIndex() == 0) - { - descriptionLabel.setText(""); - typesCombo.select(0); - typesCombo.setEnabled(false); - return; - } - String index = combo.getItem(combo.getSelectionIndex()); - NotificationInfoModel data = (NotificationInfoModel)combo.getData(index); - descriptionLabel.setText(data.getDescription()); - typesCombo.removeAll(); - typesCombo.setItems(data.getTypes()); - typesCombo.add("Select Type", 0); - typesCombo.select(0); - typesCombo.setEnabled(true); + String selectedItem = combo.getItem(combo.getSelectionIndex()); + populateNotificationType(selectedItem); } checkForEnablingButtons(); } } - /** - * Content provider class for the table viewer - */ - private class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer + private void populateNotificationType(String notificationName) { - public void inputChanged(Viewer v, Object oldInput, Object newInput) + NotificationInfoModel data = (NotificationInfoModel)notificationNameCombo.getData(notificationName); + if (data == null) { - - } - public void dispose() - { - - } - public Object[] getElements(Object parent) - { - return _notifications.toArray(new NotificationObject[0]); - } - public void addNotification(NotificationObject notification) - { - _tableViewer.add(notification); - } - - public void addNotification(List<NotificationObject> notificationList) - { - _tableViewer.add(notificationList.toArray(new NotificationObject[0])); - } - } - - /** - * Label provider for the table viewer - */ - private class LabelProviderImpl implements ITableLabelProvider - { - List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>(); - public void addListener(ILabelProviderListener listener) - { - listeners.add(listener); - } - - public void dispose(){ - - } - - public Image getColumnImage(Object element, int columnIndex) - { - return null; - } - - public String getColumnText(Object element, int columnIndex) - { - String result = null; - NotificationObject t = (NotificationObject)element; - switch(columnIndex) - { - case 0 : - result = String.valueOf(t.getSequenceNo()); - break; - case 1 : - result = String.valueOf(t.getTimeStamp()); - break; - case 2 : - result = t.getType(); - break; - case 3 : - result = t.getMessage(); - break; - default : - result = ""; - } - - return result; - } - - public boolean isLabelProperty(Object element, String property) - { - return false; - } - - public void removeListener(ILabelProviderListener listener) - { - listeners.remove(listener); - } - } // end of LabelProviderImpl - - private boolean workerRunning = false; - private void setWorkerRunning(boolean running) - { - workerRunning = running; - } - - /** - * Worker class which keeps looking if there are new notifications coming from server for the selected mbean - */ - private class Worker implements Runnable - { - public void run() - { - Display display = _tabFolder.getDisplay(); - while(true) - { - if (!workerRunning || _mbean == null || display == null) - { - sleep(); - continue; - } - - display.syncExec(new Runnable() - { - public void run() - { - setWorkerRunning(_form.isVisible()); - if (!workerRunning) return; - - updateTableViewer(); - } - }); - - sleep(); - } + descriptionLabel.setText(""); + typesCombo.select(0); + typesCombo.setEnabled(false); + return; } - - private void sleep() + descriptionLabel.setText(data.getDescription()); + typesCombo.removeAll(); + typesCombo.setItems(data.getTypes()); + if (typesCombo.getItemCount() > 1) { - try - { - Thread.sleep(2000); - } - catch(Exception ex) - { - - } + typesCombo.add(SELECT_NOTIFICATIONTYPE, 0); } + typesCombo.select(0); + typesCombo.setEnabled(true); } /** * Updates the table with new notifications received from mbean server for the selected mbean */ - private void updateTableViewer() + protected void updateTableViewer() { ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(_mbean); List<NotificationObject> newList = serverRegistry.getNotifications(_mbean); diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java index 49b61c0fc6..2ac037e4f0 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java @@ -20,10 +20,16 @@ */ 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; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularDataSupport; + import static org.apache.qpid.management.ui.Constants.*; import org.apache.qpid.management.ui.ApplicationRegistry; import org.apache.qpid.management.ui.ManagedBean; @@ -76,7 +82,7 @@ public class OperationTabControl extends TabControl private SelectionListener operationExecutionListener = new OperationExecutionListener(); private SelectionListener refreshListener = new RefreshListener(); private SelectionListener parameterSelectionListener = new ParameterSelectionListener(); - private SelectionListener bolleanSelectionListener = new BooleanSelectionListener(); + private SelectionListener booleanSelectionListener = new BooleanSelectionListener(); private VerifyListener verifyListener = new VerifyListenerImpl(); private KeyListener keyListener = new KeyListenerImpl(); private KeyListener headerBindingListener = new HeaderBindingKeyListener(); @@ -249,6 +255,8 @@ public class OperationTabControl extends TabControl formData.top = new FormAttachment(0, parameterPositionOffset); formData.left = new FormAttachment(label, 5); formData.right = new FormAttachment(valueWidth); + // this will contain the list of items, if the list is to be made available to choose from + // e.g. the list of exchanges String[] items = null; if (param.getName().equals(QUEUE)) { @@ -269,6 +277,15 @@ public class OperationTabControl extends TabControl { items = EXCHANGE_TYPE_VALUES; } + else if (_mbean.isAdmin() && param.getName().equals(OPERATION_PARAM_USERNAME) + && !_opData.getName().equals(OPERATION_CREATEUSER)) + { + List<String> list = ApplicationRegistry.getServerRegistry(_mbean).getUsernames(); + if (list != null && !list.isEmpty()) + { + items = list.toArray(new String[0]); + } + } if (items != null) { @@ -295,12 +312,17 @@ public class OperationTabControl extends TabControl Button booleanButton = _toolkit.createButton(_paramsComposite, "", SWT.CHECK); booleanButton.setLayoutData(formData); booleanButton.setData(param); - booleanButton.addSelectionListener(bolleanSelectionListener); + booleanButton.addSelectionListener(booleanSelectionListener); valueInCombo = true; } else { - Text text = _toolkit.createText(_paramsComposite, "", SWT.NONE); + int style = SWT.NONE; + if (PASSWORD.equalsIgnoreCase(param.getName())) + { + style = SWT.PASSWORD; + } + Text text = _toolkit.createText(_paramsComposite, "", style); formData = new FormData(); formData.top = new FormAttachment(0, parameterPositionOffset); formData.left = new FormAttachment(label, 5); @@ -530,6 +552,8 @@ public class OperationTabControl extends TabControl ((org.eclipse.swt.widgets.List)controls[i]).deselectAll(); else if (controls[i] instanceof Text) ((Text)controls[i]).setText(""); + else if (controls[i] instanceof Button) + ((Button)controls[i]).setSelection(false); else if (controls[i] instanceof Composite) clearParameterValues((Composite)controls[i]); } @@ -557,6 +581,21 @@ public class OperationTabControl extends TabControl } // End of custom code + + // customized for passwords + if (PASSWORD.equalsIgnoreCase(param.getName())) + { + try + { + param.setValueFromString(ViewUtility.getHashedString(param.getValue())); + } + catch (Exception ex) + { + MBeanUtility.handleException(_mbean, ex); + return; + } + } + // end of customization ViewUtility.popupInfoMessage(_form.getText(), "Please select the " + ViewUtility.getDisplayText(param.getName())); @@ -609,6 +648,17 @@ public class OperationTabControl extends TabControl return; } + // Custom code for Admin mbean operation + /* These custome codes here are to make the GUI look more user friendly. + * Here we are adding the users to a list, which will be used to list username to be selected on + * pages like "delete user", "set password" instead of typing the username + */ + if (_mbean.isAdmin() && _opData.getName().equals(OPERATION_VIEWUSERS)) + { + ApplicationRegistry.getServerRegistry(_mbean).setUserList(extractUserList(result)); + } + // end of custom code + // Some mbeans have only "type" and no "name". String title = _mbean.getType(); if (_mbean.getName() != null && _mbean.getName().length() != 0) @@ -616,9 +666,15 @@ public class OperationTabControl extends TabControl title = _mbean.getName(); } - if (_opData.getReturnType().equals("void") || _opData.getReturnType().equals("java.lang.Void")) + if (_opData.isReturnTypeVoid()) + { + ViewUtility.popupInfoMessage(title, OPERATION_SUCCESSFUL); + } + else if (_opData.isReturnTypeBoolean()) { - ViewUtility.popupInfoMessage(title, "Operation successful"); + boolean success = Boolean.parseBoolean(result.toString()); + String message = success ? OPERATION_SUCCESSFUL : OPERATION_UNSUCCESSFUL; + ViewUtility.popupInfoMessage(title, message); } else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty()) { @@ -634,6 +690,24 @@ public class OperationTabControl extends TabControl } + private List<String> extractUserList(Object result) + { + if (!(result instanceof TabularDataSupport)) + { + return null; + } + + TabularDataSupport tabularData = (TabularDataSupport)result; + Collection<CompositeData> records = tabularData.values(); + List<String> list = new ArrayList<String>(); + for (CompositeData data : records) + { + list.add(data.get(USERNAME).toString()); + } + Collections.sort(list); + return list; + } + /** * Listener class for the operation parameters widget */ diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java index 0793e33538..c13c92066c 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TabControl.java @@ -69,7 +69,18 @@ public abstract class TabControl return null; } - public abstract void refresh(ManagedBean mbean); + public void refresh(ManagedBean mbean) + { + if (mbean == null) + { + refresh(); + } + } + + public void refresh() + { + + } public void refresh(ManagedBean mbean, OperationData opData) { diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java index 511c2d7150..9545ed9876 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/TreeObject.java @@ -31,7 +31,6 @@ public class TreeObject { private String _name; private String _type; - private String _url; private String _virtualHost; private TreeObject _parent; private List<TreeObject> _children = new ArrayList<TreeObject>(); @@ -88,16 +87,6 @@ public class TreeObject { return _type; } - - public String getUrl() - { - return _url; - } - - public void setUrl(String url) - { - this._url = url; - } public String getVirtualHost() { @@ -131,7 +120,6 @@ public class TreeObject if (parent != null) { - this._url = parent.getUrl(); parent.addChild(this); } } diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java new file mode 100644 index 0000000000..258f5ce02a --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/VHNotificationsTabControl.java @@ -0,0 +1,462 @@ +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; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.qpid.management.ui.ApplicationRegistry; +import org.apache.qpid.management.ui.ServerRegistry; +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; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +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.Display; +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.Form; +import org.eclipse.ui.forms.widgets.FormToolkit; + +public class VHNotificationsTabControl extends TabControl +{ + protected FormToolkit _toolkit; + protected Form _form; + protected Table _table = null; + protected TableViewer _tableViewer = null; + + protected Thread worker = null; + + protected List<NotificationObject> _notifications = null; + + private static final String COLUMN_OBJ = "Object Name"; + private static final String COLUMN_SEQ = "Sequence No"; + private static final String COLUMN_TIME = "TimeStamp"; + private static final String COLUMN_TYPE = "Type"; + private static final String COLUMN_MSG = "Notification Message"; + protected static final String[] _tableTitles = new String [] { + COLUMN_OBJ, + COLUMN_SEQ, + COLUMN_TIME, + COLUMN_TYPE, + COLUMN_MSG + }; + + protected Button _clearButton = null; + protected Button _refreshButton = null; + + public VHNotificationsTabControl(TabFolder tabFolder) + { + super(tabFolder); + _toolkit = new FormToolkit(_tabFolder.getDisplay()); + _form = _toolkit.createForm(_tabFolder); + GridLayout gridLayout = new GridLayout(); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + _form.getBody().setLayout(gridLayout); + + worker = new Thread(new Worker()); + worker.start(); + } + + protected void createWidgets() + { + addButtons(); + createTableViewer(); + } + + /** + * @see TabControl#getControl() + */ + public Control getControl() + { + if (_table == null) + { + createWidgets(); + } + return _form; + } + + /** + * Creates clear buttin and refresh 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)); + + // Add Clear Button + _clearButton = _toolkit.createButton(composite, BUTTON_CLEAR, SWT.PUSH | SWT.CENTER); + _clearButton.setFont(ApplicationRegistry.getFont(FONT_BUTTON)); + GridData gridData = new GridData(SWT.LEAD, SWT.TOP, true, false); + 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()); + 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(); + } + }); + } + + /** + * Creates table to display notifications + */ + private void createTable() + { + _table = _toolkit.createTable(_form.getBody(), SWT.MULTI | SWT.FULL_SELECTION); + _table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + TableColumn column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[0]); + column.setWidth(100); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[1]); + column.setWidth(100); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[2]); + column.setWidth(130); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[3]); + column.setWidth(100); + + column = new TableColumn(_table, SWT.NONE); + column.setText(_tableTitles[4]); + column.setWidth(500); + + _table.setHeaderVisible(true); + _table.setLinesVisible(true); + } + + /** + * Creates JFace viewer for the notifications table + */ + protected void createTableViewer() + { + 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(); + } + + /** + * Adds listeners to the viewer for displaying notification details + */ + protected void addTableListeners() + { + _tableViewer.addDoubleClickListener(new IDoubleClickListener() + { + Display display = null; + Shell shell = null; + public void doubleClick(DoubleClickEvent event) + { + display = Display.getCurrent(); + shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX | SWT.RESIZE); + shell.setText("Notification"); + shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE)); + + int x = display.getBounds().width; + int y = display.getBounds().height; + shell.setBounds(x/4, y/4, x/2, y/3); + StructuredSelection selection = (StructuredSelection)event.getSelection(); + createPopupContents((NotificationObject)selection.getFirstElement()); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + //If you create it, you dispose it. + shell.dispose(); + } + + private void createPopupContents(NotificationObject obj) + { + shell.setLayout(new GridLayout()); + + Composite parent = _toolkit.createComposite(shell, SWT.NONE); + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + GridLayout layout = new GridLayout(4, true); + parent.setLayout(layout); + + // Object name record + Label key = _toolkit.createLabel(parent, COLUMN_OBJ, SWT.TRAIL); + GridData layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1); + key.setLayoutData(layoutData); + Text value = _toolkit.createText(parent, obj.getSourceName(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + // Sequence no record + key = _toolkit.createLabel(parent, COLUMN_SEQ, SWT.TRAIL); + layoutData = new GridData(SWT.TRAIL, SWT.TOP, false, false,1,1); + key.setLayoutData(layoutData); + value = _toolkit.createText(parent, ""+obj.getSequenceNo(), SWT.BEGINNING | SWT.BORDER |SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + // Time row + key = _toolkit.createLabel(parent, COLUMN_TIME, SWT.TRAIL); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = _toolkit.createText(parent, obj.getTimeStamp(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + key = _toolkit.createLabel(parent, COLUMN_TYPE, SWT.TRAIL); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = _toolkit.createText(parent, obj.getType(), SWT.BEGINNING | SWT.BORDER | SWT.READ_ONLY); + value.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false,3,1)); + + key = _toolkit.createLabel(parent, COLUMN_MSG, SWT.TRAIL); + key.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, true, false,1,1)); + value = _toolkit.createText(parent, obj.getMessage(), SWT.MULTI | SWT.WRAP| SWT.BORDER | SWT.V_SCROLL | SWT.READ_ONLY); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1); + gridData.heightHint = 100; + value.setLayoutData(gridData); + } + }); + } + + public void refresh() + { + _notifications = null; + _table.deselectAll(); + _tableViewer.getTable().clearAll(); + + Control[] children = _form.getBody().getChildren(); + for (int i = 0; i < children.length; i++) + { + children[i].setVisible(true); + } + + workerRunning = true; + _form.layout(true); + _form.getBody().layout(true, true); + } + + /** + * Content provider class for the table viewer + */ + protected class ContentProviderImpl implements IStructuredContentProvider, INotificationViewer + { + public void inputChanged(Viewer v, Object oldInput, Object newInput) + { + + } + public void dispose() + { + + } + public Object[] getElements(Object parent) + { + return _notifications.toArray(new NotificationObject[0]); + } + public void addNotification(NotificationObject notification) + { + _tableViewer.add(notification); + } + + public void addNotification(List<NotificationObject> notificationList) + { + _tableViewer.add(notificationList.toArray(new NotificationObject[0])); + } + } + + /** + * Label provider for the table viewer + */ + protected class LabelProviderImpl implements ITableLabelProvider + { + List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>(); + public void addListener(ILabelProviderListener listener) + { + listeners.add(listener); + } + + public void dispose(){ + + } + + public Image getColumnImage(Object element, int columnIndex) + { + return null; + } + + public String getColumnText(Object element, int columnIndex) + { + String result = null; + NotificationObject t = (NotificationObject)element; + switch(columnIndex) + { + case 0 : + result = t.getSourceName(); + break; + case 1 : + result = String.valueOf(t.getSequenceNo()); + break; + case 2 : + result = String.valueOf(t.getTimeStamp()); + break; + case 3 : + result = t.getType(); + break; + case 4 : + result = t.getMessage(); + break; + default : + result = ""; + } + + return result; + } + + public boolean isLabelProperty(Object element, String property) + { + return false; + } + + public void removeListener(ILabelProviderListener listener) + { + listeners.remove(listener); + } + } // end of LabelProviderImpl + + protected boolean workerRunning = false; + protected void setWorkerRunning(boolean running) + { + workerRunning = running; + } + + /** + * Worker class which keeps looking if there are new notifications coming from server for the selected mbean + */ + private class Worker implements Runnable + { + public void run() + { + Display display = _tabFolder.getDisplay(); + while(true) + { + if (!workerRunning || display == null) + { + sleep(); + continue; + } + + display.syncExec(new Runnable() + { + public void run() + { + if (_form == null || _form.isDisposed()) + return; + setWorkerRunning(_form.isVisible()); + if (!workerRunning) return; + + updateTableViewer(); + } + }); + + sleep(); + } + } + + private void sleep() + { + try + { + Thread.sleep(2000); + } + catch(Exception ex) + { + + } + } + } + + /** + * Updates the table with new notifications received from mbean server for all mbeans + */ + protected void updateTableViewer() + { + ServerRegistry serverRegistry = ApplicationRegistry.getServerRegistry(MBeanView.getServer()); + List<NotificationObject> newList = serverRegistry.getNotifications(null); + if (newList == null) + return; + + _notifications = newList; + _tableViewer.setInput(_notifications); + _tableViewer.refresh(); + } + +} diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java index 9625a58f20..9b5cddd342 100644 --- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java +++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java @@ -20,8 +20,13 @@ */ package org.apache.qpid.management.ui.views; +import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; @@ -70,6 +75,8 @@ public class ViewUtility public static final String PREV = "Previous"; public static final String INDEX = "Index"; + private static final Comparator tabularDataComparator = new TabularDataComparator(); + private static List<String> SUPPORTED_ARRAY_DATATYPES = new ArrayList<String>(); static { @@ -121,6 +128,9 @@ public class ViewUtility text.setLayoutData(layoutData); return; } + + Collections.sort(list, tabularDataComparator); + // Attach the tabular record to be retrieved and shown later when record is traversed // using first/next/previous/last buttons composite.setData(list); @@ -549,4 +559,63 @@ public class ViewUtility oldControls[i].dispose(); } } + + public static String getHashedString(Object text) throws NoSuchAlgorithmException, UnsupportedEncodingException + { + char[] chars = getHash((String)text); + return new String(chars); + } + + public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException + { + byte[] data = text.getBytes("utf-8"); + + MessageDigest md = MessageDigest.getInstance("MD5"); + + for (byte b : data) + { + md.update(b); + } + + byte[] digest = md.digest(); + + char[] hash = new char[digest.length ]; + + int index = 0; + for (byte b : digest) + { + hash[index++] = (char) b; + } + + return hash; + } + + private static class TabularDataComparator implements java.util.Comparator<Map.Entry> + { + public int compare(Map.Entry data1, Map.Entry data2) + { + if (data1.getKey() instanceof List) + { + Object obj1 = ((List)data1.getKey()).get(0); + Object obj2 = ((List)data2.getKey()).get(0); + String str1 = obj1.toString(); + String str2 = obj2.toString(); + if (obj1 instanceof String) + { + return str1.compareTo(str2); + } + + try + { + return Long.valueOf(str1).compareTo(Long.valueOf(str2)); + } + catch (Exception ex) + { + return -1; + } + } + + return -1; + } + } } diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF b/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF new file mode 100644 index 0000000000..7a9e5caaaf --- /dev/null +++ b/qpid/java/management/eclipse-plugin/src/main/resources/sasl/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Jmxmp Plug-in +Bundle-SymbolicName: jmxremote.optional +Bundle-Version: 1.0.1 +Bundle-ClassPath: . +Bundle-Vendor: +Bundle-Localization: plugin +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 diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini index dbe3f23fe9..1762840aff 100644 --- a/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini +++ b/qpid/java/management/eclipse-plugin/src/main/resources/win32/configuration/config.ini @@ -22,5 +22,5 @@ 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,org.eclipse.ui.workbench
+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.optional,org.eclipse.ui.workbench
osgi.bundles.defaultStartLevel=4
|
