Commit in java/trunk/monitoring-app/src/main/java/org/hps/monitoring on MAIN
gui/HasErrorHandler.java+9added 765
   /MonitoringApplication.java+41-5764 -> 765
   /SystemStatusFrame.java+184added 765
subsys/SystemStatus.java+23-37764 -> 765
      /SystemStatusImpl.java+11-10764 -> 765
      /SystemStatusRegistry.java+30added 765
subsys/et/EtSystemMonitor.java+23-46764 -> 765
+321-98
3 added + 4 modified, total 7 files
Check in some changes from last week so I can proceed to break things locally again.

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
HasErrorHandler.java added at 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/HasErrorHandler.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/HasErrorHandler.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -0,0 +1,9 @@
+package org.hps.monitoring.gui;
+
+
+public interface HasErrorHandler {    
+    
+    void setErrorHandler(ErrorHandler errorHandler);
+    
+    ErrorHandler getErrorHandler();
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
MonitoringApplication.java 764 -> 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/MonitoringApplication.java	2014-07-10 19:34:16 UTC (rev 764)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/MonitoringApplication.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -79,6 +79,9 @@
 import org.hps.monitoring.record.etevent.EtConnectionParameters;
 import org.hps.monitoring.record.etevent.EtEventSource;
 import org.hps.monitoring.record.evio.EvioFileSource;
+import org.hps.monitoring.subsys.SystemStatus;
+import org.hps.monitoring.subsys.SystemStatusRegistry;
+import org.hps.monitoring.subsys.et.EtSystemMonitor;
 import org.hps.monitoring.subsys.et.EtSystemStripCharts;
 import org.lcsim.job.JobControlManager;
 import org.lcsim.util.aida.AIDA;
@@ -106,6 +109,7 @@
     private JMenuBar menuBar;
     private SettingsDialog settingsDialog;
     private PlotFrame plotFrame;
+    private SystemStatusFrame systemStatusFrame;
 
     // References to menu items that will be toggled depending on application state.
     private JMenuItem connectItem;
@@ -159,7 +163,7 @@
     private static final int SCREEN_HEIGHT = ScreenUtil.getScreenHeight();
     private final static int LOG_TABLE_WIDTH = 700; // FIXME: Should be set from main panel width.
     private final static int LOG_TABLE_HEIGHT = 270;
-    private static final int MAIN_FRAME_HEIGHT = 450;
+    private static final int MAIN_FRAME_HEIGHT = ScreenUtil.getScreenHeight() / 2;
     private static final int MAIN_FRAME_WIDTH = 650;
                
     /**
@@ -187,6 +191,8 @@
 
         // Configuration of window for showing plots.
         createPlotFrame();
+        
+        createSystemStatusFrame();
 
         // Setup AIDA.
         setupAida();
@@ -226,9 +232,18 @@
                 plotFrame.getY());
     }
     
+    private void createSystemStatusFrame() {
+        systemStatusFrame = new SystemStatusFrame();
+        systemStatusFrame.setLocation(
+                (int)ScreenUtil.getBoundsX(0),
+                MAIN_FRAME_HEIGHT);
+    }
+    
     public void setVisible(boolean visible) {
         super.setVisible(true);
         
+        this.systemStatusFrame.setVisible(true);
+        
         // FIXME: If this is done earlier before app is visible, the GUI will fail to show!
         this.connectionStatusPanel.setStatus(ConnectionStatus.DISCONNECTED);
     }
@@ -975,6 +990,11 @@
             // Reset the plot panel and global AIDA state.
             resetPlots();
 
+            // The system status registry should be cleared here before any processors
+            // which might have a SystemStatus are added to the event processing chain
+            // e.g. an LCSim Driver, etc.
+            SystemStatusRegistry.getSystemStatusRegistery().clear();
+
             // Setup the LCSim JobControlManager and event builder.
             setupLCSim();
             
@@ -988,6 +1008,9 @@
 
             // Setup the EventProcessingChain object using the EtConnection.
             setupEventProcessingChain();
+            
+            // Setup the system status monitor table.
+            setupSystemStatusMonitor();
 
             // Start thread which will trigger a disconnect if the event processing thread
             // finishes.
@@ -1366,12 +1389,17 @@
         eventProcessing.add(jobManager.getDriverExecList());
         
         // Using an ET server or an EVIO file?
-        if (usingEtServer() || usingEvioFile())
+        if (usingEtServer() || usingEvioFile()) {
             // ET or EVIO source can be used for updating the RunPanel.
             eventProcessing.add(runPanel.new EvioUpdater());
-        else
+        
+            // DEBUG: Just testing system status stuff.
+            eventProcessing.add(new EtSystemMonitor());
+            
+        } else {
             // Direct LCIO source so must use a more generic updater for the RunPanel.
             eventProcessing.add(runPanel.new CompositeRecordUpdater());
+        }
         
         // Using an ET server?
         if (usingEtServer())
@@ -1418,6 +1446,14 @@
             }
         }
     }
+    
+    private void setupSystemStatusMonitor() {
+        systemStatusFrame.clear();
+        SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery();
+        for (SystemStatus systemStatus : registry.getSystemStatuses()) {
+            systemStatusFrame.addSystemStatus(systemStatus);
+        }
+    }
 
     /**
      * Clear state of plot panel and AIDA for a new session.
@@ -1553,9 +1589,9 @@
             // Don't know when this would ever happen.
         }
        
-        // Log last error that occurred in event processing.
+        // Handle last error that occurred in event processing.
         if (eventProcessing.getLastError() != null) {
-            logger.log(Level.SEVERE, eventProcessing.getLastError().getMessage());
+            errorHandler.setError(eventProcessing.getLastError()).log().printStackTrace();
         }
        
         // Reset event processing objects.

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
SystemStatusFrame.java added at 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/SystemStatusFrame.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/SystemStatusFrame.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -0,0 +1,184 @@
+package org.hps.monitoring.gui;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
+
+import org.hps.monitoring.subsys.SystemStatus;
+import org.hps.monitoring.subsys.SystemStatus.StatusCode;
+import org.hps.monitoring.subsys.SystemStatusListener;
+
+/**
+ * A GUI window for showing changes to {@link org.hps.monitoring.subsys.SystemStatus} objects.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+// TODO: Add custom table model.
+public class SystemStatusFrame extends JFrame implements SystemStatusListener, TableModelListener, HasErrorHandler {
+
+    private static final int ACTIVE_COL = 0;
+    private static final int STATUS_COL = 1;
+    private static final int SYSTEM_COL = 2;
+    private static final int DESCRIPTION_COL = 3;
+    private static final int MESSAGE_COL = 4;
+    private static final int LAST_CHANGED_COL = 5;
+            
+    String[] columnNames = {
+            "Active",
+            "Status",
+            "System",       
+            "Description",
+            "Message", 
+            "Last Changed"
+    };
+           
+    JTable table;
+    DefaultTableModel tableModel;
+    List<SystemStatus> systemStatuses = new ArrayList<SystemStatus>();
+    final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
+    ErrorHandler errorHandler;
+    
+    int WIDTH = 650;
+    int HEIGHT = ScreenUtil.getScreenHeight() / 2;
+    
+    SystemStatusFrame() {
+         
+        String data[][] = new String[0][0];
+        tableModel = new DefaultTableModel(data, columnNames) {
+                public Class getColumnClass(int column) {
+                    switch (column) {
+                        case ACTIVE_COL:
+                            return Boolean.class;
+                        default:
+                            return String.class;
+                    }                    
+                }
+                
+                public boolean isCellEditable(int row, int col) {
+                    if (col == ACTIVE_COL)
+                        return true;
+                    else 
+                        return false;
+                }
+        };        
+        tableModel.addTableModelListener(this);
+        table = new JTable(tableModel);
+        table.getColumnModel().getColumn(STATUS_COL).setCellRenderer(
+                new DefaultTableCellRenderer() {                    
+                    @Override
+                    public Component getTableCellRendererComponent(
+                            JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
+
+                        // Cells are by default rendered as a JLabel.
+                        JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
+
+                        // Color code the cell by its status.
+                        SystemStatus.StatusCode statusCode = SystemStatus.StatusCode.valueOf((String) value);
+                        if (statusCode.ordinal() >= StatusCode.ERROR.ordinal()) {
+                            // Any type of error is red.
+                            label.setBackground(Color.RED);
+                        } else if (statusCode.ordinal() == StatusCode.WARNING.ordinal()) {
+                            // Warnings are yellow.
+                            label.setBackground(Color.YELLOW);
+                        } else if (statusCode.ordinal() == StatusCode.OKAY.ordinal()) {
+                            // Okay is green.
+                            label.setBackground(Color.GREEN);
+                        } else if (statusCode.ordinal() == StatusCode.OFFLINE.ordinal()) {
+                            // Offline is orange.
+                            label.setBackground(Color.ORANGE);
+                        } else if (statusCode.ordinal() == StatusCode.UNKNOWN.ordinal()) {
+                            // Unknown is gray.
+                            label.setBackground(Color.GRAY);
+                        } else {
+                            // Default is white, though this shouldn't ever happen!
+                            label.setBackground(Color.WHITE);
+                        }
+                        return label;                    
+                    }
+                }
+        );
+        table.getColumnModel().getColumn(ACTIVE_COL).setPreferredWidth(8);
+        table.getColumnModel().getColumn(STATUS_COL).setPreferredWidth(10);
+        table.getColumnModel().getColumn(SYSTEM_COL).setPreferredWidth(10);
+        // TODO: Add widths for every column.
+        
+        JScrollPane scrollPane = new JScrollPane(table);
+        scrollPane.setOpaque(true);
+        
+        setMinimumSize(new Dimension(WIDTH, HEIGHT));
+        setTitle("System Status Monitor");
+        setContentPane(scrollPane);
+        setResizable(true);
+        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+        pack();        
+    }        
+    
+    void addSystemStatus(SystemStatus status) {        
+        
+        // Insert row data into table.
+        Object[] record = new Object[] {
+                (Boolean)status.isActive(),
+                status.getStatusCode().name(),
+                status.getSystemName(),                
+                status.getStatusCode().description(),
+                status.getMessage(),
+                new Date(status.getLastChangedMillis())
+        };
+        tableModel.insertRow(table.getRowCount(), record);
+        
+        // Add to list for easily finding its row number later.
+        systemStatuses.add(status);
+        
+        // Add this class as a listener to get notification of status changes.
+        status.addListener(this);
+    }
+
+    @Override
+    public void statusChanged(SystemStatus status) {
+        int rowNumber = systemStatuses.indexOf(status);
+        tableModel.setValueAt(status.isActive(), rowNumber, ACTIVE_COL);
+        tableModel.setValueAt(status.getStatusCode().name(), rowNumber, STATUS_COL);
+        tableModel.setValueAt(status.getSystemName(), rowNumber, SYSTEM_COL);        
+        tableModel.setValueAt(status.getStatusCode().description(), rowNumber, DESCRIPTION_COL);
+        tableModel.setValueAt(status.getMessage(), rowNumber, MESSAGE_COL);
+        tableModel.setValueAt(dateFormat.format(new Date(status.getLastChangedMillis())), rowNumber, LAST_CHANGED_COL);
+    }
+    
+    public void clear() {
+        tableModel.setNumRows(0);
+        systemStatuses.clear();
+    }
+
+    @Override
+    public void tableChanged(TableModelEvent e) {
+        int col = e.getColumn();
+        if (col == ACTIVE_COL) {
+            int row = e.getFirstRow();
+            SystemStatus status = this.systemStatuses.get(row);
+            boolean active = (Boolean)tableModel.getValueAt(row, col);
+            status.setActive(active);
+        }
+    }
+
+    @Override
+    public void setErrorHandler(ErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    @Override
+    public ErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys
SystemStatus.java 764 -> 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/SystemStatus.java	2014-07-10 19:34:16 UTC (rev 764)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/SystemStatus.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -22,49 +22,36 @@
     enum StatusCode {
         
         /** Status encodings with a string name and descriptor. */
-        OKAY   (0, "okay",    "The system appears to be working."),
-        UNKNOWN(1, "unknown", "The status is not known."),
-        OFFLINE(2, "offline", "The system is currently offline."),               
-        WARNING(3, "warning", "There is a non-fatal warning."),
-        ERROR  (4, "error",   "A non-fatal but serious error has occurred."),
-        ALARM  (5, "alarm",   "An error has occurred and an alarm should trip."),
-        HALT   (6, "halt",    "The system should be immediately halted.");
+        OKAY   ("System appears to be working."),
+        UNKNOWN("Status is not known."),
+        OFFLINE("System is currently offline."),               
+        WARNING("There is a non-fatal warning."),
+        ERROR  ("A serious error has occurred."),
+        ALARM  ("A fatal error has tripped an alarm."),
+        HALT   ("The system should be immediately halted.");
         
-        int code;
-        String name;
         String description;
         
-        StatusCode(int code, String name, String description) {
-            this.code = code;
-            this.name = name;
+        StatusCode(String description) {
             this.description = description;
         }
-        
+                                
         /**
-         * Get the raw int code for the status.
-         * @return The raw code.
-         */
-        int getRawCode() {
-            return code;
-        }
-        
-        /**
-         * Get the name of the status.
-         * @return The name of the status.
-         */
-        String getName() {
-            return name;
-        }                  
-        
-        /**
          * Get the description of the status.
          * @return The description of the status.
          */
-        String getDescription() {
+        public String description() {
             return description;
         }
     }
     
+    enum SystemName {        
+        ET,
+        ECAL,
+        SVT,
+        TRIGGER;        
+    }
+    
     /**
      * Get the name of the sub-system e.g. "SVT".
      */
@@ -111,15 +98,14 @@
     void addListener(SystemStatusListener listener);
     
     /**
-     * Set whether this status is masked on or off.  
-     * Listeners will not be notified of state changes when masked
-     * is set to <code>True</code>.     
+     * Set whether this status is active.  
+     * Listeners will not be notified of state changes when active is <code>False</code>.     
      */
-    void setMasked(boolean masked);
+    void setActive(boolean active);
     
     /**
-     * True if the status has been masked off.
-     * @return True if status is masked off.
+     * True if the status is active.
+     * @return True if status is active.
      */
-    boolean isMasked();
+    boolean isActive();
 }

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys
SystemStatusImpl.java 764 -> 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/SystemStatusImpl.java	2014-07-10 19:34:16 UTC (rev 764)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/SystemStatusImpl.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -15,12 +15,13 @@
     List<SystemStatusListener> listeners = new ArrayList<SystemStatusListener>();
     String systemName = "";
     String description = "";
-    boolean masked;
+    boolean active = true;
     
-    SystemStatusImpl(String systemName, String description) {
+    public SystemStatusImpl(String systemName, String description) {
         this.systemName = systemName;
         this.description = description;
-        setCurrentTime();
+        setLastChangedTime();
+        SystemStatusRegistry.getSystemStatusRegistery().register(this);
     }
     
     @Override
@@ -47,8 +48,8 @@
     public void setStatusCode(StatusCode code, String message) {
         this.code = code;
         this.message = message;
-        setCurrentTime();
-        if (!isMasked())
+        setLastChangedTime();
+        if (isActive())
             notifyListeners();
     }
 
@@ -71,17 +72,17 @@
         }
     }
     
-    private void setCurrentTime() {
+    private void setLastChangedTime() {
         this.lastChangedMillis = System.currentTimeMillis();
     }
  
     @Override
-    public void setMasked(boolean masked) {
-        this.masked = masked;
+    public void setActive(boolean masked) {
+        this.active = masked;
     }
     
     @Override
-    public boolean isMasked() {
-        return masked;
+    public boolean isActive() {
+        return active;
     }
 }

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys
SystemStatusRegistry.java added at 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/SystemStatusRegistry.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/SystemStatusRegistry.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -0,0 +1,30 @@
+package org.hps.monitoring.subsys;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class SystemStatusRegistry {
+    
+    static SystemStatusRegistry instance = new SystemStatusRegistry();
+    List<SystemStatus> systemStatuses = new ArrayList<SystemStatus>();
+    
+    public static SystemStatusRegistry getSystemStatusRegistery() {
+        return instance;
+    }
+    
+    void register(SystemStatus systemStatus) {
+        if (!systemStatuses.contains(systemStatus))
+            systemStatuses.add(systemStatus);
+        else
+            throw new IllegalArgumentException("The system status is already registered.");
+    }        
+    
+    public List<SystemStatus> getSystemStatuses() {
+        return Collections.unmodifiableList(systemStatuses);
+    }
+    
+    public void clear() {
+        systemStatuses.clear();
+    }
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/et
EtSystemMonitor.java 764 -> 765
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/et/EtSystemMonitor.java	2014-07-10 19:34:16 UTC (rev 764)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/subsys/et/EtSystemMonitor.java	2014-07-14 18:36:00 UTC (rev 765)
@@ -1,64 +1,41 @@
 package org.hps.monitoring.subsys.et;
 
 import org.hps.monitoring.record.etevent.EtEventProcessor;
+import org.hps.monitoring.subsys.HasSystemStatus;
+import org.hps.monitoring.subsys.SystemStatus;
+import org.hps.monitoring.subsys.SystemStatus.StatusCode;
+import org.hps.monitoring.subsys.SystemStatusImpl;
+import org.jlab.coda.et.EtEvent;
 
 /**
- * This is a barebones implementation of an ET system monitor.
- * It does not do much right now but accumulate statistics 
- * and set basic system statuses.
+ * This is just a test class for a monitor of the ET system.
+ * It should actually do something useful eventually!
  * @author Jeremy McCormick <[log in to unmask]>
  */
-public class EtSystemMonitor extends EtEventProcessor {
-    /*
-//implements HasSystemInfo {
-        
-    //SystemInfo info = new SystemInfoImpl("EtSystem");
-    SystemStatistics stats = new SystemStatisticsImpl();
+public class EtSystemMonitor extends EtEventProcessor implements HasSystemStatus {
+
+    SystemStatus systemStatus;
+    int events = 0;
     
-    // TEST: strip chart stuff
-    JFrame plotFrame;
-    JFreeChart stripChart;
-    StripChartUpdater updater;
-    Timer timer;
+    public EtSystemMonitor() {
+        systemStatus = new SystemStatusImpl(SystemStatus.SystemName.ET.name(), "Example ET Monitor");
+        systemStatus.setStatusCode(StatusCode.UNKNOWN, "System is not active yet.");
+    }
     
-    MonitoringPlotFactory plotFactory = (MonitoringPlotFactory) AIDA.defaultInstance().analysisFactory().createPlotterFactory("ET System Monitoring");
-    
-    @Override
     public void startJob() {
-        stats.start();
-        //info.getStatus().setStatus(StatusCode.OKAY, "EtSystemMonitor set okay.");
-        
-        // TEST: setup strip chart
-        JFreeChart stripChart = plotFactory.createStripChart("Average Event Rate", "Event Count", 100);
-        updater = new AverageEventRateUpdater();
-        updater.setChart(stripChart);
-        timer = updater.start();
+        systemStatus.setStatusCode(StatusCode.OKAY, "ET job started.");
     }
-    
-    @Override
+                   
     public void processEvent(EtEvent event) {
-        stats.update(event.getLength());
-        //info.getStatistics()
-    }    
+        //systemStatus.setStatusCode(StatusCode.WARNING, "Just a dummy warning message.");
+    }
     
-    @Override
     public void endJob() {
-        //info.getStatistics().stop();
-        stats.stop();
-        //info.getStatus().setStatus(StatusCode.OFFLINE, "EtSystemMonitor set offline.");
-
-        // TEST: stop timer for updating strip chart
-        timer.cancel();
-        timer.purge();
+        systemStatus.setStatusCode(StatusCode.OFFLINE, "ET job ended.");
     }
         
-    class AverageEventRateUpdater extends StripChartUpdater {
-
-        @Override
-        public float nextValue() {
-            return (float)stats.getAverageEventsPerSecond();
-        }
-        
+    @Override
+    public SystemStatus getSystemStatus() {
+        return systemStatus;
     }
-    */
 }
SVNspam 0.1