/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration) * and Cosylab 2002, All rights reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package com.cosylab.logging; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JRootPane; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JViewport; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import org.omg.CORBA.ORB; import alma.acs.container.AdvancedContainerServices; import alma.acs.container.ContainerServicesBase; import alma.acs.gui.widgets.ExtendedTextArea; import alma.acs.logging.archive.ArchiveConnectionManager; import alma.acs.logging.archive.ArchiveConnectionManager.DBState; import alma.acs.logging.archive.QueryDlg; import alma.acs.logging.archive.zoom.ManualZoomDlg; import alma.acs.logging.archive.zoom.ZoomManager; import alma.acs.logging.archive.zoom.ZoomPrefsDlg; import alma.acs.logging.dialogs.error.ErrorLogDialog; import alma.acs.logging.dialogs.main.LogFrame; import alma.acs.logging.dialogs.main.LogMenuBar; import alma.acs.logging.dialogs.main.LogNavigationBar; import alma.acs.logging.dialogs.main.LogToolBar; import alma.acs.logging.errorbrowser.ErrorBrowserDlg; import alma.acs.logging.preferences.ExpertPrefsDlg; import alma.acs.logging.preferences.UserPreferences; import alma.acs.logging.table.LogEntryTable; import alma.acs.logging.table.LogTableDataModel; import com.cosylab.logging.MessageWidget.MessageType; import com.cosylab.logging.MessageWidget.MessageWidgetListener; import com.cosylab.logging.client.DetailedLogTable; import com.cosylab.logging.engine.Filterable; import com.cosylab.logging.engine.FiltersVector; import com.cosylab.logging.engine.ACS.ACSLogConnectionListener; import com.cosylab.logging.engine.ACS.ACSRemoteErrorListener; import com.cosylab.logging.engine.ACS.ACSRemoteLogListener; import com.cosylab.logging.engine.ACS.LCEngine; import com.cosylab.logging.engine.audience.Audience.AudienceInfo; import com.cosylab.logging.engine.log.ILogEntry; import com.cosylab.logging.engine.log.LogTypeHelper; import com.cosylab.logging.search.SearchDialog; import com.cosylab.logging.settings.FilterChooserDialog; import com.cosylab.logging.stats.StatsDlg; import com.cosylab.logging.viewcoordination.ViewCoordinator; /** * Defines a JRootPane Application LoggingClient for displaying event logs * received through the CORBA protocol for the purpose of monitoring and * reviewing of the logs. It contains of a JScrollPane scrollLogTable for the * logs and a LogEntryTable logEntryTable for displaying the status * as well as a JPanel ivjJFrameContentPane. Multiple listeners handle * user's input. * Based on the current code and our understanding of it one could describe * the information flow as follows. User's input triggers events which are * caught by the listeners attached to each one of the available GUI object * representations defined in the LoggingClient class. * Independent of that there are messages available at the logging system * generated by the other services running in the framework. These messages are * parsed by the ACSStructuredPushConsumer class using the SAX parser and are * then passed on using the LogTableDataModel's appendLog method for putting * the logs to the log table. * In particular, we are interested in the saving and loading of files to be * implemented by the LoggingClient. While saveFile and loadFromFile are defined * in LogTabledataModel, the LogImportTask file makes use of the * the LogTabledataModel's appendLog method as well. The use of the DocumentBuilderFactory * in the LogImportTask defines a way for transforming a DOM tree into XML. *
* An important issue is the format of the Log Entry Message produced by the Logging * Service. Certain characters ('<', '>', '&', ''', '"') need to be escaped * because they delineate markup data from character data and cause the following exception * in ACSLogParserDOM class: * org.xml.sax.SAXParseException: The content beginning with '<' * is not legal markup. * One solution is replacing the character with the appropriate html substitute <. * Another solution is keeping it in a CDATA section: <[!CDATA[the log entry message]]>. *
* The panel can be instantiated:
* - by LogFrame
* - as an EXEC plugin
*/
public class LoggingClient extends JRootPane implements
ACSRemoteLogListener,
ACSLogConnectionListener,
ACSRemoteErrorListener,
MessageWidgetListener
{
/**
* The default log level
*/
public static final LogTypeHelper DEFAULT_LOGLEVEL = LogTypeHelper.INFO;
/**
* The default discard level
*/
public static final LogTypeHelper DEFAULT_DISCARDLEVEL = LogTypeHelper.DEBUG;
/**
* The name of the property to set for enabling the operator mode at startup.
*
* If the property is not found, ENGINEER audience is set in the engine
*
* @sse initAudience()
*/
private static final String AUDIENCE_PROPERTY = "jlog.mode.audience";
/**
* The audience in use by the engine and shown in the status line
*/
private JLabel audienceLbl = new JLabel();
/**
* The label showing if there are active filters in the engine
*/
private JLabel engineFiltersLbl = new JLabel();
/**
* The label showing if there are active filters in the table
*/
private JLabel tableFiltersLbl = new JLabel();
/**
* The label showing if the number of logs in memory is limited
*/
private JLabel maxNumOfLogsLbl = new JLabel();
private ArchiveConnectionManager archive;
// Create an instance of the preferences with default values
private UserPreferences userPreferences = new UserPreferences(0,100000,Integer.MAX_VALUE,Integer.MAX_VALUE);
private JPanel ivjJPanel2 = null;
private JPanel detailedInfoPanel = null;
// The table showing the whole content of a log (in the detailed
// panel at the right side of the main window)
private DetailedLogTable detailedLogTable = new DetailedLogTable();
// The panel with the suspend btn, the filter string...
// It is immediately under the table of logs
private JPanel statusLinePnl = null;
private JScrollPane statusAreaPanel = null; // The bottom scrolling panel with the status messages
private JScrollPane detailedInfoScrollPane = null;
/**
* The horizontal split panel having the text area at the bottom
* add the panel with the table and details (tableDetailsSplitPane) at the top.
*/
private JSplitPane statusAreaHrSplitP = null;
/**
* The vertical split pane having the table of logs at the left side, and the
* details panel at the right side.
*/
private JSplitPane tableDetailsVrSplitP = null;
private JScrollPane scrollLogTable = null;
/**
* The table of logs
*/
private LogEntryTable logEntryTable = null;
/**
* The status area at the bottom where messages are appended
* by {@link #reportStatus(String)}
*/
private ExtendedTextArea messageTextArea = null;
private JPanel ivjJFrameContentPane = null;
/**
* The error dialog
*/
private ErrorLogDialog errorDialog;
/**
* The progress bar for long time operations
*/
private JProgressBar progressBar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);
/**
* The ZoomManager
to perform zooming
*
* The object is built with default levels; the path of the
* folder of XML files is read from a java property.
*/
private ZoomManager zoom=new ZoomManager();
/**
* The dialog to perform the zoom with a given time interval
*/
private ManualZoomDlg manualZoomDlg;
/**
* true
if the engine is connected.
*/
private boolean isConnected=false;
/**
* true
if the application is stopped
*
* This property is set by the start()
and stop()
.
* It is also set in the constructor for the stand alone version because in that
* case the start is not executed.
*/
private volatile boolean isStopped=true;
/**
* The search dialog
* The object is built the first time the user requests a search
*/
private SearchDialog searchDialog;
/**
* Statistic dialog.
* The object is built the first time the user selects the menu item
*/
private StatsDlg statsDlg;
/**
* The dialog to query the database
*/
private QueryDlg databaseDlg=null;
private EventHandler eventHandler = new EventHandler();
private LCEngine engine = null;
private LogTableDataModel tableModel = null;
/**
* The icons to show the status of the connection
*
*/
private static final int CONNECTED_ICON = 0;
private static final int CONNECTING_ICON = 1;
private static final int DISCONNECTED_ICON=2;
private static final int SUSPENDED_ICON = 3;
private static final int DELAY_ICON = 4;
private ImageIcon[] connectionStatusIcons;
/**
* The label where icon is shown
*/
private JLabel connectionStatusLbl;
/**
* The label where the icon representing the status of the connection
* with the DB is shown
*/
private JLabel connectionDBLbl;
/**
* The label where appears the icon to tell that there are
* error in the jlog error log dialog
*/
private final JLabel jlogErrorLbl =new JLabel(new ImageIcon(this.getClass().getResource("/errorLogIcon.png")));
/**
* The toolbar
*/
private LogToolBar toolBar;
/**
* The toolbar to navigate logs
*/
private LogNavigationBar navigationToolbar;
/**
* The menu bar
*/
private LogMenuBar menuBar = new LogMenuBar();
/**
* The dialog to choose filters to apply to the engine
*/
private FilterChooserDialog engineFiltersDlg=null;
/**
* The error broser dialog
*/
private ErrorBrowserDlg errorBrowserDialog=null;
/**
* The dialog to manage table filters
* There is only one instance of this dialog that can be visible or invisible.
* It is disposed by calling the close() (usually done by
* the LoggingClient before exiting.
*/
private FilterChooserDialog filterChooserDialog = null;
/**
* The frame containing this logging client.
* It is not null
only if the application is executed in stand alone mode
*/
private final LogFrame logFrame;
/**
* The following property is set if logs runs in debug mode
*/
private static final String DEBUG_MODE_PROPERTY="alma.acs.jlog.debugMode";
/**
* true
if jlog runs in debug mode
*/
private final boolean debugMode=Boolean.getBoolean(DEBUG_MODE_PROPERTY);
/**
* containerServices
is always set while running as OMC plugin.
*
* It is used to avoid creating a new ORB when one is already available. * * @see connect() */ protected ContainerServicesBase containerServices=null; /** * The glass pane showing messages to the user */ private MessageWidget errorWidget=new MessageWidget(); /** * The glass pane visible when jlog runs offline. */ private TransparentGlassPane glassPane; class EventHandler implements ActionListener, MenuListener { public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getSource() == menuBar.getConnectMenuItem()) { connect(menuBar.getConnectMenuItem().getText().compareTo("Connect")==0); } else if (e.getSource() == menuBar.getLoadMenuItem()) { SwingUtilities.invokeLater(new Runnable() { public void run() { getLCModel1().loadFromFile(null); } }); } else if (e.getSource() == menuBar.getLoadURLMenuItem()) { SwingUtilities.invokeLater(new Runnable() { public void run() { getLCModel1().loadFromURL(); } }); } else if (e.getSource() == menuBar.getSaveFileMenuItem()) { SwingUtilities.invokeLater(new Runnable() { public void run() { getLCModel1().saveFile(); } }); } else if (e.getSource() == menuBar.getLoadDBMenuItem()) { if (archive.getDBStatus()==DBState.DATABASE_OK) { if (databaseDlg==null) { databaseDlg = new QueryDlg(archive,LoggingClient.this,LoggingClient.this,LoggingClient.this); } databaseDlg.setVisible(true); } } else if (e.getSource() == menuBar.getClearLogsMenuItem() || e.getSource()==toolBar.getClearLogsBtn()) { Thread t = new Thread("LoggingClient.clearAll") { public void run() { getLCModel1().clearAll(); } }; t.setDaemon(true); t.start(); } else if (e.getSource() == menuBar.getExitMenuItem()) { if (logFrame!=null) { // The application is executed in stand-alone mode // Signal the main window to close WindowEvent wEvt = new WindowEvent(logFrame,WindowEvent.WINDOW_CLOSING); logFrame.dispatchEvent(wEvt); } else { close(false); } }else if (e.getSource() == menuBar.getFieldsMenuItem()) { connFields(e); } else if (e.getSource() == menuBar.getFiltersMenuItem() || e.getSource()==toolBar.getFiltersBtn()) { showTableFiltersDialog(e); } else if (e.getSource()==toolBar.getPauseBtn()) { // Swap set the pause mode in the toolbar toolBar.clickPauseBtn(); // Pause/unpause the engine engine.setPaused(toolBar.isPaused()); } else if (e.getSource()==toolBar.getLogLevelCB()) { getLogEntryTable().setLogLevel((LogTypeHelper)toolBar.getLogLevelCB().getSelectedItem()); } else if (e.getSource()==toolBar.getDiscardLevelCB()){ getEngine().setDiscardLevel(LogTypeHelper.fromLogTypeDescription((String)toolBar.getDiscardLevelCB().getSelectedItem())); } else if (e.getSource()==navigationToolbar.getSearchBtn() || e.getSource()==menuBar.getSearchMenuItem()) { if (searchDialog==null) { searchDialog = new SearchDialog(LoggingClient.this); } searchDialog.setVisible(true); } else if (e.getSource()==menuBar.getSearchNextMenuItem()) { // The searchDialog is always not null otherwise the // menu item is disabled but... repetita juvant ;-) if (searchDialog!=null) { searchDialog.search(); } else { menuBar.getSearchNextMenuItem().setEnabled(false); } } else if (e.getSource()==menuBar.getViewToolbarMenuItem()) { // Hide/Show the toolbar toolBar.setVisible(menuBar.getViewToolbarMenuItem().getState()); } else if (e.getSource()==menuBar.getStatisticsMenuItem()) { // Show the statistics dialog class ShowStatisticDlg extends Thread { public void run() { getStatisticDialog().setVisible(true); } } ShowStatisticDlg showStat = new ShowStatisticDlg(); SwingUtilities.invokeLater(showStat); } else if (e.getSource()==menuBar.getViewErrorLogMenuItem()) { getJLogErroDialog().setVisible(true,LoggingClient.this); jlogErrorLbl.setVisible(false); } else if (e.getSource()==menuBar.getViewErrorBrowserMenuItem()) { getErrorDialog().setVisible(true); } else if (e.getSource()==menuBar.getViewStatusAreaMenuItem()) { getStatusAreaPanel().setVisible(menuBar.getViewStatusAreaMenuItem().getState()); if (menuBar.getViewStatusAreaMenuItem().getState()) { getStatusAreaHrPane().setDividerLocation(getHeight() - 150); } else { getStatusAreaHrPane().setDividerLocation(getHeight()); } } else if (e.getSource()==menuBar.getViewDetailedInfoMenuItem()) { getDeatailedInfoPanel().setVisible(menuBar.getViewDetailedInfoMenuItem().getState()); if (menuBar.getViewDetailedInfoMenuItem().getState()) { int w = getLogEntryTable().getWidth(); getTableDetailsVrPane().setDividerLocation(getTableDetailsVrPane().getWidth() - w/3); } else { getTableDetailsVrPane().setDividerLocation(getTableDetailsVrPane().getWidth()); } } else if (e.getSource()==menuBar.getAutoReconnectMenuItem()) { if (LoggingClient.this.engine!=null) { LoggingClient.this.engine.enableAutoReconnection(menuBar.getAutoReconnectMenuItem().getState()); } } else if (e.getSource()==menuBar.getShortDateViewMenuItem()) { logEntryTable.setShortDateFormat(menuBar.getShortDateViewMenuItem().isSelected()); } else if (e.getSource()==menuBar.getLogTypeDescriptionViewMenuItem()) { logEntryTable.setLogTypeDescriptionView(menuBar.getLogTypeDescriptionViewMenuItem().isSelected()); } else if (e.getSource()==toolBar.getPauseBtn()) { toolBar.clickPauseBtn(); } else if (e.getSource()==menuBar.getSuspendMenuItem()) { getEngine().setSupended(menuBar.getSuspendMenuItem().isSelected()); } else if (e.getSource()==menuBar.getPrefsMenuItem()) { ExpertPrefsDlg dlg = new ExpertPrefsDlg(LoggingClient.this,userPreferences); if (dlg.okPressed()) { UserPreferences newPrefs = dlg.getPreferences(); if (newPrefs.getMaxNumOfLogs()!=userPreferences.getMaxNumOfLogs()) { userPreferences.setMaxLogs(newPrefs.getMaxNumOfLogs()); getLCModel1().setMaxLog(userPreferences.getMaxNumOfLogs()); setNumberOfLogsLbl(); } if (newPrefs.getMinuteTimeFrame()!=userPreferences.getMinuteTimeFrame()) { userPreferences.setTimeFrame(userPreferences.getMinuteTimeFrame()); getLCModel1().setTimeFrame(userPreferences.getMillisecondsTimeFrame()); } if (newPrefs.getMaxInputRate()!=userPreferences.getMaxInputRate()) { userPreferences.setMaxInputRate(newPrefs.getMaxInputRate()); getEngine().setMaxInputRate(userPreferences.getMaxInputRate()); } if (newPrefs.getMaxOutputRate()!=userPreferences.getMaxOutputRate()) { userPreferences.setMaxOutputRate(newPrefs.getMaxOutputRate()); getEngine().setMaxOutputRate(userPreferences.getMaxOutputRate()); } if (newPrefs.getDynThreshold()!=userPreferences.getDynThreshold()) { userPreferences.setDynThreshold(newPrefs.getDynThreshold()); userPreferences.setDynDamping(newPrefs.getDynDamping()); userPreferences.setDynTime(newPrefs.getDynTime()); getEngine().enableDynamicDiscarding( userPreferences.getDynThreshold(), userPreferences.getDynDamping(), userPreferences.getDynTime()); } } } else if (e.getSource()==menuBar.getOperatorMode()) { getEngine().setAudience(AudienceInfo.OPERATOR.getAudience()); audienceLbl.setText(" "+AudienceInfo.OPERATOR.name+" "); } else if (e.getSource()==menuBar.getEngineeringMode()) { getEngine().setAudience(AudienceInfo.ENGINEER.getAudience()); audienceLbl.setText(" "+AudienceInfo.ENGINEER.name+" "); } else if (e.getSource()==menuBar.getSciLogMode()) { getEngine().setAudience(AudienceInfo.SCILOG.getAudience()); audienceLbl.setText(" "+AudienceInfo.SCILOG.name+" "); } else if (e.getSource()==menuBar.getEngineFiltersMenuItem()) { showEngineFiltersDialog(); } else if (e.getSource()==menuBar.getZoomPrefsMI()) { ZoomPrefsDlg dlg = new ZoomPrefsDlg(LoggingClient.this,zoom); boolean zoomAvailable=zoom.isAvailable(); toolBar.setZoomable(zoomAvailable && logEntryTable.getSelectedRowCount()>1); menuBar.getManualZoomMI().setEnabled(zoomAvailable); } else if (e.getSource()==menuBar.getManualZoomMI()) { class ShowManualZoom extends Thread { public void run() { if (manualZoomDlg==null) { manualZoomDlg=new ManualZoomDlg(LoggingClient.this,zoom); } manualZoomDlg.setVisible(true); } } SwingUtilities.invokeLater(new ShowManualZoom()); } else if (e.getSource()==toolBar.getZoomBtn()) { Thread t = new Thread(new Runnable() { public void run() { logEntryTable.zoom(); } }); t.setDaemon(true); t.setName("LoggingClient.actionPerformed.Zoom"); t.start(); } else { System.err.println("Unrecognized ActionEvent "+e); } }; public void menuCanceled(MenuEvent menuE) {} public void menuDeselected(MenuEvent menuE) {} public void menuSelected(MenuEvent menuE) { // Some menus are disabled when loading/saving boolean enableMenu = !getLCModel1().IOInProgress(); menuBar.getClearLogsMenuItem().setEnabled(enableMenu); if (getEngine().isConnected()) { menuBar.getConnectMenuItem().setText("Disconnect"); } else { menuBar.getConnectMenuItem().setText("Connect"); } menuBar.getConnectMenuItem().setEnabled(enableMenu); menuBar.getLoadMenuItem().setEnabled(enableMenu); menuBar.getLoadURLMenuItem().setEnabled(enableMenu); menuBar.getSaveFileMenuItem().setEnabled(enableMenu); // Ensure the status of the item shown in the main panel // is consistent with the menu item in View menuBar.getViewStatusAreaMenuItem().setSelected(getStatusAreaPanel().isVisible()); menuBar.getViewDetailedInfoMenuItem().setSelected(getDeatailedInfoPanel().isVisible()); menuBar.getViewToolbarMenuItem().setSelected(toolBar.isVisible()); // This button is always disabled since when the logs are not stored in the DB // see ICT-1649 // If you want to enable depending on the avalability of the DB // the replace false below with "archive.getDBStatus()==DBState.DATABASE_OK" menuBar.getLoadDBMenuItem().setEnabled(false); } } /** * Constructor *
* The empty constructor is called by the OMC GUI. * */ public LoggingClient() { super(); logFrame=null; initialize(DEFAULT_LOGLEVEL,DEFAULT_DISCARDLEVEL,false); initAudience(null); } /** * The constructor *
* This constructor is called when this object runs in stand-alone mode
* i.e outside of the OMC GUI.
*
* @param frame The shows this object
* @param logLevel The initial log level
* @param discardLevel The initial discard level
* @param unlimited If true
the number of logs in memory is unlimited,
* otherwise the default is used
*/
public LoggingClient(
LogFrame frame,
LogTypeHelper logLevel,
LogTypeHelper discardLevel,
boolean unlimited,
AudienceInfo aInfo)
{
super();
isStopped=false;
logFrame=frame;
initialize(logLevel, discardLevel, unlimited);
initAudience(aInfo);
}
/**
* Method used by the plugin interface in EXEC:
* it connects the application to the NC
*
* @see alma.exec.extension.subsystemplugin.SubsystemPlugin
*
* @throws Exception
*/
public void start() throws Exception {
if (containerServices==null) {
throw new IllegalArgumentException("Starting the plugin without setting the ContainerServices");
}
isStopped=false;
connect();
}
/**
* Method used by the plugin interface in EXEC.
* Stop the application disconnecting from the NC
* @see alma.exec.extension.subsystemplugin.SubsystemPlugin
*
* @throws Exception
*/
public void stop() throws Exception {
isStopped=true;
close(false);
}
/**
* Method used by the plugin interface in EXEC.
* Pause the application (scroll lock enabled)
* @see alma.exec.extension.subsystemplugin.IPauseResume
*
* @throws Exception
*/
public void pause() throws Exception {
toolBar.pause();
engine.setPaused(true);
}
/**
* Method used by the plugin interface in EXEC.
* Unpause the application (scroll lock disabled)
* @see alma.exec.extension.subsystemplugin.IPauseResume
*
* @throws Exception
*/
public void resume() throws Exception {
toolBar.unpause();
engine.setPaused(false);
}
/**
* Connect or disconnect the engine to the NC
*
* @param connect If true the engine is connected
* otherwise it is disconnected
*/
public void connect(boolean connectEngine) {
if (connectEngine) {
// Check and eventually un-suspend the engine
menuBar.getSuspendMenuItem().setSelected(false);
getEngine().setSupended(menuBar.getSuspendMenuItem().isSelected());
// Connect the the channel
connect();
} else {
menuBar.getAutoReconnectMenuItem().setState(false);
LoggingClient.this.engine.enableAutoReconnection(false);
disconnect();
}
}
/**
* Connects to the remote system
* as soon as the item "New" is clicked.
*/
public void connect() {
if (containerServices!=null) {
ORB orb=null;
AdvancedContainerServices advContSvc = containerServices.getAdvancedContainerServices();
if (advContSvc!=null) {
orb = advContSvc.getORB();
getEngine().setConnectionParams(orb, null);
}
}
try {
getEngine().connect("ACS");
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
private void disconnect() {
getEngine().disconnect();
}
/**
* Triggers the Field Choser's dialog visual appearance
* as soon as the item "Fields" is clicked.
* @param arg1 java.awt.event.ActionEvent
*/
private void connFields(java.awt.event.ActionEvent arg1)
{
try
{
getLogEntryTable().showFieldChooser();
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
/**
Triggers the Filters dialog visual appearance
* as soon as the item "Filters" is clicked.
* @param arg1 java.awt.event.ActionEvent
*/
private void showTableFiltersDialog(java.awt.event.ActionEvent arg1) {
class TableFilterable implements Filterable {
/* (non-Javadoc)
* @see com.cosylab.logging.engine.Filterable#getFilters()
*/
@Override
public FiltersVector getFilters() {
return logEntryTable.getFilters();
}
/* (non-Javadoc)
* @see com.cosylab.logging.engine.Filterable#setFilters(com.cosylab.logging.engine.FiltersVector, boolean)
*/
@Override
public void setFilters(FiltersVector newFilters, boolean append) {
logEntryTable.setFilters(newFilters, append);
setTableFilterLbl();
}
}
if (filterChooserDialog==null) {
filterChooserDialog=new FilterChooserDialog("Filter chooser",this,new TableFilterable());
}
filterChooserDialog.setFilters(logEntryTable.getFilters());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
enableFiltersWidgets(false);
filterChooserDialog.setVisible(true);
}
});
}
/**
* Update the label of the filtering of the table
*/
public void setTableFilterLbl() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (logEntryTable.getFilters().hasActiveFilters()) {
tableFiltersLbl.setForeground(Color.RED);
tableFiltersLbl.setText("Table filtered");
tableFiltersLbl.setToolTipText(logEntryTable.getFiltersString());
} else {
tableFiltersLbl.setForeground(Color.BLACK);
tableFiltersLbl.setText("Table not filtered");
tableFiltersLbl.setToolTipText(null);
}
}
});
}
/**
* Update the label with the number of logs in memory
*/
private void setNumberOfLogsLbl() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int nLogs=userPreferences.getMaxNumOfLogs();
if (nLogs>0) {
String str=Integer.toString(nLogs);
if (str.length()>3) {
str = str.substring(0, str.length()-3)+"K";
}
maxNumOfLogsLbl.setForeground(Color.RED);
maxNumOfLogsLbl.setText(str);
maxNumOfLogsLbl.setToolTipText("The number of logs to keep in memory is limited to "+str);
} else {
maxNumOfLogsLbl.setForeground(Color.BLACK);
maxNumOfLogsLbl.setText("Unlimited");
maxNumOfLogsLbl.setToolTipText("The number of logs to keep in memory is unlimited");
}
}
});
}
/**
* Update the label of the filtering of the table
*/
private void setEngineFilterLbl() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (engine==null || engine.getFilters()==null || !engine.getFilters().hasActiveFilters()) {
engineFiltersLbl.setForeground(Color.BLACK);
engineFiltersLbl.setText("Engine not filtered");
engineFiltersLbl.setToolTipText(null);
} else {
engineFiltersLbl.setForeground(Color.RED);
engineFiltersLbl.setText("Engine filtered");
engineFiltersLbl.setToolTipText(engine.getFiltersString());
}
}
});
}
/**
* Returns the JFrameContentPane property value.
* @return javax.swing.JPanel
*/
private JPanel getJFrameContentPane()
{
if (ivjJFrameContentPane == null)
{
try
{
ivjJFrameContentPane = new JPanel();
ivjJFrameContentPane.setName("JFrameContentPane");
ivjJFrameContentPane.setLayout(new BorderLayout());
ivjJFrameContentPane.add(getStatusAreaHrPane(), "Center");
}
catch (Throwable ivjExc)
{
handleException(ivjExc);
}
}
return ivjJFrameContentPane;
}
/**
* CustomColumnListener implements componentResized() of a ComponentListener.
* It has been added to JScrollPane scrollLogTable to increase the width of
* the Log Message column as soon as the space is available.
*/
private class CustomColumnListener implements ComponentListener
{
public void componentShown(ComponentEvent evt)
{
}
public void componentHidden(ComponentEvent evt)
{
}
public void componentMoved(ComponentEvent evt)
{
}
// This method is called after the component's size changes
public void componentResized(ComponentEvent evt)
{
// gets the component JTable LogEntryTable that has been changed
Component c = (Component) evt.getSource();
// gets the width of JTable LogEntryTable
// in case a vertical ScrollBar appears the width remains the same
int tableWidthTobe = c.getSize().width;
// sets a preferred size to JScrollPane
getLogEntryTable().setPreferredScrollableViewportSize(new Dimension(tableWidthTobe, c.getSize().height));
// gets the number of columns in JTable LogEntryTable
int numCols = getLogEntryTable().getColumnModel().getColumnCount();
// computes the width of the table taking into consideration all visible columns
int columnWidth = getLogEntryTable().getColumnWidth(numCols);
// adds width to the Log Message column
getLogEntryTable().setAdditionalWidth(numCols, tableWidthTobe - columnWidth);
}
}
/**
* Returns the scroll panel with the table of logs
* @return the scroll panel with the table of logs
*/
public JScrollPane getLogTableScroolP() {
if (scrollLogTable == null) {
try {
scrollLogTable = new JScrollPane(getLogEntryTable(),JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollLogTable.setName("scrollLogTable");
scrollLogTable.setBackground(new Color(204, 204, 204));
scrollLogTable.setFont(new Font("Arial", 1, 12));
scrollLogTable.setMinimumSize(new Dimension(100, 50));
scrollLogTable.addComponentListener(new CustomColumnListener());
scrollLogTable.getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE);
} catch (Throwable ivjExc) {
handleException(ivjExc);
}
}
return scrollLogTable;
}
/**
* Returns the table of logs
* @return the table of logs
*/
public LogEntryTable getLogEntryTable() {
if (logEntryTable == null) {
try {
logEntryTable = new LogEntryTable(
this,
menuBar.getShortDateViewMenuItem().isSelected(),
menuBar.getLogTypeDescriptionViewMenuItem().isSelected());
logEntryTable.setName("logEntryTable");
logEntryTable.setBounds(0, 0, 200, 200);
tableModel=logEntryTable.getLCModel();
} catch (Throwable ivjExc) {
handleException(ivjExc);
}
}
return logEntryTable;
}
/**
* Called whenever the part throws an exception.
* @param exception java.lang.Throwable
*/
private void handleException(java.lang.Throwable exception)
{
showErrorMessage("Uncaught exception", exception);
}
/**
* Initializes connections and adds listeners to all the menus and menu items.
* @exception java.lang.Exception The exception description.
*/
private void initConnections() throws java.lang.Exception
{
menuBar.setEventHandler(eventHandler, eventHandler);
toolBar.setEventHandler(eventHandler);
navigationToolbar.setEventHandler(eventHandler);
}
/**
* Initializes the object.
*
* @param logLevel The initial log level to set in the toolbar and in the table
* @param discardLevel The initial discard level to set in the toolbar and in the engine
* @param unlimited If true
the number of logs in memory is unlimited,
* otherwise the default is used
*/
private void initialize(LogTypeHelper logLevel, LogTypeHelper discardLevel, boolean unlimited)
{
try
{
setName("LoggingClientPanel");
messageTextArea = new ExtendedTextArea();
// Set the glass pane showing errors and messages to be acknowledged
glassPane = new TransparentGlassPane(getContentPane());
setGlassPane(glassPane);
// We want to be notified when the user presses the Ok button
// of the MessageWidget
errorWidget.addAckListener(this);
// Set the tooltip manager
ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
toolTipManager.setDismissDelay(60000);
Dimension d = new Dimension(750, 550);
setPreferredSize(d);
getContentPane().setLayout(new BorderLayout());
setJMenuBar(menuBar);
// Add the GUI in the center position
getContentPane().add(getJFrameContentPane(),BorderLayout.CENTER);
// The panel having the toolbars on top and the panel showing errors at the bottom
JPanel northPanel = new JPanel(new BorderLayout());
// Add the toolbars to the toolbarsPanel
JPanel toolbarsPanel = new JPanel();
BoxLayout toolbarLayout = new BoxLayout(toolbarsPanel,BoxLayout.Y_AXIS);
toolbarsPanel.setLayout(toolbarLayout);
toolBar = new LogToolBar(logLevel,discardLevel);
boolean zoomAvailable=zoom.isAvailable();
toolBar.setZoomable(zoomAvailable);
menuBar.getManualZoomMI().setEnabled(zoomAvailable);
toolbarsPanel.add(toolBar);
navigationToolbar = new LogNavigationBar(getLogEntryTable());
toolbarsPanel.add(navigationToolbar);
northPanel.add(toolbarsPanel,BorderLayout.NORTH);
northPanel.add(errorWidget,BorderLayout.SOUTH);
getContentPane().add(northPanel,BorderLayout.NORTH);
initConnections();
validate();
getLogEntryTable().setLogLevel((LogTypeHelper)toolBar.getLogLevelCB().getSelectedItem());
if (unlimited) {
userPreferences.setMaxLogs(0);
}
getLCModel1().setTimeFrame(userPreferences.getMillisecondsTimeFrame());
getLCModel1().setMaxLog(userPreferences.getMaxNumOfLogs());
archive = new ArchiveConnectionManager(this);
setTableFilterLbl();
setEngineFilterLbl();
setNumberOfLogsLbl();
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
getTableDetailsVrPane().setDividerLocation(getTableDetailsVrPane().getLastDividerLocation());
getStatusAreaHrPane().setDividerLocation(350); //getHeight() - 150);
}
/**
* Show a detailed view of the selected log in the right panel
*/
public void showDetailedLogInfo()
{
try {
LogEntryTable jt = getLogEntryTable();
int selectedRow = jt.getSelectedRow();
// Check whether a row has been selected
// no row selected
if (selectedRow == -1) {
detailedLogTable.setupContent(null);
} else {
// a row is selected
ILogEntry log = jt.getLCModel().getVisibleLogEntry(selectedRow);
detailedLogTable.setupContent(log);
}
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
}
/**
* Set the content of the detailed info table from the given log
*
* @param log The log entry which fields have to be shown in the table
* It can be null
*/
public void setLogDetailContent(ILogEntry log)
{
// Try to build a DetailedLogTable
class DetailedLogFiller implements Runnable {
public ILogEntry logToWrite;
public void run() {
detailedLogTable.setupContent(logToWrite);
}
}
DetailedLogFiller filler = new DetailedLogFiller();
filler.logToWrite=log;
SwingUtilities.invokeLater(filler);
}
/**
* Disconnects the LCEngine.
* @param arg1 java.awt.event.WindowEvent
*/
public void connLCEngDisconnect(WindowEvent arg1)
{
try
{
getEngine().disconnect();
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
/**
* Returns the JPanel2 property value.
* @return javax.swing.JPanel
*/
private JPanel getJPanel2() {
if (ivjJPanel2 == null) {
try {
ivjJPanel2 = new JPanel();
ivjJPanel2.setName("JPanel2");
ivjJPanel2.setLayout(new BorderLayout());
ivjJPanel2.add(getStatusLinePnl(), "South");
ivjJPanel2.add(getTableDetailsVrPane(), "Center");
} catch (Throwable ivjExc) {
handleException(ivjExc);
}
}
return ivjJPanel2;
}
/**
* Returns the JPanel3 property value.
* @return javax.swing.JPanel
*/
private JPanel getDeatailedInfoPanel()
{
if (detailedInfoPanel == null)
{
try
{
BorderLayout layout = new BorderLayout();
layout.setVgap(10);
detailedInfoPanel = new JPanel(layout);
detailedInfoPanel.setName("detailedInfoPanel");
JLabel lbl =new JLabel("Detailed info");
detailedInfoPanel.add(lbl,BorderLayout.NORTH);
detailedInfoPanel.add(getLogDetailScrollPane(), BorderLayout.CENTER);
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
return detailedInfoPanel;
}
/**
* Returns the panel for the status line
*
* @return the panel for the status line
*/
private JPanel getStatusLinePnl()
{
if (statusLinePnl == null)
{
try
{
// Load the icons for the status of the connection
connectionStatusIcons = new ImageIcon[5];
connectionStatusIcons[CONNECTED_ICON]=new ImageIcon(this.getClass().getResource("/console-connected.png"));
connectionStatusIcons[CONNECTING_ICON]=new ImageIcon(this.getClass().getResource("/console-connecting.png"));
connectionStatusIcons[DISCONNECTED_ICON]=new ImageIcon(this.getClass().getResource("/console-disconnected.png"));
connectionStatusIcons[SUSPENDED_ICON]=new ImageIcon(this.getClass().getResource("/console-suspended.png"));
connectionStatusIcons[DELAY_ICON]=new ImageIcon(this.getClass().getResource("/console-delay.png"));
connectionStatusLbl = new JLabel(connectionStatusIcons[CONNECTING_ICON]);
// Create a label to show the status of the connection with the DB
connectionDBLbl = new JLabel();
statusLinePnl = new javax.swing.JPanel();
statusLinePnl.setName("Status_line");
statusLinePnl.setLayout(new java.awt.GridBagLayout());
GridBagConstraints constraintsProgressBar = new GridBagConstraints();
constraintsProgressBar.gridx=0;
constraintsProgressBar.gridy=0;
constraintsProgressBar.fill = GridBagConstraints.BOTH;
constraintsProgressBar.anchor = GridBagConstraints.WEST;
constraintsProgressBar.weightx = 1.0;
constraintsProgressBar.insets = new Insets(1, 2, 1, 1);
statusLinePnl.add(progressBar,constraintsProgressBar);
GridBagConstraints constraintsNumFlt = new GridBagConstraints();
constraintsNumFlt.gridx=1;
constraintsNumFlt.gridy=0;
constraintsNumFlt.insets = new Insets(1,1,1,1);
maxNumOfLogsLbl.setVisible(true);
maxNumOfLogsLbl.setBorder(BorderFactory.createLoweredBevelBorder());
Font fntNumFlt = maxNumOfLogsLbl.getFont();
Font newFontNumFlt = fntNumFlt.deriveFont(fntNumFlt.getSize()-2);
maxNumOfLogsLbl.setFont(newFontNumFlt);
statusLinePnl.add(maxNumOfLogsLbl,constraintsNumFlt);
GridBagConstraints constraintsEngineFlt = new GridBagConstraints();
constraintsEngineFlt.gridx=2;
constraintsEngineFlt.gridy=0;
constraintsEngineFlt.insets = new Insets(1,1,1,1);
engineFiltersLbl.setVisible(true);
engineFiltersLbl.setBorder(BorderFactory.createLoweredBevelBorder());
Font fntEngineFlt = engineFiltersLbl.getFont();
Font newFontEngineFlt = fntEngineFlt.deriveFont(fntEngineFlt.getSize()-2);
engineFiltersLbl.setFont(newFontEngineFlt);
statusLinePnl.add(engineFiltersLbl,constraintsEngineFlt);
GridBagConstraints constraintsTableFlt= new GridBagConstraints();
constraintsTableFlt.gridx=3;
constraintsTableFlt.gridy=0;
constraintsTableFlt.insets = new Insets(1,1,1,1);
tableFiltersLbl.setVisible(true);
tableFiltersLbl.setBorder(BorderFactory.createLoweredBevelBorder());
Font fntTableFlt = tableFiltersLbl.getFont();
Font newFontTableFlt = fntTableFlt.deriveFont(fntTableFlt.getSize()-2);
tableFiltersLbl.setFont(newFontTableFlt);
statusLinePnl.add(tableFiltersLbl,constraintsTableFlt);
GridBagConstraints constraintsAudience = new GridBagConstraints();
constraintsAudience.gridx=4;
constraintsAudience.gridy=0;
constraintsAudience.insets = new Insets(1,1,1,1);
audienceLbl.setVisible(true);
audienceLbl.setBorder(BorderFactory.createLoweredBevelBorder());
Font fnt = audienceLbl.getFont();
Font newFont = fnt.deriveFont(fnt.getSize()-2);
audienceLbl.setFont(newFont);
statusLinePnl.add(audienceLbl,constraintsAudience);
GridBagConstraints constraintsConnectionDBStatus = new GridBagConstraints();
constraintsConnectionDBStatus.gridx = 5;
constraintsConnectionDBStatus.gridy = 0;
constraintsConnectionDBStatus.insets = new Insets(1, 2, 1, 2);
statusLinePnl.add(connectionDBLbl,constraintsConnectionDBStatus);
GridBagConstraints constraintsJlogErrors = new GridBagConstraints();
constraintsConnectionDBStatus.gridx = 6;
constraintsConnectionDBStatus.gridy = 0;
constraintsConnectionDBStatus.insets = new Insets(1, 2, 1, 2);
statusLinePnl.add(jlogErrorLbl,constraintsJlogErrors);
jlogErrorLbl.setVisible(false);
jlogErrorLbl.setToolTipText("Error reading logs");
jlogErrorLbl.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
jlogErrorLbl.setVisible(false);
errorDialog.setVisible(true,LoggingClient.this);
super.mouseClicked(e);
}
});
GridBagConstraints constraintsConnectionStatus = new GridBagConstraints();
constraintsConnectionStatus.gridx = 7;
constraintsConnectionStatus.gridy = 0;
constraintsConnectionStatus.insets = new Insets(1, 2, 1, 2);
statusLinePnl.add(connectionStatusLbl,constraintsConnectionStatus);
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
return statusLinePnl;
}
/**
* Returns the JScrollPane1 property value.
* @return javax.swing.JScrollPane
*/
private javax.swing.JScrollPane getStatusAreaPanel()
{
if (statusAreaPanel == null)
{
try
{
statusAreaPanel = new javax.swing.JScrollPane();
statusAreaPanel.setName("JScrollPane1");
statusAreaPanel.setVerticalScrollBarPolicy(javax.swing.JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
statusAreaPanel.setPreferredSize(new java.awt.Dimension(50, 50));
statusAreaPanel.setMinimumSize(new java.awt.Dimension(50, 50));
statusAreaPanel.setViewportView(messageTextArea);
statusAreaPanel.setVisible(false);
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
return statusAreaPanel;
}
/**
* Returns the scroll pane with the details of the logs
*
* @return JScrollPane
*/
public JScrollPane getLogDetailScrollPane()
{
if (detailedInfoScrollPane == null)
{
try
{
detailedInfoScrollPane = new JScrollPane(detailedLogTable);
detailedInfoScrollPane.setName("detailedInfoScrollPane");
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
return detailedInfoScrollPane;
}
/**
* Returns the JSplitPane1 property value.
* @return javax.swing.JSplitPane
*/
private JSplitPane getStatusAreaHrPane()
{
if (statusAreaHrSplitP == null)
{
try
{
statusAreaHrSplitP = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
statusAreaHrSplitP.setName("JSplitPane1");
statusAreaHrSplitP.setLastDividerLocation(350);
statusAreaHrSplitP.setDividerLocation(350);
statusAreaHrSplitP.add(getStatusAreaPanel(), "bottom");
statusAreaHrSplitP.add(getJPanel2(), "top");
}
catch (Throwable ivjExc)
{
handleException(ivjExc);
}
}
return statusAreaHrSplitP;
}
/**
* @return the split pane with the table of logs and the table with the details of a log
*/
private JSplitPane getTableDetailsVrPane() {
if (tableDetailsVrSplitP == null) {
try {
tableDetailsVrSplitP = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
tableDetailsVrSplitP.setName("TableDetailsSplitPane");
tableDetailsVrSplitP.setLastDividerLocation(570);
tableDetailsVrSplitP.setAlignmentX(Component.LEFT_ALIGNMENT);
tableDetailsVrSplitP.setContinuousLayout(true);
//ivjJSplitPane2.setDividerLocation(501);
tableDetailsVrSplitP.add(getLogTableScroolP(),"left");
tableDetailsVrSplitP.add(getDeatailedInfoPanel(), "right");
} catch (Throwable ivjExc) {
handleException(ivjExc);
}
}
return tableDetailsVrSplitP;
}
/**
* Returns the LCEngine property value.
* @return com.cosylab.logging.LCEngine
*/
public LCEngine getEngine()
{
if (engine == null)
{
try {
engine = new LCEngine();
engine.addLogConnectionListener(this);
engine.addLogListener(this);
engine.addLogErrorListener(this);
engine.setDiscardLevel(LogTypeHelper.fromLogTypeDescription((String)toolBar.getDiscardLevelCB().getSelectedItem()));
if (logFrame!=null) {
engine.addLogConnectionListener(logFrame);
}
}
catch (java.lang.Throwable ivjExc)
{
handleException(ivjExc);
}
}
return engine;
}
/**
* Returns the LCModel1 property value.
* @return com.cosylab.logging.LogTableDataModel
*/
public LogTableDataModel getLCModel1()
{
return tableModel;
}
/**
* Sets the height and width generated by user's actions.
*/
public void loggingClient_ComponentResized(ComponentEvent e) {
if (e.getComponent() == this) {
int w = getLogEntryTable().getWidth();
int h = getLogEntryTable().getHeight();
System.out.println(w + ", " + h);
System.out.println(getTableDetailsVrPane().getWidth());
System.out.println(getStatusAreaHrPane().getHeight());
getTableDetailsVrPane().setDividerLocation(getTableDetailsVrPane().getWidth() - w);
getStatusAreaHrPane().setDividerLocation(getStatusAreaHrPane().getHeight() - h);
}
}
/**
* Sets the LCModel1 to a new value.
* @param newValue com.cosylab.logging.LogTableDataModel
*/
private void setLCModel1(LogTableDataModel newValue) {
if (tableModel != newValue) {
try {
tableModel = newValue;
} catch (java.lang.Throwable ivjExc) {
handleException(ivjExc);
}
};
}
/**
* Enable or disable the Search next menu item
* (tipically this action is preformed by the SearchDialog when a valid search
* is performed)
*
* @param enable true enable the searchNextMenuItem
*/
public void enableSearchNext(boolean enable) {
menuBar.getSearchNextMenuItem().setEnabled(enable);
}
/**
* Show the progres bar as determinate with the given min and max
*
* @param textThe text to show in the toolbar
* If it is null or empty then no text will be displayed
* @param min The starting position
* @param max The final position
*/
public void animateProgressBar(final String text, final int min, final int max) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (min>=max) {
throw new IllegalArgumentException("Invalid range: ["+min+","+max+"]");
}
Cursor hourglassCursor = new Cursor(Cursor.WAIT_CURSOR);
setCursor(hourglassCursor);
if (text!=null && text.length()>0) {
progressBar.setString(text);
progressBar.setStringPainted(true);
progressBar.setToolTipText(text);
} else {
progressBar.setStringPainted(false);
progressBar.setToolTipText("Wait please");
}
progressBar.setMinimum(min);
progressBar.setMaximum(max);
progressBar.setIndeterminate(false);
progressBar.setVisible(true);
}
});
}
/**
* Move the progressbar when in determinate mode
* @param newPos
*/
public void moveProgressBar(final int newPos) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressBar.setValue(newPos);
}
});
}
/**
* Show the progress bar as indeterminate
*
*@param text The text to show in the toolbar
* If it is null or empty then no text will be displayed
*/
public void animateProgressBar(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Cursor hourglassCursor = new Cursor(Cursor.WAIT_CURSOR);
setCursor(hourglassCursor);
if (text!=null && text.length()>0) {
progressBar.setString(text);
progressBar.setStringPainted(true);
progressBar.setToolTipText(text);
} else {
progressBar.setStringPainted(false);
progressBar.setToolTipText("Wait please");
}
progressBar.setIndeterminate(true);
}
});
}
/**
* Hide the progress bar (i.e. a long operation
* has terminated)
*/
public void freezeProgressBar() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressBar.setIndeterminate(false);
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setValue(0);
progressBar.setStringPainted(false);
progressBar.setToolTipText(null);
Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
setCursor(normalCursor);
}
});
}
/**
* @return true if the application is connected to the notification channel
*
*/
public boolean isConnected() {
return isConnected;
}
/**
*
* @return The discard log level
* @see LoggingClient.discardLevelCB
*/
public int getDiscardLevel() {
return toolBar.getDiscardLevelCB().getSelectedIndex();
}
/**
* @see com.cosylab.logging.engine.ACS.ACSRemoteLogListener
*/
public void logEntryReceived(ILogEntry logEntry) {
getLogEntryTable().getLCModel().appendLog(logEntry);
}
/**
* Append the report status message to the status area
*
* @see com.cosylab.logging.engine.ACS.ACSRemoteLogListener
*/
public void reportStatus(String status) {
messageTextArea.append(status);
}
/**
* Notify that the connection with ACS NC has been established
* @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener
*/
public void acsLogConnEstablished() {
isConnected=true;
connectionStatusLbl.setIcon(connectionStatusIcons[CONNECTED_ICON]);
connectionStatusLbl.setToolTipText("Connected");
glassPane.setVisible(false);
if (errorWidget.getAckButton().isVisible()) {
errorWidget.getAckButton().doClick();
}
}
/**
*
* @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener
*/
public void acsLogConnDisconnected() {
isConnected=false;
connectionStatusLbl.setIcon(connectionStatusIcons[DISCONNECTED_ICON]);
connectionStatusLbl.setToolTipText("Disconnected");
glassPane.setVisible(true);
}
/**
* Notify that the connection with ACS NC has been lost
*@see com.cosylab.logging.engine.ACS.ACSLogConnectionListener
*/
public void acsLogConnLost() {
isConnected=false;
// Does not show the dialog if the application is stopped
if (isStopped) {
return;
}
glassPane.setVisible(true);
showErrorMessage("Connection lost",null);
}
/**
* Notify that an attempt to connect to ACS NC is in progress
* @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener
*/
public void acsLogConnConnecting() {
connectionStatusLbl.setIcon(connectionStatusIcons[CONNECTING_ICON]);
connectionStatusLbl.setToolTipText("Connecting");
}
/**
* Notify that the service is suspended
* @see com.cosylab.logging.engine.ACS.ACSLogConnectionListener
*/
public void acsLogConnSuspended() {
connectionStatusLbl.setIcon(connectionStatusIcons[SUSPENDED_ICON]);
connectionStatusLbl.setToolTipText("Suspended");
}
/**
* Notify that for some internal reason the service is not able
* to follow the flow of the incoming logs
* @see com.cosylab.logging.engine.ACS.ACSRemoteLogListener
*/
public void acsLogsDelay() {
connectionStatusLbl.setIcon(connectionStatusIcons[DELAY_ICON]);
connectionStatusLbl.setToolTipText("Delay");
}
/**
* Update the GUI with the status of the DB connection
*
* @param icon The icon
* @param msg A message to show as tooltip
*/
public void showDBStatus(ImageIcon icon,String msg) {
connectionDBLbl.setIcon(icon);
connectionDBLbl.setToolTipText(msg);
}
/**
* @return A reference to the preferences
*/
public UserPreferences getPrefs() {
return userPreferences;
}
/**
* Return true if the application is paused
*
* @return
*/
public boolean isPaused() {
return toolBar.isPaused();
}
/**
* Hide the Exit menu item
*
* @param hide If true the menu is set to invisible
*/
public void hideExitMenu(boolean hide) {
menuBar.hideExitMenu(hide);
}
/**
* Close all the threads and release all the resources
* @param sync If it is true wait the termination of the threads before returning
*/
public void close(boolean sync) {
setVisible(false);
if (tableModel!=null) {
tableModel.close(sync);
}
if (logEntryTable!=null) {
logEntryTable.close();
}
if (engine!=null) {
engine.close(sync);
}
if (errorDialog!=null) {
errorDialog.setVisible(false);
errorDialog.dispose();
errorDialog=null;
}
if (statsDlg!=null) {
statsDlg.setVisible(false);
statsDlg.dispose();
statsDlg=null;
}
if (searchDialog!=null) {
searchDialog.setVisible(false);
searchDialog.dispose();
searchDialog=null;
}
if (engineFiltersDlg!=null) {
engineFiltersDlg.setVisible(false);
engineFiltersDlg.dispose();
engineFiltersDlg=null;
}
if (filterChooserDialog!=null) {
filterChooserDialog.setVisible(false);
filterChooserDialog.dispose();
filterChooserDialog=null;
}
if (errorBrowserDialog!=null) {
errorBrowserDialog.close();
errorBrowserDialog=null;
}
if (databaseDlg!=null) {
databaseDlg.close();
databaseDlg=null;
}
if (manualZoomDlg!=null) {
manualZoomDlg.close();
manualZoomDlg=null;
}
}
/**
* Enable/disable the filter menu item and the filter button
* in the tool bar.
*
* Calling this method overwrites the setting of the tool bar's "filtersBtn" * via {@link LogToolBar#setEnabled(boolean)}. * This feature is needed to disable this button when jlog runs inside the OMC, * because there we get calls to LogToolBar#setEnabled(true) * for every table update, menu opening etc. * * @param enable true enables the widgets */ public void enableFiltersWidgets(boolean enable) { toolBar.enableFiltersButtonOverwrite(enable); toolBar.setEnabled(enable); menuBar.getFiltersMenuItem().setEnabled(enable); menuBar.getEngineFiltersMenuItem().setEnabled(enable); } /** * @see ACSRemoteErrorListener */ public void errorReceived(String xml) { StringBuilder str = new StringBuilder("Error parsing the following log: \n"); str.append(xml); str. append("\n The log has been lost.\n\n"); getJLogErroDialog().appendText(str.toString()); if (!getJLogErroDialog().isVisible()) { jlogErrorLbl.setVisible(true); } } /** * Return a dialog showing the statistics * * @return The dialog showing the statistic */ public StatsDlg getStatisticDialog() { if (statsDlg==null) { statsDlg=new StatsDlg(this); } return statsDlg; } /** * Init the audience. *
* If an audience has been specified in the command line then
* it will be used otherwise it tries to check if a java property
* has been set.
*
* The audience dafaults to ENGINEER.
*
* @param audienceInfo The audience: it can be null
.
*/
protected void initAudience(AudienceInfo audienceInfo) {
AudienceInfo aInfo=null;
if (audienceInfo!=null) {
// Audience set in the command line
aInfo=audienceInfo;
} else {
String audienceProp=System.getProperty(AUDIENCE_PROPERTY);
if (audienceProp==null || audienceProp.isEmpty()) {
menuBar.getEngineeringMode().doClick();
return;
}
aInfo=AudienceInfo.fromShortName(audienceProp);
if (aInfo==null) {
// Invalid property name
System.err.println(audienceProp+" is not a valid audience: using default audience");
System.err.println("Available audiences are: ");
for (String aShortName: AudienceInfo.getShortNames()) {
System.err.println("\t"+aShortName);
}
menuBar.getEngineeringMode().doClick();
return;
}
}
switch (aInfo) {
case ENGINEER: {
menuBar.getEngineeringMode().doClick();
return;
}
case OPERATOR: {
menuBar.getOperatorMode().doClick();
return;
}
case SCILOG: {
menuBar.getSciLogMode().doClick();
return;
}
default: {
// Unknown audience
menuBar.getEngineeringMode().doClick();
return;
}
}
}
/**
* Shows the dialog to set filters in the engine
*/
private void showEngineFiltersDialog() {
class EngineFilterable implements Filterable {
/* (non-Javadoc)
* @see com.cosylab.logging.engine.Filterable#getFilters()
*/
@Override
public FiltersVector getFilters() {
return engine.getFilters();
}
/* (non-Javadoc)
* @see com.cosylab.logging.engine.Filterable#setFilters(com.cosylab.logging.engine.FiltersVector, boolean)
*/
@Override
public void setFilters(FiltersVector newFilters, boolean append) {
engine.setFilters(newFilters, append);
setEngineFilterLbl();
}
}
if (engineFiltersDlg==null) {
engineFiltersDlg = new FilterChooserDialog("Engine filters",this,new EngineFilterable());
}
FiltersVector engineFilters = engine.getFilters();
if (engineFilters==null) {
engineFilters = new FiltersVector();
}
engineFiltersDlg.setFilters(engineFilters);
engineFiltersDlg.setVisible(true);
}
/* (non-Javadoc)
* @see javax.swing.JComponent#setEnabled(boolean)
*/
@Override
public void setEnabled(boolean enabled) {
if (toolBar!=null) {
toolBar.setEnabled(enabled);
}
if (navigationToolbar!=null) {
navigationToolbar.setEnabled(enabled);
}
menuBar.setEnabled(enabled);
super.setEnabled(enabled);
}
/**
* @return The error browser dialog
*/
public ErrorBrowserDlg getErrorDialog() {
if (errorBrowserDialog==null) {
errorBrowserDialog=new ErrorBrowserDlg(this);
}
return errorBrowserDialog;
}
/**
*
* @return The jlog error dialog
*/
private ErrorLogDialog getJLogErroDialog() {
if (errorDialog==null) {
errorDialog = new ErrorLogDialog(logFrame,"jlog: Error log", false);
}
return errorDialog;
}
/**
* Return {@link #logFrame}.
*
*
* @return The logFrame
* (it is null
if jlog runs inside the OMC)
*/
public LogFrame getLogFrame() {
return logFrame;
}
/**
* Add a new error stack to the error browser dialog
*
* @param stackID The STACKID
of the error trace in the tab
*/
public void addErrorTab(final String stackID) {
Runnable runnable = new Runnable() {
public void run() {
getErrorDialog().addErrorTab(getLCModel1(),stackID);
}
};
Thread t = new Thread(runnable,"LoggingClient.addErrorTab");
t.setDaemon(true);
t.start();
}
/**
* @return the zoom
*/
public ZoomManager getZoomManager() {
return zoom;
}
/**
* @return the toolBar
*/
public LogToolBar getToolBar() {
return toolBar;
}
/**
* @return the containerServices
*/
public ContainerServicesBase getContainerServices() {
return containerServices;
}
/**
* @return true
if jlog runs in debug mode
*/
public boolean inDebugMode() {
return debugMode;
}
/**
* Show an error in the error panel displayed on top of the
* table of logs.
*
* Implementation notes: *
acsLogConnEstablished
* programmatically pushes the ACS button of the error widget causing the widget
* to disappear without any intervention from the user.
* This is very useful when the auto reconnect option is enabled.
* However, note that if showErrorMessage
is used for notifying other
* abnormal situations then a different strategy must be used to avoid the error
* widget to disappear at the wrong time (i.e. without the user acknowledge the problem).
*
* showErrorMessage
prints a message in the stderr too in case the glass pane
* can't be made visible (for example if an error occurs while building the
* LoggingClient
object).
*
* @param shortDescription The description of the error
* @param t The throwable that caused the error (can be null
).
* @return
*/
public void showErrorMessage(String shortDescription, Throwable t) {
System.err.println("JLOG ERROR: "+shortDescription);
if (t!=null) {
t.printStackTrace(System.err);
}
if (t==null) {
errorWidget.showMessage(MessageType.Error, shortDescription, null);
} else {
errorWidget.showMessage(shortDescription, t);
}
glassPane.setEventComponent(errorWidget.getAckButton());
toolBar.setEnabled(false);
navigationToolbar.setEnabled(false);
menuBar.setEnabled(false);
}
/**
* When the user acknowledges the message, we enable the glass pane to forward all the
* messages to the content pane.
*
* This method is executed when the user presses over the ACK button of the
* error widget and remove the constraints on the glass pane.
*
* @see showErrorMessage
for further implementation details
*/
@Override
public void errorAcknowledged() {
glassPane.setEventComponent(null);
toolBar.setEnabled(true);
navigationToolbar.setEnabled(true);
menuBar.setEnabled(true);
}
/**
* Single ViewCoordinator instance, created on demand.
*/
private ViewCoordinator viewCoord;
public ViewCoordinator getViewCoordinator() {
if (viewCoord == null) {
viewCoord = new ViewCoordinator(this, logEntryTable);
}
return viewCoord;
}
}