/*
* Copyright 2011 JBoss, by Red Hat, Inc
*
* Licensed 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.jboss.errai.tools.monitoring;
import org.jboss.errai.bus.client.api.MessageCallback;
import org.jboss.errai.bus.client.api.base.RuleDelegateMessageCallback;
import org.jboss.errai.bus.client.framework.MessageBus;
import org.jboss.errai.bus.client.util.BusTools;
import org.jboss.errai.bus.server.api.ServerMessageBus;
import org.jboss.errai.bus.server.io.RemoteServiceCallback;
import org.jboss.errai.bus.server.security.auth.rules.RolesRequiredRule;
import org.mvel2.util.StringAppender;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.lang.String.valueOf;
import static javax.swing.SwingUtilities.invokeLater;
import static org.jboss.errai.tools.monitoring.UiHelper.getSwIcon;
public class ServerMonitorPanel implements Attachable {
private MainMonitorGUI mainMonitorGUI;
private MessageBus messageBus;
private String busId;
private JList busServices;
private JTree serviceExplorer;
private final DefaultListModel busServicesModel;
private JPanel rootPanel;
private String currentlySelectedService;
private ServerLogPanel logPanel;
private ActivityProcessor processor;
private Map<String, ServiceActivityMonitor> monitors = new HashMap<String, ServiceActivityMonitor>();
public ServerMonitorPanel(MainMonitorGUI gui, MessageBus bus, String busId) {
this.mainMonitorGUI = gui;
this.messageBus = bus;
this.busId = busId;
rootPanel = new JPanel();
rootPanel.setLayout(new BorderLayout());
JButton activityConsoleButton = new JButton("Activity Console");
JButton monitorButton = new JButton("Monitor Service...");
JButton conversationsButton = new JButton("Conversations ...");
busServices = new JList();
busServices.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
busServices.setModel(busServicesModel = new DefaultListModel());
busServices.setCellRenderer(new ServicesListCellRender());
serviceExplorer = new JTree();
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
new JScrollPane(busServices), new JScrollPane(serviceExplorer));
splitPane.setDividerLocation(150);
rootPanel.add(splitPane, BorderLayout.CENTER);
JPanel southPanel = new JPanel();
southPanel.setLayout(new BorderLayout());
rootPanel.add(southPanel, BorderLayout.SOUTH);
southPanel.add(activityConsoleButton, BorderLayout.WEST);
JPanel southEastPanel = new JPanel();
southEastPanel.setLayout(new FlowLayout());
southEastPanel.add(conversationsButton);
southEastPanel.add(monitorButton);
southPanel.add(southEastPanel, BorderLayout.EAST);
busServices.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
currentlySelectedService = getCurrentServiceSelection();
generateServiceExplorer();
}
});
busServices.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1 || e.getClickCount() != 2) return;
openActivityMonitor();
}
});
monitorButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openActivityMonitor();
}
});
conversationsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openConversationMonitor();
}
});
activityConsoleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openServerLog();
}
});
DefaultTreeModel model = (DefaultTreeModel) serviceExplorer.getModel();
((DefaultMutableTreeNode) serviceExplorer.getModel().getRoot()).removeAllChildren();
serviceExplorer.setRootVisible(false);
serviceExplorer.setCellRenderer(new MonitorTreeCellRenderer());
serviceExplorer.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
model.reload();
}
public void attach(ActivityProcessor proc) {
this.processor = proc;
}
private void openActivityMonitor() {
if (monitors.containsKey(getCurrentServiceSelection())) {
monitors.get(currentlySelectedService).toFront();
}
else {
ServiceActivityMonitor sam = new ServiceActivityMonitor(this, busId, currentlySelectedService);
sam.attach(processor);
monitors.put(currentlySelectedService, sam);
}
}
public void openConversationMonitor() {
String key = currentlySelectedService + ":Conversations";
if (monitors.containsKey(key)) {
monitors.get(key).toFront();
}
else {
ServiceActivityMonitor sam = new ConversationActivityMonitor(this, busId, currentlySelectedService);
sam.attach(processor);
monitors.put(key, sam);
}
}
private void openServerLog() {
if (this.logPanel != null && this.logPanel.isVisible()) {
return;
}
this.logPanel = new ServerLogPanel(mainMonitorGUI);
this.logPanel.attach(processor);
}
void stopMonitor(String service) {
monitors.remove(service);
}
private String getCurrentServiceSelection() {
return valueOf(busServicesModel.get(busServices.getSelectedIndex()));
}
public void addServiceName(final String serviceName) {
synchronized (busServicesModel) {
if (busServicesModel.contains(serviceName)) return;
invokeLater(new Runnable() {
public void run() {
busServicesModel.addElement(serviceName);
}
});
}
}
public void removeServiceName(final String serviceName) {
synchronized (busServicesModel) {
if (!busServicesModel.contains(serviceName)) return;
invokeLater(new Runnable() {
public void run() {
busServicesModel.removeElement(serviceName);
}
});
}
}
public JPanel getPanel() {
return rootPanel;
}
private void generateServiceExplorer() {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) serviceExplorer.getModel().getRoot();
node.setUserObject(new JLabel(currentlySelectedService + (BusTools.isReservedName(currentlySelectedService) ? " (Built-in)" : ""), getSwIcon("service.png"), SwingConstants.LEFT));
node.removeAllChildren();
serviceExplorer.setRootVisible(true);
DefaultTreeModel model = (DefaultTreeModel) serviceExplorer.getModel();
if (messageBus instanceof ServerMessageBus) {
// this is the serverside bus.
ServerMessageBus smb = (ServerMessageBus) messageBus;
List<MessageCallback> receivers = smb.getReceivers(currentlySelectedService);
DefaultMutableTreeNode receiversNode
= new DefaultMutableTreeNode("Receivers (" + receivers.size() + ")", true);
for (MessageCallback mc : receivers) {
receiversNode.add(new DefaultMutableTreeNode(mc.getClass().getName()));
if (mc instanceof RuleDelegateMessageCallback) {
RuleDelegateMessageCallback ruleDelegate = (RuleDelegateMessageCallback) mc;
DefaultMutableTreeNode securityNode =
new DefaultMutableTreeNode("Security");
if (ruleDelegate.getRoutingRule() instanceof RolesRequiredRule) {
RolesRequiredRule rule = (RolesRequiredRule) ruleDelegate.getRoutingRule();
DefaultMutableTreeNode rolesNode =
new DefaultMutableTreeNode(rule.getRoles().isEmpty() ? "Requires Authentication" : "Roles Required");
for (Object o : rule.getRoles()) {
// DefaultMutableTreeNode roleNode = new DefaultMutableTreeNode(String.valueOf(o));
rolesNode.add(UiHelper.createIconEntry("key.png", valueOf(o)));
}
securityNode.add(rolesNode);
}
node.add(securityNode);
}
else if (mc instanceof RemoteServiceCallback) {
RemoteServiceCallback remCB = (RemoteServiceCallback) mc;
Set<String> endpoints = remCB.getEndpoints();
DefaultMutableTreeNode remoteCPs =
new DefaultMutableTreeNode("Callpoints (" + endpoints.size() + ")");
for (String endpoint : endpoints) {
String[] epParts = endpoint.split(":");
StringAppender appender = new StringAppender(epParts[0]).append('(');
for (int i = 1; i < epParts.length; i++) {
appender.append(epParts[i]);
if ((i + 1) < epParts.length) appender.append(", ");
}
remoteCPs.add(UiHelper.createIconEntry("database_connect.png", appender.append(')').toString()));
}
node.add(remoteCPs);
}
}
node.add(receiversNode);
}
model.reload();
for (int i = 0; i < serviceExplorer.getRowCount(); i++) {
serviceExplorer.expandRow(i);
}
}
public MainMonitorGUI getMainMonitorGUI() {
return mainMonitorGUI;
}
public class ServicesListCellRender extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
String v = valueOf(value);
if (v.endsWith(":RPC")) {
setIcon(getSwIcon("database_connect.png"));
}
else {
setIcon(BusTools.isReservedName(v) ? getSwIcon("database_key.png") : getSwIcon("database.png"));
}
setToolTipText(v);
return this;
}
}
}