You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by dm...@apache.org on 2002/12/14 03:38:44 UTC

cvs commit: jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard StandardReflectedInstanceFactoryTest.java StandardReflectedOperationTest.java StandardReflectedClazzTest.java StandardReflectedListPropertyTest.java

dmitri      2002/12/13 18:38:43

  Modified:    clazz/src/java/org/apache/commons/clazz Clazz.java
                        ClazzLoader.java ClazzNotFoundException.java
                        ClazzOperation.java
               clazz/src/java/org/apache/commons/clazz/bean BasicBean.java
                        BeanClazz.java BeanClazzLoader.java
                        BeanClazzProperty.java BeanGroupClazzLoader.java
               clazz/src/java/org/apache/commons/clazz/common
                        CachingGroupClazzLoader.java GroupClazzLoader.java
               clazz/src/java/org/apache/commons/clazz/reflect
                        ReflectedClazz.java ReflectedClazzLoader.java
                        ReflectedGroupClazzLoader.java
                        ReflectedProperty.java
                        ReflectedPropertyIntrospector.java
               clazz/src/java/org/apache/commons/clazz/reflect/common
                        AccessorMethodParser.java ReflectedList.java
                        ReflectedListProperty.java
                        ReflectedListPropertyIntrospectorSupport.java
                        ReflectedListPropertyParseResults.java
                        ReflectedPropertyIntrospectorSupport.java
                        ReflectedPropertyParseResults.java
                        ReflectedScalarProperty.java
                        ReflectedScalarPropertyIntrospector.java
               clazz/src/java/org/apache/commons/clazz/reflect/extended
                        ExtendedReflectedClazzLoader.java
                        ExtendedReflectedListPropertyIntrospector.java
                        ReflectedMap.java ReflectedMappedProperty.java
                        ReflectedMappedPropertyIntrospector.java
                        ReflectedMappedPropertyParseResults.java
               clazz/src/java/org/apache/commons/clazz/reflect/standard
                        StandardReflectedClazzLoader.java
               clazz/src/test/org/apache/commons/clazz
                        ClazzTestSupport.java
               clazz/src/test/org/apache/commons/clazz/bean
                        BeanClazzLoaderTest.java BeanClazzTest.java
               clazz/src/test/org/apache/commons/clazz/reflect
                        ReflectableInstance.java
                        ReflectedClazzTestSupport.java
               clazz/src/test/org/apache/commons/clazz/reflect/extended
                        ExtendedReflectedClazzTest.java
                        ExtendedReflectedListPropertyTest.java
                        ReflectedMappedPropertyTest.java
               clazz/src/test/org/apache/commons/clazz/reflect/standard
                        StandardReflectedClazzTest.java
                        StandardReflectedListPropertyTest.java
  Added:       clazz/src/java/org/apache/commons/clazz
                        ClazzAccessException.java ClazzChangeListener.java
                        ClazzInstanceFactory.java
               clazz/src/java/org/apache/commons/clazz/bean
                        BeanClazzConfigurationException.java
                        BeanClazzConstructorInstanceFactory.java
                        BeanClazzInstanceFactory.java
                        BeanClazzOperaiton.java
               clazz/src/java/org/apache/commons/clazz/reflect
                        ReflectedInstanceFactoryIntrospector.java
                        ReflectedOperationIntrospector.java
               clazz/src/java/org/apache/commons/clazz/reflect/common
                        ReflectedAccessorPairProperty.java
                        ReflectedConstructorInstanceFactory.java
                        ReflectedConstructorInstanceFactoryIntrospector.java
                        ReflectedMethodFeatureSupport.java
                        ReflectedMethodInstanceFactory.java
                        ReflectedMethodInstanceFactoryIntrospector.java
                        ReflectedMethodOperation.java
                        ReflectedMethodOperationIntrospector.java
               clazz/src/test/org/apache/commons/clazz/reflect
                        ReflectedClazzTest.java
                        ReflectedInstanceFactoryTest.java
                        ReflectedListPropertyTestSupport.java
                        ReflectedOperationTest.java
               clazz/src/test/org/apache/commons/clazz/reflect/extended
                        ExtendedReflectedInstanceFactoryTest.java
                        ExtendedReflectedOperationTest.java
               clazz/src/test/org/apache/commons/clazz/reflect/standard
                        StandardReflectedInstanceFactoryTest.java
                        StandardReflectedOperationTest.java
  Removed:     clazz/src/java/org/apache/commons/clazz/bean
                        BeanClazzException.java
               clazz/src/java/org/apache/commons/clazz/reflect
                        ReflectedAccessException.java
  Log:
  Added some beef to the implementation
  
  Revision  Changes    Path
  1.4       +244 -14   jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/Clazz.java
  
  Index: Clazz.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/Clazz.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Clazz.java	6 Dec 2002 01:12:48 -0000	1.3
  +++ Clazz.java	14 Dec 2002 02:38:41 -0000	1.4
  @@ -53,6 +53,7 @@
    */
   package org.apache.commons.clazz;
   
  +import java.lang.ref.WeakReference;
   import java.util.*;
   
   import org.apache.commons.clazz.bean.BeanClazzLoader;
  @@ -73,6 +74,7 @@
   {
       private ClazzLoader loader;
       private String name;
  +    private List listeners;
   
       public static final String DEFAULT_CLAZZLOADER =
           "org.apache.commons.clazz.DefaultClazzLoader";
  @@ -93,10 +95,10 @@
        * notion of JavaBeans.
        */
       private static ClazzLoader buildDefaultClazzLoader(){
  -        GroupClazzLoader loader = new CachingGroupClazzLoader();
  +        GroupClazzLoader loader = new CachingGroupClazzLoader(null);
   
           // First build a general reflection-based ClazzLoader
  -        GroupClazzLoader reflectedGroup = new ReflectedGroupClazzLoader();
  +        GroupClazzLoader reflectedGroup = new ReflectedGroupClazzLoader(loader);
   
           ClazzLoader reflectedLoader =
               new ExtendedReflectedClazzLoader(loader, getDefaultClassLoader());
  @@ -108,7 +110,7 @@
   
           // Now build a dynamic clazz loader
           
  -        GroupClazzLoader beanGroup = new BeanGroupClazzLoader();
  +        GroupClazzLoader beanGroup = new BeanGroupClazzLoader(loader);
           
           ClazzLoader beanLoader = new BeanClazzLoader(beanGroup);
           
  @@ -124,10 +126,10 @@
        * strictly on the JavaBeans specification.
        */
       private static ClazzLoader buildStandardClazzLoader(){
  -        GroupClazzLoader loader = new CachingGroupClazzLoader();
  +        GroupClazzLoader loader = new CachingGroupClazzLoader(null);
   
           // First build a general reflection-based ClazzLoader
  -        GroupClazzLoader reflectedGroup = new ReflectedGroupClazzLoader();
  +        GroupClazzLoader reflectedGroup = new ReflectedGroupClazzLoader(loader);
   
           ClazzLoader reflectedLoader =
               new StandardReflectedClazzLoader(loader, getDefaultClassLoader());
  @@ -139,7 +141,7 @@
   
           // Now build a dynamic clazz loader
   
  -        GroupClazzLoader beanGroup = new BeanGroupClazzLoader();
  +        GroupClazzLoader beanGroup = new BeanGroupClazzLoader(loader);
   
           ClazzLoader beanLoader = new BeanClazzLoader(beanGroup);
   
  @@ -283,6 +285,12 @@
           
           return name.substring(index + 1);
       }
  +
  +    /**
  +     * Returns the class of instances created by the <code>newInstance()</code>
  +     * method.
  +     */    
  +    public abstract Class getInstanceClass();
       
       /**
        * Returns the superclazz for this Clazz, or null if there is none.
  @@ -290,12 +298,20 @@
       public abstract Clazz getSuperclazz();
       
       /**
  +     * Returns true if the supplied clazz is either the same or a subclazz of
  +     * this clazz.
        */
       public boolean isAssignableFrom(Clazz clazz){
  -        // @todo: provide default implementation
  +        if (clazz == this) {
  +            return true;
  +        }
  +        Clazz superclazz = clazz.getSuperclazz();
  +        if (superclazz != null) {
  +            return isAssignableFrom(superclazz);
  +        }
           return false;
       }
  -
  +    
       /**
        * Returns properties declared by this Clazz, not its superclazzes
        */
  @@ -333,18 +349,232 @@
   //    public abstract List getOperations(Predicate predicate);
   
       /**
  -     * Returns Operations for the given signature. The signature should be
  +     * Returns the Operation for the given signature. The signature should be
        * formatted as follows: <code>"name(paramClazzName1,...)"</code>
        */
       public abstract ClazzOperation getOperation(String signature);
   
       /**
  -     * Creates a new instance of this Clazz
  +     * Returns all InstanceFactories for this clazz.
  +     */
  +    public abstract List getInstanceFactories();
  +
  +    /**
  +     * Returns the InstanceFactories that match the Predicate.
  +     */
  +//    public abstract List getInstanceFactories(Predicate predicate);
  +
  +    /**
  +     * Returns ClazzInstanceFactory for the given signature. The signature
  +     * should be formatted as follows: <code>"(paramClazzName1,...)"</code>. You
  +     * can pass <code>null</code> in place of <code>"()"</code>. 
  +     */
  +    public abstract ClazzInstanceFactory getInstanceFactory(String signature);
  +    
  +    /**
  +     * Creates a new instance of this Clazz using the InstanceFactory that takes
  +     * no parameters.
  +     */
  +    public Object newInstance(){
  +        ClazzInstanceFactory factory = getInstanceFactory("()");
  +        if (factory == null) {
  +            // @todo: define exception
  +            throw new RuntimeException(
  +                "No such instance factory " + getName() + " ()");
  +        }
  +        return factory.newInstance(null);
  +    }
  +
  +    /**
  +     * Creates a new instance of this Clazz using the InstanceFactory
  +     * with the specified signature.
  +     */
  +    public Object newInstance(String signature, Object[] parameters){
  +        ClazzInstanceFactory factory = getInstanceFactory(signature);
  +        if (factory == null) {
  +            // @todo: define exception
  +            throw new RuntimeException(
  +                "No such instance factory "
  +                    + getName()
  +                    + (signature == null ? "" : " " + signature));
  +        }
  +        return factory.newInstance(parameters);
  +    }
  +    
  +    
  +    //--- Notification mechanism - verbose, but what are you gonna do?
  +    
  +    public void addClazzChangeListener(ClazzChangeListener listener){
  +        if (listeners == null){
  +            listeners = new ArrayList();
  +        }
  +        
  +        // We don't want to prevent the subclasses from being garbage
  +        // collection just because they are listening to their superclasses. 
  +        WeakReference reference = new WeakReference(listener);
  +        listeners.add(reference);
  +    }
  +    
  +    public void removeClazzChangeListener(ClazzChangeListener listener){
  +        if (listeners == null){
  +            return;
  +        }
  +        for (Iterator iter = listeners.iterator(); iter.hasNext();) {
  +            WeakReference reference = (WeakReference) iter.next();
  +            if (reference.get() == listener){
  +                iter.remove();
  +                break;
  +            }
  +        }
  +    }
  +        
  +    private static final WeakReference[] CLAZZ_CHANGE_LISTENER_ARRAY =
  +            new WeakReference[0];
  +
  +    private static abstract class Notifier {
  +        void fire(Clazz clazz, Object parameter) {
  +            if (clazz.listeners != null && clazz.listeners.size() != 0) {
  +                WeakReference listenerArray[] =
  +                    (WeakReference[]) clazz.listeners.toArray(
  +                        CLAZZ_CHANGE_LISTENER_ARRAY);
  +                for (int i = 0; i < listenerArray.length; i++) {
  +                    fire(
  +                        clazz,
  +                        (ClazzChangeListener) listenerArray[i].get(),
  +                        parameter);
  +                }
  +            }
  +        }
  +        
  +        abstract void fire(
  +            Clazz clazz, ClazzChangeListener listener, Object parameter);
  +    }
  +    
  +    private static Notifier PROPERTY_ADDED_NOTIFIER = new Notifier() {
  +        void fire(Clazz clazz, ClazzChangeListener listener, Object parameter) {
  +            listener.propertyAdded(clazz, (ClazzProperty) parameter);
  +        }
  +    };
  +                    
  +    protected void firePropertyAdded(ClazzProperty property){
  +        PROPERTY_ADDED_NOTIFIER.fire(this, property);
  +    }
  +
  +    private static Notifier PROPERTY_REMOVED_NOTIFIER = new Notifier() {
  +        void fire(Clazz clazz, ClazzChangeListener listener, Object parameter) {
  +            listener.propertyRemoved(clazz, (ClazzProperty) parameter);
  +        }
  +    };
  +
  +    protected void firePropertyRemoved(ClazzProperty property){
  +        PROPERTY_REMOVED_NOTIFIER.fire(this, property);
  +    }
  +
  +    private static Notifier OPERATION_ADDED_NOTIFIER = new Notifier() {
  +        void fire(Clazz clazz, ClazzChangeListener listener, Object parameter) {
  +            listener.operationAdded(clazz, (ClazzOperation) parameter);
  +        }
  +    };
  +
  +    protected void fireOperationAdded(ClazzOperation operation){
  +        OPERATION_ADDED_NOTIFIER.fire(this, operation);
  +    }
  +
  +    private static Notifier OPERATION_REMOVED_NOTIFIER = new Notifier() {
  +        void fire(Clazz clazz, ClazzChangeListener listener, Object parameter) {
  +            listener.operationRemoved(clazz, (ClazzOperation) parameter);
  +        }
  +    };
  +
  +    protected void fireOperationRemoved(ClazzOperation operation){
  +        OPERATION_REMOVED_NOTIFIER.fire(this, operation);
  +    }
  +
  +
  +    private static Notifier FACTORY_ADDED_NOTIFIER = new Notifier() {
  +        void fire(Clazz clazz, ClazzChangeListener listener, Object parameter) {
  +            listener.instanceFactoryAdded(
  +                clazz,
  +                (ClazzInstanceFactory) parameter);
  +        }
  +    };
  +
  +    protected void fireInstanceFactoryAdded(ClazzInstanceFactory factory){
  +        FACTORY_ADDED_NOTIFIER.fire(this, factory);
  +    }
  +
  +    private static Notifier FACTORY_REMOVED_NOTIFIER = new Notifier() {
  +        void fire(Clazz clazz, ClazzChangeListener listener, Object parameter) {
  +            listener.instanceFactoryRemoved(
  +                clazz,
  +                (ClazzInstanceFactory) parameter);
  +        }
  +    };
  +
  +    protected void fireInstanceFactoryRemoved(ClazzInstanceFactory factory){
  +        FACTORY_REMOVED_NOTIFIER.fire(this, factory);
  +    }
  +
  +    //--- End notification mechanism
  +    
  +    
  +    /**
  +     * Creates a signature string out of an operation or instance factory name
  +     * and parameter types.
        */
  -    public abstract Object newInstance();
  +    public static String constructSignature(String name, Class[] arguments) {
  +        StringBuffer buffer = new StringBuffer();
  +        if (name != null){
  +            buffer.append(name);
  +        }
  +        buffer.append('(');
  +        if (arguments != null){
  +            for (int i = 0; i < arguments.length; i++) {
  +                if (i != 0){
  +                    buffer.append(',');
  +                }
  +                buffer.append(getCanonicalClassName(arguments[i]));
  +            }
  +        }
  +        buffer.append(')');
  +        return buffer.toString();
  +    }
   
       /**
  -     * Creates a new instance of this Clazz using the supplied parameters
  +     * Creates a signature string out of an operation or instance factory name
  +     * and parameter types.
        */
  -    public abstract Object newInstance(Object[] parameters);
  +    public static String constructSignature(String name, Clazz[] arguments) {
  +        StringBuffer buffer = new StringBuffer();
  +        if (name != null){
  +            buffer.append(name);
  +        }
  +        buffer.append('(');
  +        if (arguments != null){
  +            for (int i = 0; i < arguments.length; i++) {
  +                if (i != 0){
  +                    buffer.append(',');
  +                }
  +                buffer.append(arguments[i].getName());
  +            }
  +        }
  +        buffer.append(')');
  +        return buffer.toString();
  +    }
  +    
  +    /**
  +     * Produces a nice type name for a classes representing an array, e.g. "[I"
  +     * is shown as "int[]". For non-array types returns the regular type name.
  +     */
  +    public static String getCanonicalClassName(Class javaClass) {
  +        /*
  +         * This is basically a remake of java.lang.reflect.Field.getTypeName
  +         * (Class), which cannot be used directly as it is declared with the
  +         * default scope.
  + 		 */
  +        if (javaClass.isArray()){
  +            return getCanonicalClassName(javaClass.getComponentType()) + "[]";
  +        }
  +        return javaClass.getName();
  +    } 
   }
  
  
  
  1.3       +42 -3     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzLoader.java
  
  Index: ClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClazzLoader.java	6 Dec 2002 01:12:48 -0000	1.2
  +++ ClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.3
  @@ -63,10 +63,37 @@
    * @version $Id$
 */
   public abstract class ClazzLoader
   {
  +    private ClazzLoader parent;
  +     
  +    /**
  +     * ClazzLoaders are organized into hierarchies. If a lower-level ClazzLoader
  +     * cannot do a job, it delegates it to its parent.
  +     */
  +    public ClazzLoader(ClazzLoader parent) {
  +        this.parent = parent;
  +    }
  +
  +    public ClazzLoader getParentClazzLoader() {
  +        return parent;
  +    }
  +    
  +    /**
  +     * Returns the ancestor that does not have a parent.
  +     */
  +    public ClazzLoader getRootClazzLoader(){
  +        if (parent == null){
  +            return this;
  +        }
  +        return parent.getRootClazzLoader();
  +    }
  +    
       /**
        * Given a Clazz name, returns the corresponding Clazz. Does not
        * cache clazzes, that's the job of CachingGroupClazzLoader.  Return null if
        * there is no Clazz for this name.
  +     * <p>
  +     * Note that we use canonical class names for primitive types and arrays, 
  +     * e.g. "byte", "byte[]", "boolean[][]", "java.lang.String[]".
        */
       public abstract Clazz getClazzForName(String name);
   
  @@ -100,10 +127,22 @@
       
       /**
        * Defines a new Clazz with the supplied name.  If it cannot define a
  -     * clazz of the supplied type or it cannot define clazzes at all, returns
  +     * clazz of the supplied type or if it cannot define clazzes at all, returns
        * null.
  +     * 
  +     * @param name the name of the clazz, should be unique within the scope of
  +     * the top-level ClazzLoader
  +     * @param clazzClass the Class of the Clazz that this method needs to
  +     * produce.
  +     * @param instanceClass the Class of the instances the new Clazz will be
  +     * able to create using the <code>newInstance()</code> method.
  +     * 
  +     * @return Clazz
        */
  -    public abstract Clazz defineClazz(String name, Class clazzType);
  +    public abstract Clazz defineClazz(
  +        String name,
  +        Class clazzClass,
  +        Class instanceClass);
       
   
       private HashSet loggingEnabledClasses = new HashSet();
  
  
  
  1.3       +2 -2      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzNotFoundException.java
  
  Index: ClazzNotFoundException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzNotFoundException.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClazzNotFoundException.java	6 Dec 2002 01:12:48 -0000	1.2
  +++ ClazzNotFoundException.java	14 Dec 2002 02:38:41 -0000	1.3
  @@ -67,6 +67,6 @@
       }
       
       public String getMessage(){
  -        return "Clazz not found for instance of class " + className;
  +        return "Clazz not found: " + className;
       }
   }
  
  
  
  1.4       +3 -1      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzOperation.java
  
  Index: ClazzOperation.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzOperation.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ClazzOperation.java	6 Dec 2002 01:12:48 -0000	1.3
  +++ ClazzOperation.java	14 Dec 2002 02:38:41 -0000	1.4
  @@ -63,6 +63,8 @@
   
       String getSignature();
       
  +    String getName();
  +    
       Clazz[] getParameterClazzes();
       
       Clazz getReturnClazz();
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzAccessException.java
  
  Index: ClazzAccessException.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz;
  
  /**
   * Thrown when an attempt to invoke an method via reflection fails.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ClazzAccessException.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public class ClazzAccessException extends RuntimeException {
  
      private Throwable cause;
      
      /**
       * Constructor for ReflectedAccessException.
       */
      public ClazzAccessException() {
          super();
      }
  
      /**
       * Constructor for ReflectedAccessException.
       * @param s
       */
      public ClazzAccessException(String s) {
          super(s);
      }
      
      /**
       * Constructor for ReflectedAccessException.
       * @param s
       */
      public ClazzAccessException(String s, Throwable cause) {
          super(s);
          this.cause = cause;
      }
      
      public String getMessage(){
          if (cause == null){
              return super.getMessage();
          }
          return super.getMessage()+ "; " + cause.getMessage(); 
      }
      
      public Throwable getCause(){
          return cause;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzChangeListener.java
  
  Index: ClazzChangeListener.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ClazzChangeListener.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public interface ClazzChangeListener {
  
      void propertyAdded(Clazz clazz, ClazzProperty property);
      void propertyRemoved(Clazz clazz, ClazzProperty property);
      
      void operationAdded(Clazz clazz, ClazzOperation operation);
      void operationRemoved(Clazz clazz, ClazzOperation operation);
  
      void instanceFactoryAdded(Clazz clazz, ClazzInstanceFactory factory);
      void instanceFactoryRemoved(Clazz clazz, ClazzInstanceFactory factory);
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzInstanceFactory.java
  
  Index: ClazzInstanceFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz;
  
  /**
   * An object resposible for allocating new <b>instances</b> of a Clazz.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ClazzInstanceFactory.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public interface ClazzInstanceFactory extends ClazzFeature {
  
      /**
       * Creates a new instance.
       * @param parameters is the list of parameters. It can be null if the
       * factory takes no parameters.
       */
      Object newInstance(Object[] parameters);
      
      /**
       * Returns the name of the factory. May be null.
       */
      String getName();
      
      /**
       * Returns the factory parameter types.
       */
      Clazz[] getParameterClazzes();
      
      /**
       * Returns the signature of the factory in the format 
       * "factoryName(paramType1,...)", where "factoryName" may be empty.
       */
      String getSignature();
  }
  
  
  
  1.2       +18 -2     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BasicBean.java
  
  Index: BasicBean.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BasicBean.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BasicBean.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ BasicBean.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -54,12 +54,13 @@
   package org.apache.commons.clazz.bean;
   
   import java.util.HashMap;
  +import java.util.Iterator;
   import java.util.Map;
   
   import org.apache.commons.clazz.Clazz;
   
   /**
  - * 
  + * A trivial implementation of the Bean interface based on a HashMap.
    *
    * @author Dmitri Plotnikov
    * @version $Revision$ $Date$
  @@ -75,6 +76,21 @@
       public BasicBean(Clazz clazz) {
           this.clazz = clazz;
       }
  +
  +    /**
  +     * Constructor that initializes properties of the bean.
  +     */
  +    public BasicBean(Clazz clazz, Map initialPropertyValues) {
  +        this(clazz);
  +        for (Iterator iter = initialPropertyValues.entrySet().iterator();
  +            iter.hasNext();
  +            )
  +        {
  +            Map.Entry element = (Map.Entry) iter.next();
  +            set((String) element.getKey(), element.getValue());
  +        }
  +    }
  +
   
       /**
        * @see org.apache.commons.clazz.bean.Bean#getClazz()
  
  
  
  1.2       +275 -112  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazz.java
  
  Index: BeanClazz.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazz.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BeanClazz.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ BeanClazz.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -56,43 +56,52 @@
   import java.lang.reflect.Constructor;
   import java.util.ArrayList;
   import java.util.Collections;
  +import java.util.HashMap;
   import java.util.HashSet;
  +import java.util.Iterator;
   import java.util.List;
  +import java.util.Map;
   import java.util.Set;
   
   import org.apache.commons.clazz.Clazz;
  +import org.apache.commons.clazz.ClazzChangeListener;
  +import org.apache.commons.clazz.ClazzInstanceFactory;
   import org.apache.commons.clazz.ClazzLoader;
   import org.apache.commons.clazz.ClazzOperation;
   import org.apache.commons.clazz.ClazzProperty;
   
   /**
  - * Dynamically constructed Clazz.
  + * Dynamically constructed Clazz. BeanClazzes are created by invoking {@link
  + * ClazzLoader#defineClazz(String, Class, Class) clazzLoader.defineClazz (name,
  + * clazzClass, instanceClass)}.
    * 
    * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class BeanClazz extends Clazz {
  -
  +public class BeanClazz extends Clazz 
  +{
       private Clazz superClazz;
       private List declaredProperties = new ArrayList();
  +    private List properties = new ArrayList();
  +    private Map propertyMap = new HashMap();
       private List declaredOperations = new ArrayList();
  +    private List operations = new ArrayList();
  +    private Map operationMap = new HashMap();
  +    private List instanceFactories;
  +    private Map instanceFactoryMap = new HashMap();
       private Class instanceClass;
  -    private Constructor instanceConstructor;
  +    private List subclasses = new ArrayList();
       
       /**
        * Constructor for BeanClazz.
        * @param loader
        * @param name
  +     * @param instanceClass
        */
  -    public BeanClazz(ClazzLoader loader, String name) {
  -        this(loader, name, null);
  -    }
  -
       public BeanClazz(ClazzLoader loader, String name, Class instanceClass) {
           super(loader, name);
           this.instanceClass = instanceClass;
  -
       }
       
       public Class getInstanceClass(){
  @@ -106,27 +115,7 @@
           
           return BasicBean.class;
       }
  -    
  -    public Constructor getInstanceConstructor(){
  -        if (instanceConstructor == null) {
  -            Class instanceClass = getInstanceClass();
  -            try {
  -                instanceConstructor =
  -                    instanceClass.getConstructor(new Class[] { Clazz.class });
  -                
  -            }
  -            catch (NoSuchMethodException e) {
  -                throw new BeanClazzException(
  -                    "No constructor "
  -                        + instanceClass.getName()
  -                        + "("
  -                        + Clazz.class.getName()
  -                        + ")");
  -            }
  -        }
  -        return instanceConstructor;
  -    }
  -    
  +        
       /**
        * @see org.apache.commons.clazz.Clazz#getSuperclazz()
        */
  @@ -135,9 +124,71 @@
       }
   
       public void setSuperclazz(Clazz clazz) {
  +        if (superClazz != null){
  +            superClazz.removeClazzChangeListener(listener);           
  +        }
           superClazz = clazz;
  +        if (clazz != null){
  +            superClazz.addClazzChangeListener(listener);
  +        }
  +        refreshAllCaches();
       }
  -    
  +
  +    protected void refreshAllCaches(){
  +        refreshPropertyCache();
  +        refreshOperationCache();
  +    }
  +
  +    protected void refreshPropertyCache(){
  +        properties = new ArrayList();
  +        propertyMap = new HashMap();
  +        
  +        Set propertyNames = new HashSet();
  +        if (superClazz != null) {
  +            List superProperties = superClazz.getProperties();
  +            properties.addAll(superProperties);
  +            for (int i = 0; i < superProperties.size(); i++) {
  +                ClazzProperty superProperty =
  +                    (ClazzProperty) superProperties.get(i);
  +                propertyNames.add(superProperty.getName());
  +            }
  +        }
  +        for (int i = 0; i < declaredProperties.size(); i++) {
  +            ClazzProperty property = (ClazzProperty) declaredProperties.get(i);
  +            String name = property.getName();
  +            if (!propertyNames.contains(name)) {
  +                properties.add(property);
  +            }
  +        }
  +        
  +        for (Iterator iter = properties.iterator(); iter.hasNext();) {
  +            ClazzProperty property = (ClazzProperty) iter.next();
  +            propertyMap.put(property.getName(), property);
  +        }
  +    }
  + 
  +    protected void refreshOperationCache(){
  +        List operations = new ArrayList();
  +        Set signatures = new HashSet();
  +        if (superClazz != null) {
  +            List superOperations = superClazz.getOperations();
  +            operations.addAll(superOperations);
  +            for (int i = 0; i < superOperations.size(); i++) {
  +                ClazzOperation superOperation =
  +                    (ClazzOperation) superOperations.get(i);
  +                signatures.add(superOperation.getSignature());
  +            }
  +        }
  +        for (int i = 0; i < declaredOperations.size(); i++) {
  +            ClazzOperation operation =
  +                (ClazzOperation) declaredOperations.get(i);
  +            String signature = operation.getSignature();
  +            if (!signatures.contains(signature)) {
  +                operations.add(operation);
  +            }
  +        }
  +    }
  +           
       /**
        * @see org.apache.commons.clazz.Clazz#getDeclaredProperties()
        */
  @@ -147,42 +198,63 @@
       
       public void addDeclaredProperty(ClazzProperty property){
           if (property.getDeclaringClazz() != this) {
  -            throw new BeanClazzException(
  +            throw new BeanClazzConfigurationException(
                   "Property belongs to a different clazz: "
                       + property.getDeclaringClazz().getName());
           }
  -        // @todo: maybe check for duplicate names
  +        
  +        ClazzProperty oldProperty =
  +            (ClazzProperty) propertyMap.get(property.getName());
  +        if (oldProperty != null) {
  +            removeDeclaredProperty(oldProperty);
  +        }
  +        
           declaredProperties.add(property);
  +
  +        addProperty(property);
  +    }
  +    
  +    /**
  +     * Called indirectly when declared properties are manipulated.
  +     */
  +    protected void addProperty(ClazzProperty property){
  +        properties.add(property);
  +        propertyMap.put(property.getName(), property);
  +        firePropertyAdded(property);
       }
       
       public void removeDeclaredProperty(ClazzProperty property){
  -        declaredProperties.remove(property);
  +        String name = property.getName();
  +        property = (ClazzProperty)propertyMap.get(name);
  +        if (property != null){
  +            declaredProperties.remove(property);
  +            removeProperty(property);
  +        }
  +    }
  +
  +    /**
  +     * Called indirectly when declared properties are manipulated.
  +     */    
  +    protected void removeProperty(ClazzProperty property){
  +        String name = property.getName();
  +        properties.remove(property);
  +        propertyMap.remove(name);
  +        firePropertyRemoved(property);
  +        
  +        // By deleting this declared property, we may have exposed 
  +        // an inherited one
  +        if (superClazz != null){
  +            property = superClazz.getProperty(name);
  +            if (property != null){
  +                addProperty(property);
  +            } 
  +        }
       }
   
       /**
        * @see org.apache.commons.clazz.Clazz#getProperties()
        */
       public List getProperties() {
  -        // @todo: cache and refresh cache as needed
  -
  -        List properties = new ArrayList();
  -        Set propertyNames = new HashSet();
  -        if (superClazz != null) {
  -            List superProperties = superClazz.getProperties();
  -            properties.addAll(superProperties);
  -            for (int i = 0; i < superProperties.size(); i++) {
  -                ClazzProperty superProperty =
  -                    (ClazzProperty) superProperties.get(i);
  -                propertyNames.add(superProperty.getName());
  -            }
  -        }
  -        for (int i = 0; i < declaredProperties.size(); i++) {
  -            ClazzProperty property = (ClazzProperty) declaredProperties.get(i);
  -            String name = property.getName();
  -            if (!propertyNames.contains(name)) {
  -                properties.add(property);
  -            }
  -        }
           return properties;
       }
   
  @@ -190,17 +262,7 @@
        * @see org.apache.commons.clazz.Clazz#getProperty(java.lang.String)
        */
       public ClazzProperty getProperty(String name) {
  -        for (int i = 0; i < declaredProperties.size(); i++){
  -            ClazzProperty property = (ClazzProperty)declaredProperties.get(i);
  -            String aName = property.getName();
  -            if (aName.equals(name)){
  -                return property;
  -            }
  -        }
  -        if (superClazz != null){
  -            return superClazz.getProperty(name);
  -        }
  -        return null;
  +        return (ClazzProperty)propertyMap.get(name);
       }
   
       /**
  @@ -212,44 +274,63 @@
   
       public void addDeclaredOperation(ClazzOperation operation){
           if (operation.getDeclaringClazz() != this) {
  -            throw new BeanClazzException(
  +            throw new BeanClazzConfigurationException(
                   "Operation belongs to a different clazz: "
                       + operation.getDeclaringClazz().getName());
           }
           
  -        // @todo: maybe check for duplicate signatures
  +        ClazzOperation oldOperation =
  +            (ClazzOperation) operationMap.get(operation.getSignature());
  +        if (oldOperation != null) {
  +            removeDeclaredOperation(oldOperation);
  +        }
  +
           declaredOperations.add(operation);
  +
  +        addOperation(operation);
  +    }
  +
  +    /**
  +     * Called indirectly when declared operations are manipulated.
  +     */
  +    protected void addOperation(ClazzOperation operation){
  +        operations.add(operation);
  +        operationMap.put(operation.getSignature(), operation);
  +        fireOperationAdded(operation);
       }
   
       public void removeDeclaredOperation(ClazzOperation operation){
  -        declaredOperations.remove(operation);
  +        String signature = operation.getSignature();
  +        operation = (ClazzOperation)operationMap.get(signature);
  +        if (operation != null){
  +            declaredOperations.remove(operation);
  +            removeOperation(operation);
  +        }
       }
   
       /**
  -     * @see org.apache.commons.clazz.Clazz#getOperations()
  +     * Called indirectly when declared operations are manipulated.
        */
  -    public List getOperations() {
  -        // @todo: cache and refresh cache as needed
  +    protected void removeOperation(ClazzOperation operation){
  +        String signature = operation.getSignature();
  +        operations.remove(operation);
  +        operationMap.remove(signature);
  +        fireOperationRemoved(operation);
   
  -        List operations = new ArrayList();
  -        Set signatures = new HashSet();
  -        if (superClazz != null) {
  -            List superOperations = superClazz.getOperations();
  -            operations.addAll(superOperations);
  -            for (int i = 0; i < superOperations.size(); i++) {
  -                ClazzOperation superOperation =
  -                    (ClazzOperation) superOperations.get(i);
  -                signatures.add(superOperation.getSignature());
  -            }
  -        }
  -        for (int i = 0; i < declaredOperations.size(); i++) {
  -            ClazzOperation operation =
  -                (ClazzOperation) declaredProperties.get(i);
  -            String signature = operation.getSignature();
  -            if (!signatures.contains(signature)) {
  -                operations.add(operation);
  +        // By deleting this declared operation, we may have exposed
  +        // an inherited one
  +        if (superClazz != null){
  +            operation = superClazz.getOperation(signature);
  +            if (operation != null){
  +                addOperation(operation);
               }
           }
  +    }
  +
  +    /**
  +     * @see org.apache.commons.clazz.Clazz#getOperations()
  +     */
  +    public List getOperations() {
           return operations;
       }
   
  @@ -257,39 +338,121 @@
        * @see org.apache.commons.clazz.Clazz#getOperation(java.lang.String)
        */
       public ClazzOperation getOperation(String signature) {
  -        // @todo: must cache
  -        for (int i = 0; i < declaredOperations.size(); i++){
  -            ClazzOperation operation = (ClazzOperation)declaredOperations.get(i);
  -            String aSignature = operation.getSignature();
  -            if (!aSignature.equals(signature)){
  -                return operation;
  -            }
  -        }
  -        if (superClazz != null){
  -            return superClazz.getOperation(signature);
  +        return (ClazzOperation)operationMap.get(signature);
  +    }
  +
  +    /**
  +     * @see org.apache.commons.clazz.Clazz#getInstanceFactories()
  +     */
  +    public List getInstanceFactories() {
  +        if (instanceFactories == null){
  +            introspectInstanceFactories();
           }
  -        return null;
  +        return Collections.unmodifiableList(instanceFactories);
       }
   
       /**
  -     * @see org.apache.commons.clazz.Clazz#newInstance()
  +     * @see org.apache.commons.clazz.Clazz#getInstanceFactory(java.lang.String)
        */
  -    public Object newInstance() {      
  -        try {
  -            return getInstanceConstructor().newInstance(new Object[]{this});
  +    public ClazzInstanceFactory getInstanceFactory(String signature) {
  +        if (instanceFactories == null){
  +            introspectInstanceFactories();
  +        }
  +
  +        return (ClazzInstanceFactory)instanceFactoryMap.get(signature);
  +    }
  +
  +    public void addInstanceFactory(ClazzInstanceFactory factory){
  +        if (factory.getDeclaringClazz() != this) {
  +            throw new BeanClazzConfigurationException(
  +                "Instance factory belongs to a different clazz: "
  +                    + factory.getDeclaringClazz().getName());
  +        }
  +
  +        if (instanceFactories == null){
  +            introspectInstanceFactories();
  +        }
  +        ClazzInstanceFactory oldFactory =
  +            (ClazzInstanceFactory) instanceFactoryMap.get(
  +                factory.getSignature());
  +        if (oldFactory != null){
  +            removeInstanceFactory(oldFactory);
           }
  -        catch (Throwable e) {
  -            e.printStackTrace();
  -            throw new BeanClazzException(
  -                "Cannot instantiate " + getInstanceClass(),
  -                e);
  +        instanceFactories.add(factory);
  +        instanceFactoryMap.put(factory.getSignature(), factory); 
  +        fireInstanceFactoryAdded(factory);
  +    }
  +    
  +    public void removeInstanceFactory(ClazzInstanceFactory factory){
  +        if (instanceFactories.remove(factory)){
  +            instanceFactoryMap.remove(factory.getSignature());
  +            fireInstanceFactoryRemoved(factory);
           }
       }
   
       /**
  -     * @see org.apache.commons.clazz.Clazz#newInstance(java.lang.Object)
  +     * Finds all constructors of the <code>instanceClass</code> that have at
  +     * least one argument and the first argument is of type Clazz. Wraps
  +     * each of those constructors into
  +     * a {@link BeanClazzConstructorInstanceFactory
  +     * BeanClazzConstructorInstanceFactory} and registers it as an
  +     * InstanceFactory for this clazz.
        */
  -    public Object newInstance(Object[] parameters) {
  -        return null;
  +    private void introspectInstanceFactories() {
  +        instanceFactories = new ArrayList();
  +        Class instanceClass = getInstanceClass();
  +        Constructor constructors[] = instanceClass.getConstructors();
  +        for (int i = 0; i < constructors.length; i++) {
  +            Class[] parameterTypes = constructors[i].getParameterTypes();
  +            if (parameterTypes != null
  +                    && parameterTypes.length >= 1
  +                    && Clazz.class.isAssignableFrom(parameterTypes[0])) {
  +                addInstanceFactory(
  +                    new BeanClazzConstructorInstanceFactory(
  +                        this,
  +                        constructors[i]));
  +            }
  +        }
       }
  +    
  +    private ClazzChangeListener listener = new ClazzChangeListener()
  +    {
  +        public void propertyAdded(Clazz clazz, ClazzProperty property) {
  +            if (propertyMap.get(property.getName()) == null){
  +                addProperty(property);
  +            }
  +        }
  +        
  +        public void propertyRemoved(Clazz clazz, ClazzProperty property) {
  +            ClazzProperty declared =
  +                (ClazzProperty) propertyMap.get(property.getName());
  +            if (declared != null && declared.equals(property)){
  +                removeProperty(property);
  +            }
  +        }
  +        
  +        public void operationAdded(Clazz clazz, ClazzOperation operation) {
  +            if (operationMap.get(operation.getSignature()) == null){
  +                addOperation(operation);
  +            }
  +        }
  +        
  +        public void operationRemoved(Clazz clazz, ClazzOperation operation) {
  +            ClazzOperation declared =
  +                (ClazzOperation) operationMap.get(operation.getSignature());
  +            if (declared != null && declared.equals(operation)){
  +                removeOperation(operation);
  +            }
  +        }
  +        
  +        public void instanceFactoryAdded(
  +                Clazz clazz, ClazzInstanceFactory property) {
  +            // Ignore - factories are not inherited
  +        }
  +        
  +        public void instanceFactoryRemoved(
  +                Clazz clazz, ClazzInstanceFactory property) {
  +            // Ignore - factories are not inherited
  +        }
  +    };
   }
  
  
  
  1.2       +21 -12    jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzLoader.java
  
  Index: BeanClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BeanClazzLoader.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ BeanClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -57,7 +57,6 @@
   
   import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzLoader;
  -import org.apache.commons.clazz.common.GroupClazzLoader;
   
   /**
    * 
  @@ -66,10 +65,8 @@
    */
   public class BeanClazzLoader extends ClazzLoader {
       
  -    private GroupClazzLoader group;
  -    
  -    public BeanClazzLoader(GroupClazzLoader group){
  -        this.group = group;
  +    public BeanClazzLoader(ClazzLoader parent){
  +        super(parent);
       }
   
       /**
  @@ -87,27 +84,39 @@
           return ((Bean)instance).getClazz().getName();
       }
           
  +    /**
  +     * BeanClazzLoader does not cache clazzes, its parent, BeanGroupClazzLoader,
  +     * is responsible for caching
  +     */
       public Clazz getClazzForName(String clazzName){
  -        // BeanClazzLoader does not cache clazzes, 
  -        // BeanGroupClazzLoader is responsible for caching
           return null;
       }
       
       /**
        * @see org.apache.commons.clazz.ClazzLoader#defineClazz(java.lang.String, java.lang.Class)
        */
  -    public Clazz defineClazz(String name, Class clazzType) {
  +    public Clazz defineClazz(String name, Class clazzType, Class instanceClass) {
           if (!BeanClazz.class.isAssignableFrom(clazzType)) {
               return null;
           }
           try {
               Constructor constructor =
                   clazzType.getConstructor(
  -                    new Class[] { ClazzLoader.class, String.class });
  -            return (Clazz) constructor.newInstance(new Object[] { this, name });
  +                    new Class[] {
  +                        ClazzLoader.class,
  +                        String.class,
  +                        Class.class });
  +            return (Clazz) constructor.newInstance(
  +                new Object[] { getRootClazzLoader(), name, instanceClass });
           }
           catch (Exception e) {
  -            throw new BeanClazzException("Cannot define clazz " + name, e);
  +            e.printStackTrace();
  +            throw new BeanClazzConfigurationException(
  +                "Cannot define clazz "
  +                    + name
  +                    + " of clazz type "
  +                    + clazzType.getName(),
  +                e);
           }
       }
   }
  
  
  
  1.2       +1 -18     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzProperty.java
  
  Index: BeanClazzProperty.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzProperty.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BeanClazzProperty.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ BeanClazzProperty.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -70,14 +70,6 @@
       private String type;
       private Clazz clazz;
       
  -    /**
  -     * Constructor for BeanClazzProperty.
  -     * @param declaringClazz
  -     */
  -    public BeanClazzProperty(Clazz declaringClazz) {
  -        this(declaringClazz, generatePropertyName(declaringClazz));
  -    }
  -
       public BeanClazzProperty(Clazz declaringClazz, String name) {
           this(declaringClazz, name, Object.class.getName());
       }
  @@ -86,15 +78,6 @@
           super(declaringClazz);
           this.name = name;
           this.clazzName = type;
  -    }
  -    
  -    private static String generatePropertyName(Clazz declaringClazz){
  -        int index = 1;
  -        String name = "property1";
  -        while (declaringClazz.getProperty(name) != null){
  -            name = "property" + (++index);
  -        }
  -        return name;
       }
       
       /**
  
  
  
  1.2       +6 -1      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanGroupClazzLoader.java
  
  Index: BeanGroupClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanGroupClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BeanGroupClazzLoader.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ BeanGroupClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -53,6 +53,7 @@
    */
   package org.apache.commons.clazz.bean;
   
  +import org.apache.commons.clazz.ClazzLoader;
   import org.apache.commons.clazz.common.GroupClazzLoader;
   
   /**
  @@ -61,6 +62,10 @@
    * @version $Id$
    */
   public class BeanGroupClazzLoader extends GroupClazzLoader {
  +
  +    public BeanGroupClazzLoader(ClazzLoader parent){
  +        super(parent);
  +    }
   
       public boolean isMember(Object instance) {
           // This is just an optimization - the Group can answer for all
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzConfigurationException.java
  
  Index: BeanClazzConfigurationException.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.bean;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzConfigurationException.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public class BeanClazzConfigurationException extends RuntimeException {
  
      private Throwable cause;
      
      /**
       * Constructor for BeanClazzConfigurationException.
       */
      public BeanClazzConfigurationException() {
          super();
      }
  
      /**
       * Constructor for BeanClazzConfigurationException.
       * @param s
       */
      public BeanClazzConfigurationException(String s) {
          super(s);
      }
      
      /**
       * Constructor for ReflectedAccessException.
       * @param s
       */
      public BeanClazzConfigurationException(String s, Throwable cause) {
          super(s);
          this.cause = cause;
      }
  
      public String getMessage(){
          if (cause == null){
              return super.getMessage();
          }
          return super.getMessage() + "; " + cause.getMessage();
      }
  
      public Throwable getCause(){
          return cause;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzConstructorInstanceFactory.java
  
  Index: BeanClazzConstructorInstanceFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.bean;
  
  import java.lang.reflect.Constructor;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzAccessException;
  import org.apache.commons.clazz.ClazzInstanceFactory;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  
  /**
   * An instance factory based on a Constructor. The first argument of the
   * Constructor is always of type <code>Clazz</code>. This parameter is not
   * included in the factory signature.
   *  
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzConstructorInstanceFactory.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public class BeanClazzConstructorInstanceFactory extends ClazzFeatureSupport
         implements ClazzInstanceFactory 
  {
  
      // Though this class is very similar to ReflectedConstructorInstanceFactory,
      // we have a separate implementation because the first parameter (Clazz) of
      // the constructor is ignored here and that affects almost every method.
  
      private Constructor constructor;
      private Class visibleParameterTypes[];
      private String signature;
      private Clazz[] parameterClazzes;
  
      /**
       * Constructor for ReflectedClazzProperty.
       */
      public BeanClazzConstructorInstanceFactory(
              Clazz declaringClazz,
              Constructor constructor)
      {
          super(declaringClazz);
          this.constructor = constructor;
      }
  
      public Constructor getConstructor(){
          return constructor;
      }
  
      public String getName(){
          return null;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getSignature()
       */
      public String getSignature() {
          if (signature == null) {
              signature =
                  Clazz.constructSignature(null, getVisibleParameterTypes());
          }
          return signature;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getParameterClazzes()
       */
      public Clazz[] getParameterClazzes() {
          if (parameterClazzes == null){
              Class paramClasses[] = getVisibleParameterTypes();
              parameterClazzes = new Clazz[paramClasses.length];
              ClazzLoader loader = getDeclaringClazz().getClazzLoader();
              for (int i = 0; i < paramClasses.length; i++){
                  String name = Clazz.getCanonicalClassName(paramClasses[i]);
                  parameterClazzes[i] = loader.getClazzForName(name);
              }
          }
          return parameterClazzes;
      }
  
      private Class[] getVisibleParameterTypes() {
          Class parameterTypes[] = constructor.getParameterTypes();
          visibleParameterTypes = new Class[parameterTypes.length - 1];
          for (int i = 1; i < parameterTypes.length; i++) {
              visibleParameterTypes[i - 1] = parameterTypes[i];
          }
          return visibleParameterTypes;
      }
      
      public Object newInstance(Object[] parameters) {
          try {
              // Insert the declaring clazz as the invisible first parameter
              int length = (parameters == null ? 0 : parameters.length);
              Object allParameters[] = new Object[length+1];
              allParameters[0] = getDeclaringClazz();
              for (int i = 0; i < length; i++) {
                  allParameters[i+1] = parameters[i];
              }
              return constructor.newInstance(allParameters);
          }
          catch (Throwable e) {
              throw new ClazzAccessException(
                  "Cannot invoke constructor " + getSignature(),
                  e);
          }
      }
  
      public String toString(){
          return getSignature();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzInstanceFactory.java
  
  Index: BeanClazzInstanceFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.bean;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzInstanceFactory;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzInstanceFactory.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public abstract class BeanClazzInstanceFactory
      extends ClazzFeatureSupport
      implements ClazzInstanceFactory 
  {
      private String name;
      private final String[] EMPTY_STRING_ARRAY = new String[0];
      private String[] parameterClazzNames;
      private Clazz[] parameterClazzes;
      private String signature;
      
      public BeanClazzInstanceFactory(
              Clazz declaringClazz,
              String parameterClazzNames[])
      {
          this(declaringClazz, null, parameterClazzNames);
      }
      
      /**
       * Constructor for BeanClazzInstanceFactory.
       * @param declaringClazz
       */
      public BeanClazzInstanceFactory(
              Clazz declaringClazz,
              String name,
              String parameterClazzNames[]) 
      {
          super(declaringClazz);
          this.name = name;
          this.parameterClazzNames = parameterClazzNames;
          this.parameterClazzNames =
              (parameterClazzNames != null
                  ? parameterClazzNames
                  : EMPTY_STRING_ARRAY);
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzInstanceFactory#getName()
       */
      public String getName() {
          return name;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzInstanceFactory#getParameterClazzes()
       */
      public Clazz[] getParameterClazzes() {
          if (parameterClazzes == null) {
              parameterClazzes = new Clazz[parameterClazzNames.length];
              ClazzLoader loader = getDeclaringClazz().getClazzLoader();
              for (int i = 0; i < parameterClazzes.length; i++) {
                  parameterClazzes[i] =
                      loader.getClazzForName(parameterClazzNames[i]);
                  if (parameterClazzes[i] == null){
                      throw new BeanClazzConfigurationException(
                          "Invalid argument type: "
                              + parameterClazzNames[i]
                              + ". Clazz not found.");
                  }
              }
          }
  
          return parameterClazzes;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzInstanceFactory#getSignature()
       */
      public String getSignature() {
          if (signature == null) {
              signature = Clazz.constructSignature(name, getParameterClazzes());
          }
          return signature;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzOperaiton.java
  
  Index: BeanClazzOperaiton.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.bean;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.ClazzOperation;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzOperaiton.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public abstract class BeanClazzOperaiton
      extends ClazzFeatureSupport
      implements ClazzOperation 
  {
      private String returnClazzName;
      private Clazz returnClazz;
      private String name;
      private final String[] EMPTY_STRING_ARRAY = new String[0];
      private String[] parameterClazzNames;
      private Clazz[] parameterClazzes;
      private String signature;
      
      /**
       * Method BeanClazzOperaiton.
       * @param declaringClazz the Clazz this Operation belongs to
       * @param returnClazz the return type of the operation, pass
       * <code>null</code> for <code>void</code>.
       * @param name the name of the operation.
       * @param parameterTypes types of operation parameters, pass
       * <code>null</code> if the operation does not take any parameters.
       */
      public BeanClazzOperaiton(
              Clazz declaringClazz,
              String returnClazzName,
              String name,
              String[] parameterClazzNames) 
      {
          super(declaringClazz);
          this.returnClazzName = returnClazzName;
          this.name = name;
          this.parameterClazzNames =
              (parameterClazzNames != null
                  ? parameterClazzNames
                  : EMPTY_STRING_ARRAY);
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getSignature()
       */
      public String getSignature() {
          if (signature == null) {
              signature = Clazz.constructSignature(name, getParameterClazzes());            
          }
  
          return signature;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getName()
       */
      public String getName() {
          return name;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getParameterClazzes()
       */
      public Clazz[] getParameterClazzes() {
          if (parameterClazzes == null) {
              parameterClazzes = new Clazz[parameterClazzNames.length];
              ClazzLoader loader = getDeclaringClazz().getClazzLoader();
              for (int i = 0; i < parameterClazzes.length; i++) {
                  parameterClazzes[i] =
                      loader.getClazzForName(parameterClazzNames[i]);
                  if (parameterClazzes[i] == null){
                      throw new BeanClazzConfigurationException(
                          "Invalid argument type: "
                              + parameterClazzNames[i]
                              + ". Clazz not found.");
                  }
              }
          }
  
          return parameterClazzes;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getReturnClazz()
       */
      public Clazz getReturnClazz() {
          if (returnClazzName == null){
              return null;
          }
          
          if (returnClazz == null) {
              ClazzLoader loader = getDeclaringClazz().getClazzLoader();
              returnClazz = loader.getClazzForName(returnClazzName);            
          }
  
          return returnClazz;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#invoke(java.lang.Object, java.lang.Object)
       */
      public abstract Object invoke(Object target, Object[] parameters);
  }
  
  
  
  1.2       +13 -4     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/CachingGroupClazzLoader.java
  
  Index: CachingGroupClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/CachingGroupClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CachingGroupClazzLoader.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ CachingGroupClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -56,6 +56,7 @@
   import java.util.HashMap;
   
   import org.apache.commons.clazz.Clazz;
  +import org.apache.commons.clazz.ClazzLoader;
   
   /**
    * An implementation of <code>GroupClazzLoader</code> that caches clazzes by
  @@ -67,6 +68,10 @@
   public class CachingGroupClazzLoader extends GroupClazzLoader {
   
       private HashMap clazzMap = new HashMap();
  +
  +    public CachingGroupClazzLoader(ClazzLoader parent){
  +        super(parent);
  +    }
       
       /**
        * @see org.apache.commons.clazz.ClazzLoader#getClazzForName(java.lang.
  @@ -86,9 +91,13 @@
       /**
        * @see org.apache.commons.clazz.ClazzLoader#defineClazz(java.lang.String, java.lang.Class)
        */
  -    public Clazz defineClazz(String name, Class clazzType) {
  -        Clazz clazz = super.defineClazz(name, clazzType);
  -        if (clazz != null){
  +    public Clazz defineClazz(
  +            String name,
  +            Class clazzType,
  +            Class instanceClass) 
  +    {
  +        Clazz clazz = super.defineClazz(name, clazzType, instanceClass);
  +        if (clazz != null) {
               clazzMap.put(name, clazz);
           }
           return clazz;
  
  
  
  1.2       +14 -6     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/GroupClazzLoader.java
  
  Index: GroupClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/GroupClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- GroupClazzLoader.java	6 Dec 2002 01:12:48 -0000	1.1
  +++ GroupClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -70,6 +70,10 @@
   {
       private ArrayList loaders = new ArrayList();
   
  +    public GroupClazzLoader(ClazzLoader parent){
  +        super(parent);
  +    }
  +    
       /**
        * Returns true iff this group has a member loader that has or can construct
        * a Clazz for the supplied instance.
  @@ -117,13 +121,17 @@
       /**
        * @see org.apache.commons.clazz.ClazzLoader#defineClazz(java.lang.String, java.lang.Class)
        */
  -    public Clazz defineClazz(String name, Class clazzType) {
  +    public Clazz defineClazz(
  +            String name,
  +            Class clazzClass,
  +            Class instanceClass) 
  +    {
           Clazz clazz = null;
           // Note the reverse order
  -        for (int i = loaders.size(); --i >= 0; ){
  -            ClazzLoader loader = (ClazzLoader)loaders.get(i);
  -            clazz = loader.defineClazz(name, clazzType);
  -            if (clazz != null){
  +        for (int i = loaders.size(); --i >= 0;) {
  +            ClazzLoader loader = (ClazzLoader) loaders.get(i);
  +            clazz = loader.defineClazz(name, clazzClass, instanceClass);
  +            if (clazz != null) {
                   break;
               }
           }
  
  
  
  1.3       +171 -32   jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedClazz.java
  
  Index: ReflectedClazz.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedClazz.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReflectedClazz.java	6 Dec 2002 01:12:49 -0000	1.2
  +++ ReflectedClazz.java	14 Dec 2002 02:38:41 -0000	1.3
  @@ -65,30 +65,57 @@
    */
   public class ReflectedClazz extends Clazz {
   
  +    private Class instanceClass;
       private ReflectedPropertyIntrospector[] propertyIntrospectors;
  +    private ReflectedOperationIntrospector[] operationIntrospectors;
  +    private ReflectedInstanceFactoryIntrospector[] factoryIntrospectors;
       private boolean superClazzKnown;
       private Clazz superClazz;
  -    private Class javaClass;
  +    
  +    /**
  +     * This map includes all properties, declared and inherited
  +     */
       private Map propertyMap;
       private List propertyList;
       private List declaredPropertyList;
       
       /**
  +     * This map includes all operations, declared and inherited
  +     */
  +    private Map operationMap;
  +    private List operationList;
  +    private List declaredOperationList;
  +    
  +    /**
  +     * This map includes all factories
  +     */
  +    private Map factoryMap;
  +    private List factoryList;
  +
  +    /**
        * 
        * @param loader
  -     * @param javaClass
  +     * @param instanceClass
        * @param propertyIntrospectors The order of introspectors is significant,
        * they are invoked sequencially. Once a property has been recoginzed by an
        * introspector, it will not be overridden by subsequently invoked ones.
        */
       public ReflectedClazz(
               ClazzLoader loader,
  -            Class javaClass,
  -            ReflectedPropertyIntrospector[] propertyIntrospectors) 
  +            Class instanceClass,
  +            ReflectedPropertyIntrospector[] propertyIntrospectors,
  +            ReflectedOperationIntrospector[] operationIntrospectors,
  +            ReflectedInstanceFactoryIntrospector[] factoryIntrospectors) 
       {
  -        super(loader, javaClass.getName());
  +        super(loader, getCanonicalClassName(instanceClass));
           this.propertyIntrospectors = propertyIntrospectors;
  -        this.javaClass = javaClass;
  +        this.operationIntrospectors = operationIntrospectors;
  +        this.factoryIntrospectors = factoryIntrospectors;
  +        this.instanceClass = instanceClass;
  +    }
  +    
  +    public Class getInstanceClass(){
  +        return instanceClass;
       }
       
       /**
  @@ -100,7 +127,7 @@
       /**
        * Returns the class this ReflectedClazz is based upon.
     * @return Class
     */
       public Class getReflectedClass(){
  -        return javaClass;
  +        return instanceClass;
       }
       
       /**
  @@ -109,7 +136,7 @@
       public Clazz getSuperclazz() {
           if (!superClazzKnown){
               superClazzKnown = true;
  -            Class superclass = javaClass.getSuperclass();
  +            Class superclass = instanceClass.getSuperclass();
               if (superclass == null){
                   superClazz = null;
               }
  @@ -132,7 +159,7 @@
        */
       public List getDeclaredProperties() {
           if (declaredPropertyList == null){
  -            if (javaClass.getSuperclass() == null){
  +            if (instanceClass.getSuperclass() == null){
                   declaredPropertyList = getProperties();
               }
               else {
  @@ -182,11 +209,16 @@
           return (ClazzProperty)propertyMap.get(name);
       }
   
  -    protected void addProperty(ReflectedProperty property){
  +    protected void addProperty(ClazzProperty property){
  +        if (property.getName().equals("ter")){
  +            new Exception().printStackTrace();
  +        }
           propertyMap.put(property.getName(), property);
  -        String[] aliases = property.getAliases();
  -        for (int i = 0; i < aliases.length; i++) {
  -            propertyMap.put(aliases[i], property);
  +        if (property instanceof ReflectedProperty){
  +            String[] aliases = ((ReflectedProperty)property).getAliases();
  +            for (int i = 0; i < aliases.length; i++) {
  +                propertyMap.put(aliases[i], property);
  +            }
           }
           propertyList.add(property);
       }
  @@ -194,42 +226,84 @@
       /**
        */
       public List getOperations() {
  -        return null;
  +        if (operationList == null){
  +            introspectOperations();
  +        }
  +        return operationList;
       }
   
       /**
        * @see org.apache.commons.clazz.Clazz#getDeclaredOperations()
        */
       public List getDeclaredOperations() {
  -        return null;
  +        if (declaredOperationList == null){
  +            introspectOperations();
  +        }
  +        return declaredOperationList;
       }
   
       /**
        * @see org.apache.commons.clazz.Clazz#getOperation(java.lang.String)
        */
       public ClazzOperation getOperation(String signature) {
  -        return null;
  +        if (operationMap == null){
  +            introspectOperations();
  +        }
  +        return (ClazzOperation)operationMap.get(signature);
  +    }
  +
  +    protected void addOperation(ClazzOperation operation){
  +        operationMap.put(operation.getSignature(), operation);
  +        declaredOperationList.add(operation);
  +    }
  +
  +    /**
  +     * Returns all InstanceFactories for this clazz.
  +     */
  +    public List getInstanceFactories(){
  +        if (factoryList == null){
  +            introspectInstanceFactories();
  +        }
  +        return factoryList;
       }
   
       /**
  -     * @see org.apache.commons.clazz.Clazz#newInstance()
  +     * Returns the InstanceFactories that match the Predicate.
        */
  -    public Object newInstance() {
  -        try {
  -            return javaClass.newInstance();
  +//    public List getInstanceFactories(Predicate predicate);
  +
  +    /**
  +     * @see org.apache.commons.clazz.Clazz#getInstanceFactory(java.lang.String)
  +     */
  +    public ClazzInstanceFactory getInstanceFactory(String signature){
  +        if (factoryMap == null){
  +            introspectInstanceFactories();
           }
  -        catch (Throwable e) {
  -            throw new ReflectedAccessException(
  -                "Cannot create instance of clazz " + getName(),
  -                e);
  +        if (signature == null) {
  +            signature = "()";
           }
  +        return (ClazzInstanceFactory)factoryMap.get(signature);
  +    }
  +
  +    protected void addInstanceFactory(ClazzInstanceFactory factory){
  +        factoryMap.put(factory.getSignature(), factory);
  +        factoryList.add(factory);
       }
   
       /**
  -     * @see org.apache.commons.clazz.Clazz#newInstance(java.lang.Object)
  +     * Overrides the default implementation, checks if the supplied clazz is
  +     * also a ReflectedClazz and if so invokes isAssignableFrom on the
  +     * corresponding java classes.
        */
  -    public Object newInstance(Object[] parameters) {
  -        return null;
  +    public boolean isAssignableFrom(Clazz clazz){
  +        if (clazz == this) {
  +            return true;
  +        }
  +        if (clazz instanceof ReflectedClazz) {
  +            return getReflectedClass().isAssignableFrom(
  +                ((ReflectedClazz) clazz).getReflectedClass());
  +        }
  +        return super.isAssignableFrom(clazz);
       }
   
       /**
  @@ -238,15 +312,16 @@
        */   
       protected void introspectProperties()
       {
  -        propertyMap = new HashMap();
           propertyList = new ArrayList();
  +        propertyMap = new HashMap();
   
           for (int i = 0; i < propertyIntrospectors.length; i++) {
               List properties =
  -                propertyIntrospectors[i].introspectProperties(this, javaClass);
  +                propertyIntrospectors[i].introspectProperties(
  +                    this,
  +                    instanceClass);
               for (int j = 0; j < properties.size(); j++) {
  -                ReflectedProperty property =
  -                        (ReflectedProperty) properties.get(j);
  +                ClazzProperty property = (ClazzProperty) properties.get(j);
                   addProperty(property);
               }
           }
  @@ -256,7 +331,71 @@
           }
       }
       
  +    /**
  +     * Override this method to provide an alternate way of mapping
  +     * methods (and possibly fields) to Operations.
  +     */
  +    protected void introspectOperations()
  +    {
  +        declaredOperationList = new ArrayList();
  +        operationMap = new HashMap();
  +        operationList = new ArrayList();
  +        
  +        Clazz superClazz = getSuperclazz();
  +        if (superClazz != null) {
  +            List superOps = superClazz.getOperations();
  +            for (int i = 0; i < superOps.size(); i++) {
  +                ClazzOperation operation = (ClazzOperation) superOps.get(i);
  +                operationMap.put(operation.getSignature(), operation);
  +            }
  +        }
  +
  +        for (int i = 0; i < operationIntrospectors.length; i++) {
  +            List operations =
  +                operationIntrospectors[i].introspectOperations(
  +                    this,
  +                    instanceClass);
  +            for (int j = 0; j < operations.size(); j++) {
  +                ClazzOperation operation = (ClazzOperation) operations.get(j);
  +                addOperation(operation);
  +            }
  +        }
  +
  +        operationList.addAll(operationMap.values());
  +        
  +        //        if (isLoggingEnabled()) {
  +        //            logPropertyParseResults();
  +        //        }
  +    }
           
  +    /**
  +     * Override this method to provide an alternate way of mapping
  +     * constructors, methods (and possibly fields) to InstanceFactories.
  +     */
  +    protected void introspectInstanceFactories()
  +    {
  +        factoryMap = new HashMap();
  +        factoryList = new ArrayList();
  +
  +        for (int i = 0; i < factoryIntrospectors.length; i++) {
  +            List factories =
  +                factoryIntrospectors[i].introspectInstanceFactories(
  +                    this,
  +                    instanceClass);
  +            for (int j = 0; j < factories.size(); j++) {
  +                ClazzInstanceFactory factory =
  +                    (ClazzInstanceFactory) factories.get(j);
  +                addInstanceFactory(factory);
  +            }
  +        }
  +
  +        operationList.addAll(operationMap.values());
  +
  +        //        if (isLoggingEnabled()) {
  +        //            logPropertyParseResults();
  +        //        }
  +    }
  +
       private List propertyParseResults;
       
       /**
  
  
  
  1.3       +113 -15   jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedClazzLoader.java
  
  Index: ReflectedClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedClazzLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReflectedClazzLoader.java	6 Dec 2002 01:12:49 -0000	1.2
  +++ ReflectedClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.3
  @@ -55,8 +55,6 @@
   
   import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzLoader;
  -import org.apache.commons.clazz.ClazzNotFoundException;
  -import org.apache.commons.clazz.common.GroupClazzLoader;
   
   /**
    * 
  @@ -65,28 +63,27 @@
    */
   public abstract class ReflectedClazzLoader extends ClazzLoader {
   
  -    private GroupClazzLoader group;
       private ClassLoader classLoader;
       
       public ReflectedClazzLoader(
  -            GroupClazzLoader group,
  +            ClazzLoader parent,
               ClassLoader classLoader) 
       {
  -        this.group = group;
  +        super(parent);
       }
       
       public String getClazzName(Object instance) {
           if (instance == null){
               return null;
           }
  -        return instance.getClass().getName();
  +        return Clazz.getCanonicalClassName(instance.getClass()); 
       }
       
       /**
        * @see org.apache.commons.clazz.ClazzLoader#getClazzForName(java.lang.String)
        */
       public Clazz getClazzForName(String name) {
  -        Class javaClass;
  +        Class javaClass = null;
           try {
               if (classLoader != null){
                   javaClass = classLoader.loadClass(name);
  @@ -96,10 +93,107 @@
               }
           }
           catch (ClassNotFoundException ex){
  -            throw new ClazzNotFoundException(name);
           }
  -        return createClazz(group, javaClass);
  +        if (javaClass == null){
  +            try {
  +                javaClass = getClazzForCanonicalName(classLoader, name);
  +            }
  +            catch (ClassNotFoundException ex){
  +            }
  +        }
  +        if (javaClass == null){
  +            return null;
  +        }
  +        return createClazz(getRootClazzLoader(), javaClass);
  +    }
  +    
  +    /**
  +     * Converts a canonical class name into the corresponding internal JVM type
  +     * name format and looks up the type.
  +     */
  +    private static Class getClazzForCanonicalName(
  +            ClassLoader classLoader,
  +            String name)
  +        throws ClassNotFoundException 
  +    {
  +        int arrayDepth = 0;
  +        while (name.endsWith("[]")) {
  +            arrayDepth++;
  +            name = name.substring(0, name.length() - 2);
  +        }
  +
  +        if (name.equals("boolean")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Boolean.TYPE, 'Z');
  +        }
  +        else if (name.equals("byte")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Byte.TYPE, 'B');
  +        }
  +        else if (name.equals("char")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Character.TYPE, 'C');
  +        }
  +        else if (name.equals("short")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Short.TYPE, 'S');
  +        }
  +        else if (name.equals("int")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Integer.TYPE, 'I');
  +        }
  +        else if (name.equals("long")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Long.TYPE, 'J');
  +        }
  +        else if (name.equals("float")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Float.TYPE, 'F');
  +        }
  +        else if (name.equals("double")) {
  +            return getPrimitiveType(classLoader, arrayDepth, Double.TYPE, 'D');
  +        }
  +        if (arrayDepth != 0) {
  +            StringBuffer buffer = new StringBuffer();
  +            for (int i = 0; i < arrayDepth; i++) {
  +                buffer.append('[');
  +            }
  +            buffer.append('L');
  +            buffer.append(name);
  +            buffer.append(';');
  +            name = buffer.toString();
  +        }
  +
  +        if (classLoader != null) {
  +            return classLoader.loadClass(name);
  +        }
  +        else {
  +            return Class.forName(name);
  +        }
       }
  +
  +    /**
  +     * Hacking around some JVM quirks, looks up Classes for primitive types and
  +     * arrays thereof.
  +     */
  +    private static Class getPrimitiveType(
  +            ClassLoader classLoader,
  +            int arrayDepth,
  +            Class primitiveType,
  +            char typeLetter)
  +        throws ClassNotFoundException 
  +    {
  +        if (arrayDepth == 0) {
  +            return primitiveType;
  +        }
  +
  +        StringBuffer buffer = new StringBuffer();
  +        for (int i = 0; i < arrayDepth; i++) {
  +            buffer.append('[');
  +        }
  +        buffer.append(typeLetter);
  +        String name = buffer.toString();
  +
  +        if (classLoader != null) {
  +            return classLoader.loadClass(name);
  +        }
  +        else {
  +            return Class.forName(name);
  +        }
  +    }      
       
       /**
        * Returns <code>true</code> for all objects.
  @@ -111,19 +205,23 @@
       }
   
       /**
  -     * Override this method to construct an alternative Clazz for the given
  -     * Class.  Make sure that the new Clazz is initialized with the supplied
  -     * clazzLoader representing the clazz loader group, not with
  +     * Override this method to construct an Clazz for the given Class
  +     * (javaClass). Make sure that the new Clazz is initialized with the
  +     * supplied clazzLoader representing the clazz loader group, not with
        * <code>this</code>.
        */
       protected abstract Clazz createClazz(
                   ClazzLoader clazzLoader,
                   Class javaClass);  
  +
       /**
        * @see org.apache.commons.clazz.ClazzLoader#defineClazz(java.lang.String, java.lang.Class)
        */
  -    public Clazz defineClazz(String name, Class clazzType) {
  +    public Clazz defineClazz(
  +                String name,
  +                Class clazzClass,
  +                Class instanceClass) 
  +    {
           return null;
       }
  -
   }
  
  
  
  1.2       +9 -2      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedGroupClazzLoader.java
  
  Index: ReflectedGroupClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedGroupClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedGroupClazzLoader.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedGroupClazzLoader.java	14 Dec 2002 02:38:41 -0000	1.2
  @@ -53,16 +53,23 @@
    */
   package org.apache.commons.clazz.reflect;
   
  +import org.apache.commons.clazz.ClazzLoader;
   import org.apache.commons.clazz.common.GroupClazzLoader;
   
   /**
  + * A clazz loader that groups multiple <code>ReflectedClazzLoaders</code>.
  + * Its primary purpose is to optimize the methods that are executed the same way
  + * by all <code>ReflectedClazzLoaders</code>, specifically the
  + * <code>getClazzName()</code> method, which is always the same as the
  + * corresponding <b>class</b> name
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
   public class ReflectedGroupClazzLoader extends GroupClazzLoader {
       
  -    public ReflectedGroupClazzLoader(){
  +    public ReflectedGroupClazzLoader(ClazzLoader parent){
  +        super(parent);
       }
           
       /**
  
  
  
  1.3       +7 -198    jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedProperty.java
  
  Index: ReflectedProperty.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedProperty.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReflectedProperty.java	6 Dec 2002 01:12:49 -0000	1.2
  +++ ReflectedProperty.java	14 Dec 2002 02:38:41 -0000	1.3
  @@ -53,212 +53,21 @@
    */
   package org.apache.commons.clazz.reflect;
   
  -import java.lang.reflect.Field;
  -import java.lang.reflect.Method;
  -
  -import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzProperty;
  -import org.apache.commons.clazz.common.ClazzFeatureSupport;
   
   /**
  + * The same reflected property may have more than one name.  For example, if we
  + * have two methods: <code>Map getAuthors()</code> and <code>String getAuthor
  + * (String)</code>, they both map to the same property, which then has two names:
  + * "author" and "authors".
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedProperty extends ClazzFeatureSupport implements ClazzProperty 
  +public interface ReflectedProperty extends ClazzProperty 
   {
  -    private String name;
  -    private static final String[] EMPTY_STRING_ARRAY = new String[0];
  -    private String[] aliases = EMPTY_STRING_ARRAY;
  -    private Class type;
  -    private Clazz clazz;
  -    private Field field;
  -    private Method readMethod;
  -    private Method writeMethod;
  -    
  -    /**
  -     * Constructor for ReflectedClazzProperty.
  -     */
  -    public ReflectedProperty(Clazz declaringClazz, String name) {
  -        super(declaringClazz);
  -        this.name = name;
  -    }
  -
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#getName()
  -     */
  -    public String getName() {
  -        return name;
  -    }
  -    
  -    /**
  -     * Returns the aliases.
  -     * @return String[]
  -     */
  -    public String[] getAliases() {
  -        return aliases;
  -    }
  -
  -    /**
  -     * Sets the aliases.
  -     * @param aliases The aliases to set
  -     */
  -    public void setAliases(String[] aliases) {
  -        this.aliases = aliases;
  -    }
  -    
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#getClazz()
  -     */
  -    public Clazz getClazz() {
  -        if (clazz == null){
  -            clazz = getDeclaringClazz().
  -                getClazzLoader().getClazzForName(type.getName());
  -        }
  -        return clazz;
  -    }
  -    
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#getContentClazz()
  -     */
  -    public Clazz getContentClazz() {
  -        return null;
  -    }
  -
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#getKeyClazz()
  -     */
  -    public Clazz getKeyClazz() {
  -        return null;
  -    }
  -
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#isReadOnly()
  -     */
  -    public boolean isReadOnly() {
  -        return false;
  -    }
  -
  -    /**
  -     * Returns the field.
  -     * @return Field
  -     */
  -    public Field getField() {
  -        return field;
  -    }
  -
  -    /**
  -     * Returns the readMethod.
  -     * @return Method
  -     */
  -    public Method getReadMethod() {
  -        return readMethod;
  -    }
  -
  -
  -    /**
  -     * Sets the field.
  -     * @param field The field to set
  -     */
  -    public void setField(Field field) {
  -        this.field = field;
  -    }
  -
  -    /**
  -     * Sets the readMethod.
  -     * @param readMethod The readMethod to set
  -     */
  -    public void setReadMethod(Method readMethod) {
  -        this.readMethod = readMethod;
  -    }
  -    
  -    /**
  -     * Returns the writeMethod.
  -     * @return Method
  -     */
  -    public Method getWriteMethod() {
  -        return writeMethod;
  -    }
  -    
  -    /**
  -     * Sets the writeMethod.
  -     * @param writeMethod The writeMethod to set
  -     */
  -    public void setWriteMethod(Method writeMethod) {
  -        this.writeMethod = writeMethod;
  -    }
  -    
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#get(java.lang.Object)
  -     */
  -    public Object get(Object instance) {
  -        if (readMethod == null){
  -            throw new ReflectedAccessException(
  -                "Cannot read property " + name + ": no read method");
  -        }
  -        try {
  -            return readMethod.invoke(instance, null);
  -        }
  -        catch (Exception ex) {
  -            throw new ReflectedAccessException(
  -                "Cannot get property : "
  -                    + name
  -                    + ": cannot invoke method: "
  -                    + readMethod.getName(),
  -                ex);
  -        }
  -    }
  -
       /**
  -     * @see org.apache.commons.clazz.ClazzProperty#set(java.lang.Object, java.lang.Object)
  +     * Alternative names for the property.
        */
  -    public void set(Object instance, Object value) {
  -        if (writeMethod == null){
  -            throw new ReflectedAccessException(
  -                "Cannot modify property " + name + ": no write method");
  -        }
  -        try {
  -            writeMethod.invoke(instance, new Object[]{value});
  -        }
  -        catch (Exception ex) {
  -            throw new ReflectedAccessException(
  -                "Cannot set property : "
  -                    + name
  -                    + ": cannot invoke method: "
  -                    + writeMethod.getName(),
  -                ex);
  -        }
  -    }
  -
  -
  -    /**
  -     * Returns the valueClass.
  -     * @return Class
  -     */
  -    public Class getType() {
  -        return type;
  -    }
  -
  -    /**
  -     * Sets the type.
  -     * @param type The type to set
  -     */
  -    public void setType(Class type) {
  -        this.type = type;
  -    }
  -    
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#isCollection()
  -     */
  -    public boolean isCollection() {
  -        return false;
  -    }
  -
  -    /**
  -     * @see org.apache.commons.clazz.ClazzProperty#isMap()
  -     */
  -    public boolean isMap() {
  -        return false;
  -    }
  -
  +    String[] getAliases();    
   }
  
  
  
  1.3       +4 -4      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedPropertyIntrospector.java
  
  Index: ReflectedPropertyIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedPropertyIntrospector.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReflectedPropertyIntrospector.java	6 Dec 2002 01:12:49 -0000	1.2
  +++ ReflectedPropertyIntrospector.java	14 Dec 2002 02:38:41 -0000	1.3
  @@ -58,8 +58,8 @@
   /**
    * Performs introspection for one kind of property - scalar, indexed, mapped,
    * etc.  In the process of introspection ReflectedClazz invokes 
  - * ReflectedPropertyFactories one after another, discovering properties
  - * of one kind at a time.
  + * ReflectedPropertyIntrospectors one after another, discovering properties of
  + * one kind at a time.
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
  @@ -70,7 +70,7 @@
        * Find methods and fields constituting properties of the
        * corresponding kind.  Create ClazzProperty objects and 
        * return them as a list.  The clazz may already 
  -     * have been populated with properties created by other factories.
  +     * have been populated with properties created by other methods.
        */
       public List introspectProperties(ReflectedClazz clazz, Class javaClass);
   }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedInstanceFactoryIntrospector.java
  
  Index: ReflectedInstanceFactoryIntrospector.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect;
  
  import java.util.List;
  
  /**
   * Performs introspection for one kind of operations. In the process of
   * introspection ReflectedClazz invokes ReflectedInstanceFactoryIntrospectors
   * one after another, discovering factories of one kind at a time.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedInstanceFactoryIntrospector.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public interface ReflectedInstanceFactoryIntrospector {
  
      /**
       * Find constructors, methods and perhaps fields constituting factories.
       * Create ClazzInstanceFactory objects and return them as a list.
       */
      public List introspectInstanceFactories(
          ReflectedClazz clazz,
          Class javaClass);
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedOperationIntrospector.java
  
  Index: ReflectedOperationIntrospector.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect;
  
  import java.util.List;
  
  /**
   * Performs introspection for one kind of operations. In the process of
   * introspection ReflectedClazz invokes ReflectedOperationIntrospectors one
   * after another, discovering operations of one kind at a time.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedOperationIntrospector.java,v 1.1 2002/12/14 02:38:41 dmitri Exp $
   */
  public interface ReflectedOperationIntrospector {
  
      /**
       * Find methods (and perhaps fields) constituting operations.  Create
       * ClazzOperation objects and return them as a list.
       */
      public List introspectOperations(ReflectedClazz clazz, Class javaClass);
  }
  
  
  
  1.2       +20 -5     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/AccessorMethodParser.java
  
  Index: AccessorMethodParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/AccessorMethodParser.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AccessorMethodParser.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ AccessorMethodParser.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -108,6 +108,14 @@
       }
       
       /**
  +     * Returns true if the character can be the first character of a Capitalized
  +     * property name.
  +     */
  +    protected boolean testFirstCharacterOfPropertyName(char ch){
  +        return Character.isUpperCase(ch);
  +    }
  +    
  +    /**
        * Extract the value type from the method. Depending on the type
        * of method, it could be the return type or the type of a parameter.
        */
  @@ -191,14 +199,21 @@
               return name;
           }
           
  -        if (name.length() <= prefix.length()){
  +        int prefixLength = prefix.length();
  +        
  +        if (name.length() <= prefixLength){
               return null;
           }
           
  -        if (name.startsWith(prefix)){
  -            return decapitalize(name.substring(prefix.length()));
  +        if (!name.startsWith(prefix)){
  +            return null;
           }
  -        return null;
  +        
  +        if (!testFirstCharacterOfPropertyName(name.charAt(prefixLength))){
  +            return null;
  +        }
  +        
  +        return decapitalize(name.substring(prefixLength));
       }
       
       /**
  
  
  
  1.2       +469 -145  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedList.java
  
  Index: ReflectedList.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedList.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedList.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedList.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -54,10 +54,11 @@
   package org.apache.commons.clazz.reflect.common;
   
   import java.lang.reflect.Array;
  +import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
   import java.util.*;
   
  -import org.apache.commons.clazz.reflect.ReflectedAccessException;
  +import org.apache.commons.clazz.ClazzAccessException;
   
   
   /**
  @@ -80,11 +81,20 @@
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedList implements List {
  +public class ReflectedList extends AbstractList 
  +{
  +    /*
  +     * We have a concurrent modification issue with ReflectedList. We have no
  +     * way of knowing if somebody has modified the property value unless it was
  +     * modified through this very ReflectedList. So, in some cases we will not
  +     * get a ConcurrentModificationException when we are supposed to.
  +     */ 
       
       private Object instance;
       private ReflectedListProperty property;
  -    
  +        
  +    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
  +        
       /**
        * Constructor for ReflectedList.
        */
  @@ -95,7 +105,40 @@
           this.instance = instance;
           this.property = property;
       }
  +    
  +    public Object getPropertyValue(){ 
  +        Method readMethod = property.getReadMethod();
  +        if (readMethod == null){
  +            throw new ClazzAccessException(
  +                "Cannot read property "
  +                    + property.getName()
  +                    + ": no read method");
  +        }
  +        try {
  +            return readMethod.invoke(instance, null);
  +        }
  +        catch (Exception ex) {
  +            throw accessException("Cannot read property", readMethod, ex);
  +        }
  +    }
   
  +    public void setPropertyValue(Object value) {
  +        Method writeMethod = property.getWriteMethod();
  +        if (writeMethod == null){
  +            throw new ClazzAccessException(
  +                "Cannot set property: "
  +                    + property.getName()
  +                    + ": no set(array) method");
  +        }
  +
  +        try {
  +            writeMethod.invoke(instance, new Object[] { value });
  +        }
  +        catch (Exception ex) {
  +            throw accessException("Cannot set property", writeMethod, ex);
  +        }
  +    }
  +    
       /**
        * @see java.util.Collection#size()
        */
  @@ -107,16 +150,11 @@
                   return ((Integer)value).intValue();
               }
               catch (Exception ex) {
  -                throw new ReflectedAccessException(
  -                    "Cannot get list size: "
  -                        + property.getName()
  -                        + ": cannot invoke method: "
  -                        + sizeMethod.getName(),
  -                    ex);
  +                throw accessException("Cannot get list size", sizeMethod, ex);
               }
           }
           else {
  -            Object list = property.getList(instance);
  +            Object list = getPropertyValue();
               if (list == null){
                   return 0;
               }
  @@ -130,96 +168,6 @@
       }
   
       /**
  -     * @see java.util.Collection#isEmpty()
  -     */
  -    public boolean isEmpty() {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#contains(java.lang.Object)
  -     */
  -    public boolean contains(Object o) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#iterator()
  -     */
  -    public Iterator iterator() {
  -        return null;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#toArray()
  -     */
  -    public Object[] toArray() {
  -        return null;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#toArray(java.lang.Object)
  -     */
  -    public Object[] toArray(Object[] a) {
  -        return null;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#add(java.lang.Object)
  -     */
  -    public boolean add(Object o) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#remove(java.lang.Object)
  -     */
  -    public boolean remove(Object o) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#containsAll(java.util.Collection)
  -     */
  -    public boolean containsAll(Collection c) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#addAll(java.util.Collection)
  -     */
  -    public boolean addAll(Collection c) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.List#addAll(int, java.util.Collection)
  -     */
  -    public boolean addAll(int index, Collection c) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#removeAll(java.util.Collection)
  -     */
  -    public boolean removeAll(Collection c) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#retainAll(java.util.Collection)
  -     */
  -    public boolean retainAll(Collection c) {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Collection#clear()
  -     */
  -    public void clear() {
  -    }
  -
  -    /**
        * @see java.util.List#get(int)
        */
       public Object get(int index) {
  @@ -232,62 +180,81 @@
                           instance,
                           new Object[] { new Integer(index)});
               }
  -            catch (Exception ex) {
  -                throw new ReflectedAccessException(
  -                    "Cannot get property : "
  -                        + property.getName()
  -                        + ": cannot invoke method: "
  -                        + getMethod.getName(),
  -                    ex);
  +            catch (Throwable ex) {
  +                throw accessException("Cannot get property", getMethod, ex);
               }
               return value;
           }
           else {
  -            Object list = property.getList(instance);
  +            Object list = getPropertyValue();
               if (list == null){
                   return null;
               }
  -            
  +
               if (list instanceof List){
                   return ((List)list).get(index);
               }
  -           
  +
               return Array.get(list, index);
           }
       }
   
       /**
  +     * @see java.util.Collection#iterator()
  +     */
  +    public Iterator iterator(){
  +        return new QuickList().iterator();
  +    }
  +
  +    /**
  +     * @see java.util.List#listIterator()
  +     */
  +    public ListIterator listIterator() {
  +        return new QuickList().listIterator();
  +    }
  +
  +    /**
  +     * @see java.util.List#listIterator(int)
  +     */
  +    public ListIterator listIterator(int index) {
  +        return new QuickList().listIterator(index);
  +    }
  +
  +    /**
        * @see java.util.List#set(int, java.lang.Object)
        */
       public Object set(int index, Object element) {
  +        modCount++;
           Method setMethod = property.getSetMethod();
           if (setMethod != null){
  -            Object oldValue = get(index);
  +            Object oldValue = null;
  +            try {
  +                oldValue = get(index);
  +            }
  +            catch (Throwable t){
  +                // Ignore
  +            }
               try {
                   setMethod.invoke(
                       instance,
                       new Object[] { new Integer(index), element });
               }
               catch (Exception ex) {
  -                throw new ReflectedAccessException(
  -                    "Cannot set property : "
  -                        + property.getName()
  -                        + ": cannot invoke method: "
  -                        + setMethod.getName(),
  -                    ex);
  +                throw accessException(
  +                    "Cannot set property element", setMethod, ex);
               }
               return oldValue;
           }
           else {
  -            Object list = property.getList(instance);
  +            Object list = getPropertyValue();
               if (list == null){
                   return null;
               }
  -            
  +
               if (list instanceof List){
                   return ((List)list).set(index, element);
               }
  -           
  +
               Object oldValue = Array.get(list, index);
               Array.set(list, index, element);
               return oldValue;
  @@ -295,51 +262,408 @@
       }
   
       /**
  -     * @see java.util.List#add(int, java.lang.Object)
  +     * Will perform the following steps:
  +     * <ol>
  +     * 
  +     * <li>If the instance has an <code>addFoo(element)</code>, calls that
  +     * method.</li>
  +     * 
  +     * <li>Otherwise, if the instance has an <code>add(index,element)</code>,
  +     * computes the size of the list and calls <code>add(size(),element)
  +     * </code>.<li>
  +     * 
  +     * <li>Othewise, if the instance has a <code>List getFoo<i>[plural suffix]
  +     * </i>()</code> method, calls that and adds the element to the list.</li>
  +     * 
  +     * <li>Othewise, if the instance has a <code>Foo[] getFoo<i>[plural suffix]
  +     * </i>()</code> method as well as a <code>setFoo<i>[plural suffix]
  +     * </i>(Foo[])</code> method, calls the read method, copies the array into a
  +     * new array with an additional element and calls the write method to assign
  +     * the new array to the property.</li>
  +     * 
  +     * </ol>
  +     * 
  +     * @see java.util.Collection#add(java.lang.Object)
        */
  -    public void add(int index, Object element) {
  +    public boolean add(Object element) {
  +        modCount++;
  +        if (property.getAddMethod() != null){
  +            Method addMethod = property.getAddMethod();
  +            try {
  +                addMethod.invoke(
  +                    instance,
  +                    new Object[] { element });
  +            }
  +            catch (Exception ex) {
  +                throw accessException(
  +                    "Cannot add value to property", addMethod, ex);
  +            }
  +        }
  +        else {
  +            add(-1, element);
  +        }
  +        return true;
       }
   
       /**
  -     * @see java.util.List#remove(int)
  +     * Will perform the following steps:
  +     * <ol>
  +     * <li>If the instance has an <code>add(index,element)</code>,
  +     * calls that method.<li>
  +     * 
  +     * <li>Othewise, if the instance has an <code>add(element)</code> method and
  +     * index == size(), calls that method.</li>
  +     * 
  +     * <li>Othewise, if the instance has a <code>List getFoo<i> [plural
  +     * suffix]</i>()</code> method, calls that and inserts the element into the
  +     * list.</li>
  +     * 
  +     * <li>Othewise, if the instance has a <code>Foo[] getFoo<i>[plural suffix]
  +     * </i>()</code> method as well as a <code>setFoo<i>[plural suffix]
  +     * </i>(Foo[])</code> method, calls the read method, copies the array into a
  +     * new, one-longer, array inserting the additional element and calls the
  +     * write method to assign the new array to the property.</li>
  +     * 
  +     * </ol>
  +     * 
  +     * @see java.util.List#add(int, java.lang.Object)
        */
  -    public Object remove(int index) {
  -        return null;
  +    public void add(int index, Object element) {
  +        modCount++;
  +        if (property.getAddIndexedMethod() != null){
  +            if (index == -1){       // This would indicate that the call
  +                                    // is coming from add(element) and
  +                                    // the addMethod does not exist
  +                index = size();
  +            }
  +            Method addIndexedMethod = property.getAddIndexedMethod();
  +            try {
  +                addIndexedMethod.invoke(
  +                    instance,
  +                    new Object[] { new Integer(index), element });
  +            }
  +            catch (Exception ex) {
  +                throw accessException(
  +                    "Cannot add value to property", addIndexedMethod, ex);
  +            }
  +            return;
  +        }
  +        
  +        if (property.getAddMethod() != null && index == size()){ // This
  +                    // guarantees that the call is not coming from add(element),
  +                    // therefore we can call it without the fear of recursion
  +            add(element);
  +        }
  +        else if (property.getType().isArray()){
  +            addToArray(index, element);
  +        }            
  +        else {
  +            addToList(index, element);
  +        }
       }
   
       /**
  -     * @see java.util.List#indexOf(java.lang.Object)
  +     * Inserts a new element into an array.  Creates the array if necessary. 
        */
  -    public int indexOf(Object o) {
  -        return 0;
  -    }
  +    private void addToArray(int index, Object element){        
  +        Object newList;
  +        Object list = getPropertyValue();
  +        if (list == null){
  +            if (index != 0 && index != -1){
  +                throw new ArrayIndexOutOfBoundsException(
  +                    "Size: 0; Index: " + index);
  +            }                    
  +            Class contentType = property.getContentType();
  +            newList = Array.newInstance(contentType, 1);
  +            Array.set(newList, 0, element);
  +        }
  +        else {
  +            Class contentType = property.getContentType();
  +            int size = Array.getLength(list);
  +            if (index == -1){
  +                index = size;
  +            }
  +            if (index < 0 || index > size){
  +                throw new ArrayIndexOutOfBoundsException(
  +                    "Size: " + size + "; Index: " + index);
  +            }
  +            newList = Array.newInstance(contentType, size + 1);
  +            System.arraycopy(list, 0, newList, 0, index);
  +            Array.set(newList, index, element);
  +            System.arraycopy(
  +                list, index, newList, index + 1, size - index);
  +        }
   
  +        setPropertyValue(newList);
  +    }
  +    
       /**
  -     * @see java.util.List#lastIndexOf(java.lang.Object)
  +     * Inserts a new element into an List.  Creates the list if necessary.
        */
  -    public int lastIndexOf(Object o) {
  -        return 0;
  -    }
  +    private void addToList(int index, Object element){
  +        Object list = getPropertyValue();
  +        if (list == null){
  +            List newList;            
  +            Class type = property.getType();
  +            if (!type.isInterface()){
  +                try {
  +                    newList = (List)type.newInstance();
  +                }
  +                catch (Exception ex) {
  +                    throw new ClazzAccessException(
  +                        "Cannot add value to property : "
  +                            + property.getName()
  +                            + ": cannot create List of type "
  +                            + type.getName(),
  +                        ex);
  +                }
  +            }
  +            else {
  +                newList = new ArrayList();
  +            }
  +            newList.add(element);
   
  +            setPropertyValue(newList);
  +        }
  +        else if (index == -1){
  +            ((List)list).add(element);
  +        }
  +        else {
  +            ((List)list).add(index, element);
  +        }
  +    }
  +    
       /**
  -     * @see java.util.List#listIterator()
  +     * Will perform the following steps:
  +     * <ol>
  +     *
  +     * <li>If the instance has an <code>removeFoo(element)</code>, calls that
  +     * method.</li>
  +     *
  +     * <li>Otherwise, if iterates over elements of the collection until it
  +     * finds one equal to the supplied value. Then it removes it by calling
  +     * <code>remove(index)</code><li>
  +     *
  +     * </ol>
  +     *
  +     * @see java.util.Collection#remove(java.lang.Object)
        */
  -    public ListIterator listIterator() {
  -        return null;
  +    public boolean remove(Object element) {
  +        modCount++;
  +        if (property.getRemoveMethod() != null){
  +            Method removeMethod = property.getRemoveMethod();
  +            try {
  +                removeMethod.invoke(
  +                    instance,
  +                    new Object[] { element });
  +            }
  +            catch (Exception ex) {
  +                throw accessException(
  +                    "Cannot remove value from property", removeMethod, ex);
  +            }
  +            return true;        // @todo: we really don't know if it got removed
  +        }
  +        else {
  +            return super.remove(element);
  +        }
       }
   
       /**
  -     * @see java.util.List#listIterator(int)
  +     * Will perform the following steps:
  +     * <ol>
  +     * <li>If the instance has a <code>remove(index)</code>, calls that method.
  +     * <li>
  +     *
  +     * <li>Othewise, if the instance has an <code>add(element)</code> method and
  +     * index == size(), calls that method.</li>
  +     *
  +     * <li>Othewise, if the instance has a <code>List getFoo<i> [plural
  +     * suffix]</i>()</code> method, calls that and removes the element from the
  +     * list.
  +     * </li>
  +     *
  +     * <li>Othewise, if the instance has a <code>Foo[] getFoo<i>[plural suffix]
  +     * </i>()</code> method as well as a <code>setFoo<i>[plural suffix]
  +     * </i>(Foo[])</code> method, calls the read method, copies the array into a
  +     * new, one-shorter, array removing the supplied element and calls the write
  +     * method to assign the new array to the property.</li>
  +     *
  +     * </ol>
  +     *
  +     * @see java.util.List#add(int, java.lang.Object)
        */
  -    public ListIterator listIterator(int index) {
  -        return null;
  +    public Object remove(int index) {
  +        modCount++;
  +        
  +        if (property.getRemoveIndexedMethod() != null){
  +            Object value = null;
  +            
  +            try {
  +                value = get(index);
  +            }
  +            catch (Throwable t){
  +                // Ignore
  +            }
  +            
  +            Method removeIndexedMethod = property.getRemoveIndexedMethod();
  +            try {
  +                removeIndexedMethod.invoke(
  +                    instance,
  +                    new Object[] { new Integer(index)});
  +            }
  +            catch (Exception ex) {
  +                throw accessException(
  +                    "Cannot remove value from property",
  +                    removeIndexedMethod,
  +                    ex);
  +            }
  +            
  +            return value;
  +        }
  +        
  +        Object list = getPropertyValue();
  +        if (list == null){
  +            throw new ArrayIndexOutOfBoundsException(
  +                "Size: 0; Index: " + index);
  +        }
  +        else if (property.getType().isArray()){
  +            Object value;
  +            Class contentType = property.getContentType();
  +            int size = Array.getLength(list);
  +            if (index < 0 || index >= size){
  +                throw new ArrayIndexOutOfBoundsException(
  +                    "Size: " + size + "; Index: " + index);
  +            }
  +            value = Array.get(list, index);
  +
  +            Object newList = Array.newInstance(contentType, size - 1);
  +            System.arraycopy(list, 0, newList, 0, index);
  +            System.arraycopy(
  +                list, index + 1, newList, index, size - index - 1);
  +            setPropertyValue(newList);
  +            return value;
  +        }
  +        else {
  +            return ((List)list).remove(index);
  +        }
       }
   
  -    /**
  -     * @see java.util.List#subList(int, int)
  -     */
  -    public List subList(int fromIndex, int toIndex) {
  -        return null;
  +    private RuntimeException accessException(
  +        String message,
  +        Method method,
  +        Throwable ex)
  +    {
  +        if (ex instanceof InvocationTargetException) {
  +            ex = ((InvocationTargetException) ex).getTargetException();
  +        }
  +        
  +        // Just re-throw all runtime exceptions - there is really no
  +        // point in wrapping them 
  +        if (ex instanceof RuntimeException) {
  +            throw (RuntimeException) ex;
  +        }
  +        if (ex instanceof Error) {
  +            throw (Error) ex;
  +        }
  +        
  +        throw new ClazzAccessException(
  +            message
  +                + ": "
  +                + property.getName()
  +                + ": cannot invoke method: "
  +                + method.getName(),
  +            ex);
       }
   
  +    /**
  +     * QuickList is used exclusively as short-lived helper object for
  +     * an optimization of Iterator.
  +     * 
  +     * The point is to avoid requesting the collection or its size from the
  +     * instance on every step of the iteration. The instance may be creating the
  +     * collection every time we ask for it, or it may be wrapping it into an
  +     * unmodifiable list. We want to avoid that overhead. The computation of
  +     * size can be rather expensive too.
  +     * 
  +     * A QuickList maintains temporary cache of the reflected collection and its
  +     * size.
  +     */
  +    private class QuickList extends AbstractList {
  +        private Object list;
  +        private int size;
  +
  +        public QuickList(){
  +            update();
  +        }
  +                
  +        public void refresh(){
  +            // If QuickList is out of sync with the parent ReflectedList,
  +            // update the cached list and size
  +            if (super.modCount != ReflectedList.this.modCount){
  +                update();
  +            }            
  +        }
  +        
  +        public void update(){            
  +            // Make sure modCount of QuickList is maintained in sync with
  +            // that of the embracing List 
  +            super.modCount = ReflectedList.this.modCount;
  +            
  +            if (property.getReadMethod() != null){
  +                list = getPropertyValue();
  +                if (list == null){
  +                    size = 0;
  +                }    
  +                else if (list instanceof List){
  +                    size = ((List)list).size();
  +                }
  +                else {
  +                    size = Array.getLength(list);
  +                }
  +            }
  +            else {
  +                list = NOT_ACCESSIBLE;
  +                size = ReflectedList.this.size();
  +            }
  +        }
  +        
  +        public int size(){
  +            refresh();
  +            return size;
  +        }
  +        
  +        public Object get(int index) {
  +            refresh();
  +            if (list != NOT_ACCESSIBLE) {
  +                if (list == null) {
  +                    throw new IndexOutOfBoundsException(
  +                        "Size= 0; index=" + index);
  +                }
  +
  +                if (list instanceof List) {
  +                    return ((List) list).get(index);
  +                }
  +
  +                return Array.get(list, index);
  +            }
  +            else {
  +                return ReflectedList.this.get(index);
  +            }
  +        }
  +        
  +        public Object set(int index, Object value){
  +            return ReflectedList.this.set(index, value);
  +        }
  +        
  +        public void add(int index, Object value){
  +            ReflectedList.this.add(index, value);
  +        }
  +        
  +        public Object remove(int index){
  +            return ReflectedList.this.remove(index);
  +        }
  +
  +    }
  +    
  +    private static final Object NOT_ACCESSIBLE = new Object();
   }
  
  
  
  1.2       +31 -11    jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListProperty.java
  
  Index: ReflectedListProperty.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListProperty.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedListProperty.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedListProperty.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -56,14 +56,13 @@
   import java.lang.reflect.Method;
   
   import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.reflect.ReflectedProperty;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedListProperty extends ReflectedProperty {
  +public class ReflectedListProperty extends ReflectedAccessorPairProperty {
   
       private Class contentType;
       private Method sizeMethod;
  @@ -72,6 +71,7 @@
       private Method addIndexedMethod;
       private Method setMethod;
       private Method removeMethod;
  +    private Method removeIndexedMethod;
       
       /**
        * Constructor for ReflectedListProperty.
  @@ -186,6 +186,22 @@
       }
   
       /**
  +     * Returns the removeIndexedMethod.
  +     * @return Method
  +     */
  +    public Method getRemoveIndexedMethod() {
  +        return removeIndexedMethod;
  +    }
  +
  +    /**
  +     * Sets the removeIndexedMethod.
  +     * @param removeIndexedMethod The removeIndexedMethod to set
  +     */
  +    public void setRemoveIndexedMethod(Method removeIndexedMethod) {
  +        this.removeIndexedMethod = removeIndexedMethod;
  +    }
  +
  +    /**
        * Returns the sizeMethod.
        * @return Method
        */
  @@ -214,35 +230,39 @@
           }
           buffer.append(getName());
           if (getReadMethod() != null){
  -            buffer.append("\n   [read method]   ");
  +            buffer.append("\n   [read method]      ");
               buffer.append(getReadMethod());            
           }
           if (getWriteMethod() != null){
  -            buffer.append("\n   [write method]  ");
  +            buffer.append("\n   [write method]     ");
               buffer.append(getWriteMethod());            
           }
           if (getGetMethod() != null){
  -            buffer.append("\n   [get method]    ");
  +            buffer.append("\n   [get method]       ");
               buffer.append(getGetMethod());            
           }
           if (getSetMethod() != null){
  -            buffer.append("\n   [set method]    ");
  +            buffer.append("\n   [set method]       ");
               buffer.append(getSetMethod());            
           }
           if (getAddMethod() != null){
  -            buffer.append("\n   [add method]    ");
  +            buffer.append("\n   [add method]       ");
               buffer.append(getAddMethod());            
           }
           if (getAddIndexedMethod() != null){
  -            buffer.append("\n   [add(i) method] ");
  +            buffer.append("\n   [add(i) method]    ");
               buffer.append(getAddIndexedMethod());            
           }
           if (getRemoveMethod() != null){
  -            buffer.append("\n   [remove method] ");
  +            buffer.append("\n   [remove method]    ");
               buffer.append(getRemoveMethod());            
           }
  +        if (getRemoveIndexedMethod() != null){
  +            buffer.append("\n   [remove(i) method] ");
  +            buffer.append(getRemoveIndexedMethod());
  +        }
           if (getSizeMethod() != null){
  -            buffer.append("\n   [size method]   ");
  +            buffer.append("\n   [size method]      ");
               buffer.append(getSizeMethod());            
           }
           buffer.append("]");
  
  
  
  1.2       +4 -2      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListPropertyIntrospectorSupport.java
  
  Index: ReflectedListPropertyIntrospectorSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListPropertyIntrospectorSupport.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedListPropertyIntrospectorSupport.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedListPropertyIntrospectorSupport.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -306,7 +306,7 @@
       /**
        * Creates a new ReflectedListProperty based on parse results. 
        */
  -    protected ReflectedProperty createProperty(
  +    protected ReflectedAccessorPairProperty createProperty(
           ReflectedClazz clazz,
           ReflectedPropertyParseResults parseResults)
       {
  @@ -326,6 +326,8 @@
           property.setAddMethod(parseResultsList.getAddMethod());
           property.setAddIndexedMethod(parseResultsList.getAddIndexedMethod());
           property.setRemoveMethod(parseResultsList.getRemoveMethod());
  +        property.setRemoveIndexedMethod(
  +            parseResultsList.getRemoveIndexedMethod());
           property.setSizeMethod(parseResultsList.getSizeMethod());
           return property;
       }     
  
  
  
  1.2       +36 -2     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListPropertyParseResults.java
  
  Index: ReflectedListPropertyParseResults.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListPropertyParseResults.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedListPropertyParseResults.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedListPropertyParseResults.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -56,6 +56,7 @@
   import java.lang.reflect.Method;
   import java.util.List;
   
  +import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.reflect.ReflectedClazz;
   
   /**
  @@ -73,6 +74,7 @@
       private AccessorMethodParseResults addMethodParseResults;
       private AccessorMethodParseResults addIndexedMethodParseResults;
       private AccessorMethodParseResults removeMethodParseResults;
  +    private AccessorMethodParseResults removeIndexedMethodParseResults;
       
       private AccessorMethodParseResults sizeMethodParseResults;
       
  @@ -134,6 +136,18 @@
           if (removeMethodParseResults != null){
               return removeMethodParseResults.getType();
           }
  +        if (readMethodParseResults != null){
  +            Class type = readMethodParseResults.getType();
  +            if (type.isArray()){
  +                return type.getComponentType();
  +            }
  +        }
  +        if (writeMethodParseResults != null){
  +            Class type = writeMethodParseResults.getType();
  +            if (type.isArray()){
  +                return type.getComponentType();
  +            }
  +        }
           return null;
       }
   
  @@ -217,6 +231,22 @@
           return removeMethodParseResults.getMethod();
       }
       
  +    public void setRemoveIndexedMethodParseResults(
  +                AccessorMethodParseResults removeIndexedMethodParseResults)
  +    {
  +        checkForExtraneousAccessor(
  +            this.removeIndexedMethodParseResults,
  +            removeIndexedMethodParseResults);
  +        this.removeIndexedMethodParseResults = removeIndexedMethodParseResults;
  +    }
  +
  +    public Method getRemoveIndexedMethod() {
  +        if (removeIndexedMethodParseResults == null){
  +            return null;
  +        }
  +        return removeIndexedMethodParseResults.getMethod();
  +    }
  +
   
       public void setSizeMethodParseResults(
                   AccessorMethodParseResults sizeMethodParseResults) 
  @@ -275,7 +305,7 @@
           Class contentType = getContentType();
           if (contentType != null){
               buffer.append("\n  [content type]   ");
  -            buffer.append(contentType.getName());
  +            buffer.append(Clazz.getCanonicalClassName(contentType));
           }
       }
       
  @@ -300,6 +330,10 @@
           if (removeMethodParseResults != null){
               buffer.append("\n    [remove~(v)]   ");
               buffer.append(removeMethodParseResults.getMethod());
  +        }
  +        if (removeIndexedMethodParseResults != null){
  +            buffer.append("\n    [remove~(i)]   ");
  +            buffer.append(removeIndexedMethodParseResults.getMethod());
           }
           if (sizeMethodParseResults != null){
               buffer.append("\n    [get~Count()]  ");
  
  
  
  1.2       +42 -4     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedPropertyIntrospectorSupport.java
  
  Index: ReflectedPropertyIntrospectorSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedPropertyIntrospectorSupport.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedPropertyIntrospectorSupport.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedPropertyIntrospectorSupport.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -55,6 +55,7 @@
   
   import java.util.*;
   
  +import org.apache.commons.clazz.ClazzProperty;
   import org.apache.commons.clazz.reflect.*;
   
   /**
  @@ -109,11 +110,48 @@
           ReflectedClazz clazz,
           Class javaClass,
           Map parseResultMap);
  -            
  +
  +    public List introspectDeclaredProperties(
  +            ReflectedClazz clazz,
  +            Class javaClass)
  +    {
  +        Class instanceClass = clazz.getInstanceClass();
  +        List declaredPropertyList = null;
  +        if (instanceClass.getSuperclass() == null){
  +            declaredPropertyList = clazz.getProperties();
  +        }
  +        else {
  +            List superProperties = clazz.getSuperclazz().getProperties();
  +            if (superProperties.size() == 0){
  +                declaredPropertyList = clazz.getProperties();
  +            }
  +            else {
  +                HashSet superNames = new HashSet();
  +                for (int i = 0; i < superProperties.size(); i++){
  +                    ClazzProperty property =
  +                            (ClazzProperty)superProperties.get(i);
  +                    superNames.add(property.getName());
  +                }
  +
  +                List properties = clazz.getProperties();
  +                declaredPropertyList = new ArrayList();
  +                for (int i = 0; i < properties.size(); i++){
  +                    ClazzProperty property =
  +                        (ClazzProperty) properties.get(i);
  +                    String name = property.getName();
  +                    if (!superNames.contains(name)){
  +                        declaredPropertyList.add(property);
  +                    }
  +                }
  +            }
  +        }
  +        return declaredPropertyList;
  +    }
  +                
       /**
  -     * Creates a new ReflectedProperty based on parse results. 
  +     * Creates a new ReflectedAccessorPairProperty based on parse results. 
        */
  -    protected abstract ReflectedProperty createProperty(
  +    protected abstract ReflectedAccessorPairProperty createProperty(
           ReflectedClazz clazz,
           ReflectedPropertyParseResults parseResults);
       
  
  
  
  1.2       +3 -2      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedPropertyParseResults.java
  
  Index: ReflectedPropertyParseResults.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedPropertyParseResults.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedPropertyParseResults.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedPropertyParseResults.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -57,6 +57,7 @@
   import java.util.ArrayList;
   import java.util.List;
   
  +import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.reflect.ReflectedClazz;
   
   /**
  @@ -252,7 +253,7 @@
           Class type = getPropertyType();
           if (type != null){
               buffer.append("\n  [type]           ");
  -            buffer.append(type.getName());
  +            buffer.append(Clazz.getCanonicalClassName(type));
           }
       }
       
  
  
  
  1.2       +4 -5      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarProperty.java
  
  Index: ReflectedScalarProperty.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarProperty.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedScalarProperty.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedScalarProperty.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -54,14 +54,13 @@
   package org.apache.commons.clazz.reflect.common;
   
   import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.reflect.ReflectedProperty;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedScalarProperty extends ReflectedProperty {
  +public class ReflectedScalarProperty extends ReflectedAccessorPairProperty {
       /**
        * Constructor for ReflectedScalarProperty.
        * @param declaringClazz
  @@ -79,11 +78,11 @@
           }
           buffer.append(getName());
           if (getReadMethod() != null){
  -            buffer.append("\n   [read method]  ");
  +            buffer.append("\n   [read method]     ");
               buffer.append(getReadMethod());            
           }
           if (getWriteMethod() != null){
  -            buffer.append("\n   [write method] ");
  +            buffer.append("\n   [write method]    ");
               buffer.append(getWriteMethod());            
           }
           buffer.append("]");
  
  
  
  1.2       +15 -4     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarPropertyIntrospector.java
  
  Index: ReflectedScalarPropertyIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarPropertyIntrospector.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedScalarPropertyIntrospector.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedScalarPropertyIntrospector.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -57,7 +57,6 @@
   import java.util.Map;
   
   import org.apache.commons.clazz.reflect.ReflectedClazz;
  -import org.apache.commons.clazz.reflect.ReflectedProperty;
   
   /**
    * A ReflectedPropertyIntrospector that discovers scalar properties.
  @@ -140,10 +139,22 @@
               String name = method.getName();
               String propertyName = null;
               if (name.startsWith("get")){
  +                if (name.length() <= 3){
  +                    return null;
  +                }
  +                if (!testFirstCharacterOfPropertyName(name.charAt(3))){
  +                    return null;
  +                }
                   propertyName = decapitalize(name.substring(3));
               }
               else if (method.getReturnType().equals(Boolean.TYPE) && 
                           name.startsWith("is")){
  +                if (name.length() <= 2){
  +                    return null;
  +                }
  +                if (!testFirstCharacterOfPropertyName(name.charAt(2))){
  +                    return null;
  +                }
                   propertyName = decapitalize(name.substring(2));
               }
               return propertyName;           
  @@ -219,8 +230,8 @@
       }
       
       /**
  -     * Creates a new ReflectedProperty based on parse results. 
     */
  -    protected ReflectedProperty createProperty(
  +     * Creates a new ReflectedAccessorPairProperty based on parse results. 
     */
  +    protected ReflectedAccessorPairProperty createProperty(
           ReflectedClazz clazz,
           ReflectedPropertyParseResults parseResults)
       {
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedAccessorPairProperty.java
  
  Index: ReflectedAccessorPairProperty.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzAccessException;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  import org.apache.commons.clazz.reflect.ReflectedProperty;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedAccessorPairProperty.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedAccessorPairProperty extends ClazzFeatureSupport 
          implements ReflectedProperty 
  {
      private String name;
      private static final String[] EMPTY_STRING_ARRAY = new String[0];
      private String[] aliases = EMPTY_STRING_ARRAY;
      private Class type;
      private Clazz clazz;
      private Field field;
      private Method readMethod;
      private Method writeMethod;
      
      /**
       * Constructor for ReflectedClazzProperty.
       */
      public ReflectedAccessorPairProperty(Clazz declaringClazz, String name) {
          super(declaringClazz);
          this.name = name;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#getName()
       */
      public String getName() {
          return name;
      }
      
      /**
       * Returns the aliases.
       * @return String[]
       */
      public String[] getAliases() {
          return aliases;
      }
  
      /**
       * Sets the aliases.
       * @param aliases The aliases to set
       */
      public void setAliases(String[] aliases) {
          this.aliases = aliases;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#getClazz()
       */
      public Clazz getClazz() {
          if (clazz == null){
              clazz = getDeclaringClazz().
                  getClazzLoader().getClazzForName(type.getName());
          }
          return clazz;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#getContentClazz()
       */
      public Clazz getContentClazz() {
          return null;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#getKeyClazz()
       */
      public Clazz getKeyClazz() {
          return null;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#isReadOnly()
       */
      public boolean isReadOnly() {
          return false;
      }
  
      /**
       * Returns the field.
       * @return Field
       */
      public Field getField() {
          return field;
      }
  
      /**
       * Returns the readMethod.
       * @return Method
       */
      public Method getReadMethod() {
          return readMethod;
      }
  
  
      /**
       * Sets the field.
       * @param field The field to set
       */
      public void setField(Field field) {
          this.field = field;
      }
  
      /**
       * Sets the readMethod.
       * @param readMethod The readMethod to set
       */
      public void setReadMethod(Method readMethod) {
          this.readMethod = readMethod;
      }
      
      /**
       * Returns the writeMethod.
       * @return Method
       */
      public Method getWriteMethod() {
          return writeMethod;
      }
      
      /**
       * Sets the writeMethod.
       * @param writeMethod The writeMethod to set
       */
      public void setWriteMethod(Method writeMethod) {
          this.writeMethod = writeMethod;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#get(java.lang.Object)
       */
      public Object get(Object instance) {
          if (readMethod == null){
              throw new ClazzAccessException(
                  "Cannot read property " + name + ": no read method");
          }
          try {
              return readMethod.invoke(instance, null);
          }
          catch (Exception ex) {
              throw new ClazzAccessException(
                  "Cannot get property : "
                      + name
                      + ": cannot invoke method: "
                      + readMethod.getName(),
                  ex);
          }
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#set(java.lang.Object, java.lang.Object)
       */
      public void set(Object instance, Object value) {
          if (writeMethod == null){
              throw new ClazzAccessException(
                  "Cannot modify property " + name + ": no write method");
          }
          try {
              writeMethod.invoke(instance, new Object[]{value});
          }
          catch (Exception ex) {
              throw new ClazzAccessException(
                  "Cannot set property : "
                      + name
                      + ": cannot invoke method: "
                      + writeMethod.getName(),
                  ex);
          }
      }
  
  
      /**
       * Returns the valueClass.
       * @return Class
       */
      public Class getType() {
          return type;
      }
  
      /**
       * Sets the type.
       * @param type The type to set
       */
      public void setType(Class type) {
          this.type = type;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#isCollection()
       */
      public boolean isCollection() {
          return false;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#isMap()
       */
      public boolean isMap() {
          return false;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedConstructorInstanceFactory.java
  
  Index: ReflectedConstructorInstanceFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Constructor;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzAccessException;
  import org.apache.commons.clazz.ClazzInstanceFactory;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  
  /**
   * A wrapper for a java constructor.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedConstructorInstanceFactory.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedConstructorInstanceFactory extends ClazzFeatureSupport
          implements ClazzInstanceFactory
  {   
      private Constructor constructor;
      private String signature;
      private static final Clazz[] EMPTY_CLAZZ_ARRAY = new Clazz[0];
      private Clazz[] parameterClazzes;
  
      /**
       * Constructor for ReflectedClazzProperty.
       */
      public ReflectedConstructorInstanceFactory(
              Clazz declaringClazz,
              Constructor constructor)
      {
          super(declaringClazz);
          this.constructor = constructor;
      }
  
      public Constructor getConstructor(){
          return constructor;
      }
  
      public String getName(){
          return null;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getSignature()
       */
      public String getSignature() {
          if (signature == null) {
              signature =
                  Clazz.constructSignature(null, constructor.getParameterTypes());
          }
          return signature;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getParameterClazzes()
       */
      public Clazz[] getParameterClazzes() {
          if (parameterClazzes == null){
              Class paramClasses[] = constructor.getParameterTypes();
              if (paramClasses == null){
                  parameterClazzes = EMPTY_CLAZZ_ARRAY;
              }
              else {
                  parameterClazzes = new Clazz[paramClasses.length];
                  ClazzLoader loader = getDeclaringClazz().getClazzLoader();
                  for (int i = 0; i < paramClasses.length; i++){
                      String name = Clazz.getCanonicalClassName(paramClasses[i]);
                      parameterClazzes[i] = loader.getClazzForName(name);
                  }
              }
          }
          return parameterClazzes;
      }
  
      public Object newInstance(Object[] parameters) {
          try {
              return constructor.newInstance(parameters);
          }
          catch (Throwable e) {
              throw new ClazzAccessException(
                  "Cannot invoke constructor " + getSignature(),
                  e);
          }
      }
  
      public String toString(){
          return getSignature();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedConstructorInstanceFactoryIntrospector.java
  
  Index: ReflectedConstructorInstanceFactoryIntrospector.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.ReflectedInstanceFactoryIntrospector;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedConstructorInstanceFactoryIntrospector.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedConstructorInstanceFactoryIntrospector
      implements ReflectedInstanceFactoryIntrospector {
  
      public static final 
          ReflectedConstructorInstanceFactoryIntrospector INTROSPECTOR =
              new ReflectedConstructorInstanceFactoryIntrospector();
  
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected ReflectedConstructorInstanceFactoryIntrospector(){
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedInstanceFactoryIntrospector#introspectInstanceFactories(org.apache.commons.clazz.reflect.ReflectedClazz, java.lang.Class)
       */
      public List introspectInstanceFactories(
              ReflectedClazz clazz,
              Class javaClass) 
      {
          ArrayList list = new ArrayList();
          Constructor constructors[] = javaClass.getDeclaredConstructors();
          for (int i = 0; i < constructors.length; i++) {
              Constructor constructor = constructors[i];
              if (Modifier.isPublic(constructor.getModifiers())) {
                  list.add(
                      new ReflectedConstructorInstanceFactory(
                          clazz,
                          constructor));
              }
          }
          return list;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedMethodFeatureSupport.java
  
  Index: ReflectedMethodFeatureSupport.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Method;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzFeature;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  
  /**
   * A wrapper for a java method.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMethodFeatureSupport.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedMethodFeatureSupport extends ClazzFeatureSupport 
          implements ClazzFeature 
  {
      private Method method;
      private String signature;
      private static final Clazz[] EMPTY_CLAZZ_ARRAY = new Clazz[0];
      private Clazz[] parameterClazzes;
      boolean returnClazzCached = false;
      private Clazz returnClazz;
      
      /**
       * Constructor for ReflectedClazzProperty.
       */
      public ReflectedMethodFeatureSupport(Clazz declaringClazz, Method method) {
          super(declaringClazz);
          this.method = method;
      }
  
      public Method getMethod(){
          return method;
      }
      
      public String getName(){
          return method.getName();
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getSignature()
       */
      public String getSignature() {
          if (signature == null) {
              signature =
                  Clazz.constructSignature(
                      method.getName(),
                      method.getParameterTypes());
          }
          return signature;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getParameterClazzes()
       */
      public Clazz[] getParameterClazzes() {
          if (parameterClazzes == null){
              Class paramClasses[] = method.getParameterTypes();
              if (paramClasses == null){
                  parameterClazzes = EMPTY_CLAZZ_ARRAY;
              }
              else {
                  parameterClazzes = new Clazz[paramClasses.length];
                  ClazzLoader loader = getDeclaringClazz().getClazzLoader();
                  for (int i = 0; i < paramClasses.length; i++){
                      String name = Clazz.getCanonicalClassName(paramClasses[i]);
                      parameterClazzes[i] = loader.getClazzForName(name);                    
                  }
              }
          }
          return parameterClazzes;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#getReturnClazz()
       */
      public Clazz getReturnClazz() {
          if (!returnClazzCached){
              returnClazzCached = true;
              Class returnType = method.getReturnType();
              if (returnType == null || returnType.equals(Void.TYPE)){
                  returnClazz = null;
              }
              else {
                  ClazzLoader loader = getDeclaringClazz().getClazzLoader();
                  returnClazz = loader.getClazzForName(returnType.getName());
              }
          }
          return returnClazz;
      }
  
      public String toString(){
          return getSignature();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedMethodInstanceFactory.java
  
  Index: ReflectedMethodInstanceFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Method;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzAccessException;
  import org.apache.commons.clazz.ClazzInstanceFactory;
  
  /**
   * A wrapper for a static java method that returns an instance of the Clazz.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMethodInstanceFactory.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedMethodInstanceFactory 
          extends ReflectedMethodFeatureSupport 
          implements ClazzInstanceFactory 
  {
      /**
       * Constructor for ReflectedClazzProperty.
       */
      public ReflectedMethodInstanceFactory(
              Clazz declaringClazz,
              Method method) 
      {
          super(declaringClazz, method);
      }
  
      public Object newInstance(Object[] parameters) {
          try {
              return getMethod().invoke(null, parameters);
          }
          catch (Throwable e) {
              throw new ClazzAccessException(
                  "Cannot invoke static method " + getSignature(),
                  e);
          }
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedMethodInstanceFactoryIntrospector.java
  
  Index: ReflectedMethodInstanceFactoryIntrospector.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.ReflectedInstanceFactoryIntrospector;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMethodInstanceFactoryIntrospector.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedMethodInstanceFactoryIntrospector
      implements ReflectedInstanceFactoryIntrospector {
  
      public static final ReflectedMethodInstanceFactoryIntrospector INTROSPECTOR =
          new ReflectedMethodInstanceFactoryIntrospector();
  
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected ReflectedMethodInstanceFactoryIntrospector() {
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedInstanceFactoryIntrospector#introspectInstanceFactories(org.apache.commons.clazz.reflect.ReflectedClazz, java.lang.Class)
       */
      public List introspectInstanceFactories(
          ReflectedClazz clazz,
          Class javaClass) 
      {
          ArrayList list = new ArrayList();
          Method methods[] = javaClass.getMethods();
          for (int i = 0; i < methods.length; i++) {
              Method method = methods[i];
              int modifiers = method.getModifiers();
              if (Modifier.isStatic(modifiers)
                  && javaClass.equals(method.getReturnType())) {
                  list.add(new ReflectedMethodInstanceFactory(clazz, method));
              }
          }
          return list;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedMethodOperation.java
  
  Index: ReflectedMethodOperation.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Method;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzAccessException;
  import org.apache.commons.clazz.ClazzOperation;
  
  /**
   * A ClazzOperation that is a wrapper for a java method.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMethodOperation.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedMethodOperation extends ReflectedMethodFeatureSupport 
          implements ClazzOperation 
  {    
      /**
       * Constructor for ReflectedMethodOperation.
       */
      public ReflectedMethodOperation(Clazz declaringClazz, Method method) {
          super(declaringClazz, method);
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzOperation#invoke(java.lang.Object, java.lang.Object)
       */
      public Object invoke(Object target, Object[] parameters) {
          try {
              return getMethod().invoke(target, parameters);
          }
          catch (Throwable e) {
              throw new ClazzAccessException(
                  "Cannot invoke method " + getSignature(),
                  e);
          }
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedMethodOperationIntrospector.java
  
  Index: ReflectedMethodOperationIntrospector.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.common;
  
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.ReflectedOperationIntrospector;
  
  /**
   * A ReflectedOperationIntrospector that discovers an operation for each public
   * method of the class.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMethodOperationIntrospector.java,v 1.1 2002/12/14 02:38:42 dmitri Exp $
   */
  public class ReflectedMethodOperationIntrospector 
              implements ReflectedOperationIntrospector 
  {
      public static final ReflectedMethodOperationIntrospector INTROSPECTOR =
              new ReflectedMethodOperationIntrospector();
   
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected ReflectedMethodOperationIntrospector(){
      }
      
      public List introspectOperations(
              ReflectedClazz clazz,
              Class javaClass)
      {
          ArrayList list = new ArrayList();
          Method methods[] = javaClass.getDeclaredMethods();
          for (int i = 0; i < methods.length; i++){
              Method method = methods[i];
              if (Modifier.isPublic(method.getModifiers())){
                  list.add(new ReflectedMethodOperation(clazz, method));
              }
          }
          return list;
      }
  }
  
  
  
  1.2       +26 -2     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ExtendedReflectedClazzLoader.java
  
  Index: ExtendedReflectedClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ExtendedReflectedClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExtendedReflectedClazzLoader.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ExtendedReflectedClazzLoader.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -58,6 +58,8 @@
   import org.apache.commons.clazz.common.GroupClazzLoader;
   import org.apache.commons.clazz.reflect.ReflectedClazz;
   import org.apache.commons.clazz.reflect.ReflectedClazzLoader;
  +import org.apache.commons.clazz.reflect.ReflectedInstanceFactoryIntrospector;
  +import org.apache.commons.clazz.reflect.ReflectedOperationIntrospector;
   import org.apache.commons.clazz.reflect.ReflectedPropertyIntrospector;
   import org.apache.commons.clazz.reflect.common.*;
   
  @@ -83,6 +85,26 @@
               ReflectedMappedPropertyIntrospector.INTROSPECTOR,
               ReflectedScalarPropertyIntrospector.INTROSPECTOR };
   
  +    /**
  +     * The default list of introspectors consists just the basic method-to-
  +     * operation introspector.
  +     */
  +    private static final
  +            ReflectedOperationIntrospector[] DEFAULT_OPERATION_INTROSPECTORS =
  +        new ReflectedOperationIntrospector[] {
  +            ReflectedMethodOperationIntrospector.INTROSPECTOR
  +        };
  +        
  +    /**
  +     * The default list of introspectors consists just the basic constructor-to-
  +     * factory introspector.
  +     */
  +    private static final
  +        ReflectedInstanceFactoryIntrospector[] DEFAULT_FACTORY_INTROSPECTORS =
  +        new ReflectedInstanceFactoryIntrospector[] {
  +            ReflectedConstructorInstanceFactoryIntrospector.INTROSPECTOR,
  +            ReflectedMethodInstanceFactoryIntrospector.INTROSPECTOR
  +        };
   
       /**
        * Constructor for ExtendedReflectedClazzLoader.
  @@ -103,6 +125,8 @@
           return new ReflectedClazz(
               clazzLoader,
               javaClass,
  -            DEFAULT_PROPERTY_INTROSPECTORS);
  +            DEFAULT_PROPERTY_INTROSPECTORS,
  +            DEFAULT_OPERATION_INTROSPECTORS,
  +            DEFAULT_FACTORY_INTROSPECTORS);
       }
   }
  
  
  
  1.2       +47 -1     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ExtendedReflectedListPropertyIntrospector.java
  
  Index: ExtendedReflectedListPropertyIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ExtendedReflectedListPropertyIntrospector.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExtendedReflectedListPropertyIntrospector.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ExtendedReflectedListPropertyIntrospector.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -186,6 +186,17 @@
                   parseResults.setRemoveMethodParseResults(results);
                   continue;
               }
  +
  +            results = parseRemoveIndexedMethod(method);
  +            if (results != null){
  +                parseResults =
  +                    getParseResults(
  +                        clazz,
  +                        parseResultMapSingular,
  +                        results.getPropertyName());
  +                parseResults.setRemoveIndexedMethodParseResults(results);
  +                continue;
  +            }
           }
           
           Iterator iter = parseResultMap.entrySet().iterator();
  @@ -277,6 +288,37 @@
        * <ul>
        *  <li>Name starts with "remove" followed by capitalized singular
        *      form of the property name</li>
  +     *  <li>One integer parameter</li>
  +     * </ul>
  +     */
  +    protected static AccessorMethodParser REMOVE_INDEXED_METHOD_PARSER =
  +            new AccessorMethodParser()
  +    {
  +        protected String requiredPrefix(){
  +            return "remove";
  +        }
  +
  +        protected int requiredParameterCount(){
  +            return 1;
  +        }
  +
  +        protected boolean testParameterType(int index, Class parameterType){
  +            return parameterType.equals(Integer.TYPE);
  +        }
  +    };
  +
  +    /**
  +     * @see #parseReadMethod
  +     */
  +    public AccessorMethodParseResults parseRemoveIndexedMethod(Method method) {
  +        return REMOVE_INDEXED_METHOD_PARSER.parse(method);
  +    }
  +
  +    /**
  +     * Parser for the <code>removeFoo(value)</code> method:
  +     * <ul>
  +     *  <li>Name starts with "remove" followed by capitalized singular
  +     *      form of the property name</li>
        *  <li>One parameter</li>
        * </ul>
        */                        
  @@ -291,6 +333,10 @@
               return 1;
           }
   
  +        protected boolean testParameterType(int index, Class parameterType){
  +            return !parameterType.equals(Integer.TYPE);
  +        }
  +        
           protected Class getValueType(Method method){
               return method.getParameterTypes()[0];
           }
  
  
  
  1.2       +361 -96   jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMap.java
  
  Index: ReflectedMap.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedMap.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedMap.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -53,10 +53,12 @@
    */
   package org.apache.commons.clazz.reflect.extended;
   
  +import java.lang.reflect.Array;
  +import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
   import java.util.*;
   
  -import org.apache.commons.clazz.reflect.ReflectedAccessException;
  +import org.apache.commons.clazz.ClazzAccessException;
   
   
   /**
  @@ -78,10 +80,11 @@
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedMap implements Map 
  +public class ReflectedMap extends AbstractMap 
   {
       private Object instance;
       private ReflectedMappedProperty property;
  +    private int modCount = 0;
       
       /**
        * Constructor for ReflectedMap.
  @@ -93,35 +96,78 @@
           this.instance = instance;
           this.property = property;
       }
  -
  -    /**
  -     * If there is a removeFoo(key) method, calls that for every key.
  -     * Otherwise, calls getFooMap().clear()
  -     * 
  -     * @see java.util.Map#clear()
  -     */
  -    public void clear() {
  +    
  +    public Map getPropertyValue(){
  +        Method readMethod = property.getReadMethod();
  +        if (readMethod == null){
  +            throw new ClazzAccessException(
  +                "Cannot read property "
  +                    + property.getName()
  +                    + ": no read method");
  +        }
  +        try {
  +            return (Map)readMethod.invoke(instance, null);
  +        }
  +        catch (Exception ex) {
  +            throw accessException("Cannot read property", readMethod, ex);
  +        }
       }
   
  -    /**
  -     * @see java.util.Map#containsKey(java.lang.Object)
  -     */
  -    public boolean containsKey(Object key) {
  -        return false;
  -    }
  +    public void setPropertyValue(Map value) {
  +        Method writeMethod = property.getWriteMethod();
  +        if (writeMethod == null){
  +            throw new ClazzAccessException(
  +                "Cannot set property: "
  +                    + property.getName()
  +                    + ": no set(array) method");
  +        }
   
  -    /**
  -     * @see java.util.Map#containsValue(java.lang.Object)
  -     */
  -    public boolean containsValue(Object value) {
  -        return false;
  +        try {
  +            writeMethod.invoke(instance, new Object[] { value });
  +        }
  +        catch (Exception ex) {
  +            throw accessException("Cannot set property", writeMethod, ex);
  +        }
       }
   
  -    /**
  -     * @see java.util.Map#entrySet()
  -     */
  -    public Set entrySet() {
  -        return null;
  +    public Set getPropertyKeySet() {
  +        Method keySetMethod = property.getKeySetMethod();
  +        if (keySetMethod != null) {
  +            Set set;
  +            try {
  +                Object value = keySetMethod.invoke(instance, null);
  +                if (value == null) {
  +                    set = Collections.EMPTY_SET;
  +                }
  +                else if (value instanceof Set) {
  +                    set = (Set) value;
  +                }
  +                else if (value instanceof Collection) {
  +                    set = new ConcurrentChangeSafeSet((Collection) value);
  +                }
  +                else {
  +                    set =
  +                        new ConcurrentChangeSafeSet(
  +                            Arrays.asList((Object[]) value));
  +                }
  +            }
  +            catch (Exception ex) {
  +                throw new ClazzAccessException(
  +                    "Cannot get key set: "
  +                        + property.getName()
  +                        + ": cannot invoke method: "
  +                        + keySetMethod.getName(),
  +                    ex);
  +            }
  +            return set;
  +        }
  +        else {
  +            Map map = getPropertyValue();
  +            if (map == null) {
  +                return Collections.EMPTY_SET;
  +            }
  +            return map.keySet();
  +        }
       }
   
       /**
  @@ -138,7 +184,7 @@
                   value = getMethod.invoke(instance, new Object[]{key});
               }
               catch (Exception ex) {
  -                throw new ReflectedAccessException(
  +                throw new ClazzAccessException(
                       "Cannot get property : "
                           + property.getName()
                           + ": cannot invoke method: "
  @@ -148,7 +194,7 @@
               return value;
           }
           else {
  -            Map map = property.getMap(instance);
  +            Map map = getPropertyValue();
               if (map == null){
                   return null;
               }
  @@ -157,54 +203,58 @@
       }
   
       /**
  -     * @see java.util.Map#isEmpty()
  -     */
  -    public boolean isEmpty() {
  -        return false;
  -    }
  -
  -    /**
  -     * @see java.util.Map#keySet()
  +     * @see java.util.Map#size()
        */
  -    public Set keySet() {
  +    public int size() {
           Method keySetMethod = property.getKeySetMethod();
  -        if (keySetMethod != null){
  -            Set set;
  +        if (keySetMethod != null) {
               try {
                   Object value = keySetMethod.invoke(instance, null);
  -                if (value == null){
  -                    set = Collections.EMPTY_SET;
  -                }
  -                else if (value instanceof Set){
  -                    set = (Set)value;
  +                if (value == null) {
  +                    return 0;
                   }
  -                else if (value instanceof Collection){
  -                    set = new HashSet((Collection)value);
  +                else if (value instanceof Collection) {
  +                    return ((Collection) value).size();
                   }
                   else {
  -                    set = new HashSet(Arrays.asList((Object[])value));
  +                    return Array.getLength(value);
                   }
               }
               catch (Exception ex) {
  -                throw new ReflectedAccessException(
  -                    "Cannot get key set: "
  -                        + property.getName()
  -                        + ": cannot invoke method: "
  -                        + keySetMethod.getName(),
  -                    ex);
  +                throw accessException("Cannot get key set", keySetMethod, ex);
               }
  -            return set;
           }
           else {
  -            Map map = property.getMap(instance);
  -            if (map == null){
  -                return Collections.EMPTY_SET;
  +            Map map = getPropertyValue();
  +            if (map == null) {
  +                return 0;
               }
  -            return map.keySet();
  +            return map.size();
           }
       }
   
       /**
  +     * @see java.util.Map#isEmpty()
  +     */
  +    public boolean isEmpty() {
  +        return size() == 0;
  +    }
  +
  +    /**
  +     * @see java.util.Map#keySet()
  +     */
  +    public Set keySet() {
  +        return new EntrySet(KEYS);
  +    }
  +    
  +    /**
  +     * @see java.util.Map#entrySet()
  +     */
  +    public Set entrySet() {
  +        return new EntrySet(ENTRIES);
  +    }
  +    
  +    /**
        * @see java.util.Map#put(java.lang.Object, java.lang.Object)
        */
       public Object put(Object key, Object value) {        
  @@ -222,7 +272,7 @@
                   putMethod.invoke(instance, new Object[]{key, value});
               }
               catch (Exception ex) {
  -                throw new ReflectedAccessException(
  +                throw new ClazzAccessException(
                       "Cannot set property : "
                           + property.getName()
                           + ": cannot invoke method: "
  @@ -232,60 +282,275 @@
               return oldValue;
           }
           else {
  -            Map map = property.getMap(instance);
  +            Map map = getPropertyValue();
               if (map == null){
                   map = new HashMap();
  -                
  -                Method writeMethod = property.getWriteMethod();
  -                if (writeMethod != null){
  -                    try {
  -                        writeMethod.invoke(instance, new Object[]{map});
  -                    }
  -                    catch (Exception ex) {
  -                        throw new ReflectedAccessException(
  -                            "Cannot set property : "
  -                                + property.getName()
  -                                + ": cannot invoke method: "
  -                                + writeMethod.getName(),
  -                            ex);
  -                    }        
  -                }
  -                else {
  -                    throw new ReflectedAccessException(
  -                        "Cannot set property : "
  -                            + property.getName()
  -                            + ": no write method");
  -                }
  +                setPropertyValue(map);
               }
               return map.put(key, value);
           }
       }
   
       /**
  -     * @see java.util.Map#putAll(java.util.Map)
  -     */
  -    public void putAll(Map t) {
  -    }
  -
  -    /**
        * @see java.util.Map#remove(java.lang.Object)
        */
       public Object remove(Object key) {
  -        return null;
  +        Method removeMethod = property.getRemoveMethod();
  +        if (removeMethod != null){
  +            Object oldValue = null;
  +            try {
  +                oldValue = get(key);
  +            }
  +            catch (Throwable t){
  +                // Ignore
  +            }
  +
  +            try {
  +                removeMethod.invoke(instance, new Object[]{key});
  +            }
  +            catch (Exception ex) {
  +                throw new ClazzAccessException(
  +                    "Cannot set property : "
  +                        + property.getName()
  +                        + ": cannot invoke method: "
  +                        + removeMethod.getName(),
  +                    ex);
  +            }
  +            return oldValue;
  +        }
  +        else {
  +            Map map = getPropertyValue();
  +            if (map != null){
  +                return map.remove(key);
  +            }
  +            return null;
  +        }
  +    }
  +    
  +    private RuntimeException accessException(
  +        String message,
  +        Method method,
  +        Throwable ex)
  +    {
  +        if (ex instanceof InvocationTargetException) {
  +            ex = ((InvocationTargetException) ex).getTargetException();
  +        }
  +
  +        // Just re-throw all runtime exceptions - there is really no
  +        // point in wrapping them
  +        if (ex instanceof RuntimeException) {
  +            throw (RuntimeException) ex;
  +        }
  +        if (ex instanceof Error) {
  +            throw (Error) ex;
  +        }
  +
  +        throw new ClazzAccessException(
  +            message
  +                + ": "
  +                + property.getName()
  +                + ": cannot invoke method: "
  +                + method.getName(),
  +            ex);
       }
   
  +    private static final int ENTRIES = 0;
  +    private static final int KEYS = 1;
  +    
       /**
  -     * @see java.util.Map#size()
  +     * An implementation of Set that delegates object deletion to the
  +     * encompassing ReflectedMap.
        */
  -    public int size() {
  -        return 0;
  -    }
  +    private class EntrySet extends AbstractSet {
  +        private int type;
  +        private int modCount = -1;
  +        private Set keySet;
  +        private int size;        
  +
  +        public EntrySet(int type){
  +            this.type = type;
  +            update();            
  +        }
   
  +        public void refresh(){
  +            // If EntrySet is out of sync with the 
  +            // parent ReflectedMap, update the cached key set and size
  +            if (modCount != ReflectedMap.this.modCount){
  +                update();
  +            }
  +        }
  +
  +        public void update(){
  +            // Make sure modCount of EntrySet is maintained in sync with
  +            // that of the embracing List
  +            modCount = ReflectedMap.this.modCount;
  +            
  +            keySet = ReflectedMap.this.getPropertyKeySet();
  +            size = keySet.size();
  +        }
  +        
  +        public int size(){
  +            refresh();
  +            return size;
  +        }
  +        
  +        public Iterator iterator(){
  +            refresh();
  +            return new EntryIterator(keySet, type);
  +        }
  +        
  +        public boolean remove(Object object){
  +            refresh();
  +            Object key =
  +                (type == KEYS ? object : ((Map.Entry) object).getKey());
  +                
  +            boolean exists = true;
  +            try {
  +                exists = keySet.contains(key);
  +            }
  +            catch (Throwable t){
  +                // Ignore
  +            }
  +            if (exists){
  +                ReflectedMap.this.remove(key);
  +            }
  +            return exists;
  +        }
  +    }
  +    
       /**
  -     * @see java.util.Map#values()
  +     * An implementation of Iterator that delegates object deletion to the
  +     * encompassing ReflectedMap.
        */
  -    public Collection values() {
  -        return null;
  +    private class EntryIterator implements Iterator {
  +        private int type;
  +        private Set keySet;
  +        private Iterator keyIterator;
  +        private Object lastReturned = UNINITIALIZED;
  +        
  +        public EntryIterator(Set keySet, int type){
  +            this.type = type;
  +            this.keySet = keySet;
  +            this.keyIterator = keySet.iterator();
  +        }
  +        
  +        /**
  +         * @see java.util.Iterator#hasNext()
  +         */
  +        public boolean hasNext() {
  +            return keyIterator.hasNext();
  +        }
  +
  +        /**
  +         * @see java.util.Iterator#next()
  +         */
  +        public Object next() {            
  +            lastReturned = keyIterator.next();
  +            if (type == KEYS){
  +                return lastReturned;
  +            }
  +            else {
  +                return new Entry(lastReturned);
  +            }
  +        }
  +
  +        /**
  +         * @see java.util.Iterator#remove()
  +         */
  +        public void remove() {
  +            if (lastReturned == UNINITIALIZED){
  +                throw new IllegalStateException();
  +            }
  +            ensureConcurrentChangeSafety();
  +            ReflectedMap.this.remove(lastReturned);
  +        }
  +
  +        /**
  +         * This is called when we are about to delete a key from the map.
  +         * The method checks if the set of keys we are iterating over is in fact
  +         * a copy of the set of keys of the original collection.  If it is not,
  +         * the method creates such copy and re-executes the iteration steps that
  +         * have already been made.  The assumption made here is that as long as
  +         * set remains unchanged, an iteration will always present elements in
  +         * the same order (which is not to say that the order is predicatble).
  +         */
  +        private void ensureConcurrentChangeSafety() {
  +            if (!(keySet instanceof ConcurrentChangeSafeSet)) {
  +                keySet = new ConcurrentChangeSafeSet(keySet);
  +                keyIterator = keySet.iterator(); 
  +                while (keyIterator.hasNext()) {
  +                    Object key = keyIterator.next();
  +                    if ((key == null && lastReturned == null)
  +                        || (key != null && key.equals(lastReturned))) {
  +                        return;
  +                    }
  +                }
  +                throw new IllegalStateException(
  +                    "The second iteration over the key set"
  +                        + " did not produce the same elements");
  +            }
  +        }
       }
  +    
  +    private static final Object UNINITIALIZED = new Object();
  +    
  +    /**
  +     * An implementation of Map.Entry that maintains a key and gets the value
  +     * from the property, if needed.
  +     */
  +    private class Entry implements Map.Entry {
  +        private Object key;
  +        
  +        public Entry(Object key) {
  +            this.key = key;            
  +        }
  +        
  +        /**
  +         * @see java.util.Map.Entry#getKey()
  +         */
  +        public Object getKey() {
  +            return key;
  +        }
  +        /**
  +         * @see java.util.Map.Entry#getValue()
  +         */
  +        public Object getValue() {
  +            return ReflectedMap.this.get(key);
  +        }
  +        
  +        /**
  +         * @see java.util.Map.Entry#setValue(java.lang.Object)
  +         */
  +        public Object setValue(Object value) {
  +            return ReflectedMap.this.put(key, value);
  +        }        
  +
  +        public boolean equals(Object o) {
  +            if (!(o instanceof Map.Entry)) {
  +                return false;
  +            }
  +            
  +            Map.Entry e = (Map.Entry) o;
  +            return (key == null ? e.getKey() == null : key.equals(e.getKey()));
  +        }
  +
  +        public int hashCode() {
  +            return key == null ? 0 : key.hashCode();
  +        }
   
  +        public String toString() {
  +            return key + "=" + getValue();
  +        }        
  +    }
  +    
  +    /**
  +     * This is a simple HashSet. We are only introducing the subclass as a
  +     * marker of the fact that we created the set rather than getting it
  +     * directly from the map value of the property.
  +     */
  +    private static class ConcurrentChangeSafeSet extends HashSet {
  +        public ConcurrentChangeSafeSet(Collection collection){
  +            super(collection);
  +        }
  +    }
   }
  
  
  
  1.2       +9 -9      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedProperty.java
  
  Index: ReflectedMappedProperty.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedProperty.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedMappedProperty.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedMappedProperty.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -57,14 +57,14 @@
   import java.util.Map;
   
   import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.reflect.ReflectedProperty;
  +import org.apache.commons.clazz.reflect.common.ReflectedAccessorPairProperty;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedMappedProperty extends ReflectedProperty {
  +public class ReflectedMappedProperty extends ReflectedAccessorPairProperty {
   
       private Class keyType;
       private Class contentType;
  @@ -204,27 +204,27 @@
           }
           buffer.append(getName());
           if (getReadMethod() != null){
  -            buffer.append("\n   [read method]   ");
  +            buffer.append("\n   [read method]      ");
               buffer.append(getReadMethod());            
           }
           if (getWriteMethod() != null){
  -            buffer.append("\n   [write method]  ");
  +            buffer.append("\n   [write method]     ");
               buffer.append(getWriteMethod());            
           }
           if (getGetMethod() != null){
  -            buffer.append("\n   [get method]    ");
  +            buffer.append("\n   [get method]       ");
               buffer.append(getGetMethod());            
           }
           if (getPutMethod() != null){
  -            buffer.append("\n   [put method]    ");
  +            buffer.append("\n   [put method]       ");
               buffer.append(getPutMethod());            
           }
           if (getRemoveMethod() != null){
  -            buffer.append("\n   [remove method] ");
  +            buffer.append("\n   [remove method]    ");
               buffer.append(getRemoveMethod());            
           }
           if (getKeySetMethod() != null){
  -            buffer.append("\n   [keySet method] ");
  +            buffer.append("\n   [keySet method]    ");
               buffer.append(getKeySetMethod());            
           }
           buffer.append("]");
  
  
  
  1.2       +3 -3      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyIntrospector.java
  
  Index: ReflectedMappedPropertyIntrospector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyIntrospector.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedMappedPropertyIntrospector.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedMappedPropertyIntrospector.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -84,7 +84,7 @@
       
       /**
        * Goes over methods of the supplied class and creates 
  -     * ReflectedProperty objects for discovered properties.
     */
  +     * ReflectedAccessorPairProperty objects for discovered properties.
     */
       public void introspectProperties(
               ReflectedClazz clazz,
               Class javaClass,
  @@ -509,7 +509,7 @@
       /**
        * Creates a new ReflectedMappedProperty based on parse results. 
        */
  -    protected ReflectedProperty createProperty(
  +    protected ReflectedAccessorPairProperty createProperty(
           ReflectedClazz clazz,
           ReflectedPropertyParseResults parseResults)
       {
  
  
  
  1.2       +4 -3      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyParseResults.java
  
  Index: ReflectedMappedPropertyParseResults.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyParseResults.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedMappedPropertyParseResults.java	6 Dec 2002 01:12:49 -0000	1.1
  +++ ReflectedMappedPropertyParseResults.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -56,6 +56,7 @@
   import java.lang.reflect.Method;
   import java.util.Map;
   
  +import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.reflect.ReflectedClazz;
   import org.apache.commons.clazz.reflect.common.AccessorMethodParseResults;
   import org.apache.commons.clazz.reflect.common.ReflectedPropertyParseResults;
  @@ -235,13 +236,13 @@
           Class keyType = getKeyType();
           if (keyType != null){
               buffer.append("\n  [key type]       ");
  -            buffer.append(keyType.getName());
  +            buffer.append(Clazz.getCanonicalClassName(keyType));
           }
           
           Class contentType = getContentType();
           if (contentType != null){
               buffer.append("\n  [content type]   ");
  -            buffer.append(contentType.getName());
  +            buffer.append(Clazz.getCanonicalClassName(contentType));
           }
       }
       
  
  
  
  1.2       +28 -2     jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/standard/StandardReflectedClazzLoader.java
  
  Index: StandardReflectedClazzLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/standard/StandardReflectedClazzLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StandardReflectedClazzLoader.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ StandardReflectedClazzLoader.java	14 Dec 2002 02:38:42 -0000	1.2
  @@ -58,6 +58,8 @@
   import org.apache.commons.clazz.common.GroupClazzLoader;
   import org.apache.commons.clazz.reflect.ReflectedClazz;
   import org.apache.commons.clazz.reflect.ReflectedClazzLoader;
  +import org.apache.commons.clazz.reflect.ReflectedInstanceFactoryIntrospector;
  +import org.apache.commons.clazz.reflect.ReflectedOperationIntrospector;
   import org.apache.commons.clazz.reflect.ReflectedPropertyIntrospector;
   import org.apache.commons.clazz.reflect.common.*;
   
  @@ -80,6 +82,28 @@
               ReflectedScalarPropertyIntrospector.INTROSPECTOR };
   
       /**
  +     * The default list of introspectors consists just the basic method-to-
  +     * operation introspector.
  +     */
  +    private static final
  +            ReflectedOperationIntrospector[] STANDARD_OPERATION_INTROSPECTORS =
  +        new ReflectedOperationIntrospector[] {
  +            ReflectedMethodOperationIntrospector.INTROSPECTOR
  +        };
  +
  +    /**
  +     * The default list of introspectors consists just the basic constructor-to-
  +     * factory introspector.
  +     */
  +    private static final
  +        ReflectedInstanceFactoryIntrospector[] STANDARD_FACTORY_INTROSPECTORS =
  +        new ReflectedInstanceFactoryIntrospector[] {
  +            ReflectedConstructorInstanceFactoryIntrospector.INTROSPECTOR,
  +            ReflectedMethodInstanceFactoryIntrospector.INTROSPECTOR
  +        };
  +
  +
  +    /**
        * Constructor for StandardReflectedClazzLoader.
        * @param group
        * @param classLoader
  @@ -98,6 +122,8 @@
           return new ReflectedClazz(
               clazzLoader,
               javaClass,
  -            STANDARD_PROPERTY_INTROSPECTORS);
  +            STANDARD_PROPERTY_INTROSPECTORS,
  +            STANDARD_OPERATION_INTROSPECTORS,
  +            STANDARD_FACTORY_INTROSPECTORS);
       }
   }
  
  
  
  1.2       +38 -1     jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/ClazzTestSupport.java
  
  Index: ClazzTestSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/ClazzTestSupport.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ClazzTestSupport.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ ClazzTestSupport.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -93,4 +93,41 @@
   //        System.out.println("Actual:   " + testName + names);
           assertEquals(testName, expectedList, names);
       }
  +
  +    public void assertOperationList(
  +            String testName,
  +            String[] expectedSignatures,
  +            List operations)
  +    {
  +        List expectedList = Arrays.asList(expectedSignatures);
  +        Collections.sort(expectedList);
  +        List signatures = new ArrayList();
  +        for (Iterator iter = operations.iterator(); iter.hasNext();) {
  +            ClazzOperation operation = (ClazzOperation) iter.next();
  +            signatures.add(operation.getSignature());
  +        }
  +        Collections.sort(signatures);
  +//        System.out.println("Expected: " + testName + expectedList);
  +//        System.out.println("Actual:   " + testName + signatures);
  +        assertEquals(testName, expectedList, signatures);
  +    }
  +    
  +    
  +    public void assertInstanceFactoryList(
  +            String testName,
  +            String[] expectedSignatures,
  +            List factories)
  +    {
  +        List expectedList = Arrays.asList(expectedSignatures);
  +        Collections.sort(expectedList);
  +        List signatures = new ArrayList();
  +        for (Iterator iter = factories.iterator(); iter.hasNext();) {
  +            ClazzInstanceFactory factory = (ClazzInstanceFactory) iter.next();
  +            signatures.add(factory.getSignature());
  +        }
  +        Collections.sort(signatures);
  +//        System.out.println("Expected: " + testName + expectedList);
  +//        System.out.println("Actual:   " + testName + signatures);
  +        assertEquals(testName, expectedList, signatures);
  +    }
   }
  
  
  
  1.2       +2 -2      jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/bean/BeanClazzLoaderTest.java
  
  Index: BeanClazzLoaderTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/bean/BeanClazzLoaderTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BeanClazzLoaderTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ BeanClazzLoaderTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -86,7 +86,7 @@
           BeanClazz clazz =
               (BeanClazz) Clazz.getDefaultClazzLoader().defineClazz(
                   BeanClazzTest.TEST_CLAZZ_NAME,
  -                BeanClazz.class);
  +                BeanClazz.class, null);
           assertNotNull(clazz);
           ClazzProperty prop1 =
               new BeanClazzProperty(clazz, "integerProperty", "int");
  
  
  
  1.2       +122 -13   jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/bean/BeanClazzTest.java
  
  Index: BeanClazzTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/bean/BeanClazzTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BeanClazzTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ BeanClazzTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -53,9 +53,14 @@
    */
   package org.apache.commons.clazz.bean;
   
  +import java.util.HashMap;
  +import java.util.Map;
  +
   import junit.framework.TestSuite;
   
   import org.apache.commons.clazz.Clazz;
  +import org.apache.commons.clazz.ClazzInstanceFactory;
  +import org.apache.commons.clazz.ClazzOperation;
   import org.apache.commons.clazz.ClazzProperty;
   import org.apache.commons.clazz.ClazzTestSupport;
   
  @@ -91,7 +96,7 @@
       }
   
       public static TestSuite suite(){
  -        TestSuite suite = new TestSuite("Bean clazz tests");
  +        TestSuite suite = new TestSuite("BeanClazz tests");
           suite.addTestSuite(BeanClazzLoaderTest.class);
           suite.addTestSuite(BeanClazzTest.class);
           return suite;
  @@ -101,24 +106,57 @@
           superClazz =         
               (BeanClazz) Clazz.getDefaultClazzLoader().defineClazz(
                   TEST_SUPERCLAZZ_NAME,
  -                BeanClazz.class);
  -        superClazz.addDeclaredProperty(
  -            new BeanClazzProperty(superClazz));
  -        superClazz.addDeclaredProperty(
  -            new BeanClazzProperty(superClazz, "baseProperty"));
  +                BeanClazz.class, null);
                   
           clazz =
               (BeanClazz) Clazz.getDefaultClazzLoader().defineClazz(
                   TEST_CLAZZ_NAME,
  -                BeanClazz.class);                
  +                BeanClazz.class, null);                
           clazz.setSuperclazz(superClazz);
           
  -        clazz.addDeclaredProperty(
  -            new BeanClazzProperty(clazz));
  +        superClazz.addDeclaredProperty(
  +            new BeanClazzProperty(superClazz, "baseProperty"));
           clazz.addDeclaredProperty(
               new BeanClazzProperty(clazz, "objectProperty"));
           clazz.addDeclaredProperty(
               new BeanClazzProperty(clazz, "integerProperty", "int"));
  +            
  +            
  +        clazz.addDeclaredOperation(
  +            new BeanClazzOperaiton(clazz, null, "twoPlusTwo", null){
  +                public Object invoke(Object instance, Object[] parameters){
  +                    return new Integer(4);
  +                }
  +            }
  +        );
  +
  +        clazz.addDeclaredOperation(
  +            new BeanClazzOperaiton(
  +                    clazz,
  +                    "java.lang.Integer",
  +                    "computeAplusB",
  +                    new String[] { "java.lang.Integer", "java.lang.Integer" }) {
  +                public Object invoke(Object instance, Object[] parameters) {
  +                    Integer arg1 = (Integer)parameters[0];
  +                    Integer arg2 = (Integer)parameters[1];
  +                    return new Integer(arg1.intValue() + arg2.intValue());
  +                }
  +            }
  +        );
  +        
  +        clazz.addInstanceFactory(
  +            new BeanClazzInstanceFactory(
  +                    clazz, 
  +                    null, 
  +                    new String[]{"java.lang.String"}){
  +                public Object newInstance(Object parameters[]){
  +                    String value = (String)parameters[0];
  +                    BasicBean bb = new BasicBean(clazz);
  +                    bb.set("objectProperty", value);
  +                    return bb;
  +                }
  +            }
  +        );
       }
       
       public void testGetName() {
  @@ -151,7 +189,6 @@
               new String[]{
                   "integerProperty",
                   "objectProperty",
  -                "property2"
               },
               clazz.getDeclaredProperties());       
       }
  @@ -163,8 +200,6 @@
                   "baseProperty",
                   "integerProperty",
                   "objectProperty",
  -                "property1",
  -                "property2",
               },
               clazz.getProperties());
       }
  @@ -182,12 +217,55 @@
       }
       
       public void testGetOperations() {
  +        assertOperationList(
  +            "Get operations",
  +            new String[]{
  +                "twoPlusTwo()",
  +                "computeAplusB(java.lang.Integer,java.lang.Integer)"
  +            },
  +            clazz.getOperations());
       }
   
       public void testGetDeclaredOperations() {
       }
   
       public void testGetOperation() {
  +        ClazzOperation op = clazz.getOperation("twoPlusTwo()");
  +        assertNotNull(op);
  +    }
  +
  +    public void testInvokeOperationWithoutParameters() {
  +        ClazzOperation op = clazz.getOperation("twoPlusTwo()");
  +        Object object = clazz.newInstance();
  +        op.invoke(object, null);
  +    }
  +    
  +    public void testInvokeOperationWithParameters() {
  +        ClazzOperation op =
  +            clazz.getOperation(
  +                "computeAplusB(java.lang.Integer,java.lang.Integer)");
  +        Object object = clazz.newInstance();
  +        Object result =
  +            op.invoke(object, new Object[] { new Integer(3), new Integer(4)});
  +        assertEquals("Result value", new Integer(7), result);
  +    }
  +    
  +    public void testGetInstanceFactories() {
  +        assertInstanceFactoryList(
  +            "Get instance factories",
  +            new String[]{
  +                "()",
  +                "(java.util.Map)",
  +                "(java.lang.String)"
  +            },
  +            clazz.getInstanceFactories());
  +    }
  +
  +    public void testGetInstanceFactory() {
  +        ClazzInstanceFactory factory =
  +            clazz.getInstanceFactory("(java.util.Map)");
  +        assertNotNull(factory);
  +        assertEquals("Signature", "(java.util.Map)", factory.getSignature());
       }
   
       /*
  @@ -203,6 +281,37 @@
        * Test for Object newInstance(Object[])
        */
       public void testNewInstanceObjectArray() {
  +        Map initialValues = new HashMap();
  +        initialValues.put("integerProperty", new Integer(3));
  +        
  +        Object object =
  +            clazz.newInstance(
  +                "(java.util.Map)",
  +                new Object[] { initialValues });
  +                
  +        assertNotNull(object);
  +        assertTrue("New instance type ", object instanceof BasicBean);
  +        assertEquals(
  +            "Property value",
  +            new Integer(3),
  +            ((BasicBean) object).get("integerProperty"));
  +    }
  +
  +    /*
  +     * Test for Object newInstance(Object[])
  +     */
  +    public void testNewInstanceWithCustomFactory() {
  +        Object object =
  +            clazz.newInstance(
  +                "(java.lang.String)",
  +                new Object[] { "foo" });
  +
  +        assertNotNull(object);
  +        assertTrue("New instance type ", object instanceof BasicBean);
  +        assertEquals(
  +            "Property value",
  +            "foo",
  +            ((BasicBean) object).get("objectProperty"));
       }
   
       public void testAddDeclaredProperty() {
  
  
  
  1.3       +80 -2     jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectableInstance.java
  
  Index: ReflectableInstance.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectableInstance.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReflectableInstance.java	6 Dec 2002 01:12:50 -0000	1.2
  +++ ReflectableInstance.java	14 Dec 2002 02:38:43 -0000	1.3
  @@ -54,6 +54,7 @@
   package org.apache.commons.clazz.reflect;
   
   import java.util.ArrayList;
  +import java.util.Collections;
   import java.util.HashMap;
   import java.util.List;
   import java.util.Map;
  @@ -77,6 +78,13 @@
       private List stringList = new ArrayList();
       private String notAProperty;        // Get/set have different types
       
  +    public ReflectableInstance(){
  +    }
  +    
  +    public ReflectableInstance(int intInit){
  +        integerProperty = intInit;
  +    }
  +    
       public List trace(){
           return traceList;
       }
  @@ -89,6 +97,17 @@
           traceList.add(methodName);
       }
       
  +    public String getter(){
  +        return null;
  +    }
  +    
  +    public String get2er(){
  +        return null;
  +    }
  +    
  +    public String get_er(){
  +        return null;
  +    }
       
       /**
        * Please note that the write method for this property
  @@ -135,9 +154,12 @@
           this.booleanProperty = booleanProperty;
       }
   
  +    /**
  +     * MappedStrings property has the full set of accessors.
  +     */
       public Map getMappedStrings(){
           trace("getMappedStrings()");
  -        return mappedStrings;
  +        return Collections.unmodifiableMap(mappedStrings);
       }
       
       public void setMappedStrings(Map mappedStrings){
  @@ -238,6 +260,11 @@
           stringList.remove(string);
       }
       
  +    public void removeString(int index){
  +        trace("removeString(int)");
  +        stringList.remove(index);
  +    }
  +
       public int getStringCount(){
           trace("getStringCount()");
           return stringList.size();
  @@ -274,5 +301,56 @@
        * If there is not "get" method, there is no mapped property
     */
       public void setNotAMappedProperty(String key, String value){
           trace("setNotAMappedProperty(String,String)");
  +    }
  +    
  +    public void doNothing(){
  +    }
  +
  +    public String toUpperCase(String string){
  +        return string.toUpperCase();
  +    }
  +    
  +    public void scalars(
  +            boolean a,
  +            byte b,
  +            char c,
  +            short d,
  +            int e,
  +            long f,
  +            float g,
  +            double h,
  +            Object i,
  +            String j) 
  +    {
  +    }
  +    
  +    public void arrays(
  +            boolean[] a,
  +            byte[] b,
  +            char[] c,
  +            short[] d,
  +            int[] e,
  +            long[] f,
  +            float[] g,
  +            double[] h,
  +            Object[] i,
  +            String[] j,
  +            boolean[][] k,
  +            String[][] l            
  +            )
  +    {
  +    }
  +    
  +    /**
  +     * Factory method
  +     */
  +    public static ReflectableInstance createInstance(
  +        boolean boolProp,
  +        int intProp) 
  +    {
  +        ReflectableInstance ri = new ReflectableInstance();
  +        ri.setBooleanProperty(boolProp);
  +        ri.setIntegerProperty(intProp);
  +        return ri;
       }
   }
  
  
  
  1.3       +16 -11    jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedClazzTestSupport.java
  
  Index: ReflectedClazzTestSupport.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedClazzTestSupport.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ReflectedClazzTestSupport.java	6 Dec 2002 01:12:50 -0000	1.2
  +++ ReflectedClazzTestSupport.java	14 Dec 2002 02:38:43 -0000	1.3
  @@ -55,6 +55,7 @@
   
   import java.lang.reflect.Method;
   import java.util.ArrayList;
  +import java.util.Arrays;
   import java.util.Collections;
   import java.util.List;
   
  @@ -71,7 +72,7 @@
   {
       protected ReflectableInstance instance;
       protected Clazz clazz;
  -    private static boolean ENABLE_LOGGING = true;
  +    private static boolean ENABLE_LOGGING = false;
       
       /**
        * Constructor for ReflectedClazzTestSupport.
  @@ -81,6 +82,13 @@
           super(name);
       }
   
  +    /**
  +     * Override to test out different Clazz models.
  +     *
  +     * @return ClazzLoader
  +     */
  +    protected abstract ClazzLoader getClazzLoader();
  +
   
       /**
        * @see TestCase#setUp()
  @@ -92,13 +100,6 @@
               getClazzLoader().enableLogging(clazz.getName());
           }
       }
  -    
  -    /**
  -     * Override to test out different Clazz models.
  -     * 
  -     * @return ClazzLoader
  -     */
  -    protected abstract ClazzLoader getClazzLoader();
   
       protected void assertMethodSignature(
               String text,
  @@ -141,5 +142,9 @@
           methods.add(method2);
           assertEquals("Methods invoked for " + text, methods, instance.trace());
       }
  -
  -}
  +    
  +    protected void assertTrace(String text, String[] methodArray) {
  +        List methods = Arrays.asList(methodArray);
  +        assertEquals("Methods invoked for " + text, methods, instance.trace());
  +    }
  + }
  
  
  
  1.3       +183 -125  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedClazzTest.java
  
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedInstanceFactoryTest.java
  
  Index: ReflectedInstanceFactoryTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzInstanceFactory;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedInstanceFactoryTest.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public abstract class ReflectedInstanceFactoryTest extends ReflectedClazzTestSupport 
  {
      protected ClazzInstanceFactory zeroParameterFactory;
      protected ClazzInstanceFactory oneParameterFactory;
      protected ClazzInstanceFactory staticMethodFactory;
  
      /**
       * Constructor for ReflectedInstanceFactoryTest.
       * @param name
       */
      public ReflectedInstanceFactoryTest(String name) {
          super(name);
      }
  
      public void setUp() throws Exception {
          super.setUp();
          zeroParameterFactory =
              clazz.getInstanceFactory("()");
  
          oneParameterFactory =
              clazz.getInstanceFactory("(int)");
   
          staticMethodFactory =
              clazz.getInstanceFactory("createInstance(boolean,int)");
      }
  
      public void testGetDeclaringClazz() {
          assertTrue(
              "declaring clazz",
              zeroParameterFactory.getDeclaringClazz() == clazz);
      }
  
      public void testGetSignature() {
          assertEquals(
              "Signature",
              "()",
              zeroParameterFactory.getSignature());
          assertEquals(
              "Signature",
              "(int)",
              oneParameterFactory.getSignature());
          assertEquals(
              "Signature",
              "createInstance(boolean,int)",
              staticMethodFactory.getSignature());
      }
  
      public void testGetParameterClazzesScalar() {
          Clazz params[] = staticMethodFactory.getParameterClazzes();
          assertNotNull(params);
          assertEquals("Parameter count", 2, params.length);
          assertEquals("Param 0", "boolean", params[0].getName());
          assertEquals("Param 1", "int", params[1].getName());
      }
  
      public void testNewInstanceZeroArguments() {
          Object result =
              zeroParameterFactory.newInstance(null);
          assertNotNull(result);
          assertEquals("Clazz instance class", ReflectableInstance.class, result);
      }
  
      public void testNewInstanceOneArgument() {
          Object result =
              oneParameterFactory.newInstance(new Object[] { new Integer(3)});
          assertNotNull(result);
          assertEquals("Clazz instance class", ReflectableInstance.class, result);
          assertEquals(
              "Initialization",
              3,
              ((ReflectableInstance) result).getIntegerProperty());
      }
  
      public void testNewInstanceStaticMethod() {
          Object result =
              staticMethodFactory.newInstance(
                  new Object[] { Boolean.TRUE, new Integer(4)});
          assertNotNull(result);
          assertEquals("Clazz instance class", ReflectableInstance.class, result);
          assertEquals(
              "Initialization",
              true,
              ((ReflectableInstance) result).isBooleanProperty());
          assertEquals(
              "Initialization",
              4,
              ((ReflectableInstance) result).getIntegerProperty());
      }
  
      /*
       * Test for String toString()
       */
      public void testToString() {
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedListPropertyTestSupport.java
  
  Index: ReflectedListPropertyTestSupport.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect;
  
  import java.util.ArrayList;
  import java.util.ConcurrentModificationException;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.commons.clazz.reflect.common.ReflectedListProperty;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedListPropertyTestSupport.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public abstract class ReflectedListPropertyTestSupport 
          extends ReflectedClazzTestSupport
  {
      protected ReflectedListProperty intArrayProperty;
      protected ReflectedListProperty stringProperty;
      
      /**
       * Constructor for ReflectedPropertyMapTest.
       * @param name Is the test method name
       */
      public ReflectedListPropertyTestSupport(String name) {
          super(name);
      }
  
      public void setUp() throws Exception {
          super.setUp();
          intArrayProperty = 
              (ReflectedListProperty)clazz.getProperty("intArray");
          stringProperty = 
              (ReflectedListProperty)clazz.getProperty("string");
      }
  
      public void testSizeWithArray(){
          populateIntArray();
  
          List list = (List)intArrayProperty.get(instance);
          int count = list.size();
  
          assertTrace(
              "getting size with count getter",
              "getIntArray()");
          assertEquals(3, count);
      }
  
      public void testSizeWithEmpty() {
          List list = (List)intArrayProperty.get(instance);
          int count = list.size();
          
          assertTrace("getting size", "getIntArray()");
          assertEquals(0, count);
      }
  
      public void testIsEmptyWithArray() {
          List list = (List)intArrayProperty.get(instance);
          boolean empty = list.isEmpty();
          assertTrace("empty", "getIntArray()");
          assertTrue(empty);
  
          populateIntArray();        
  //        list = (List)intArrayProperty.get(instance);
          empty = list.isEmpty();
          assertTrace("not empty", "getIntArray()");
          assertTrue(!empty);
      }
  
      public void testContainsWithArraySuccess() {
          populateIntArray();
          
          List list = (List)intArrayProperty.get(instance);
          boolean contains = list.contains(new Integer(2));
          assertTrace("contains", "getIntArray()");
          assertTrue(contains);
      }
      
      public void testContainsWithArrayFailure() {
          populateIntArray();
  
          List list = (List)intArrayProperty.get(instance);
          boolean contains = list.contains(new Integer(371));
          assertTrace("does not contain", "getIntArray()");
          assertTrue(!contains);
      }
  
      public void testIteratorWithArray() {
          populateIntArray();
          
          List list = (List)intArrayProperty.get(instance);
          Iterator it = list.iterator();
          ArrayList result = new ArrayList();
          while (it.hasNext()){
              result.add(it.next());
          }        
          
          assertTrace("iterator", "getIntArray()");
          
          ArrayList expected = new ArrayList();
          expected.add(new Integer(1));
          expected.add(new Integer(2));
          expected.add(new Integer(3));
          
          assertEquals("iterator", expected, result);
      }
  
      /*
       * Test for Object[] toArray()
       */
      public void testToArray() {
      }
  
      /*
       * Test for Object[] toArray(Object[])
       */
      public void testToArrayObjectArray() {
      }
  
      /*
       * Test for boolean add(Object)
       */
      public void testAddObjectWithArrayStartEmpty() {
          List list = (List)intArrayProperty.get(instance);
          list.add(new Integer(1));
  
          assertTrace("add", "getIntArray()", "setIntArray(int[])");
  
          ArrayList expected = new ArrayList();
          expected.add(new Integer(1));
          assertEquals("result of add via list", expected, list);
          
          int array[] = instance.getIntArray();        
          assertEquals("result of add directly (length)", 1, array.length);
          assertEquals("result of add directly (value)", 1, array[0]);
      }
  
      /*
       * Test for boolean add(Object)
       */
      public void testAddObjectWithArrayStartPopulated() {
          populateIntArray();
          
          List list = (List)intArrayProperty.get(instance);
          list.add(new Integer(4));
  
          assertTrace("add", "getIntArray()", "setIntArray(int[])");
  
  //        System.err.println("LIST: " + list);
          ArrayList expected = new ArrayList();
          expected.add(new Integer(1));
          expected.add(new Integer(2));
          expected.add(new Integer(3));
          expected.add(new Integer(4));
          assertEquals("result of add via list", expected, list);
  
          int array[] = instance.getIntArray();
          assertEquals("result of add directly (length)", 4, array.length);
          assertEquals("result of add directly (value)", 4, array[3]);
      }
      
      /*
       * Test for boolean add(Object)
       */
      public void testConcurrentModificationException() {
          populateIntArray();
  
          boolean ex = false;
          List list = (List)intArrayProperty.get(instance);
          Iterator it = list.iterator();
          it.next();
          list.add(new Integer(4));
          try {
              it.next();
          }
          catch (ConcurrentModificationException e){
              ex = true;
          }
          
          assertTrue("concurrent mod exception", ex);
      }
  
      /*
       * Test for boolean remove(Object)
       */
      public void testRemoveObjectFromArray() {
          populateIntArray();
  
          List list = (List)intArrayProperty.get(instance);
          list.remove(new Integer(2));
  
          assertTrace(
              "remove",
              new String[] {
                  "getIntArray()",            // For iteration
                  "getIntArray()",            // For removal
                  "setIntArray(int[])" });    // New shorter array
          
          ArrayList expected = new ArrayList();
          expected.add(new Integer(1));
          expected.add(new Integer(3));
          assertEquals("result of remove via list", expected, list);
  
          int array[] = instance.getIntArray();
          assertEquals("result of remove directly (length)", 2, array.length);
      }
  
      /*
       * Test for Object remove(int)
       */
      public void testRemoveWithIndexFromArray() {
          populateIntArray();
  
          List list = (List)intArrayProperty.get(instance);
          list.remove(1);
  
          assertTrace("remove", "getIntArray()", "setIntArray(int[])");
  
          ArrayList expected = new ArrayList();
          expected.add(new Integer(1));
          expected.add(new Integer(3));
          assertEquals("result of remove via list", expected, list);
  
          int array[] = instance.getIntArray();
          assertEquals("result of remove directly (length)", 2, array.length);
      }
      
      public void testContainsAll() {
      }
  
      /*
       * Test for boolean addAll(Collection)
       */
      public void testAddAllCollection() {
      }
  
      /*
       * Test for boolean addAll(int, Collection)
       */
      public void testAddAllICollection() {
      }
  
      public void testRemoveAll() {
      }
  
      public void testRetainAll() {
      }
  
      public void testClear() {
      }
  
      public void testGetWithArray() {
          populateIntArray();
                  
          List list = (List)intArrayProperty.get(instance);
          Object value = list.get(1);
          
          assertTrace(
              "getting value with direct getter",
              "getIntArray()");
          assertEquals(new Integer(2), value);
      }
  
      public void testGetWithList() {
          populateStringList();
          
          List list = (List)stringProperty.get(instance);
          Object value = list.get(1);
          
          assertTrace(
              "getting value with parameterized getter",
              "getString(int)");
              
          assertEquals("bar", value);
      }
  
      public void testSetWithArray() {
          populateIntArray();
          
          List list = (List)intArrayProperty.get(instance);
          list.set(1, new Integer(7));
          
          assertTrace(
              "setting value with direct getter",
              "getIntArray()");
          assertEquals(7, instance.getIntArray()[1]);
      }
      
      public void testSetWithList() {
          populateStringList();
          
          List list = (List)stringProperty.get(instance);
          list.set(1, "biz");
          
          assertTrace(
              "setting value with parameterized setter",
              "getString(int)",
              "setString(int,String)");
              
          assertEquals("biz", instance.getString(1));
      }
  
      public void testIndexOf() {
      }
  
      public void testLastIndexOf() {
      }
  
      /*
       * Test for ListIterator listIterator()
       */
      public void testListIterator() {
      }
  
      /*
       * Test for ListIterator listIterator(int)
       */
      public void testListIteratorI() {
      }
  
      public void testSubList() {
      }
      
      /**
       * We are supposed to get different results for standard and extended models
       * when the corresponding property does not have a <code>get</code> method
       * that returns the whole list. The extended model can still take care of
       * this as long as there is a <code>get<i>Foo</i>Count()</code> method.
       */
      public abstract void testSizeWithList();
      public abstract void testIsEmptyWithList();    
      public abstract void testContainsWithListSuccess();
      public abstract void testContainsWithListFailure();
      public abstract void testIteratorWithList();
      public abstract void testAddObjectWithListStartEmpty();
      public abstract void testAddObjectWithListStartPopulated();
      public abstract void testAddIndexedWithList();
  
      public void populateIntArray() {
          instance.setIntArray(new int[]{1, 2, 3});
          instance.resetTrace();
      }
  
      public void populateStringList() {
          instance.addString("foo");
          instance.addString("bar");
          instance.addString("baz");
          instance.resetTrace();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedOperationTest.java
  
  Index: ReflectedOperationTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzOperation;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedOperationTest.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public abstract class ReflectedOperationTest extends ReflectedClazzTestSupport 
  {
      protected ClazzOperation voidOperationWithoutParameters;
      protected ClazzOperation stringOperationWithParameters;
      protected ClazzOperation operationWithScalarParameters;
      protected ClazzOperation operationWithArrayParameters;
      
      /**
       * Constructor for ReflectedOperationTest.
       * @param name
       */
      public ReflectedOperationTest(String name) {
          super(name);
      }
      
      public void setUp() throws Exception {
          super.setUp();
          voidOperationWithoutParameters =
              clazz.getOperation("doNothing()");
              
          stringOperationWithParameters =
              clazz.getOperation("toUpperCase(java.lang.String)");
              
          operationWithScalarParameters =
              clazz.getOperation(
                  "scalars("
                      + "boolean,byte,char,short,int,long,float,double,"
                      + "java.lang.Object,java.lang.String)");
                      
          operationWithArrayParameters =
              clazz.getOperation(
                  "arrays("
                      + "boolean[],byte[],char[],short[],"
                      + "int[],long[],float[],double[],"
                      + "java.lang.Object[],java.lang.String[],"
                      + "boolean[][],java.lang.String[][])");
      }
  
      public void testGetDeclaringClazz() {
          assertTrue(
              "declaring clazz",
              stringOperationWithParameters.getDeclaringClazz() == clazz);
      }
  
      public void testGetSignature() {
          assertEquals(
              "Signature",
              "toUpperCase(java.lang.String)",
              stringOperationWithParameters.getSignature());
      }
  
      public void testGetParameterClazzesScalar() {
          Clazz params[] = operationWithScalarParameters.getParameterClazzes();
          assertNotNull(params);
          assertEquals("Parameter count", 10, params.length);
          assertEquals("Param 0", "boolean", params[0].getName());
          assertEquals("Param 1", "byte", params[1].getName());
          assertEquals("Param 2", "char", params[2].getName());
          assertEquals("Param 3", "short", params[3].getName());
          assertEquals("Param 4", "int", params[4].getName());
          assertEquals("Param 5", "long", params[5].getName());
          assertEquals("Param 6", "float", params[6].getName());
          assertEquals("Param 7", "double", params[7].getName());
          assertEquals("Param 8", "java.lang.Object", params[8].getName());
          assertEquals("Param 9", "java.lang.String", params[9].getName());
      }
  
      public void testGetParameterClazzesArrays() {
          Clazz params[] = operationWithArrayParameters.getParameterClazzes();
          assertNotNull(params);
          assertEquals("Parameter count", 12, params.length);
          assertEquals("Param 0", "boolean[]", params[0].getName());
          assertEquals("Param 1", "byte[]", params[1].getName());
          assertEquals("Param 2", "char[]", params[2].getName());
          assertEquals("Param 3", "short[]", params[3].getName());
          assertEquals("Param 4", "int[]", params[4].getName());
          assertEquals("Param 5", "long[]", params[5].getName());
          assertEquals("Param 6", "float[]", params[6].getName());
          assertEquals("Param 7", "double[]", params[7].getName());
          assertEquals("Param 8", "java.lang.Object[]", params[8].getName());
          assertEquals("Param 9", "java.lang.String[]", params[9].getName());
          assertEquals("Param 10", "boolean[][]", params[10].getName());
          assertEquals("Param 11", "java.lang.String[][]", params[11].getName());
      }
  
      public void testGetReturnClazz() {
          Clazz returnClazz = stringOperationWithParameters.getReturnClazz();
          assertNotNull(returnClazz);
          assertEquals("Return clazz", "java.lang.String", returnClazz.getName()); 
      }
  
      public void testInvokeWithStringResult() {
          Object result =
              stringOperationWithParameters.invoke(
                  new ReflectableInstance(),
                  new Object[] { "foo" });
          assertNotNull(result);
          assertEquals("Return type", String.class, result.getClass());
          assertEquals("Return value", "FOO", result);
      }
  
      public void testInvokeWithVoidResult() {
          Object result =
              voidOperationWithoutParameters.invoke(
                  new ReflectableInstance(),
                  null);
          assertNull(result);
      }
      
      /*
       * Test for String toString()
       */
      public void testToString() {
      }
  
  }
  
  
  
  1.2       +7 -101    jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedClazzTest.java
  
  Index: ExtendedReflectedClazzTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedClazzTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExtendedReflectedClazzTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ ExtendedReflectedClazzTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -57,20 +57,18 @@
   
   import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzLoader;
  -import org.apache.commons.clazz.ClazzProperty;
   import org.apache.commons.clazz.reflect.ReflectableInstance;
  -import org.apache.commons.clazz.reflect.ReflectedClazzTestSupport;
  -import org.apache.commons.clazz.reflect.common.ReflectedScalarProperty;
  +import org.apache.commons.clazz.reflect.ReflectedClazzTest;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ExtendedReflectedClazzTest extends ReflectedClazzTestSupport {
  +public class ExtendedReflectedClazzTest extends ReflectedClazzTest {
   
       /**
  -     * Constructor for ExtendedReflectedClazzTest.
  +     * Constructor for ReflectedClazzTest.
        * @param name
        */
       public ExtendedReflectedClazzTest(String name) {
  @@ -82,10 +80,12 @@
       }
   
       public static TestSuite suite(){
  -        TestSuite suite = new TestSuite();
  +        TestSuite suite = new TestSuite("ExtendedReflectedClazz tests");
           suite.addTestSuite(ExtendedReflectedClazzTest.class);
           suite.addTestSuite(ExtendedReflectedListPropertyTest.class);
           suite.addTestSuite(ReflectedMappedPropertyTest.class);
  +        suite.addTestSuite(ExtendedReflectedOperationTest.class);
  +        suite.addTestSuite(ExtendedReflectedInstanceFactoryTest.class);
           return suite;
       }
   
  @@ -155,99 +155,5 @@
                   "baseProperty",
               },
               clazz.getSuperclazz().getDeclaredProperties());
  -    }
  -    
  -    /**
  -     * Checks that get/set methods are recognized properly.
     */
  -    public void testRecognitionOfScalarPropertyMethods(){
  -        ReflectedScalarProperty property = 
  -            (ReflectedScalarProperty)clazz.getProperty("integerProperty");
  -            
  -        assertMethodSignature("Read method",
  -            "getIntegerProperty()",
  -            property.getReadMethod());
  -            
  -        assertMethodSignature("Write method",
  -            "setIntegerProperty(int)",
  -            property.getWriteMethod());
  -    }
  -    
  -    /**
  -     * Checks that the "is" method is recognized for a boolean property.
  -     */
  -    public void testRecognitionOfScalarBooleanPropertyMethods(){
  -        ReflectedScalarProperty property = 
  -            (ReflectedScalarProperty)clazz.getProperty("booleanProperty");
  -            
  -        assertMethodSignature("Read method",
  -            "isBooleanProperty()",
  -            property.getReadMethod());
  -            
  -        assertMethodSignature("Write method",
  -            "setBooleanProperty(boolean)",
  -            property.getWriteMethod());
  -    }
  -    
  -    public void testGetOperations() {
  -    }
  -
  -    public void testGetDeclaredOperations() {
  -    }
  -
  -    public void testGetOperation() {
  -    }
  -
  -    /*
  -     * Test for Object newInstance()
  -     */
  -    public void testNewInstance() {
  -        Object object = clazz.newInstance();
  -        assertNotNull(object);
  -        assertTrue("New instance type ", object instanceof ReflectableInstance);
  -    }
  -
  -    /*
  -     * Test for Object newInstance(Object[])
  -     */
  -    public void testNewInstanceObjectArray() {
  -    }
  -
  -    public void testGetName() {
  -        assertEquals(instance.getClass().getName(), clazz.getName());
  -    }
  -
  -    public void testGetPackageName() {
  -        String pname = ReflectableInstance.class.getName().substring(0, 
  -                ReflectableInstance.class.getName().lastIndexOf('.'));
  -        assertEquals(pname, clazz.getPackageName());
  -    }
  -
  -    public void testGetShortClassName() {
  -        String cname = ReflectableInstance.class.getName().substring( 
  -                ReflectableInstance.class.getName().lastIndexOf('.') + 1);
  -        assertEquals(cname, clazz.getShortClassName());
  -    }
  -
  -    public void testIsAssignableFrom() {
  -    }
  -
  -    public void testGetScalarPropertyValue(){
  -        ClazzProperty property =
  -            (ClazzProperty) clazz.getProperty("integerProperty");
  -        Object result = property.get(instance);
  -        assertTrace(
  -            "getting scalar property value",
  -            "getIntegerProperty()");
  -        assertEquals(result, new Integer(0));
  -    }
  -    
  -    public void testPutScalarPropertyValue(){
  -        ClazzProperty property =
  -            (ClazzProperty) clazz.getProperty("integerProperty");
  -        property.set(instance, new Integer(3));
  -        assertTrace(
  -            "setting scalar property value",
  -            "setIntegerProperty()");
  -        assertEquals(3, instance.getIntegerProperty());
       }
   }
  
  
  
  1.2       +155 -157  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedListPropertyTest.java
  
  Index: ExtendedReflectedListPropertyTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedListPropertyTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExtendedReflectedListPropertyTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ ExtendedReflectedListPropertyTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -53,26 +53,23 @@
    */
   package org.apache.commons.clazz.reflect.extended;
   
  +import java.util.ArrayList;
  +import java.util.Iterator;
   import java.util.List;
   
   import junit.framework.TestSuite;
   
   import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzLoader;
  -import org.apache.commons.clazz.reflect.ReflectedClazzTestSupport;
  -import org.apache.commons.clazz.reflect.common.ReflectedList;
  -import org.apache.commons.clazz.reflect.common.ReflectedListProperty;
  +import org.apache.commons.clazz.reflect.ReflectedListPropertyTestSupport;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ExtendedReflectedListPropertyTest extends ReflectedClazzTestSupport
  +public class ExtendedReflectedListPropertyTest extends ReflectedListPropertyTestSupport
   {
  -    private ReflectedListProperty intArrayProperty;
  -    private ReflectedListProperty stringProperty;
  -    
       /**
        * Constructor for ReflectedPropertyMapTest.
        * @param name Is the test method name
  @@ -88,20 +85,11 @@
       public static TestSuite suite(){
           return new TestSuite(ExtendedReflectedListPropertyTest.class);
       }
  -    
  -    public void setUp() throws Exception {
  -        super.setUp();
  -        intArrayProperty = 
  -            (ReflectedListProperty)clazz.getProperty("intArray");
  -        stringProperty = 
  -            (ReflectedListProperty)clazz.getProperty("string");
  -    }
   
       protected ClazzLoader getClazzLoader(){
           return Clazz.getClazzLoader(Clazz.DEFAULT_CLAZZLOADER);
       }
   
  -    
       /**
        * Checks the set of methods recognized for a List property that
        * does not have regular get/set methods.
  @@ -169,28 +157,11 @@
           assertNull("Size method",
               intArrayProperty.getSizeMethod());
       }
  -    
  -    public void testGetListPropertyValue(){
  -        Object result = intArrayProperty.get(instance);
  -        assertTraceEmpty(
  -            "getting List property value");
  -            
  -        assertTrue(result instanceof ReflectedList);
  -    }
  -        
  -    public void testSizeWithArray() {
  -        instance.setIntArray(new int[]{1, 2, 3});
  -        instance.resetTrace();
  -        
  -        List list = (List)intArrayProperty.get(instance);
  -        int count = list.size();
  -        
  -        assertTrace(
  -            "getting size with direct getter",
  -            "getIntArray()");
  -        assertEquals(3, count);
  -    }
   
  +    /**
  +     * The test checks that the <code>getStringCount()</code> method is used,
  +     * this would not work in the standard case. 
  +     */
       public void testSizeWithList() {
           instance.addString("foo");
           instance.addString("bar");
  @@ -206,162 +177,189 @@
           assertEquals(3, count);
       }
       
  -    public void testSizeWithEmpty() {
  -        List list = (List)intArrayProperty.get(instance);
  -        int count = list.size();
  -        
  -        assertTrace(
  -            "getting size with count getter",
  -            "getIntArray()");
  -        assertEquals(0, count);
  +    public void testIsEmptyWithList(){
  +        List list = (List)stringProperty.get(instance);
  +        boolean empty = list.isEmpty();
  +        assertTrace("empty", "getStringCount()");
  +        assertTrue(empty);
  +
  +        populateStringList();
  +
  +        list = (List)stringProperty.get(instance);
  +        empty = list.isEmpty();
  +        assertTrace("not empty", "getStringCount()");
  +        assertTrue(!empty);
       }
       
  -    public void testIsEmpty() {
  -    }
  +    public void testContainsWithListSuccess() {
  +        populateStringList();
   
  -    public void testContains() {
  +        List list = (List) stringProperty.get(instance);
  +        boolean contains = list.contains("foo");
  +        assertTrace("contains", "getStringCount()", "getString(int)");
  +        assertTrue(contains);
       }
  +    
  +    public void testContainsWithListFailure() {
  +        populateStringList();
   
  -    public void testIterator() {
  +        List list = (List) stringProperty.get(instance);
  +        boolean contains = list.contains("abracadabra");
  +        assertTrace(
  +            "does not contain",
  +            new String[] {
  +                "getStringCount()",
  +                "getString(int)",
  +                "getString(int)",
  +                "getString(int)" });
  +        assertTrue(!contains);
       }
  +    
  +    public void testIteratorWithList() {
  +        populateStringList();
   
  -    /*
  -     * Test for Object[] toArray()
  -     */
  -    public void testToArray() {
  -    }
  +        List list = (List)stringProperty.get(instance);
  +        Iterator it = list.iterator();
  +        ArrayList result = new ArrayList();
  +        while (it.hasNext()){
  +            result.add(it.next());
  +        }
   
  -    /*
  -     * Test for Object[] toArray(Object[])
  -     */
  -    public void testToArrayObjectArray() {
  -    }
  +        assertTrace(
  +            "iterator",
  +                new String[] {
  +                    "getStringCount()",
  +                    "getString(int)",
  +                    "getString(int)",
  +                    "getString(int)"});
  +
  +        ArrayList expected = new ArrayList();
  +        expected.add("foo");
  +        expected.add("bar");
  +        expected.add("baz");
   
  +        assertEquals("iterator", expected, result);
  +    }    
  +    
       /*
        * Test for boolean add(Object)
        */
  -    public void testAddObject() {
  -    }
  -
  -    /*
  -     * Test for boolean remove(Object)
  -     */
  -    public void testRemoveObject() {
  -    }
  +    public void testAddObjectWithListStartEmpty() {
  +        List list = (List)stringProperty.get(instance);
  +        list.add("biz");
   
  -    public void testContainsAll() {
  -    }
  +        assertTrace("add", "addString()");
   
  -    /*
  -     * Test for boolean addAll(Collection)
  -     */
  -    public void testAddAllCollection() {
  +        ArrayList expected = new ArrayList();
  +        expected.add("biz");
  +        assertEquals("result of add via list", expected, list);
  +
  +        assertEquals(
  +            "result of add directly (length)",
  +            1,
  +            instance.getStringCount());
  +        assertEquals(
  +            "result of add directly (value)",
  +            "biz",
  +            instance.getString(0));
       }
   
       /*
  -     * Test for boolean addAll(int, Collection)
  +     * Test for boolean add(Object)
        */
  -    public void testAddAllICollection() {
  -    }
  +    public void testAddObjectWithListStartPopulated() {
  +        populateStringList();
   
  -    public void testRemoveAll() {
  -    }
  -
  -    public void testRetainAll() {
  -    }
  +        List list = (List)stringProperty.get(instance);
  +        list.add("biz");
   
  -    public void testClear() {
  -    }
  +        assertTrace("add", "addString()");
   
  -    public void testGetWithArray() {
  -        instance.setIntArray(new int[]{1, 2, 3});
  -        instance.resetTrace();
  -        
  -        List list = (List)intArrayProperty.get(instance);
  -        Object value = list.get(1);
  -        
  -        assertTrace(
  -            "getting value with direct getter",
  -            "getIntArray()");
  -        assertEquals(new Integer(2), value);
  +        ArrayList expected = new ArrayList();
  +        expected.add("foo");
  +        expected.add("bar");
  +        expected.add("baz");
  +        expected.add("biz");
  +        assertEquals("result of add via list", expected, list);
  +
  +        assertEquals(
  +            "result of add directly (length)",
  +            4,
  +            instance.getStringCount());
  +        assertEquals(
  +            "result of add directly (value)",
  +            "biz",
  +            instance.getString(3));
       }
  +    
  +    /*
  +     * Test for boolean add(Object)
  +     */
  +    public void testAddIndexedWithList() {
  +        populateStringList();
   
  -    public void testGetWithList() {
  -        instance.addString("foo");
  -        instance.addString("bar");
  -        instance.addString("baz");
  -        instance.resetTrace();
  -        
           List list = (List)stringProperty.get(instance);
  -        Object value = list.get(1);
  -        
  -        assertTrace(
  -            "getting value with parameterized getter",
  -            "getString(int)");
  -            
  -        assertEquals("bar", value);
  -    }
  +        list.add(1, "biz");
   
  -    public void testSetWithArray() {
  -        instance.setIntArray(new int[]{1, 2, 3});
  -        instance.resetTrace();
  -        
  -        List list = (List)intArrayProperty.get(instance);
  -        list.set(1, new Integer(7));
  -        
  -        assertTrace(
  -            "setting value with direct getter",
  -            "getIntArray()");
  -        assertEquals(7, instance.getIntArray()[1]);
  -    }
  -    
  -    public void testSetWithList() {
  -        instance.addString("foo");
  -        instance.addString("bar");
  -        instance.addString("baz");
  -        instance.resetTrace();
  -        
  -        List list = (List)stringProperty.get(instance);
  -        list.set(1, "biz");
  -        
  -        assertTrace(
  -            "setting value with parameterized setter",
  -            "getString(int)",
  -            "setString(int,String)");
  -            
  -        assertEquals("biz", instance.getString(1));
  -    }
  +        assertTrace("add", "addString(int,String)");
   
  -    /*
  -     * Test for void add(int, Object)
  -     */
  -    public void testAddIObject() {
  +        ArrayList expected = new ArrayList();
  +        expected.add("foo");
  +        expected.add("biz");
  +        expected.add("bar");
  +        expected.add("baz");
  +        assertEquals("result of add via list", expected, list);
  +
  +        assertEquals(
  +            "result of add directly (length)",
  +            4,
  +            instance.getStringCount());
  +        assertEquals(
  +            "result of add directly (value)",
  +            "biz",
  +            instance.getString(1));
       }
   
       /*
  -     * Test for Object remove(int)
  +     * Test for boolean remove(Object)
        */
  -    public void testRemoveI() {
  -    }
  +    public void testRemoveObjectFromList() {
  +        populateStringList();
   
  -    public void testIndexOf() {
  -    }
  +        List list = (List) stringProperty.get(instance);
  +        list.remove("bar");
   
  -    public void testLastIndexOf() {
  -    }
  +        assertTrace("remove", "removeString(String)");
   
  -    /*
  -     * Test for ListIterator listIterator()
  -     */
  -    public void testListIterator() {
  +        ArrayList expected = new ArrayList();
  +        expected.add("foo");
  +        expected.add("baz");
  +        assertEquals("result of remove via list", expected, list);
  +        assertEquals(
  +            "result of remove directly (length)",
  +            2,
  +            instance.getStringCount());
       }
   
       /*
  -     * Test for ListIterator listIterator(int)
  +     * Test for Object remove(int)
        */
  -    public void testListIteratorI() {
  -    }
  +    public void testRemoveWithIndexFromList() {
  +        populateStringList();
  +
  +        List list = (List)stringProperty.get(instance);
  +        list.remove(1);
  +
  +        assertTrace("remove", "getString(int)", "removeString(int)");
   
  -    public void testSubList() {
  +        ArrayList expected = new ArrayList();
  +        expected.add("foo");
  +        expected.add("baz");
  +        assertEquals("result of remove via list", expected, list);
  +
  +        assertEquals(
  +            "result of remove directly (length)",
  +            2,
  +            instance.getStringCount());
       }
   }
  
  
  
  1.2       +225 -39   jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyTest.java
  
  Index: ReflectedMappedPropertyTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedMappedPropertyTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ ReflectedMappedPropertyTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -53,7 +53,11 @@
    */
   package org.apache.commons.clazz.reflect.extended;
   
  -import java.util.*;
  +import java.util.HashMap;
  +import java.util.HashSet;
  +import java.util.Iterator;
  +import java.util.Map;
  +import java.util.Set;
   
   import junit.framework.TestSuite;
   
  @@ -194,18 +198,6 @@
           assertTrue(result instanceof ReflectedMap);
       }
           
  -    public void testClear() {
  -    }
  -
  -    public void testContainsKey() {
  -    }
  -
  -    public void testContainsValue() {
  -    }
  -
  -    public void testEntrySet() {
  -    }
  -
       public void testGetEmptyMap() {
           Map map = (Map) mappedBooleansProperty.get(instance);
           Object value = map.get("bar");
  @@ -215,8 +207,7 @@
       }
   
       public void testGetWithSpecificAccessor() {
  -        instance.getMappedStrings().put("foo", "bar");
  -        instance.resetTrace();
  +        populateMappedStrings();
   
           Map map = (Map) mappedStringsProperty.get(instance);
           Object value = map.get("foo");
  @@ -224,14 +215,11 @@
           assertTrace(
               "getting value with specific getter",
               "getMappedString(String)");
  -        assertEquals("bar", value);
  +        assertEquals("1", value);
       }
   
       public void testGetWithDirectAccessor() {
  -        instance.setMappedBooleans(new HashMap());
  -        instance.getMappedBooleans().put("foo", Boolean.TRUE);
  -        instance.resetTrace();
  -
  +        populateMappedBooleans();
           Map map = (Map) mappedBooleansProperty.get(instance);
           Object value = map.get("foo");
   
  @@ -240,10 +228,9 @@
               "getMappedBooleans()");
           assertEquals(Boolean.TRUE, value);
       }
  -    
  +
       public void testPutWithSpecificAccessor() {
  -        instance.getMappedStrings().put("foo", "bar");
  -        instance.resetTrace();
  +        populateMappedStrings();
           
           Map map = (Map) mappedStringsProperty.get(instance);
           Object oldValue = map.put("foo", "baz");
  @@ -252,7 +239,7 @@
               "getMappedString(String)",
               "setMappedString(String,String)");
           assertEquals("baz", instance.getMappedStrings().get("foo"));        
  -        assertEquals("bar", oldValue);        
  +        assertEquals("1", oldValue);        
       }
   
       public void testPutWithDirectAccessor() {
  @@ -279,18 +266,13 @@
           assertNull(oldValue);        
       }
   
  -    public void testIsEmpty() {
  -    }
  -
       public void testKeySetWithSpecificAccessor() {
  -        instance.getMappedStrings().put("foo", "1");
  -        instance.getMappedStrings().put("bar", "2");
  -        instance.resetTrace();
  +        populateMappedStrings();
           
           Map map = (Map) mappedStringsProperty.get(instance);
           Set keySet = map.keySet();
           assertTrace(
  -            "getting key set with specific setter",
  +            "getting key set with specific accessor",
               "getMappedStringKeys()");
           
           HashSet expected = new HashSet();
  @@ -301,15 +283,12 @@
       }
   
       public void testKeySetWithPrincipalAccessor() {
  -        instance.setMappedBooleans(new HashMap());
  -        instance.getMappedBooleans().put("foo", Boolean.TRUE);
  -        instance.getMappedBooleans().put("bar", Boolean.FALSE);
  -        instance.resetTrace();
  +        populateMappedBooleans();
           
           Map map = (Map) mappedBooleansProperty.get(instance);
           Set keySet = map.keySet();
           assertTrace(
  -            "getting key set with principal setter",
  +            "getting key set with principal accessor",
               "getMappedBooleans()");
           
           HashSet expected = new HashSet();
  @@ -319,16 +298,223 @@
           assertEquals(expected, keySet);        
       }
   
  +    public void testEntrySetWithPrincipalAccessor() {
  +        populateMappedBooleans();
  +
  +        Map map = (Map) mappedBooleansProperty.get(instance);
  +        Set entrySet = map.entrySet();
  +        assertTrace(
  +            "getting entry set",
  +            "getMappedBooleans()");
  +        
  +        assertEquals("Regular entry set size", 2, entrySet.size());
  +    }
  +
  +    public void testEntrySetWithSpecificAccessor() {
  +        populateMappedIntegers();
  +
  +        Map map = (Map) mappedIntegerProperty.get(instance);
  +        Set entrySet = map.entrySet();
  +        assertTrace(
  +            "getting entry set",
  +            "getMappedIntegerKeys()");
  +
  +        assertEquals("Custom entry set size", 2, entrySet.size());
  +    }
  +
  +    public void testCustomEntrySetIterator() {
  +        populateMappedIntegers();
  +
  +        Map map = (Map) mappedIntegerProperty.get(instance);
  +        Set entrySet = map.entrySet();
  +        HashSet keys = new HashSet();
  +        HashSet values = new HashSet();
  +        Iterator it = entrySet.iterator();
  +        while (it.hasNext()){
  +            Map.Entry entry = (Map.Entry)it.next();
  +            keys.add(entry.getKey());
  +            values.add(entry.getValue());
  +        }
  +        assertTrace(
  +            "getting entry set",
  +            new String[] {
  +                "getMappedIntegerKeys()",
  +                "getMappedInteger(Integer)",
  +                "getMappedInteger(Integer)" });
  +
  +        HashSet expected = new HashSet();
  +        expected.add(new Integer(1));
  +        expected.add(new Integer(2));
  +
  +        assertEquals(expected, keys);
  +
  +        expected = new HashSet();
  +        expected.add(new Integer(1001));
  +        expected.add(new Integer(1002));
  +
  +        assertEquals(expected, values);
  +    }
  +
  +    public void testRemoveWithEntryIterator() {
  +        testRemoveWithIterator(false);
  +    }
  +    
  +    public void testRemoveWithKeyIterator() {
  +        testRemoveWithIterator(true);
  +    }
  +    
  +    public void testRemoveWithIterator(boolean keys) {
  +        populateMappedStrings();
  +
  +        Map map = (Map) mappedStringsProperty.get(instance);
  +        Set set = keys ? map.keySet() : map.entrySet();
  +
  +        Iterator it = set.iterator();
  +        while (it.hasNext()){
  +            it.next();
  +            it.remove();
  +        }
  +        
  +        assertTrace(
  +            "getting entry set",
  +            new String[] {
  +                "getMappedStringKeys()",
  +                "getMappedString(String)",
  +                "removeMappedString(String)",
  +                "getMappedString(String)",
  +                "removeMappedString(String)" });
  +
  +        assertTrue(
  +            "Resulting map is empty",
  +            instance.getMappedStrings().isEmpty());
  +    }
  +
  +    public void testRemoveWithKeySet() {
  +        populateMappedStrings();
  +
  +        Map map = (Map) mappedStringsProperty.get(instance);
  +        Set set = map.keySet();
  +        
  +        boolean eFoo = set.remove("foo");
  +        boolean eBar = set.remove("bar");
  +        boolean eBiz = set.remove("biz");
  +        
  +        assertTrace(
  +            "getting entry set",
  +            new String[] {
  +                "getMappedStringKeys()",
  +                "getMappedString(String)",
  +                "removeMappedString(String)",
  +                "getMappedString(String)",
  +                "removeMappedString(String)"});
  +
  +        assertTrue("existed foo", eFoo);
  +        assertTrue("existed bar", eBar);
  +        assertTrue("did not exist biz", !eBiz);
  +        assertTrue(
  +            "Resulting map is empty",
  +            instance.getMappedStrings().isEmpty());
  +    }
  +
  +    public void testIsEmptyTrue() {
  +        Map map = (Map) mappedStringsProperty.get(instance);
  +        assertTrue(map.isEmpty());
  +    }
  +
  +    public void testIsEmptyFalse() {
  +        populateMappedStrings();
  +        Map map = (Map) mappedStringsProperty.get(instance);
  +        assertTrue(!map.isEmpty());
  +    }
  +
  +    public void testClear() {
  +        populateMappedStrings();
  +        Map map = (Map) mappedStringsProperty.get(instance);
  +        map.clear();
  +        assertTrace(
  +            "clearing",
  +            new String[] {
  +                "getMappedStringKeys()",
  +                "getMappedString(String)",
  +                "removeMappedString(String)",
  +                "getMappedString(String)",
  +                "removeMappedString(String)"});
  +        assertTrue(map.isEmpty());
  +    }
  +
  +    public void testContainsKey() {
  +    }
  +
  +    public void testContainsValue() {
  +    }
  +
       public void testPutAll() {
       }
   
  -    public void testRemove() {
  +    public void testSizeWithKeySet() {
  +        populateMappedIntegers();
  +        Map map = (Map) mappedIntegerProperty.get(instance);
  +        int size = map.size();
  +        
  +        assertTrace(
  +            "getting size",
  +            new String[] {
  +                "getMappedIntegerKeys()"});
  +
  +        assertEquals("size", 2, size);        
       }
   
  -    public void testSize() {
  +    public void testSizeWithMap() {
  +        populateMappedBooleans();
  +        Map map = (Map) mappedBooleansProperty.get(instance);
  +        int size = map.size();
  +
  +        assertTrace(
  +            "getting size",
  +            new String[] {
  +                "getMappedBooleans()"});
  +
  +        assertEquals("size", 2, size);
       }
   
       public void testValues() {
  +        populateMappedStrings();
  +
  +        Map map = (Map) mappedStringsProperty.get(instance);
  +        Set values = new HashSet();
  +        values.addAll(map.values());
  +
  +        assertTrace(
  +            "getting values",
  +            new String[] {
  +                "getMappedStringKeys()",
  +                "getMappedString(String)",
  +                "getMappedString(String)" });
  +
  +                
  +        Set expected = new HashSet();
  +        expected.add("1");
  +        expected.add("2");
  +
  +        assertEquals(expected, values);
       }
   
  +    private void populateMappedBooleans() {
  +        instance.setMappedBooleans(new HashMap());
  +        instance.getMappedBooleans().put("foo", Boolean.TRUE);
  +        instance.getMappedBooleans().put("bar", Boolean.FALSE);
  +        instance.resetTrace();
  +    }
  +    
  +    private void populateMappedStrings() {
  +        instance.setMappedString("foo", "1");
  +        instance.setMappedString("bar", "2");
  +        instance.resetTrace();
  +    }
  +
  +    private void populateMappedIntegers() {
  +        instance.setMappedInteger(new Integer(1), new Integer(1001));
  +        instance.setMappedInteger(new Integer(2), new Integer(1002));
  +        instance.resetTrace();
  +    }
   }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedInstanceFactoryTest.java
  
  Index: ExtendedReflectedInstanceFactoryTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.extended;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedOperationTest;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ExtendedReflectedInstanceFactoryTest.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public class ExtendedReflectedInstanceFactoryTest extends ReflectedOperationTest {
  
      /**
       * Constructor for ExtendedReflectedOperationTest.
       * @param name
       */
      public ExtendedReflectedInstanceFactoryTest(String name) {
          super(name);
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedClazzTestSupport#getClazzLoader()
       */
      protected ClazzLoader getClazzLoader() {
          return Clazz.getClazzLoader(Clazz.DEFAULT_CLAZZLOADER);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedOperationTest.java
  
  Index: ExtendedReflectedOperationTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.extended;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedOperationTest;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ExtendedReflectedOperationTest.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public class ExtendedReflectedOperationTest extends ReflectedOperationTest {
  
      /**
       * Constructor for ExtendedReflectedOperationTest.
       * @param name
       */
      public ExtendedReflectedOperationTest(String name) {
          super(name);
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedClazzTestSupport#getClazzLoader()
       */
      protected ClazzLoader getClazzLoader() {
          return Clazz.getClazzLoader(Clazz.DEFAULT_CLAZZLOADER);
      }
  }
  
  
  
  1.2       +7 -98     jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedClazzTest.java
  
  Index: StandardReflectedClazzTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedClazzTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StandardReflectedClazzTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ StandardReflectedClazzTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -57,20 +57,18 @@
   
   import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzLoader;
  -import org.apache.commons.clazz.ClazzProperty;
   import org.apache.commons.clazz.reflect.ReflectableInstance;
  -import org.apache.commons.clazz.reflect.ReflectedClazzTestSupport;
  -import org.apache.commons.clazz.reflect.common.ReflectedScalarProperty;
  +import org.apache.commons.clazz.reflect.ReflectedClazzTest;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class StandardReflectedClazzTest extends ReflectedClazzTestSupport {
  +public class StandardReflectedClazzTest extends ReflectedClazzTest {
   
       /**
  -     * Constructor for ExtendedReflectedClazzTest.
  +     * Constructor for ReflectedClazzTest.
        * @param name
        */
       public StandardReflectedClazzTest(String name) {
  @@ -82,9 +80,11 @@
       }
   
       public static TestSuite suite(){
  -        TestSuite suite = new TestSuite();
  +        TestSuite suite = new TestSuite("StandardReflectedClazz tests");
           suite.addTestSuite(StandardReflectedClazzTest.class);
           suite.addTestSuite(StandardReflectedListPropertyTest.class);
  +        suite.addTestSuite(StandardReflectedOperationTest.class);
  +        suite.addTestSuite(StandardReflectedInstanceFactoryTest.class);
           return suite;
       }
   
  @@ -154,96 +154,5 @@
                   "baseProperty",
               },
               clazz.getSuperclazz().getDeclaredProperties());
  -    }
  -    
  -    /**
  -     * Checks that get/set methods are recognized properly.
     */
  -    public void testRecognitionOfScalarPropertyMethods(){
  -        ReflectedScalarProperty property = 
  -            (ReflectedScalarProperty)clazz.getProperty("integerProperty");
  -            
  -        assertMethodSignature("Read method",
  -            "getIntegerProperty()",
  -            property.getReadMethod());
  -            
  -        assertMethodSignature("Write method",
  -            "setIntegerProperty(int)",
  -            property.getWriteMethod());
  -    }
  -    
  -    /**
  -     * Checks that the "is" method is recognized for a boolean property.
  -     */
  -    public void testRecognitionOfScalarBooleanPropertyMethods(){
  -        ReflectedScalarProperty property = 
  -            (ReflectedScalarProperty)clazz.getProperty("booleanProperty");
  -            
  -        assertMethodSignature("Read method",
  -            "isBooleanProperty()",
  -            property.getReadMethod());
  -            
  -        assertMethodSignature("Write method",
  -            "setBooleanProperty(boolean)",
  -            property.getWriteMethod());
  -    }
  -    
  -    public void testGetOperations() {
  -    }
  -
  -    public void testGetDeclaredOperations() {
  -    }
  -
  -    public void testGetOperation() {
  -    }
  -
  -    /*
  -     * Test for Object newInstance()
  -     */
  -    public void testNewInstance() {
  -    }
  -
  -    /*
  -     * Test for Object newInstance(Object[])
  -     */
  -    public void testNewInstanceObjectArray() {
  -    }
  -
  -    public void testGetName() {
  -        assertEquals(instance.getClass().getName(), clazz.getName());
  -    }
  -
  -    public void testGetPackageName() {
  -        String pname = ReflectableInstance.class.getName().substring(0, 
  -                ReflectableInstance.class.getName().lastIndexOf('.'));
  -        assertEquals(pname, clazz.getPackageName());
  -    }
  -
  -    public void testGetShortClassName() {
  -        String cname = ReflectableInstance.class.getName().substring( 
  -                ReflectableInstance.class.getName().lastIndexOf('.') + 1);
  -        assertEquals(cname, clazz.getShortClassName());
  -    }
  -
  -    public void testIsAssignableFrom() {
  -    }
  -
  -    public void testGetScalarPropertyValue(){
  -        ClazzProperty property =
  -            (ClazzProperty) clazz.getProperty("integerProperty");
  -        Object result = property.get(instance);
  -        assertTrace(
  -            "getting scalar property value",
  -            "getIntegerProperty()");
  -        assertEquals(result, new Integer(0));
  -    }
  -    
  -    public void testPutScalarPropertyValue(){
  -        ClazzProperty property =
  -            (ClazzProperty) clazz.getProperty("integerProperty");
  -        property.set(instance, new Integer(3));
  -        assertTrace(
  -            "setting scalar property value",
  -            "setIntegerProperty()");
  -        assertEquals(3, instance.getIntegerProperty());
       }
   }
  
  
  
  1.2       +73 -186   jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedListPropertyTest.java
  
  Index: StandardReflectedListPropertyTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedListPropertyTest.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StandardReflectedListPropertyTest.java	6 Dec 2002 01:12:50 -0000	1.1
  +++ StandardReflectedListPropertyTest.java	14 Dec 2002 02:38:43 -0000	1.2
  @@ -59,20 +59,16 @@
   
   import org.apache.commons.clazz.Clazz;
   import org.apache.commons.clazz.ClazzLoader;
  -import org.apache.commons.clazz.reflect.ReflectedClazzTestSupport;
  -import org.apache.commons.clazz.reflect.common.ReflectedList;
  -import org.apache.commons.clazz.reflect.common.ReflectedListProperty;
  +import org.apache.commons.clazz.reflect.ReflectedListPropertyTestSupport;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class StandardReflectedListPropertyTest extends ReflectedClazzTestSupport
  +public class StandardReflectedListPropertyTest 
  +    extends ReflectedListPropertyTestSupport
   {
  -    private ReflectedListProperty intArrayProperty;
  -    private ReflectedListProperty stringProperty;
  -    
       /**
        * Constructor for ReflectedPropertyMapTest.
        * @param name Is the test method name
  @@ -93,14 +89,6 @@
           return Clazz.getClazzLoader(Clazz.STANDARD_CLAZZLOADER);
       }
       
  -    public void setUp() throws Exception {
  -        super.setUp();
  -        intArrayProperty = 
  -            (ReflectedListProperty)clazz.getProperty("intArray");
  -        stringProperty = 
  -            (ReflectedListProperty)clazz.getProperty("string");
  -    }
  -    
       /**
        * Checks the set of methods recognized for a List property that
        * does not have regular get/set methods.
  @@ -164,27 +152,6 @@
           assertNull("Size method",
               intArrayProperty.getSizeMethod());
       }
  -    
  -    public void testGetListPropertyValue(){
  -        Object result = intArrayProperty.get(instance);
  -        assertTraceEmpty(
  -            "getting List property value");
  -            
  -        assertTrue(result instanceof ReflectedList);
  -    }
  -        
  -    public void testSizeWithArray() {
  -        instance.setIntArray(new int[]{1, 2, 3});
  -        instance.resetTrace();
  -        
  -        List list = (List)intArrayProperty.get(instance);
  -        int count = list.size();
  -        
  -        assertTrace(
  -            "getting size with direct getter",
  -            "getIntArray()");
  -        assertEquals(3, count);
  -    }
   
       public void testSizeWithList() {
           instance.addString("foo");
  @@ -203,162 +170,82 @@
           assertTrue("Exception because there is no read method ", ex);
       }
       
  -    public void testSizeWithEmpty() {
  -        List list = (List)intArrayProperty.get(instance);
  -        int count = list.size();
  -        
  -        assertTrace(
  -            "getting size with count getter",
  -            "getIntArray()");
  -        assertEquals(0, count);
  +    public void testIsEmptyWithList(){
  +        List list = (List)stringProperty.get(instance);
  +        boolean ex = false;
  +        try {
  +            list.isEmpty();
  +        }
  +        catch (Throwable t){
  +            ex = true;
  +        }
  +        assertTrue("Exception because there is no read method ", ex);
       }
       
  -    public void testIsEmpty() {
  -    }
  -
  -    public void testContains() {
  -    }
  -
  -    public void testIterator() {
  -    }
  -
  -    /*
  -     * Test for Object[] toArray()
  -     */
  -    public void testToArray() {
  -    }
  -
  -    /*
  -     * Test for Object[] toArray(Object[])
  -     */
  -    public void testToArrayObjectArray() {
  -    }
  -
  -    /*
  -     * Test for boolean add(Object)
  -     */
  -    public void testAddObject() {
  -    }
  -
  -    /*
  -     * Test for boolean remove(Object)
  -     */
  -    public void testRemoveObject() {
  -    }
  -
  -    public void testContainsAll() {
  -    }
  -
  -    /*
  -     * Test for boolean addAll(Collection)
  -     */
  -    public void testAddAllCollection() {
  -    }
  -
  -    /*
  -     * Test for boolean addAll(int, Collection)
  -     */
  -    public void testAddAllICollection() {
  -    }
  -
  -    public void testRemoveAll() {
  -    }
  -
  -    public void testRetainAll() {
  -    }
  -
  -    public void testClear() {
  -    }
  -
  -    public void testGetWithArray() {
  -        instance.setIntArray(new int[]{1, 2, 3});
  -        instance.resetTrace();
  -        
  -        List list = (List)intArrayProperty.get(instance);
  -        Object value = list.get(1);
  -        
  -        assertTrace(
  -            "getting value with direct getter",
  -            "getIntArray()");
  -        assertEquals(new Integer(2), value);
  +    public void testContainsWithListSuccess() {
  +        testContainsWithListFailure();
       }
  -
  -    public void testGetWithList() {
  -        instance.addString("foo");
  -        instance.addString("bar");
  -        instance.addString("baz");
  -        instance.resetTrace();
  -        
  +    
  +    public void testContainsWithListFailure() {
           List list = (List)stringProperty.get(instance);
  -        Object value = list.get(1);
  -        
  -        assertTrace(
  -            "getting value with parameterized getter",
  -            "getString(int)");
  -            
  -        assertEquals("bar", value);
  -    }
  -
  -    public void testSetWithArray() {
  -        instance.setIntArray(new int[]{1, 2, 3});
  -        instance.resetTrace();
  -        
  -        List list = (List)intArrayProperty.get(instance);
  -        list.set(1, new Integer(7));
  -        
  -        assertTrace(
  -            "setting value with direct getter",
  -            "getIntArray()");
  -        assertEquals(7, instance.getIntArray()[1]);
  -    }
  +        boolean ex = false;
  +        try {
  +            list.contains("foo");
  +        }
  +        catch (Throwable t){
  +            ex = true;
  +        }
  +        assertTrue("Exception because there is no read method ", ex);
  +    }    
       
  -    public void testSetWithList() {
  -        instance.addString("foo");
  -        instance.addString("bar");
  -        instance.addString("baz");
  -        instance.resetTrace();
  -        
  +    public void testIteratorWithList(){
           List list = (List)stringProperty.get(instance);
  -        list.set(1, "biz");
  -        
  -        assertTrace(
  -            "setting value with parameterized setter",
  -            "getString(int)",
  -            "setString(int,String)");
  -            
  -        assertEquals("biz", instance.getString(1));
  -    }
  -
  -    /*
  -     * Test for void add(int, Object)
  -     */
  -    public void testAddIObject() {
  -    }
  -
  -    /*
  -     * Test for Object remove(int)
  -     */
  -    public void testRemoveI() {
  -    }
  -
  -    public void testIndexOf() {
  -    }
  -
  -    public void testLastIndexOf() {
  -    }
  -
  -    /*
  -     * Test for ListIterator listIterator()
  -     */
  -    public void testListIterator() {
  +        boolean ex = false;
  +        try {
  +            list.iterator();
  +        }
  +        catch (Throwable t){
  +            ex = true;
  +        }
  +        assertTrue("Exception because there is no read method ", ex);
  +    }    
  +    
  +    public void testAddObjectWithListStartEmpty() {
  +        List list = (List)stringProperty.get(instance);
  +        boolean ex = false;
  +        try {
  +            list.add("biz");
  +        }
  +        catch (Throwable t){
  +            ex = true;
  +        }
  +        assertTrue("Exception because there is no read method ", ex);
       }
  -
  -    /*
  -     * Test for ListIterator listIterator(int)
  -     */
  -    public void testListIteratorI() {
  +    
  +    public void testAddObjectWithListStartPopulated() {
  +        populateStringList();
  +        List list = (List)stringProperty.get(instance);
  +        boolean ex = false;
  +        try {
  +            list.add("biz");
  +        }
  +        catch (Throwable t){
  +            ex = true;
  +        }
  +        assertTrue("Exception because there is no read method ", ex);
       }
  -
  -    public void testSubList() {
  +    
  +    public void testAddIndexedWithList() {
  +        populateStringList();
  +        List list = (List)stringProperty.get(instance);
  +        boolean ex = false;
  +        try {
  +            list.add(1, "biz");
  +        }
  +        catch (Throwable t){
  +            ex = true;
  +        }
  +        assertTrue("Exception because there is no read method ", ex);
       }
  +    
   }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedInstanceFactoryTest.java
  
  Index: StandardReflectedInstanceFactoryTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.standard;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedOperationTest;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: StandardReflectedInstanceFactoryTest.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public class StandardReflectedInstanceFactoryTest extends ReflectedOperationTest {
  
      /**
       * Constructor for StandardReflectedOperationTest.
       * @param name
       */
      public StandardReflectedInstanceFactoryTest(String name) {
          super(name);
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedClazzTestSupport#getClazzLoader()
       */
      protected ClazzLoader getClazzLoader() {
          return Clazz.getClazzLoader(Clazz.STANDARD_CLAZZLOADER);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedOperationTest.java
  
  Index: StandardReflectedOperationTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (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.clazz.reflect.standard;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedOperationTest;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: StandardReflectedOperationTest.java,v 1.1 2002/12/14 02:38:43 dmitri Exp $
   */
  public class StandardReflectedOperationTest extends ReflectedOperationTest {
  
      /**
       * Constructor for StandardReflectedOperationTest.
       * @param name
       */
      public StandardReflectedOperationTest(String name) {
          super(name);
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedClazzTestSupport#getClazzLoader()
       */
      protected ClazzLoader getClazzLoader() {
          return Clazz.getClazzLoader(Clazz.STANDARD_CLAZZLOADER);
      }
  }
  
  
  

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