/* * Copyright 2008-2017 by Emeric Vernat * * This file is part of Java Melody. * * 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 net.bull.javamelody; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Desktop; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import net.bull.javamelody.SessionInformations.SessionAttribute; import net.bull.javamelody.swing.MButton; import net.bull.javamelody.swing.Utilities; import net.bull.javamelody.swing.table.MDateTableCellRenderer; import net.bull.javamelody.swing.table.MDefaultTableCellRenderer; import net.bull.javamelody.swing.table.MTable; import net.bull.javamelody.swing.table.MTableScrollPane; /** * Panel de la liste des sessions. * @author Emeric Vernat */ class SessionInformationsPanel extends MelodyPanel { private static final ImageIcon INVALIDATE_SESSION_ICON = ImageIconCache .getScaledImageIcon("user-trash.png", 16, 16); private static final long serialVersionUID = 1L; @SuppressWarnings("all") private List<SessionInformations> sessionsInformations; private MTable<SessionInformations> table; private MTable<SessionAttribute> attributesTable; private class CountryTableCellRenderer extends MDefaultTableCellRenderer { private static final long serialVersionUID = 1L; CountryTableCellRenderer() { super(); setHorizontalAlignment(SwingConstants.CENTER); } @Override public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // icône et tooltip correspondant au pays if (row == -1) { setIcon(null); setToolTipText(null); } else { final MTable<SessionInformations> myTable = getTable(); final SessionInformations sessionInformations = myTable.getList() .get(myTable.convertRowIndexToModel(row)); final String country = sessionInformations.getCountry(); if (country == null) { setIcon(null); } else { final String fileName = "flags/" + country + ".gif"; if (getClass().getResource(Parameters.getResourcePath(fileName)) == null) { setIcon(null); } else { setIcon(ImageIconCache.getImageIcon(fileName)); } } setToolTipText(sessionInformations.getCountryDisplay()); } // sans texte return super.getTableCellRendererComponent(jtable, null, isSelected, hasFocus, row, column); } } private class BrowserTableCellRenderer extends MDefaultTableCellRenderer { private static final long serialVersionUID = 1L; BrowserTableCellRenderer() { super(); setHorizontalAlignment(SwingConstants.CENTER); } @Override public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // icône et tooltip correspondant au navigateur if (row == -1) { setIcon(null); setToolTipText(null); } else { final MTable<SessionInformations> myTable = getTable(); final SessionInformations sessionInformations = myTable.getList() .get(myTable.convertRowIndexToModel(row)); final String browser = sessionInformations.getBrowser(); if (browser == null) { setIcon(null); } else { final String browserIconName = HtmlSessionInformationsReport .getBrowserIconName(browser); final String fileName = "browsers/" + browserIconName; if (getClass().getResource(Parameters.getResourcePath(fileName)) == null) { setIcon(null); } else { setIcon(ImageIconCache.getImageIcon(fileName)); } } setToolTipText(browser); } // sans texte return super.getTableCellRendererComponent(jtable, null, isSelected, hasFocus, row, column); } } private class OsTableCellRenderer extends MDefaultTableCellRenderer { private static final long serialVersionUID = 1L; OsTableCellRenderer() { super(); setHorizontalAlignment(SwingConstants.CENTER); } @Override public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // icône et tooltip correspondant au navigateur if (row == -1) { setIcon(null); setToolTipText(null); } else { final MTable<SessionInformations> myTable = getTable(); final SessionInformations sessionInformations = myTable.getList() .get(myTable.convertRowIndexToModel(row)); final String os = sessionInformations.getOs(); if (os == null) { setIcon(null); } else { final String osIconName = HtmlSessionInformationsReport.getOSIconName(os); final String fileName = "servers/" + osIconName; if (getClass().getResource(Parameters.getResourcePath(fileName)) == null) { setIcon(null); } else { setIcon(ImageIconCache.getImageIcon(fileName)); } } setToolTipText(os); } // sans texte return super.getTableCellRendererComponent(jtable, null, isSelected, hasFocus, row, column); } } SessionInformationsPanel(RemoteCollector remoteCollector) throws IOException { super(remoteCollector); refresh(); } final void refresh() throws IOException { removeAll(); this.sessionsInformations = getRemoteCollector().collectSessionInformations(null); this.attributesTable = new MTable<>(); setName(getString("Sessions")); final JLabel titleLabel = Utilities.createParagraphTitle(getName(), "system-users.png"); add(titleLabel, BorderLayout.NORTH); final MTableScrollPane<SessionInformations> scrollPane = createScrollPane(); this.table = scrollPane.getTable(); table.setList(sessionsInformations); add(scrollPane, BorderLayout.CENTER); final JPanel southPanel = new JPanel(new BorderLayout()); southPanel.setOpaque(false); southPanel.add(createButtonsPanel(), BorderLayout.NORTH); southPanel.add(createSummaryLabel(), BorderLayout.CENTER); southPanel.add(createAttributesPanel(), BorderLayout.SOUTH); add(southPanel, BorderLayout.SOUTH); } private MTableScrollPane<SessionInformations> createScrollPane() { boolean displayUser = false; for (final SessionInformations sessionInformations : sessionsInformations) { if (sessionInformations.getRemoteUser() != null) { displayUser = true; break; } } final MTableScrollPane<SessionInformations> tableScrollPane = new MTableScrollPane<>(); final MTable<SessionInformations> myTable = tableScrollPane.getTable(); myTable.addColumn("id", getString("Session_id")); myTable.addColumn("lastAccess", getString("Dernier_acces")); myTable.addColumn("age", getString("Age")); myTable.addColumn("expirationDate", getString("Expiration")); myTable.addColumn("attributeCount", getString("Nb_attributs")); myTable.addColumn("serializable", getString("Serialisable")); myTable.addColumn("serializedSize", getString("Taille_serialisee")); myTable.addColumn("remoteAddr", getString("Adresse_IP")); myTable.addColumn("countryDisplay", getString("Pays")); myTable.addColumn("browser", getString("Navigateur")); myTable.addColumn("os", getString("OS")); if (displayUser) { myTable.addColumn("remoteUser", getString("Utilisateur")); } final MDateTableCellRenderer durationTableCellRenderer = new MDateTableCellRenderer(); durationTableCellRenderer.setDateFormat(I18N.createDurationFormat()); myTable.setColumnCellRenderer("lastAccess", durationTableCellRenderer); myTable.setColumnCellRenderer("age", durationTableCellRenderer); final MDateTableCellRenderer dateAndTimeTableCellRenderer = new MDateTableCellRenderer(); dateAndTimeTableCellRenderer.setDateFormat(I18N.createDateAndTimeFormat()); myTable.setColumnCellRenderer("expirationDate", dateAndTimeTableCellRenderer); myTable.setColumnCellRenderer("countryDisplay", new CountryTableCellRenderer()); myTable.setColumnCellRenderer("browser", new BrowserTableCellRenderer()); myTable.setColumnCellRenderer("os", new OsTableCellRenderer()); return tableScrollPane; } private JPanel createAttributesPanel() { final JPanel attributesPanel = new JPanel(new BorderLayout()); attributesPanel.setOpaque(false); final JLabel attributesLabel = new JLabel(getString("Attributs")); attributesLabel.setFont(attributesLabel.getFont().deriveFont(Font.BOLD)); attributesPanel.add(attributesLabel, BorderLayout.NORTH); final MTableScrollPane<SessionAttribute> attributesTableScrollPane = new MTableScrollPane<>( attributesTable); attributesTable.addColumn("name", getString("Nom")); attributesTable.addColumn("type", getString("Type")); attributesTable.addColumn("serializable", getString("Serialisable")); attributesTable.addColumn("serializedSize", getString("Taille_serialisee")); attributesTable.addColumn("content", getString("Contenu")); attributesTable.setPreferredScrollableViewportSize(new Dimension(-1, 100)); attributesPanel.add(attributesTableScrollPane, BorderLayout.CENTER); table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { refreshAttributes(); } } }); return attributesPanel; } private JLabel createSummaryLabel() { long totalSerializedSize = 0; int nbSerializableSessions = 0; for (final SessionInformations sessionInformations : sessionsInformations) { final int size = sessionInformations.getSerializedSize(); if (size >= 0) { totalSerializedSize += size; nbSerializableSessions++; } } final long meanSerializedSize; if (nbSerializableSessions > 0) { meanSerializedSize = totalSerializedSize / nbSerializableSessions; } else { meanSerializedSize = -1; } final JLabel summaryLabel = new JLabel("<html><div align='right'>" + getFormattedString("nb_sessions", sessionsInformations.size()) + "<br/>" + getFormattedString("taille_moyenne_sessions", meanSerializedSize)); summaryLabel.setHorizontalAlignment(SwingConstants.RIGHT); return summaryLabel; } private JPanel createButtonsPanel() { final MButton refreshButton = createRefreshButton(); refreshButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { refresh(); } catch (final IOException ex) { showException(ex); } } }); final MButton pdfButton = createPdfButton(); pdfButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { actionPdf(); } catch (final IOException ex) { showException(ex); } } }); final MButton xmlJsonButton = createXmlJsonButton((Serializable) sessionsInformations); final MButton invalidateAllSessionsButton = createInvalidateAllSessionsButton(); final MButton invalidateSessionButton = createInvalidateSessionButton(); getTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { final SessionInformations sessionInformations = getTable().getSelectedObject(); invalidateSessionButton.setEnabled(sessionInformations != null); } }); invalidateSessionButton.setEnabled(getTable().getSelectedObject() != null); return Utilities.createButtonsPanel(refreshButton, pdfButton, xmlJsonButton, invalidateAllSessionsButton, invalidateSessionButton); } private MButton createInvalidateAllSessionsButton() { final MButton invalidateAllSessionsButton = new MButton(getString("invalidate_sessions"), INVALIDATE_SESSION_ICON); invalidateAllSessionsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (confirm(getFormattedString("confirm_invalidate_sessions"))) { actionInvalidateAllSessions(); } } }); return invalidateAllSessionsButton; } private MButton createInvalidateSessionButton() { final MButton invalidateSessionButton = new MButton(getString("invalidate_session"), INVALIDATE_SESSION_ICON); invalidateSessionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final SessionInformations sessionInformations = getTable().getSelectedObject(); if (sessionInformations != null && confirm(getFormattedString("confirm_invalidate_session"))) { actionInvalidateSession(sessionInformations); } } }); return invalidateSessionButton; } final void actionInvalidateAllSessions() { try { final String message = getRemoteCollector().executeActionAndCollectData( Action.INVALIDATE_SESSIONS, null, null, null, null, null); showMessage(message); refresh(); } catch (final IOException ex) { showException(ex); } } final void actionInvalidateSession(final SessionInformations sessionInformations) { try { final String message = getRemoteCollector().executeActionAndCollectData( Action.INVALIDATE_SESSION, null, sessionInformations.getId(), null, null, null); showMessage(message); refresh(); } catch (final IOException ex) { showException(ex); } } final void actionPdf() throws IOException { final File tempFile = createTempFileForPdf(); final PdfOtherReport pdfOtherReport = createPdfOtherReport(tempFile); try { pdfOtherReport.writeSessionInformations(sessionsInformations); } finally { pdfOtherReport.close(); } Desktop.getDesktop().open(tempFile); } final void refreshAttributes() { getAttributesTable().setList(null); final SessionInformations sessionInformations = getTable().getSelectedObject(); if (sessionInformations != null) { try { final List<SessionInformations> list = getRemoteCollector() .collectSessionInformations(sessionInformations.getId()); if (list.isEmpty()) { final String message = getFormattedString("session_invalidee", sessionInformations.getId()); showMessage(message); } else { getAttributesTable().setList(list.get(0).getAttributes()); } } catch (final IOException ex) { showException(ex); } } } MTable<SessionInformations> getTable() { return table; } MTable<SessionAttribute> getAttributesTable() { return attributesTable; } }