[jboss-cvs] apache/commons-logging/src/test/org/apache/commons/logging ...

Scott Stark scott.stark at jboss.com
Fri Feb 9 01:57:17 EST 2007


  User: starksm 
  Date: 07/02/09 01:57:17

  Modified:    commons-logging/src/test/org/apache/commons/logging            
                        UserClass.java AbstractLogTest.java
  Added:       commons-logging/src/test/org/apache/commons/logging            
                        LoadTestCase.java NullClassLoaderTestCase.java
                        AltHashtable.java PathableTestSuite.java
                        AltHashtableTestCase.java SimpleLogTestCase.java
                        LogTestCase.java BadHashtablePropertyTestCase.java
                        BasicOperationsTestCase.java
                        PathableClassLoader.java
  Log:
  Update to the http://apache.ziply.com/jakarta/commons/logging/source/commons-logging-1.1-src.zip release
  
  Revision  Changes    Path
  1.2       +42 -27    apache/commons-logging/src/test/org/apache/commons/logging/UserClass.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: UserClass.java
  ===================================================================
  RCS file: /cvsroot/jboss/apache/commons-logging/src/test/org/apache/commons/logging/UserClass.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- UserClass.java	17 Apr 2006 21:00:05 -0000	1.1
  +++ UserClass.java	9 Feb 2007 06:57:16 -0000	1.2
  @@ -16,12 +16,27 @@
    
   package org.apache.commons.logging;
   
  +import org.apache.commons.logging.LogFactory;
  +import org.apache.commons.logging.impl.LogFactoryImpl;
  +
   public class UserClass {
       
      
  +    /**
  +     * Set the ALLOW_FLAWED_CONTEXT feature on the LogFactoryImpl object
  +     * associated with this class' classloader.
  +     * <p>
  +     * Don't forget to set the context classloader to whatever it will be
  +     * when an instance of this class is actually created <i>before</i> calling
  +     * this method!
  +     */
  +    public static void setAllowFlawedContext(String state) {
  +        LogFactory f = LogFactory.getFactory();
  +        f.setAttribute(LogFactoryImpl.ALLOW_FLAWED_CONTEXT_PROPERTY, state); 
  +    }
    
       public UserClass() {
  -        Log log = LogFactory.getLog(LoadTest.class);
  +        Log log = LogFactory.getLog(LoadTestCase.class);
         }
       
   }
  
  
  
  1.2       +95 -98    apache/commons-logging/src/test/org/apache/commons/logging/AbstractLogTest.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: AbstractLogTest.java
  ===================================================================
  RCS file: /cvsroot/jboss/apache/commons-logging/src/test/org/apache/commons/logging/AbstractLogTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- AbstractLogTest.java	17 Apr 2006 21:00:05 -0000	1.1
  +++ AbstractLogTest.java	9 Feb 2007 06:57:17 -0000	1.2
  @@ -17,22 +17,19 @@
    
   package org.apache.commons.logging;
   
  -import junit.framework.*;
  +import junit.framework.TestCase;
   
   
   /**
  +  * Generic tests that can be applied to any log adapter by
  +  * subclassing this class and defining method getLogObject
  +  * appropriately.
     *
     * @author Sean C. Sullivan
  -  * @version $Revision: 1.1 $
  -  * 
  +  * @version $Revision: 1.2 $
     */
   public abstract class AbstractLogTest extends TestCase {
   
  -    public AbstractLogTest(String testName) {
  -        super(testName);
  -    }
  -
  -    
       public abstract Log getLogObject();
   
   	public void testLoggingWithNullParameters()
  
  
  
  1.1      date: 2007/02/09 06:57:16;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/LoadTestCase.java
  
  Index: LoadTestCase.java
  ===================================================================
  /*
   * Copyright 2001-2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  package org.apache.commons.logging;
  
  import junit.framework.TestCase;
  
  /**
   * testcase to emulate container and application isolated from container
   * @author  baliuka
   * @version $Id: LoadTestCase.java,v 1.1 2007/02/09 06:57:16 starksm Exp $
   */
  public class LoadTestCase extends TestCase{
      //TODO: need some way to add service provider packages
      static private String LOG_PCKG[] = {"org.apache.commons.logging",
                                          "org.apache.commons.logging.impl"};
      
      /**
       * A custom classloader which "duplicates" logging classes available
       * in the parent classloader into itself.
       * <p>
       * When asked to load a class that is in one of the LOG_PCKG packages,
       * it loads the class itself (child-first). This class doesn't need
       * to be set up with a classpath, as it simply uses the same classpath
       * as the classloader that loaded it.
       */
      static class AppClassLoader extends ClassLoader{
          
          java.util.Map classes = new java.util.HashMap();
          
          AppClassLoader(ClassLoader parent){
              super(parent);
          }
          
          private Class def(String name)throws ClassNotFoundException{
              
              Class result = (Class)classes.get(name);
              if(result != null){
                  return result;
              }
              
              try{
                  
                  ClassLoader cl = this.getClass().getClassLoader();
                  String classFileName = name.replace('.','/') + ".class";
                  java.io.InputStream is = cl.getResourceAsStream(classFileName);
                  java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
                  
                  while(is.available() > 0){
                      out.write(is.read());
                  }
                  
                  byte data [] = out.toByteArray();
                  
                  result = super.defineClass(name, data, 0, data.length );
                  classes.put(name,result);
                  
                  return result;
                  
              }catch(java.io.IOException ioe){
                  
                  throw new ClassNotFoundException( name + " caused by "
                  + ioe.getMessage() );
              }
              
              
          }
          
          // not very trivial to emulate we must implement "findClass",
          // but it will delegete to junit class loder first
          public Class loadClass(String name)throws ClassNotFoundException{
              
              //isolates all logging classes, application in the same classloader too.
              //filters exeptions to simlify handling in test
              for(int i = 0; i < LOG_PCKG.length; i++ ){
                  if( name.startsWith( LOG_PCKG[i] ) &&
                  name.indexOf("Exception") == -1   ){
                      return def(name);
                  }
              }
              return super.loadClass(name);
          }
          
      }
      
  
      /**
       * Call the static setAllowFlawedContext method on the specified class
       * (expected to be a UserClass loaded via a custom classloader), passing
       * it the specified state parameter.
       */
      private void setAllowFlawedContext(Class c, String state) throws Exception {
          Class[] params = {String.class};
          java.lang.reflect.Method m = c.getDeclaredMethod("setAllowFlawedContext", params);
          m.invoke(null, new Object[] {state});
      }
  
      /**
       * Test what happens when we play various classloader tricks like those
       * that happen in web and j2ee containers.
       * <p>
       * Note that this test assumes that commons-logging.jar and log4j.jar
       * are available via the system classpath.
       */
      public void testInContainer()throws Exception{
          
          //problem can be in this step (broken app container or missconfiguration)
          //1.  Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
          //2.  Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
          // we expect this :
          // 1. Thread.currentThread().setContextClassLoader(appLoader);
          // 2. Thread.currentThread().setContextClassLoader(null);
          
          // Context classloader is same as class calling into log
          Class cls = reload();
          Thread.currentThread().setContextClassLoader(cls.getClassLoader());
          execute(cls);
          
          // Context classloader is the "bootclassloader". This is technically
          // bad, but LogFactoryImpl.ALLOW_FLAWED_CONTEXT defaults to true so
          // this test should pass.
          cls = reload();
          Thread.currentThread().setContextClassLoader(null);
          execute(cls);
          
          // Context classloader is the "bootclassloader". This is same as above
          // except that ALLOW_FLAWED_CONTEXT is set to false; an error should
          // now be reported.
          cls = reload();
          Thread.currentThread().setContextClassLoader(null);
          try {
              setAllowFlawedContext(cls, "false");
              execute(cls);
              fail("Logging config succeeded when context classloader was null!");
          } catch(LogConfigurationException ex) {
              // expected; the boot classloader doesn't *have* JCL available
          }
          
          // Context classloader is the system classloader.
          //
          // This is expected to cause problems, as LogFactoryImpl will attempt
          // to use the system classloader to load the Log4JLogger class, which
          // will then be unable to cast that object to the Log interface loaded
          // via the child classloader. However as ALLOW_FLAWED_CONTEXT defaults
          // to true this test should pass.
          cls = reload();
          Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
          execute(cls);
          
          // Context classloader is the system classloader. This is the same
          // as above except that ALLOW_FLAWED_CONTEXT is set to false; an error 
          // should now be reported.
          cls = reload();
          Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
          try {
              setAllowFlawedContext(cls, "false");
              execute(cls);
              fail("Error: somehow downcast a Logger loaded via system classloader"
                      + " to the Log interface loaded via a custom classloader");
          } catch(LogConfigurationException ex) {
              // expected 
          }
      }
  
      /**
       * Load class UserClass via a temporary classloader which is a child of
       * the classloader used to load this test class.
       */
      private Class reload()throws Exception{
          
          Class testObjCls = null;
          
          AppClassLoader appLoader = new AppClassLoader( 
                  this.getClass().getClassLoader());
          try{
              
              testObjCls = appLoader.loadClass(UserClass.class.getName());
              
          }catch(ClassNotFoundException cnfe){
              throw cnfe;
          }catch(Throwable t){
              t.printStackTrace();
              fail("AppClassLoader failed ");
          }
          
          assertTrue( "app isolated" ,testObjCls.getClassLoader() == appLoader );
          
          
          return testObjCls;
          
          
      }
      
      
      private void execute(Class cls)throws Exception{
              
              cls.newInstance();
          
      }
      
      
      public static void main(String[] args){
          String[] testCaseName = { LoadTestCase.class.getName() };
          junit.textui.TestRunner.main(testCaseName);
      }
      
      public void setUp() {
          // save state before test starts so we can restore it when test ends
          origContextClassLoader = Thread.currentThread().getContextClassLoader();
      }
      
      public void tearDown() {
          // restore original state so a test can't stuff up later tests.
          Thread.currentThread().setContextClassLoader(origContextClassLoader);
      }
      
      private ClassLoader origContextClassLoader;
  }
  
  
  
  1.1      date: 2007/02/09 06:57:16;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/NullClassLoaderTestCase.java
  
  Index: NullClassLoaderTestCase.java
  ===================================================================
  /*
   * Copyright 2001-2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  package org.apache.commons.logging;
  
  import junit.framework.TestCase;
  
  /**
   * Test cases for situations where getClassLoader or getContextClassLoader
   * return null. This can happen when using JDK 1.1. It can also happen when
   * JCL is deployed via the bootclassloader - something that could be done when
   * using java in embedded systems.
   */
  public class NullClassLoaderTestCase extends TestCase {
  
      //---------------------- Main ---------------------------------    
  
      /**
       * Main method so this test case can be run direct from the command line.
       */
      public static void main(String[] args){
          String[] testCaseName = { NullClassLoaderTestCase.class.getName() };
          junit.textui.TestRunner.main(testCaseName);
      }
  
      //---------------------- unit tests ---------------------------------    
      
      /**
       * This tests that when getContextClassLoader returns null, the
       * LogFactory.getLog(name) method still correctly returns the same
       * log object when called multiple times with the same name.
       */
      public void testSameLogObject() throws Exception {
          // unfortunately, there just isn't any way to emulate JCL being
          // accessable via the null classloader in "standard" systems, so
          // we can't include this test in our standard unit tests.
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:16;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/AltHashtable.java
  
  Index: AltHashtable.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  
  package org.apache.commons.logging;
  
  import java.util.Hashtable;
  
  public class AltHashtable extends Hashtable {
  
      public static Object lastKey;
      public static Object lastValue;
      
      public Object put(Object key, Object value) {
          lastKey = key;
          lastValue = value;
          return super.put(key, value);
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:16;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/PathableTestSuite.java
  
  Index: PathableTestSuite.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  
  package org.apache.commons.logging;
  
  import java.util.Properties;
  
  import junit.framework.Test;
  import junit.framework.TestResult;
  import junit.framework.TestSuite;
  
  /**
   * Custom TestSuite class that can be used to control the context classloader
   * in operation when a test runs.
   * <p>
   * For tests that need to control exactly what the classloader hierarchy is
   * like when the test is run, something like the following is recommended:
   * <pre>
   * class SomeTestCase extends TestCase {
   *  public static Test suite() throws Exception {
   *   PathableClassLoader parent = new PathableClassLoader(null);
   *   parent.useSystemLoader("junit.");
   * 
   *   PathableClassLoader child = new PathableClassLoader(parent);
   *   child.addLogicalLib("testclasses");
   *   child.addLogicalLib("log4j12");
   *   child.addLogicalLib("commons-logging");
   * 
   *   Class testClass = child.loadClass(SomeTestCase.class.getName());
   *   ClassLoader contextClassLoader = child;
   * 
   *   PathableTestSuite suite = new PathableTestSuite(testClass, child);
   *   return suite;
   *  }
   * 
   *  // test methods go here
   * }
   * </pre>
   * Note that if the suite method throws an exception then this will be handled
   * reasonable gracefully by junit; it will report that the suite method for 
   * a test case failed with exception yyy.
   * <p>
   * The use of PathableClassLoader is not required to use this class, but it
   * is expected that using the two classes together is common practice.
   * <p>
   * This class will run each test methods within the specified TestCase using
   * the specified context classloader and system classloader. If different
   * tests within the same class require different context classloaders,
   * then the context classloader passed to the constructor should be the 
   * "lowest" one available, and tests that need the context set to some parent
   * of this "lowest" classloader can call
   * <pre>
   *  // NB: pseudo-code only
   *  setContextClassLoader(getContextClassLoader().getParent());
   * </pre>
   * This class ensures that any context classloader changes applied by a test
   * is undone after the test is run, so tests don't need to worry about
   * restoring the context classloader on exit. This class also ensures that
   * the system properties are restored to their original settings after each
   * test, so tests that manipulate those don't need to worry about resetting them. 
   * <p>
   * This class does not provide facilities for manipulating system properties;
   * tests that need specific system properties can simply set them in the
   * fixture or at the start of a test method.
   * <p>
   * <b>Important!</b> When the test case is run, "this.getClass()" refers of
   * course to the Class object passed to the constructor of this class - which 
   * is different from the class whose suite() method was executed to determine
   * the classpath. This means that the suite method cannot communicate with
   * the test cases simply by setting static variables (for example to make the
   * custom classloaders available to the test methods or setUp/tearDown fixtures).
   * If this is really necessary then it is possible to use reflection to invoke
   * static methods on the class object passed to the constructor of this class.
   * <p>
   * <h2>Limitations</h2>
   * <p>
   * This class cannot control the system classloader (ie what method 
   * ClassLoader.getSystemClassLoader returns) because Java provides no
   * mechanism for setting the system classloader. In this case, the only
   * option is to invoke the unit test in a separate JVM with the appropriate
   * settings.
   * <p>
   * The effect of using this approach in a system that uses junit's
   * "reloading classloader" behaviour is unknown. This junit feature is
   * intended for junit GUI apps where a test may be run multiple times
   * within the same JVM - and in particular, when the .class file may
   * be modified between runs of the test. How junit achieves this is
   * actually rather weird (the whole junit code is rather weird in fact)
   * and it is not clear whether this approach will work as expected in
   * such situations.
   */
  public class PathableTestSuite extends TestSuite {
  
      /**
       * The classloader that should be set as the context classloader
       * before each test in the suite is run.
       */
      private ClassLoader contextLoader;
  
      /**
       * Constructor.
       * 
       * @param testClass is the TestCase that is to be run, as loaded by
       * the appropriate ClassLoader.
       * 
       * @param contextClassLoader is the loader that should be returned by
       * calls to Thread.currentThread.getContextClassLoader from test methods
       * (or any method called by test methods).
       */
      public PathableTestSuite(Class testClass, ClassLoader contextClassLoader) {
          super(testClass);
          contextLoader = contextClassLoader;
      }
  
      /**
       * This method is invoked once for each Test in the current TestSuite.
       * Note that a Test may itself be a TestSuite object (ie a collection
       * of tests).
       * <p>
       * The context classloader and system properties are saved before each
       * test, and restored after the test completes to better isolate tests.
       */
      public void runTest(Test test, TestResult result) {
          ClassLoader origContext = Thread.currentThread().getContextClassLoader();
          Properties oldSysProps = (Properties) System.getProperties().clone();
          try {
              Thread.currentThread().setContextClassLoader(contextLoader);
              test.run(result);
          } finally {
              System.setProperties(oldSysProps);
              Thread.currentThread().setContextClassLoader(origContext);
          }
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:17;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/AltHashtableTestCase.java
  
  Index: AltHashtableTestCase.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  
  package org.apache.commons.logging;
  
  import junit.framework.*;
  
  /**
   * Test the ability to force the LogFactory class to use some
   * arbitrary Hashtable implementation to store its mapping from
   * context-classloader -> LogFactory object.
   * <p>
   * This is done by 
   */
  public class AltHashtableTestCase extends TestCase {
  
      public static Test suite() throws Exception {
          Class thisClass = AltHashtableTestCase.class;
          ClassLoader thisClassLoader = thisClass.getClassLoader();
  
          PathableClassLoader loader = new PathableClassLoader(null);
          loader.useExplicitLoader("junit.", thisClassLoader);
          loader.addLogicalLib("testclasses");
          loader.addLogicalLib("commons-logging");
  
          Class testClass = loader.loadClass(thisClass.getName());
          return new PathableTestSuite(testClass, loader);
      }
  
      /**
       * Set up before each test.
       * <p>
       * This method ensures that the appropriate system property is defined
       * to force the LogFactory class to use the AltHashtable class as its
       * Hashtable implementation for storing factories in. 
       * <p>
       * This does make the assumption that whatever JVM we are running in
       * doesn't initialise classes until they are actually referenced (ie the
       * LogFactory class hasn't been initialised before this method is called).
       * This is true of all JVMs I know of; and if it isn't then this test will
       * fail and someone will tell us. 
       */
      public void setUp() {
          System.setProperty(
                  "org.apache.commons.logging.LogFactory.HashtableImpl",
                  AltHashtable.class.getName());
      }
      
      /**
       * Verify that initialising the LogFactory class will cause it
       * to instantiate an object of type specified in system property
       * "org.apache.commons.logging.LogFactory.HashtableImpl".
       */
      public void testType() {
          // Here, the reference to the LogFactory class should cause the
          // class to be loaded and initialised. It will see the property
          // set and use the AltHashtable class. If other tests in this
          // class have already been run within the same classloader then
          // LogFactory will already have been initialised, but that
          // doesn't change the effectiveness of this test.
          assertTrue(LogFactory.factories instanceof AltHashtable);
      }
      
      /**
       * Verify that when LogFactory sees a context-classloader for the
       * first time that it creates a new entry in the LogFactory.factories
       * hashmap. In particular, this checks that this process works ok when
       * a system property has been used to specify an alternative Hashtable
       * implementation for LogFactory to use.
       */
      public void testPutCalled() throws Exception {
          AltHashtable.lastKey = null;
          AltHashtable.lastValue = null;
          
          LogFactory.getLog(AltHashtableTestCase.class);
          ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
          assertEquals(contextLoader, AltHashtable.lastKey);
          assertNotNull(AltHashtable.lastValue);
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:17;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/SimpleLogTestCase.java
  
  Index: SimpleLogTestCase.java
  ===================================================================
  /*
   * Copyright 2001-2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
   
  package org.apache.commons.logging;
  
  import org.apache.commons.logging.impl.SimpleLog;
  
  /**
   * 
   *
   * 
   * 
   * 
   * 
   */
  public class SimpleLogTestCase extends AbstractLogTest
  {
  	/**
  	 * 
  	 * 
  	 * 
  	 */
      public Log getLogObject()
      {
          return (Log) new SimpleLog(this.getClass().getName());
      }
  
      public static void main(String[] args) {
          String[] testCaseName = { SimpleLogTestCase.class.getName() };
          junit.textui.TestRunner.main(testCaseName);	
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:17;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/LogTestCase.java
  
  Index: LogTestCase.java
  ===================================================================
  /*
   * Copyright 2001-2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
   
  package org.apache.commons.logging;
  
  
  /**
   * 
   *
   * 
   * 
   * 
   * 
   */
  public class LogTestCase extends AbstractLogTest
  {
  
      /**
       * 
       * 
       * 
       */
      public Log getLogObject()
      {
          /**
           * Pickup whatever is found/configured!
           */
          return LogFactory.getLog(this.getClass().getName());
      }
  
      public static void main(String[] args)
      {
              String[] testCaseName = { LogTestCase.class.getName() };
              junit.textui.TestRunner.main(testCaseName);    
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:17;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/BadHashtablePropertyTestCase.java
  
  Index: BadHashtablePropertyTestCase.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  
  package org.apache.commons.logging;
  
  import junit.framework.*;
  import java.util.Hashtable;
  
  /**
   * Tests behaviour when the property is misconfigured.
   */
  public class BadHashtablePropertyTestCase extends TestCase {
  
      public void testType()  {
          assertTrue(LogFactory.factories instanceof Hashtable);
      }
      
      public void testPutCalled() throws Exception {
          Log log = LogFactory.getLog(BadHashtablePropertyTestCase.class);
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:17;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/BasicOperationsTestCase.java
  
  Index: BasicOperationsTestCase.java
  ===================================================================
  /*
   * Copyright 2004,2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
   
  package org.apache.commons.logging;
  
  import junit.framework.TestCase;
  
  /**
   * Tests the basic logging operations to ensure that they all function 
   * without exception failure. In other words, that they do no fail by
   * throwing exceptions.
   * This is the minimum requirement for any well behaved logger 
   * and so this test should be run for each kind.
   */
  public class BasicOperationsTestCase extends TestCase
  {
      public void testIsEnabledClassLog()
      {
          Log log = LogFactory.getLog(BasicOperationsTestCase.class);
          executeIsEnabledTest(log);
      }
      
      public void testIsEnabledNamedLog()
      {
          Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
          executeIsEnabledTest(log);
      }    
      
      public void executeIsEnabledTest(Log log)
      {
          try
          {
              log.isTraceEnabled();
              log.isDebugEnabled();
              log.isInfoEnabled();
              log.isWarnEnabled();
              log.isErrorEnabled();
              log.isFatalEnabled();
          }
          catch (Throwable t)
          {
              t.printStackTrace();
              fail("Exception thrown: " + t);
          }
      }
      
      
      public void testMessageWithoutExceptionClassLog()
      {
          Log log = LogFactory.getLog(BasicOperationsTestCase.class);
          executeMessageWithoutExceptionTest(log);
      }
      
      public void testMessageWithoutExceptionNamedLog()
      {
          Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
          executeMessageWithoutExceptionTest(log);
      }    
      
      public void executeMessageWithoutExceptionTest(Log log)
      {
          try
          {
              log.trace("Hello, Mum");
              log.debug("Hello, Mum");
              log.info("Hello, Mum");
              log.warn("Hello, Mum");
              log.error("Hello, Mum");
              log.fatal("Hello, Mum");
          }
          catch (Throwable t)
          {
              t.printStackTrace();
              fail("Exception thrown: " + t);
          }
      }
      
      public void testMessageWithExceptionClassLog()
      {
          Log log = LogFactory.getLog(BasicOperationsTestCase.class);
          executeMessageWithExceptionTest(log);
      }
      
      public void testMessageWithExceptionNamedLog()
      {
          Log log = LogFactory.getLog(BasicOperationsTestCase.class.getName());
          executeMessageWithExceptionTest(log);
      }    
      
      public void executeMessageWithExceptionTest(Log log)
      {
          try
          {
              log.trace("Hello, Mum", new ArithmeticException());
              log.debug("Hello, Mum", new ArithmeticException());
              log.info("Hello, Mum", new ArithmeticException());
              log.warn("Hello, Mum", new ArithmeticException());
              log.error("Hello, Mum", new ArithmeticException());
              log.fatal("Hello, Mum", new ArithmeticException());
          }
          catch (Throwable t)
          {
              t.printStackTrace();
              fail("Exception thrown: " + t);
          }
      }
  }
  
  
  
  1.1      date: 2007/02/09 06:57:17;  author: starksm;  state: Exp;apache/commons-logging/src/test/org/apache/commons/logging/PathableClassLoader.java
  
  Index: PathableClassLoader.java
  ===================================================================
  /*
   * Copyright 2005 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */ 
  
  package org.apache.commons.logging;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  /**
   * A ClassLoader which sees only specified classes, and which can be
   * set to do parent-first or child-first path lookup.
   * <p>
   * Note that this classloader is not "industrial strength"; users
   * looking for such a class may wish to look at the Tomcat sourcecode
   * instead. In particular, this class may not be threadsafe.
   * <p>
   * Note that the ClassLoader.getResources method isn't overloaded here.
   * It would be nice to ensure that when child-first lookup is set the
   * resources from the child are returned earlier in the list than the
   * resources from the parent. However overriding this method isn't possible
   * as the java 1.4 version of ClassLoader declares this method final
   * (though the java 1.5 version has removed the final qualifier). As the
   * ClassLoader javadoc doesn't specify the order in which resources
   * are returned, it's valid to return the resources in any order (just
   * untidy) so the inherited implementation is technically ok.
   */
  
  public class PathableClassLoader extends URLClassLoader {
      
      private static final URL[] NO_URLS = new URL[0];
      
      /**
       * A map of package-prefix to ClassLoader. Any class which is in
       * this map is looked up via the specified classloader instead of
       * the classpath associated with this classloader or its parents.
       * <p>
       * This is necessary in order for the rest of the world to communicate
       * with classes loaded via a custom classloader. As an example, junit
       * testcases which are loaded via a custom classloader needs to see
       * the same junit classes as the code invoking the testcase, otherwise
       * they can't pass result objects back. 
       * <p>
       * Normally, only a classloader created with a null parent needs to
       * have any lookasides defined.
       */
      private HashMap lookasides = null;
  
      /**
       * See setParentFirst.
       */
      private boolean parentFirst = true;
      
      /**
       * Constructor.
       */
      public PathableClassLoader(ClassLoader parent) {
          super(NO_URLS, parent);
      }
      
      /**
       * Allow caller to explicitly add paths. Generally this not a good idea;
       * use addLogicalLib instead, then define the location for that logical
       * library in the build.xml file.
       */
      public void addURL(URL url) {
          super.addURL(url);
      }
  
      /**
       * Specify whether this classloader should ask the parent classloader
       * to resolve a class first, before trying to resolve it via its own
       * classpath.
       * <p> 
       * Checking with the parent first is the normal approach for java, but
       * components within containers such as servlet engines can use 
       * child-first lookup instead, to allow the components to override libs
       * which are visible in shared classloaders provided by the container.
       * <p>
       * Note that the method getResources always behaves as if parentFirst=true,
       * because of limitations in java 1.4; see the javadoc for method
       * getResourcesInOrder for details.
       * <p>
       * This value defaults to true.
       */
      public void setParentFirst(boolean state) {
          parentFirst = state;
      }
  
      /**
       * For classes with the specified prefix, get them from the system
       * classpath <i>which is active at the point this method is called</i>.
       * <p>
       * This method is just a shortcut for
       * <pre>
       * useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
       * </pre>
       */
      public void useSystemLoader(String prefix) {
          useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
          
      }
  
      /**
       * Specify a classloader to use for specific java packages.
       */
      public void useExplicitLoader(String prefix, ClassLoader loader) {
          if (lookasides == null) {
              lookasides = new HashMap();
          }
          lookasides.put(prefix, loader);
      }
  
      /**
       * Specify a collection of logical libraries. See addLogicalLib.
       */
      public void addLogicalLib(String[] logicalLibs) {
          for(int i=0; i<logicalLibs.length; ++i) {
              addLogicalLib(logicalLibs[i]);
          }
      }
  
      /**
       * Specify a logical library to be included in the classpath used to
       * locate classes. 
       * <p>
       * The specified lib name is used as a key into the system properties;
       * there is expected to be a system property defined with that name
       * whose value is a url that indicates where that logical library can
       * be found. Typically this is the name of a jar file, or a directory
       * containing class files.
       * <p>
       * Using logical library names allows the calling code to specify its
       * desired classpath without knowing the exact location of the necessary
       * classes. 
       */
      public void addLogicalLib(String logicalLib) {
          String filename = System.getProperty(logicalLib);
          if (filename == null) {
              throw new UnknownError(
                  "Logical lib [" + logicalLib + "] is not defined"
                  + " as a System property.");
          }
  
          try {
              URL url = new File(filename).toURL();
              addURL(url);
          } catch(java.net.MalformedURLException e) {
              throw new UnknownError(
                  "Invalid file [" + filename + "] for logical lib [" + logicalLib + "]");
          }
      }
      
      /**
       * Override ClassLoader method.
       * <p>
       * For each explicitly mapped package prefix, if the name matches the 
       * prefix associated with that entry then attempt to load the class via 
       * that entries' classloader.
       */
      protected Class loadClass(String name, boolean resolve) 
      throws ClassNotFoundException {
          // just for performance, check java and javax
          if (name.startsWith("java.") || name.startsWith("javax.")) {
              return super.loadClass(name, resolve);
          }
  
          if (lookasides != null) {
              for(Iterator i = lookasides.entrySet().iterator(); i.hasNext(); ) {
                  Map.Entry entry = (Map.Entry) i.next();
                  String prefix = (String) entry.getKey();
                  if (name.startsWith(prefix) == true) {
                      ClassLoader loader = (ClassLoader) entry.getValue();
                      Class clazz = Class.forName(name, resolve, loader);
                      return clazz;
                  }
              }
          }
          
          if (parentFirst) {
              return super.loadClass(name, resolve);
          } else {
              // Implement child-first. 
              //
              // It appears that the findClass method doesn't check whether the
              // class has already been loaded. This seems odd to me, but without
              // first checking via findLoadedClass we can get java.lang.LinkageError
              // with message "duplicate class definition" which isn't good.
              
              try {
                  Class clazz = findLoadedClass(name);
                  if (clazz == null) {
                      clazz = super.findClass(name);
                  }
                  if (resolve) {
                      resolveClass(clazz);
                  }
                  return clazz;
              } catch(ClassNotFoundException e) {
                  return super.loadClass(name, resolve);
              }
          }
      }
      
      /**
       * Same as parent class method except that when parentFirst is false
       * the resource is looked for in the local classpath before the parent
       * loader is consulted.
       */
      public URL getResource(String name) {
          if (parentFirst) {
              return super.getResource(name);
          } else {
              URL local = super.findResource(name);
              if (local != null) {
                  return local;
              }
              return super.getResource(name);
          }
      }
      
      /**
       * Emulate a proper implementation of getResources which respects the
       * setting for parentFirst.
       * <p>
       * Note that it's not possible to override the inherited getResources, as
       * it's declared final in java1.4 (thought that's been removed for 1.5).
       * The inherited implementation always behaves as if parentFirst=true.
       */
      public Enumeration getResourcesInOrder(String name) throws IOException {
          if (parentFirst) {
              return super.getResources(name);
          } else {
              Enumeration localUrls = super.findResources(name);
              
              ClassLoader parent = getParent();
              if (parent == null) {
                  // Alas, there is no method to get matching resources
                  // from a null (BOOT) parent classloader. Calling
                  // ClassLoader.getSystemClassLoader isn't right. Maybe
                  // calling Class.class.getResources(name) would do?
                  //
                  // However for the purposes of unit tests, we can
                  // simply assume that no relevant resources are
                  // loadable from the parent; unit tests will never be
                  // putting any of their resources in a "boot" classloader
                  // path!
                  return localUrls;
              }
              Enumeration parentUrls = parent.getResources(name);
  
              ArrayList localItems = toList(localUrls);
              ArrayList parentItems = toList(parentUrls);
              localItems.addAll(parentItems);
              return Collections.enumeration(localItems);
          }
      }
      
      /**
       * 
       * Clean implementation of list function of 
       * {@link java.utils.Collection} added in JDK 1.4 
       * @param en <code>Enumeration</code>, possibly null
       * @return <code>ArrayList</code> containing the enumerated
       * elements in the enumerated order, not null
       */
      private ArrayList toList(Enumeration en) {
          ArrayList results = new ArrayList();
          if (en != null) {
              while (en.hasMoreElements()){
                  Object element = en.nextElement();
                  results.add(element);
              }
          }
          return results;
      }
      
      /**
       * Same as parent class method except that when parentFirst is false
       * the resource is looked for in the local classpath before the parent
       * loader is consulted.
       */
      public InputStream getResourceAsStream(String name) {
          if (parentFirst) {
              return super.getResourceAsStream(name);
          } else {
              URL local = super.findResource(name);
              if (local != null) {
                  try {
                      return local.openStream();
                  } catch(IOException e) {
                      // TODO: check if this is right or whether we should
                      // fall back to trying parent. The javadoc doesn't say...
                      return null;
                  }
              }
              return super.getResourceAsStream(name);
          }
      }
  }
  
  
  



More information about the jboss-cvs-commits mailing list