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.lf5.viewer.configure;
    18
    19  import java.awt.Color;
    20  import java.io.File;
    21  import java.io.FileWriter;
    22  import java.io.IOException;
    23  import java.io.PrintWriter;
    24  import java.util.ArrayList;
    25  import java.util.Enumeration;
    26  import java.util.Iterator;
    27  import java.util.List;
    28  import java.util.Map;
    29
    30  import javax.swing.JCheckBoxMenuItem;
    31  import javax.swing.tree.TreePath;
    32  import javax.xml.parsers.DocumentBuilder;
    33  import javax.xml.parsers.DocumentBuilderFactory;
    34
    35  import org.apache.log4j.lf5.LogLevel;
    36  import org.apache.log4j.lf5.LogLevelFormatException;
    37  import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
    38  import org.apache.log4j.lf5.viewer.LogTable;
    39  import org.apache.log4j.lf5.viewer.LogTableColumn;
    40  import org.apache.log4j.lf5.viewer.LogTableColumnFormatException;
    41  import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryExplorerModel;
    42  import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryExplorerTree;
    43  import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryNode;
    44  import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryPath;
    45  import org.w3c.dom.Document;
    46  import org.w3c.dom.NamedNodeMap;
    47  import org.w3c.dom.Node;
    48  import org.w3c.dom.NodeList;
    49
    50  /**
    51   * <p>ConfigurationManager handles the storage and retrival of the state of
    52   * the CategoryExplorer
    53   *
    54   * @author Richard Hurst
    55   * @author Brad Marlborough
    56   */
    57
    58  // Contributed by ThoughtWorks Inc.
    59
    60  public class ConfigurationManager extends Object {
    61    //--------------------------------------------------------------------------
    62    //   Constants:
    63    //--------------------------------------------------------------------------
    64    private static final String CONFIG_FILE_NAME = "lf5_configuration.xml";
    65    private static final String NAME = "name";
    66    private static final String PATH = "path";
    67    private static final String SELECTED = "selected";
    68    private static final String EXPANDED = "expanded";
    69    private static final String CATEGORY = "category";
    70    private static final String FIRST_CATEGORY_NAME = "Categories";
    71    private static final String LEVEL = "level";
    72    private static final String COLORLEVEL = "colorlevel";
    73    private static final String RED = "red";
    74    private static final String GREEN = "green";
    75    private static final String BLUE = "blue";
    76    private static final String COLUMN = "column";
    77    private static final String NDCTEXTFILTER = "searchtext";
    78    //--------------------------------------------------------------------------
    79    //   Protected Variables:
    80    //--------------------------------------------------------------------------
    81
    82    //--------------------------------------------------------------------------
    83    //   Private Variables:
    84    //--------------------------------------------------------------------------
    85    private LogBrokerMonitor _monitor = null;
    86    private LogTable _table = null;
    87
    88    //--------------------------------------------------------------------------
    89    //   Constructors:
    90    //--------------------------------------------------------------------------
    91    public ConfigurationManager(LogBrokerMonitor monitor, LogTable table) {
    92      super();
    93      _monitor = monitor;
    94      _table = table;
    95      load();
    96    }
    97    //--------------------------------------------------------------------------
    98    //   Public Methods:
    99    //--------------------------------------------------------------------------
    100
    101   public void save() {
    102     CategoryExplorerModel model = _monitor.getCategoryExplorerTree().getExplorerModel();
    103     CategoryNode root = model.getRootCategoryNode();
    104
    105     StringBuffer xml = new StringBuffer(2048);
    106     openXMLDocument(xml);
    107     openConfigurationXML(xml);
    108     processLogRecordFilter(_monitor.getNDCTextFilter(), xml);
    109     processLogLevels(_monitor.getLogLevelMenuItems(), xml);
    110     processLogLevelColors(_monitor.getLogLevelMenuItems(),
    111         LogLevel.getLogLevelColorMap(), xml);
    112     processLogTableColumns(LogTableColumn.getLogTableColumns(), xml);
    113     processConfigurationNode(root, xml);
    114     closeConfigurationXML(xml);
    115     store(xml.toString());
    116   }
    117
    118   public void reset() {
    119     deleteConfigurationFile();
    120     collapseTree();
    121     selectAllNodes();
    122   }
    123
    124   public static String treePathToString(TreePath path) {
    125     // count begins at one so as to not include the 'Categories' - root category
    126     StringBuffer sb = new StringBuffer();
    127     CategoryNode n = null;
    128     Object[] objects = path.getPath();
    129     for (int i = 1; i < objects.length; i++) {
    130       n = (CategoryNode) objects[i];
    131       if (i > 1) {
    132         sb.append(".");
    133       }
    134       sb.append(n.getTitle());
    135     }
    136     return sb.toString();
    137   }
    138
    139   //--------------------------------------------------------------------------
    140   //   Protected Methods:
    141   //--------------------------------------------------------------------------
    142   protected void load() {
    143     File file = new File(getFilename());
    144     if (file.exists()) {
    145       try {
    146         DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.
    147             newInstance();
    148         DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    149         Document doc = docBuilder.parse(file);
    150         processRecordFilter(doc);
    151         processCategories(doc);
    152         processLogLevels(doc);
    153         processLogLevelColors(doc);
    154         processLogTableColumns(doc);
    155       } catch (Exception e) {
    156         // ignore all error and just continue as if there was no
    157         // configuration xml file but do report a message
    158         System.err.println("Unable process configuration file at " +
    159             getFilename() + ". Error Message=" + e.getMessage());
    160       }
    161     }
    162
    163   }
    164
    165   // Added in version 1.2 - reads in the NDC text filter from the
    166   // xml configuration file.  If the value of the filter is not null
    167   // or an empty string ("") then the manager will set the LogBrokerMonitor's
    168   // LogRecordFilter to use the NDC LogRecordFilter.  Otherwise, the
    169   // LogBrokerMonitor will use the default LogRecordFilter.
    170   protected void processRecordFilter(Document doc) {
    171     NodeList nodeList = doc.getElementsByTagName(NDCTEXTFILTER);
    172
    173     // there is only one value stored
    174     Node n = nodeList.item(0);
    175     // add check for backwards compatibility  as this feature was added in
    176     // version 1.2
    177     if (n == null) {
    178       return;
    179     }
    180
    181     NamedNodeMap map = n.getAttributes();
    182     String text = getValue(map, NAME);
    183
    184     if (text == null || text.equals("")) {
    185       return;
    186     }
    187     _monitor.setNDCLogRecordFilter(text);
    188   }
    189
    190   protected void processCategories(Document doc) {
    191     CategoryExplorerTree tree = _monitor.getCategoryExplorerTree();
    192     CategoryExplorerModel model = tree.getExplorerModel();
    193     NodeList nodeList = doc.getElementsByTagName(CATEGORY);
    194
    195     // determine where the starting node is
    196     NamedNodeMap map = nodeList.item(0).getAttributes();
    197     int j = (getValue(map, NAME).equalsIgnoreCase(FIRST_CATEGORY_NAME)) ? 1 : 0;
    198     // iterate backwards throught the nodeList so that expansion of the
    199     // list can occur
    200     for (int i = nodeList.getLength() - 1; i >= j; i--) {
    201       Node n = nodeList.item(i);
    202       map = n.getAttributes();
    203       CategoryNode chnode = model.addCategory(new CategoryPath(getValue(map, PATH)));
    204       chnode.setSelected((getValue(map, SELECTED).equalsIgnoreCase("true")) ? true : false);
    205       if (getValue(map, EXPANDED).equalsIgnoreCase("true")) ;
    206       tree.expandPath(model.getTreePathToRoot(chnode));
    207     }
    208
    209   }
    210
    211   protected void processLogLevels(Document doc) {
    212     NodeList nodeList = doc.getElementsByTagName(LEVEL);
    213     Map menuItems = _monitor.getLogLevelMenuItems();
    214
    215     for (int i = 0; i < nodeList.getLength(); i++) {
    216       Node n = nodeList.item(i);
    217       NamedNodeMap map = n.getAttributes();
    218       String name = getValue(map, NAME);
    219       try {
    220         JCheckBoxMenuItem item =
    221             (JCheckBoxMenuItem) menuItems.get(LogLevel.valueOf(name));
    222         item.setSelected(getValue(map, SELECTED).equalsIgnoreCase("true"));
    223       } catch (LogLevelFormatException e) {
    224         // ignore it will be on by default.
    225       }
    226     }
    227   }
    228
    229   protected void processLogLevelColors(Document doc) {
    230     NodeList nodeList = doc.getElementsByTagName(COLORLEVEL);
    231     LogLevel.getLogLevelColorMap();
    232
    233     for (int i = 0; i < nodeList.getLength(); i++) {
    234       Node n = nodeList.item(i);
    235       // check for backwards compatibility since this feature was added
    236       // in version 1.3
    237       if (n == null) {
    238         return;
    239       }
    240
    241       NamedNodeMap map = n.getAttributes();
    242       String name = getValue(map, NAME);
    243       try {
    244         LogLevel level = LogLevel.valueOf(name);
    245         int red = Integer.parseInt(getValue(map, RED));
    246         int green = Integer.parseInt(getValue(map, GREEN));
    247         int blue = Integer.parseInt(getValue(map, BLUE));
    248         Color c = new Color(red, green, blue);
    249         if (level != null) {
    250           level.setLogLevelColorMap(level, c);
    251         }
    252
    253       } catch (LogLevelFormatException e) {
    254         // ignore it will be on by default.
    255       }
    256     }
    257   }
    258
    259   protected void processLogTableColumns(Document doc) {
    260     NodeList nodeList = doc.getElementsByTagName(COLUMN);
    261     Map menuItems = _monitor.getLogTableColumnMenuItems();
    262     List selectedColumns = new ArrayList();
    263     for (int i = 0; i < nodeList.getLength(); i++) {
    264       Node n = nodeList.item(i);
    265       // check for backwards compatibility since this feature was added
    266       // in version 1.3
    267       if (n == null) {
    268         return;
    269       }
    270       NamedNodeMap map = n.getAttributes();
    271       String name = getValue(map, NAME);
    272       try {
    273         LogTableColumn column = LogTableColumn.valueOf(name);
    274         JCheckBoxMenuItem item =
    275             (JCheckBoxMenuItem) menuItems.get(column);
    276         item.setSelected(getValue(map, SELECTED).equalsIgnoreCase("true"));
    277
    278         if (item.isSelected()) {
    279           selectedColumns.add(column);
    280         }
    281       } catch (LogTableColumnFormatException e) {
    282         // ignore it will be on by default.
    283       }
    284
    285       if (selectedColumns.isEmpty()) {
    286         _table.setDetailedView();
    287       } else {
    288         _table.setView(selectedColumns);
    289       }
    290
    291     }
    292   }
    293
    294   protected String getValue(NamedNodeMap map, String attr) {
    295     Node n = map.getNamedItem(attr);
    296     return n.getNodeValue();
    297   }
    298
    299   protected void collapseTree() {
    300     // collapse everything except the first category
    301     CategoryExplorerTree tree = _monitor.getCategoryExplorerTree();
    302     for (int i = tree.getRowCount() - 1; i > 0; i--) {
    303       tree.collapseRow(i);
    304     }
    305   }
    306
    307   protected void selectAllNodes() {
    308     CategoryExplorerModel model = _monitor.getCategoryExplorerTree().getExplorerModel();
    309     CategoryNode root = model.getRootCategoryNode();
    310     Enumeration all = root.breadthFirstEnumeration();
    311     CategoryNode n = null;
    312     while (all.hasMoreElements()) {
    313       n = (CategoryNode) all.nextElement();
    314       n.setSelected(true);
    315     }
    316   }
    317
    318   protected void store(String s) {
    319
    320     try {
    321       PrintWriter writer = new PrintWriter(new FileWriter(getFilename()));
    322       writer.print(s);
    323       writer.close();
    324     } catch (IOException e) {
    325       // do something with this error.
    326       e.printStackTrace();
    327     }
    328
    329   }
    330
    331   protected void deleteConfigurationFile() {
    332     try {
    333       File f = new File(getFilename());
    334       if (f.exists()) {
    335         f.delete();
    336       }
    337     } catch (SecurityException e) {
    338       System.err.println("Cannot delete " + getFilename() +
    339           " because a security violation occured.");
    340     }
    341   }
    342
    343   protected String getFilename() {
    344     String home = System.getProperty("user.home");
    345     String sep = System.getProperty("file.separator");
    346
    347     return home + sep + "lf5" + sep + CONFIG_FILE_NAME;
    348   }
    349
    350   //--------------------------------------------------------------------------
    351   //   Private Methods:
    352   //--------------------------------------------------------------------------
    353   private void processConfigurationNode(CategoryNode node, StringBuffer xml) {
    354     CategoryExplorerModel model = _monitor.getCategoryExplorerTree().getExplorerModel();
    355
    356     Enumeration all = node.breadthFirstEnumeration();
    357     CategoryNode n = null;
    358     while (all.hasMoreElements()) {
    359       n = (CategoryNode) all.nextElement();
    360       exportXMLElement(n, model.getTreePathToRoot(n), xml);
    361     }
    362
    363   }
    364
    365   private void processLogLevels(Map logLevelMenuItems, StringBuffer xml) {
    366     xml.append("\t<loglevels>\r\n");
    367     Iterator it = logLevelMenuItems.keySet().iterator();
    368     while (it.hasNext()) {
    369       LogLevel level = (LogLevel) it.next();
    370       JCheckBoxMenuItem item = (JCheckBoxMenuItem) logLevelMenuItems.get(level);
    371       exportLogLevelXMLElement(level.getLabel(), item.isSelected(), xml);
    372     }
    373
    374     xml.append("\t</loglevels>\r\n");
    375   }
    376
    377   private void processLogLevelColors(Map logLevelMenuItems, Map logLevelColors, StringBuffer xml) {
    378     xml.append("\t<loglevelcolors>\r\n");
    379     // iterate through the list of log levels being used (log4j, jdk1.4, custom levels)
    380     Iterator it = logLevelMenuItems.keySet().iterator();
    381     while (it.hasNext()) {
    382       LogLevel level = (LogLevel) it.next();
    383       // for each level, get the associated color from the log level color map
    384       Color color = (Color) logLevelColors.get(level);
    385       exportLogLevelColorXMLElement(level.getLabel(), color, xml);
    386     }
    387
    388     xml.append("\t</loglevelcolors>\r\n");
    389   }
    390
    391
    392   private void processLogTableColumns(List logTableColumnMenuItems, StringBuffer xml) {
    393     xml.append("\t<logtablecolumns>\r\n");
    394     Iterator it = logTableColumnMenuItems.iterator();
    395     while (it.hasNext()) {
    396       LogTableColumn column = (LogTableColumn) it.next();
    397       JCheckBoxMenuItem item = _monitor.getTableColumnMenuItem(column);
    398       exportLogTableColumnXMLElement(column.getLabel(), item.isSelected(), xml);
    399     }
    400
    401     xml.append("\t</logtablecolumns>\r\n");
    402   }
    403
    404   // Added in version 1.2 - stores the NDC text filter in the xml file
    405   // for future use.
    406   private void processLogRecordFilter(String text, StringBuffer xml) {
    407     xml.append("\t<").append(NDCTEXTFILTER).append(" ");
    408     xml.append(NAME).append("=\"").append(text).append("\"");
    409     xml.append("/>\r\n");
    410   }
    411
    412   private void openXMLDocument(StringBuffer xml) {
    413     xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n");
    414   }
    415
    416   private void openConfigurationXML(StringBuffer xml) {
    417     xml.append("<configuration>\r\n");
    418   }
    419
    420   private void closeConfigurationXML(StringBuffer xml) {
    421     xml.append("</configuration>\r\n");
    422   }
    423
    424   private void exportXMLElement(CategoryNode node, TreePath path, StringBuffer xml) {
    425     CategoryExplorerTree tree = _monitor.getCategoryExplorerTree();
    426
    427     xml.append("\t<").append(CATEGORY).append(" ");
    428     xml.append(NAME).append("=\"").append(node.getTitle()).append("\" ");
    429     xml.append(PATH).append("=\"").append(treePathToString(path)).append("\" ");
    430     xml.append(EXPANDED).append("=\"").append(tree.isExpanded(path)).append("\" ");
    431     xml.append(SELECTED).append("=\"").append(node.isSelected()).append("\"/>\r\n");
    432   }
    433
    434   private void exportLogLevelXMLElement(String label, boolean selected, StringBuffer xml) {
    435     xml.append("\t\t<").append(LEVEL).append(" ").append(NAME);
    436     xml.append("=\"").append(label).append("\" ");
    437     xml.append(SELECTED).append("=\"").append(selected);
    438     xml.append("\"/>\r\n");
    439   }
    440
    441   private void exportLogLevelColorXMLElement(String label, Color color, StringBuffer xml) {
    442     xml.append("\t\t<").append(COLORLEVEL).append(" ").append(NAME);
    443     xml.append("=\"").append(label).append("\" ");
    444     xml.append(RED).append("=\"").append(color.getRed()).append("\" ");
    445     xml.append(GREEN).append("=\"").append(color.getGreen()).append("\" ");
    446     xml.append(BLUE).append("=\"").append(color.getBlue());
    447     xml.append("\"/>\r\n");
    448   }
    449
    450   private void exportLogTableColumnXMLElement(String label, boolean selected, StringBuffer xml) {
    451     xml.append("\t\t<").append(COLUMN).append(" ").append(NAME);
    452     xml.append("=\"").append(label).append("\" ");
    453     xml.append(SELECTED).append("=\"").append(selected);
    454     xml.append("\"/>\r\n");
    455   }
    456   //--------------------------------------------------------------------------
    457   //   Nested Top-Level Classes or Interfaces:
    458   //--------------------------------------------------------------------------
    459
    460 }
    461
    462
    463
    464
    465
    466