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