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.Component;
21  import java.awt.Container;
22  import java.awt.Dimension;
23  import java.awt.EventQueue;
24  import java.awt.GridBagConstraints;
25  import java.awt.GridBagLayout;
26  import java.awt.Insets;
27  import java.awt.event.ActionEvent;
28  import java.awt.event.ActionListener;
29  import java.awt.event.FocusEvent;
30  import java.awt.event.FocusListener;
31  import java.io.File;
32  import java.net.MalformedURLException;
33  import java.net.URISyntaxException;
34  import java.net.URL;
35  import java.util.List;
36  
37  import java.util.Locale;
38  import javax.swing.AbstractAction;
39  import javax.swing.BorderFactory;
40  import javax.swing.ButtonGroup;
41  import javax.swing.DefaultComboBoxModel;
42  import javax.swing.JButton;
43  import javax.swing.JCheckBox;
44  import javax.swing.JComboBox;
45  import javax.swing.JFrame;
46  import javax.swing.JLabel;
47  import javax.swing.JPanel;
48  import javax.swing.JRadioButton;
49  import javax.swing.JTextField;
50  import javax.swing.JTextPane;
51  import javax.swing.text.SimpleAttributeSet;
52  import javax.swing.text.StyleConstants;
53  import javax.swing.text.StyledDocument;
54  
55  import org.apache.log4j.LogManager;
56  import org.apache.log4j.Logger;
57  import org.apache.log4j.chainsaw.helper.SwingHelper;
58  import org.apache.log4j.chainsaw.prefs.SettingsManager;
59  import org.apache.log4j.net.SocketReceiver;
60  import org.apache.log4j.net.UDPReceiver;
61  
62  
63  /**
64   * A panel providing receiver configuration options
65   *
66   * @author Paul Smith
67   */
68  class ReceiverConfigurationPanel extends JPanel {
69      private final Logger logger = LogManager.getLogger(ReceiverConfigurationPanel.class);
70  
71      private final PanelModel panelModel = new PanelModel();
72  
73      //network receiver widgets
74      private JComboBox networkReceiverPortComboBox;
75      private JComboBox networkReceiverClassNameComboBox;
76      private DefaultComboBoxModel networkReceiverClassNameComboBoxModel;
77      private DefaultComboBoxModel networkReceiverPortComboBoxModel;
78  
79      //log4j config receiver widgets
80      private JButton browseLog4jConfigButton;
81      private JTextField log4jConfigURLTextField;
82  
83      //logfile receiver widgets
84      private JButton browseLogFileButton;
85      private JComboBox logFileFormatTypeComboBox;
86  
87      private JComboBox logFileFormatComboBox;
88      private JComboBox logFileFormatTimestampFormatComboBox;
89      private JTextField logFileURLTextField;
90      private DefaultComboBoxModel logFileFormatComboBoxModel;
91      private DefaultComboBoxModel logFileFormatTimestampFormatComboBoxModel;
92  
93      //use existing configuration widgets
94      private JButton browseForAnExistingConfigurationButton;
95      private DefaultComboBoxModel existingConfigurationComboBoxModel;
96      private JComboBox existingConfigurationComboBox;
97  
98      //don't warn again widgets
99      private JCheckBox dontwarnIfNoReceiver;
100 
101     private JButton saveButton;
102     private JButton okButton;
103     private JButton cancelButton;
104 
105     //radiobutton widgets
106     private JRadioButton log4jConfigReceiverRadioButton;
107     private JRadioButton logFileReceiverRadioButton;
108     private JRadioButton networkReceiverRadioButton;
109     private JRadioButton useExistingConfigurationRadioButton;
110     private ButtonGroup buttonGroup;
111 
112     private JPanel lowerPanel;
113 
114     private final JPanel networkReceiverPanel = buildNetworkReceiverPanel();
115     private final JPanel logFileReceiverPanel = buildLogFileReceiverPanel();
116     private final JPanel log4jConfigReceiverPanel = buildLog4jConfigReceiverPanel();
117     private final JPanel useExistingConfigurationPanel = buildUseExistingConfigurationPanel();
118     private final JPanel dontWarnAndOKPanel = buildDontWarnAndOKPanel();
119     private final JPanel bottomDescriptionPanel = buildBottomDescriptionPanel();
120 
121     //set by LogUI to handle hiding of the dialog
122     private ActionListener completionActionListener;
123     //used as frame for file open dialogs
124     private Container dialog;
125 
126   ReceiverConfigurationPanel() {
127         setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
128         setLayout(new GridBagLayout());
129 
130         buttonGroup = new ButtonGroup();
131 
132         lowerPanel = new JPanel(new BorderLayout());
133         lowerPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
134         lowerPanel.setPreferredSize(new Dimension(600, 200));
135         lowerPanel.setMinimumSize(new Dimension(600, 200));
136 
137         int yPos = 0;
138 
139         GridBagConstraints c = new GridBagConstraints();
140         c.gridx = 0;
141         c.gridy = yPos++;
142         c.fill = GridBagConstraints.HORIZONTAL;
143         log4jConfigReceiverRadioButton = new JRadioButton(" Use fileappender entries from a log4j config file ");
144         buttonGroup.add(log4jConfigReceiverRadioButton);
145         add(log4jConfigReceiverRadioButton, c);
146 
147         c = new GridBagConstraints();
148         c.gridx = 0;
149         c.gridy = yPos++;
150         c.fill = GridBagConstraints.HORIZONTAL;
151         logFileReceiverRadioButton = new JRadioButton(" Process a log file ");
152         buttonGroup.add(logFileReceiverRadioButton);
153         add(logFileReceiverRadioButton, c);
154 
155         c = new GridBagConstraints();
156         c.gridx = 0;
157         c.gridy = yPos++;
158         c.fill = GridBagConstraints.HORIZONTAL;
159         networkReceiverRadioButton = new JRadioButton(" Receive events from the network ");
160         buttonGroup.add(networkReceiverRadioButton);
161         add(networkReceiverRadioButton, c);
162 
163         c = new GridBagConstraints();
164         c.gridx = 0;
165         c.gridy = yPos++;
166         c.fill = GridBagConstraints.HORIZONTAL;
167         useExistingConfigurationRadioButton = new JRadioButton(" Use a Chainsaw config file ");
168         buttonGroup.add(useExistingConfigurationRadioButton);
169         add(useExistingConfigurationRadioButton, c);
170 
171         c = new GridBagConstraints();
172         c.gridx = 0;
173         c.gridy = yPos++;
174         c.fill = GridBagConstraints.HORIZONTAL;
175         c.insets = new Insets(10, 10, 10, 0);
176         add(lowerPanel, c);
177         
178         c = new GridBagConstraints();
179         c.gridx = 0;
180         c.gridy = yPos++;
181         c.weightx = 0.5;
182         c.fill = GridBagConstraints.HORIZONTAL;
183         c.insets = new Insets(0, 10, 0, 0);
184         add(dontWarnAndOKPanel, c);
185 
186         c = new GridBagConstraints();
187         c.gridx = 0;
188         c.gridy = yPos++;
189         c.fill = GridBagConstraints.HORIZONTAL;
190         c.insets = new Insets(10, 10, 10, 0);
191         add(bottomDescriptionPanel, c);
192 
193         /**
194          * This listener activates/deactivates certain controls based on the current
195          * state of the options
196          */
197         ActionListener al = new ActionListener() {
198                 public void actionPerformed(ActionEvent e) {
199                     updateEnabledState((Component)e.getSource());
200                 }
201             };
202 
203         logFileReceiverRadioButton.addActionListener(al);
204         log4jConfigReceiverRadioButton.addActionListener(al);
205         networkReceiverRadioButton.addActionListener(al);
206         useExistingConfigurationRadioButton.addActionListener(al);
207 
208         buttonGroup.setSelected(log4jConfigReceiverRadioButton.getModel(), true);
209         updateEnabledState(log4jConfigReceiverRadioButton);
210     }
211 
212     private JPanel buildDontWarnAndOKPanel() {
213         JPanel panel = new JPanel(new GridBagLayout());
214 
215         GridBagConstraints c = new GridBagConstraints();
216         c.gridx = 0;
217         c.gridy = 0;
218         c.weightx = 1.0;
219         c.anchor = GridBagConstraints.LINE_START;
220         dontwarnIfNoReceiver = new JCheckBox(" Always start Chainsaw with this configuration ");
221         panel.add(dontwarnIfNoReceiver, c);
222 
223         saveButton = new JButton(" Save configuration as... ");
224         c = new GridBagConstraints();
225         c.fill = GridBagConstraints.HORIZONTAL;
226         c.gridx = 1;
227         c.gridy = 0;
228         c.insets = new Insets(0, 0, 0, 10);
229         panel.add(saveButton, c);
230 
231         okButton = new JButton(" OK ");
232         cancelButton = new JButton(" Cancel ");
233 
234         List okCancelButtons = SwingHelper.orderOKCancelButtons(okButton, cancelButton);
235 
236         c = new GridBagConstraints();
237         c.fill = GridBagConstraints.HORIZONTAL;
238         c.gridx = 2;
239         c.gridy = 0;
240         c.insets = new Insets(0, 0, 0, 10);
241         panel.add((JButton)okCancelButtons.get(0), c);
242 
243         c = new GridBagConstraints();
244         c.fill = GridBagConstraints.HORIZONTAL;
245         c.gridx = 3;
246         c.gridy = 0;
247         panel.add((JButton)okCancelButtons.get(1), c);
248 
249         cancelButton.addActionListener(new ActionListener()
250         {
251             public void actionPerformed(ActionEvent e)
252             {
253                 panelModel.setCancelled(true);
254                 completionActionListener.actionPerformed(new ActionEvent(this, -1, "cancelled"));
255             }
256         });
257 
258         okButton.addActionListener(new ActionListener()
259         {
260             public void actionPerformed(ActionEvent e)
261             {
262                 panelModel.setCancelled(false);
263                 if (logFileFormatComboBox.getSelectedItem() != null && !(logFileFormatComboBox.getSelectedItem().toString().trim().equals(""))) {
264                   panelModel.setLogFormat(logFileFormatComboBox.getSelectedItem().toString());
265                 }
266                 completionActionListener.actionPerformed(new ActionEvent(this, -1, "ok"));
267             }
268         });
269 
270       saveButton.addActionListener(new ActionListener()
271       {
272           public void actionPerformed(ActionEvent e)
273           {
274             try {
275                 URL url = browseFile("Choose a path and file name to save", false);
276                 if (url != null) {
277                   File file = new File(url.toURI());
278                   panelModel.setSaveConfigFile(file);
279                 }
280             } catch (Exception ex) {
281                 logger.error(
282                     "Error browsing for log file", ex);
283             }
284           }
285       });
286       return panel;
287     }
288 
289     private JPanel buildBottomDescriptionPanel() {
290         JTextPane descriptionTextPane = new JTextPane();
291         StyledDocument doc = descriptionTextPane.getStyledDocument();
292         SimpleAttributeSet center = new SimpleAttributeSet();
293         StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
294         doc.setParagraphAttributes(0, doc.getLength(), center, false);
295 
296         descriptionTextPane.setText(" An example configuration file is available from the Welcome tab ");
297         descriptionTextPane.setEditable(false);
298         descriptionTextPane.setOpaque(false);
299         descriptionTextPane.setFont(getFont());
300 
301         JPanel panel = new JPanel(new GridBagLayout());
302 
303         GridBagConstraints c = new GridBagConstraints();
304         c.gridx = 0;
305         c.gridy = 0;
306         c.weightx = 1.0;
307         c.fill = GridBagConstraints.HORIZONTAL;
308 
309         panel.add(descriptionTextPane, c);
310 
311         return panel;
312     }
313 
314     private JPanel buildNetworkReceiverPanel() {
315         networkReceiverPortComboBoxModel = new DefaultComboBoxModel();
316         networkReceiverPortComboBoxModel.addElement("4445");
317         networkReceiverPortComboBoxModel.addElement("4560");
318 
319         networkReceiverPortComboBox = new JComboBox(networkReceiverPortComboBoxModel);
320         networkReceiverPortComboBox.setEditable(true);
321         networkReceiverPortComboBox.setOpaque(false);
322 
323         networkReceiverClassNameComboBoxModel = new DefaultComboBoxModel();
324         networkReceiverClassNameComboBoxModel.addElement(SocketReceiver.class.getName());
325         networkReceiverClassNameComboBoxModel.addElement(UDPReceiver.class.getName());
326 
327         networkReceiverClassNameComboBox = new JComboBox(networkReceiverClassNameComboBoxModel);
328 
329         networkReceiverClassNameComboBox.setEditable(false);
330         networkReceiverClassNameComboBox.setOpaque(false);
331 
332         JPanel panel = new JPanel(new GridBagLayout());
333 
334         GridBagConstraints c = new GridBagConstraints();
335         c.fill = GridBagConstraints.HORIZONTAL;
336         c.weightx = 0.5;
337         c.gridx = 0;
338         c.gridy = 0;
339         c.insets = new Insets(0, 0, 0, 5);
340         panel.add(networkReceiverClassNameComboBox, c);
341 
342         c = new GridBagConstraints();
343         c.fill = GridBagConstraints.HORIZONTAL;
344         c.weightx = 0.5;
345         c.gridx = 1;
346         c.gridy = 0;
347         panel.add(networkReceiverPortComboBox, c);
348 
349         return panel;
350     }
351 
352     private JPanel buildLog4jConfigReceiverPanel() {
353         log4jConfigURLTextField = new JTextField();
354         browseLog4jConfigButton = new JButton(new AbstractAction(" Open File... ") {
355                     public void actionPerformed(ActionEvent e) {
356                         try {
357 
358                             URL url = browseConfig();
359 
360                             if (url != null) {
361                                 log4jConfigURLTextField.setText(url.toExternalForm());
362                             }
363                         } catch (Exception ex) {
364                             logger.error(
365                                 "Error browsing for log4j config file", ex);
366                         }
367                     }
368                 });
369 
370         browseLog4jConfigButton.setToolTipText(
371             "Shows a File Open dialog to allow you to find a log4j configuration file");
372         JPanel panel = new JPanel(new GridBagLayout());
373         GridBagConstraints c = new GridBagConstraints();
374         c.gridx = 0;
375         c.gridy = 0;
376         c.gridwidth = 2;
377         c.anchor = GridBagConstraints.LINE_START;
378         c.insets = new Insets(0, 0, 5, 0);
379         panel.add(browseLog4jConfigButton, c);
380 
381         c = new GridBagConstraints();
382         c.gridx = 0;
383         c.gridy = 1;
384         c.insets = new Insets(0, 5, 0, 5);
385         panel.add(new JLabel(" log4j configuration file URL "), c);
386 
387         c = new GridBagConstraints();
388         c.gridx = 1;
389         c.gridy = 1;
390         c.weightx = 0.5;
391         c.fill = GridBagConstraints.HORIZONTAL;
392         panel.add(log4jConfigURLTextField, c);
393 
394 
395         return panel;
396     }
397 
398     private JPanel buildLogFileReceiverPanel() {
399         JPanel panel = new JPanel(new GridBagLayout());
400         browseLogFileButton = new JButton(new AbstractAction(" Open File... ") {
401             public void actionPerformed(ActionEvent e) {
402                 try {
403                     URL url = browseFile("Select a log file", true);
404                     if (url != null) {
405                         String item = url.toURI().toString();
406                         logFileURLTextField.setText(item);
407                     }
408                 } catch (Exception ex) {
409                     logger.error(
410                         "Error browsing for log file", ex);
411                 }
412             }
413         });
414 
415         browseLogFileButton.setToolTipText("Shows a File Open dialog to allow you to find a log file");
416         GridBagConstraints c = new GridBagConstraints();
417         c.gridx = 0;
418         c.gridy = 0;
419         c.anchor = GridBagConstraints.LINE_START;
420         c.insets = new Insets(0, 0, 5, 0);
421         panel.add(browseLogFileButton, c);
422 
423         c = new GridBagConstraints();
424         c.gridx = 0;
425         c.gridy = 1;
426         c.anchor = GridBagConstraints.LINE_END;
427         c.insets = new Insets(0, 0, 5, 5);
428         panel.add(new JLabel(" Log file URL "), c);
429         logFileURLTextField = new JTextField();
430         logFileURLTextField.setEditable(true);
431 
432         c = new GridBagConstraints();
433         c.gridx = 1;
434         c.gridy = 1;
435         c.weightx = 1.0;
436         c.gridwidth = 1;
437         c.anchor = GridBagConstraints.LINE_START;
438         c.fill = GridBagConstraints.HORIZONTAL;
439         c.insets = new Insets(0, 0, 5, 0);
440         panel.add(logFileURLTextField, c);
441 
442         c = new GridBagConstraints();
443         c.gridx = 0;
444         c.gridy = 2;
445         c.anchor = GridBagConstraints.LINE_END;
446         c.insets = new Insets(0, 0, 5, 5);
447         panel.add(new JLabel(" Log file format type "), c);
448 
449         DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
450         comboBoxModel.addElement("LogFilePatternReceiver LogFormat");
451         comboBoxModel.addElement("PatternLayout format");
452 
453         logFileFormatTypeComboBox = new JComboBox(comboBoxModel);
454         logFileFormatTypeComboBox.setOpaque(false);
455 
456         c = new GridBagConstraints();
457         c.gridx = 1;
458         c.gridy = 2;
459         c.anchor = GridBagConstraints.LINE_START;
460         c.insets = new Insets(0, 0, 5, 0);
461         panel.add(logFileFormatTypeComboBox, c);
462 
463         c = new GridBagConstraints();
464         c.gridx = 0;
465         c.gridy = 3;
466         c.anchor = GridBagConstraints.LINE_END;
467         c.insets = new Insets(0, 5, 5, 5);
468         panel.add(new JLabel(" Log file format "), c);
469 
470         logFileFormatComboBoxModel = new DefaultComboBoxModel();
471         seedLogFileFormatComboBoxModel();
472         logFileFormatComboBox = new JComboBox(logFileFormatComboBoxModel);
473         logFileFormatComboBox.setEditable(true);
474         logFileFormatComboBox.setOpaque(false);
475         logFileFormatComboBox.setSelectedIndex(0);
476 
477         c = new GridBagConstraints();
478         c.gridx = 1;
479         c.gridy = 3;
480         c.weightx = 0.5;
481         c.anchor = GridBagConstraints.LINE_START;
482         c.fill = GridBagConstraints.HORIZONTAL;
483         c.insets = new Insets(0, 0, 5, 0);
484         panel.add(logFileFormatComboBox, c);
485 
486         c = new GridBagConstraints();
487         c.gridx = 0;
488         c.gridy = 4;
489         c.insets = new Insets(0, 5, 5, 5);
490         panel.add(new JLabel(" Log file timestamp format "), c);
491 
492         logFileFormatTimestampFormatComboBoxModel = new DefaultComboBoxModel();
493         seedLogFileFormatTimestampComboBoxModel();
494         logFileFormatTimestampFormatComboBox = new JComboBox(logFileFormatTimestampFormatComboBoxModel);
495         logFileFormatTimestampFormatComboBox.setEditable(true);
496         logFileFormatTimestampFormatComboBox.setOpaque(false);
497 
498         c = new GridBagConstraints();
499         c.gridx = 1;
500         c.gridy = 4;
501         c.weightx = 0.5;
502         c.fill = GridBagConstraints.HORIZONTAL;
503         c.insets = new Insets(0, 0, 0, 0);
504         panel.add(logFileFormatTimestampFormatComboBox, c);
505 
506         c = new GridBagConstraints();
507         c.gridx = 0;
508         c.gridy = 5;
509         c.gridwidth=5;
510         c.insets = new Insets(15, 5, 0, 5);
511         panel.add(new JLabel("<html> See PatternLayout or LogFilePatternReceiver JavaDoc for details </html>"), c);
512         return panel;
513     }
514 
515     private void seedLogFileFormatComboBoxModel()
516     {
517         logFileFormatComboBoxModel.addElement("MESSAGE");
518         logFileFormatComboBoxModel.addElement("%p %t %c - %m%n");
519         logFileFormatComboBoxModel.addElement("LEVEL THREAD LOGGER - MESSAGE");
520         logFileFormatComboBoxModel.addElement("%d{ABSOLUTE} %-5p [%c{1}] %m%n");
521         logFileFormatComboBoxModel.addElement("TIMESTAMP LEVEL [LOGGER] MESSAGE");
522     }
523 
524     private void seedLogFileFormatTimestampComboBoxModel()
525     {
526         logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-dd HH:mm:ss,SSS");
527         logFileFormatTimestampFormatComboBoxModel.addElement("yyyyMMdd HH:mm:ss.SSS");
528         logFileFormatTimestampFormatComboBoxModel.addElement("yyyy/MM/dd HH:mm:ss");
529         logFileFormatTimestampFormatComboBoxModel.addElement("dd MMM yyyy HH:mm:ss,SSS");
530         logFileFormatTimestampFormatComboBoxModel.addElement("HH:mm:ss,SSS");
531         logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-ddTHH:mm");
532         logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-ddTHH:mm:ss.SSS");
533     }
534 
535     private JPanel buildUseExistingConfigurationPanel() {
536         existingConfigurationComboBoxModel = new DefaultComboBoxModel();
537 
538         existingConfigurationComboBox = new JComboBox(existingConfigurationComboBoxModel);
539         existingConfigurationComboBox.setOpaque(false);
540         existingConfigurationComboBox.setToolTipText("Previously loaded configurations can be chosen here");
541         existingConfigurationComboBox.setEditable(true);
542 
543         existingConfigurationComboBox.getEditor().getEditorComponent().addFocusListener(
544             new FocusListener() {
545                 public void focusGained(FocusEvent e) {
546                     selectAll();
547                 }
548 
549                 private void selectAll() {
550                     existingConfigurationComboBox.getEditor().selectAll();
551                 }
552 
553                 public void focusLost(FocusEvent e) {
554                 }
555             });
556 
557         browseForAnExistingConfigurationButton = new JButton(new AbstractAction(" Open File... ") {
558                     public void actionPerformed(ActionEvent e) {
559                         try {
560 
561                             URL url = browseConfig();
562 
563                             if (url != null) {
564                                 existingConfigurationComboBoxModel.addElement(url.toExternalForm());
565                                 existingConfigurationComboBox.getModel().setSelectedItem(
566                                     url);
567                             }
568                         } catch (Exception ex) {
569                             logger.error(
570                                 "Error browsing for Configuration file", ex);
571                         }
572                     }
573                 });
574 
575         browseForAnExistingConfigurationButton.setToolTipText(
576             "Shows a File Open dialog to allow you to find a configuration file");
577         JPanel panel = new JPanel(new GridBagLayout());
578         GridBagConstraints c = new GridBagConstraints();
579         c.gridx = 0;
580         c.gridy = 0;
581         c.gridwidth = 2;
582         c.anchor = GridBagConstraints.LINE_START;
583         c.insets = new Insets(0, 0, 5, 0);
584         panel.add(browseForAnExistingConfigurationButton, c);
585 
586         c = new GridBagConstraints();
587         c.gridx = 0;
588         c.gridy = 1;
589         c.insets = new Insets(0, 5, 0, 5);
590         panel.add(new JLabel(" Configuration file URL "), c);
591 
592         c = new GridBagConstraints();
593         c.gridx = 1;
594         c.gridy = 1;
595         c.weightx = 0.5;
596         c.fill = GridBagConstraints.HORIZONTAL;
597         panel.add(existingConfigurationComboBox, c);
598 
599 
600         return panel;
601     }
602 
603     /**
604      * Returns the current Model/state of the chosen options by the user.
605      * @return model
606      */
607     PanelModel getModel() {
608         return panelModel;
609     }
610 
611     /**
612      * Clients of this panel can configure the ActionListener to be used
613      * when the user presses the OK button, so they can read
614      * back this Panel's model top determine what to do.
615      * @param actionListener listener which will be notified that ok was selected
616      */
617     void setCompletionActionListener(ActionListener actionListener) {
618         completionActionListener = actionListener;
619     }
620 
621     private void updateEnabledState(Component component) {
622         lowerPanel.removeAll();
623         if (component == useExistingConfigurationRadioButton) {
624             lowerPanel.add(useExistingConfigurationPanel, BorderLayout.NORTH);
625         }
626         if (component == networkReceiverRadioButton) {
627             lowerPanel.add(networkReceiverPanel, BorderLayout.NORTH);
628         }
629         if (component == logFileReceiverRadioButton) {
630             lowerPanel.add(logFileReceiverPanel, BorderLayout.NORTH);
631         }
632         if (component == log4jConfigReceiverRadioButton) {
633             lowerPanel.add(log4jConfigReceiverPanel, BorderLayout.NORTH);
634         }
635         lowerPanel.revalidate();
636         lowerPanel.repaint();
637     }
638 
639     /**
640      * Returns the URL chosen by the user for a Configuration file
641      * or null if they cancelled.
642      */
643     private URL browseConfig() throws MalformedURLException {
644         //hiding and showing the dialog to avoid focus issues with 2 dialogs
645         dialog.setVisible(false);
646         File selectedFile = SwingHelper.promptForFile(dialog, null, "Choose a Chainsaw configuration file", true);
647         URL result = null;
648         if (selectedFile == null) {
649             result = null;
650         }
651         if (selectedFile != null && (!selectedFile.exists() || !selectedFile.canRead())) {
652             result = null;
653         }
654         if (selectedFile != null) {
655           result = selectedFile.toURI().toURL();
656         }
657         EventQueue.invokeLater(new Runnable() {
658           public void run() {
659             dialog.setVisible(true);
660           }
661         });
662         return result;
663     }
664 
665     /**
666      * Returns the URL chosen by the user for a Configuration file
667      * or null if they cancelled.
668      */
669     private URL browseFile(String title, boolean loadDialog) throws MalformedURLException {
670         //hiding and showing the dialog to avoid focus issues with 2 dialogs
671         dialog.setVisible(false);
672         File selectedFile = SwingHelper.promptForFile(dialog, null, title, loadDialog);
673         URL result = null;
674         if (selectedFile == null) {
675             result = null;
676         }
677         if (selectedFile != null && (!selectedFile.exists() || !selectedFile.canRead())) {
678             result = null;
679         }
680         if (selectedFile != null) {
681           result = selectedFile.toURI().toURL();
682         }
683         EventQueue.invokeLater(new Runnable() {
684           public void run() {
685             dialog.setVisible(true);
686           }
687         });
688         return result;
689     }
690 
691     public static void main(String[] args) {
692 
693         JFrame frame = new JFrame();
694         frame.getContentPane().add(new ReceiverConfigurationPanel());
695         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
696         frame.pack();
697         frame.setVisible(true);
698     }
699 
700     /**
701      * @return Returns the dontWarnMeAgain.
702      */
703     public final boolean isDontWarnMeAgain() {
704 
705         return dontwarnIfNoReceiver.isSelected();
706     }
707 
708   public void setDialog(Container dialog) {
709     this.dialog = dialog;
710   }
711 
712   /**
713      * This class represents the model of the chosen options the user
714      * has configured.
715      *
716      */
717     class PanelModel {
718 
719     private File file;
720     //default to cancelled
721     private boolean cancelled = true;
722     private String lastLogFormat;
723     private File saveConfigFile;
724 
725     public PanelModel(){
726             file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
727         }
728 
729         boolean isNetworkReceiverMode() {
730 
731             return !cancelled && networkReceiverRadioButton.isSelected();
732         }
733 
734         int getNetworkReceiverPort() {
735 
736             return Integer.parseInt(networkReceiverPortComboBoxModel.getSelectedItem().toString());
737         }
738 
739         Class getNetworkReceiverClass() throws ClassNotFoundException {
740             return Class.forName(networkReceiverClassNameComboBoxModel.getSelectedItem().toString());
741         }
742 
743         boolean isLoadConfig() {
744 
745             return !cancelled && useExistingConfigurationRadioButton.isSelected();
746         }
747 
748         boolean isLogFileReceiverConfig() {
749             return !cancelled && logFileReceiverRadioButton.isSelected();
750         }
751 
752         boolean isLog4jConfig() {
753             return !cancelled && log4jConfigReceiverRadioButton.isSelected();
754         }
755 
756         URL getConfigToLoad() {
757 
758             try
759             {
760                 return new URL(existingConfigurationComboBoxModel.getSelectedItem().toString());
761             }
762             catch (MalformedURLException e)
763             {
764                 return null;
765             }
766         }
767 
768         URL getDefaultConfigFileURL() {
769             try {
770                 return file.toURI().toURL();
771             } catch (MalformedURLException e) {
772                 logger.error("Error loading saved configurations by Chainsaw", e);
773             }
774             return null;
775         }
776 
777         File getSaveConfigFile() {
778           return saveConfigFile;
779         }
780 
781         void setSaveConfigFile(File file) {
782           this.saveConfigFile = file;
783         }
784 
785         URL getLogFileURL() {
786             try
787             {
788                 Object item = logFileURLTextField.getText();
789                 if (item != null) {
790                     return new URL(item.toString());
791                 }
792             }
793             catch (MalformedURLException e)
794             {
795                 logger.error("Error retrieving log file URL", e);
796             }
797             return null;
798         }
799 
800         String getLogFormat() {
801             if (cancelled) {
802               return lastLogFormat;
803             }
804             Object item = logFileFormatComboBox.getSelectedItem();
805             if (item != null) {
806                 return item.toString();
807             }
808             return null;
809         }
810 
811         boolean isPatternLayoutLogFormat() {
812             Object item = logFileFormatTypeComboBox.getSelectedItem();
813             return item != null && item.toString().toLowerCase(Locale.ENGLISH).contains("patternlayout");
814         }
815 
816         String getLogFormatTimestampFormat() {
817             Object item = logFileFormatTimestampFormatComboBox.getSelectedItem();
818             if (item != null) {
819                 return item.toString();
820             }
821 
822             return null;
823         }
824 
825         public void setCancelled(boolean cancelled)
826         {
827             this.cancelled = cancelled;
828         }
829 
830         public void setLogFormat(String lastLogFormat) {
831           this.lastLogFormat = lastLogFormat;
832           logFileFormatComboBoxModel.removeElement(lastLogFormat);
833           logFileFormatComboBoxModel.insertElementAt(lastLogFormat, 0);
834           logFileFormatComboBox.setSelectedIndex(0);
835         }
836 
837         public boolean isCancelled() {
838           return cancelled;
839         }
840 
841     public File getLog4jConfigFile() {
842       try {
843         URL newConfigurationURL = new URL(log4jConfigURLTextField.getText());
844         return new File(newConfigurationURL.toURI());
845       } catch (URISyntaxException e) {
846         e.printStackTrace();
847       } catch (MalformedURLException e) {
848         e.printStackTrace();
849       }
850       return null;
851     }
852   }
853 }