You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2017/05/30 23:48:53 UTC

[16/50] [abbrv] logging-chainsaw git commit: Added ability to save the receiver configuration defined through the initial receiver configuration panel with a user-specified file path and name

Added ability to save the receiver configuration defined through the initial receiver configuration panel with a user-specified file path and name


Project: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/commit/f95619e9
Tree: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/tree/f95619e9
Diff: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/diff/f95619e9

Branch: refs/heads/master
Commit: f95619e914469204882877d812354a4fc74884ee
Parents: 345dc27
Author: Scott Deboy <sd...@apache.org>
Authored: Thu Nov 4 08:12:54 2010 +0000
Committer: Scott Deboy <sd...@apache.org>
Committed: Thu Nov 4 08:12:54 2010 +0000

----------------------------------------------------------------------
 .../ApplicationPreferenceModelPanel.java        |  2 +-
 .../apache/log4j/chainsaw/FileLoadAction.java   |  2 +-
 .../java/org/apache/log4j/chainsaw/LogUI.java   | 24 +++--
 .../chainsaw/ReceiverConfigurationPanel.java    | 60 +++++++++---
 .../log4j/chainsaw/helper/SwingHelper.java      | 11 ++-
 .../chainsaw/receivers/ReceiversHelper.java     | 99 +++++++++++++++++++-
 .../chainsaw/receivers/ReceiversPanel.java      | 90 +-----------------
 .../log4j/chainsaw/help/release-notes.html      |  1 +
 8 files changed, 175 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
index 64cba35..c1460e0 100644
--- a/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
+++ b/src/main/java/org/apache/log4j/chainsaw/ApplicationPreferenceModelPanel.java
@@ -560,7 +560,7 @@ public static void main(String[] args) {
                   }
               }
           }
-      File selectedFile = SwingHelper.promptForFile(this, defaultPath, "Select a Chainsaw configuration file");
+      File selectedFile = SwingHelper.promptForFile(this, defaultPath, "Select a Chainsaw configuration file", true);
       if (selectedFile != null) {
               try
               {

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/FileLoadAction.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/FileLoadAction.java b/src/main/java/org/apache/log4j/chainsaw/FileLoadAction.java
index 638bc50..44b16cd 100644
--- a/src/main/java/org/apache/log4j/chainsaw/FileLoadAction.java
+++ b/src/main/java/org/apache/log4j/chainsaw/FileLoadAction.java
@@ -80,7 +80,7 @@ class FileLoadAction extends AbstractAction {
 
       if (!remoteURL) {
             try {
-              File selectedFile = SwingHelper.promptForFile(parent, null, "Load Events from XML file or zipped XML file...");
+              File selectedFile = SwingHelper.promptForFile(parent, null, "Load Events from XML file or zipped XML file...", true);
               if (selectedFile != null) {
                 url = selectedFile.toURI().toURL();
                 name = selectedFile.getName();

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/LogUI.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/LogUI.java b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
index 12502f3..dd9775a 100644
--- a/src/main/java/org/apache/log4j/chainsaw/LogUI.java
+++ b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
@@ -106,6 +106,7 @@ import org.apache.log4j.chainsaw.prefs.MRUFileListPreferenceSaver;
 import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
 import org.apache.log4j.chainsaw.prefs.SettingsListener;
 import org.apache.log4j.chainsaw.prefs.SettingsManager;
+import org.apache.log4j.chainsaw.receivers.ReceiversHelper;
 import org.apache.log4j.chainsaw.receivers.ReceiversPanel;
 import org.apache.log4j.chainsaw.vfs.VFSLogFilePatternReceiver;
 import org.apache.log4j.net.SocketNodeEventListener;
@@ -1418,16 +1419,17 @@ public class LogUI extends JFrame implements ChainsawViewer, SettingsListener {
               public void actionPerformed(ActionEvent e) {
                 dialog.setVisible(false);
 
+            if (receiverConfigurationPanel.getModel().isCancelled()) {
+              return;
+            }
             applicationPreferenceModel.setShowNoReceiverWarning(!receiverConfigurationPanel.isDontWarnMeAgain());
-            //using this config next time - stop all plugins
-            if (receiverConfigurationPanel.isDontWarnMeAgain()) {
-                List plugins = pluginRegistry.getPlugins();
-                for (Iterator iter = plugins.iterator();iter.hasNext();) {
-                    Plugin plugin = (Plugin)iter.next();
-                    //don't stop ZeroConfPlugin if it is registered
-                    if (!plugin.getName().toLowerCase().contains("zeroconf")) {
-                      pluginRegistry.stopPlugin(plugin.getName());
-                    }
+            //remove existing plugins
+            List plugins = pluginRegistry.getPlugins();
+            for (Iterator iter = plugins.iterator();iter.hasNext();) {
+                Plugin plugin = (Plugin)iter.next();
+                //don't stop ZeroConfPlugin if it is registered
+                if (!plugin.getName().toLowerCase().contains("zeroconf")) {
+                  pluginRegistry.stopPlugin(plugin.getName());
                 }
             }
             URL configURL = null;
@@ -1525,6 +1527,10 @@ public class LogUI extends JFrame implements ChainsawViewer, SettingsListener {
                     }
                   }).start();
               }
+                File saveConfigFile = receiverConfigurationPanel.getModel().getSaveConfigFile();
+                if (saveConfigFile != null) {
+                  ReceiversHelper.getInstance().saveReceiverConfiguration(saveConfigFile);
+                }
           }
         });
 

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java b/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java
index 8265361..d04a8e1 100644
--- a/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java
+++ b/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java
@@ -46,7 +46,6 @@ import javax.swing.JPanel;
 import javax.swing.JRadioButton;
 import javax.swing.JTextField;
 import javax.swing.JTextPane;
-import javax.swing.SwingUtilities;
 import javax.swing.text.SimpleAttributeSet;
 import javax.swing.text.StyleConstants;
 import javax.swing.text.StyledDocument;
@@ -93,6 +92,7 @@ class ReceiverConfigurationPanel extends JPanel {
     //don't warn again widgets
     private JCheckBox dontwarnIfNoReceiver;
 
+    private JButton saveButton;
     private JButton okButton;
     private JButton cancelButton;
 
@@ -214,6 +214,14 @@ class ReceiverConfigurationPanel extends JPanel {
         dontwarnIfNoReceiver = new JCheckBox("Always start Chainsaw with this configuration");
         panel.add(dontwarnIfNoReceiver, c);
 
+        saveButton = new JButton(" Save configuration as... ");
+        c = new GridBagConstraints();
+        c.fill = GridBagConstraints.HORIZONTAL;
+        c.gridx = 1;
+        c.gridy = 0;
+        c.insets = new Insets(0, 0, 0, 10);
+        panel.add(saveButton, c);
+
         okButton = new JButton(" OK ");
         cancelButton = new JButton(" Cancel ");
 
@@ -221,14 +229,14 @@ class ReceiverConfigurationPanel extends JPanel {
 
         c = new GridBagConstraints();
         c.fill = GridBagConstraints.HORIZONTAL;
-        c.gridx = 1;
+        c.gridx = 2;
         c.gridy = 0;
         c.insets = new Insets(0, 0, 0, 10);
         panel.add((JButton)okCancelButtons.get(0), c);
 
         c = new GridBagConstraints();
         c.fill = GridBagConstraints.HORIZONTAL;
-        c.gridx = 2;
+        c.gridx = 3;
         c.gridy = 0;
         panel.add((JButton)okCancelButtons.get(1), c);
 
@@ -249,10 +257,27 @@ class ReceiverConfigurationPanel extends JPanel {
                 if (logFileFormatComboBox.getSelectedItem() != null && !(logFileFormatComboBox.getSelectedItem().toString().trim().equals(""))) {
                   panelModel.setLogFormat(logFileFormatComboBox.getSelectedItem().toString());
                 }
-                completionActionListener.actionPerformed(new ActionEvent(this, -1, "cancelled"));
+                completionActionListener.actionPerformed(new ActionEvent(this, -1, "ok"));
             }
         });
-        return panel;
+
+      saveButton.addActionListener(new ActionListener()
+      {
+          public void actionPerformed(ActionEvent e)
+          {
+            try {
+                URL url = browseFile("Choose a path and file name to save", false);
+                if (url != null) {
+                  File file = new File(url.toURI());
+                  panelModel.setSaveConfigFile(file);
+                }
+            } catch (Exception ex) {
+                logger.error(
+                    "Error browsing for log file", ex);
+            }
+          }
+      });
+      return panel;
     }
 
     private JPanel buildBottomDescriptionPanel() {
@@ -323,8 +348,7 @@ class ReceiverConfigurationPanel extends JPanel {
         browseLogFileButton = new JButton(new AbstractAction(" Open File... ") {
             public void actionPerformed(ActionEvent e) {
                 try {
-
-                    URL url = browseLogFile();
+                    URL url = browseFile("Select a log file", true);
                     if (url != null) {
                         String item = url.toURI().toString();
                         logFileURLTextField.setText(item);
@@ -564,7 +588,7 @@ class ReceiverConfigurationPanel extends JPanel {
     private URL browseConfig() throws MalformedURLException {
         //hiding and showing the dialog to avoid focus issues with 2 dialogs
         dialog.setVisible(false);
-        File selectedFile = SwingHelper.promptForFile(dialog, null, "Choose a Chainsaw configuration file");
+        File selectedFile = SwingHelper.promptForFile(dialog, null, "Choose a Chainsaw configuration file", true);
         URL result = null;
         if (selectedFile == null) {
             result = null;
@@ -587,10 +611,10 @@ class ReceiverConfigurationPanel extends JPanel {
      * Returns the URL chosen by the user for a Configuration file
      * or null if they cancelled.
      */
-    private URL browseLogFile() throws MalformedURLException {
+    private URL browseFile(String title, boolean loadDialog) throws MalformedURLException {
         //hiding and showing the dialog to avoid focus issues with 2 dialogs
         dialog.setVisible(false);
-        File selectedFile = SwingHelper.promptForFile(dialog, null, "Select a log file");
+        File selectedFile = SwingHelper.promptForFile(dialog, null, title, loadDialog);
         URL result = null;
         if (selectedFile == null) {
             result = null;
@@ -641,6 +665,7 @@ class ReceiverConfigurationPanel extends JPanel {
     //default to cancelled
     private boolean cancelled = true;
     private String lastLogFormat;
+    private File saveConfigFile;
 
     public PanelModel(){
             file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
@@ -666,7 +691,6 @@ class ReceiverConfigurationPanel extends JPanel {
         }
 
         boolean isLoadSavedConfigs() {
-
             return !cancelled && useAutoSavedConfigRadioButton.isSelected();
         }
 
@@ -695,6 +719,14 @@ class ReceiverConfigurationPanel extends JPanel {
             return null;
         }
 
+        File getSaveConfigFile() {
+          return saveConfigFile;
+        }
+
+        void setSaveConfigFile(File file) {
+          this.saveConfigFile = file;
+        }
+
         URL getLogFileURL() {
             try
             {
@@ -746,5 +778,9 @@ class ReceiverConfigurationPanel extends JPanel {
           logFileFormatComboBoxModel.insertElementAt(lastLogFormat, 0);
           logFileFormatComboBox.setSelectedIndex(0);
         }
-    }
+
+        public boolean isCancelled() {
+          return cancelled;
+        }
+  }
 }

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java b/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java
index 89045a6..239a8bc 100644
--- a/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java
+++ b/src/main/java/org/apache/log4j/chainsaw/helper/SwingHelper.java
@@ -107,7 +107,7 @@ public final class SwingHelper {
     return result;
   }
 
-  public static File promptForFile(Container parent, String defaultPath, String title) {
+  public static File promptForFile(Container parent, String defaultPath, String title, boolean loadDialog) {
         if (SwingHelper.isMacOSX()) {
             //use filedialog on mac
             Component root = SwingUtilities.getRoot(parent);
@@ -118,6 +118,7 @@ public final class SwingHelper {
 
             FileDialog fileDialog = new FileDialog(frame, title);
             fileDialog.setModal(true);
+            fileDialog.setMode(loadDialog ? FileDialog.LOAD : FileDialog.SAVE);
             if (defaultPath != null) {
               fileDialog.setDirectory(defaultPath);
             }
@@ -144,7 +145,13 @@ public final class SwingHelper {
 
                 chooser.setAcceptAllFileFilterUsed(true);
 
-                int i = chooser.showOpenDialog(parent);
+                int i;
+                if (loadDialog) {
+                  i = chooser.showOpenDialog(parent);
+                } else {
+                  i = chooser.showSaveDialog(parent);
+                }
+
                 if (i != JFileChooser.APPROVE_OPTION) {
                     return null;
                 }

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversHelper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversHelper.java b/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversHelper.java
index 2db5d16..1c7a671 100644
--- a/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversHelper.java
+++ b/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversHelper.java
@@ -17,17 +17,39 @@
 package org.apache.log4j.chainsaw.receivers;
 
 
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.LineNumberReader;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 import org.apache.log4j.chainsaw.plugins.PluginClassLoaderFactory;
+import org.apache.log4j.plugins.Plugin;
+import org.apache.log4j.plugins.PluginRegistry;
+import org.apache.log4j.plugins.Receiver;
+import org.apache.log4j.spi.LoggerRepository;
+import org.apache.log4j.spi.LoggerRepositoryEx;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 
 /**
@@ -108,6 +130,81 @@ public class ReceiversHelper {
     public List getKnownReceiverClasses() {
       return Collections.unmodifiableList(receiverClassList);
     }
-    
 
+
+  public void saveReceiverConfiguration(File file) {
+    LoggerRepository repo = LogManager.getLoggerRepository();
+    PluginRegistry pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
+    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) {
+            //we programmatically register the ZeroConf plugin in the plugin registry
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            Document document = builder.newDocument();
+            Element rootElement = document.createElementNS("http://jakarta.apache.org/log4j/", "configuration");
+            rootElement.setPrefix("log4j");
+            rootElement.setAttribute("xmlns:log4j", "http://jakarta.apache.org/log4j/");
+            rootElement.setAttribute("debug", "true");
+
+            for (int i = 0; i < pluginList.size(); i++) {
+                Receiver receiver;
+
+                if (pluginList.get(i) instanceof Receiver) {
+                    receiver = (Receiver) pluginList.get(i);
+                } else {
+                    continue;
+                }
+
+                Element pluginElement = document.createElement("plugin");
+                pluginElement.setAttribute("name", receiver.getName());
+                pluginElement.setAttribute("class", receiver.getClass().getName());
+
+                BeanInfo beanInfo = Introspector.getBeanInfo(receiver.getClass());
+                List list = new ArrayList(Arrays.asList(beanInfo.getPropertyDescriptors()));
+
+                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");
+                        paramElement.setAttribute("name", d.getName());
+                        paramElement.setAttribute("value", o.toString());
+                        pluginElement.appendChild(paramElement);
+                    }
+                }
+
+                rootElement.appendChild(pluginElement);
+
+            }
+
+            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);
+            transformer.transform(source, result);
+            stream.close();
+        }
+
+    } catch (Exception e) {
+        e.printStackTrace();
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java b/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java
index d20037f..91ba7ca 100644
--- a/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java
+++ b/src/main/java/org/apache/log4j/chainsaw/receivers/ReceiversPanel.java
@@ -22,17 +22,12 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
 import java.io.File;
-import java.io.FileOutputStream;
 
 import javax.swing.AbstractAction;
 import javax.swing.Action;
@@ -62,13 +57,6 @@ import javax.swing.event.TreeWillExpandListener;
 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;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.DocumentBuilder;
 
 import org.apache.log4j.Level;
 import org.apache.log4j.LogManager;
@@ -95,8 +83,6 @@ import org.apache.log4j.plugins.PluginRegistry;
 import org.apache.log4j.plugins.Receiver;
 import org.apache.log4j.spi.LoggerRepository;
 import org.apache.log4j.spi.LoggerRepositoryEx;
-import org.w3c.dom.Element;
-import org.w3c.dom.Document;
 
 
 /**
@@ -642,80 +628,8 @@ public class ReceiversPanel extends JPanel implements SettingsListener {
     */
 
   public void saveSettings(SaveSettingsEvent event){
-      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) {
-              //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();
-              Document document = builder.newDocument();
-              Element rootElement = document.createElementNS("http://jakarta.apache.org/log4j/", "configuration");
-              rootElement.setPrefix("log4j");
-              rootElement.setAttribute("xmlns:log4j", "http://jakarta.apache.org/log4j/");
-              rootElement.setAttribute("debug", "true");
-
-              for (int i = 0; i < pluginList.size(); i++) {
-                  Receiver receiver;
-
-                  if (pluginList.get(i) instanceof Receiver) {
-                      receiver = (Receiver) pluginList.get(i);
-                  } else {
-                      continue;
-                  }
-
-                  Element pluginElement = document.createElement("plugin");
-                  pluginElement.setAttribute("name", receiver.getName());
-                  pluginElement.setAttribute("class", receiver.getClass().getName());
-
-                  BeanInfo beanInfo = Introspector.getBeanInfo(receiver.getClass());
-                  List list = new ArrayList(Arrays.asList(beanInfo.getPropertyDescriptors()));
-
-                  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");
-                          paramElement.setAttribute("name", d.getName());
-                          paramElement.setAttribute("value", o.toString());
-                          pluginElement.appendChild(paramElement);
-                      }
-                  }
-
-                  rootElement.appendChild(pluginElement);
-
-              }
-
-              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);
-              transformer.transform(source, result);
-              stream.close();
-          }
-
-      } catch (Exception e) {
-          e.printStackTrace();
-          logger.error("Error while writing receiver configurations to the configuration file");
-      }
-
+     File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
+     ReceiversHelper.getInstance().saveReceiverConfiguration(file);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/f95619e9/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html b/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
index 3068296..803563d 100644
--- a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
+++ b/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
@@ -12,6 +12,7 @@
 <h1>2.1</h1>
 <h2>4 Nov 2010</h2>
 <ul>
+<li>Added ability to save the receiver configuration defined through the initial receiver configuration panel with a user-specified file path and name</li>
 <li>Added ability to define which columns are displayed by default when a new tab is created by clicking the 'Use selected columns as default visible columns' button on the logpanel preferences column selection screen</li>
 </ul>
 <h2>22 Oct 2010</h2>