View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.log4j.chainsaw;
18  
19  import java.awt.BorderLayout;
20  import java.awt.Dimension;
21  import java.awt.event.WindowAdapter;
22  import java.awt.event.WindowEvent;
23  import java.io.IOException;
24  import java.util.Properties;
25  import javax.swing.BorderFactory;
26  import javax.swing.JFrame;
27  import javax.swing.JMenu;
28  import javax.swing.JMenuBar;
29  import javax.swing.JMenuItem;
30  import javax.swing.JOptionPane;
31  import javax.swing.JPanel;
32  import javax.swing.JScrollPane;
33  import javax.swing.JSplitPane;
34  import javax.swing.JTable;
35  import javax.swing.ListSelectionModel;
36  import org.apache.log4j.Logger;
37  import org.apache.log4j.PropertyConfigurator;
38  
39  /**
40   * The main application.
41   *
42   * @author <a href="mailto:oliver@puppycrawl.com">Oliver Burn</a>
43   */
44  public class Main
45      extends JFrame
46  {
47      /** the default port number to listen on **/
48      private static final int DEFAULT_PORT = 4445;
49  
50      /** name of property for port name **/
51      public static final String PORT_PROP_NAME = "chainsaw.port";
52  
53      /** use to log messages **/
54      private static final Logger LOG = Logger.getLogger(Main.class);
55  
56  
57      /**
58       * Creates a new <code>Main</code> instance.
59       */
60      private Main() {
61          super("CHAINSAW - Log4J Log Viewer");
62          // create the all important model
63          final MyTableModel model = new MyTableModel();
64  
65          //Create the menu bar.
66          final JMenuBar menuBar = new JMenuBar();
67          setJMenuBar(menuBar);
68          final JMenu menu = new JMenu("File");
69          menuBar.add(menu);
70  
71          try {
72              final LoadXMLAction lxa = new LoadXMLAction(this, model);
73              final JMenuItem loadMenuItem = new JMenuItem("Load file...");
74              menu.add(loadMenuItem);
75              loadMenuItem.addActionListener(lxa);
76          } catch (NoClassDefFoundError e) {
77              LOG.info("Missing classes for XML parser", e);
78              JOptionPane.showMessageDialog(
79                  this,
80                  "XML parser not in classpath - unable to load XML events.",
81                  "CHAINSAW",
82                  JOptionPane.ERROR_MESSAGE);
83          } catch (Exception e) {
84              LOG.info("Unable to create the action to load XML files", e);
85              JOptionPane.showMessageDialog(
86                  this,
87                  "Unable to create a XML parser - unable to load XML events.",
88                  "CHAINSAW",
89                  JOptionPane.ERROR_MESSAGE);
90          }
91  
92          final JMenuItem exitMenuItem = new JMenuItem("Exit");
93          menu.add(exitMenuItem);
94          exitMenuItem.addActionListener(ExitAction.INSTANCE);
95  
96          // Add control panel
97          final ControlPanel cp = new ControlPanel(model);
98          getContentPane().add(cp, BorderLayout.NORTH);
99  
100         // Create the table
101         final JTable table = new JTable(model);
102         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
103         final JScrollPane scrollPane = new JScrollPane(table);
104         scrollPane.setBorder(BorderFactory.createTitledBorder("Events: "));
105         scrollPane.setPreferredSize(new Dimension(900, 300));
106 
107         // Create the details
108         final JPanel details = new DetailPanel(table, model);
109         details.setPreferredSize(new Dimension(900, 300));
110 
111         // Add the table and stack trace into a splitter
112         final JSplitPane jsp =
113             new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, details);
114         getContentPane().add(jsp, BorderLayout.CENTER);
115 
116         addWindowListener(new WindowAdapter() {
117                 public void windowClosing(WindowEvent aEvent) {
118                     ExitAction.INSTANCE.actionPerformed(null);
119                 }
120             });
121 
122         pack();
123         setVisible(true);
124 
125         setupReceiver(model);
126     }
127 
128     /**
129      * Setup recieving messages.
130      *
131      * @param aModel a <code>MyTableModel</code> value
132      */
133     private void setupReceiver(MyTableModel aModel) {
134         int port = DEFAULT_PORT;
135         final String strRep = System.getProperty(PORT_PROP_NAME);
136         if (strRep != null) {
137             try {
138                 port = Integer.parseInt(strRep);
139             } catch (NumberFormatException nfe) {
140                 LOG.fatal("Unable to parse " + PORT_PROP_NAME +
141                           " property with value " + strRep + ".");
142                 JOptionPane.showMessageDialog(
143                     this,
144                     "Unable to parse port number from '" + strRep +
145                     "', quitting.",
146                     "CHAINSAW",
147                     JOptionPane.ERROR_MESSAGE);
148                 System.exit(1);
149             }
150         }
151 
152         try {
153             final LoggingReceiver lr = new LoggingReceiver(aModel, port);
154             lr.start();
155         } catch (IOException e) {
156             LOG.fatal("Unable to connect to socket server, quiting", e);
157             JOptionPane.showMessageDialog(
158                 this,
159                 "Unable to create socket on port " + port + ", quitting.",
160                 "CHAINSAW",
161                 JOptionPane.ERROR_MESSAGE);
162             System.exit(1);
163         }
164     }
165 
166 
167     ////////////////////////////////////////////////////////////////////////////
168     // static methods
169     ////////////////////////////////////////////////////////////////////////////
170 
171 
172     /** initialise log4j **/
173     private static void initLog4J() {
174         final Properties props = new Properties();
175         props.setProperty("log4j.rootLogger", "DEBUG, A1");
176         props.setProperty("log4j.appender.A1",
177                           "org.apache.log4j.ConsoleAppender");
178         props.setProperty("log4j.appender.A1.layout",
179                           "org.apache.log4j.TTCCLayout");
180         PropertyConfigurator.configure(props);
181     }
182 
183     /**
184      * The main method.
185      *
186      * @param aArgs ignored
187      */
188     public static void main(String[] aArgs) {
189         initLog4J();
190         new Main();
191     }
192 }