Author: sdeboy
Date: Thu Jul 22 06:58:54 2010
New Revision: 966518
URL: http://svn.apache.org/viewvc?rev=966518&view=rev
Log:
- Renamed the auto-saved xml configuration to receiver-config.xml
- Replaced 'load chainsaw configuration' menu item to display a new configuration dialog instead of taking the user to the auto-config URL preference
- New configuration dialog provides ability to define a VFSLogFilePatternReceiver (and ability to provide a PatternLayout as the format)
- Shifted the thumbnail bar tooltip down 30 pixels so the tooltip doesn't block the thumbnail under the pointer
Added:
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java (contents, props changed)
- copied, changed from r965025, logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/NoReceiversWarningPanel.java
Removed:
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/NoReceiversWarningPanel.java
Modified:
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/FileMenu.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanelPreferenceModel.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogUI.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java
logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java
logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java Thu Jul 22 06:58:54 2010
@@ -169,10 +169,6 @@ public static void main(String[] args) {
return model;
}
- public void browseForConfiguration() {
- generalAllPrefPanel.browseForConfiguration();
- }
-
public class VisualsPrefPanel extends BasicPrefPanel {
private final JRadioButton topPlacement = new JRadioButton("Top");
private final JRadioButton bottomPlacement = new JRadioButton("Bottom");
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/FileMenu.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/FileMenu.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/FileMenu.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/FileMenu.java Thu Jul 22 06:58:54 2010
@@ -65,7 +65,7 @@ class FileMenu extends JMenu {
loadConfigAction = new AbstractAction("Load Chainsaw configuration"){
public void actionPerformed(ActionEvent actionEvent) {
- logUI.showApplicationPreferencesBrowse();
+ logUI.showReceiverConfiguration();
}
};
Added: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java?rev=966518&view=auto
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java (added)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java Thu Jul 22 06:58:54 2010
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.chainsaw;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.helpers.OptionConverter;
+import org.apache.log4j.pattern.ClassNamePatternConverter;
+import org.apache.log4j.pattern.FileLocationPatternConverter;
+import org.apache.log4j.pattern.FullLocationPatternConverter;
+import org.apache.log4j.pattern.LevelPatternConverter;
+import org.apache.log4j.pattern.LineLocationPatternConverter;
+import org.apache.log4j.pattern.LineSeparatorPatternConverter;
+import org.apache.log4j.pattern.LiteralPatternConverter;
+import org.apache.log4j.pattern.LoggerPatternConverter;
+import org.apache.log4j.pattern.LoggingEventPatternConverter;
+import org.apache.log4j.pattern.MessagePatternConverter;
+import org.apache.log4j.pattern.MethodLocationPatternConverter;
+import org.apache.log4j.pattern.NDCPatternConverter;
+import org.apache.log4j.pattern.PatternParser;
+import org.apache.log4j.pattern.PropertiesPatternConverter;
+import org.apache.log4j.pattern.RelativeTimePatternConverter;
+import org.apache.log4j.pattern.SequenceNumberPatternConverter;
+import org.apache.log4j.pattern.ThreadPatternConverter;
+
+public class LogFilePatternLayoutBuilder
+{
+ public static String getLogFormatFromPatternLayout(String patternLayout) {
+ String input = OptionConverter.convertSpecialChars(patternLayout);
+ List converters = new ArrayList();
+ List fields = new ArrayList();
+ Map converterRegistry = null;
+
+ PatternParser.parse(input, converters, fields, converterRegistry, PatternParser.getPatternLayoutRules());
+ return getFormatFromConverters(converters);
+ }
+
+ private static String getFormatFromConverters(List converters) {
+ StringBuffer buffer = new StringBuffer();
+ for (Iterator iter = converters.iterator();iter.hasNext();) {
+ LoggingEventPatternConverter converter = (LoggingEventPatternConverter)iter.next();
+ if (converter instanceof MessagePatternConverter) {
+ buffer.append("MESSAGE");
+ } else if (converter instanceof LoggerPatternConverter) {
+ buffer.append("LOGGER");
+ } else if (converter instanceof ClassNamePatternConverter) {
+ buffer.append("CLASS");
+ } else if (converter instanceof RelativeTimePatternConverter) {
+ buffer.append("PROP(RELATIVETIME)");
+ } else if (converter instanceof ThreadPatternConverter) {
+ buffer.append("THREAD");
+ } else if (converter instanceof NDCPatternConverter) {
+ buffer.append("NDC");
+ } else if (converter instanceof LiteralPatternConverter) {
+ LiteralPatternConverter literal = (LiteralPatternConverter)converter;
+ //format shouldn't normally take a null, but we're getting a literal, so passing in the buffer will work
+ literal.format(null, buffer);
+ } else if (converter instanceof SequenceNumberPatternConverter) {
+ buffer.append("PROP(log4jid)");
+ } else if (converter instanceof LevelPatternConverter) {
+ buffer.append("LEVEL");
+ } else if (converter instanceof MethodLocationPatternConverter) {
+ buffer.append("METHOD");
+ } else if (converter instanceof FullLocationPatternConverter) {
+ buffer.append("PROP(locationInfo)");
+ } else if (converter instanceof LineLocationPatternConverter) {
+ buffer.append("LINE");
+ } else if (converter instanceof FileLocationPatternConverter) {
+ buffer.append("FILE");
+ } else if (converter instanceof PropertiesPatternConverter) {
+ PropertiesPatternConverter propertiesConverter = (PropertiesPatternConverter) converter;
+// String option = propertiesConverter.getOption();
+// if (option != null && option.length() > 0) {
+// buffer.append("PROP(" + option + ")");
+// } else {
+ buffer.append("PROP(PROPERTIES)");
+// }
+ } else if (converter instanceof LineSeparatorPatternConverter) {
+ //done
+ }
+ }
+ return buffer.toString();
+ }
+}
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java Thu Jul 22 06:58:54 2010
@@ -3564,6 +3564,12 @@ public class LogPanel extends DockablePa
}
}
+ public Point getToolTipLocation(MouseEvent event)
+ {
+ //shift tooltip down so the the pointer doesn't cover up events below the current mouse location
+ return new Point(event.getX(), event.getY() + 30);
+ }
+
private void drawEvent(Color newColor, int verticalLocation, int eventHeight, Graphics g, int x, int width) {
// System.out.println("painting: - color: " + newColor + ", verticalLocation: " + verticalLocation + ", eventHeight: " + eventHeight);
//center drawing at vertical location
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanelPreferenceModel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanelPreferenceModel.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanelPreferenceModel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanelPreferenceModel.java Thu Jul 22 06:58:54 2010
@@ -122,7 +122,8 @@ public class LogPanelPreferenceModel imp
private TableColumn findColumnByHeader(List list, String header) {
for (Iterator iter = list.iterator();iter.hasNext();) {
TableColumn c = (TableColumn)iter.next();
- if (c.getHeaderValue().equals(header)) {
+ //columns may have changed - header may not exist
+ if (c != null && c.getHeaderValue() != null && c.getHeaderValue().equals(header)) {
return c;
}
}
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogUI.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogUI.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogUI.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogUI.java Thu Jul 22 06:58:54 2010
@@ -105,6 +105,7 @@ import org.apache.log4j.chainsaw.prefs.S
import org.apache.log4j.chainsaw.prefs.SettingsListener;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.chainsaw.receivers.ReceiversPanel;
+import org.apache.log4j.chainsaw.vfs.VFSLogFilePatternReceiver;
import org.apache.log4j.net.SocketNodeEventListener;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.PluginEvent;
@@ -1038,7 +1039,7 @@ public class LogUI extends JFrame implem
&& applicationPreferenceModel.isShowNoReceiverWarning()) {
EventQueue.invokeLater(new Runnable() {
public void run() {
- showNoReceiversWarningPanel();
+ showReceiverConfigurationPanel();
}
});
}
@@ -1385,34 +1386,51 @@ public class LogUI extends JFrame implem
}
/**
- * Displays a warning dialog about having no Receivers defined and allows the
- * user to choose some options for configuration
+ * Displays a dialog which will provide options for selecting a configuratino
*/
- private void showNoReceiversWarningPanel() {
- final NoReceiversWarningPanel noReceiversWarningPanel =
- new NoReceiversWarningPanel();
+ private void showReceiverConfigurationPanel() {
+ final ReceiverConfigurationPanel receiverConfigurationPanel =
+ new ReceiverConfigurationPanel();
final SettingsListener sl =
new SettingsListener() {
public void loadSettings(LoadSettingsEvent event) {
- int size = event.asInt("SavedConfigs.Size");
- Object[] configs = new Object[size];
+ if (event.getSetting("SavedConfigs.Size") != null) {
+ int configSize = event.asInt("SavedConfigs.Size");
+ Object[] configs = new Object[configSize];
- for (int i = 0; i < size; i++) {
- configs[i] = event.getSetting("SavedConfigs." + i);
+ for (int i = 0; i < configSize; i++) {
+ configs[i] = event.getSetting("SavedConfigs." + i);
+ }
+
+ receiverConfigurationPanel.getModel().setRememberedConfigs(configs);
}
- noReceiversWarningPanel.getModel().setRememberedConfigs(configs);
+ if (event.getSetting("SavedLayouts.Size") != null) {
+ int layoutSize = event.asInt("SavedLayouts.Size");
+ Object[] layouts = new Object[layoutSize];
+
+ for (int i = 0; i < layoutSize; i++) {
+ layouts[i] = event.getSetting("SavedLayouts." + i);
+ }
+ receiverConfigurationPanel.getModel().setRememberedLayouts(layouts);
+ }
}
public void saveSettings(SaveSettingsEvent event) {
- Object[] configs =
- noReceiversWarningPanel.getModel().getRememberedConfigs();
+ Object[] configs = receiverConfigurationPanel.getModel().getRememberedConfigs();
event.saveSetting("SavedConfigs.Size", configs.length);
for (int i = 0; i < configs.length; i++) {
event.saveSetting("SavedConfigs." + i, configs[i].toString());
}
+ Object[] layouts = receiverConfigurationPanel.getModel().getRememberedLayouts();
+ event.saveSetting("SavedLayouts.Size", layouts.length);
+
+ for (int i = 0; i < layouts.length; i++) {
+ //the layout is an object, not a string (containing timestamp format, pattern & pattern type)
+ event.saveSetting("SavedLayouts." + i, layouts[i]);
+ }
}
};
@@ -1427,19 +1445,19 @@ public class LogUI extends JFrame implem
new Runnable() {
public void run() {
final JDialog dialog = new JDialog(LogUI.this, true);
- dialog.setTitle("Warning: You have no Receivers defined...");
+ dialog.setTitle("Load events into Chainsaw");
dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
dialog.setResizable(false);
- noReceiversWarningPanel.setOkActionListener(
+ receiverConfigurationPanel.setOkActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
});
- dialog.getContentPane().add(noReceiversWarningPanel);
+ dialog.getContentPane().add(receiverConfigurationPanel);
dialog.pack();
@@ -1449,29 +1467,27 @@ public class LogUI extends JFrame implem
(screenSize.height / 2) - (dialog.getHeight() / 2));
dialog.setVisible(true);
- applicationPreferenceModel.setShowNoReceiverWarning(!noReceiversWarningPanel.isDontWarnMeAgain());
+ applicationPreferenceModel.setShowNoReceiverWarning(!receiverConfigurationPanel.isDontWarnMeAgain());
+ URL configURL = null;
- if (noReceiversWarningPanel.getModel().isManualMode()) {
- applicationPreferenceModel.setReceivers(true);
- } else if (noReceiversWarningPanel.getModel().isSimpleReceiverMode()) {
- int port = noReceiversWarningPanel.getModel().getSimplePort();
- Class receiverClass =
- noReceiversWarningPanel.getModel().getSimpleReceiverClass();
+ if (receiverConfigurationPanel.getModel().isNetworkReceiverMode()) {
+ int port = receiverConfigurationPanel.getModel().getNetworkReceiverPort();
+ Class receiverClass = receiverConfigurationPanel.getModel().getNetworkReceiverClass();
try {
- Receiver simpleReceiver = (Receiver) receiverClass.newInstance();
- simpleReceiver.setName("Simple Receiver");
+ Receiver networkReceiver = (Receiver) receiverClass.newInstance();
+ networkReceiver.setName(receiverClass.getSimpleName() + "-" + port);
Method portMethod =
- simpleReceiver.getClass().getMethod(
+ networkReceiver.getClass().getMethod(
"setPort", new Class[] { int.class });
portMethod.invoke(
- simpleReceiver, new Object[] { new Integer(port) });
+ networkReceiver, new Object[] { new Integer(port) });
- simpleReceiver.setThreshold(Level.TRACE);
+ networkReceiver.setThreshold(Level.TRACE);
- pluginRegistry.addPlugin(simpleReceiver);
- simpleReceiver.activateOptions();
+ pluginRegistry.addPlugin(networkReceiver);
+ networkReceiver.activateOptions();
receiversPanel.updateReceiverTreeInDispatchThread();
} catch (Exception e) {
MessageCenter.getInstance().getLogger().error(
@@ -1479,33 +1495,61 @@ public class LogUI extends JFrame implem
MessageCenter.getInstance().getLogger().info(
"An error occurred creating your Receiver");
}
- } else if (noReceiversWarningPanel.getModel().isLoadConfig() ||
- noReceiversWarningPanel.getModel().isLoadSavedConfigs()) {
- final URL url;
- if (noReceiversWarningPanel.getModel().isLoadSavedConfigs()) {
- url = noReceiversWarningPanel.getModel().getSavedConfigToLoad();
+ } else if (receiverConfigurationPanel.getModel().isLoadConfig() ||
+ receiverConfigurationPanel.getModel().isLoadSavedConfigs()) {
+ if (receiverConfigurationPanel.getModel().isLoadSavedConfigs()) {
+ configURL = receiverConfigurationPanel.getModel().getSavedConfigToLoad();
} else {
- url = noReceiversWarningPanel.getModel().getConfigToLoad();
+ configURL = receiverConfigurationPanel.getModel().getConfigToLoad();
}
+ } else if (receiverConfigurationPanel.getModel().isLogFileReceiverConfig()) {
+ try {
+ URL fileURL = receiverConfigurationPanel.getModel().getLogFileURL();
+ if (fileURL != null) {
+ VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
+ fileReceiver.setName(fileURL.getFile());
+ fileReceiver.setAutoReconnect(true);
+ fileReceiver.setContainer(LogUI.this);
+ fileReceiver.setAppendNonMatches(true);
+ fileReceiver.setFileURL(fileURL.toURI().toString());
+ fileReceiver.setTailing(true);
+ if (receiverConfigurationPanel.getModel().isPatternLayoutLogFormat()) {
+ fileReceiver.setLogFormat(LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(receiverConfigurationPanel.getModel().getLogFormat()));
+ } else {
+ fileReceiver.setLogFormat(receiverConfigurationPanel.getModel().getLogFormat());
+ }
+ fileReceiver.setTimestampFormat(receiverConfigurationPanel.getModel().getLogFormatTimestampFormat());
+ fileReceiver.setThreshold(Level.TRACE);
- if (url != null) {
+ pluginRegistry.addPlugin(fileReceiver);
+ fileReceiver.activateOptions();
+ receiversPanel.updateReceiverTreeInDispatchThread();
+ }
+ } catch (Exception e) {
+ MessageCenter.getInstance().getLogger().error(
+ "Error creating Receiver", e);
+ MessageCenter.getInstance().getLogger().info(
+ "An error occurred creating your Receiver");
+ }
+ }
+ if (configURL != null) {
MessageCenter.getInstance().getLogger().debug(
- "Initialiazing Log4j with " + url.toExternalForm());
-
+ "Initialiazing Log4j with " + configURL.toExternalForm());
+ final URL finalURL = configURL;
new Thread(
new Runnable() {
public void run() {
- if (noReceiversWarningPanel.isDontWarnMeAgain()) {
- applicationPreferenceModel.setConfigurationURL(url.toExternalForm());
- }
- loadConfigurationUsingPluginClassLoader(url);
+ if (receiverConfigurationPanel.isDontWarnMeAgain()) {
+ applicationPreferenceModel.setConfigurationURL(finalURL.toExternalForm());
+ }
+ loadConfigurationUsingPluginClassLoader(finalURL);
receiversPanel.updateReceiverTreeInDispatchThread();
}
}).start();
}
- }
+
}
});
}
@@ -1550,10 +1594,8 @@ public class LogUI extends JFrame implem
preferencesFrame.setVisible(true);
}
- public void showApplicationPreferencesBrowse() {
- applicationPreferenceModelPanel.updateModel();
- preferencesFrame.setVisible(true);
- applicationPreferenceModelPanel.browseForConfiguration();
+ public void showReceiverConfiguration() {
+ showReceiverConfigurationPanel();
}
public void showAboutBox() {
Copied: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java (from r965025, logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/NoReceiversWarningPanel.java)
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java?p2=logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java&p1=logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/NoReceiversWarningPanel.java&r1=965025&r2=966518&rev=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/NoReceiversWarningPanel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java Thu Jul 22 06:58:54 2010
@@ -17,10 +17,9 @@
package org.apache.log4j.chainsaw;
import java.awt.Component;
-import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
-import java.awt.GridLayout;
+import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
@@ -28,10 +27,12 @@ import java.awt.event.FocusListener;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
@@ -46,422 +47,528 @@ import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
-import javax.swing.event.ListDataEvent;
-import javax.swing.event.ListDataListener;
import javax.swing.filechooser.FileFilter;
+
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
-import org.apache.log4j.net.PortBased;
-import org.apache.log4j.net.SocketAppender;
-import org.apache.log4j.net.SocketHubReceiver;
import org.apache.log4j.net.SocketReceiver;
+import org.apache.log4j.net.UDPReceiver;
/**
- * A dialog panel to inform the user that they do not have
- * Receiver's defined, and prompting them to either
- * load a Log4j Log file, search for a Log4j configuration file
- * or use the GUI to define the Receivers
+ * A panel providing receiver configuration options
*
* @author Paul Smith
*/
-class NoReceiversWarningPanel extends JPanel {
-
- private final JComboBox previousConfigs = new JComboBox();
+class ReceiverConfigurationPanel extends JPanel {
+ private final Logger logger = LogManager.getLogger(ReceiverConfigurationPanel.class);
- private final JRadioButton simpleReceiver = new JRadioButton(
- "Define a ");
+ private final PanelModel panelModel = new PanelModel();
- private final JRadioButton justLoadingFile = new JRadioButton(
- "I'm fine thanks, don't worry");
- private final JRadioButton searchOption = new JRadioButton(
- "Use an existing receiver configuration file...");
- private final JRadioButton chainsawSavedConfigOption = new JRadioButton(
- "Use most recent configuration defined through the Receiver configuration panel");
- private final JRadioButton manualOption = new JRadioButton(
- "Define receivers through the Receiver configuration panel (configuration saved on exit)");
- private final JButton okButton = new JButton(" OK ");
- private final PanelModel model = new PanelModel();
- final DefaultComboBoxModel configModel = new DefaultComboBoxModel();
-
- final DefaultComboBoxModel simpleReceiverModel = new DefaultComboBoxModel();
- final DefaultComboBoxModel simplePortModel = new DefaultComboBoxModel();
-
- private boolean dontWarnMeAgain = false;
-
- private final Logger logger = LogManager.getLogger(NoReceiversWarningPanel.class);
+ //network receiver widgets
+ private JComboBox networkReceiverPortComboBox;
+ private JComboBox networkReceiverClassNameComboBox;
+ private DefaultComboBoxModel networkReceiverClassNameComboBoxModel;
+ private DefaultComboBoxModel networkReceiverPortComboBoxModel;
+
+ //logfile receiver widgets
+ private JButton browseLogFileButton;
+ private JComboBox logFileFormatTypeComboBox;
+
+ private JComboBox logFileFormatComboBox;
+ private JComboBox logFileFormatTimestampFormatComboBox;
+ private JComboBox logFileURLComboBox;
+ private DefaultComboBoxModel logFileFormatComboBoxModel;
+ private DefaultComboBoxModel logFileFormatTimestampFormatComboBoxModel;
+ private DefaultComboBoxModel logFileURLComboBoxModel;
+
+ //use existing configuration widgets
+ private JButton browseForAnExistingConfigurationButton;
+ private DefaultComboBoxModel existingConfigurationComboBoxModel;
+ private JComboBox existingConfigurationComboBox;
+
+ //don't warn again widgets
+ private JCheckBox dontwarnIfNoReceiver;
+
+ //ok button
+ private JButton okButton;
+
+ //radiobutton widgets
+ private JRadioButton logFileReceiverRadioButton;
+ private JRadioButton networkReceiverRadioButton;
+ private JRadioButton doNothingRadioButton;
+ private JRadioButton useExistingConfigurationRadioButton;
+ private JRadioButton useAutoSavedConfigRadioButton;
+ private ButtonGroup buttonGroup;
+
+ ReceiverConfigurationPanel() {
+ JPanel topDescriptionPanel = buildTopDescriptionPanel();
+ JPanel networkReceiverPanel = buildNetworkReceiverPanel();
+ JPanel logFileReceiverPanel = buildLogFileReceiverPanel();
+ JPanel useExistingConfigurationPanel = buildUseExistingConfigurationPanel();
+ JPanel dontWarnAndOKPanel = buildDontWarnAndOKPanel();
+ JPanel bottomDescriptionPanel = buildBottomDescriptionPanel();
- NoReceiversWarningPanel() {
- initComponents();
- }
-
- /**
- * Returns the current Model/state of the chosen options by the user.
- * @return
- */
- PanelModel getModel() {
+ buttonGroup = new ButtonGroup();
- return model;
- }
+ setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
- /**
- * Clients of this panel can configure the ActionListener to be used
- * when the user presses the OK button, so they can read
- * back this Panel's model top determine what to do.
- * @param actionListener
- */
- void setOkActionListener(ActionListener actionListener) {
- okButton.addActionListener(actionListener);
- }
-
- /**
- * Sets up all the GUI components for this paenl
- */
- private void initComponents() {
setLayout(new GridBagLayout());
- GridBagConstraints gc = new GridBagConstraints();
-
- setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
-
- gc.gridx = 1;
- gc.fill = GridBagConstraints.BOTH;
- gc.weightx = 1.0;
- gc.weighty = 1.0;
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 0, 10, 0);
+ add(topDescriptionPanel, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 1;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ logFileReceiverRadioButton = new JRadioButton("Load events from a regular log file (and continue to tail the file)");
+ buttonGroup.add(logFileReceiverRadioButton);
+ add(logFileReceiverRadioButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 2;
+ c.weightx = 0.5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 20, 20, 0);
+ add(logFileReceiverPanel, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 3;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ networkReceiverRadioButton = new JRadioButton("Receive events from the network");
+ buttonGroup.add(networkReceiverRadioButton);
+ add(networkReceiverRadioButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 4;
+ c.weightx = 0.5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 20, 20, 0);
+ add(networkReceiverPanel, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ useExistingConfigurationRadioButton = new JRadioButton("Use an existing Chainsaw configuration file...");
+ buttonGroup.add(useExistingConfigurationRadioButton);
+ add(useExistingConfigurationRadioButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 6;
+ c.weightx = 0.5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 20, 20, 0);
+ add(useExistingConfigurationPanel, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 7;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 0, 20, 0);
+ useAutoSavedConfigRadioButton = new JRadioButton("Use last used/auto-saved configuration from $HOME/.chainsaw/receiver-config.xml");
+ buttonGroup.add(useAutoSavedConfigRadioButton);
+ add(useAutoSavedConfigRadioButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 9;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ doNothingRadioButton = new JRadioButton("I'm fine thanks, don't worry");
+ buttonGroup.add(doNothingRadioButton);
+ add(doNothingRadioButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 10;
+ c.weightx = 0.5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 20, 20, 0);
+ add(dontWarnAndOKPanel, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 11;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ add(bottomDescriptionPanel, c);
- JTextPane description = new JTextPane();
- description.setText("To load events into Chainsaw, a 'receiver' configuration must be provided.\n\n" +
- "NOTE: An example receiver configuration is available from the Welcome tab ('view example receiver configuration')");
- description.setEditable(false);
- description.setOpaque(false);
- description.setFont(getFont());
+ /**
+ * This listener activates/deactivates certain controls based on the current
+ * state of the options
+ */
+ ActionListener al = new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateEnabledState((Component)e.getSource());
+ }
+ };
- add(description, gc);
+ logFileReceiverRadioButton.addActionListener(al);
+ networkReceiverRadioButton.addActionListener(al);
+ doNothingRadioButton.addActionListener(al);
+ useExistingConfigurationRadioButton.addActionListener(al);
+ useAutoSavedConfigRadioButton.addActionListener(al);
+
+ //set 'do nothing' as default
+ buttonGroup.setSelected(doNothingRadioButton.getModel(), true);
+ updateEnabledState(doNothingRadioButton);
+ }
- gc.weightx = 0;
- gc.weighty = 0;
- gc.gridy = GridBagConstraints.RELATIVE;
- add(Box.createVerticalStrut(20), gc);
+ private JPanel buildTopDescriptionPanel() {
+ JPanel panel = new JPanel(new GridBagLayout());
- JPanel optionpanel = new JPanel();
- optionpanel.setLayout(new GridLayout(5, 1, 3, 3));
- optionpanel.setBackground(getBackground());
- optionpanel.setBorder(BorderFactory.createEtchedBorder());
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1.0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ JTextPane descriptionTextPane = new JTextPane();
+ descriptionTextPane.setText("Specify the source of events to process or load a Chainsaw configuration file\nAn example configuration file is available from the Welcome tab");
+ descriptionTextPane.setEditable(false);
+ descriptionTextPane.setOpaque(false);
+ descriptionTextPane.setFont(getFont());
+ panel.add(descriptionTextPane, c);
+ return panel;
+ }
- final ButtonGroup optionGroup = new ButtonGroup();
+ private JPanel buildDontWarnAndOKPanel() {
+ JPanel panel = new JPanel(new GridBagLayout());
- simpleReceiver.setToolTipText(
- "Creates one of the standard Receivers on one of the standard port");
- simpleReceiver.setMnemonic('p');
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1.0;
+ c.anchor = GridBagConstraints.LINE_END;
+ dontwarnIfNoReceiver = new JCheckBox("Don't show this again");
+ panel.add(dontwarnIfNoReceiver, c);
+
+ c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.gridx = 1;
+ c.gridy = 0;
+ okButton = new JButton(" OK ");
+ panel.add(okButton, c);
- searchOption.setToolTipText(
- "Allows you to choose a Log4J Configuration file that contains Receiver definitions");
+ return panel;
+ }
- searchOption.setMnemonic('S');
-
- chainsawSavedConfigOption.setToolTipText(
- "Allows you to load Receiver definitions saved by Chainsaw previously");
+ private JPanel buildBottomDescriptionPanel() {
+ JTextPane descriptionTextPane = new JTextPane();
+ descriptionTextPane.setText("The active receiver configuration is auto-saved on exit to $HOME/.chainsaw/receiver-config.xml");
+ descriptionTextPane.setEditable(false);
+ descriptionTextPane.setOpaque(false);
+ descriptionTextPane.setFont(getFont());
+
+ JPanel panel = new JPanel(new GridBagLayout());
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.weightx = 1.0;
+ c.fill = GridBagConstraints.HORIZONTAL;
- chainsawSavedConfigOption.setMnemonic('C');
+ panel.add(descriptionTextPane, c);
+ return panel;
+ }
- manualOption.setToolTipText(
- "Opens the Receivers panel so you can define them via a GUI");
+ private JPanel buildNetworkReceiverPanel() {
+ networkReceiverPortComboBoxModel = new DefaultComboBoxModel();
+ networkReceiverPortComboBoxModel.addElement("4445");
+ networkReceiverPortComboBoxModel.addElement("4560");
- manualOption.setMnemonic('m');
+ networkReceiverPortComboBox = new JComboBox(networkReceiverPortComboBoxModel);
+ networkReceiverPortComboBox.setEditable(true);
+ networkReceiverPortComboBox.setOpaque(false);
+ networkReceiverPortComboBox.setBackground(getBackground());
- justLoadingFile.setToolTipText(
- "Use this if you just want to view a Log4J Log file stored somewhere");
+ networkReceiverClassNameComboBoxModel = new DefaultComboBoxModel();
+ networkReceiverClassNameComboBoxModel.addElement(SocketReceiver.class);
+ networkReceiverClassNameComboBoxModel.addElement(UDPReceiver.class);
- justLoadingFile.setMnemonic('I');
+ networkReceiverClassNameComboBox = new JComboBox(networkReceiverClassNameComboBoxModel);
-// searchOption.setOpaque(false);
- manualOption.setOpaque(false);
- justLoadingFile.setOpaque(false);
+ networkReceiverClassNameComboBox.setEditable(false);
- optionGroup.add(searchOption);
- optionGroup.add(chainsawSavedConfigOption);
- optionGroup.add(manualOption);
- optionGroup.add(justLoadingFile);
- optionGroup.add(simpleReceiver);
+ networkReceiverClassNameComboBox.setRenderer(new DefaultListCellRenderer() {
+ public Component getListCellRendererComponent(JList list,
+ Object value, int index, boolean isSelected,
+ boolean cellHasFocus) {
- chainsawSavedConfigOption.setEnabled(getModel().isChinsawConfigFileExists());
+ Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
- gc.gridy = GridBagConstraints.RELATIVE;
+ if (value instanceof Class) {
+ Class receiverClass = (Class) value;
+ JLabel cellLabel = (JLabel) component;
+ String shortenedName = receiverClass.getName().substring(receiverClass.getName().lastIndexOf('.') + 1);
+ cellLabel.setText(shortenedName);
+ }
+ return component;
+ }
+ });
- configModel.removeAllElements();
+ JPanel panel = new JPanel(new GridBagLayout());
- previousConfigs.setModel(configModel);
- previousConfigs.setOpaque(false);
- previousConfigs.setBackground(getBackground());
- previousConfigs.setToolTipText(
- "Previously loaded configurations can be chosen here");
+ GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 0.5;
+ c.gridx = 0;
+ c.gridy = 0;
+ panel.add(networkReceiverClassNameComboBox, c);
+
+ c = new GridBagConstraints();
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.weightx = 0.5;
+ c.gridx = 1;
+ c.gridy = 0;
+ panel.add(networkReceiverPortComboBox, c);
- previousConfigs.setEditable(true);
+ return panel;
+ }
- previousConfigs.getModel().addListDataListener(new ListDataListener() {
- private void validateUrl() {
- okButton.setEnabled(isValidConfigURL());
+ private JPanel buildLogFileReceiverPanel() {
+ JPanel panel = new JPanel(new GridBagLayout());
+ browseLogFileButton = new JButton(new AbstractAction(" Find a log file ") {
+ public void actionPerformed(ActionEvent e) {
+ try {
+
+ URL url = browseLogFile();
+ if (url != null) {
+ String item = url.toURI().toString();
+ logFileURLComboBoxModel.addElement(item);
+ logFileURLComboBox.setSelectedItem(item);
+ }
+ } catch (Exception ex) {
+ logger.error(
+ "Error browsing for log file", ex);
}
+ }
+ });
- public void contentsChanged(ListDataEvent e) {
- validateUrl();
- }
+ browseLogFileButton.setToolTipText("Shows a File Open dialog to allow you to find a log file");
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.anchor = GridBagConstraints.LINE_START;
+ panel.add(browseLogFileButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 1;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.insets = new Insets(0, 0, 0, 5);
+ panel.add(new JLabel("Log file URL"), c);
+ logFileURLComboBoxModel = new DefaultComboBoxModel();
+ logFileURLComboBox = new JComboBox(logFileURLComboBoxModel);
+ logFileURLComboBox.setEditable(true);
+ logFileURLComboBox.setOpaque(false);
+ logFileURLComboBox.setBackground(getBackground());
+
+ c = new GridBagConstraints();
+ c.gridx = 1;
+ c.gridy = 1;
+ c.weightx = 1.0;
+ c.gridwidth = 1;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ panel.add(logFileURLComboBox, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 2;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.insets = new Insets(0, 0, 0, 5);
+ panel.add(new JLabel("Log file format type"), c);
+
+ DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
+ comboBoxModel.addElement("PatternLayout format");
+ comboBoxModel.addElement("LogFilePatternReceiver LogFormat");
+
+ logFileFormatTypeComboBox = new JComboBox(comboBoxModel);
+ logFileFormatTypeComboBox.setOpaque(false);
+ logFileFormatTypeComboBox.setBackground(getBackground());
+
+ c = new GridBagConstraints();
+ c.gridx = 1;
+ c.gridy = 2;
+ c.anchor = GridBagConstraints.LINE_START;
+ panel.add(logFileFormatTypeComboBox, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 3;
+ c.anchor = GridBagConstraints.LINE_END;
+ c.insets = new Insets(0, 5, 0, 5);
+ panel.add(new JLabel("Log file format"), c);
+
+ logFileFormatComboBoxModel = new DefaultComboBoxModel();
+ logFileFormatComboBox = new JComboBox(logFileFormatComboBoxModel);
+ logFileFormatComboBox.setEditable(true);
+ logFileFormatComboBox.setOpaque(false);
+ logFileFormatComboBox.setBackground(getBackground());
+
+ c = new GridBagConstraints();
+ c.gridx = 1;
+ c.gridy = 3;
+ c.weightx = 0.5;
+ c.anchor = GridBagConstraints.LINE_START;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ panel.add(logFileFormatComboBox, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 4;
+ c.insets = new Insets(0, 5, 0, 5);
+ panel.add(new JLabel("Log file timestamp format"), c);
+
+ logFileFormatTimestampFormatComboBoxModel = new DefaultComboBoxModel();
+ seedLogFileFormatTimestampComboBoxModel();
+ logFileFormatTimestampFormatComboBox = new JComboBox(logFileFormatTimestampFormatComboBoxModel);
+ logFileFormatTimestampFormatComboBox.setEditable(true);
+ logFileFormatTimestampFormatComboBox.setOpaque(false);
+ logFileFormatTimestampFormatComboBox.setBackground(getBackground());
+ c = new GridBagConstraints();
+ c.gridx = 1;
+ c.gridy = 4;
+ c.weightx = 0.5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ panel.add(logFileFormatTimestampFormatComboBox, c);
+
+ DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss,SSS");
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 5;
+ c.gridwidth=5;
+ c.insets = new Insets(5, 5, 0, 5);
+ panel.add(new JLabel("Timestamps parsed using Java's SimpleDateFormat - use yyyy.MM.dd HH:mm:ss,SSS to parse " + dateFormat.format(new Date())), c);
+ return panel;
+ }
- public void intervalAdded(ListDataEvent e) {
- validateUrl();
- }
+ private void seedLogFileFormatTimestampComboBoxModel()
+ {
+ logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-dd HH:mm:ss,SSS");
+ logFileFormatTimestampFormatComboBoxModel.addElement("yyyyMMdd HH:mm:ss.SSS");
+ logFileFormatTimestampFormatComboBoxModel.addElement("yyyy/MM/dd HH:mm:ss");
+ logFileFormatTimestampFormatComboBoxModel.addElement("dd MMM yyyy HH:mm:ss,SSS");
+ logFileFormatTimestampFormatComboBoxModel.addElement("HH:mm:ss,SSS");
+ logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-ddTHH:mm");
+ logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-ddTHH:mm:ss.SSS");
+ }
- public void intervalRemoved(ListDataEvent e) {
- validateUrl();
- }
- });
+ private JPanel buildUseExistingConfigurationPanel() {
+ existingConfigurationComboBoxModel = new DefaultComboBoxModel();
- previousConfigs.setMaximumSize(new Dimension(200,
- (int) previousConfigs.getPreferredSize().getHeight()));
- previousConfigs.setPreferredSize(previousConfigs.getMaximumSize());
- previousConfigs.getEditor().getEditorComponent().addFocusListener(
+ existingConfigurationComboBox = new JComboBox(existingConfigurationComboBoxModel);
+ existingConfigurationComboBox.setOpaque(false);
+ existingConfigurationComboBox.setBackground(getBackground());
+ existingConfigurationComboBox.setToolTipText("Previously loaded configurations can be chosen here");
+ existingConfigurationComboBox.setEditable(true);
+
+ existingConfigurationComboBox.getEditor().getEditorComponent().addFocusListener(
new FocusListener() {
public void focusGained(FocusEvent e) {
selectAll();
}
private void selectAll() {
- previousConfigs.getEditor().selectAll();
+ existingConfigurationComboBox.getEditor().selectAll();
}
public void focusLost(FocusEvent e) {
}
});
- final JButton searchButton = new JButton(new AbstractAction(
- " Browse... ") {
+ browseForAnExistingConfigurationButton = new JButton(new AbstractAction(" Find an existing configuration ") {
public void actionPerformed(ActionEvent e) {
-
try {
- URL url = browseForConfig();
+ URL url = browseConfig();
if (url != null) {
getModel().configUrl = url;
- configModel.addElement(url);
- previousConfigs.getModel().setSelectedItem(
+ existingConfigurationComboBoxModel.addElement(url);
+ existingConfigurationComboBox.getModel().setSelectedItem(
url);
}
} catch (Exception ex) {
logger.error(
- "Error browswing for Configuration file", ex);
+ "Error browsing for Configuration file", ex);
}
}
});
- searchButton.setToolTipText(
+ browseForAnExistingConfigurationButton.setToolTipText(
"Shows a File Open dialog to allow you to find a configuration file");
+ JPanel panel = new JPanel(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.gridwidth = 2;
+ c.anchor = GridBagConstraints.LINE_START;
+ panel.add(browseForAnExistingConfigurationButton, c);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 1;
+ c.insets = new Insets(0, 5, 0, 5);
+ panel.add(new JLabel("Configuration file URL"), c);
+
+ c = new GridBagConstraints();
+ c.gridx = 1;
+ c.gridy = 1;
+ c.weightx = 0.5;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ panel.add(existingConfigurationComboBox, c);
- simplePortModel.addElement(new PortBased() {
-
- private void unsupported() {
- throw new UnsupportedOperationException(
- "Should not be used in this context");
- }
-
- public String getName() {
- unsupported();
-
- return null;
- }
-
- public boolean isActive() {
- unsupported();
-
- return false;
- }
-
- public int getPort() {
-
- return 4445;
- }
-
- public String toString() {
-
- return getPort() + " (Old style/standard Chainsaw port)";
- }
- });
-
- simplePortModel.addElement(new PortBased() {
-
- private void unsupported() {
- throw new UnsupportedOperationException(
- "Should not be used in this context");
- }
-
- public String getName() {
- unsupported();
-
- return null;
- }
-
- public boolean isActive() {
- unsupported();
-
- return false;
- }
-
- public int getPort() {
-
- return SocketAppender.DEFAULT_PORT;
- }
-
- public String toString() {
-
- return getPort() + " (Default SocketAppender port)";
- }
- });
-
- JPanel simpleSocketPanel = new JPanel();
- simpleSocketPanel.setLayout(new BoxLayout(simpleSocketPanel, BoxLayout.X_AXIS));
-
- simpleSocketPanel.add(simpleReceiver);
- simpleSocketPanel.add(Box.createHorizontalStrut(5));
-
- final JComboBox socketCombo = new JComboBox(simplePortModel);
-
-
- simpleReceiverModel.addElement(SocketReceiver.class);
- simpleReceiverModel.addElement(SocketHubReceiver.class);
-
- final JComboBox receiverCombo = new JComboBox(simpleReceiverModel);
- receiverCombo.setEditable(false);
- receiverCombo.setRenderer(new DefaultListCellRenderer() {
- public Component getListCellRendererComponent(JList list,
- Object value, int index, boolean isSelected,
- boolean cellHasFocus) {
-
- Component c = super.getListCellRendererComponent(list,
- value, index, isSelected, cellHasFocus);
-
- if (value instanceof Class) {
-
- Class receiverClass = (Class) value;
- JLabel cellLabel = (JLabel) c;
- String shortenedName = receiverClass.getName()
- .substring(
- receiverClass.getName().lastIndexOf('.') + 1);
- cellLabel.setText(shortenedName);
- }
-
- return c;
- }
-
- });
-
- simpleSocketPanel.add(receiverCombo);
- simpleSocketPanel.add(Box.createHorizontalStrut(5));
- simpleSocketPanel.add(new JLabel(" on port "));
- simpleSocketPanel.add(Box.createHorizontalStrut(5));
- simpleSocketPanel.add(socketCombo);
-
- /**
- * This listener activates/deactivates certain controls based on the current
- * state of the options
- */
- ActionListener al = new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- previousConfigs.setEnabled(e.getSource() == searchOption);
- searchButton.setEnabled(e.getSource() == searchOption);
- socketCombo.setEnabled(e.getSource() == simpleReceiver);
- receiverCombo.setEnabled(e.getSource() == simpleReceiver);
-
- if (optionGroup.isSelected(searchOption.getModel())) {
- okButton.setEnabled(isValidConfigURL());
- } else {
- okButton.setEnabled(true);
- }
- }
- };
-
- searchOption.addActionListener(al);
- chainsawSavedConfigOption.addActionListener(al);
- manualOption.addActionListener(al);
- justLoadingFile.addActionListener(al);
- simpleReceiver.addActionListener(al);
-
- justLoadingFile.doClick();
-
- JPanel searchOptionPanel = new JPanel(new GridBagLayout());
-
- searchOptionPanel.setOpaque(false);
-
- GridBagConstraints searchGCC = new GridBagConstraints();
-
- searchGCC.fill = GridBagConstraints.HORIZONTAL;
- searchGCC.gridx = 1;
- searchGCC.weightx = 0.0;
- searchGCC.anchor = GridBagConstraints.WEST;
- searchOptionPanel.add(searchOption, searchGCC);
-
- searchGCC.fill = GridBagConstraints.NONE;
- searchGCC.weightx = 1.0;
- searchGCC.gridx = 2;
- searchOptionPanel.add(Box.createHorizontalStrut(5), searchGCC);
-
- searchGCC.gridx = 3;
- searchGCC.weightx = 0.0;
- searchOptionPanel.add(previousConfigs, searchGCC);
-
- searchGCC.weightx = 0.0;
- searchGCC.gridx = 4;
- searchOptionPanel.add(Box.createHorizontalStrut(5), searchGCC);
- searchGCC.gridx = 5;
- searchOptionPanel.add(searchButton, searchGCC);
-
-// searchGCC.gridx = 6;
-// searchGCC.fill = GridBagConstraints.HORIZONTAL;
-// searchGCC.weightx = 1.0;
-// searchOptionPanel.add(Box.createHorizontalGlue(), searchGCC);
-
-
- optionpanel.add(justLoadingFile);
- optionpanel.add(simpleSocketPanel);
- optionpanel.add(searchOptionPanel);
- optionpanel.add(chainsawSavedConfigOption);
- optionpanel.add(manualOption);
-
- add(optionpanel, gc);
-
- gc.gridy = GridBagConstraints.RELATIVE;
- gc.weightx = 0;
- gc.fill = GridBagConstraints.NONE;
- gc.anchor = GridBagConstraints.SOUTHEAST;
-
- add(Box.createVerticalStrut(20), gc);
-
- okButton.setMnemonic('O');
-
- final JCheckBox dontwarnIfNoReceiver = new JCheckBox(
- "Don't show me this again");
- JPanel okPanel = new JPanel();
+ return panel;
+ }
- okPanel.add(dontwarnIfNoReceiver);
- okPanel.add(okButton);
- add(okPanel, gc);
+ /**
+ * Returns the current Model/state of the chosen options by the user.
+ * @return model
+ */
+ PanelModel getModel() {
+ return panelModel;
+ }
- okButton.addActionListener(new ActionListener() {
+ /**
+ * Clients of this panel can configure the ActionListener to be used
+ * when the user presses the OK button, so they can read
+ * back this Panel's model top determine what to do.
+ * @param actionListener listener which will be notified that ok was selected
+ */
+ void setOkActionListener(ActionListener actionListener) {
+ okButton.addActionListener(actionListener);
+ }
- public void actionPerformed(ActionEvent e) {
- dontWarnMeAgain = dontwarnIfNoReceiver.isSelected();
- }
- });
+ private void updateEnabledState(Component component) {
+ existingConfigurationComboBox.setEnabled(component == useExistingConfigurationRadioButton);
+ browseForAnExistingConfigurationButton.setEnabled(component == useExistingConfigurationRadioButton);
+ networkReceiverPortComboBox.setEnabled(component == networkReceiverRadioButton);
+ networkReceiverClassNameComboBox.setEnabled(component == networkReceiverRadioButton);
+ browseLogFileButton.setEnabled(component == logFileReceiverRadioButton);
+ logFileURLComboBox.setEnabled(component == logFileReceiverRadioButton);
+ logFileFormatTypeComboBox.setEnabled(component == logFileReceiverRadioButton);
+ logFileFormatComboBox.setEnabled(component == logFileReceiverRadioButton);
+ logFileFormatTimestampFormatComboBox.setEnabled(component == logFileReceiverRadioButton);
}
/**
* Returns the URL chosen by the user for a Configuration file
* or null if they cancelled.
*/
- private URL browseForConfig() throws MalformedURLException {
+ private URL browseConfig() throws MalformedURLException {
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Use an existing receiver configuration file...");
@@ -498,31 +605,33 @@ class NoReceiversWarningPanel extends JP
}
/**
- * Determions if the Configuration URL is a valid url.
+ * Returns the URL chosen by the user for a Configuration file
+ * or null if they cancelled.
*/
- private boolean isValidConfigURL() {
+ private URL browseLogFile() throws MalformedURLException {
- if (previousConfigs.getSelectedItem() == null) {
-
- return false;
- }
+ JFileChooser chooser = new JFileChooser();
+ chooser.setDialogTitle("Browse for a log file...");
+ chooser.setDialogType(JFileChooser.OPEN_DIALOG);
+ chooser.showOpenDialog(this);
- String urlString = previousConfigs.getSelectedItem().toString();
+ File selectedFile = chooser.getSelectedFile();
- try {
- getModel().configUrl = new URL(urlString);
+ if (selectedFile == null) {
+ return null;
+ }
- return true;
- } catch (Exception ex) {
+ if (!selectedFile.exists() || !selectedFile.canRead()) {
+ return null;
}
- return false;
+ return chooser.getSelectedFile().toURI().toURL();
}
public static void main(String[] args) {
JFrame frame = new JFrame();
- frame.getContentPane().add(new NoReceiversWarningPanel());
+ frame.getContentPane().add(new ReceiverConfigurationPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
@@ -533,7 +642,7 @@ class NoReceiversWarningPanel extends JP
*/
public final boolean isDontWarnMeAgain() {
- return dontWarnMeAgain;
+ return dontwarnIfNoReceiver.isSelected();
}
/**
@@ -547,50 +656,44 @@ class NoReceiversWarningPanel extends JP
private File file;
public PanelModel(){
- file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-configs.xml");
- }
-
- boolean isLoadLogFile() {
-
- return justLoadingFile.isSelected();
+ file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
}
- boolean isSimpleReceiverMode() {
+ boolean isNetworkReceiverMode() {
- return simpleReceiver.isSelected();
+ return networkReceiverRadioButton.isSelected();
}
- int getSimplePort() {
+ int getNetworkReceiverPort() {
- return ((PortBased) simplePortModel.getSelectedItem()).getPort();
+ return Integer.parseInt(networkReceiverPortComboBoxModel.getSelectedItem().toString());
}
- Class getSimpleReceiverClass() {
+ Class getNetworkReceiverClass() {
- return (Class) simpleReceiverModel.getSelectedItem();
+ return (Class) networkReceiverClassNameComboBoxModel.getSelectedItem();
}
boolean isLoadConfig() {
- return searchOption.isSelected();
+ return useExistingConfigurationRadioButton.isSelected();
}
boolean isLoadSavedConfigs() {
- return chainsawSavedConfigOption.isSelected();
+ return useAutoSavedConfigRadioButton.isSelected();
}
- boolean isManualMode() {
-
- return manualOption.isSelected();
+ boolean isLogFileReceiverConfig() {
+ return logFileReceiverRadioButton.isSelected();
}
public Object[] getRememberedConfigs() {
- Object[] urls = new Object[configModel.getSize()];
+ Object[] urls = new Object[existingConfigurationComboBoxModel.getSize()];
- for (int i = 0; i < configModel.getSize(); i++) {
- urls[i] = configModel.getElementAt(i);
+ for (int i = 0; i < existingConfigurationComboBoxModel.getSize(); i++) {
+ urls[i] = existingConfigurationComboBoxModel.getElementAt(i);
}
return urls;
@@ -599,10 +702,10 @@ class NoReceiversWarningPanel extends JP
public void setRememberedConfigs(final Object[] configs) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
- configModel.removeAllElements();
+ existingConfigurationComboBoxModel.removeAllElements();
for (int i = 0; i < configs.length; i++) {
- configModel.addElement(configs[i]);
+ existingConfigurationComboBoxModel.addElement(configs[i]);
}
}
});
@@ -613,12 +716,6 @@ class NoReceiversWarningPanel extends JP
return configUrl;
}
- boolean isChinsawConfigFileExists(){
-
- return file.exists();
-
- }
-
URL getSavedConfigToLoad() {
try {
if (file.exists()){
@@ -627,9 +724,59 @@ class NoReceiversWarningPanel extends JP
logger.debug("No configuration file found");
}
} catch (MalformedURLException e) {
- logger.error("Error laoding saved configurations by Chainsaw", e);
+ logger.error("Error loading saved configurations by Chainsaw", e);
}
return null;
}
+
+ URL getLogFileURL() {
+ try
+ {
+ Object item = logFileURLComboBox.getSelectedItem();
+ if (item != null) {
+ return new URL(item.toString());
+ }
+ }
+ catch (MalformedURLException e)
+ {
+ logger.error("Error retrieving log file URL", e);
+ }
+ return null;
+ }
+
+ String getLogFormat() {
+ Object item = logFileFormatComboBox.getSelectedItem();
+ if (item != null) {
+ return item.toString();
+ }
+ return null;
+ }
+
+ boolean isPatternLayoutLogFormat() {
+ Object item = logFileFormatTypeComboBox.getSelectedItem();
+ return item != null && item.toString().toLowerCase().contains("patternlayout");
+ }
+
+ String getLogFormatTimestampFormat() {
+ Object item = logFileFormatTimestampFormatComboBox.getSelectedItem();
+ if (item != null) {
+ return item.toString();
+ }
+
+ return null;
+ }
+
+ public void setRememberedLayouts(Object[] layouts)
+ {
+ //TODO: implement
+ //add an entry to the logformat, formattype and timestamp fields
+
+ }
+
+ public Object[] getRememberedLayouts()
+ {
+ //TODO: implement
+ return new Object[0];
+ }
}
}
Propchange: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java Thu Jul 22 06:58:54 2010
@@ -62,6 +62,7 @@ import javax.swing.event.TreeWillExpandL
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreePath;
+import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamResult;
@@ -641,11 +642,19 @@ public class ReceiversPanel extends JPan
*/
public void saveSettings(SaveSettingsEvent event){
- List pluginList = pluginRegistry.getPlugins();
-
+ List fullPluginList = pluginRegistry.getPlugins();
+ List pluginList = new ArrayList();
+ for (Iterator iter = fullPluginList.iterator();iter.hasNext();) {
+ Plugin thisPlugin = (Plugin)iter.next();
+ if (thisPlugin instanceof Receiver) {
+ pluginList.add(thisPlugin);
+ }
+ }
+ //remove everything that isn't a receiver..otherwise, we'd create an empty config file
try {
- if (pluginList.size() != 0) {
- File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-configs.xml");
+ if (pluginList.size() > 0) {
+ //we programmatically register the ZeroConf plugin in the plugin registry
+ File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
@@ -673,7 +682,11 @@ public class ReceiversPanel extends JPan
for (int j = 0; j < list.size(); j++) {
PropertyDescriptor d = (PropertyDescriptor) list.get(j);
-
+ //don't serialize the loggerRepository property for subclasses of componentbase..
+ //easier to change this than tweak componentbase right now..
+ if (d.getReadMethod().getName().equals("getLoggerRepository")) {
+ continue;
+ }
Object o = d.getReadMethod().invoke(receiver, new Object[] {} );
if (o != null) {
Element paramElement = document.createElement("param");
@@ -689,6 +702,8 @@ public class ReceiversPanel extends JPan
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
DOMSource source = new DOMSource(rootElement);
FileOutputStream stream = new FileOutputStream(file);
StreamResult result = new StreamResult(stream);
Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/vfs/VFSLogFilePatternReceiver.java Thu Jul 22 06:58:54 2010
@@ -242,9 +242,9 @@ public class VFSLogFilePatternReceiver e
//on receiver restart, only prompt for credentials if we don't already have them
if (promptForUserInfo && getFileURL().indexOf("@") == -1) {
/*
- if promptforuserinfo is true, wait for a reference to the container
+ if promptforuserinfo is true, wait for a reference to the container
(via the VisualReceiver callback).
-
+
We need to display a login dialog on top of the container, so we must then
wait until the container has been added to a frame
*/
@@ -260,18 +260,22 @@ public class VFSLogFilePatternReceiver e
} catch (InterruptedException ie){}
}
}
-
+
Frame containerFrame1;
- synchronized(waitForContainerLock) {
- //loop until the container has a frame
- while ((containerFrame1 = (Frame)SwingUtilities.getAncestorOfClass(Frame.class, container)) == null) {
- try {
- waitForContainerLock.wait(1000);
- getLogger().debug("waiting for container's frame to be available");
- } catch (InterruptedException ie) {}
- }
- }
- final Frame containerFrame = containerFrame1;
+ if (container instanceof Frame) {
+ containerFrame1 = (Frame)container;
+ } else {
+ synchronized(waitForContainerLock) {
+ //loop until the container has a frame
+ while ((containerFrame1 = (Frame)SwingUtilities.getAncestorOfClass(Frame.class, container)) == null) {
+ try {
+ waitForContainerLock.wait(1000);
+ getLogger().debug("waiting for container's frame to be available");
+ } catch (InterruptedException ie) {}
+ }
+ }
+ }
+ final Frame containerFrame = containerFrame1;
//create the dialog
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Modified: logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html?rev=966518&r1=966517&r2=966518&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html (original)
+++ logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html Thu Jul 22 06:58:54 2010
@@ -10,6 +10,11 @@
<b>NOTE:</b> The mechanism and format used to persist settings in Chainsaw is subject to change. If you are experiencing problems displaying events in Chainsaw, please delete everything in the $user.dir/.chainsaw directory and restart Chainsaw.
<br>
<h1>2.1</h1>
+<h2>21 Jul 2010</h2>
+<ul>
+<li>Rewrote initial configuration screen with new ability to define a file receiver from the dialog (and provide a PatternLayout as the format) </li>
+<li>Renamed auto-save xml configuration to receiver-config.xml (in $HOME/.chainsaw)</li>
+</ul>
<h2>25 Jun 2010</h2>
<ul>
<li>Added new log panel feature: 'clear table expression' (define an expression that will automatically clear the table)</li>
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.