/*
* Copyright 2008-2014 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.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import net.bull.javamelody.swing.Utilities;
import net.bull.javamelody.swing.table.MDateTableCellRenderer;
import net.bull.javamelody.swing.table.MMultiLineTableCellRenderer;
import net.bull.javamelody.swing.table.MTable;
import net.bull.javamelody.swing.table.MTableScrollPane;
import com.lowagie.text.Font;
/**
* Panel des erreurs http et dans les logs ou dans les jobs.
* @author Emeric Vernat
*/
class CounterErrorPanel extends MelodyPanel {
private static final long serialVersionUID = 1L;
private final Counter counter;
private final MTable<CounterError> table;
private final class MessageWithStackTraceTableCellRenderer extends MMultiLineTableCellRenderer {
private static final long serialVersionUID = 1L;
MessageWithStackTraceTableCellRenderer() {
super();
}
@Override
public Component getTableCellRendererComponent(JTable jtable, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
// texte selon la valeur (message de l'erreur)
super.getTableCellRendererComponent(jtable, value, isSelected, hasFocus, row, column);
// et tooltip selon la stackTrace
// (l'appel à setToolTipText doit être après getTableCellRendererComponent
// car MMultiLineTableCellRenderer change le toolTipText dans setValue)
if (row == -1) {
setToolTipText(null);
} else {
final MTable<CounterError> myTable = getTable();
final CounterError counterError = myTable.getList().get(
myTable.convertRowIndexToModel(row));
final String stackTrace = counterError.getStackTrace();
if (stackTrace == null) {
setToolTipText(null);
} else {
setToolTipText("<html>"
+ stackTrace.replace("[See nested", "\n[See nested").replaceAll("\n",
"<br/>"));
}
}
return this;
}
}
CounterErrorPanel(RemoteCollector remoteCollector, Counter counter) {
super(remoteCollector);
assert counter != null;
assert counter.isErrorCounter();
this.counter = counter;
if (counter.getErrorsCount() == 0) {
this.table = null;
final JLabel noErrorsLabel = createNoErrorsLabel();
add(noErrorsLabel, BorderLayout.CENTER);
} else {
final MTableScrollPane<CounterError> scrollPane = createScrollPane();
this.table = scrollPane.getTable();
final List<CounterError> errors = counter.getErrors();
table.setList(errors);
Utilities.adjustTableHeight(table);
add(scrollPane, BorderLayout.CENTER);
}
}
private MTableScrollPane<CounterError> createScrollPane() {
final MTableScrollPane<CounterError> tableScrollPane = new MTableScrollPane<>();
final MTable<CounterError> myTable = tableScrollPane.getTable();
final List<CounterError> errors = counter.getErrors();
final boolean displayUser = HtmlCounterErrorReport.shouldDisplayUser(errors);
final boolean displayHttpRequest = HtmlCounterErrorReport.shouldDisplayHttpRequest(errors);
if (errors.size() >= Counter.MAX_ERRORS_COUNT) {
final JLabel warnLabel = new JLabel(' ' + getFormattedString(
"Dernieres_erreurs_seulement", Counter.MAX_ERRORS_COUNT));
warnLabel.setFont(warnLabel.getFont().deriveFont(Font.BOLD));
warnLabel.setForeground(Color.RED);
add(warnLabel, BorderLayout.NORTH);
}
myTable.addColumn("date", getString("Date"));
if (displayHttpRequest) {
myTable.addColumn("httpRequest", getString("Requete"));
}
if (displayUser) {
myTable.addColumn("remoteUser", getString("Utilisateur"));
}
myTable.addColumn("message", getString("Erreur"));
final MDateTableCellRenderer dateTableCellRenderer = new MDateTableCellRenderer();
dateTableCellRenderer.setDateFormat(DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.MEDIUM, I18N.getCurrentLocale()));
myTable.setColumnCellRenderer("date", dateTableCellRenderer);
myTable.setColumnCellRenderer("message", new MessageWithStackTraceTableCellRenderer());
// invokeLater nécessaire pour que les dimensions et l'affichage soient corrects
// avec le MessageWithStackTraceTableCellRenderer extends MMultiLineTableCellRenderer
// (tester par exemple l'erreur de compilation dans la page jsp avec tomcat)
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Utilities.adjustTableHeight(myTable);
}
});
myTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
final CounterError counterError = getTable().getSelectedObject();
if (counterError.getStackTrace() != null) {
Utilities.showTextInPopup(CounterErrorPanel.this,
counterError.getMessage(), counterError.getStackTrace());
}
}
}
});
return tableScrollPane;
}
private JLabel createNoErrorsLabel() {
return new JLabel(' ' + getString("Aucune_erreur"));
}
MTable<CounterError> getTable() {
return table;
}
}