ceki        2003/06/03 11:44:18

  Modified:    src/java/org/apache/log4j/xml DOMConfigurator.java
  Log:
  Reformatted with Jalopy. No other changes.
  
  Revision  Changes    Path
  1.56      +472 -379  jakarta-log4j/src/java/org/apache/log4j/xml/DOMConfigurator.java
  
  Index: DOMConfigurator.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/xml/DOMConfigurator.java,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- DOMConfigurator.java      5 May 2003 20:42:58 -0000       1.55
  +++ DOMConfigurator.java      3 Jun 2003 18:44:18 -0000       1.56
  @@ -1,35 +1,82 @@
   /*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  + * ============================================================================
  + *                   The Apache Software License, Version 1.1
  + * ============================================================================
    *
  - * This software is published under the terms of the Apache Software
  - * License version 1.1, a copy of which has been included with this
  - * distribution in the LICENSE.txt file.  */
  + *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without modifica-
  + * tion, are permitted provided that the following conditions are met:
  + *
  + * 1. Redistributions of  source code must  retain the above copyright  notice,
  + *    this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright notice,
  + *    this list of conditions and the following disclaimer in the documentation
  + *    and/or other materials provided with the distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if any, must
  + *    include  the following  acknowledgment:  "This product includes  software
  + *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
  + *    Alternately, this  acknowledgment may  appear in the software itself,  if
  + *    and wherever such third-party acknowledgments normally appear.
  + *
  + * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
  + *    endorse  or promote  products derived  from this  software without  prior
  + *    written permission. For written permission, please contact
  + *    [EMAIL PROTECTED]
  + *
  + * 5. Products  derived from this software may not  be called "Apache", nor may
  + *    "Apache" appear  in their name,  without prior written permission  of the
  + *    Apache Software Foundation.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  + * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  + * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
  + * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
  + * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
  + * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
  + * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  + * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + *
  + * This software  consists of voluntary contributions made  by many individuals
  + * on  behalf of the Apache Software  Foundation.  For more  information on the
  + * Apache Software Foundation, please see <http://www.apache.org/>.
  + *
  + */
   
   package org.apache.log4j.xml;
   
  -import java.util.*;
  -
  -import java.net.URL;
  -
  -import org.w3c.dom.*;
  -import java.lang.reflect.Method;
   import org.apache.log4j.*;
  -import org.apache.log4j.spi.*;
  -import org.apache.log4j.or.RendererMap;
  -import org.apache.log4j.helpers.*;
   import org.apache.log4j.config.PropertySetter;
  +import org.apache.log4j.helpers.*;
  +import org.apache.log4j.or.RendererMap;
   import org.apache.log4j.plugins.Plugin;
   import org.apache.log4j.plugins.PluginRegistry;
  +import org.apache.log4j.spi.*;
  +
  +import org.w3c.dom.*;
   
   import org.xml.sax.InputSource;
  +
   import java.io.FileInputStream;
  +import java.io.IOException;
   import java.io.InputStream;
   import java.io.Reader;
  -import java.io.IOException;
  -import javax.xml.parsers.DocumentBuilderFactory;
  +
  +import java.lang.reflect.Method;
  +
  +import java.net.URL;
  +
  +import java.util.*;
  +
   import javax.xml.parsers.DocumentBuilder;
  +import javax.xml.parsers.DocumentBuilderFactory;
   import javax.xml.parsers.FactoryConfigurationError;
   
  +
   // Contributors:   Mark Womack
   //                 Arun Katkere 
   
  @@ -51,244 +98,264 @@
   </pre>
   
      <p>There are sample XML files included in the package.
  -   
  +
      @author Christopher Taylor
      @author Ceki G&uuml;lc&uuml;
      @author Anders Kristensen
   
      @since 0.8.3 */
   public class DOMConfigurator implements Configurator {
  -
  -  static Logger logger = Logger.getLogger("LOG4J."+DOMConfigurator.class.getName());
  -
  +  static Logger logger =
  +    Logger.getLogger("LOG4J." + DOMConfigurator.class.getName());
     static final String CONFIGURATION_TAG = "log4j:configuration";
     static final String OLD_CONFIGURATION_TAG = "configuration";
  -  static final String RENDERER_TAG      = "renderer";
  -  static final String APPENDER_TAG   = "appender";
  -  static final String APPENDER_REF_TAG       = "appender-ref";  
  -  static final String PARAM_TAG      = "param";
  -  static final String LAYOUT_TAG     = "layout";
  -  static final String CATEGORY               = "category";
  -  static final String LOGGER         = "logger";
  -  static final String LOGGER_REF     = "logger-ref";
  -  static final String CATEGORY_FACTORY_TAG  = "categoryFactory";
  -  static final String NAME_ATTR              = "name";
  -  static final String CLASS_ATTR        = "class";
  -  static final String VALUE_ATTR     = "value";
  -  static final String ROOT_TAG               = "root";
  -  static final String ROOT_REF               = "root-ref";
  -  static final String LEVEL_TAG              = "level";
  -  static final String PRIORITY_TAG      = "priority";
  -  static final String FILTER_TAG     = "filter";
  -  static final String ERROR_HANDLER_TAG      = "errorHandler";
  -  static final String REF_ATTR               = "ref";
  -  static final String ADDITIVITY_ATTR    = "additivity";  
  -  static final String THRESHOLD_ATTR       = "threshold";
  -  static final String CONFIG_DEBUG_ATTR  = "configDebug";
  -  static final String INTERNAL_DEBUG_ATTR  = "debug";
  +  static final String RENDERER_TAG = "renderer";
  +  static final String APPENDER_TAG = "appender";
  +  static final String APPENDER_REF_TAG = "appender-ref";
  +  static final String PARAM_TAG = "param";
  +  static final String LAYOUT_TAG = "layout";
  +  static final String CATEGORY = "category";
  +  static final String LOGGER = "logger";
  +  static final String LOGGER_REF = "logger-ref";
  +  static final String CATEGORY_FACTORY_TAG = "categoryFactory";
  +  static final String NAME_ATTR = "name";
  +  static final String CLASS_ATTR = "class";
  +  static final String VALUE_ATTR = "value";
  +  static final String ROOT_TAG = "root";
  +  static final String ROOT_REF = "root-ref";
  +  static final String LEVEL_TAG = "level";
  +  static final String PRIORITY_TAG = "priority";
  +  static final String FILTER_TAG = "filter";
  +  static final String ERROR_HANDLER_TAG = "errorHandler";
  +  static final String REF_ATTR = "ref";
  +  static final String ADDITIVITY_ATTR = "additivity";
  +  static final String THRESHOLD_ATTR = "threshold";
  +  static final String CONFIG_DEBUG_ATTR = "configDebug";
  +  static final String INTERNAL_DEBUG_ATTR = "debug";
     static final String RENDERING_CLASS_ATTR = "renderingClass";
     static final String RENDERED_CLASS_ATTR = "renderedClass";
     static final String PLUGIN_TAG = "plugin";
  -
     static final String EMPTY_STR = "";
  -  static final Class[] ONE_STRING_PARAM = new Class[] {String.class};
  +  static final Class[] ONE_STRING_PARAM = new Class[] { String.class };
  +  static final String dbfKey = "javax.xml.parsers.DocumentBuilderFactory";
   
  -  final static String dbfKey = "javax.xml.parsers.DocumentBuilderFactory";
  -
  -  
     // key: appenderName, value: appender
     Hashtable appenderBag;
  -
     Properties props;
     LoggerRepository repository;
   
     /**
        No argument constructor.
     */
  -  public
  -  DOMConfigurator () { 
  +  public DOMConfigurator() {
       appenderBag = new Hashtable();
     }
   
     /**
        Used internally to parse appenders by IDREF name.
     */
  -  protected
  -  Appender findAppenderByName(Document doc, String appenderName)  {      
  +  protected Appender findAppenderByName(Document doc, String appenderName) {
       Appender appender = (Appender) appenderBag.get(appenderName);
   
  -    if(appender != null) {
  +    if (appender != null) {
         return appender;
       } else {
         // Doesn't work on DOM Level 1 :
         // Element element = doc.getElementById(appenderName);
  -                        
         // Endre's hack:
         Element element = null;
         NodeList list = doc.getElementsByTagName("appender");
  -      for (int t=0; t < list.getLength(); t++) {
  -     Node node = list.item(t);
  -     NamedNodeMap map= node.getAttributes();
  -     Node attrNode = map.getNamedItem("name");
  -     if (appenderName.equals(attrNode.getNodeValue())) {
  -       element = (Element) node;
  -       break;
  -     }
  +
  +      for (int t = 0; t < list.getLength(); t++) {
  +        Node node = list.item(t);
  +        NamedNodeMap map = node.getAttributes();
  +        Node attrNode = map.getNamedItem("name");
  +
  +        if (appenderName.equals(attrNode.getNodeValue())) {
  +          element = (Element) node;
  +
  +          break;
  +        }
         }
  +
         // Hack finished.
  +      if (element == null) {
  +        LogLog.error(
  +          "No appender named [" + appenderName + "] could be found.");
   
  -      if(element == null) {
  -     LogLog.error("No appender named ["+appenderName+"] could be found."); 
  -     return null;
  +        return null;
         } else {
  -     appender = parseAppender(element);
  -     appenderBag.put(appenderName, appender);
  -     return appender;
  +        appender = parseAppender(element);
  +        appenderBag.put(appenderName, appender);
  +
  +        return appender;
         }
  -    } 
  +    }
     }
  +
     /**
        Used internally to parse appenders by IDREF element.
      */
  -  protected
  -  Appender findAppenderByReference(Element appenderRef) {    
  -    String appenderName = subst(appenderRef.getAttribute(REF_ATTR));    
  +  protected Appender findAppenderByReference(Element appenderRef) {
  +    String appenderName = subst(appenderRef.getAttribute(REF_ATTR));
       Document doc = appenderRef.getOwnerDocument();
  +
       return findAppenderByName(doc, appenderName);
     }
   
     /**
        Used internally to parse an appender element.
      */
  -  protected
  -  Appender parseAppender (Element appenderElement) {
  +  protected Appender parseAppender(Element appenderElement) {
       String className = subst(appenderElement.getAttribute(CLASS_ATTR));
  -    LogLog.debug("Class name: [" + className+']');    
  +    LogLog.debug("Class name: [" + className + ']');
  +
       try {
  -      Object instance        = Loader.loadClass(className).newInstance();
  -      Appender appender      = (Appender)instance;
  +      Object instance = Loader.loadClass(className).newInstance();
  +      Appender appender = (Appender) instance;
         PropertySetter propSetter = new PropertySetter(appender);
   
         appender.setName(subst(appenderElement.getAttribute(NAME_ATTR)));
  -      
  -      NodeList children      = appenderElement.getChildNodes();
  -      final int length       = children.getLength();
  +
  +      NodeList children = appenderElement.getChildNodes();
  +      final int length = children.getLength();
   
         for (int loop = 0; loop < length; loop++) {
  -     Node currentNode = children.item(loop);
  +        Node currentNode = children.item(loop);
  +
  +        /* We're only interested in Elements */
  +        if (!isElement(currentNode)) {
  +          continue;
  +        }
  +
  +        Element currentElement = (Element) currentNode;
   
  -     /* We're only interested in Elements */
  -     if (!isElement(currentNode)) {
  -       continue;
  -     }
  -     
  -     Element currentElement = (Element)currentNode;
  -
  -     // Parse appender parameters 
  -     if (currentElement.getTagName().equals(PARAM_TAG)) {
  -       setParameter(currentElement, propSetter);     
  -     } else if (currentElement.getTagName().equals(ERROR_HANDLER_TAG)) {
  -       parseErrorHandler(currentElement, appender);
  -     } else if (currentElement.getTagName().equals(APPENDER_REF_TAG)) {
  -       String refName = subst(currentElement.getAttribute(REF_ATTR));
  -       if(appender instanceof AppenderAttachable) {
  -         AppenderAttachable aa = (AppenderAttachable) appender;
  -         LogLog.debug("Attaching appender named ["+ refName+
  -                      "] to appender named ["+ appender.getName()+"].");
  -         aa.addAppender(findAppenderByReference(currentElement));
  -       } else {
  -         LogLog.error("Requesting attachment of appender named ["+
  -                      refName+ "] to appender named ["+ appender.getName()+
  -                      "] which does not implement 
org.apache.log4j.spi.AppenderAttachable.");
  -       }
  -     } else {
  -       logger.debug("Handling nested <"+ currentElement.getTagName() 
  -                          + "> for appender "+appender.getName());
  -       configureNestedComponent(propSetter, currentElement);     
  -     }
  +        // Parse appender parameters 
  +        if (currentElement.getTagName().equals(PARAM_TAG)) {
  +          setParameter(currentElement, propSetter);
  +        } else if (currentElement.getTagName().equals(ERROR_HANDLER_TAG)) {
  +          parseErrorHandler(currentElement, appender);
  +        } else if (currentElement.getTagName().equals(APPENDER_REF_TAG)) {
  +          String refName = subst(currentElement.getAttribute(REF_ATTR));
  +
  +          if (appender instanceof AppenderAttachable) {
  +            AppenderAttachable aa = (AppenderAttachable) appender;
  +            LogLog.debug(
  +              "Attaching appender named [" + refName + "] to appender named ["
  +              + appender.getName() + "].");
  +            aa.addAppender(findAppenderByReference(currentElement));
  +          } else {
  +            LogLog.error(
  +              "Requesting attachment of appender named [" + refName
  +              + "] to appender named [" + appender.getName()
  +              + "] which does not implement 
org.apache.log4j.spi.AppenderAttachable.");
  +          }
  +        } else {
  +          logger.debug(
  +            "Handling nested <" + currentElement.getTagName()
  +            + "> for appender " + appender.getName());
  +          configureNestedComponent(propSetter, currentElement);
  +        }
         }
  +
         propSetter.activate();
  +
         return appender;
       }
       /* Yes, it's ugly.  But all of these exceptions point to the same
          problem: we can't create an Appender */
  -    catch (Exception oops) {
  -      LogLog.error("Could not create an Appender. Reported error follows.",
  -                oops);
  +     catch (Exception oops) {
  +      LogLog.error(
  +        "Could not create an Appender. Reported error follows.", oops);
  +
         return null;
       }
     }
  -  
  -  protected void configureNestedComponent(PropertySetter parentBean, Element 
nestedElement) {
  -    
  +
  +  protected void configureNestedComponent(
  +    PropertySetter parentBean, Element nestedElement) {
       String nestedElementTagName = nestedElement.getTagName();
  -    
  +
       int containmentType = parentBean.canContainComponent(nestedElementTagName);
  -    
  -    if(containmentType == PropertySetter.NOT_FOUND) {
  -      logger.warn("A component with tag name ["+nestedElementTagName
  -               +"] cannot be contained within an object of class ["
  -               + parentBean.getObjClass().getName()+"].");
  +
  +    if (containmentType == PropertySetter.NOT_FOUND) {
  +      logger.warn(
  +        "A component with tag name [" + nestedElementTagName
  +        + "] cannot be contained within an object of class ["
  +        + parentBean.getObjClass().getName() + "].");
  +
         return; // nothing can be done
       }
  -    
  +
       boolean debug = logger.isDebugEnabled();
   
       String className = subst(nestedElement.getAttribute(CLASS_ATTR));
  -    if(debug)
  -      logger.debug("Will instantiate instance of class ["+className+']');    
  -    
  +
  +    if (debug) {
  +      logger.debug("Will instantiate instance of class [" + className + ']');
  +    }
  +
       Object nestedComponent = null;
  +
       try {
  -      nestedComponent = Loader.loadClass(className).newInstance();      
  -    } catch(Exception e) {
  -      logger.warn("Could not instantiate object of type ["+className+"].", e);
  +      nestedComponent = Loader.loadClass(className).newInstance();
  +    } catch (Exception e) {
  +      logger.warn(
  +        "Could not instantiate object of type [" + className + "].", e);
  +
         return;
  -    } 
  +    }
   
  -    NodeList children        = nestedElement.getChildNodes();
  -    final int length         = children.getLength();
  -    PropertySetter nestedBean = new PropertySetter(nestedComponent); 
  +    NodeList children = nestedElement.getChildNodes();
  +    final int length = children.getLength();
  +    PropertySetter nestedBean = new PropertySetter(nestedComponent);
   
       for (int loop = 0; loop < length; loop++) {
         Node currentNode = children.item(loop);
   
         /* We're only interested in Elements */
         if (!isElement(currentNode)) {
  -     continue;
  +        continue;
         }
   
  -      Element currentElement = (Element)currentNode;
  -      if(hasParamTag(currentElement)) {
  -     if(debug) {
  -       logger.debug("Configuring parameter ["+currentElement.getAttribute("name")
  -                    + "] for <"+nestedElementTagName+">.");
  -     }
  -     setParameter(currentElement, nestedBean);
  +      Element currentElement = (Element) currentNode;
  +
  +      if (hasParamTag(currentElement)) {
  +        if (debug) {
  +          logger.debug(
  +            "Configuring parameter [" + currentElement.getAttribute("name")
  +            + "] for <" + nestedElementTagName + ">.");
  +        }
  +
  +        setParameter(currentElement, nestedBean);
         } else {
  -     if(debug) {
  -       logger.debug("Configuring component "+nestedComponent+ " with tagged as <"
  -                    +currentElement.getTagName()+">.");
  -     }
  -     configureNestedComponent(nestedBean, currentElement);
  +        if (debug) {
  +          logger.debug(
  +            "Configuring component " + nestedComponent + " with tagged as <"
  +            + currentElement.getTagName() + ">.");
  +        }
  +
  +        configureNestedComponent(nestedBean, currentElement);
         }
       }
  -    
  +
       // Now let us attach the component
  -    switch(containmentType) {
  -    case PropertySetter.AS_PROPERTY:  
  +    switch (containmentType) {
  +    case PropertySetter.AS_PROPERTY:
         parentBean.setComponent(nestedElementTagName, nestedComponent);
  +
         break;
  -    case PropertySetter.AS_COLLECTION:  
  +
  +    case PropertySetter.AS_COLLECTION:
         parentBean.addComponent(nestedElementTagName, nestedComponent);
  +
         break;
       }
     }
   
  -
     /**
      * Returns <code>true</code> if the node passed as parameter is an
  -   * Element, returns <code>false</code> otherwise.  
  +   * Element, returns <code>false</code> otherwise.
      * */
     protected boolean isElement(Node node) {
       return (node.getNodeType() == Node.ELEMENT_NODE);
  @@ -305,115 +372,123 @@
     /**
        Used internally to parse an [EMAIL PROTECTED] ErrorHandler} element.
      */
  -  protected
  -  void parseErrorHandler(Element element, Appender appender) {
  -    ErrorHandler eh = (ErrorHandler) OptionConverter.instantiateByClassName(
  -                                       subst(element.getAttribute(CLASS_ATTR)),
  -                                       org.apache.log4j.spi.ErrorHandler.class, 
  -                                    null);
  -    
  -    if(eh != null) {
  +  protected void parseErrorHandler(Element element, Appender appender) {
  +    ErrorHandler eh =
  +      (ErrorHandler) OptionConverter.instantiateByClassName(
  +        subst(element.getAttribute(CLASS_ATTR)),
  +        org.apache.log4j.spi.ErrorHandler.class, null);
  +
  +    if (eh != null) {
         eh.setAppender(appender);
   
         PropertySetter propSetter = new PropertySetter(eh);
         NodeList children = element.getChildNodes();
  -      final int length       = children.getLength();
  +      final int length = children.getLength();
   
         for (int loop = 0; loop < length; loop++) {
  -     Node currentNode = children.item(loop);
  -     if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -       Element currentElement = (Element) currentNode;
  -       String tagName = currentElement.getTagName();
  -       if(tagName.equals(PARAM_TAG)) {
  +        Node currentNode = children.item(loop);
  +
  +        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  +          Element currentElement = (Element) currentNode;
  +          String tagName = currentElement.getTagName();
  +
  +          if (tagName.equals(PARAM_TAG)) {
               setParameter(currentElement, propSetter);
  -       } else if(tagName.equals(APPENDER_REF_TAG)) {
  -         eh.setBackupAppender(findAppenderByReference(currentElement));
  -       } else if(tagName.equals(LOGGER_REF)) {
  -         String loggerName = currentElement.getAttribute(REF_ATTR);      
  -         Logger logger = repository.getLogger(loggerName);
  -         eh.setLogger(logger);
  -       } else if(tagName.equals(ROOT_REF)) {
  -         Logger root = repository.getRootLogger();
  -         eh.setLogger(root);
  -       }
  -     }
  +          } else if (tagName.equals(APPENDER_REF_TAG)) {
  +            eh.setBackupAppender(findAppenderByReference(currentElement));
  +          } else if (tagName.equals(LOGGER_REF)) {
  +            String loggerName = currentElement.getAttribute(REF_ATTR);
  +            Logger logger = repository.getLogger(loggerName);
  +            eh.setLogger(logger);
  +          } else if (tagName.equals(ROOT_REF)) {
  +            Logger root = repository.getRootLogger();
  +            eh.setLogger(root);
  +          }
  +        }
         }
  +
         propSetter.activate();
         appender.setErrorHandler(eh);
       }
     }
  -  
  +
     /**
        Used internally to parse a filter element.
      */
  -  protected
  -  void parseFilters(Element element, Appender appender) {
  +  protected void parseFilters(Element element, Appender appender) {
       String clazz = subst(element.getAttribute(CLASS_ATTR));
  -    Filter filter = (Filter) OptionConverter.instantiateByClassName(clazz,
  -                                                Filter.class, null);
  -    
  -    if(filter != null) {
  +    Filter filter =
  +      (Filter) OptionConverter.instantiateByClassName(
  +        clazz, Filter.class, null);
  +
  +    if (filter != null) {
         PropertySetter propSetter = new PropertySetter(filter);
         NodeList children = element.getChildNodes();
  -      final int length       = children.getLength();
  +      final int length = children.getLength();
   
         for (int loop = 0; loop < length; loop++) {
  -     Node currentNode = children.item(loop);
  -     if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -       Element currentElement = (Element) currentNode;
  -       String tagName = currentElement.getTagName();
  -       if(tagName.equals(PARAM_TAG)) {
  +        Node currentNode = children.item(loop);
  +
  +        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  +          Element currentElement = (Element) currentNode;
  +          String tagName = currentElement.getTagName();
  +
  +          if (tagName.equals(PARAM_TAG)) {
               setParameter(currentElement, propSetter);
  -       } 
  -     }
  +          }
  +        }
         }
  +
         propSetter.activate();
  -      LogLog.debug("Adding filter of type ["+filter.getClass()
  -                +"] to appender named ["+appender.getName()+"].");
  +      LogLog.debug(
  +        "Adding filter of type [" + filter.getClass()
  +        + "] to appender named [" + appender.getName() + "].");
         appender.addFilter(filter);
  -    }    
  +    }
     }
  -  
  +
     /**
        Used internally to parse an category element.
     */
  -  protected
  -  void parseCategory (Element loggerElement) {
  +  protected void parseCategory(Element loggerElement) {
       // Create a new org.apache.log4j.Category object from the <category> element.
       String catName = subst(loggerElement.getAttribute(NAME_ATTR));
   
  -    Logger cat;    
  +    Logger cat;
   
       String className = subst(loggerElement.getAttribute(CLASS_ATTR));
   
  -
  -    if(EMPTY_STR.equals(className)) {
  +    if (EMPTY_STR.equals(className)) {
         LogLog.debug("Retreiving an instance of org.apache.log4j.Logger.");
         cat = repository.getLogger(catName);
  -    }
  -    else {
  -      LogLog.debug("Desired logger sub-class: ["+className+']');
  -       try {  
  -      Class clazz = Loader.loadClass(className);
  -      Method getInstanceMethod = clazz.getMethod("getLogger", 
  -                                                 ONE_STRING_PARAM);
  -      cat = (Logger) getInstanceMethod.invoke(null, new Object[] {catName});
  -       } catch (Exception oops) {
  -      LogLog.error("Could not retrieve category ["+catName+
  -                   "]. Reported error follows.", oops);
  -      return;
  -       }
  +    } else {
  +      LogLog.debug("Desired logger sub-class: [" + className + ']');
  +
  +      try {
  +        Class clazz = Loader.loadClass(className);
  +        Method getInstanceMethod =
  +          clazz.getMethod("getLogger", ONE_STRING_PARAM);
  +        cat =
  +          (Logger) getInstanceMethod.invoke(null, new Object[] { catName });
  +      } catch (Exception oops) {
  +        LogLog.error(
  +          "Could not retrieve category [" + catName
  +          + "]. Reported error follows.", oops);
  +
  +        return;
  +      }
       }
   
       // Setting up a category needs to be an atomic operation, in order
       // to protect potential log operations while category
       // configuration is in progress.
  -    synchronized(cat) {
  -      boolean additivity = OptionConverter.toBoolean(
  -                           subst(loggerElement.getAttribute(ADDITIVITY_ATTR)),
  -                        true);
  -    
  -      LogLog.debug("Setting ["+cat.getName()+"] additivity to ["+additivity+"].");
  +    synchronized (cat) {
  +      boolean additivity =
  +        OptionConverter.toBoolean(
  +          subst(loggerElement.getAttribute(ADDITIVITY_ATTR)), true);
  +
  +      LogLog.debug(
  +        "Setting [" + cat.getName() + "] additivity to [" + additivity + "].");
         cat.setAdditivity(additivity);
         parseChildrenOfLoggerElement(loggerElement, cat, false);
       }
  @@ -422,68 +497,70 @@
     /**
        Used internally to parse the roor category element.
     */
  -  protected void parseRoot (Element rootElement) {
  +  protected void parseRoot(Element rootElement) {
       Logger root = repository.getRootLogger();
  +
       // category configuration needs to be atomic
  -    synchronized(root) {    
  +    synchronized (root) {
         parseChildrenOfLoggerElement(rootElement, root, true);
       }
     }
   
  -
     /**
        Used internally to parse the children of a category element.
     */
  -  protected void parseChildrenOfLoggerElement(Element catElement,
  -                                   Logger cat, boolean isRoot) {
  -    
  +  protected void parseChildrenOfLoggerElement(
  +    Element catElement, Logger cat, boolean isRoot) {
       PropertySetter propSetter = new PropertySetter(cat);
  -    
  +
       // Remove all existing appenders from cat. They will be
       // reconstructed if need be.
       cat.removeAllAppenders();
   
  +    NodeList children = catElement.getChildNodes();
  +    final int length = children.getLength();
   
  -    NodeList children        = catElement.getChildNodes();
  -    final int length         = children.getLength();
  -    
       for (int loop = 0; loop < length; loop++) {
         Node currentNode = children.item(loop);
   
         if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
  -     Element currentElement = (Element) currentNode;
  -     String tagName = currentElement.getTagName();
  -     
  -     if (tagName.equals(APPENDER_REF_TAG)) {
  -       Element appenderRef = (Element) currentNode;
  -       Appender appender = findAppenderByReference(appenderRef);
  -       String refName =  subst(appenderRef.getAttribute(REF_ATTR));
  -       if(appender != null)
  -         LogLog.debug("Adding appender named ["+ refName+ 
  -                      "] to category ["+cat.getName()+"].");
  -       else 
  -         LogLog.debug("Appender named ["+ refName + "] not found.");
  -         
  -       cat.addAppender(appender);
  -       
  -     } else if(tagName.equals(LEVEL_TAG)) {
  -       parseLevel(currentElement, cat, isRoot);      
  -     } else if(tagName.equals(PRIORITY_TAG)) {
  -       parseLevel(currentElement, cat, isRoot);
  -     } else if(tagName.equals(PARAM_TAG)) {
  +        Element currentElement = (Element) currentNode;
  +        String tagName = currentElement.getTagName();
  +
  +        if (tagName.equals(APPENDER_REF_TAG)) {
  +          Element appenderRef = (Element) currentNode;
  +          Appender appender = findAppenderByReference(appenderRef);
  +          String refName = subst(appenderRef.getAttribute(REF_ATTR));
  +
  +          if (appender != null) {
  +            LogLog.debug(
  +              "Adding appender named [" + refName + "] to category ["
  +              + cat.getName() + "].");
  +          } else {
  +            LogLog.debug("Appender named [" + refName + "] not found.");
  +          }
  +
  +          cat.addAppender(appender);
  +        } else if (tagName.equals(LEVEL_TAG)) {
  +          parseLevel(currentElement, cat, isRoot);
  +        } else if (tagName.equals(PRIORITY_TAG)) {
  +          parseLevel(currentElement, cat, isRoot);
  +        } else if (tagName.equals(PARAM_TAG)) {
             setParameter(currentElement, propSetter);
  -     }
  +        }
         }
       }
  +
       propSetter.activate();
     }
   
     protected void parseRenderer(Element element) {
       String renderingClass = subst(element.getAttribute(RENDERING_CLASS_ATTR));
       String renderedClass = subst(element.getAttribute(RENDERED_CLASS_ATTR));
  -    if(repository instanceof RendererSupport) {
  -      RendererMap.addRenderer((RendererSupport) repository, renderedClass, 
  -                           renderingClass);
  +
  +    if (repository instanceof RendererSupport) {
  +      RendererMap.addRenderer(
  +        (RendererSupport) repository, renderedClass, renderingClass);
       }
     }
   
  @@ -492,53 +569,60 @@
     */
     protected void parseLevel(Element element, Logger logger, boolean isRoot) {
       String catName = logger.getName();
  -    if(isRoot) {
  +
  +    if (isRoot) {
         catName = "root";
       }
   
       String priStr = subst(element.getAttribute(VALUE_ATTR));
  -    LogLog.debug("Level value for "+catName+" is  ["+priStr+"].");
  -    
  -    if(INHERITED.equalsIgnoreCase(priStr) || NULL.equalsIgnoreCase(priStr)) {
  -      if(isRoot) {
  -     LogLog.error("Root level cannot be inherited. Ignoring directive.");
  +    LogLog.debug("Level value for " + catName + " is  [" + priStr + "].");
  +
  +    if (INHERITED.equalsIgnoreCase(priStr) || NULL.equalsIgnoreCase(priStr)) {
  +      if (isRoot) {
  +        LogLog.error("Root level cannot be inherited. Ignoring directive.");
         } else {
  -     logger.setLevel(null);
  +        logger.setLevel(null);
         }
       } else {
  -      String className = subst(element.getAttribute(CLASS_ATTR));      
  -      if(EMPTY_STR.equals(className)) {      
  -     logger.setLevel(OptionConverter.toLevel(priStr, Level.DEBUG));
  +      String className = subst(element.getAttribute(CLASS_ATTR));
  +
  +      if (EMPTY_STR.equals(className)) {
  +        logger.setLevel(OptionConverter.toLevel(priStr, Level.DEBUG));
         } else {
  -     LogLog.debug("Desired Level sub-class: ["+className+']');
  -     try {    
  -       Class clazz = Loader.loadClass(className);
  -       Method toLevelMethod = clazz.getMethod("toLevel", 
  -                                                 ONE_STRING_PARAM);
  -       Level pri = (Level) toLevelMethod.invoke(null, 
  -                                                 new Object[] {priStr});
  -       logger.setLevel(pri);
  -     } catch (Exception oops) {
  -       LogLog.error("Could not create level ["+priStr+
  -                    "]. Reported error follows.", oops);
  -       return;
  -     }
  +        LogLog.debug("Desired Level sub-class: [" + className + ']');
  +
  +        try {
  +          Class clazz = Loader.loadClass(className);
  +          Method toLevelMethod = clazz.getMethod("toLevel", ONE_STRING_PARAM);
  +          Level pri =
  +            (Level) toLevelMethod.invoke(null, new Object[] { priStr });
  +          logger.setLevel(pri);
  +        } catch (Exception oops) {
  +          LogLog.error(
  +            "Could not create level [" + priStr + "]. Reported error follows.",
  +            oops);
  +
  +          return;
  +        }
         }
       }
  -    LogLog.debug(catName + " level set to " + logger.getLevel());    
  +
  +    LogLog.debug(catName + " level set to " + logger.getLevel());
     }
   
     protected Plugin parsePlugin(Element pluginElement) {
       String className = subst(pluginElement.getAttribute(CLASS_ATTR));
  -    LogLog.debug("Creating plugin: [" + className+']');    
  +    LogLog.debug("Creating plugin: [" + className + ']');
  +
       try {
  -      Plugin plugin = (Plugin)Loader.loadClass(className).newInstance();
  +      Plugin plugin = (Plugin) Loader.loadClass(className).newInstance();
         PropertySetter propSetter = new PropertySetter(plugin);
   
         plugin.setName(subst(pluginElement.getAttribute(NAME_ATTR)));
  -      
  -      NodeList children      = pluginElement.getChildNodes();
  -      final int length       = children.getLength();
  +
  +      NodeList children = pluginElement.getChildNodes();
  +      final int length = children.getLength();
  +
         for (int loop = 0; loop < length; loop++) {
           Node currentNode = children.item(loop);
   
  @@ -546,22 +630,23 @@
           if (!isElement(currentNode)) {
             continue;
           }
  -     
  -        Element currentElement = (Element)currentNode;
  -  
  -             // Parse appender parameters 
  -             if (currentElement.getTagName().equals(PARAM_TAG)) {
  -               setParameter(currentElement, propSetter);     
  -             }
  +
  +        Element currentElement = (Element) currentNode;
  +
  +        // Parse appender parameters 
  +        if (currentElement.getTagName().equals(PARAM_TAG)) {
  +          setParameter(currentElement, propSetter);
  +        }
         }
  +
         return plugin;
       } catch (Exception e) {
  -      LogLog.error("Could not create plugin. Reported error follows.",
  -                e);
  +      LogLog.error("Could not create plugin. Reported error follows.", e);
  +
         return null;
       }
     }
  -  
  +
     protected void setParameter(Element elem, PropertySetter propSetter) {
       String name = subst(elem.getAttribute(NAME_ATTR));
       String value = (elem.getAttribute(VALUE_ATTR));
  @@ -569,26 +654,25 @@
       propSetter.setProperty(name, value);
     }
   
  -
     /**
        Configure log4j using a <code>configuration</code> element as
  -     defined in the log4j.dtd. 
  +     defined in the log4j.dtd.
   
     */
  -  static public void configure (Element element) {
  +  public static void configure(Element element) {
       DOMConfigurator configurator = new DOMConfigurator();
  -    configurator.doConfigure(element,  LogManager.getLoggerRepository());
  +    configurator.doConfigure(element, LogManager.getLoggerRepository());
     }
   
  - /**
  -     Like [EMAIL PROTECTED] #configureAndWatch(String, long)} except that the
  -     default delay as defined by [EMAIL PROTECTED] FileWatchdog#DEFAULT_DELAY} is
  -     used. 
  +  /**
  +      Like [EMAIL PROTECTED] #configureAndWatch(String, long)} except that the
  +      default delay as defined by [EMAIL PROTECTED] FileWatchdog#DEFAULT_DELAY} is
  +      used.
   
  -     @param configFilename A log4j configuration file in XML format.
  +      @param configFilename A log4j configuration file in XML format.
   
  -  */
  -  static public void configureAndWatch(String configFilename) {
  +   */
  +  public static void configureAndWatch(String configFilename) {
       configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY);
     }
   
  @@ -598,12 +682,12 @@
        check if <code>configFilename</code> has been created or
        modified. The period is determined by the <code>delay</code>
        argument. If a change or file creation is detected, then
  -     <code>configFilename</code> is read to configure log4j.  
  +     <code>configFilename</code> is read to configure log4j.
   
         @param configFilename A log4j configuration file in XML format.
         @param delay The delay in milliseconds to wait between each check.
     */
  -  static public void configureAndWatch(String configFilename, long delay) {
  +  public static void configureAndWatch(String configFilename, long delay) {
       XMLWatchdog xdog = new XMLWatchdog(configFilename);
       xdog.setDelay(delay);
       xdog.start();
  @@ -611,28 +695,28 @@
   
     public void doConfigure(String filename, LoggerRepository repository) {
       FileInputStream fis = null;
  +
       try {
         fis = new FileInputStream(filename);
         doConfigure(fis, repository);
  -    } catch(IOException e) {
  -      LogLog.error("Could not open ["+filename+"].", e);
  +    } catch (IOException e) {
  +      LogLog.error("Could not open [" + filename + "].", e);
       } finally {
         if (fis != null) {
  -     try {
  -       fis.close();
  -     } catch(java.io.IOException e) {
  -       LogLog.error("Could not close ["+filename+"].", e);
  -     }
  +        try {
  +          fis.close();
  +        } catch (java.io.IOException e) {
  +          LogLog.error("Could not close [" + filename + "].", e);
  +        }
         }
       }
     }
  -  
   
     public void doConfigure(URL url, LoggerRepository repository) {
       try {
         doConfigure(url.openStream(), repository);
  -    } catch(IOException e) {
  -      LogLog.error("Could not open ["+url+"].", e);
  +    } catch (IOException e) {
  +      LogLog.error("Could not open [" + url + "].", e);
       }
     }
   
  @@ -641,8 +725,9 @@
        configuration file.
   
     */
  -  public void doConfigure(InputStream inputStream, LoggerRepository repository) 
  -                                          throws FactoryConfigurationError {
  +  public void doConfigure(
  +    InputStream inputStream, LoggerRepository repository)
  +    throws FactoryConfigurationError {
       doConfigure(new InputSource(inputStream), repository);
     }
   
  @@ -651,9 +736,8 @@
        configuration file.
   
     */
  -  public
  -  void doConfigure(Reader reader, LoggerRepository repository) 
  -                                          throws FactoryConfigurationError {
  +  public void doConfigure(Reader reader, LoggerRepository repository)
  +    throws FactoryConfigurationError {
       doConfigure(new InputSource(reader), repository);
     }
   
  @@ -662,65 +746,66 @@
        configuration file.
   
     */
  -  protected
  -  void doConfigure(InputSource inputSource, LoggerRepository repository) 
  -                                          throws FactoryConfigurationError {
  +  protected void doConfigure(
  +    InputSource inputSource, LoggerRepository repository)
  +    throws FactoryConfigurationError {
       DocumentBuilderFactory dbf = null;
       this.repository = repository;
  -    try { 
  -      LogLog.debug("System property ["+dbfKey+"] is: "+
  -                             OptionConverter.getSystemProperty(dbfKey, 
  -                                                               null)); 
  +
  +    try {
  +      LogLog.debug(
  +        "System property [" + dbfKey + "] is: "
  +        + OptionConverter.getSystemProperty(dbfKey, null));
         dbf = DocumentBuilderFactory.newInstance();
         LogLog.debug("Search for the standard DocumentBuilderFactory succeded.");
  -      LogLog.debug("DocumentBuilderFactory is: "+dbf.getClass().getName());
  -    } catch(FactoryConfigurationError fce) {
  +      LogLog.debug("DocumentBuilderFactory is: " + dbf.getClass().getName());
  +    } catch (FactoryConfigurationError fce) {
         Exception e = fce.getException();
         LogLog.debug("Could not instantiate a DocumentBuilderFactory.", e);
         throw fce;
       }
  -      
  +
       try {
         dbf.setValidating(true);
   
         DocumentBuilder docBuilder = dbf.newDocumentBuilder();
  -      docBuilder.setErrorHandler(new SAXErrorHandler());      
  -      docBuilder.setEntityResolver(new Log4jEntityResolver());        
  +      docBuilder.setErrorHandler(new SAXErrorHandler());
  +      docBuilder.setEntityResolver(new Log4jEntityResolver());
  +
         // we change the system ID to a valid URI so that Crimson won't
         // complain. Indeed, "log4j.dtd" alone is not a valid URI which
         // causes Crimson to barf. The Log4jEntityResolver only cares
         // about the "log4j.dtd" ending.
         inputSource.setSystemId("dummy://log4j.dtd");
  -      Document doc = docBuilder.parse(inputSource); 
  +
  +      Document doc = docBuilder.parse(inputSource);
         parse(doc.getDocumentElement());
       } catch (Exception e) {
         // I know this is miserable...
  -      LogLog.error("Could not parse input source ["+inputSource+"].", e);
  +      LogLog.error("Could not parse input source [" + inputSource + "].", e);
       }
     }
   
  -    /**
  -       Configure by taking in an DOM element. 
  -     */
  -    public void doConfigure(Element element, LoggerRepository repository) {
  -     this.repository = repository;
  -     parse(element);
  -    }
  +  /**
  +     Configure by taking in an DOM element.
  +   */
  +  public void doConfigure(Element element, LoggerRepository repository) {
  +    this.repository = repository;
  +    parse(element);
  +  }
   
  -  
     /**
        A static version of [EMAIL PROTECTED] #doConfigure(String, LoggerRepository)}. 
 */
  -  static public void configure(String filename) throws FactoryConfigurationError {
  -    new DOMConfigurator().doConfigure(filename, 
  -                                   LogManager.getLoggerRepository());
  +  public static void configure(String filename)
  +    throws FactoryConfigurationError {
  +    new DOMConfigurator().doConfigure(
  +      filename, LogManager.getLoggerRepository());
     }
   
     /**
        A static version of [EMAIL PROTECTED] #doConfigure(URL, LoggerRepository)}.
      */
  -  static
  -  public
  -  void configure(URL url) throws FactoryConfigurationError {
  +  public static void configure(URL url) throws FactoryConfigurationError {
       new DOMConfigurator().doConfigure(url, LogManager.getLoggerRepository());
     }
   
  @@ -728,44 +813,51 @@
        Used internally to configure the log4j framework by parsing a DOM
        tree of XML elements based on <a
        href="doc-files/log4j.dtd">log4j.dtd</a>.
  -     
  +
     */
     protected void parse(Element element) {
  -
       String rootElementName = element.getTagName();
   
       if (!rootElementName.equals(CONFIGURATION_TAG)) {
  -      if(rootElementName.equals(OLD_CONFIGURATION_TAG)) {
  -     LogLog.warn("The <"+OLD_CONFIGURATION_TAG+
  -                  "> element has been deprecated.");
  -     LogLog.warn("Use the <"+CONFIGURATION_TAG+"> element instead.");
  +      if (rootElementName.equals(OLD_CONFIGURATION_TAG)) {
  +        LogLog.warn(
  +          "The <" + OLD_CONFIGURATION_TAG + "> element has been deprecated.");
  +        LogLog.warn("Use the <" + CONFIGURATION_TAG + "> element instead.");
         } else {
  -     LogLog.error("DOM element is - not a <"+CONFIGURATION_TAG+"> element.");
  -     return;
  +        LogLog.error(
  +          "DOM element is - not a <" + CONFIGURATION_TAG + "> element.");
  +
  +        return;
         }
       }
   
       String debugAttrib = subst(element.getAttribute(INTERNAL_DEBUG_ATTR));
  -      
  -    LogLog.debug("debug attribute= \"" + debugAttrib +"\".");
  +
  +    LogLog.debug("debug attribute= \"" + debugAttrib + "\".");
  +
       // if the log4j.dtd is not specified in the XML file, then the
       // "debug" attribute is returned as the empty string.
  -    if(!debugAttrib.equals("") && !debugAttrib.equals("null")) {      
  -      LogLog.setInternalDebugging(OptionConverter.toBoolean(debugAttrib, true));
  +    if (!debugAttrib.equals("") && !debugAttrib.equals("null")) {
  +      LogLog.setInternalDebugging(
  +        OptionConverter.toBoolean(debugAttrib, true));
       } else {
         LogLog.debug("Ignoring " + INTERNAL_DEBUG_ATTR + " attribute.");
       }
   
       String confDebug = subst(element.getAttribute(CONFIG_DEBUG_ATTR));
  -    if(!confDebug.equals("") && !confDebug.equals("null")) {      
  -      LogLog.warn("The \""+CONFIG_DEBUG_ATTR+"\" attribute is deprecated.");
  -      LogLog.warn("Use the \""+INTERNAL_DEBUG_ATTR+"\" attribute instead.");
  +
  +    if (!confDebug.equals("") && !confDebug.equals("null")) {
  +      LogLog.warn(
  +        "The \"" + CONFIG_DEBUG_ATTR + "\" attribute is deprecated.");
  +      LogLog.warn(
  +        "Use the \"" + INTERNAL_DEBUG_ATTR + "\" attribute instead.");
         LogLog.setInternalDebugging(OptionConverter.toBoolean(confDebug, true));
       }
   
       String thresholdStr = subst(element.getAttribute(THRESHOLD_ATTR));
  -    LogLog.debug("Threshold =\"" + thresholdStr +"\".");
  -    if(!"".equals(thresholdStr) && !"null".equals(thresholdStr)) {
  +    LogLog.debug("Threshold =\"" + thresholdStr + "\".");
  +
  +    if (!"".equals(thresholdStr) && !"null".equals(thresholdStr)) {
         repository.setThreshold(thresholdStr);
       }
   
  @@ -778,44 +870,47 @@
       // Category factories need to be configured before any of
       // categories they support.
       //
  -    String   tagName = null;
  -    Element  currentElement = null;
  -    Node     currentNode = null;
  +    String tagName = null;
  +    Element currentElement = null;
  +    Node currentNode = null;
       NodeList children = element.getChildNodes();
       final int length = children.getLength();
   
       for (int loop = 0; loop < length; loop++) {
         currentNode = children.item(loop);
  +
         if (!isElement(currentNode)) {
           continue;
         }
  +
         currentElement = (Element) currentNode;
         tagName = currentElement.getTagName();
  -      
  +
         if (tagName.equals(CATEGORY) || tagName.equals(LOGGER)) {
           parseCategory(currentElement);
         } else if (tagName.equals(ROOT_TAG)) {
           parseRoot(currentElement);
  -      } else if(tagName.equals(RENDERER_TAG)) {
  +      } else if (tagName.equals(RENDERER_TAG)) {
           parseRenderer(currentElement);
         } else if (tagName.equals(PLUGIN_TAG)) {
           Plugin plugin = parsePlugin(currentElement);
  +
           if (plugin != null) {
             PluginRegistry.startPlugin(plugin, repository);
           }
         }
       }
  -        
  +
       // let listeners know the configuration just changed
       repository.fireConfigurationChangedEvent();
     }
   
  -  
     protected String subst(String value) {
       try {
         return OptionConverter.substVars(value, props);
  -    } catch(IllegalArgumentException e) {
  +    } catch (IllegalArgumentException e) {
         LogLog.warn("Could not perform variable substitution.", e);
  +
         return value;
       }
     }
  @@ -823,7 +918,6 @@
   
   
   class XMLWatchdog extends FileWatchdog {
  -
     XMLWatchdog(String filename) {
       super(filename);
     }
  @@ -831,9 +925,8 @@
     /**
        Call [EMAIL PROTECTED] PropertyConfigurator#configure(String)} with the
        <code>filename</code> to reconfigure log4j. */
  -  public
  -  void doOnChange() {
  -    new DOMConfigurator().doConfigure(filename, 
  -                                   LogManager.getLoggerRepository());
  +  public void doOnChange() {
  +    new DOMConfigurator().doConfigure(
  +      filename, LogManager.getLoggerRepository());
     }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to