/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package net.java.visualvm.modules.glassfish.dataview; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.util.logging.Level; import javax.management.AttributeNotFoundException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MalformedObjectNameException; import javax.management.ReflectionException; import net.java.visualvm.modules.glassfish.ui.StatsTable; import com.sun.appserv.management.monitor.WebModuleVirtualServerMonitor; import com.sun.appserv.management.monitor.statistics.WebModuleVirtualServerStats; import com.sun.tools.visualvm.charts.ChartFactory; import com.sun.tools.visualvm.charts.SimpleXYChartDescriptor; import com.sun.tools.visualvm.charts.SimpleXYChartSupport; import com.sun.tools.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory; import com.sun.tools.visualvm.core.scheduler.Quantum; import com.sun.tools.visualvm.core.scheduler.ScheduledTask; import com.sun.tools.visualvm.core.scheduler.Scheduler; import com.sun.tools.visualvm.core.scheduler.SchedulerTask; import com.sun.tools.visualvm.core.ui.DataSourceWindowManager; import com.sun.tools.visualvm.core.ui.DataSourceView; import com.sun.tools.visualvm.core.ui.DataSourceViewProvider; import com.sun.tools.visualvm.core.ui.DataSourceViewsManager; import com.sun.tools.visualvm.core.ui.components.DataViewComponent; import com.sun.tools.visualvm.tools.jmx.JmxModel; import com.sun.tools.visualvm.tools.jmx.JmxModelFactory; import com.sun.tools.visualvm.uisupport.HTMLLabel; import com.sun.tools.visualvm.uisupport.HTMLTextArea; import net.java.visualvm.modules.glassfish.datasource.GlassFishWebModule; import org.openide.util.ImageUtilities; import java.awt.BorderLayout; import java.awt.Image; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.RowSorter; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; /** * * @author Jaroslav Bachorik */ public class GlassFishWebModuleViewProvider extends DataSourceViewProvider<GlassFishWebModule> { private final static GlassFishWebModuleViewProvider INSTANCE = new GlassFishWebModuleViewProvider(); private final static Logger LOGGER = Logger.getLogger(GlassFishWebModuleViewProvider.class.getName()); private final Map<GlassFishWebModule, GlassfishWebModuleView> viewMap = new HashMap<GlassFishWebModule, GlassFishWebModuleViewProvider.GlassfishWebModuleView>(); private static class GlassfishWebModuleView extends DataSourceView { //~ Static fields/initializers ------------------------------------------------------------------------------------------- private static final Image NODE_ICON = ImageUtilities.loadImage("net/java/visualvm/modules/glassfish/resources/application.png", true); //~ Instance fields ------------------------------------------------------------------------------------------------------ private SimpleXYChartSupport activeSessionsChart; private SimpleXYChartSupport jspChart; private SimpleXYChartSupport totalSessionsChart; private DataViewComponent dvc; private TableModel servletsModel; private TableModel wsModel; private GlassFishWebModule module; private ScheduledTask refreshTask; //~ Constructors --------------------------------------------------------------------------------------------------------- public GlassfishWebModuleView(GlassFishWebModule webModule) { super(webModule, "Overview", NODE_ICON, 0, true); module = webModule; JPanel masterPanel = new JPanel(new BorderLayout()); masterPanel.setOpaque(false); HTMLTextArea generalDataArea = new HTMLTextArea(); generalDataArea.setText(buildInfo()); generalDataArea.setBorder(BorderFactory.createEmptyBorder()); // generalDataArea.setOpaque(false); JScrollPane generalDataScroll = new JScrollPane(generalDataArea); generalDataScroll.setViewportBorder(BorderFactory.createEmptyBorder()); generalDataScroll.setBorder(BorderFactory.createEmptyBorder()); generalDataScroll.setOpaque(false); HTMLLabel appLink = new HTMLLabel("<html><body><h2>Application hosted by <a href=\"#\">" + DataSourceDescriptorFactory.getDescriptor(module.getGlassFishRoot().getApplication()).getName()+ "</a></h2></body></html>") { protected void showURL(URL url) { DataSourceWindowManager.sharedInstance().openDataSource(module.getGlassFishRoot().getApplication()); } }; masterPanel.add(generalDataScroll, BorderLayout.CENTER); masterPanel.add(appLink, BorderLayout.NORTH); SimpleXYChartDescriptor desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Current","Maximum"); activeSessionsChart = ChartFactory.createSimpleXYChart(desc); desc = SimpleXYChartDescriptor.decimal(10, true, 500); desc.addLineItems("Created","Expired","Rejected"); totalSessionsChart = ChartFactory.createSimpleXYChart(desc); desc = SimpleXYChartDescriptor.decimal(10, false, 500); desc.addLineItems("Count","Reloads","Errors"); jspChart = ChartFactory.createSimpleXYChart(desc); JPanel servletsPanel = new JPanel(new BorderLayout()); servletsPanel.setOpaque(false); servletsModel = new ServletTableModel(webModule.getMonitor(), Quantum.seconds(5)); RowSorter<TableModel> servletsRowSorter = new TableRowSorter<TableModel>(servletsModel); StatsTable servletsTable = new StatsTable(servletsModel); servletsTable.setRowSorter(servletsRowSorter); JScrollPane servletsScroller = new JScrollPane(servletsTable); servletsScroller.getViewport().setBackground(generalDataArea.getBackground()); servletsPanel.add(servletsScroller, BorderLayout.CENTER); JPanel wsPanel = new JPanel(new BorderLayout()); wsPanel.setOpaque(false); wsModel = new WSTableModel(webModule.getMonitor(), Quantum.seconds(5)); RowSorter<TableModel> wsRowSorter = new TableRowSorter<TableModel>(wsModel); StatsTable wsTable = new StatsTable(wsModel); wsTable.setRowSorter(wsRowSorter); JScrollPane wsScroller = new JScrollPane(wsTable); wsScroller.getViewport().setBackground(generalDataArea.getBackground()); wsPanel.add(wsScroller, BorderLayout.CENTER); DataViewComponent.MasterView masterView = new DataViewComponent.MasterView("Overview", null, masterPanel); DataViewComponent.MasterViewConfiguration masterConfiguration = new DataViewComponent.MasterViewConfiguration(false); dvc = new DataViewComponent(masterView, masterConfiguration); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Sessions", true), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Sessions Active", null, 10, activeSessionsChart.getChart(), null), DataViewComponent.TOP_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Sessions Total", null, 20, totalSessionsChart.getChart(), null), DataViewComponent.TOP_LEFT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("JSPs", true), DataViewComponent.TOP_RIGHT); dvc.addDetailsView(new DataViewComponent.DetailsView("JSPs", null, 10, jspChart.getChart(), null), DataViewComponent.TOP_RIGHT); dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration("Runtime", true), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("Servlets", null, 10, servletsPanel, null), DataViewComponent.BOTTOM_LEFT); dvc.addDetailsView(new DataViewComponent.DetailsView("WebServices", null, 20, wsPanel, null), DataViewComponent.BOTTOM_LEFT); refreshTask = Scheduler.sharedInstance().schedule(new SchedulerTask() { public void onSchedule(long timeStamp) { try { refreshData(timeStamp); } catch (Exception e) { if (!(e instanceof UndeclaredThrowableException)) { Logger.getLogger(GlassFishWebModuleViewProvider.class.getName()).log(Level.INFO,"onSchedule",e); } else { Scheduler.sharedInstance().unschedule(refreshTask); refreshTask = null; } } } }, Quantum.seconds(5)); } @Override protected DataViewComponent createComponent() { return dvc; } //~ Methods -------------------------------------------------------------------------------------------------------------- private String buildInfo() { JmxModel jmx = JmxModelFactory.getJmxModelFor(module.getGlassFishRoot().getApplication()); StringBuilder sb = new StringBuilder(); try { ObjectName objName = new ObjectName(module.getObjectName()); MBeanServerConnection connection = jmx.getMBeanServerConnection(); sb.append("<br/>"); sb.append("<b>Context: </b>").append(connection.getAttribute(objName, "path")).append("<br/>"); sb.append("<b>Document Base: </b>").append(connection.getAttribute(objName, "docBase")).append("<br/>"); sb.append("<b>Working Dir: </b>").append(connection.getAttribute(objName, "workDir")).append("<br/>"); sb.append("<br/>"); boolean cacheAllowed = (Boolean)connection.getAttribute(objName, "cachingAllowed"); sb.append("<b>Caching: </b>").append(cacheAllowed ? "Allowed" : "Disallowed").append("<br/>"); sb.append("<br/>"); } catch (MBeanException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (AttributeNotFoundException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (InstanceNotFoundException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (ReflectionException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (IOException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (MalformedObjectNameException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } catch (NullPointerException ex) { LOGGER.throwing(GlassFishWebModuleViewProvider.class.getName(), "buildInfo", ex); } return sb.toString(); } private void refreshData(long sampleTime) { WebModuleVirtualServerMonitor monitor = module.getMonitor(); WebModuleVirtualServerStats stats = monitor.getWebModuleVirtualServerStats(); activeSessionsChart.addValues(sampleTime, new long[] { stats.getActiveSessionsCurrent().getCount(), stats.getActiveSessionsHigh().getCount() }); totalSessionsChart.addValues(sampleTime, new long[] { stats.getSessionsTotal().getCount(), stats.getExpiredSessionsTotal().getCount(), stats.getRejectedSessionsTotal().getCount() }); jspChart.addValues(sampleTime, new long[] { stats.getJSPCount().getCount(), stats.getJSPReloadCount().getCount(), stats.getJSPErrorCount().getCount() }); } } private GlassFishWebModuleViewProvider() {} //~ Methods ------------------------------------------------------------------------------------------------------------------ public static void initialize() { DataSourceViewsManager.sharedInstance().addViewProvider(INSTANCE, GlassFishWebModule.class); } public static void shutdown() { DataSourceViewsManager.sharedInstance().removeViewProvider(INSTANCE); INSTANCE.viewMap.clear(); } @Override protected DataSourceView createView(GlassFishWebModule webModule) { return new GlassfishWebModuleView(webModule); } @Override protected boolean supportsViewFor(GlassFishWebModule webModule) { return true; } }