Package simtools.logging.ui

Source Code of simtools.logging.ui.Viewer$ServerIndicatorCyclicCaller

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program 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 program 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
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2005, by :
*     Corporate:
*         EADS Astrium SAS
*         EADS CRC
*     Individual:
*         Claude Cazenave
*
* $Id: Viewer.java,v 1.7 2006/09/29 08:26:23 booba_skaya Exp $
*
* Changes
* -------
* 11 sept. 06  : Initial public release (CC);
*
*/
package simtools.logging.ui;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import simtools.logging.LoggingEntryByteBuffer;
import simtools.ui.CustomizedLocale;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;
import simtools.ui.UserProperties;
import simtools.ui.UserPropertiesEditor;
import simtools.util.AbstractCyclicCallerRunnable;

/**
* Class Viewer
* This class permits to view, save, filter the java's JUL log system.
*/
public class Viewer extends JFrame {

    /**(<b>Viewer</b>) instance: the singleton of the class.*/
    protected static Viewer instance;

  /**(<b>UserProperties</b>) userProperties: the properties.*/
  protected UserProperties userProperties;

  /**(<b>MenuResourceBundle</b>) resources: the resources.*/
  protected MenuResourceBundle resources;

  // Properties Management => save and restore size
  static protected final String PROPERTY_WIDTH = "jlogtool.Viewer.width";

  static protected final String PROPERTY_HEIGHT = "jlogtool.Viewer.height";

    static protected final String PROPERTY_LOCATION_X = "jlogtool.Viewer.location.x";

    static protected final String PROPERTY_LOCATION_Y = "jlogtool.Viewer.location.y";

    static protected final String PROPERTY_FOLDER = "jlogtool.Viewer.folder";

  // Properties Management => default TCP/IP port
  static protected final String PROPERTY_PORT = "jlogtool.port";

  /**(<b>LoggingBufferPanel</b>) panel: the main panel, that contains the JTable with the logs.*/
  private LoggingBufferPanel panel;

    /**(<b>HashMap</b>) actions: The hashMap that contains all the actions of the GUI.*/
    private HashMap actions;

    //The ACTIONS PROPERTIES
    private static final String ACTION_OPEN_FILE = "openFile";
    private static final String ACTION_SAVE_FILE = "saveFile";
    private static final String ACTION_OPEN_SERVER = "openServer";
    private static final String ACTION_CLOSE_SERVER = "closeServer";
    private static final String ACTION_CLEAR_LOGS = "clearLogs";
    private static final String ACTION_OPTIONS = "options";
    private static final String ACTION_QUIT = "quit";

    /**(<b>int</b>) DEFAULT_PORT: The default server port.*/
    private static final int DEFAULT_PORT = 3009;

    /**(<b>JLabel</b>) jLabelViewerInfo: the status label that will be used to display message to user.*/
    private JLabel jLabelViewerInfo;

    /**(<b>JLabel</b>) jLabelServerStatus: The jlabel that is used to display the server status.*/
    private JLabel jLabelServerStatus;

    /**
     * Contructor Viewer
     * <br><b>Summary:</b><br>
     * The constructor of the class Viewer.
     */
    public Viewer(){
        //set the singleton.
        instance = this;
    init();
    setTitle(getString("title"));
    setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        quitAction();
      }
    });
    createContent();
        initJMenuBar();
  }

  /**
   * Method initJMenuBar
   * <br><b>Summary:</b><br>
   * This method initialise the JMenuBar.
     * The actions need to have been intialized before calling this method.
   */
  private void initJMenuBar() {
      JMenuBar jMenuBar = new JMenuBar();
        setJMenuBar(jMenuBar);
        //The FILE menu
        JMenu fileMenu = new JMenu(getString("fileMenuTitle"));
        addMenuItem(fileMenu, ACTION_OPEN_FILE);
        addMenuItem(fileMenu, ACTION_SAVE_FILE);
        addMenuItem(fileMenu, ACTION_QUIT);
        jMenuBar.add(fileMenu);
        //The LOGS menu
        JMenu logsMenu = new JMenu(getString("logsMenuTitle"));
        addMenuItem(logsMenu, ACTION_CLEAR_LOGS);
        jMenuBar.add(logsMenu);
        //The Server menu
        JMenu serverMenu = new JMenu(getString("serverMenuTitle"));
        addMenuItem(serverMenu, ACTION_OPEN_SERVER);
        addMenuItem(serverMenu, ACTION_CLOSE_SERVER);
        jMenuBar.add(serverMenu);
        //The options Menu
        JMenu optionsMenu = new JMenu(getString("optionsMenuTitle"));
        addMenuItem(optionsMenu, ACTION_OPTIONS);
        jMenuBar.add(optionsMenu);
    }

    /**
     * Method addMenuItem
     * <br><b>Summary:</b><br>
     * Add a menu item action to the menu, adding a mnemonic item if available in the resources.
     * @param menu          The menu to add the action.
     * @param tag      The tag of the action to add.
     */
    private void addMenuItem(JMenu menu, String tag) {
        Action action = (Action) actions.get(tag);
        JMenuItem item = new JMenuItem(action);
        String s = getString(tag + "MnemonicIndex");
        if (s != null) {
            int i = getInt(tag + "MnemonicIndex");
            item.setDisplayedMnemonicIndex(i);
        }
        menu.add(item);
    }

    /**
     * Method createContent
     * <br><b>Summary:</b><br>
     * This method create the object that compose the GUI.
     */
    private void createContent(){
    panel=new LoggingBufferPanel(this,"jlogtool",resources);
        getContentPane().setLayout(new BorderLayout());
    getContentPane().add(panel, BorderLayout.CENTER);
        getContentPane().add(getStatusPanel(), BorderLayout.SOUTH);
        //Create the Cyclic caller that refresh the server status.
        ServerIndicatorCyclicCaller cyclicRunnable = new ServerIndicatorCyclicCaller(panel.getBuffer(), jLabelServerStatus);
        Thread cyclicThread = new Thread(cyclicRunnable, "ServerIndicatorThread");
        cyclicThread.start();
  }

    /**
     * Method getStatusPanel
     * <br><b>Summary:</b><br>
     * return the statusPanel
     * @return <b>(JPanel)</b>  A JPanel.
     */
    private JPanel getStatusPanel(){
        JPanel statusPanel = new JPanel(new GridBagLayout());
        //add the status Label.
        jLabelViewerInfo = new JLabel(getString("statusWelcome"));
        GridBagConstraints c1 = new GridBagConstraints();
        c1.gridx = 0;
        c1.gridy = 0;
        c1.anchor = GridBagConstraints.WEST;
        c1.fill = GridBagConstraints.HORIZONTAL;
        c1.weightx = 1;


        statusPanel.add(jLabelViewerInfo, c1);
        jLabelServerStatus = new JLabel("XXXXXXXX");
        GridBagConstraints c2 = new GridBagConstraints();
        c2.gridx = 1;
        c2.gridy = 0;
        c2.anchor = GridBagConstraints.EAST;
        c2.fill = GridBagConstraints.HORIZONTAL;
        c2.weightx = 1;
        statusPanel.add(jLabelServerStatus);
        return statusPanel;
    }

  /**
   * Method init
   * <br><b>Summary:</b><br>
   * initialise stuff such as, userproperties, language and the actions.
   */
  private void init(){
    // Read properties => this contain the user preference, including language setup
    userProperties=new UserProperties("jlogtool", true);
    userProperties.read();

    // language may be "fr", or "en_US", or whatever. If unsupported, it will default to best match
    String language = userProperties.getString("jlogtool.language","");

    // Let command-line -D JVM define take precedence
    if ((System.getProperty("language")==null) || System.getProperty("language").equals(""))
    if (!language.equals("")) {
      int sep = language.indexOf('_');
      if (sep==-1) {
        CustomizedLocale.set(new Locale(language));
      } else {
        String lang = language.substring(0,sep);
        String country = language.substring(sep+1);
        sep = country.indexOf('_');
        if (sep==-1) {
          CustomizedLocale.set(new Locale(lang, country));
        } else {
          CustomizedLocale.set(new Locale(lang, country.substring(0,sep), country.substring(sep+1)));
        }
      }
    }

    // Now initialize resources => those use the Locale defined above.
    resources = ResourceFinder.getMenu(Viewer.class);
        //Initialize the actions.
        initActions();
  }

  /**
   * Method initActions
   * <br><b>Summary:</b><br>
   * This method initialize the available actions in Viewer.
   */
  private void initActions() {
      actions = new HashMap();
        actions.put(ACTION_OPEN_FILE, new OpenFileViewerAction());
        actions.put(ACTION_SAVE_FILE, new SaveFileViewerAction());
        actions.put(ACTION_OPEN_SERVER, new OpenServerViewerAction());
        actions.put(ACTION_CLOSE_SERVER, new CloseServerViewerAction());
        actions.put(ACTION_CLEAR_LOGS, new ClearLogsViewerAction());
        actions.put(ACTION_OPTIONS, new OptionsViewerAction());
        actions.put(ACTION_QUIT, new QuitViewerAction());
    }

  /**
   * Method saveProperties
   * <br><b>Summary:</b><br>
   * Save the Viewer window property to userProperties.
   */
  private void saveProperties() {
        //save windows properties.
    userProperties.setInt(PROPERTY_WIDTH, getWidth());
    userProperties.setInt(PROPERTY_HEIGHT, getHeight());
        userProperties.setInt(PROPERTY_LOCATION_X, (int) getLocation().getX());
        userProperties.setInt(PROPERTY_LOCATION_Y, (int) getLocation().getY());
        //do not forget the
    panel.getUserProperties(userProperties);
  }

  /**
   * Method loadProperties
   * <br><b>Summary:</b><br>
   * Use this method to load the properties, and apply them to current GUI.
   * @return <b>(void)</b>  A void.
   */
  private void loadProperties() {
        //load windows properties.
    setSize(userProperties.getInt(PROPERTY_WIDTH, 700),
        userProperties.getInt(PROPERTY_HEIGHT, 500));
        setLocation(new Point(userProperties.getInt(PROPERTY_LOCATION_X, 0), userProperties.getInt(PROPERTY_LOCATION_Y, 0)));
    panel.setUserProperties(userProperties);
  }

  /**
   * Method open
   * <br><b>Summary:</b><br>
   * The method to open a log file under binary  or xml format.
   * @param file    The log file to be opened under binary or xml format.
   */
    private void open(File file) {
        String fileName = file.getName();
        try {
            //clear the logs before opening a log file.
            clearLogsAction();
            //indicate in status.
            setViewerInfo(getString("statusOpeningFile")+": "+fileName);
            //And if server is open, close it.
            if(panel.getBuffer().isSocketServerOpen() != -1){
                closeServerAction();
            }
            //check on file extension, to know if we have to read a binary or a xml log file.
            if (fileName.endsWith(".log")) {
                //It is a xml log file.
                panel.getBuffer().readXML(file);
            } else if (fileName.endsWith(".logb")) {
                //It is a binary log file.
                panel.getBuffer().read(file);
            }else{
                //we can not read this type of message.
                setViewerInfo("statusNotRecognizedFileType"+fileName);
            }
            //indicate the table that data have changed.
            panel.getLogbookModel().fireTableDataChanged();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
            setViewerInfo(getString("statusFailedToOpenFile")+" "+fileName+": "+e.getMessage());
        } catch (SAXException e) {
            e.printStackTrace();
            setViewerInfo(getString("statusFailedToOpenFile")+" "+fileName+": "+e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            setViewerInfo(getString("statusFailedToOpenFile")+" "+fileName+": "+e.getMessage());
        }
    }

  /**
   * Method openServer
   * <br><b>Summary:</b><br>
   * Use this method to open a listening log server on the given port.
   * @param port     The port to listen for connection.
   */
  private void openServer(int port){
    try {
      panel.getBuffer().openServer(port);
            //Change status.
            setViewerInfo(getString("statusServerOpenOnPort")+" "+port);
    } catch (IOException e) {
            setViewerInfo(getString("statusCantOpenServerBecause")+ " "+e.getMessage());
      e.printStackTrace();
    }
    ((LoggingBufferTableModel)panel.getLogbookModel()).startRefreshLoop();
  }

  /**
   * Method main
   * <br><b>Summary:</b><br>
   * @param args A log file to open under binary format (*.logb) or xml format (*.xml) or a port number to listen to.
   */
  public static void main(String[] args){
    Viewer v=new Viewer();
    v.pack();
    v.loadProperties();
    v.show();
    //Parse arguments.
    if(args.length>0){
            //If first arg is a file that exist, it should be a log file to be opened.
      File f=new File(args[0]);
            if(f.exists()){
                v.open(f);
            }
      else{
                //else it should be a port to listen to.
        try{
          int port=Integer.parseInt(args[0]);
          v.openServer(port);
        }catch(NumberFormatException e){
        }
      }
    }
    else{
            //If no arguments is precised, open a server on default port.
      v.openServer(DEFAULT_PORT);
    }
  }

    /**
     * Class OpenFileViewerAction.
     * The action to open a file.
     */
    private class OpenFileViewerAction extends AbstractViewerAction{

        public OpenFileViewerAction(){
            super(ACTION_OPEN_FILE);
        }
        public void actionPerformed(ActionEvent e) {
            openAction();
        }
    }


    /**
     * Method openAction
     * <br><b>Summary:</b><br>
     * Use this method to open a file and view its content in the log viewer.
     * Can open wether a XML, or a binary file.
     */
    private void openAction() {
        JDialogFile dialogFile = new JDialogFile(JDialogFile.TYPE_OPEN);
        dialogFile.show();
        //If used had validated the dialog, retrieve the selected file to open.
        if(dialogFile.hasBeenValidated()){
            //retrieve the file to open
            File fileToOpen = dialogFile.getResult();
            //open it
            open(fileToOpen);
            //save the file just open in the properties, to open files easily.
            userProperties.setProperty(PROPERTY_FOLDER, fileToOpen.getPath());
        }
    }

    /**
     * Class SaveFileViewerAction.
     * The action to save a file.
     */
    private class SaveFileViewerAction extends AbstractViewerAction{

        public SaveFileViewerAction(){
            super(ACTION_SAVE_FILE);
        }
        public void actionPerformed(ActionEvent e) {
            saveAction();
        }
    }


    /**
     * Method saveAction
     * <br><b>Summary:</b><br>
     * Use this method to save to a file.
     */
    private void saveAction() {
        JDialogFile dialogFile = new JDialogFile(JDialogFile.TYPE_SAVE);
        dialogFile.show();
        //If used had validated the dialog, retrieve the selected file to open.
        if(dialogFile.hasBeenValidated()){
            File fileTosave = dialogFile.getResult();
            //If file does not end with ".logb" add suffix.
            if(!fileTosave.getName().endsWith(".logb")){
                fileTosave = new File(fileTosave.getAbsoluteFile()+".logb");
            }
            try {
                panel.getBuffer().save(fileTosave);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Class OpenServerViewerAction.
     * The action to open a server to listen to a socket.
     */
    private class OpenServerViewerAction extends AbstractViewerAction{

        public OpenServerViewerAction(){
            super(ACTION_OPEN_SERVER);
        }
        public void actionPerformed(ActionEvent e) {
            openServerAction();
        }
    }

    /**
     * Method openServerAction
     * <br><b>Summary:</b><br>
     * Use this method to open a server to listen to a socket.
     */
    private void openServerAction() {
        //Open a dialog to enter port number.
        int port=userProperties.getInt(PROPERTY_PORT, DEFAULT_PORT);
        String newPort = JOptionPane.showInputDialog(getString("openServerPortMessage"), ""+port);
        try{
            port = Integer.parseInt(newPort);
        }catch(NumberFormatException e){
            setViewerInfo(getString("statusBadPortNumberUsing")+ " "+port);
            port = DEFAULT_PORT;
        }
        openServer(port);
    }

    /**
     * Class CloseServerViewerAction.
     * The action to Close a server to listen to a socket.
     */
    private class CloseServerViewerAction extends AbstractViewerAction{

        public CloseServerViewerAction(){
            super(ACTION_CLOSE_SERVER);
        }
        public void actionPerformed(ActionEvent e) {
            closeServerAction();
        }
    }

    /**
     * Method closeServerAction
     * <br><b>Summary:</b><br>
     * Use this method to Close a server.
     */
    private void closeServerAction() {
        try {
            panel.getBuffer().closeServer();
            ((LoggingBufferTableModel)panel.getLogbookModel()).stopRefreshLoop();
            //Change status.
            setViewerInfo(getString("statusServerClose"));
        } catch (IOException e) {
            setViewerInfo(getString("statusCantCloseServerBecause")+ " "+e.getMessage());
            e.printStackTrace();
        }
    }


    /**
     * Class ClearLogsViewerAction.
     * The action to clear the logs.
     */
    private class ClearLogsViewerAction extends AbstractViewerAction{

        public ClearLogsViewerAction(){
            super(ACTION_CLEAR_LOGS);
        }
        public void actionPerformed(ActionEvent e) {
            clearLogsAction();
        }
    }


    /**
     * Method clearLogsAction
     * <br><b>Summary:</b><br>
     * Use this method to clear the logs.
     */
    private void clearLogsAction() {
        panel.clearLogs();
        setViewerInfo(getString("statusLogsCleared"));
    }

    /**
     * Class OptionsViewerAction.
     * The action to display the options dialog.
     */
    private class OptionsViewerAction extends AbstractViewerAction{

        public OptionsViewerAction(){
            super(ACTION_OPTIONS);
        }
        public void actionPerformed(ActionEvent e) {
            optionsAction();
        }
    }


    /**
     * Method optionsAction
     * <br><b>Summary:</b><br>
     * Use this method to display the options dialog.
     */
    private void optionsAction() {
        //Construct the properties editor that will be used to edit/import/export the properties.
        UserPropertiesEditor propEditor=new UserPropertiesEditor(instance);
            propEditor.setLocationRelativeTo(instance);
        //show the editor.
        if(propEditor.showAndUpdate(userProperties,true)){
            //If we are here, it means that users changes the properties, and save the changes.
            setViewerInfo(getString("statusOptionsChanged"));
        }
    }

    /**
     * Class QuitViewerAction.
     * The action to quit the viewer.
     */
    private class QuitViewerAction extends AbstractViewerAction{

        public QuitViewerAction(){
            super(ACTION_QUIT);
        }
        public void actionPerformed(ActionEvent e) {
            quitAction();
        }
    }


    /**
     * Method quitAction
     * <br><b>Summary:</b><br>
     * Use this method to quit the viewer.
     */
    private void quitAction() {
        saveProperties();
        userProperties.write();
        System.exit(0);
    }

    /**
     * Method getString
     * <br><b>Summary:</b><br>
     * Return the resource that correspond to the given key.
     * @param key   The key to search.
     * @return <b>(String)</b>  A String: the resource that correspond to the given key..
     */
    protected String getString(String key){
        return resources.getString(key);
    }

    /**
     * Method getInt
     * <br><b>Summary:</b><br>
     * Return the resource that correspond to the given key.
     * @param key   The key to search.
     * @return <b>(int)</b>  A int: the resource that correspond to the given key..
     */
    protected int getInt(String key){
        return resources.getIntValue(key);
    }

    /**
     * Method setViewerInfo
     * <br><b>Summary:</b><br>
     * Use this method to diaply a status message in the status bar.
     * @param status        The status message to display.
     */
    private void setViewerInfo(String status){
        jLabelViewerInfo.setText(status);
    }

    /**
     * Class ServerIndicatorRunnable
     * A cyclic caller, to retrieve the status of the server, and set it in the server status component.
     */
    private class ServerIndicatorCyclicCaller extends AbstractCyclicCallerRunnable{

        /**(<b>LoggingEntryByteBuffer</b>) buffer: The buffer that permits to get the status of the server.*/
        private LoggingEntryByteBuffer buffer;

        /**(<b>JLabel</b>) jLabelServerIndicator: The JLabel used to indicate server status.*/
        private JLabel jLabelServerIndicator;

        /**(<b>String[]</b>) OPEN_ANIMATION: The animation to use to indicate that server is opened.*/
        private final String[] OPEN_ANIMATION = new String[]{"----<#", "---<#-", "--<#--", "-<#---", "<#----", ">-----", "-->---", "--->--", "---->-", "----->"};

        /**(<b>int</b>) openIndex:the current index in the open animation.*/
        private int openIndex;

        /**
         * Contructor ServerIndicatorCyclicCaller
         * <br><b>Summary:</b><br>
         * The constructor of the class ServerIndicatorCyclicCaller.
         * @param buffer    The buffer to use to retrieve the server status.
         */
        public ServerIndicatorCyclicCaller(LoggingEntryByteBuffer buffer, JLabel jLabelServerIndicator){
            this.buffer = buffer;
            this.jLabelServerIndicator = jLabelServerIndicator;
            openIndex = 0;
        }

        /* (non-Javadoc)
         * @see simtools.util.AbstractCyclicCallerRunnable#process()
         */
        public void process() {
            int port = buffer.isSocketServerOpen();
            //If a server is opened, use open animation.
            if(port != -1){
                jLabelServerIndicator.setText(OPEN_ANIMATION[openIndex]+port+OPEN_ANIMATION[openIndex]);
                openIndex++;
                if(openIndex == OPEN_ANIMATION.length){
                    openIndex = 0;
                }
            }else{
                jLabelServerIndicator.setText("XXXX");
            }
        }
    }
}
TOP

Related Classes of simtools.logging.ui.Viewer$ServerIndicatorCyclicCaller

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.