You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rs...@apache.org on 2002/08/26 15:08:46 UTC

cvs commit: jakarta-commons/discovery/src/java/org/apache/commons/discovery ResourceDiscovery.java ServiceDiscovery.java ClassInfo.java ClassDiscovery.java

rsitze      2002/08/26 06:08:46

  Modified:    discovery project.xml build.xml
               discovery/src/java/org/apache/commons/discovery
                        ResourceDiscovery.java ServiceDiscovery.java
                        ClassInfo.java ClassDiscovery.java
  Added:       discovery/src/test/org/apache/commons/discovery/test
                        TestAll.java TestInterface.java
                        TestInterface.properties TestImpl_1.java
                        TestImpl_2.java
               discovery/src/java/org/apache/commons/discovery/log
                        SimpleLog.java DiscoveryLogFactory.java
               discovery/src/java/org/apache/commons/logging
                        LogFactory.java Log.java
                        LogConfigurationException.java
  Removed:     discovery/src/test/org/apache/commons/discovery TestAll.java
  Log:
  Added logging support.  Copied 2 files from commons-logging (Log & LogFactory)
  to prevent circular dependencies during build.  Support for a bootstrap mechanism
  to allow the default (VERY simple logging) to be replaced with app/system loggers.
  
  Revision  Changes    Path
  1.1                  jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestAll.java
  
  Index: TestAll.java
  ===================================================================
  /*
   * $Header$
   * $Revision: 1.2 $
   * $Date: 2002/01/17 22:55:43 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.discovery.test;
  
  
  import java.util.Properties;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import org.apache.commons.discovery.tools.DefaultClassHolder;
  import org.apache.commons.discovery.tools.DiscoverSingleton;
  import org.apache.commons.discovery.tools.ManagedProperties;
  import org.apache.commons.discovery.tools.PropertiesHolder;
  import org.apache.commons.discovery.tools.SPInterface;
  
  
  /**
    * @author Richard A. Sitze
    * @version $Revision: 1.2 $
   */
  public class TestAll extends TestCase {
      private static final int logLevel =
          org.apache.commons.discovery.log.SimpleLog.LOG_LEVEL_INFO;
  
      
      public TestAll(String testName) {
          super(testName);
      }
      
      public static Test suite() {
          return new TestSuite(TestAll.class);
      }
  
      public void testFindDefaultImpl_1() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
          
          try {
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class,
                                                         TestImpl_1.class.getName());
  
              assertTrue(ti.getClass().getName() + "!=" + TestImpl_1.class.getName(),
                         ti.getClass().getName().equals(TestImpl_1.class.getName()));
          } finally {
              DiscoverSingleton.release();
          }
      }
      
      public void testFindDefaultImpl_2() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
  
          try {
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class,
                                                         TestImpl_2.class.getName());
  
              assertTrue(ti.getClass().getName() + "!=" + TestImpl_2.class.getName(),
                         ti.getClass().getName().equals(TestImpl_2.class.getName()));
          } finally {
              DiscoverSingleton.release();
          }
      }
      
      public void testCache() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
          
          try {
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class,
                                                         TestImpl_1.class.getName());
  
              assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl_1.class.getName(),
                         ti.getClass().getName().equals(TestImpl_1.class.getName()));
              
              // no release, should get cached value..
              
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class,
                                                         TestImpl_2.class.getName());
  
              // factory should be cached LogFactoryImpl
              assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl_1.class.getName(),
                         ti.getClass().getName().equals(TestImpl_1.class.getName()));
          } finally {
              DiscoverSingleton.release();
          }
      }
      
      public void testRelease() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
          
          try {
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class,
                                                         TestImpl_1.class.getName());
  
              assertTrue("1. " + ti.getClass().getName() + "!=" + TestImpl_1.class.getName(),
                         ti.getClass().getName().equals(TestImpl_1.class.getName()));
              
              DiscoverSingleton.release();
              
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class,
                                                         TestImpl_2.class.getName());
  
              // factory should be cached LogFactoryImpl
              assertTrue("2. " + ti.getClass().getName() + "!=" + TestImpl_2.class.getName(),
                         ti.getClass().getName().equals(TestImpl_2.class.getName()));
          } finally {
              DiscoverSingleton.release();
          }
      }
      
      public void testFindPropertyImpl_1() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
  
          try {
              Properties props = new Properties();
              
              props.setProperty(TestInterface.class.getName(),
                                TestImpl_2.class.getName());
              
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class, props);
  
              assertTrue(ti.getClass().getName() + "!=" + TestImpl_2.class.getName(),
                         ti.getClass().getName().equals(TestImpl_2.class.getName()));
          } finally {
              DiscoverSingleton.release();
          }
      }
      
      public void testMyFactoryManagedProperty() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
  
          try {
              ManagedProperties.setProperty(TestInterface.class.getName(),
                                            TestImpl_2.class.getName());
                                
              ti = (TestInterface)DiscoverSingleton.find(TestInterface.class);
  
              assertTrue(ti.getClass().getName() + "!=" + TestImpl_2.class.getName(),
                         ti.getClass().getName().equals(TestImpl_2.class.getName()));
          } finally {
              DiscoverSingleton.release();
              
              /**
               * Cleanup, don't want to affect next test..
               */
              ManagedProperties.setProperty(TestInterface.class.getName(), null);
          }
      }
      
  
      public void testFindGroupLogFactoryImplPropFileDefault() {
          org.apache.commons.discovery.log.SimpleLog.setLevel(logLevel);
  
          TestInterface ti = null;
          
          try {
              ti = (TestInterface)DiscoverSingleton.find(null,
                                     new SPInterface(TestInterface.class),
                                     new PropertiesHolder("TestInterface.properties"),
                                     new DefaultClassHolder(TestImpl_2.class.getName()));
  
              assertTrue(ti.getClass().getName() + "!=" + TestImpl_1.class.getName(),
                         ti.getClass().getName().equals(TestImpl_1.class.getName()));
          } finally {
              DiscoverSingleton.release();
          }
      }
  
      /**
       * This allows the tests to run as a standalone application.
       */
      public static void main(String args[]) {
          String[] testCaseName = { TestAll.class.getName() };
          junit.textui.TestRunner.main(testCaseName);
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestInterface.java
  
  Index: TestInterface.java
  ===================================================================
  /*
   * $Header$
   * $Revision$
   * $Date$
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.discovery.test;
  
  
  /**
    * @author Richard A. Sitze
    * @version $Revision$
   */
  public interface TestInterface {
      public void method();
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestInterface.properties
  
  Index: TestInterface.properties
  ===================================================================
  org.apache.commons.discovery.test.TestInterface=org.apache.commons.discovery.test.TestImpl_1
  
  
  1.1                  jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestImpl_1.java
  
  Index: TestImpl_1.java
  ===================================================================
  /*
   * $Header$
   * $Revision$
   * $Date$
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.discovery.test;
  
  
  /**
    * @author Richard A. Sitze
    * @version $Revision$
   */
  public class TestImpl_1 implements TestInterface {
      public TestImpl_1() {
      }
  
      public void method() {
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/test/org/apache/commons/discovery/test/TestImpl_2.java
  
  Index: TestImpl_2.java
  ===================================================================
  /*
   * $Header$
   * $Revision$
   * $Date$
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.discovery.test;
  
  
  /**
    * @author Richard A. Sitze
    * @version $Revision$
   */
  public class TestImpl_2 implements TestInterface {
      public TestImpl_2() {
      }
  
      public void method() {
      }
  }
  
  
  
  1.7       +3 -1      jakarta-commons/discovery/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/project.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- project.xml	21 Aug 2002 11:49:36 -0000	1.6
  +++ project.xml	26 Aug 2002 13:08:45 -0000	1.7
  @@ -41,11 +41,13 @@
     </developers>
     
     <dependencies>
  -    
  +
  +<!--    
       <dependency>
         <id>commons-logging</id>
         <version>1.0.1</version>
       </dependency>
  +-->
   
       <dependency>
         <id>junit</id>
  
  
  
  1.6       +3 -2      jakarta-commons/discovery/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/build.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- build.xml	9 Aug 2002 15:20:52 -0000	1.5
  +++ build.xml	26 Aug 2002 13:08:45 -0000	1.6
  @@ -164,7 +164,8 @@
                tofile="${build.home}/classes/META-INF/LICENSE.txt"/>
       <jar    jarfile="${dist.home}/commons-${component.name}.jar"
               basedir="${build.home}/classes"
  -           manifest="${build.home}/conf/MANIFEST.MF"/>
  +           manifest="${build.home}/conf/MANIFEST.MF"
  +           excludes="org/apache/commons/logging/**"/>
     </target>
   
   <!-- ========== Testing section ======================================== -->
  @@ -187,7 +188,7 @@
       <echo message="Running basic Service tests ..."/>
       <java classname="${test.runner}" fork="yes"
           failonerror="${test.failonerror}">
  -      <arg value="org.apache.commons.discovery.TestAll"/>
  +      <arg value="org.apache.commons.discovery.test.TestAll"/>
         <classpath refid="test.classpath"/>
       </java>
     </target>
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/log/SimpleLog.java
  
  Index: SimpleLog.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/impl/SimpleLog.java,v 1.4 2002/06/15 20:54:48 craigmcc Exp $
   * $Revision: 1.4 $
   * $Date: 2002/06/15 20:54:48 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.discovery.log;
  
  import java.io.PrintStream;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  
  import org.apache.commons.logging.Log;
  
  
  /**
   * <p>Simple implementation of Log that sends all enabled log messages,
   * for all defined loggers, to System.err.
   * </p>
   * 
   * <p>Hacked from commons-logging SimpleLog for use in discovery.
   * This is intended to be enough of a Log implementation to bootstrap
   * Discovery.
   * </p>
   * 
   * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
   * valid values: all, trace, debug, info, warn, error, fatal, off.
   * </p>
   * 
   * @author Richard A. Sitze
   * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
   * @author Rod Waldhoff
   * @author Robert Burrell Donkin
   *
   * @version $Id: SimpleLog.java,v 1.4 2002/06/15 20:54:48 craigmcc Exp $
   */
  public class SimpleLog implements Log {
        // ---------------------------------------------------- Log Level Constants
  
      /** "Trace" level logging. */
      public static final int LOG_LEVEL_TRACE  = 1;
      /** "Debug" level logging. */
      public static final int LOG_LEVEL_DEBUG  = 2;
      /** "Info" level logging. */
      public static final int LOG_LEVEL_INFO   = 3;
      /** "Warn" level logging. */
      public static final int LOG_LEVEL_WARN   = 4;
      /** "Error" level logging. */
      public static final int LOG_LEVEL_ERROR  = 5;
      /** "Fatal" level logging. */
      public static final int LOG_LEVEL_FATAL  = 6;
  
      /** Enable all logging levels */
      public static final int LOG_LEVEL_ALL    = (LOG_LEVEL_TRACE - 1);
  
      /** Enable no logging levels */
      public static final int LOG_LEVEL_OFF    = (LOG_LEVEL_FATAL + 1);
  
      // ------------------------------------------------------- Class Attributes
  
      static protected final String PROP_LEVEL =
          "org.apache.commons.discovery.log.level";
  
      /** Include the instance name in the log message? */
      static protected boolean showLogName = false;
  
      /** Include the short name ( last component ) of the logger in the log
          message. Default to true - otherwise we'll be lost in a flood of
          messages without knowing who sends them.
      */
      static protected boolean showShortName = true;
  
      /** Include the current time in the log message */
      static protected boolean showDateTime = false;
  
      /** Used to format times */
      static protected DateFormat dateFormatter = null;
  
      /** The current log level */
      static protected int logLevel = LOG_LEVEL_INFO;
      
      
      /**
       * Use 'out' instead of 'err' for logging
       * to keep in-sync with test messages.
       */
      static private PrintStream out = System.out;
  
      // ------------------------------------------------------------ Initializer
  
      // initialize class attributes
      static {
          if(showDateTime) {
              dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS zzz");
          }
  
          // set log level from properties
          String lvl = System.getProperty(PROP_LEVEL);
  
          if("all".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_ALL);
          } else if("trace".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_TRACE);
          } else if("debug".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_DEBUG);
          } else if("info".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_INFO);
          } else if("warn".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_WARN);
          } else if("error".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_ERROR);
          } else if("fatal".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_FATAL);
          } else if("off".equalsIgnoreCase(lvl)) {
              setLevel(SimpleLog.LOG_LEVEL_OFF);
          }
      }
  
      // -------------------------------------------------------- Properties
  
      /**
       * <p> Set logging level. </p>
       *
       * @param level new logging level
       */
      public static void setLevel(int currentLogLevel) {
          logLevel = currentLogLevel;
      }
  
      /**
       * <p> Get logging level. </p>
       */
      public static int getLevel() {
          return logLevel;
      }
  
      /**
       * Is the given log level currently enabled?
       *
       * @param logLevel is this level enabled?
       */
      protected static boolean isLevelEnabled(int level) {
          // log level are numerically ordered so can use simple numeric
          // comparison
          return (level >= getLevel());
      }
  
  
  
      // ------------------------------------------------------------- Attributes
  
      /** The name of this simple log instance */
      protected String logName = null;
  
      private String prefix=null;
  
      
      // ------------------------------------------------------------ Constructor
      
      /**
       * Construct a simple log with given name.
       *
       * @param name log name
       */
      public SimpleLog(String name) {
          logName = name;
      }
  
  
      // -------------------------------------------------------- Logging Methods
  
  
      /**
       * <p> Do the actual logging.
       * This method assembles the message
       * and then prints to <code>System.err</code>.</p>
       */
      protected void log(int type, Object message, Throwable t) {
          // use a string buffer for better performance
          StringBuffer buf = new StringBuffer();
  
          // append date-time if so configured
          if(showDateTime) {
              buf.append(dateFormatter.format(new Date()));
              buf.append(" ");
          }
  
          // append a readable representation of the log leve
          switch(type) {
              case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;
              case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;
              case SimpleLog.LOG_LEVEL_INFO:  buf.append("[INFO ] "); break;
              case SimpleLog.LOG_LEVEL_WARN:  buf.append("[WARN ] "); break;
              case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;
              case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;
          }
  
          // append the name of the log instance if so configured
       	if( showShortName) {
              if( prefix==null ) {
                  // cut all but the last component of the name for both styles
                  prefix = logName.substring( logName.lastIndexOf(".") +1) + " - ";
                  prefix = prefix.substring( prefix.lastIndexOf("/") +1) + "-";
              }
              buf.append( prefix );
          } else if(showLogName) {
              buf.append(String.valueOf(logName)).append(" - ");
          }
  
          // append the message
          buf.append(String.valueOf(message));
  
          // append stack trace if not null
          if(t != null) {
              buf.append(" <");
              buf.append(t.toString());
              buf.append(">");
          }
  
          // print to System.err
          out.println(buf.toString());
          
          if (t != null)
              t.printStackTrace(System.err);
      }
  
  
      // -------------------------------------------------------- Log Implementation
  
  
      /**
       * <p> Log a message with debug log level.</p>
       */
      public final void debug(Object message) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
              log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
          }
      }
  
  
      /**
       * <p> Log an error with debug log level.</p>
       */
      public final void debug(Object message, Throwable t) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
              log(SimpleLog.LOG_LEVEL_DEBUG, message, t);
          }
      }
  
  
      /**
       * <p> Log a message with debug log level.</p>
       */
      public final void trace(Object message) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
              log(SimpleLog.LOG_LEVEL_TRACE, message, null);
          }
      }
  
  
      /**
       * <p> Log an error with debug log level.</p>
       */
      public final void trace(Object message, Throwable t) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
              log(SimpleLog.LOG_LEVEL_TRACE, message, t);
          }
      }
  
  
      /**
       * <p> Log a message with info log level.</p>
       */
      public final void info(Object message) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
              log(SimpleLog.LOG_LEVEL_INFO,message,null);
          }
      }
  
  
      /**
       * <p> Log an error with info log level.</p>
       */
      public final void info(Object message, Throwable t) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
              log(SimpleLog.LOG_LEVEL_INFO, message, t);
          }
      }
  
  
      /**
       * <p> Log a message with warn log level.</p>
       */
      public final void warn(Object message) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
              log(SimpleLog.LOG_LEVEL_WARN, message, null);
          }
      }
  
  
      /**
       * <p> Log an error with warn log level.</p>
       */
      public final void warn(Object message, Throwable t) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
              log(SimpleLog.LOG_LEVEL_WARN, message, t);
          }
      }
  
  
      /**
       * <p> Log a message with error log level.</p>
       */
      public final void error(Object message) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
              log(SimpleLog.LOG_LEVEL_ERROR, message, null);
          }
      }
  
  
      /**
       * <p> Log an error with error log level.</p>
       */
      public final void error(Object message, Throwable t) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
              log(SimpleLog.LOG_LEVEL_ERROR, message, t);
          }
      }
  
  
      /**
       * <p> Log a message with fatal log level.</p>
       */
      public final void fatal(Object message) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
              log(SimpleLog.LOG_LEVEL_FATAL, message, null);
          }
      }
  
  
      /**
       * <p> Log an error with fatal log level.</p>
       */
      public final void fatal(Object message, Throwable t) {
          if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
              log(SimpleLog.LOG_LEVEL_FATAL, message, t);
          }
      }
  
  
      /**
       * <p> Are debug messages currently enabled? </p>
       *
       * <p> This allows expensive operations such as <code>String</code>
       * concatenation to be avoided when the message will be ignored by the
       * logger. </p>
       */
      public final boolean isDebugEnabled() {
          return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
      }
  
  
      /**
       * <p> Are error messages currently enabled? </p>
       *
       * <p> This allows expensive operations such as <code>String</code>
       * concatenation to be avoided when the message will be ignored by the
       * logger. </p>
       */
      public final boolean isErrorEnabled() {
          return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
      }
  
  
      /**
       * <p> Are fatal messages currently enabled? </p>
       *
       * <p> This allows expensive operations such as <code>String</code>
       * concatenation to be avoided when the message will be ignored by the
       * logger. </p>
       */
      public final boolean isFatalEnabled() {
          return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
      }
  
  
      /**
       * <p> Are info messages currently enabled? </p>
       *
       * <p> This allows expensive operations such as <code>String</code>
       * concatenation to be avoided when the message will be ignored by the
       * logger. </p>
       */
      public final boolean isInfoEnabled() {
          return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
      }
  
  
      /**
       * <p> Are trace messages currently enabled? </p>
       *
       * <p> This allows expensive operations such as <code>String</code>
       * concatenation to be avoided when the message will be ignored by the
       * logger. </p>
       */
      public final boolean isTraceEnabled() {
          return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
      }
  
  
      /**
       * <p> Are warn messages currently enabled? </p>
       *
       * <p> This allows expensive operations such as <code>String</code>
       * concatenation to be avoided when the message will be ignored by the
       * logger. </p>
       */
      public final boolean isWarnEnabled() {
          return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/discovery/log/DiscoveryLogFactory.java
  
  Index: DiscoveryLogFactory.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/impl/SimpleLog.java,v 1.4 2002/06/15 20:54:48 craigmcc Exp $
   * $Revision: 1.4 $
   * $Date: 2002/06/15 20:54:48 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.discovery.log;
  
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.Enumeration;
  import java.util.Hashtable;
  
  import org.apache.commons.discovery.DiscoveryException;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  
  /**
   * <p>Simple implementation of Log that sends all enabled log messages,
   * for all defined loggers, to System.err.
   * </p>
   * 
   * <p>Hacked from commons-logging SimpleLog for use in discovery.
   * This is intended to be enough of a Log implementation to bootstrap
   * Discovery.
   * </p>
   * 
   * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
   * valid values: all, trace, debug, info, warn, error, fatal, off.
   * </p>
   * 
   * @author Richard A. Sitze
   * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
   * @author Rod Waldhoff
   * @author Robert Burrell Donkin
   *
   * @version $Id: SimpleLog.java,v 1.4 2002/06/15 20:54:48 craigmcc Exp $
   */
  public class DiscoveryLogFactory {
      private static LogFactory logFactory = null;
      private static final Hashtable  classRegistry = new Hashtable();
      private static final Class[] setLogParamClasses = new Class[] { Log.class };
  
      /**
       * Above fields must be initialied before this one..
       */
      private static Log log = DiscoveryLogFactory._newLog(DiscoveryLogFactory.class);
  
      /**
       */    
      public static Log newLog(Class clazz) {
          /**
           * Required to implement 'public static void setLog(Log)'
           */
          try {
              boolean problem = false;
              Method setLog = null;
              
              // verify 'setLog(Log)' is in class
              try {
                  setLog = clazz.getDeclaredMethod("setLog", setLogParamClasses);
              } catch(NoSuchMethodException e) {
                  problem = true;
              }
              
              // verify 'public static void'
              if (!problem  &&
                  !(Modifier.isPublic(setLog.getModifiers())  &&
                    Modifier.isStatic(setLog.getModifiers())  &&
                    setLog.getReturnType() == void.class)) {
                  problem = true;
              }
              
              if (problem) {
                  String msg = "Internal Error: " + clazz.getName() + " required to implement 'public static void setLog(Log)'";
                  log.fatal(msg);
                  throw new DiscoveryException(msg);
              }
          } catch (SecurityException se) {
              String msg = "Required Security Permissions not present";
              log.fatal(msg, se);
              throw new DiscoveryException(msg, se);
          }
  
          if (log.isDebugEnabled())
              log.debug("Class meets requirements: " + clazz.getName());
  
          return _newLog(clazz);
      }
  
      /**
       * This method MUST not invoke any logging..
       */
      public static Log _newLog(Class clazz) {
          classRegistry.put(clazz, clazz);
  
          return (logFactory == null)
                 ? new SimpleLog(clazz.getName())
                 : logFactory.getInstance(clazz.getName());
      }
      
      public static void setLog(Log _log) {
          log = _log;
      }
  
      /**
       * Set logFactory, works ONLY on first call.
       */
      public static void setFactory(LogFactory factory) {
          if (logFactory == null) {
              // for future generations.. if any
              logFactory = factory;
              
              // now, go back and reset loggers for all current classes..
              Enumeration elements = classRegistry.elements();
              while (elements.hasMoreElements()) {
                  Class clazz = (Class)elements.nextElement();
  
                  if (log.isDebugEnabled())
                      log.debug("Reset Log for: " + clazz.getName());
                  
                  Method setLog = null;
                  
                  // verify 'setLog(Log)'
                  try {
                      setLog = clazz.getMethod("setLog", setLogParamClasses);
                  } catch(Exception e) {
                      String msg = "Internal Error: pre-check for " + clazz.getName() + " failed?!";
                      log.fatal(msg, e);
                      throw new DiscoveryException(msg, e);
                  }
      
                  Object[] setLogParam = new Object[] { factory.getInstance(clazz.getName()) };
                  
                  try {
                      setLog.invoke(null, setLogParam);
                  } catch(Exception e) {
                      String msg = "Internal Error: setLog failed for " + clazz.getName();
                      log.fatal(msg, e);
                      throw new DiscoveryException(msg, e);
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/logging/LogFactory.java
  
  Index: LogFactory.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/LogFactory.java,v 1.11 2002/08/12 21:01:07 rsitze Exp $
   * $Revision: 1.11 $
   * $Date: 2002/08/12 21:01:07 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.logging;
  
  
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.lang.SecurityException;
  
  
  /**
   * <p>Factory for creating {@link Log} instances, with discovery and
   * configuration features similar to that employed by standard Java APIs
   * such as JAXP.</p>
   *
   * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily
   * based on the SAXParserFactory and DocumentBuilderFactory implementations
   * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p>
   *
   * @author Craig R. McClanahan
   * @author Costin Manolache
   * @version $Revision: 1.11 $ $Date: 2002/08/12 21:01:07 $
   */
  
  public abstract class LogFactory {
  
  
      // ----------------------------------------------------- Manifest Constants
  
  
      /**
       * The name of the property used to identify the LogFactory implementation
       * class name.
       */
      public static final String FACTORY_PROPERTY =
          "org.apache.commons.logging.LogFactory";
  
  
      /**
       * The fully qualified class name of the fallback <code>LogFactory</code>
       * implementation class to use, if no other can be found.
       */
      public static final String FACTORY_DEFAULT =
          "org.apache.commons.logging.impl.LogFactoryImpl";
  
  
      /**
       * The name of the properties file to search for.
       */
      public static final String FACTORY_PROPERTIES =
          "commons-logging.properties";
  
      /**
       * JDK1.3+ 'Service Provider' specification 
       * ( http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html )
       */
      protected static final String SERVICE_ID =
          "META-INF/services/org.apache.commons.logging.LogFactory";
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Protected constructor that is not available for public use.
       */
      protected LogFactory() { }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return the configuration attribute with the specified name (if any),
       * or <code>null</code> if there is no such attribute.
       *
       * @param name Name of the attribute to return
       */
      public abstract Object getAttribute(String name);
  
  
      /**
       * Return an array containing the names of all currently defined
       * configuration attributes.  If there are no such attributes, a zero
       * length array is returned.
       */
      public abstract String[] getAttributeNames();
  
  
      /**
       * Convenience method to derive a name from the specified class and
       * call <code>getInstance(String)</code> with it.
       *
       * @param clazz Class for which a suitable Log name will be derived
       *
       * @exception LogConfigurationException if a suitable <code>Log</code>
       *  instance cannot be returned
       */
      public abstract Log getInstance(Class clazz)
          throws LogConfigurationException;
  
  
      /**
       * <p>Construct (if necessary) and return a <code>Log</code> instance,
       * using the factory's current set of configuration attributes.</p>
       *
       * <p><strong>NOTE</strong> - Depending upon the implementation of
       * the <code>LogFactory</code> you are using, the <code>Log</code>
       * instance you are returned may or may not be local to the current
       * application, and may or may not be returned again on a subsequent
       * call with the same name argument.</p>
       *
       * @param name Logical name of the <code>Log</code> instance to be
       *  returned (the meaning of this name is only known to the underlying
       *  logging implementation that is being wrapped)
       *
       * @exception LogConfigurationException if a suitable <code>Log</code>
       *  instance cannot be returned
       */
      public abstract Log getInstance(String name)
          throws LogConfigurationException;
  
  
      /**
       * Release any internal references to previously created {@link Log}
       * instances returned by this factory.  This is useful environments
       * like servlet containers, which implement application reloading by
       * throwing away a ClassLoader.  Dangling references to objects in that
       * class loader would prevent garbage collection.
       */
      public abstract void release();
  
  
      /**
       * Remove any configuration attribute associated with the specified name.
       * If there is no such attribute, no action is taken.
       *
       * @param name Name of the attribute to remove
       */
      public abstract void removeAttribute(String name);
  
  
      /**
       * Set the configuration attribute with the specified name.  Calling
       * this with a <code>null</code> value is equivalent to calling
       * <code>removeAttribute(name)</code>.
       *
       * @param name Name of the attribute to set
       * @param value Value of the attribute to set, or <code>null</code>
       *  to remove any setting for this attribute
       */
      public abstract void setAttribute(String name, Object value);
  
  
      // ------------------------------------------------------- Static Variables
  
  
      /**
       * The previously constructed <code>LogFactory</code> instances, keyed by
       * the <code>ClassLoader</code> with which it was created.
       */
      protected static Hashtable factories = new Hashtable();
  
  
      // --------------------------------------------------------- Static Methods
  
  
      /**
       * <p>Construct (if necessary) and return a <code>LogFactory</code>
       * instance, using the following ordered lookup procedure to determine
       * the name of the implementation class to be loaded.</p>
       * <ul>
       * <li>The <code>org.apache.commons.logging.LogFactory</code> system
       *     property.</li>
       * <li>Use the properties file <code>commons-logging.properties</code>
       *     file, if found in the class path of this class.  The configuration
       *     file is in standard <code>java.util.Propertis</code> format and
       *     contains the fully qualified name of the implementation class
       *     with the key being the system property defined above.</li>
       * <li>Fall back to a default implementation class
       *     (<code>org.apache.commons.logging.impl.LogFactoryImpl</code>).</li>
       * </ul>
       *
       * <p><em>NOTE</em> - If the properties file method of identifying the
       * <code>LogFactory</code> implementation class is utilized, all of the
       * properties defined in this file will be set as configuration attributes
       * on the corresponding <code>LogFactory</code> instance.</p>
       *
       * @exception LogConfigurationException if the implementation class is not
       *  available or cannot be instantiated.
       */
      public static LogFactory getFactory() throws LogConfigurationException {
  
          // Identify the class loader we will be using
          ClassLoader contextClassLoader = getContextClassLoader();
  
          // Return any previously registered factory for this class loader
          LogFactory factory = getCachedFactory(contextClassLoader);
          if (factory != null)
              return factory;
  
          // First, try the system property
          try {
              String factoryClass = System.getProperty(FACTORY_PROPERTY);
              if (factoryClass != null) {
                  factory = newFactory(factoryClass, contextClassLoader);
              }
          } catch (SecurityException e) {
              ;  // ignore
          }
  
          // Second, try to find a service by using the JDK1.3 jar
          // discovery mechanism. This will allow users to plug a logger
          // by just placing it in the lib/ directory of the webapp ( or in
          // CLASSPATH or equivalent ). This is similar with the second
          // step, except that it uses the (standard?) jdk1.3 location in the jar.
  
          if (factory == null) {
              try {
                  InputStream is = (contextClassLoader == null
                                    ? ClassLoader.getSystemResourceAsStream( SERVICE_ID )
                                    : contextClassLoader.getResourceAsStream( SERVICE_ID ));
  
                  if( is != null ) {
                      // This code is needed by EBCDIC and other strange systems.
                      // It's a fix for bugs reported in xerces
                      BufferedReader rd;
                      try {
                          rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                      } catch (java.io.UnsupportedEncodingException e) {
                          rd = new BufferedReader(new InputStreamReader(is));
                      }
                      
                      String factoryClassName = rd.readLine();
                      rd.close();
                      
                      if (factoryClassName != null &&
                          ! "".equals(factoryClassName)) {
                          
                          factory= newFactory( factoryClassName, contextClassLoader );
                      }
                  }
              } catch( Exception ex ) {
                  ;
              }
          }
  
  
          Properties props=null;
          
          // Third try a properties file. 
          // If the properties file exists, it'll be read and the properties
          // used. IMHO ( costin ) System property and JDK1.3 jar service
          // should be enough for detecting the class name. The properties
          // should be used to set the attributes ( which may be specific to
          // the webapp, even if a default logger is set at JVM level by a
          // system property )
  
          try {
              InputStream stream =
                  contextClassLoader.getResourceAsStream(FACTORY_PROPERTIES);
              if (stream != null) {
                  props = new Properties();
                  props.load(stream);
                  stream.close();
                  String factoryClass = props.getProperty(FACTORY_PROPERTY);
                  if( factory==null ) {
                      if (factoryClass == null) {
                          factoryClass = FACTORY_DEFAULT;
                      }
                      factory = newFactory(factoryClass, contextClassLoader);
                  }
              }
              // the properties will be set at the end.
          } catch (IOException e) {
          } catch (SecurityException e) {
          }
  
          // Fourth, try the fallback implementation class
          if (factory == null) {
              factory = newFactory(FACTORY_DEFAULT, LogFactory.class.getClassLoader());
          }
          
          if (factory != null) {
              /**
               * Always cache using context class loader..
               */
              cacheFactory(contextClassLoader, factory);
          }
  
          if( props!=null ) {
              Enumeration names = props.propertyNames();
              while (names.hasMoreElements()) {
                  String name = (String) names.nextElement();
                  String value = props.getProperty(name);
                  factory.setAttribute(name, value);
              }
          }
          
          return factory;
      }
  
  
      /**
       * Convenience method to return a named logger, without the application
       * having to care about factories.
       *
       * @param clazz Class for which a log name will be derived
       *
       * @exception LogConfigurationException if a suitable <code>Log</code>
       *  instance cannot be returned
       */
      public static Log getLog(Class clazz)
          throws LogConfigurationException {
  
          return (getFactory().getInstance(clazz));
  
      }
  
  
      /**
       * Convenience method to return a named logger, without the application
       * having to care about factories.
       *
       * @param name Logical name of the <code>Log</code> instance to be
       *  returned (the meaning of this name is only known to the underlying
       *  logging implementation that is being wrapped)
       *
       * @exception LogConfigurationException if a suitable <code>Log</code>
       *  instance cannot be returned
       */
      public static Log getLog(String name)
          throws LogConfigurationException {
  
          return (getFactory().getInstance(name));
  
      }
  
  
      /**
       * Release any internal references to previously created {@link LogFactory}
       * instances, after calling the instance method <code>release()</code> on
       * each of them.  This is useful environments like servlet containers,
       * which implement application reloading by throwing away a ClassLoader.
       * Dangling references to objects in that class loader would prevent
       * garbage collection.
       */
      public static void releaseAll() {
  
          synchronized (factories) {
              Enumeration elements = factories.elements();
              while (elements.hasMoreElements()) {
                  LogFactory element = (LogFactory) elements.nextElement();
                  element.release();
              }
              factories.clear();
          }
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Return the thread context class loader if available.
       * Otherwise return null.
       * 
       * The thread context class loader is available for JDK 1.2
       * or later, if certain security conditions are met.
       *
       * @exception LogConfigurationException if a suitable class loader
       * cannot be identified.
       */
      protected static ClassLoader getContextClassLoader()
          throws LogConfigurationException
      {
          ClassLoader classLoader = null;
  
          try {
              // Are we running on a JDK 1.2 or later system?
              Method method = Thread.class.getMethod("getContextClassLoader", null);
  
              // Get the thread context class loader (if there is one)
              try {
                  classLoader = (ClassLoader)method.invoke(Thread.currentThread(), null);
              } catch (IllegalAccessException e) {
                  throw new LogConfigurationException
                      ("Unexpected IllegalAccessException", e);
              } catch (InvocationTargetException e) {
                  /**
                   * InvocationTargetException is thrown by 'invoke' when
                   * the method being invoked (getContextClassLoader) throws
                   * an exception.
                   * 
                   * getContextClassLoader() throws SecurityException when
                   * the context class loader isn't an ancestor of the
                   * calling class's class loader, or if security
                   * permissions are restricted.
                   * 
                   * In the first case (not related), we want to ignore and
                   * keep going.  We cannot help but also ignore the second
                   * with the logic below, but other calls elsewhere (to
                   * obtain a class loader) will trigger this exception where
                   * we can make a distinction.
                   */
                  if (e.getTargetException() instanceof SecurityException) {
                      ;  // ignore
                  } else {
                      // Capture 'e.getTargetException()' exception for details
                      // alternate: log 'e.getTargetException()', and pass back 'e'.
                      throw new LogConfigurationException
                          ("Unexpected InvocationTargetException", e.getTargetException());
                  }
              }
          } catch (NoSuchMethodException e) {
              // Assume we are running on JDK 1.1
              classLoader = LogFactory.class.getClassLoader();
          }
  
          // Return the selected class loader
          return classLoader;
      }
  
      /**
       * Check cached factories (keyed by classLoader)
       */
      private static LogFactory getCachedFactory(ClassLoader contextClassLoader)
      {
          LogFactory factory = null;
          
          if (contextClassLoader != null)
              factory = (LogFactory) factories.get(contextClassLoader);
              
          if (factory==null)
              factory = (LogFactory) factories.get(LogFactory.class.getClassLoader());
          
          return factory;
      }
      
      private static void cacheFactory(ClassLoader classLoader, LogFactory factory)
      {
          if (classLoader != null && factory != null)
              factories.put(classLoader, factory);
      }
  
      /**
       * Return a new instance of the specified <code>LogFactory</code>
       * implementation class, loaded by the specified class loader.
       * If that fails, try the class loader used to load this
       * (abstract) LogFactory.
       *
       * @param factoryClass Fully qualified name of the <code>LogFactory</code>
       *  implementation class
       * @param classLoader ClassLoader from which to load this class
       *
       * @exception LogConfigurationException if a suitable instance
       *  cannot be created
       */
      protected static LogFactory newFactory(String factoryClass,
                                             ClassLoader classLoader)
          throws LogConfigurationException
      {
          
          try {
              if (classLoader == null)
                  classLoader = LogFactory.class.getClassLoader();
  
              Class clazz = null;
              try {
                  // first the thread class loader
                  clazz = classLoader.loadClass(factoryClass);
              } catch (ClassNotFoundException ex) {
                  // if this failed (i.e. no implementation is
                  // found in the webapp), try the caller's loader
                  // if we haven't already...
                  if (classLoader != LogFactory.class.getClassLoader()) {
                      classLoader = LogFactory.class.getClassLoader();
                      clazz = classLoader.loadClass(factoryClass);
                  }
              }
              
              LogFactory factory = (LogFactory)clazz.newInstance();
              
              return factory;
          } catch (Exception e) {
              throw new LogConfigurationException(e);
          }
  
      }
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/logging/Log.java
  
  Index: Log.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/Log.java,v 1.13 2002/06/15 18:13:01 craigmcc Exp $
   * $Revision: 1.13 $
   * $Date: 2002/06/15 18:13:01 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.logging;
  
  /**
   * <p>A simple logging interface abstracting logging APIs.  In order to be
   * instantiated successfully by {@link LogSource}, classes that implement
   * this interface must have a constructor that takes a single String
   * parameter representing the "name" of this Log.</p>
   *
   * <p> The six logging levels used by <code>Log</code> are (in order):
   * <ol>
   * <li>trace (the least serious)</li>
   * <li>debug</li>
   * <li>info</li>
   * <li>warn</li>
   * <li>error</li>
   * <li>fatal (the most serious)</li>
   * </ol>
   * The mapping of these log levels to the concepts used by the underlying
   * logging system is implementation dependent.
   * The implemention should ensure, though, that this ordering behaves
   * as expected.</p>
   *
   * <p>Performance is often a logging concern.
   * By examining the appropriate property,
   * a component can avoid expensive operations (producing information
   * to be logged).</p>
   *
   * <p> For example,
   * <code><pre>
   *    if (log.isDebugEnabled()) {
   *        ... do something expensive ...
   *        log.debug(theResult);
   *    }
   * </pre></code>
   * </p>
   *
   * <p>Configuration of the underlying logging system will generally be done
   * external to the Logging APIs, through whatever mechanism is supported by
   * that system.</p>
   *
   * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
   * @author Rod Waldhoff
   * @version $Id: Log.java,v 1.13 2002/06/15 18:13:01 craigmcc Exp $
   */
  public interface Log {
  
  
      // ----------------------------------------------------- Logging Properties
  
  
      /**
       * <p> Is debug logging currently enabled? </p>
       *
       * <p> Call this method to prevent having to perform expensive operations
       * (for example, <code>String</code> concatination)
       * when the log level is more than debug. </p>
       */
      public boolean isDebugEnabled();
  
  
      /**
       * <p> Is error logging currently enabled? </p>
       *
       * <p> Call this method to prevent having to perform expensive operations
       * (for example, <code>String</code> concatination)
       * when the log level is more than error. </p>
       */
      public boolean isErrorEnabled();
  
  
      /**
       * <p> Is fatal logging currently enabled? </p>
       *
       * <p> Call this method to prevent having to perform expensive operations
       * (for example, <code>String</code> concatination)
       * when the log level is more than fatal. </p>
       */
      public boolean isFatalEnabled();
  
  
      /**
       * <p> Is info logging currently enabled? </p>
       *
       * <p> Call this method to prevent having to perform expensive operations
       * (for example, <code>String</code> concatination)
       * when the log level is more than info. </p>
       */
      public boolean isInfoEnabled();
  
  
      /**
       * <p> Is trace logging currently enabled? </p>
       *
       * <p> Call this method to prevent having to perform expensive operations
       * (for example, <code>String</code> concatination)
       * when the log level is more than trace. </p>
       */
      public boolean isTraceEnabled();
  
  
      /**
       * <p> Is warning logging currently enabled? </p>
       *
       * <p> Call this method to prevent having to perform expensive operations
       * (for example, <code>String</code> concatination)
       * when the log level is more than warning. </p>
       */
      public boolean isWarnEnabled();
  
  
      // -------------------------------------------------------- Logging Methods
  
  
      /**
       * <p> Log a message with trace log level. </p>
       *
       * @param message log this message
       */
      public void trace(Object message);
  
  
      /**
       * <p> Log an error with trace log level. </p>
       *
       * @param message log this message
       * @param t log this cause
       */
      public void trace(Object message, Throwable t);
  
  
      /**
       * <p> Log a message with debug log level. </p>
       *
       * @param message log this message
       */
      public void debug(Object message);
  
  
      /**
       * <p> Log an error with debug log level. </p>
       *
       * @param message log this message
       * @param t log this cause
       */
      public void debug(Object message, Throwable t);
  
  
      /**
       * <p> Log a message with info log level. </p>
       *
       * @param message log this message
       */
      public void info(Object message);
  
  
      /**
       * <p> Log an error with info log level. </p>
       *
       * @param message log this message
       * @param t log this cause
       */
      public void info(Object message, Throwable t);
  
  
      /**
       * <p> Log a message with warn log level. </p>
       *
       * @param message log this message
       */
      public void warn(Object message);
  
  
      /**
       * <p> Log an error with warn log level. </p>
       *
       * @param message log this message
       * @param t log this cause
       */
      public void warn(Object message, Throwable t);
  
  
      /**
       * <p> Log a message with error log level. </p>
       *
       * @param message log this message
       */
      public void error(Object message);
  
  
      /**
       * <p> Log an error with error log level. </p>
       *
       * @param message log this message
       * @param t log this cause
       */
      public void error(Object message, Throwable t);
  
  
      /**
       * <p> Log a message with fatal log level. </p>
       *
       * @param message log this message
       */
      public void fatal(Object message);
  
  
      /**
       * <p> Log an error with fatal log level. </p>
       *
       * @param message log this message
       * @param t log this cause
       */
      public void fatal(Object message, Throwable t);
  
  
  }
  
  
  
  1.1                  jakarta-commons/discovery/src/java/org/apache/commons/logging/LogConfigurationException.java
  
  Index: LogConfigurationException.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/LogConfigurationException.java,v 1.1 2002/02/13 02:18:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2002/02/13 02:18:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, 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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 (INCLUDING, 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.commons.logging;
  
  
  /**
   * <p>An exception that is thrown only if a suitable <code>LogFactory</code>
   * or <code>Log</code> instance cannot be created by the corresponding
   * factory methods.</p>
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2002/02/13 02:18:30 $
   */
  
  public class LogConfigurationException extends RuntimeException {
  
  
      /**
       * Construct a new exception with <code>null</code> as its detail message.
       */
      public LogConfigurationException() {
  
          super();
  
      }
  
  
      /**
       * Construct a new exception with the specified detail message.
       *
       * @param message The detail message
       */
      public LogConfigurationException(String message) {
  
          super(message);
  
      }
  
  
      /**
       * Construct a new exception with the specified cause and a derived
       * detail message.
       *
       * @param cause The underlying cause
       */
      public LogConfigurationException(Throwable cause) {
  
          this((cause == null) ? null : cause.toString(), cause);
  
      }
  
  
      /**
       * Construct a new exception with the specified detail message and cause.
       *
       * @param message The detail message
       * @param cause The underlying cause
       */
      public LogConfigurationException(String message, Throwable cause) {
  
          super(message);
          this.cause = cause; // Two-argument version requires JDK 1.4 or later
  
      }
  
  
      /**
       * The underlying cause of this exception.
       */
      protected Throwable cause = null;
  
  
      /**
       * Return the underlying cause of this exception (if any).
       */
      public Throwable getCause() {
  
          return (this.cause);
  
      }
  
  
  }
  
  
  
  1.10      +19 -3     jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceDiscovery.java
  
  Index: ResourceDiscovery.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ResourceDiscovery.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ResourceDiscovery.java	23 Aug 2002 21:56:10 -0000	1.9
  +++ ResourceDiscovery.java	26 Aug 2002 13:08:46 -0000	1.10
  @@ -63,6 +63,9 @@
   
   import org.apache.commons.discovery.jdk.JDKHooks;
   
  +import org.apache.commons.discovery.log.DiscoveryLogFactory;
  +import org.apache.commons.logging.Log;
  +
   
   /**
    * This class supports any VM, including JDK1.1, via
  @@ -77,6 +80,8 @@
    */
   public class ResourceDiscovery
   {
  +    private static Log log = DiscoveryLogFactory.newLog(ResourceDiscovery.class);
  +
       /**
        * this doesn't buy anything except +/- style (subjective).
        */
  @@ -124,6 +129,9 @@
        * @return Enumeration of ResourceInfo
        */
       public Enumeration findResources(final String resourceName) {
  +        if (log.isDebugEnabled())
  +            log.debug("findResources: resourceName='" + resourceName + "'");
  +
           return new Enumeration() {
               private int idx = 0;
               private ClassLoader loader = null;
  @@ -151,9 +159,11 @@
                   ResourceInfo resourceInfo;
                   if (resources != null) {
                       URL url = (URL)resources.nextElement();
  -                    System.out.println("XXX URL " + url );
  +
  +                    if (log.isDebugEnabled())
  +                        log.debug("getNextResource: next URL='" + url + "'");
  +
                       resourceInfo = new ResourceInfo(resourceName, loader, url);
  -                    System.out.println("XXX " + resourceInfo.toString());
                   } else {
                       resourceInfo = null;
                   }
  @@ -164,17 +174,23 @@
               private Enumeration getNextResources() {
                   while (idx < getClassLoaders().size()) {
                       loader = getClassLoaders().get(idx++);
  +                    if (log.isDebugEnabled())
  +                        log.debug("getNextResources: search using ClassLoader '" + loader + "'");
                       try {
                           Enumeration enum = jdkHooks.getResources(loader, resourceName);
                           if (enum != null && enum.hasMoreElements()) {
                               return enum;
                           }
                       } catch( IOException ex ) {
  -                        ex.printStackTrace();
  +                        log.warn("getNextResources: Ignoring Exception", ex);
                       }
                   }
                   return null;
               }
           };
  +    }
  +    
  +    public static void setLog(Log _log) {
  +        log = _log;
       }
   }
  
  
  
  1.9       +27 -8     jakarta-commons/discovery/src/java/org/apache/commons/discovery/ServiceDiscovery.java
  
  Index: ServiceDiscovery.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ServiceDiscovery.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ServiceDiscovery.java	23 Aug 2002 21:56:09 -0000	1.8
  +++ ServiceDiscovery.java	26 Aug 2002 13:08:46 -0000	1.9
  @@ -66,6 +66,9 @@
   import java.util.Enumeration;
   import java.util.Vector;
   
  +import org.apache.commons.discovery.log.DiscoveryLogFactory;
  +import org.apache.commons.logging.Log;
  +
   
   
   /**
  @@ -92,6 +95,8 @@
    */
   public class ServiceDiscovery extends ResourceDiscovery
   {
  +    private static Log log = DiscoveryLogFactory.newLog(ServiceDiscovery.class);
  +
       protected static final String SERVICE_HOME = "META-INF/services/";
       
       /** Construct a new service discoverer
  @@ -113,9 +118,12 @@
        * 
        * @return Enumeration of ClassInfo
        */
  -    public Enumeration findResources(final String resourceName) {
  +    public Enumeration findResources(final String serviceName) {
  +        if (log.isDebugEnabled())
  +            log.debug("findResources: serviceName='" + serviceName + "'");
  +
           final Enumeration files =
  -            super.findResources(SERVICE_HOME + resourceName);
  +            super.findResources(SERVICE_HOME + serviceName);
   
           return new Enumeration() {
               private ClassDiscovery classDiscovery =
  @@ -128,7 +136,7 @@
               
               public boolean hasMoreElements() {
                   if (resource == null) {
  -                    resource = getNextResource();
  +                    resource = getNextService();
                   }
                   return resource != null;
               }
  @@ -139,7 +147,7 @@
                   return element;
               }
               
  -            private ClassInfo getNextResource() {
  +            private ClassInfo getNextService() {
                   if (classResources == null || !classResources.hasMoreElements()) {
                       classResources = getNextClassResources();
                       if (classResources == null) {
  @@ -148,7 +156,7 @@
                   }
   
                   ClassInfo classInfo = (ClassInfo)classResources.nextElement();
  -                System.out.println("XXX " + classInfo.toString());
  +
                   return classInfo;
               }
   
  @@ -161,7 +169,12 @@
                           }
                           idx = 0;
                       }
  -    
  +
  +                    String className = (String)classNames.get(idx++);
  +                    
  +                    if (log.isDebugEnabled())
  +                        log.debug("getNextClassResource: next class='" + className + "'");
  +
                       /**
                        * The loader used to find the service file
                        * is of no (limited?) use here... likewise
  @@ -170,7 +183,7 @@
                        * find unique classes & their loaders...
                        */
                       Enumeration classes =
  -                        classDiscovery.findResources((String)classNames.get(idx++));
  +                        classDiscovery.findResources(className);
   
                       if (classes != null && classes.hasMoreElements()) {
                           return classes;
  @@ -203,7 +216,9 @@
                * URL is of the form: baseURL/META-INF/services/resourceName
                */
               URL baseURL = new URL( url, "../../.." );
  -            System.out.println("XXX BaseURL " + baseURL);
  +
  +            if (log.isDebugEnabled())
  +                log.debug("readServices: baseURL='" + baseURL + "'");
               
               InputStream is = url.openStream();
               
  @@ -245,5 +260,9 @@
           }
           
           return results;
  +    }
  +    
  +    public static void setLog(Log _log) {
  +        log = _log;
       }
   }
  
  
  
  1.2       +11 -2     jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassInfo.java
  
  Index: ClassInfo.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassInfo.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ClassInfo.java	23 Aug 2002 21:56:10 -0000	1.1
  +++ ClassInfo.java	26 Aug 2002 13:08:46 -0000	1.2
  @@ -59,6 +59,9 @@
   
   import java.net.URL;
   
  +import org.apache.commons.discovery.log.DiscoveryLogFactory;
  +import org.apache.commons.logging.Log;
  +
   
   /**
    * 'Resource' located by discovery.
  @@ -69,6 +72,8 @@
    */
   public class ClassInfo extends ResourceInfo
   {
  +    private static Log log = DiscoveryLogFactory.newLog(ClassInfo.class);
  +
       private static final boolean debug = false;
   
       protected Class       resourceClass;
  @@ -93,8 +98,8 @@
        */
       public Class getResourceClass() {
           if (resourceClass == null) {
  -            if (debug)
  -                System.out.println("Loading class '" + getResourceName() + "' with " + loader);
  +            if (log.isDebugEnabled())
  +                log.debug("getResourceClass: Loading class '" + getResourceName() + "' with " + loader);
       
               try {
                   setResourceClass(getLoader().loadClass(getResourceName()));
  @@ -123,5 +128,9 @@
       
       public String toString() {
           return "ClassResource " + resourceName + " " + loader + " " + location;
  +    }
  +    
  +    public static void setLog(Log _log) {
  +        log = _log;
       }
   }
  
  
  
  1.4       +20 -2     jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassDiscovery.java
  
  Index: ClassDiscovery.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/discovery/src/java/org/apache/commons/discovery/ClassDiscovery.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ClassDiscovery.java	23 Aug 2002 21:56:09 -0000	1.3
  +++ ClassDiscovery.java	26 Aug 2002 13:08:46 -0000	1.4
  @@ -61,6 +61,9 @@
   import java.util.Enumeration;
   import java.util.Vector;
   
  +import org.apache.commons.discovery.log.DiscoveryLogFactory;
  +import org.apache.commons.logging.Log;
  +
   
   
   /**
  @@ -76,6 +79,8 @@
    */
   public class ClassDiscovery extends ResourceDiscovery
   {
  +    private static Log log = DiscoveryLogFactory.newLog(ClassDiscovery.class);
  +
       protected static final String SERVICE_HOME = "META-INF/services/";
       
       /** Construct a new class discoverer
  @@ -102,6 +107,9 @@
       public Enumeration findResources(final String className) {
           final String resourceName = className.replace('.','/') + ".class";
           
  +        if (log.isDebugEnabled())
  +            log.debug("findResources: className='" + className + "'");
  +
           return new Enumeration() {
               private Vector history = new Vector();
               private int idx = 0;
  @@ -109,7 +117,7 @@
               
               public boolean hasMoreElements() {
                   if (resource == null) {
  -                    resource = getNextResource();
  +                    resource = getNextClass();
                   }
                   return resource != null;
               }
  @@ -120,17 +128,27 @@
                   return element;
               }
               
  -            private ClassInfo getNextResource() {
  +            private ClassInfo getNextClass() {
                   while (idx < getClassLoaders().size()) {
                       ClassLoader loader = getClassLoaders().get(idx++);
                       URL url = loader.getResource(resourceName);
                       if (url != null  &&  !history.contains(url)) {
                           history.addElement(url);
  +
  +                        if (log.isDebugEnabled())
  +                            log.debug("getNextClass: next URL='" + url + "'");
  +
                           return new ClassInfo(className, loader, url);
                       }
  +                    if (log.isDebugEnabled())
  +                        log.debug("getNextClass: duplicate URL='" + url + "'");
                   }
                   return null;
               }
           };
  +    }
  +    
  +    public static void setLog(Log _log) {
  +        log = _log;
       }
   }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>