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/06 02:12:50 UTC

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

dmitri      2002/12/05 17:12:50

  Modified:    clazz/src/java/org/apache/commons/clazz Clazz.java
                        ClazzFeature.java ClazzLoader.java
                        ClazzModifiers.java ClazzNotFoundException.java
                        ClazzOperation.java ClazzProperty.java
               clazz/src/java/org/apache/commons/clazz/reflect
                        ReflectedClazz.java ReflectedClazzLoader.java
                        ReflectedProperty.java
                        ReflectedPropertyIntrospector.java
               clazz/src/test/org/apache/commons/clazz/reflect
                        ReflectableInstance.java
                        ReflectedClazzTestSupport.java
                        ReflectedSuperclazzInstance.java
  Added:       clazz/src/java/org/apache/commons/clazz/bean BasicBean.java
                        Bean.java BeanClazz.java BeanClazzException.java
                        BeanClazzLoader.java BeanClazzProperty.java
                        BeanGroupClazzLoader.java
               clazz/src/java/org/apache/commons/clazz/common
                        CachingGroupClazzLoader.java
                        ClazzFeatureSupport.java GroupClazzLoader.java
               clazz/src/java/org/apache/commons/clazz/reflect
                        ReflectedAccessException.java
                        ReflectedGroupClazzLoader.java
               clazz/src/java/org/apache/commons/clazz/reflect/common
                        AccessorMethodParseResults.java
                        AccessorMethodParser.java ReflectedList.java
                        ReflectedListProperty.java
                        ReflectedListPropertyIntrospectorSupport.java
                        ReflectedListPropertyParseResults.java
                        ReflectedPropertyIntrospectorSupport.java
                        ReflectedPropertyParseResults.java
                        ReflectedScalarProperty.java
                        ReflectedScalarPropertyIntrospector.java
                        ReflectedScalarPropertyParseResults.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
                        StandardReflectedListPropertyIntrospector.java
               clazz/src/test/org/apache/commons/clazz ClazzTest.java
                        ClazzTestSupport.java
               clazz/src/test/org/apache/commons/clazz/bean
                        BeanClazzLoaderTest.java BeanClazzTest.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
  Removed:     clazz/src/java/org/apache/commons/clazz Bean.java
                        CachingClazzLibrary.java ClazzException.java
                        ClazzLibrary.java MetaUnit.java Operation.java
                        Property.java Unit.java
               clazz/src/java/org/apache/commons/clazz/reflect
                        AccessorMethodParseResults.java
                        AccessorMethodParser.java
                        ReflectedClazzLibrary.java ReflectedFeature.java
                        ReflectedList.java ReflectedListProperty.java
                        ReflectedListPropertyIntrospector.java
                        ReflectedListPropertyParseResults.java
                        ReflectedMap.java ReflectedMappedProperty.java
                        ReflectedMappedPropertyIntrospector.java
                        ReflectedMappedPropertyParseResults.java
                        ReflectedPropertyIntrospectorSupport.java
                        ReflectedPropertyParseResults.java
                        ReflectedScalarProperty.java
                        ReflectedScalarPropertyIntrospector.java
                        ReflectedScalarPropertyParseResults.java
               clazz/src/test/org/apache/commons/clazz/reflect
                        ReflectedClazzTest.java
                        ReflectedListPropertyTest.java
                        ReflectedMappedPropertyTest.java
  Log:
  Some refactoring
  
  Revision  Changes    Path
  1.3       +158 -82   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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Clazz.java	8 Nov 2002 14:29:35 -0000	1.2
  +++ Clazz.java	6 Dec 2002 01:12:48 -0000	1.3
  @@ -53,90 +53,198 @@
    */
   package org.apache.commons.clazz;
   
  -import java.util.ArrayList;
  -import java.util.Collections;
  -import java.util.Comparator;
  -import java.util.HashSet;
  -import java.util.List;
  +import java.util.*;
   
  -import org.apache.commons.clazz.reflect.ReflectedClazzLibrary;
  +import org.apache.commons.clazz.bean.BeanClazzLoader;
  +import org.apache.commons.clazz.bean.BeanGroupClazzLoader;
  +import org.apache.commons.clazz.common.CachingGroupClazzLoader;
  +import org.apache.commons.clazz.common.GroupClazzLoader;
  +import org.apache.commons.clazz.reflect.ReflectedGroupClazzLoader;
  +import org.apache.commons.clazz.reflect.extended.ExtendedReflectedClazzLoader;
  +import org.apache.commons.clazz.reflect.standard.StandardReflectedClazzLoader;
   
   /**
    * 
    * 
    * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
  - * @version $Id$
  - */
  + * @version $Id$
 */
   public abstract class Clazz
   {
  -    private ClazzLibrary library;
  +    private ClazzLoader loader;
       private String name;
  -    
  -    // Static fields
  -    private static ArrayList libraryList = new ArrayList();
  -    private static ClazzLibrary libraries[];
  +
  +    public static final String DEFAULT_CLAZZLOADER =
  +        "org.apache.commons.clazz.DefaultClazzLoader";
  +        
  +    public static final String STANDARD_CLAZZLOADER =
  +        "org.apache.commons.clazz.StandardClazzLoader";
  +        
  +    private static ClazzLoader defaultClazzLoader;
  +    private static Map clazzLoaders = new HashMap();
       
       static {
  -        libraryList.add(ReflectedClazzLibrary.LIBRARY);
  +        setClazzLoader(DEFAULT_CLAZZLOADER, buildDefaultClazzLoader());
  +        setClazzLoader(STANDARD_CLAZZLOADER, buildStandardClazzLoader());
       }
       
       /**
  -     * Automatically detects the ClazzLibrary for the given
  -     * object and returns the corresponding Clazz from that library.
  +     * Construct the default clazz loader, that is the one based on the extended
  +     * notion of JavaBeans.
        */
  -    public static Clazz getClazz(Object instance){
  -        if (instance == null){
  -            throw new NullPointerException();
  -        }
  +    private static ClazzLoader buildDefaultClazzLoader(){
  +        GroupClazzLoader loader = new CachingGroupClazzLoader();
  +
  +        // First build a general reflection-based ClazzLoader
  +        GroupClazzLoader reflectedGroup = new ReflectedGroupClazzLoader();
  +
  +        ClazzLoader reflectedLoader =
  +            new ExtendedReflectedClazzLoader(loader, getDefaultClassLoader());
  +            
  +        reflectedGroup.addClazzLoader(reflectedLoader);
  +
  +        loader.addClazzLoader(reflectedGroup);
  +
  +
  +        // Now build a dynamic clazz loader
           
  -        if (libraries == null){
  -            constructLibraryArray();
  -        }
  +        GroupClazzLoader beanGroup = new BeanGroupClazzLoader();
           
  -        for (int i = 0; i < libraries.length; i++){
  -            if (libraries[i].isMember(instance)){
  -                return libraries[i].getClazz(instance);
  -            }
  -        }
  +        ClazzLoader beanLoader = new BeanClazzLoader(beanGroup);
  +        
  +        beanGroup.addClazzLoader(beanLoader);
  +        
  +        loader.addClazzLoader(beanGroup);
           
  -        throw new ClazzNotFoundException(instance.getClass().getName());
  +        return loader;
  +    }
  +
  +    /**
  +     * Construct the standard clazz loader, that is the one that is based
  +     * strictly on the JavaBeans specification.
  +     */
  +    private static ClazzLoader buildStandardClazzLoader(){
  +        GroupClazzLoader loader = new CachingGroupClazzLoader();
  +
  +        // First build a general reflection-based ClazzLoader
  +        GroupClazzLoader reflectedGroup = new ReflectedGroupClazzLoader();
  +
  +        ClazzLoader reflectedLoader =
  +            new StandardReflectedClazzLoader(loader, getDefaultClassLoader());
  +
  +        reflectedGroup.addClazzLoader(reflectedLoader);
  +
  +        loader.addClazzLoader(reflectedGroup);
  +
  +
  +        // Now build a dynamic clazz loader
  +
  +        GroupClazzLoader beanGroup = new BeanGroupClazzLoader();
  +
  +        ClazzLoader beanLoader = new BeanClazzLoader(beanGroup);
  +
  +        beanGroup.addClazzLoader(beanLoader);
  +
  +        loader.addClazzLoader(beanGroup);
  +
  +        return loader;
  +    }
  +
  +    /**
  +     * @todo this is a questionable method of acquiring "the" classloader for
  +     * the ClazzLoaders to work with.
  +     * 
  +     * @return ClassLoader
  +     */
  +    private static ClassLoader getDefaultClassLoader() {
  +        ClassLoader classLoader =
  +            Thread.currentThread().getContextClassLoader();
  +        if (classLoader == null) {
  +            classLoader = Clazz.class.getClassLoader();
  +        }
  +        return classLoader;
       }
   
       /**
  -     * Register a global ClazzLibrary. The getClazz() method
  -     * uses registered ClazzLibraries to produce a Clazz for an instance.
  +     * Sets the default ClazzLoader.
  +     * @param defaultClazzLoader The defaultClazzLoader to set
        */
  -    public static void addClazzLibrary(ClazzLibrary clazzLibrary){
  -        libraryList.add(clazzLibrary);
  -        libraries = null;
  +    public static void setDefaultClazzLoader(ClazzLoader defaultClazzLoader) {
  +        setClazzLoader(DEFAULT_CLAZZLOADER, defaultClazzLoader);
       }
       
  +    /**
  +     * Register a clazz loader for the specified key, which represents the type
  +     * of model the clazz loader implements. 
  +     * 
  +     * @param key is the type of the model
  +     * @param clazzLoader
  +     */
  +    public static void setClazzLoader(String key, ClazzLoader clazzLoader){
  +        clazzLoaders.put(key, clazzLoader);
  +        if (key.equals(DEFAULT_CLAZZLOADER)){
  +            defaultClazzLoader = clazzLoader;
  +        }
  +    }
  +    
  +    /**
  +     * Returns the default ClazzLoader.
  +     * @return ClazzLoader
  +     */
  +    public static ClazzLoader getDefaultClazzLoader() {
  +        return defaultClazzLoader;
  +    }
  +
  +    /**
  +     * Returns a ClazzLoader registered for the supplied key. We can have
  +     * multiple top- level clazz loaders implementing different models (e.g.
  +     * STANDARD_JAVA_BEANS, EXTENDED_JAVA_BEANS etc).
  +     * 
  +     * @param key is the type of the model we need
  +     * @return ClazzLoader
  +     */
  +    public static ClazzLoader getClazzLoader(String key){
  +        return (ClazzLoader)clazzLoaders.get(key);
  +    }
  +    
  +    /**
  +     * Uses the default clazz loader to obtain the Clazz for the supplied
  +     * object.
  +     */
  +    public static Clazz getClazz(Object instance){
  +        if (instance == null){
  +            throw new NullPointerException();
  +        }
  +        
  +        Clazz clazz = getDefaultClazzLoader().getClazz(instance);
  +        if (clazz == null){
  +            throw new ClazzNotFoundException(instance.getClass().getName());
  +        }
  +        return clazz;
  +    }    
  +    
       
       /**
        * Keep the constructor protected or private, we want Clazzes to 
        * be created by their ClazzLoaders only.
  -     *  
  -     * @param library is the owning library
  -     * @param name must be unique within the library
  -     */
  -    protected Clazz(ClazzLibrary library, String name){
  -        this.library = library;
  +     *  
     * @param loader is the owning loader
  +     * @param name must be unique within the loader
     */
  +    protected Clazz(ClazzLoader loader, String name){
  +        this.loader = loader;
           this.name = name;
       }
       
       /**
  -     * Every Clazz belongs to one and only one ClazzLibrary. Its name
  -     * is unique within that library.
  +     * Every Clazz belongs to one and only one ClazzLoader. Its name is unique
  +     * within that loader.
        */
  -    public ClazzLibrary getClazzLibrary(){
  -        return library;
  +    public ClazzLoader getClazzLoader(){
  +        return loader;
       }
       
       /**
  -     * Returns the name of the Clazz. Clazz names
  -     * are unique within a ClazzLibrary.
  -     * It is ok for the same name to be present in different libraries.
  +     * Returns the name of the Clazz. It is ok for the same name to be present
  +     * in different ClazzLoaders, except CachingClazzLoaders.
        */
       public String getName(){
           return name;
  @@ -225,9 +333,10 @@
   //    public abstract List getOperations(Predicate predicate);
   
       /**
  -     * Returns Operations for the given name
  +     * Returns Operations for the given signature. The signature should be
  +     * formatted as follows: <code>"name(paramClazzName1,...)"</code>
        */
  -    public abstract List getOperation(String name);
  +    public abstract ClazzOperation getOperation(String signature);
   
       /**
        * Creates a new instance of this Clazz
  @@ -238,37 +347,4 @@
        * Creates a new instance of this Clazz using the supplied parameters
        */
       public abstract Object newInstance(Object[] parameters);
  -    
  -    
  -    private static final ClazzLibrary[] CLASS_LIBRARY_ARRAY = 
  -            new ClazzLibrary[0];
  -            
  -    /**
  -     * Sort libraryList by priority and convert to array for speed
  -     */
  -    private static void constructLibraryArray(){
  -        // Sort in the descending order of priority
  -        Collections.sort(libraryList, new Comparator(){
  -            public int compare(Object o1, Object o2){
  -                int priority1 = ((ClazzLibrary)o1).getPriority();
  -                int priority2 = ((ClazzLibrary)o2).getPriority();
  -                return priority2 - priority1;
  -            }
  -        });
  -        
  -        libraries = (ClazzLibrary[])libraryList.toArray(CLASS_LIBRARY_ARRAY);
  -    }
  -    
  -    private static HashSet loggingEnabledClasses = new HashSet();
  -    
  -    /**
  -     * Enable diagnistic logging for the specified class.
  -     */
  -    public static void enableLogging(String className){
  -        loggingEnabledClasses.add(className);
  -    }
  -    
  -    public static boolean isLoggingEnabled(String className){
  -        return loggingEnabledClasses.contains(className);
  -    }
   }
  
  
  
  1.2       +0 -0      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzFeature.java
  
  Index: ClazzFeature.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzFeature.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  
  
  
  1.2       +43 -10    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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ClazzLoader.java	8 Nov 2002 14:29:35 -0000	1.1
  +++ ClazzLoader.java	6 Dec 2002 01:12:48 -0000	1.2
  @@ -53,6 +53,8 @@
    */
   package org.apache.commons.clazz;
   
  +import java.util.HashSet;
  +
   /**
    * Constructs/loads Clazzes. ClazzLoaders are accessed indirectly
    * via ClazzLibraries.
  @@ -63,27 +65,58 @@
   {
       /**
        * Given a Clazz name, returns the corresponding Clazz. Does not
  -     * cache clazzes, that's the job of ClazzLibrary.  Return null
  -     * if there is no Clazz for this name.
  +     * cache clazzes, that's the job of CachingGroupClazzLoader.  Return null if
  +     * there is no Clazz for this name.
        */
       public abstract Clazz getClazzForName(String name);
   
       /**
  -     * Returns true iff this library has or can construct a Clazz for
  -     * the supplied instance.
  +     * Returns true iff this loader has or can construct a Clazz for the
  +     * supplied instance.
        */
       public abstract boolean isMember(Object instance);
   
       /**
  -     * Returns the Clazz for the supplied instance.
  +     * Returns the Clazz for the supplied instance.  Returns <code>null</code>
  +     * if it cannot produce such a Clazz.
  +     */
  +    public Clazz getClazz(Object instance){
  +        if (instance == null){
  +            return null;
  +        }
  +        
  +        String name = getClazzName(instance);
  +        if (name == null){
  +            return null;
  +        }
  +        return getClazzForName(name);
  +    }
  +
  +    /**
  +     * Returns the clazz name for the supplied instance. Returns
  +     * <code>null</code> if it cannot produce a clazz name for the instance.
        */
  -    public abstract Clazz getClazz(Object instance);
  +    public abstract String getClazzName(Object instance);
  +    
  +    /**
  +     * 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
  +     * null.
  +     */
  +    public abstract Clazz defineClazz(String name, Class clazzType);
  +    
  +
  +    private HashSet loggingEnabledClasses = new HashSet();
   
       /**
  -     * When ClazzLibrary is looking for a ClazzLoader to produce a Clazz,
  -     * it does so in the descending order of loader priorities.
  +     * Enable diagnistic logging for the specified class.
        */
  -    public int getPriority(){
  -        return 0;
  +    public void enableLogging(String className){
  +        loggingEnabledClasses.add(className);
  +    }
  +
  +    public boolean isLoggingEnabled(String className){
  +        return loggingEnabledClasses.contains(className);
       }
  +    
   }
  
  
  
  1.3       +0 -2      jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzModifiers.java
  
  Index: ClazzModifiers.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzModifiers.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClazzModifiers.java	8 Nov 2002 14:29:35 -0000	1.2
  +++ ClazzModifiers.java	6 Dec 2002 01:12:48 -0000	1.3
  @@ -55,8 +55,6 @@
   
   import java.lang.reflect.Modifier;
   
  -import org.apache.commons.lang.StringUtils;
  -
   /**
    * <code>ClazzModifiers</code> defines the modifiers in a manipulable way.
    *
  
  
  
  1.2       +0 -0      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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  
  
  
  1.3       +4 -2      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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClazzOperation.java	8 Nov 2002 14:29:35 -0000	1.2
  +++ ClazzOperation.java	6 Dec 2002 01:12:48 -0000	1.3
  @@ -58,13 +58,15 @@
    * 
    * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
  - * @version $Id$
  - */
  + * @version $Id$
 */
   public interface ClazzOperation extends ClazzFeature {
   
  +    String getSignature();
  +    
       Clazz[] getParameterClazzes();
       
       Clazz getReturnClazz();
       
       Object invoke(Object target, Object[] parameters);
  +
   }
  
  
  
  1.3       +17 -11    jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzProperty.java
  
  Index: ClazzProperty.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/ClazzProperty.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClazzProperty.java	8 Nov 2002 14:29:35 -0000	1.2
  +++ ClazzProperty.java	6 Dec 2002 01:12:48 -0000	1.3
  @@ -58,15 +58,12 @@
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
  - * @version $Id$
  - */
  + * @version $Id$
 */
   public interface ClazzProperty extends ClazzFeature
   {
       /**
        * Returns the name of the property.
  -     * 
  -     * @return String
  -     */    
  +     * 
     * @return String
     */    
       String getName();
   
       /**
  @@ -75,22 +72,32 @@
       Clazz getClazz();
       
       /**
  -     * Gets the type of the item if a List or Map.
  +     * Returns true if the property is a collection.
  +     */
  +    boolean isCollection();
  +    
  +    /**
  +     * Returns true if the property is a map.
  +     */
  +    boolean isMap();
  +
  +    /**
  +     * Gets the type of the item if the property <code>isCollection()</code> or
  +     * <code>isMap()</code>.
        *
        * @return the type of the item
        */
       public Clazz getContentClazz();
       
       /**
  -     * Gets the type of the key if a Map.
  +     * Gets the type of the key if the property <code>isMap()</code>.
        *
        * @return the type of the key
        */
       public Clazz getKeyClazz();
       
       /**
  -     * @return true if the property can not be changed
  -     */
  +     * @return true if the property can not be changed
     */
       public boolean isReadOnly();
       
       /**
  @@ -99,7 +106,6 @@
       Object get(Object instance);
       
       /**
  -     * @todo
  -     */
  +     * @todo
     */
       void set(Object instance, Object value);
   }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BasicBean.java
  
  Index: BasicBean.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.util.HashMap;
  import java.util.Map;
  
  import org.apache.commons.clazz.Clazz;
  
  /**
   * 
   *
   * @author Dmitri Plotnikov
   * @version $Revision: 1.1 $ $Date: 2002/12/06 01:12:48 $
   */
  public class BasicBean implements Bean {
  
      private Clazz clazz;
      private Map properties = new HashMap();
      
      /**
       * Constructor for BasicBean.
       */
      public BasicBean(Clazz clazz) {
          this.clazz = clazz;
      }
  
      /**
       * @see org.apache.commons.clazz.bean.Bean#getClazz()
       */
      public Clazz getClazz() {
          return clazz;
      }
  
      /**
       * @see org.apache.commons.clazz.bean.Bean#get(java.lang.String)
       */
      public Object get(String propertyName) {
          // @todo validate property name using the clazz
          // @todo possible provide a default value based on the clazz
          return properties.get(propertyName);
      }
  
      /**
       * @see org.apache.commons.clazz.bean.Bean#set(java.lang.String, java.lang.Object)
       */
      public void set(String propertyName, Object value) {
          // @todo validate property name and value type using the clazz
          properties.put(propertyName, value);       
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/Bean.java
  
  Index: Bean.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;
  
  /**
   * <code>Bean</code> is an interface that should be implemented by beans, or
   * classes that can make themselves appear to be beans.
   *
   * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
   * @version $Id: Bean.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public interface Bean {
      
      /**
       * Gets the Clazz for the bean.
       * 
       * @return the meta bean for the bean
       */
      public Clazz getClazz();
  
  
      public Object get(String propertyName);
      
      public void set(String propertyName, Object value);
      
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazz.java
  
  Index: BeanClazz.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 java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.ClazzOperation;
  import org.apache.commons.clazz.ClazzProperty;
  
  /**
   * Dynamically constructed Clazz.
   * 
   * @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazz.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public class BeanClazz extends Clazz {
  
      private Clazz superClazz;
      private List declaredProperties = new ArrayList();
      private List declaredOperations = new ArrayList();
      private Class instanceClass;
      private Constructor instanceConstructor;
      
      /**
       * Constructor for BeanClazz.
       * @param loader
       * @param name
       */
      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(){
          if (instanceClass != null){
              return instanceClass;
          }
          
          if (superClazz instanceof BeanClazz){
              return ((BeanClazz)superClazz).getInstanceClass();
          }
          
          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()
       */
      public Clazz getSuperclazz() {
          return superClazz;
      }
  
      public void setSuperclazz(Clazz clazz) {
          superClazz = clazz;
      }
      
      /**
       * @see org.apache.commons.clazz.Clazz#getDeclaredProperties()
       */
      public List getDeclaredProperties() {
          return Collections.unmodifiableList(declaredProperties);
      }
      
      public void addDeclaredProperty(ClazzProperty property){
          if (property.getDeclaringClazz() != this) {
              throw new BeanClazzException(
                  "Property belongs to a different clazz: "
                      + property.getDeclaringClazz().getName());
          }
          // @todo: maybe check for duplicate names
          declaredProperties.add(property);
      }
      
      public void removeDeclaredProperty(ClazzProperty property){
          declaredProperties.remove(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;
      }
  
      /**
       * @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;
      }
  
      /**
       * @see org.apache.commons.clazz.Clazz#getDeclaredOperations()
       */
      public List getDeclaredOperations() {
          return Collections.unmodifiableList(declaredOperations);
      }
  
      public void addDeclaredOperation(ClazzOperation operation){
          if (operation.getDeclaringClazz() != this) {
              throw new BeanClazzException(
                  "Operation belongs to a different clazz: "
                      + operation.getDeclaringClazz().getName());
          }
          
          // @todo: maybe check for duplicate signatures
          declaredOperations.add(operation);
      }
  
      public void removeDeclaredOperation(ClazzOperation operation){
          declaredOperations.remove(operation);
      }
  
      /**
       * @see org.apache.commons.clazz.Clazz#getOperations()
       */
      public List getOperations() {
          // @todo: cache and refresh cache as needed
  
          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);
              }
          }
          return operations;
      }
  
      /**
       * @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 null;
      }
  
      /**
       * @see org.apache.commons.clazz.Clazz#newInstance()
       */
      public Object newInstance() {      
          try {
              return getInstanceConstructor().newInstance(new Object[]{this});
          }
          catch (Throwable e) {
              e.printStackTrace();
              throw new BeanClazzException(
                  "Cannot instantiate " + getInstanceClass(),
                  e);
          }
      }
  
      /**
       * @see org.apache.commons.clazz.Clazz#newInstance(java.lang.Object)
       */
      public Object newInstance(Object[] parameters) {
          return null;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzException.java
  
  Index: BeanClazzException.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: BeanClazzException.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public class BeanClazzException extends RuntimeException {
  
      private Throwable cause;
      
      /**
       * Constructor for BeanClazzException.
       */
      public BeanClazzException() {
          super();
      }
  
      /**
       * Constructor for BeanClazzException.
       * @param s
       */
      public BeanClazzException(String s) {
          super(s);
      }
      
      /**
       * Constructor for ReflectedAccessException.
       * @param s
       */
      public BeanClazzException(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/BeanClazzLoader.java
  
  Index: BeanClazzLoader.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.ClazzLoader;
  import org.apache.commons.clazz.common.GroupClazzLoader;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzLoader.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public class BeanClazzLoader extends ClazzLoader {
      
      private GroupClazzLoader group;
      
      public BeanClazzLoader(GroupClazzLoader group){
          this.group = group;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzLoader#isMember(java.lang.Object)
       */
      public boolean isMember(Object instance) {
          return instance instanceof Bean;
      }
  
      public String getClazzName(Object instance) {
          if (!isMember(instance)){
              return null;
          }
          
          return ((Bean)instance).getClazz().getName();
      }
          
      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) {
          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 });
          }
          catch (Exception e) {
              throw new BeanClazzException("Cannot define clazz " + name, e);
          }
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanClazzProperty.java
  
  Index: BeanClazzProperty.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.ClazzProperty;
  import org.apache.commons.clazz.common.ClazzFeatureSupport;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzProperty.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public class BeanClazzProperty extends ClazzFeatureSupport 
      implements ClazzProperty {
  
      private String name;
      private String clazzName;
      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());
      }
      
      public BeanClazzProperty(Clazz declaringClazz, String name, String type) {
          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;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#getName()
       */
      public String getName() {
          return name;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#getClazz()
       */
      public Clazz getClazz() {
          if (clazz == null) {
              clazz =
                  getDeclaringClazz().getClazzLoader().getClazzForName(clazzName);
          }
          return clazz;
      }
  
      /**
       * Returns true if the property is a collection.
       */
      public boolean isCollection(){
          return false;
      }
  
      /**
       * Returns true if the property is a map.
       */
      public boolean isMap(){
          return false;
      }
          
      /**
       * @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;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#get(java.lang.Object)
       */
      public Object get(Object instance) {
          return ((Bean)instance).get(getName());
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#set(java.lang.Object, java.lang.Object)
       */
      public void set(Object instance, Object value) {
          ((Bean)instance).set(getName(), value);
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/bean/BeanGroupClazzLoader.java
  
  Index: BeanGroupClazzLoader.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.common.GroupClazzLoader;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanGroupClazzLoader.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public class BeanGroupClazzLoader extends GroupClazzLoader {
  
      public boolean isMember(Object instance) {
          // This is just an optimization - the Group can answer for all
          // of its members without checking with each one individually
          return instance instanceof Bean;
      }
  
      /**
       * @see org.apache.commons.clazz.common.CachingGroupClazzLoader#getClazzName(java.lang.Object)
       */
      public String getClazzName(Object instance) {
          // This is just an optimization - the Group can answer for all 
          // of its members without checking with each one individually 
          if (!isMember(instance)){
              return null;
          }
          return super.getClazzName(instance);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/CachingGroupClazzLoader.java
  
  Index: CachingGroupClazzLoader.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.common;
  
  import java.util.HashMap;
  
  import org.apache.commons.clazz.Clazz;
  
  /**
   * An implementation of <code>GroupClazzLoader</code> that caches clazzes by
   * name.
   *
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: CachingGroupClazzLoader.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public class CachingGroupClazzLoader extends GroupClazzLoader {
  
      private HashMap clazzMap = new HashMap();
      
      /**
       * @see org.apache.commons.clazz.ClazzLoader#getClazzForName(java.lang.
       * String)
       */
      public Clazz getClazzForName(String name) {
          Clazz clazz = (Clazz)clazzMap.get(name);
          if (clazz == null){
              clazz = super.getClazzForName(name);
              if (clazz != null){
                  clazzMap.put(name, clazz);
              }
          }
          return clazz;
      }
  
      /**
       * @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){
              clazzMap.put(name, clazz);
          }
          return clazz;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/ClazzFeatureSupport.java
  
  Index: ClazzFeatureSupport.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.common;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzFeature;
  
  /**
   * Maintains common behavior of various implementations of ClazzFeature.
   *  
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ClazzFeatureSupport.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
   */
  public abstract class ClazzFeatureSupport implements ClazzFeature {
  
      private Clazz declaringClazz;
  
      /**
       * Constructor for ClazzFeature.
       */
      public ClazzFeatureSupport(Clazz declaringClazz) {
          if (declaringClazz == null){
              throw new NullPointerException("Declaring Clazz cannot be null");
          }
          this.declaringClazz = declaringClazz;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzFeature#getDeclaringClazz()
       */
      public Clazz getDeclaringClazz() {
          return declaringClazz;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/common/GroupClazzLoader.java
  
  Index: GroupClazzLoader.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.common;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  
  /**
   * Aggregates multiple ClazzLoaders, which are invoked one after another
   * according to the ChainOfResponsibility pattern.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: GroupClazzLoader.java,v 1.1 2002/12/06 01:12:48 dmitri Exp $
 */
  public class GroupClazzLoader extends ClazzLoader
  {
      private ArrayList loaders = new ArrayList();
  
      /**
       * Returns true iff this group has a member loader that has or can construct
       * a Clazz for the supplied instance.
       */
      public boolean isMember(Object instance){
          // Note the reverse order
          for (int i = loaders.size(); --i >= 0; ){
              ClazzLoader loader = (ClazzLoader)loaders.get(i);
              if (loader.isMember(instance)){
                  return true;
              }
          }
          return false;
      }
  
      public String getClazzName(Object instance) {
          // Note the reverse order
          for (int i = loaders.size(); --i >= 0; ){
              ClazzLoader loader = (ClazzLoader)loaders.get(i);
              String name = loader.getClazzName(instance);
              if (name != null){
                  return name;
              }
          }
          return null;
      }
  
      /**
       * Given a Clazz name, produces the corresponding Clazz by invoking member
       * loaders one by one until the clazz is found.
       */
      public Clazz getClazzForName(String name) {
          Clazz clazz = null;
          // Note the reverse order
          for (int i = loaders.size(); --i >= 0; ){
              ClazzLoader loader = (ClazzLoader)loaders.get(i);
              clazz = loader.getClazzForName(name);
              if (clazz != null){
                  break;
              }
          }
          return clazz;
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzLoader#defineClazz(java.lang.String, java.lang.Class)
       */
      public Clazz defineClazz(String name, Class clazzType) {
          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){
                  break;
              }
          }
          return clazz;
      }
  
      /**
       * Adds a ClazzLoader to the group. The added clazz loader will be
       * invoked before the one supplied as the second argument.
       */
      public void addClazzLoader(ClazzLoader loader, ClazzLoader invokeBefore){
          if (invokeBefore == null){
              addClazzLoader(loader);
              return;
          }
          
          int index = loaders.indexOf(invokeBefore);
          if (index == -1){
              throw new IllegalArgumentException(
                  "ClazzLoader "
                      + invokeBefore.getClass().getName()
                      + " is not a member of the group");
          }
          
          // In order to be invoked before, the clazz loader needs to be
          // inserted after the parameter.
          loaders.add(index + 1, loader);
      }
  
      /**
       * Adds a ClazzLoader to the group. ClazzLoaders added last are invoked
       * first.
       */
      public void addClazzLoader(ClazzLoader loader){
          loaders.add(loader);
      }
  
      /**
       * Returns all clazz loaders registered with this group,
       * in the order of priority
       */    
      public List getClazzLoaders(){
          return Collections.unmodifiableList(loaders);
      }
  
      /**
       * Returns clazzloaders matching the supplied Predicate
       */    
  //    public List getClazzLoaders(Predicate predicate){
  //    }
  }
  
  
  
  1.2       +35 -65    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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedClazz.java	8 Nov 2002 14:29:35 -0000	1.1
  +++ ReflectedClazz.java	6 Dec 2002 01:12:49 -0000	1.2
  @@ -53,21 +53,9 @@
    */
   package org.apache.commons.clazz.reflect;
   
  -import java.lang.reflect.Method;
  -import java.lang.reflect.Modifier;
  -import java.util.ArrayList;
  -import java.util.Collections;
  -import java.util.Comparator;
  -import java.util.HashMap;
  -import java.util.HashSet;
  -import java.util.Iterator;
  -import java.util.List;
  -import java.util.Map;
  -
  -import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.ClazzLibrary;
  -import org.apache.commons.clazz.ClazzOperation;
  -import org.apache.commons.clazz.ClazzProperty;
  +import java.util.*;
  +
  +import org.apache.commons.clazz.*;
   
   /**
    * This implementation of Clazz is based on Java reflection. 
  @@ -77,6 +65,7 @@
    */
   public class ReflectedClazz extends Clazz {
   
  +    private ReflectedPropertyIntrospector[] propertyIntrospectors;
       private boolean superClazzKnown;
       private Clazz superClazz;
       private Class javaClass;
  @@ -85,42 +74,27 @@
       private List declaredPropertyList;
       
       /**
  -     * The default list of introspectors consists of List, Mapped and Scalar
  -     * property introspectors.
     */
  -    private static final ReflectedPropertyIntrospector[] DEFAULT_INTROSPECTORS =
  -        new ReflectedPropertyIntrospector[] {
  -            ReflectedListPropertyIntrospector.INTROSPECTOR,
  -            ReflectedMappedPropertyIntrospector.INTROSPECTOR,
  -            ReflectedScalarPropertyIntrospector.INTROSPECTOR };
  -    
  -    /**
  -     * Constructor for ReflectedClazz.
        * 
  -     * @param library
  -     * @param name
  -     */
  -    public ReflectedClazz(ClazzLibrary library, Class javaClass) {
  -        super(library, javaClass.getName());
  -        this.javaClass = javaClass;
  -    }
  -
  -    /**
  -     * The default list of introspectors consists of List, Mapped and Scalar
  -     * property introspectors. 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.
  -     */
  -    protected ReflectedPropertyIntrospector[] 
  -                        getReflectedPropertyIntrospectors() 
  +     * @param loader
  +     * @param javaClass
  +     * @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) 
       {
  -        return DEFAULT_INTROSPECTORS;
  +        super(loader, javaClass.getName());
  +        this.propertyIntrospectors = propertyIntrospectors;
  +        this.javaClass = javaClass;
       }
       
       /**
        * Returns true if diagnostic is enabled for this clazz
     */
  -    protected boolean isLoggingEnabled(){
  -        return Clazz.isLoggingEnabled(getName());
  +    public boolean isLoggingEnabled(){
  +        return getClazzLoader().isLoggingEnabled(getName());
       }
       
       /**
  @@ -140,7 +114,7 @@
                   superClazz = null;
               }
               else {
  -                superClazz = getClazzLibrary().
  +                superClazz = getClazzLoader().
                           getClazzForName(superclass.getName());
               }
           }
  @@ -233,7 +207,7 @@
       /**
        * @see org.apache.commons.clazz.Clazz#getOperation(java.lang.String)
        */
  -    public List getOperation(String name) {
  +    public ClazzOperation getOperation(String signature) {
           return null;
       }
   
  @@ -241,7 +215,14 @@
        * @see org.apache.commons.clazz.Clazz#newInstance()
        */
       public Object newInstance() {
  -        return null;
  +        try {
  +            return javaClass.newInstance();
  +        }
  +        catch (Throwable e) {
  +            throw new ReflectedAccessException(
  +                "Cannot create instance of clazz " + getName(),
  +                e);
  +        }
       }
   
       /**
  @@ -260,11 +241,9 @@
           propertyMap = new HashMap();
           propertyList = new ArrayList();
   
  -        ReflectedPropertyIntrospector[] introspectors =
  -                getReflectedPropertyIntrospectors();
  -        for (int i = 0; i < introspectors.length; i++) {
  +        for (int i = 0; i < propertyIntrospectors.length; i++) {
               List properties =
  -                    introspectors[i].introspectProperties(this, javaClass);
  +                propertyIntrospectors[i].introspectProperties(this, javaClass);
               for (int j = 0; j < properties.size(); j++) {
                   ReflectedProperty property =
                           (ReflectedProperty) properties.get(j);
  @@ -284,10 +263,8 @@
        * Called by ReflectedPropertyIntrospector's to log results of
        * introspection, successful or not.
        */
  -    protected void logPropertyParseResults(
  -            ReflectedPropertyParseResults parseResults) 
  -    {
  -        if (propertyParseResults == null){
  +    public void logPropertyParseResults(Object parseResults) {
  +        if (propertyParseResults == null) {
               propertyParseResults = new ArrayList();
           }
           propertyParseResults.add(parseResults);
  @@ -300,15 +277,8 @@
               return;
           }
                   
  -        Collections.sort(propertyParseResults, new Comparator(){
  -            public int compare(Object o1, Object o2) {
  -                String n1 =
  -                    ((ReflectedPropertyParseResults) o1).getPropertyName();
  -                String n2 =
  -                    ((ReflectedPropertyParseResults) o2).getPropertyName();
  -                return n1.compareTo(n2);
  -            }
  -        });
  +        // PropertyParseResults are supposed to implement Comparable
  +        Collections.sort(propertyParseResults);
           
           // @todo: use a logger
           System.err.println("[Clazz: " + getName());
  
  
  
  1.2       +34 -22    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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedClazzLoader.java	8 Nov 2002 14:29:35 -0000	1.1
  +++ ReflectedClazzLoader.java	6 Dec 2002 01:12:49 -0000	1.2
  @@ -54,21 +54,32 @@
   package org.apache.commons.clazz.reflect;
   
   import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.ClazzLibrary;
   import org.apache.commons.clazz.ClazzLoader;
   import org.apache.commons.clazz.ClazzNotFoundException;
  +import org.apache.commons.clazz.common.GroupClazzLoader;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedClazzLoader extends ClazzLoader {
  +public abstract class ReflectedClazzLoader extends ClazzLoader {
   
  -    private ClazzLibrary library;
  +    private GroupClazzLoader group;
  +    private ClassLoader classLoader;
       
  -    public ReflectedClazzLoader(ClazzLibrary library){
  -        this.library = library;
  +    public ReflectedClazzLoader(
  +            GroupClazzLoader group,
  +            ClassLoader classLoader) 
  +    {
  +        this.group = group;
  +    }
  +    
  +    public String getClazzName(Object instance) {
  +        if (instance == null){
  +            return null;
  +        }
  +        return instance.getClass().getName();
       }
       
       /**
  @@ -77,14 +88,19 @@
       public Clazz getClazzForName(String name) {
           Class javaClass;
           try {
  -            javaClass = Class.forName(name);
  +            if (classLoader != null){
  +                javaClass = classLoader.loadClass(name);
  +            }
  +            else {
  +                javaClass = Class.forName(name);
  +            }
           }
           catch (ClassNotFoundException ex){
               throw new ClazzNotFoundException(name);
           }
  -        return new ReflectedClazz(library, javaClass);
  +        return createClazz(group, javaClass);
       }
  -
  +    
       /**
        * Returns <code>true</code> for all objects.
        * 
  @@ -95,23 +111,19 @@
       }
   
       /**
  -     * @see org.apache.commons.clazz.ClazzLoader#getClazz(java.lang.Object)
  +     * 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
  +     * <code>this</code>.
        */
  -    public Clazz getClazz(Object instance) {
  -        if (instance == null){
  -            return null;
  -        }
  -        
  -        return new ReflectedClazz(library, instance.getClass());
  -    }
  -
  +    protected abstract Clazz createClazz(
  +                ClazzLoader clazzLoader,
  +                Class javaClass);  
       /**
  -     * Return -1, the lowest allowed priority
  -     * 
  -     * @see org.apache.commons.clazz.ClazzLoader#getPriority()
  +     * @see org.apache.commons.clazz.ClazzLoader#defineClazz(java.lang.String, java.lang.Class)
        */
  -    public int getPriority() {
  -        return -1;
  +    public Clazz defineClazz(String name, Class clazzType) {
  +        return null;
       }
   
   }
  
  
  
  1.2       +22 -10    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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedProperty.java	8 Nov 2002 14:29:36 -0000	1.1
  +++ ReflectedProperty.java	6 Dec 2002 01:12:49 -0000	1.2
  @@ -54,21 +54,18 @@
   package org.apache.commons.clazz.reflect;
   
   import java.lang.reflect.Field;
  -import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
  -import java.util.ArrayList;
  -import java.util.List;
   
   import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.ClazzException;
   import org.apache.commons.clazz.ClazzProperty;
  +import org.apache.commons.clazz.common.ClazzFeatureSupport;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedProperty extends ReflectedFeature implements ClazzProperty 
  +public class ReflectedProperty extends ClazzFeatureSupport implements ClazzProperty 
   {
       private String name;
       private static final String[] EMPTY_STRING_ARRAY = new String[0];
  @@ -116,7 +113,7 @@
       public Clazz getClazz() {
           if (clazz == null){
               clazz = getDeclaringClazz().
  -                getClazzLibrary().getClazzForName(type.getName());
  +                getClazzLoader().getClazzForName(type.getName());
           }
           return clazz;
       }
  @@ -196,14 +193,14 @@
        */
       public Object get(Object instance) {
           if (readMethod == null){
  -            throw new ClazzException(
  +            throw new ReflectedAccessException(
                   "Cannot read property " + name + ": no read method");
           }
           try {
               return readMethod.invoke(instance, null);
           }
           catch (Exception ex) {
  -            throw new ClazzException(
  +            throw new ReflectedAccessException(
                   "Cannot get property : "
                       + name
                       + ": cannot invoke method: "
  @@ -217,14 +214,14 @@
        */
       public void set(Object instance, Object value) {
           if (writeMethod == null){
  -            throw new ClazzException(
  +            throw new ReflectedAccessException(
                   "Cannot modify property " + name + ": no write method");
           }
           try {
               writeMethod.invoke(instance, new Object[]{value});
           }
           catch (Exception ex) {
  -            throw new ClazzException(
  +            throw new ReflectedAccessException(
                   "Cannot set property : "
                       + name
                       + ": cannot invoke method: "
  @@ -249,4 +246,19 @@
       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.2       +0 -0      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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/ReflectedAccessException.java
  
  Index: ReflectedAccessException.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;
  
  /**
   * Thrown when an attempt to invoke an accessor method fails.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedAccessException.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedAccessException extends RuntimeException {
  
      private Throwable cause;
      
      /**
       * Constructor for ReflectedAccessException.
       */
      public ReflectedAccessException() {
          super();
      }
  
      /**
       * Constructor for ReflectedAccessException.
       * @param s
       */
      public ReflectedAccessException(String s) {
          super(s);
      }
      
      /**
       * Constructor for ReflectedAccessException.
       * @param s
       */
      public ReflectedAccessException(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/reflect/ReflectedGroupClazzLoader.java
  
  Index: ReflectedGroupClazzLoader.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.common.GroupClazzLoader;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedGroupClazzLoader.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedGroupClazzLoader extends GroupClazzLoader {
      
      public ReflectedGroupClazzLoader(){
      }
          
      /**
       * @see org.apache.commons.clazz.ClazzLoader#isMember(java.lang.Object)
       */
      public boolean isMember(Object instance) {
          return true;
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzLoader#getClazzName(java.lang.Object)
       */
      public String getClazzName(Object instance) {
          if (instance == null){
              return null;
          }
          return instance.getClass().getName();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/AccessorMethodParseResults.java
  
  Index: AccessorMethodParseResults.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;
  
  /**
   * Container for the results of method parsing: propertyName 
   * and two types. The types are used differently depending on
   * how the corresponding AccessorMethodParser uses them. 
   *  
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: AccessorMethodParseResults.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class AccessorMethodParseResults {
  
      private Method method;
      private String propertyName;
      private Class type;
      private Class parameterType;
      
      public AccessorMethodParseResults(Method method, 
                          String propertyName, Class type, Class parameterType)
      {
          this.method = method;
          this.propertyName = propertyName;
          this.type = type;
          this.parameterType = parameterType;
      }
      
      /**
       * Returns the method.
       * @return Method
       */
      public Method getMethod() {
          return method;
      }
  
      /**
       * Returns the propertyName.
       * @return String
       */
      public String getPropertyName() {
          return propertyName;
      }
  
      /**
       * Returns the type.
       * @return Class
       */
      public Class getType() {
          return type;
      }
  
      /**
       * Returns the parameterType.
       * @return Class
       */
      public Class getParameterType() {
          return parameterType;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/AccessorMethodParser.java
  
  Index: AccessorMethodParser.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;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: AccessorMethodParser.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class AccessorMethodParser {
      
      /**
       * If a method parsed by this parser must have a number or parameters,
       * override and return that number.  
       */
      protected int requiredParameterCount() {
          return -1;
      }
  
      /**
       * If a method parsed by this parser must have a certain prefix,
       * override and return a non-null prefix string  
       */
      protected String requiredPrefix() {
          return null;
      }
  
      /**
       * To check constraints on the return type of methods parsed
       * by this parser, override and perform the check.
       *  
     * @param javaClass The return type of the method (never null)
     * @return boolean True if the return type passes the parser's constraints
     */    
      protected boolean testReturnType(Class javaClass){
          return true;
      }
      
      /**
       * To check constraints on the type of a parameter, override 
       * and perform the check.
       *  
       * @param javaClass The return type of the method (never null)
       * @return boolean True if the return type passes the parser's constraints
       */    
      protected boolean testParameterType(int index, Class parameterType){
          return true;
      }
      
      /**
       * If a method parsed by this parser must have a certain suffix,
       * override this method, check that it does and remove the
       * suffix.
       */
      protected String testAndRemoveSuffix(String methodName){
          return methodName;
      }
      
      /**
       * 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.
       */
      protected Class getValueType(Method method){
          return null;
      }
      
      /**
       * Extract the parameter type from the method, if it has one. 
       * For example a mapped property "get" method might have
       * a "key" parameter.
       */
      protected Class getParameterType(Method method){
          return null;
      }
  
      /**
       * Parses the supplied method according to the parser's configuration.
       * If the parse process fails, returns null.
       * 
     * @param method
     * @return AccessorMethodParseResults
     */
      public AccessorMethodParseResults parse(Method method){
          int modifiers = method.getModifiers();
  
          // An accessor methods must be public and non-static
          if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers)){
              return null;
          }
  
          Class returnType = method.getReturnType();
          if (returnType == null){
              returnType = Void.TYPE; 
          }
          if (!testReturnType(returnType)){
              return null;
          }
          
          int reqParamCount = requiredParameterCount();
          if (reqParamCount != -1){
              Class paramTypes[] = method.getParameterTypes();
              if (paramTypes.length != reqParamCount){
                  return null;
              }
              
              for (int i = 0; i < paramTypes.length; i++) {
                  if (!testParameterType(i, paramTypes[i])){
                      return null;
                  }
              }
          }
          
          String propertyName = parseMethodName(method);
          if (propertyName == null) {
              return null;
          }
          
          return new AccessorMethodParseResults(
                          method, 
                          propertyName, 
                          getValueType(method), 
                          getParameterType(method));
      }
      
      /**
       * Parse method name and return the corresponding property name.
       * Return null if the method name does not satisfy the parser's
       * grammar.
       * <p>
       * The default implementation of the method checks if the 
       * method name starts with the specified prefix followed
       * by an optionally capitalized property name.
       * 
     * @param methodName
     * @return String
     */
      protected String parseMethodName(Method method){
          String name = method.getName();
          name = testAndRemoveSuffix(name);
          if (name == null){
              return null;
          }
          
          String prefix = requiredPrefix(); 
          if (prefix == null){
              return name;
          }
          
          if (name.length() <= prefix.length()){
              return null;
          }
          
          if (name.startsWith(prefix)){
              return decapitalize(name.substring(prefix.length()));
          }
          return null;
      }
      
      /**
       * Changes the first character of the <code>string</code>
       * to lower case, unless the second character is
       * upper case.  This is consistent with the JavaBean specification.
       * 
       * @param candidate
       * @return String
       */
      protected String decapitalize(String string)
      {
          char firstChar = string.charAt(0);
          if (!Character.isUpperCase(firstChar)){
              return string;
          }
          
          int len = string.length();
          if (len == 1){
              return String.valueOf(Character.toLowerCase(firstChar));
          }
          else if (Character.isLowerCase(string.charAt(1))){
              char buffer[] = new char[len];
              buffer[0] = Character.toLowerCase(firstChar);
              string.getChars(1, len, buffer, 1);
              return new String(buffer);
          }
          
          return string;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedList.java
  
  Index: ReflectedList.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.Array;
  import java.lang.reflect.Method;
  import java.util.*;
  
  import org.apache.commons.clazz.reflect.ReflectedAccessException;
  
  
  /**
   * This is an implementation of the <code>List</code> interface
   * that is based on a List property.  Whenever possible, it
   * uses concrete methods on the owner of the property to manipulate 
   * the list or array.
   * <p>
   * Consider the following example:
   * <pre>
   *      List list = (List)clazz.getProperty("fooList").get(instance);
   *      Object value = list.get(3);
   * </pre>
   * 
   * If <code>instance</code> has a <code>getFoo(int index)</code> method,
   * this code will implicitly invoke it like this: <code>getFoo(3)</code>,
   * otherwise it will obtain the whole list or array and extract the 
   * requested element.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedList.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedList implements List {
      
      private Object instance;
      private ReflectedListProperty property;
      
      /**
       * Constructor for ReflectedList.
       */
      public ReflectedList(
              Object instance,
              ReflectedListProperty property) 
      {
          this.instance = instance;
          this.property = property;
      }
  
      /**
       * @see java.util.Collection#size()
       */
      public int size() {
          Method sizeMethod = property.getSizeMethod();
          if (sizeMethod != null){
              try {
                  Object value = sizeMethod.invoke(instance, null);
                  return ((Integer)value).intValue();
              }
              catch (Exception ex) {
                  throw new ReflectedAccessException(
                      "Cannot get list size: "
                          + property.getName()
                          + ": cannot invoke method: "
                          + sizeMethod.getName(),
                      ex);
              }
          }
          else {
              Object list = property.getList(instance);
              if (list == null){
                  return 0;
              }
              
              if (list instanceof List){
                  return ((List)list).size();
              }
             
              return Array.getLength(list);
          }
      }
  
      /**
       * @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) {
          Method getMethod = property.getGetMethod();
          if (getMethod != null){
              Object value;
              try {
                  value =
                      getMethod.invoke(
                          instance,
                          new Object[] { new Integer(index)});
              }
              catch (Exception ex) {
                  throw new ReflectedAccessException(
                      "Cannot get property : "
                          + property.getName()
                          + ": cannot invoke method: "
                          + getMethod.getName(),
                      ex);
              }
              return value;
          }
          else {
              Object list = property.getList(instance);
              if (list == null){
                  return null;
              }
              
              if (list instanceof List){
                  return ((List)list).get(index);
              }
             
              return Array.get(list, index);
          }
      }
  
      /**
       * @see java.util.List#set(int, java.lang.Object)
       */
      public Object set(int index, Object element) {
          Method setMethod = property.getSetMethod();
          if (setMethod != null){
              Object oldValue = get(index);
              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);
              }
              return oldValue;
          }
          else {
              Object list = property.getList(instance);
              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;
          }
      }
  
      /**
       * @see java.util.List#add(int, java.lang.Object)
       */
      public void add(int index, Object element) {
      }
  
      /**
       * @see java.util.List#remove(int)
       */
      public Object remove(int index) {
          return null;
      }
  
      /**
       * @see java.util.List#indexOf(java.lang.Object)
       */
      public int indexOf(Object o) {
          return 0;
      }
  
      /**
       * @see java.util.List#lastIndexOf(java.lang.Object)
       */
      public int lastIndexOf(Object o) {
          return 0;
      }
  
      /**
       * @see java.util.List#listIterator()
       */
      public ListIterator listIterator() {
          return null;
      }
  
      /**
       * @see java.util.List#listIterator(int)
       */
      public ListIterator listIterator(int index) {
          return null;
      }
  
      /**
       * @see java.util.List#subList(int, int)
       */
      public List subList(int fromIndex, int toIndex) {
          return null;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListProperty.java
  
  Index: ReflectedListProperty.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.reflect.ReflectedProperty;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedListProperty.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedListProperty extends ReflectedProperty {
  
      private Class contentType;
      private Method sizeMethod;
      private Method getMethod;
      private Method addMethod;
      private Method addIndexedMethod;
      private Method setMethod;
      private Method removeMethod;
      
      /**
       * Constructor for ReflectedListProperty.
       * @param declaringClazz
       * @param name
       */
      public ReflectedListProperty(Clazz declaringClazz, String name) {
          super(declaringClazz, name);
      }
      
      /**
       * @see org.apache.commons.clazz.ClazzProperty#isCollection()
       */
      public boolean isCollection() {
          return true;
      }
  
      /**
       * Returns the contentType.
       * @return Class
       */
      public Class getContentType() {
          return contentType;
      }
  
      /**
       * Sets the contentType.
       * @param contentType The contentType to set
       */
      public void setContentType(Class valueType) {
          this.contentType = valueType;
      }
      
      /**
       * Returns the getMethod.
       * @return Method
       */
      public Method getGetMethod() {
          return getMethod;
      }
  
      /**
       * Sets the getMethod.
       * @param getMethod The getMethod to set
       */
      public void setGetMethod(Method getMethod) {
          this.getMethod = getMethod;
      }
      
     /**
       * Returns the setMethod.
       * @return Method
       */
      public Method getSetMethod() {
          return setMethod;
      }
  
      /**
       * Sets the setMethod.
       * @param setMethod The setMethod to set
       */
      public void setSetMethod(Method setMethod) {
          this.setMethod = setMethod;
      }
  
      /**
       * Returns the addMethod.
       * @return Method
       */
      public Method getAddMethod() {
          return addMethod;
      }
  
      /**
       * Sets the addMethod.
       * @param addMethod The addMethod to set
       */
      public void setAddMethod(Method addMethod) {
          this.addMethod = addMethod;
      }
  
      /**
       * Returns the addIndexedMethod.
       * @return Method
       */
      public Method getAddIndexedMethod() {
          return addIndexedMethod;
      }
  
      /**
       * Sets the addIndexedMethod.
       * @param addIndexedMethod The addIndexedMethod to set
       */
      public void setAddIndexedMethod(Method addIndexedMethod) {
          this.addIndexedMethod = addIndexedMethod;
      }
  
      /**
       * Returns the removeMethod.
       * @return Method
       */
      public Method getRemoveMethod() {
          return removeMethod;
      }
  
      /**
       * Sets the removeMethod.
       * @param removeMethod The removeMethod to set
       */
      public void setRemoveMethod(Method removeMethod) {
          this.removeMethod = removeMethod;
      }
  
      /**
       * Returns the sizeMethod.
       * @return Method
       */
      public Method getSizeMethod() {
          return sizeMethod;
      }
  
      /**
       * Sets the sizeMethod.
       * @param sizeMethod The sizeMethod to set
       */
      public void setSizeMethod(Method sizeMethod) {
          this.sizeMethod = sizeMethod;
      }
  
      public String toString(){
          StringBuffer buffer = new StringBuffer("[ReflectedListProperty ");
          if (getType() != null){
              buffer.append(getType().getName());
              buffer.append(" ");
          }
          if (getContentType() != null){
              buffer.append("[content: ");
              buffer.append(getContentType().getName());
              buffer.append("] ");
          }
          buffer.append(getName());
          if (getReadMethod() != null){
              buffer.append("\n   [read method]   ");
              buffer.append(getReadMethod());            
          }
          if (getWriteMethod() != null){
              buffer.append("\n   [write method]  ");
              buffer.append(getWriteMethod());            
          }
          if (getGetMethod() != null){
              buffer.append("\n   [get method]    ");
              buffer.append(getGetMethod());            
          }
          if (getSetMethod() != null){
              buffer.append("\n   [set method]    ");
              buffer.append(getSetMethod());            
          }
          if (getAddMethod() != null){
              buffer.append("\n   [add method]    ");
              buffer.append(getAddMethod());            
          }
          if (getAddIndexedMethod() != null){
              buffer.append("\n   [add(i) method] ");
              buffer.append(getAddIndexedMethod());            
          }
          if (getRemoveMethod() != null){
              buffer.append("\n   [remove method] ");
              buffer.append(getRemoveMethod());            
          }
          if (getSizeMethod() != null){
              buffer.append("\n   [size method]   ");
              buffer.append(getSizeMethod());            
          }
          buffer.append("]");
          return buffer.toString();
      }
      /**
       * @see org.apache.commons.clazz.ClazzProperty#get(java.lang.Object)
       */
      public Object get(Object instance) {
          return new ReflectedList(instance, this);
      }
      
      public Object getList(Object instance) {
          return super.get(instance);
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#set(java.lang.Object, java.lang.Object)
       */
      public void set(Object instance, Object value) {
          super.set(instance, value);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListPropertyIntrospectorSupport.java
  
  Index: ReflectedListPropertyIntrospectorSupport.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.util.Iterator;
  import java.util.Map;
  
  import org.apache.commons.clazz.reflect.*;
  
  /**
   * A ReflectedPropertyIntrospector that discovers list (aka indexed) properties.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedListPropertyIntrospectorSupport.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public abstract class ReflectedListPropertyIntrospectorSupport
      extends ReflectedPropertyIntrospectorSupport 
  {
      /**
       * Parser for the <code>getFooMap()</code> method:
       * <ul>
       *  <li>Return type not void</li>
       *  <li>Name starts with "get" followed by capitalized property name</li>
       *  <li>No parameters</li>
       * </ul>
       * 
       * We don't check if the parameter is a List here. If it is not,
       * we want to recognize the method and them mark the corresponding
       * property as NotAProperty.
       */
      protected static AccessorMethodParser READ_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class returnType){
              return !returnType.equals(Void.TYPE);
          }
          
          protected String requiredPrefix(){
              return "get";
          }
          
          protected int requiredParameterCount(){
              return 0;
          }
  
          protected Class getValueType(Method method){
              return method.getReturnType();
          }
          
      };
              
      /**
       * Looks at the method to see if it has the signature
       * of a property read method, like "List getIntegerList()", parses it
       * and returns the results of parsing.  If the method signature 
       * does not fit the criteria, returns <code>null</code>.
       */
      protected AccessorMethodParseResults parseReadMethod(Method method) {
          return READ_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>setFooList(List)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "set" followed by capitalized property name</li>
       *  <li>One parameter</li>
       * </ul>
       * 
       * We don't check if the parameter is a List here. If it is not,
       * we want to recognize the method and them mark the corresponding
       * property as NotAProperty.
       */            
      protected static AccessorMethodParser WRITE_METHOD_PARSER =
              new AccessorMethodParser()
      {
          protected boolean testReturnType(Class returnType){
              return returnType.equals(Void.TYPE);
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected String requiredPrefix(){
              return "set";
          }
                  
          protected Class getValueType(Method method){
              return method.getParameterTypes()[0];
          }
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseWriteMethod(Method method) {
          return WRITE_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>getFoo(int)</code> method:
       * <ul>
       *  <li>Return type not void</li>
       *  <li>Name starts with "get" followed by capitalized singular
       *      form of the property name</li>
       *  <li>One integer parameter</li>
       * </ul>
       */            
      protected static AccessorMethodParser GET_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class returnType){
              return !returnType.equals(Void.TYPE);
          }
          
          protected String requiredPrefix(){
              return "get";
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected boolean testParameterType(int index, Class parameterType){            
              return parameterType.equals(Integer.TYPE);
          }
          
          protected Class getValueType(Method method){
              return method.getReturnType();
          }
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseGetMethod(Method method) {
          return GET_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>setFoo(index, value)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "set" followed by capitalized singular
       *      form of the property name</li>
       *  <li>Two parameters, first integer</li>
       * </ul>
       */                        
      protected static AccessorMethodParser SET_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected String requiredPrefix(){
              return "set";
          }
          
          protected int requiredParameterCount(){
              return 2;
          }
  
          protected boolean testParameterType(int index, Class parameterType){
              if (index == 0){            
                  return parameterType.equals(Integer.TYPE);
              }
              return true;
          }
          
          protected Class getValueType(Method method){
              return method.getParameterTypes()[1];
          }                
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseSetMethod(Method method) {
          return SET_METHOD_PARSER.parse(method);
      }
  
      /**
       * Finds a ReflectedListPropertyParseResults for the given
       * propertyName or creates a new one and puts it in the map.
       */
      protected ReflectedListPropertyParseResults getParseResults(
              ReflectedClazz clazz,
              Map parseResultMap,
              String propertyName) 
      {
          ReflectedListPropertyParseResults parseResults =
              (ReflectedListPropertyParseResults) parseResultMap.get(
                  propertyName);
          if (parseResults == null) {
              parseResults =
                  new ReflectedListPropertyParseResults(clazz, propertyName);
              parseResultMap.put(propertyName, parseResults);
          }
          return parseResults;
      }
  
      /**
       * Combines data collected from singular methods like
       * <code>getFoo(index)</code> with Properties, which already
       * contain data about plural methods like <code>getFooList()</code>.
       */
      protected void mergeSingularMethods(
              Map parseResultMapPlural, Map parseResultMapSingular)
      {
          Iterator iter = parseResultMapSingular.values().iterator();
          while (iter.hasNext()) {
  
              ReflectedListPropertyParseResults singular =
                  (ReflectedListPropertyParseResults) iter.next();
  
              ReflectedListPropertyParseResults plural =
                  findBySingularName(
                          parseResultMapPlural, singular.getPropertyName());
  
              if (plural != null) {
                  plural.merge(singular);
              }
              else {
                  // We don't have any plural methods - let's just use
                  // the singular ones then
                  parseResultMapPlural.put(singular.getPropertyName(), singular);
              }
          }
      }
      
      /**
       * Given a singular form of a property name, locates parse results
       * for a property with the corresponding plural name.
       */
      protected ReflectedListPropertyParseResults findBySingularName(
              Map parseResultMapPlural,
              String singularName)
      {
          ReflectedListPropertyParseResults plural =
              (ReflectedListPropertyParseResults)
                  parseResultMapPlural.get(singularName);
          if (plural != null) {
              return plural;
          }
  
          Iterator iter = parseResultMapPlural.entrySet().iterator();
          while (iter.hasNext()) {
              Map.Entry entry = (Map.Entry) iter.next();
              if (isCorrectPluralForm(singularName, (String) entry.getKey())) {
                  return (ReflectedListPropertyParseResults) entry.getValue();
              }
          }
          return null;
      }
      
      /**
       * Creates a new ReflectedListProperty based on parse results. 
       */
      protected ReflectedProperty createProperty(
          ReflectedClazz clazz,
          ReflectedPropertyParseResults parseResults)
      {
          ReflectedListProperty property =
              new ReflectedListProperty(clazz, parseResults.getPropertyName());
  
          ReflectedListPropertyParseResults parseResultsList =
                  (ReflectedListPropertyParseResults)parseResults;
          
          property.setAliases(parseResultsList.getAliases());
          property.setType(parseResultsList.getPropertyType());
          property.setContentType(parseResultsList.getContentType());
          property.setReadMethod(parseResultsList.getReadMethod());
          property.setWriteMethod(parseResultsList.getWriteMethod());
          property.setGetMethod(parseResultsList.getGetMethod());
          property.setSetMethod(parseResultsList.getSetMethod());
          property.setAddMethod(parseResultsList.getAddMethod());
          property.setAddIndexedMethod(parseResultsList.getAddIndexedMethod());
          property.setRemoveMethod(parseResultsList.getRemoveMethod());
          property.setSizeMethod(parseResultsList.getSizeMethod());
          return property;
      }     
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedListPropertyParseResults.java
  
  Index: ReflectedListPropertyParseResults.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.util.List;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  
  /**
   * Holds parse results for individual accessor methods for a 
   * list property.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedListPropertyParseResults.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedListPropertyParseResults 
              extends ReflectedPropertyParseResults
  {
      private AccessorMethodParseResults getMethodParseResults;
      private AccessorMethodParseResults setMethodParseResults;
      private AccessorMethodParseResults addMethodParseResults;
      private AccessorMethodParseResults addIndexedMethodParseResults;
      private AccessorMethodParseResults removeMethodParseResults;
      
      private AccessorMethodParseResults sizeMethodParseResults;
      
  
      /**
       * Constructor for ReflectedMappedPropertyParseResults.
       */
      public ReflectedListPropertyParseResults(
              ReflectedClazz clazz, String propertyName) 
      {
          super(clazz, propertyName);
      }
      
      protected String getPropertyCategory(){
          return "list";
      }
      
      /**
       * Returns <code>true</code> if the property is an array or 
       * implements java.util.List.
       */
      public boolean isList(){
          if (readMethodParseResults != null &&
                  isList(readMethodParseResults.getType())){
              return true;
          }
          if (writeMethodParseResults != null &&
                  isList(writeMethodParseResults.getType())){
              return true;
          }
          return false;        
      }
          
      /**
       * Returns <code>true</code> if javaClass is an array or 
       * implements java.util.List.
       */
      protected boolean isList(Class javaClass){
          return javaClass != null
              && (List.class.isAssignableFrom(javaClass) || javaClass.isArray());
      }
      
      /**
       * Returns the type of the list/array element, if known. 
       * Returns <code>null</code> otherwise.
     */
      public Class getContentType(){
          if (getMethodParseResults != null){
              return getMethodParseResults.getType();
          }
          if (setMethodParseResults != null){
              return setMethodParseResults.getType();
          }
          if (addMethodParseResults != null){
              return addMethodParseResults.getType();
          }
          if (addIndexedMethodParseResults != null){
              return addIndexedMethodParseResults.getType();
          }
          if (removeMethodParseResults != null){
              return removeMethodParseResults.getType();
          }
          return null;
      }
  
      public void setGetMethodParseResults(
                  AccessorMethodParseResults getMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.getMethodParseResults,
              getMethodParseResults);
          this.getMethodParseResults = getMethodParseResults;
      }
  
      public Method getGetMethod() {
          if (getMethodParseResults == null){
              return null;
          }
          return getMethodParseResults.getMethod();
      }
      
      public void setSetMethodParseResults(
                  AccessorMethodParseResults setMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.setMethodParseResults,
              setMethodParseResults);
          this.setMethodParseResults = setMethodParseResults;
      }
  
      public Method getSetMethod() {
          if (setMethodParseResults == null){
              return null;
          }
          return setMethodParseResults.getMethod();
      }
      
      public void setAddMethodParseResults(
                  AccessorMethodParseResults addMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.addMethodParseResults,
              addMethodParseResults);
          this.addMethodParseResults = addMethodParseResults;
      }
  
      public Method getAddMethod() {
          if (addMethodParseResults == null){
              return null;
          }
          return addMethodParseResults.getMethod();
      }
      
      public void setAddIndexedMethodParseResults(
                  AccessorMethodParseResults addIndexedMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.addIndexedMethodParseResults,
              addIndexedMethodParseResults);
          this.addIndexedMethodParseResults = addIndexedMethodParseResults;
      }
      
      public Method getAddIndexedMethod() {
          if (addIndexedMethodParseResults == null){
              return null;
          }
          return addIndexedMethodParseResults.getMethod();
      }
          
      public void setRemoveMethodParseResults(
                  AccessorMethodParseResults removeMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.removeMethodParseResults,
              removeMethodParseResults);
          this.removeMethodParseResults = removeMethodParseResults;
      }
      
      public Method getRemoveMethod() {
          if (removeMethodParseResults == null){
              return null;
          }
          return removeMethodParseResults.getMethod();
      }
      
  
      public void setSizeMethodParseResults(
                  AccessorMethodParseResults sizeMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.sizeMethodParseResults,
              sizeMethodParseResults);
          this.sizeMethodParseResults = sizeMethodParseResults;
      }
      
      public Method getSizeMethod() {
          if (sizeMethodParseResults == null){
              return null;
          }
          return sizeMethodParseResults.getMethod();
      }
      
      /**
       * Combines parse results from another instance of 
       * <code>ReflectedMappedPropertyParseResults</code> with
       * results contained by this object.
       * <p>
       * Node that the property name is not copied from the 
       * <code>other</code> object.
       */        
      public void merge(ReflectedListPropertyParseResults other){
          super.merge(other);
          if (other.readMethodParseResults != null){
              setReadMethodParseResults(other.readMethodParseResults);
          }
          if (other.writeMethodParseResults != null){
              setWriteMethodParseResults(other.writeMethodParseResults);
          }
          if (other.getMethodParseResults != null){
              setGetMethodParseResults(other.getMethodParseResults);
          }
          if (other.setMethodParseResults != null){
              setSetMethodParseResults(other.setMethodParseResults);
          }
          if (other.addMethodParseResults != null){
              setAddMethodParseResults(other.addMethodParseResults);
          }
          if (other.addIndexedMethodParseResults != null){
              setAddIndexedMethodParseResults(other.addIndexedMethodParseResults);
          }
          if (other.removeMethodParseResults != null){
              setRemoveMethodParseResults(other.removeMethodParseResults);
          }
          if (other.sizeMethodParseResults != null){
              setSizeMethodParseResults(other.sizeMethodParseResults);
          }
      }
      
      protected void appendDescription(StringBuffer buffer){
          super.appendDescription(buffer);
          Class contentType = getContentType();
          if (contentType != null){
              buffer.append("\n  [content type]   ");
              buffer.append(contentType.getName());
          }
      }
      
      protected void appendMethodDescriptions(StringBuffer buffer){
          super.appendMethodDescriptions(buffer);
          if (getMethodParseResults != null){
              buffer.append("\n    [get~(int)]    ");
              buffer.append(getMethodParseResults.getMethod());
          }
          if (setMethodParseResults != null){
              buffer.append("\n    [set~(int,v)]  ");
              buffer.append(setMethodParseResults.getMethod());
          }
          if (addMethodParseResults != null){
              buffer.append("\n    [add~(v)]      ");
              buffer.append(addMethodParseResults.getMethod());
          }
          if (addIndexedMethodParseResults != null){
              buffer.append("\n    [add~(int,v)]  ");
              buffer.append(addIndexedMethodParseResults.getMethod());
          }
          if (removeMethodParseResults != null){
              buffer.append("\n    [remove~(v)]   ");
              buffer.append(removeMethodParseResults.getMethod());
          }
          if (sizeMethodParseResults != null){
              buffer.append("\n    [get~Count()]  ");
              buffer.append(sizeMethodParseResults.getMethod());
          }
      }
      
      public boolean checkConsistency(){        
          if (!super.checkConsistency()){
              return false;
          }
                  
          if (readMethodParseResults == null && getMethodParseResults == null){
              return false;
          }
  
          if (readMethodParseResults != null){
              Class type = readMethodParseResults.getType();
              if (writeMethodParseResults != null){
                  if (!type.equals(writeMethodParseResults.getType())){
                      return false;
                  }
              }
          }
                  
          Class contentType = null;
           
          if (getMethodParseResults != null){
              contentType = getMethodParseResults.getType();
          }
          
          if (setMethodParseResults != null){
              if (contentType == null){
                  contentType = setMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(setMethodParseResults.getType())) {
                      return false;
                  }
              }
          }
          
          if (addMethodParseResults != null){
              if (contentType == null){
                  contentType = addMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(addMethodParseResults.getType())) {
                      return false;
                  }
              }
          }
          
          if (addIndexedMethodParseResults != null){
              if (contentType == null){
                  contentType = addIndexedMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(
                          addIndexedMethodParseResults.getType())){
                      return false;
                  }
              }
          }
          
          if (removeMethodParseResults != null) {
              if (contentType != null){
                  if (!contentType.equals(removeMethodParseResults.getType())){
                      return false;
                  }
              }
          }
          
          return true;
      }
          
      protected boolean appendInconsistencyDescriptions(StringBuffer buffer){
          if (!super.appendInconsistencyDescriptions(buffer)){
              return false;
          }        
          
          if (readMethodParseResults == null && getMethodParseResults == null){
              buffer.append(
                  "\n     - Does not have either get() or get(int) method");
              return true;
          }
  
          if (readMethodParseResults != null){
              Class type = readMethodParseResults.getType();
              if (writeMethodParseResults != null){
                  if (!type.equals(writeMethodParseResults.getType())){
                      buffer.append(
                          "\n     - Get() and set(v) types do not match");
                  }
              }
          }
          
          Class contentType = null;
           
          if (getMethodParseResults != null){
              contentType = getMethodParseResults.getType();
          }
          
          if (setMethodParseResults != null){
              if (contentType == null){
                  contentType = setMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(setMethodParseResults.getType())) {
                      buffer.append(
                          "\n     - Content type mismatch between "
                              + "get(int) and set(int,v)");
                  }
              }
          }
          
          if (addMethodParseResults != null){
              if (contentType == null){
                  contentType = addMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(addMethodParseResults.getType())) {
                      buffer.append(
                          "\n     - Content type mismatch between "
                              + "get(int) and add(v)");
                  }
              }
          }
          
          if (addIndexedMethodParseResults != null){
              if (contentType == null){
                  contentType = addIndexedMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(
                          addIndexedMethodParseResults.getType())){
                      buffer.append(
                          "\n     - Content type mismatch between "
                              + "get(int) and add(int,v)");
                  }
              }
          }
          
          if (removeMethodParseResults != null) {
              if (contentType != null){
                  Class removeType = removeMethodParseResults.getType(); 
                  if (removeType != null && !contentType.equals(removeType)){
                      buffer.append(
                          "\n     - Content type mismatch between "
                              + "get(int) and remove(v)");
                  }
              }
          }        
          return true;
      }  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedPropertyIntrospectorSupport.java
  
  Index: ReflectedPropertyIntrospectorSupport.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.util.*;
  
  import org.apache.commons.clazz.reflect.*;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedPropertyIntrospectorSupport.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public abstract class ReflectedPropertyIntrospectorSupport
      implements ReflectedPropertyIntrospector 
  {
      /**
       */
      public List introspectProperties(ReflectedClazz clazz, Class javaClass) {        
          HashMap parseResultMap = new HashMap();
          introspectProperties(clazz, javaClass, parseResultMap);
          
          boolean loggingEnabled = clazz.isLoggingEnabled();
          
          ArrayList list = new ArrayList();
          Iterator iter = parseResultMap.values().iterator();
          while (iter.hasNext()) {
              ReflectedPropertyParseResults parseResults = 
                      (ReflectedPropertyParseResults) iter.next();
              if (clazz.getProperty(parseResults.getPropertyName()) != null){
                  continue;
              }
              
              boolean aliasExists = false;
              String aliases[] = parseResults.getAliases();
              for (int i = 0; i < aliases.length; i++){
                  if (clazz.getProperty(aliases[i]) != null){
                      aliasExists = true;
                      break;
                  }
              }
              if (aliasExists){
                  continue;
              }
  
              boolean consistent = parseResults.checkConsistency();
              if (consistent){                
                  list.add(createProperty(clazz, parseResults));
              }
              if (loggingEnabled){
                  clazz.logPropertyParseResults(parseResults);
              }
          }
          return list;
      }
      
      public abstract void introspectProperties(
          ReflectedClazz clazz,
          Class javaClass,
          Map parseResultMap);
              
      /**
       * Creates a new ReflectedProperty based on parse results. 
       */
      protected abstract ReflectedProperty createProperty(
          ReflectedClazz clazz,
          ReflectedPropertyParseResults parseResults);
      
      
      /**
       * Returns true if the <code>plural</code> parameter is
       * a correct plural form for the property names <code>singular</code>.
       * If the plural.startsWith(singular), calls isCorrectPluralSuffix
       * with the singular form and the remaining part of the plural form.
       * Separately handles the "~y" - "~ies" substitution for English.
       */
      protected boolean isCorrectPluralForm(String singular, String plural){
          if (plural.startsWith(singular)){            
              return isCorrectPluralSuffix(
                      singular,
                      plural.substring(singular.length()));
          }
          else if (singular.endsWith("y") &&
                  plural.endsWith("ies") && 
                  plural.substring(0, plural.length() - 3).
                          equals(singular.substring(singular.length() - 1))){
              return true;
          }
          return false;
      }
      
      protected boolean isCorrectPluralSuffix(String singular, String suffix){
          return suffix.equals("s");
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedPropertyParseResults.java
  
  Index: ReflectedPropertyParseResults.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.util.ArrayList;
  import java.util.List;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  
  /**
   * Base class for <code>Reflected*PropertyParseResults</code> classes;
   * aggregates parse results for individual accessor methods.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedPropertyParseResults.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public abstract class ReflectedPropertyParseResults implements Comparable 
  {
      private ReflectedClazz clazz;
      private String propertyName;
      private List aliases;
      
      protected AccessorMethodParseResults readMethodParseResults;
      protected AccessorMethodParseResults writeMethodParseResults;
      protected List extraneousAccessors;
      
      private static final String[] EMPTY_STRING_ARRAY = new String[0];
      
      public ReflectedPropertyParseResults(
              ReflectedClazz clazz,
              String propertyName) 
      {
          this.clazz = clazz;
          this.propertyName = propertyName;
      }
      
      public ReflectedClazz getClazz(){
          return clazz;
      }
      
      /**
       * Returns the propertyName.
       * @return String
       */
      public String getPropertyName() {
          return propertyName;
      }
      
      public int compareTo(Object object){
          String n1 = getPropertyName();
          String n2 = ((ReflectedPropertyParseResults) object).getPropertyName();
          return n1.compareTo(n2);
      }
      
      public String[] getAliases(){
          if (aliases == null){
              return EMPTY_STRING_ARRAY;
          }
          return (String[])aliases.toArray(EMPTY_STRING_ARRAY);
      }
      
      public void addAlias(String alias){
          if (!alias.equals(propertyName)){
              if (aliases == null){
                  aliases = new ArrayList();
                  aliases.add(alias);
              }
              else if (!aliases.contains(alias)){
                  aliases.add(alias);
              }
          }
      }
      
      protected abstract String getPropertyCategory();
      
      public void merge(ReflectedPropertyParseResults other){
          addAlias(other.getPropertyName());
          String[] aliases = other.getAliases();
          for (int i = 0; i < aliases.length; i++) {
              addAlias(aliases[i]);
          }
      }    
      
      public Class getPropertyType(){
          if (readMethodParseResults != null){
              return readMethodParseResults.getType();
          }
          if (writeMethodParseResults != null){
              return writeMethodParseResults.getType();
          }
          return null;
      }
          
      public Method getReadMethod() {
          if (readMethodParseResults == null){
              return null;
          }
          return readMethodParseResults.getMethod();
      }
      
      public Method getWriteMethod() {
          if (writeMethodParseResults == null){
              return null;
          }
          return writeMethodParseResults.getMethod();
      }
      
      /**
       * Sets the readMethodParseResults.
       * @param readMethodParseResults The readMethodParseResults to set
       */
      public void setReadMethodParseResults(
                  AccessorMethodParseResults readMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.readMethodParseResults,
              readMethodParseResults);
          this.readMethodParseResults = readMethodParseResults;
      }
      
      /**
       * Sets the writeMethodParseResults.
       * @param writeMethodParseResults The writeMethodParseResults to set
       */
      public void setWriteMethodParseResults(
              AccessorMethodParseResults writeMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.writeMethodParseResults,
              writeMethodParseResults);
          this.writeMethodParseResults = writeMethodParseResults;
      }
      
      /**
       * Checks if there is an existing parse result recorded and if
       * so saves it into the extraneousAccessors for error reporting.
     */
      protected void checkForExtraneousAccessor(
              AccessorMethodParseResults currentValue, 
              AccessorMethodParseResults newValue)
      {
          if (currentValue != null && newValue != null &&
                  currentValue != newValue){
              if (extraneousAccessors == null){
                  extraneousAccessors = new ArrayList();
                  extraneousAccessors.add(currentValue);
              }
          }
      }
          
      public boolean checkConsistency(){        
          if (extraneousAccessors != null){
              return false;
          }
          
          return true;
      }
      
      public String toString(){
          boolean consistent = checkConsistency();
          
          StringBuffer buffer = new StringBuffer();
          buffer.append("[");
          if (consistent){
              buffer.append(propertyName);
              if (!getPropertyCategory().equals("scalar")){            
                  buffer.append(" (");
                  buffer.append(getPropertyCategory());
                  buffer.append(")");
              }
          }
          else {
              buffer.append("*");
              buffer.append(propertyName);            
              buffer.append(" - NOT a ");
              if (!getPropertyCategory().equals("scalar")){            
                  buffer.append(getPropertyCategory());
              }
              buffer.append(" property");
              appendInconsistencyDescriptions(buffer);
          }
          if (aliases != null){
              buffer.append("\n  [aliases: ");
              for (int i = 0; i < aliases.size(); i++){
                  if (i != 0){
                      buffer.append(", ");
                  }
                  buffer.append(aliases.get(i));
              }
              buffer.append("]");
          }
          appendDescription(buffer);
          buffer.append("\n  [accessor methods:");
          appendMethodDescriptions(buffer);
          buffer.append("\n  ]");
          buffer.append("\n]");
          return buffer.toString();
      }
      
      protected void appendDescription(StringBuffer buffer){
          Class type = getPropertyType();
          if (type != null){
              buffer.append("\n  [type]           ");
              buffer.append(type.getName());
          }
      }
      
      protected void appendMethodDescriptions(StringBuffer buffer){        
          if (readMethodParseResults != null){
              buffer.append("\n    [get~()]       ");
              buffer.append(readMethodParseResults.getMethod());
          }
          if (writeMethodParseResults != null){
              buffer.append("\n    [set~(v)]      ");
              buffer.append(writeMethodParseResults.getMethod());
          }
      }
      
      protected boolean appendInconsistencyDescriptions(StringBuffer buffer){        
          if (extraneousAccessors != null){
              buffer.append(
                  "\n     - Has extraneous accessors:");
              for (int i = 0; i < extraneousAccessors.size(); i++) {
                  AccessorMethodParseResults results =
                      (AccessorMethodParseResults)extraneousAccessors.get(i); 
                  buffer.append("\n         ");
                  buffer.append(results.getMethod());
              }
          }    
          return true;
      }    
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarProperty.java
  
  Index: ReflectedScalarProperty.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 org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.reflect.ReflectedProperty;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedScalarProperty.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedScalarProperty extends ReflectedProperty {
      /**
       * Constructor for ReflectedScalarProperty.
       * @param declaringClazz
       * @param name
       */
      public ReflectedScalarProperty(Clazz declaringClazz, String name) {
          super(declaringClazz, name);
      }
          
      public String toString(){
          StringBuffer buffer = new StringBuffer("[ReflectedScalarProperty ");
          if (getType() != null){
              buffer.append(getType().getName());
              buffer.append(" ");
          }
          buffer.append(getName());
          if (getReadMethod() != null){
              buffer.append("\n   [read method]  ");
              buffer.append(getReadMethod());            
          }
          if (getWriteMethod() != null){
              buffer.append("\n   [write method] ");
              buffer.append(getWriteMethod());            
          }
          buffer.append("]");
          return buffer.toString();
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarPropertyIntrospector.java
  
  Index: ReflectedScalarPropertyIntrospector.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.util.Map;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.ReflectedProperty;
  
  /**
   * A ReflectedPropertyIntrospector that discovers scalar properties.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedScalarPropertyIntrospector.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedScalarPropertyIntrospector 
              extends ReflectedPropertyIntrospectorSupport 
  {
      public static final ReflectedScalarPropertyIntrospector INTROSPECTOR =
              new ReflectedScalarPropertyIntrospector();
   
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected ReflectedScalarPropertyIntrospector(){
      }
      
      public void introspectProperties(
              ReflectedClazz clazz,
              Class javaClass,
              Map parseResultMap)
      {
          Method methods[] = javaClass.getMethods();
          ReflectedScalarPropertyParseResults parseResults;
          AccessorMethodParseResults results;
          for (int i = 0; i < methods.length; i++){
              Method method = methods[i];
              if (method.getDeclaringClass().equals(Object.class)){
                  continue;
              }
              
              results = parseReadMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setReadMethodParseResults(results);
                  continue;
              }
              
              results = parseWriteMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setWriteMethodParseResults(results);
                  continue;
              }    
          }
      }
      
      /**
       * Parser for the <code>getFoo()</code> method:
       * <ul>
       *  <li>Return type not void</li>
       *  <li>Name starts with "get" followed by capitalized property name.
       *      If the property is boolean the name may also start with "is".</li>
       *  <li>No parameters</li>
       * </ul>
       */
      protected static AccessorMethodParser READ_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class returnType){
              return !returnType.equals(Void.TYPE);
          }
          
          protected int requiredParameterCount(){
              return 0;
          }
          
          protected String parseMethodName(Method method){
              String name = method.getName();
              String propertyName = null;
              if (name.startsWith("get")){
                  propertyName = decapitalize(name.substring(3));
              }
              else if (method.getReturnType().equals(Boolean.TYPE) && 
                          name.startsWith("is")){
                  propertyName = decapitalize(name.substring(2));
              }
              return propertyName;           
          }
  
          protected Class getValueType(Method method){
              return method.getReturnType();
          }
      };
              
      /**
       * Looks at the method to see if it has the signature
       * of a property read method, like "int getInteger()", parses it
       * and returns the results of parsing.  If the method signature 
       * does not fit the criteria, returns <code>null</code>.
       */
      public AccessorMethodParseResults parseReadMethod(Method method) {
          return READ_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>setFoo(value)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "set" followed by capitalized property name</li>
       *  <li>One parameter</li>
       * </ul>
       */            
      protected static AccessorMethodParser WRITE_METHOD_PARSER =
              new AccessorMethodParser()
      {
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected String requiredPrefix(){
              return "set";
          }
                  
          protected boolean testReturnType(Class returnType){
              return returnType.equals(Void.TYPE);
          }
          
          protected Class getValueType(Method method){
              return method.getParameterTypes()[0];
          }
      };
  
      /**
       * @see #parseReadMethod(Method)
     */
      public AccessorMethodParseResults parseWriteMethod(Method method) {
          return WRITE_METHOD_PARSER.parse(method);
      }
  
      /**
       * Finds a ReflectedScalarPropertyParseResults for the given
       * propertyName or creates a new one and puts it in the map.
       */
      protected ReflectedScalarPropertyParseResults getParseResults(
              ReflectedClazz clazz,
              Map parseResultMap,
              String propertyName) 
      {
          ReflectedScalarPropertyParseResults parseResults =
              (ReflectedScalarPropertyParseResults) parseResultMap.get(
                  propertyName);
          if (parseResults == null) {
              parseResults =
                  new ReflectedScalarPropertyParseResults(clazz, propertyName);
              parseResultMap.put(propertyName, parseResults);
          }
          return parseResults;
      }
      
      /**
       * Creates a new ReflectedProperty based on parse results. 
     */
      protected ReflectedProperty createProperty(
          ReflectedClazz clazz,
          ReflectedPropertyParseResults parseResults)
      {
          ReflectedScalarProperty property =
              new ReflectedScalarProperty(clazz, parseResults.getPropertyName());
  
          property.setType(parseResults.getPropertyType());
          property.setReadMethod(parseResults.getReadMethod());
          property.setWriteMethod(parseResults.getWriteMethod());
          return property;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/common/ReflectedScalarPropertyParseResults.java
  
  Index: ReflectedScalarPropertyParseResults.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 org.apache.commons.clazz.reflect.ReflectedClazz;
  
  /**
   * Holds parse results for individual accessor methods for a 
   * scalar property.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedScalarPropertyParseResults.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedScalarPropertyParseResults 
              extends ReflectedPropertyParseResults
  {
      /**
       * Constructor for ReflectedScalarPropertyParseResults.
       */
      public ReflectedScalarPropertyParseResults(
              ReflectedClazz clazz, String propertyName) 
      {
          super(clazz, propertyName);
      }
      
      protected String getPropertyCategory(){
          return "scalar";
      }
      
      public boolean checkConsistency(){        
          if (!super.checkConsistency()){
              return false;
          }
                  
          if (readMethodParseResults == null){
              return false;
          }
  
          Class type = readMethodParseResults.getType();
          if (writeMethodParseResults != null){
              if (!type.equals(writeMethodParseResults.getType())){
                  return false;
              }
          }
          return true;
      }
          
      protected boolean appendInconsistencyDescriptions(StringBuffer buffer){
          if (!super.appendInconsistencyDescriptions(buffer)){
              return false;
          }
                  
          if (readMethodParseResults == null){
              buffer.append("\n     - Does not have a get() method");
              return true;
          }
  
          Class type = readMethodParseResults.getType();
          if (writeMethodParseResults != null){
              if (!type.equals(writeMethodParseResults.getType())){
                  buffer.append("\n     - Get() and set(v) types do not match");
              }
          }
          return true;  
      }  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ExtendedReflectedClazzLoader.java
  
  Index: ExtendedReflectedClazzLoader.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.common.GroupClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.ReflectedClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedPropertyIntrospector;
  import org.apache.commons.clazz.reflect.common.*;
  
  /**
   * A version of ReflectedClazzLoader that supports the extended notion of
   * JavaBeans.
   * <p>
   * It recognizes of  List, Mapped and Scalar properties. 
   *
   * @author Dmitri Plotnikov
   * @version $Revision: 1.1 $ $Date: 2002/12/06 01:12:49 $
   */
  public class ExtendedReflectedClazzLoader extends ReflectedClazzLoader {
  
      /**
       * The default list of introspectors consists of List, Mapped and Scalar
       * property introspectors.
       */
      private static final 
              ReflectedPropertyIntrospector[] DEFAULT_PROPERTY_INTROSPECTORS =
          new ReflectedPropertyIntrospector[] {
              ExtendedReflectedListPropertyIntrospector.INTROSPECTOR,
              ReflectedMappedPropertyIntrospector.INTROSPECTOR,
              ReflectedScalarPropertyIntrospector.INTROSPECTOR };
  
  
      /**
       * Constructor for ExtendedReflectedClazzLoader.
       * @param group
       * @param classLoader
       */
      public ExtendedReflectedClazzLoader(
                  GroupClazzLoader group,
                  ClassLoader classLoader) 
      {
          super(group, classLoader);
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedClazzLoader#createClazz(org.apache.commons.clazz.ClazzLoader, java.lang.Class)
       */
      protected Clazz createClazz(ClazzLoader clazzLoader, Class javaClass) {
          return new ReflectedClazz(
              clazzLoader,
              javaClass,
              DEFAULT_PROPERTY_INTROSPECTORS);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ExtendedReflectedListPropertyIntrospector.java
  
  Index: ExtendedReflectedListPropertyIntrospector.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 java.lang.reflect.Method;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.commons.clazz.reflect.*;
  import org.apache.commons.clazz.reflect.common.*;
  
  /**
   * A ReflectedPropertyIntrospector that discovers list (aka indexed) properties.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ExtendedReflectedListPropertyIntrospector.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ExtendedReflectedListPropertyIntrospector
      extends ReflectedListPropertyIntrospectorSupport 
  {
  
      /**
       * The global instance of ReflectedListPropertyIntrospectorSupport that
       * should be used by ReflectedClass to create list properties.
     */
      public static final ExtendedReflectedListPropertyIntrospector INTROSPECTOR =
              new ExtendedReflectedListPropertyIntrospector();
   
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected ExtendedReflectedListPropertyIntrospector(){
      }
      
      public void introspectProperties(
              ReflectedClazz clazz,
              Class javaClass,
              Map parseResultMap)
      {
          HashMap parseResultMapSingular = new HashMap();
          Method methods[] = javaClass.getMethods();
          ReflectedListPropertyParseResults parseResults;
          AccessorMethodParseResults results;
          for (int i = 0; i < methods.length; i++) {
              Method method = methods[i];
  
              // Check getFooCount() before we check getFooList(),
              // because the parser for the latter is generic enough
              // to include the former            
              results = parseSizeMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setSizeMethodParseResults(results);
                  continue;
              }
              
              results = parseReadMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setReadMethodParseResults(results);
                  continue;
              }
  
              results = parseWriteMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setWriteMethodParseResults(results);
                  continue;
              }
  
              results = parseGetMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setGetMethodParseResults(results);
                  continue;
              }
              
              results = parseSetMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setSetMethodParseResults(results);
                  continue;
              }
              
              results = parseAddMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setAddMethodParseResults(results);
                  continue;
              }
              
              results = parseAddIndexedMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setAddIndexedMethodParseResults(results);
                  continue;
              }
              
              results = parseRemoveMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setRemoveMethodParseResults(results);
                  continue;
              }
          }
          
          Iterator iter = parseResultMap.entrySet().iterator();
          while (iter.hasNext()) {
              Map.Entry entry = (Map.Entry) iter.next();
              ReflectedListPropertyParseResults result = 
                  (ReflectedListPropertyParseResults) entry.getValue();
              if (!result.isList()){
                  iter.remove();
              }
          }
          
          mergeSingularMethods(parseResultMap, parseResultMapSingular);
      }
  
      /**
       * Parser for the <code>addFoo(value)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "add" followed by capitalized singular
       *      form of the property name</li>
       *  <li>One parameter</li>
       * </ul>
       */                        
      protected static AccessorMethodParser ADD_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected String requiredPrefix(){
              return "add";
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected Class getValueType(Method method){
              return method.getParameterTypes()[0];
          }        
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseAddMethod(Method method) {
          return ADD_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>addFoo(index, value)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "add" followed by capitalized singular
       *      form of the property name</li>
       *  <li>Two parameters, first integer</li>
       * </ul>
       */                        
      protected static AccessorMethodParser ADD_INDEXED_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected String requiredPrefix(){
              return "add";
          }
          
          protected int requiredParameterCount(){
              return 2;
          }
  
          protected boolean testParameterType(int index, Class parameterType){            
              if (index == 0){            
                  return parameterType.equals(Integer.TYPE);
              }
              return true;
          }
          
          protected Class getValueType(Method method){
              return method.getParameterTypes()[1];
          }        
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseAddIndexedMethod(Method method) {
          return ADD_INDEXED_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>removeFoo(index)</code> method:
       * <ul>
       *  <li>Name starts with "remove" followed by capitalized singular
       *      form of the property name</li>
       *  <li>One parameter</li>
       * </ul>
       */                        
      protected static AccessorMethodParser REMOVE_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected String requiredPrefix(){
              return "remove";
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected Class getValueType(Method method){
              return method.getParameterTypes()[0];
          }
      };
                          
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseRemoveMethod(Method method) {
          return REMOVE_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>getFooCount()</code> method:
       * <ul>
       *  <li>Returns integer</li>
       *  <li>Name starts with "get" followed by capitalized singular
       *      form of the property name, followed by "Count" or "Size"</li>
       *  <li>No parameters</li>
       * </ul>
       */                        
      protected static AccessorMethodParser SIZE_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class javaClass){
              return javaClass.equals(Integer.TYPE);
          }
          
          protected String requiredPrefix(){
              return "get";
          }
          
          protected int requiredParameterCount(){
              return 0;
          }
          
          protected String testAndRemoveSuffix(String methodName){
              if (methodName.endsWith("Count")){                
                  return methodName.substring(0, methodName.length() - 5);
              }
              if (methodName.endsWith("Size")){
                  return methodName.substring(0, methodName.length() - 4);
              }
              return null;
          }
      };
                          
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseSizeMethod(Method method) {
          return SIZE_METHOD_PARSER.parse(method);
      }
  
      /**
       * Returns <code>true</code> if the suffix is "s" or 
       * "List", "Array" or "Vector".
       *  
       * @see org.apache.commons.clazz.reflect.ReflectedPropertyFactorySupport#isCorrectPluralSuffix(String, String)
       */
      protected boolean isCorrectPluralSuffix(String singular, String suffix){
          return super.isCorrectPluralSuffix(singular, suffix) || 
                  suffix.equals("List") ||
                  suffix.equals("Array") ||
                  suffix.equals("Vector");
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMap.java
  
  Index: ReflectedMap.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 java.lang.reflect.Method;
  import java.util.*;
  
  import org.apache.commons.clazz.reflect.ReflectedAccessException;
  
  
  /**
   * This is an implementation of the <code>Map</code> interface
   * that is based on a Mapped property.  Whenever possible, it
   * uses concrete methods on the owner of the property to manipulate the map.
   * <p>
   * Consider the following example:
   * <pre>
   *      Map map = (Map)clazz.getProperty("fooMap").get(instance);
   *      Object value = map.get("bar");
   * </pre>
   * 
   * If <code>instance</code> has a <code>getFoo(String key)</code> method,
   * this code will implicitly invoke it like this: <code>getFoo("bar")</code>.
   * otherwise it will obtain the whole map and extract the 
   * requested value.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMap.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedMap implements Map 
  {
      private Object instance;
      private ReflectedMappedProperty property;
      
      /**
       * Constructor for ReflectedMap.
       */
      public ReflectedMap(
              Object instance,
              ReflectedMappedProperty property) 
      {
          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() {
      }
  
      /**
       * @see java.util.Map#containsKey(java.lang.Object)
       */
      public boolean containsKey(Object key) {
          return false;
      }
  
      /**
       * @see java.util.Map#containsValue(java.lang.Object)
       */
      public boolean containsValue(Object value) {
          return false;
      }
  
      /**
       * @see java.util.Map#entrySet()
       */
      public Set entrySet() {
          return null;
      }
  
      /**
       * If there is a getFoo(key) method, calls that for every key.
       * Otherwise, calls getFooMap().get(key)
       * 
       * @see java.util.Map#get(java.lang.Object)
       */
      public Object get(Object key) {
          Method getMethod = property.getGetMethod();
          if (getMethod != null){
              Object value;
              try {
                  value = getMethod.invoke(instance, new Object[]{key});
              }
              catch (Exception ex) {
                  throw new ReflectedAccessException(
                      "Cannot get property : "
                          + property.getName()
                          + ": cannot invoke method: "
                          + getMethod.getName(),
                      ex);
              }
              return value;
          }
          else {
              Map map = property.getMap(instance);
              if (map == null){
                  return null;
              }
              return map.get(key);
          }
      }
  
      /**
       * @see java.util.Map#isEmpty()
       */
      public boolean isEmpty() {
          return false;
      }
  
      /**
       * @see java.util.Map#keySet()
       */
      public Set keySet() {
          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 HashSet((Collection)value);
                  }
                  else {
                      set = new HashSet(Arrays.asList((Object[])value));
                  }
              }
              catch (Exception ex) {
                  throw new ReflectedAccessException(
                      "Cannot get key set: "
                          + property.getName()
                          + ": cannot invoke method: "
                          + keySetMethod.getName(),
                      ex);
              }
              return set;
          }
          else {
              Map map = property.getMap(instance);
              if (map == null){
                  return Collections.EMPTY_SET;
              }
              return map.keySet();
          }
      }
  
      /**
       * @see java.util.Map#put(java.lang.Object, java.lang.Object)
       */
      public Object put(Object key, Object value) {        
          Method putMethod = property.getPutMethod();
          if (putMethod != null){
              Object oldValue = null;
              try {
                  oldValue = get(key);
              }
              catch (Throwable t){
                  // Ignore
              }
              
              try {
                  putMethod.invoke(instance, new Object[]{key, value});
              }
              catch (Exception ex) {
                  throw new ReflectedAccessException(
                      "Cannot set property : "
                          + property.getName()
                          + ": cannot invoke method: "
                          + putMethod.getName(),
                      ex);
              }
              return oldValue;
          }
          else {
              Map map = property.getMap(instance);
              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");
                  }
              }
              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;
      }
  
      /**
       * @see java.util.Map#size()
       */
      public int size() {
          return 0;
      }
  
      /**
       * @see java.util.Map#values()
       */
      public Collection values() {
          return null;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedProperty.java
  
  Index: ReflectedMappedProperty.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 java.lang.reflect.Method;
  import java.util.Map;
  
  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: ReflectedMappedProperty.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedMappedProperty extends ReflectedProperty {
  
      private Class keyType;
      private Class contentType;
      private Method sizeMethod;
      private Method getMethod;
      private Method putMethod;
      private Method removeMethod;
      private Method keySetMethod;
      
      /**
       * Constructor for ReflectedMappedProperty.
       * @param declaringClazz
       * @param name
       */
      public ReflectedMappedProperty(Clazz declaringClazz, String name) {
          super(declaringClazz, name);
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#isMap()
       */
      public boolean isMap() {
          return true;
      }
      
      /**
       * Returns the keyType.
       * @return Class
       */
      public Class getKeyType() {
          return keyType;
      }
  
      /**
       * Sets the keyType.
       * @param keyType The keyType to set
       */
      public void setKeyType(Class keyType) {
          this.keyType = keyType;
      }
  
      /**
       * Returns the contentType.
       * @return Class
       */
      public Class getContentType() {
          return contentType;
      }
  
      /**
       * Sets the contentType.
       * @param contentType The contentType to set
       */
      public void setContentType(Class valueType) {
          this.contentType = valueType;
      }
      
      /**
       * Returns the getMethod.
       * @return Method
       */
      public Method getGetMethod() {
          return getMethod;
      }
  
      /**
       * Sets the getMethod.
       * @param getMethod The getMethod to set
       */
      public void setGetMethod(Method getMethod) {
          this.getMethod = getMethod;
      }
      
      /**
       * Returns the putMethod.
       * @return Method
       */
      public Method getPutMethod() {
          return putMethod;
      }
  
      /**
       * Sets the putMethod.
       * @param putMethod The putMethod to set
       */
      public void setPutMethod(Method putMethod) {
          this.putMethod = putMethod;
      }
  
      /**
       * Returns the removeMethod.
       * @return Method
       */
      public Method getRemoveMethod() {
          return removeMethod;
      }
  
      /**
       * Sets the removeMethod.
       * @param removeMethod The removeMethod to set
       */
      public void setRemoveMethod(Method removeMethod) {
          this.removeMethod = removeMethod;
      }
  
      /**
       * Returns the keySetMethod.
       * @return Method
       */
      public Method getKeySetMethod() {
          return keySetMethod;
      }
  
      /**
       * Sets the keySetMethod.
       * @param keySetMethod The keySetMethod to set
       */
      public void setKeySetMethod(Method keySetMethod) {
          this.keySetMethod = keySetMethod;
      }
  
      public String toString(){
          StringBuffer buffer = new StringBuffer("[ReflectedMappedProperty ");
          if (getType() != null){
              buffer.append(getType().getName());
              buffer.append(" ");
          }
          if (getKeyType() != null){
              buffer.append("[key: ");
              buffer.append(getKeyType().getName());
              buffer.append("] ");
          }
          if (getContentType() != null){
              buffer.append("[content: ");
              buffer.append(getContentType().getName());
              buffer.append("] ");
          }
          buffer.append(getName());
          if (getReadMethod() != null){
              buffer.append("\n   [read method]   ");
              buffer.append(getReadMethod());            
          }
          if (getWriteMethod() != null){
              buffer.append("\n   [write method]  ");
              buffer.append(getWriteMethod());            
          }
          if (getGetMethod() != null){
              buffer.append("\n   [get method]    ");
              buffer.append(getGetMethod());            
          }
          if (getPutMethod() != null){
              buffer.append("\n   [put method]    ");
              buffer.append(getPutMethod());            
          }
          if (getRemoveMethod() != null){
              buffer.append("\n   [remove method] ");
              buffer.append(getRemoveMethod());            
          }
          if (getKeySetMethod() != null){
              buffer.append("\n   [keySet method] ");
              buffer.append(getKeySetMethod());            
          }
          buffer.append("]");
          return buffer.toString();
      }
      /**
       * @see org.apache.commons.clazz.ClazzProperty#get(java.lang.Object)
       */
      public Object get(Object instance) {
          return new ReflectedMap(instance, this);
      }
      
      public Map getMap(Object instance) {
          if (getReadMethod() == null){
              return null;
          }
          
          return (Map)super.get(instance);
      }
  
      /**
       * @see org.apache.commons.clazz.ClazzProperty#set(java.lang.Object, java.lang.Object)
       */
      public void set(Object instance, Object value) {
          super.set(instance, value);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyIntrospector.java
  
  Index: ReflectedMappedPropertyIntrospector.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 java.lang.reflect.Method;
  import java.util.*;
  
  import org.apache.commons.clazz.reflect.*;
  import org.apache.commons.clazz.reflect.common.*;
  
  /**
   * A ReflectedPropertyIntrospector that discovers mapped properties.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMappedPropertyIntrospector.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedMappedPropertyIntrospector
      extends ReflectedPropertyIntrospectorSupport 
  {
  
      /**
       * The global instance of ReflectedMappedPropertyIntrospector that
       * should be used by ReflectedClass to create mapped properties.
     */
      public static final ReflectedMappedPropertyIntrospector INTROSPECTOR =
              new ReflectedMappedPropertyIntrospector();
   
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected ReflectedMappedPropertyIntrospector(){
      }
      
      /**
       * Goes over methods of the supplied class and creates 
       * ReflectedProperty objects for discovered properties.
     */
      public void introspectProperties(
              ReflectedClazz clazz,
              Class javaClass,
              Map parseResultMap)
      {
          HashMap parseResultMapSingular = new HashMap();
          Method methods[] = javaClass.getMethods();
          ReflectedMappedPropertyParseResults parseResults;
          AccessorMethodParseResults results;
          for (int i = 0; i < methods.length; i++) {
              Method method = methods[i];
              
              // Check getFooKeys() before we check getFooList(),
              // because the parser for the latter is generic enough
              // to include the former            
              results = parseKeySetMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setKeySetMethodParseResults(results);
                  continue;
              }
              
              results = parseReadMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setReadMethodParseResults(results);
                  continue;
              }
  
              results = parseWriteMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setWriteMethodParseResults(results);
                  continue;
              }
  
              results = parseGetMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setGetMethodParseResults(results);
                  continue;
              }
              
              results = parsePutMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setPutMethodParseResults(results);
                  continue;
              }
              
              results = parseRemoveMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setRemoveMethodParseResults(results);
                  continue;
              }
          }
          
          Iterator iter = parseResultMap.entrySet().iterator();
          while (iter.hasNext()) {
              Map.Entry entry = (Map.Entry) iter.next();
              ReflectedMappedPropertyParseResults result = 
                  (ReflectedMappedPropertyParseResults) entry.getValue();
              if (!result.isMap()){
                  iter.remove();
              }
          }
          
          mergeSingularMethods(parseResultMap, parseResultMapSingular);
      }
  
      /**
       * Parser for the <code>getFooMap()</code> method:
       * <ul>
       *  <li>Return type not void</li>
       *  <li>Name starts with "get" followed by capitalized property name</li>
       *  <li>No parameters</li>
       * </ul>
       * 
       * We don't check if the parameter is a Map here. If it is not,
       * we want to recognize the method and them mark the corresponding
       * property as NotAProperty.
       */
      protected static AccessorMethodParser READ_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class returnType){
              return !returnType.equals(Void.TYPE);
          }
          
          protected String requiredPrefix(){
              return "get";
          }
          
          protected int requiredParameterCount(){
              return 0;
          }
  
          protected Class getValueType(Method method){
              return method.getReturnType();
          }
          
      };
              
      /**
       * Looks at the method to see if it has the signature
       * of a property read method, like "Map getIntegerMap()", parses it
       * and returns the results of parsing.  If the method signature 
       * does not fit the criteria, returns <code>null</code>.
       */
      protected AccessorMethodParseResults parseReadMethod(Method method) {
          return READ_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>setFooMap(Map)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "set" followed by capitalized property name</li>
       *  <li>One parameter</li>
       * </ul>
       * 
       * We don't check if the parameter is a Map here. If it is not,
       * we want to recognize the method and them mark the corresponding
       * property as NotAProperty.
       */            
      protected static AccessorMethodParser WRITE_METHOD_PARSER =
              new AccessorMethodParser()
      {
          protected boolean testReturnType(Class returnType){
              return returnType.equals(Void.TYPE);
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected String requiredPrefix(){
              return "set";
          }
                  
          protected Class getValueType(Method method){
              return method.getParameterTypes()[0];
          }
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseWriteMethod(Method method) {
          return WRITE_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>getFoo(key)</code> method:
       * <ul>
       *  <li>Return type not void</li>
       *  <li>Name starts with "get" followed by capitalized singular
       *      form of the property name</li>
       *  <li>One parameter</li>
       * </ul>
       */            
      protected static AccessorMethodParser GET_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class returnType){
              return !returnType.equals(Void.TYPE);
          }
          
          protected String requiredPrefix(){
              return "get";
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected Class getValueType(Method method){
              return method.getReturnType();
          }
          
          protected Class getParameterType(Method method){
              return method.getParameterTypes()[0];
          }
          
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseGetMethod(Method method) {
          return GET_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>setFoo(key, value)</code> method:
       * <ul>
       *  <li>Return type void</li>
       *  <li>Name starts with "set" followed by capitalized singular
       *      form of the property name</li>
       *  <li>Two parameters</li>
       * </ul>
       */                        
      protected static AccessorMethodParser PUT_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected String requiredPrefix(){
              return "set";
          }
          
          protected int requiredParameterCount(){
              return 2;
          }
  
          protected Class getValueType(Method method){
              return method.getParameterTypes()[1];
          }
          
          protected Class getParameterType(Method method){
              return method.getParameterTypes()[0];
          }
          
      };
      
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parsePutMethod(Method method) {
          return PUT_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>removeFoo(key)</code> method:
       * <ul>
       *  <li>Name starts with "remove" followed by capitalized singular
       *      form of the property name</li>
       *  <li>One parameter</li>
       * </ul>
       */                        
      protected static AccessorMethodParser REMOVE_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected String requiredPrefix(){
              return "remove";
          }
          
          protected int requiredParameterCount(){
              return 1;
          }
  
          protected Class getValueType(Method method){
              Class returnType = method.getReturnType();
              if (Void.TYPE.equals(returnType)){
                  return null;
              }
              return returnType;
          }
          
          protected Class getParameterType(Method method){
              return method.getParameterTypes()[0];
          }
          
      };
                          
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseRemoveMethod(Method method) {
          return REMOVE_METHOD_PARSER.parse(method);
      }
  
      /**
       * Parser for the <code>getFooKeys()</code> method:
       * <ul>
       *  <li>Returns integer</li>
       *  <li>Name starts with "get" followed by capitalized singular
       *      form of the property name, followed by "Keys" or "KeySet"</li>
       *  <li>No parameters</li>
       * </ul>
       */                        
      protected static AccessorMethodParser KEY_SET_METHOD_PARSER = 
              new AccessorMethodParser()
      {               
          protected boolean testReturnType(Class javaClass){
              return javaClass.isArray() ||
                  Collection.class.isAssignableFrom(javaClass);
          }
          
          protected String requiredPrefix(){
              return "get";
          }
          
          protected int requiredParameterCount(){
              return 0;
          }
          
          protected String testAndRemoveSuffix(String methodName){
              if (methodName.endsWith("Keys")){                
                  return methodName.substring(0, methodName.length() - 4);
              }
              if (methodName.endsWith("KeySet")){
                  return methodName.substring(0, methodName.length() - 6);
              }
              return null;
          }
      };
                          
      /**
       * @see #parseReadMethod
       */
      public AccessorMethodParseResults parseKeySetMethod(Method method) {
          return KEY_SET_METHOD_PARSER.parse(method);
      }
  
      /**
       * Combines data collected from singular methods like 
       * <code>getFoo(key)</code> with parse results for plural methods 
       * like <code>getFooMap()</code>. 
     */    
      protected void mergeSingularMethods(
              Map parseResultMapPlural, Map parseResultMapSingular)
      {
          Iterator iter = parseResultMapSingular.values().iterator();
          while (iter.hasNext()) {
              
              ReflectedMappedPropertyParseResults singular =
                  (ReflectedMappedPropertyParseResults) iter.next();
                  
              ReflectedMappedPropertyParseResults plural =
                  findBySingularName(
                          parseResultMapPlural, singular.getPropertyName());
              
              if (plural != null) {
                  plural.merge(singular);
              }
              else {
                  // We don't have any plural methods - let's just use
                  // the singular ones then
                  parseResultMapPlural.put(singular.getPropertyName(), singular);
              }
          }
      }
  
      /**
       * Given a singular form of a property name, locates parse results
       * for a property with the corresponding plural name.
     */
      protected ReflectedMappedPropertyParseResults findBySingularName(
              Map parseResultMapPlural,
              String singularName) 
      {
          ReflectedMappedPropertyParseResults plural =
              (ReflectedMappedPropertyParseResults) 
                  parseResultMapPlural.get(singularName);
          if (plural != null) {
              return plural;
          }
  
          Iterator iter = parseResultMapPlural.entrySet().iterator();
          while (iter.hasNext()) {
              Map.Entry entry = (Map.Entry) iter.next();
              if (isCorrectPluralForm(singularName, (String) entry.getKey())) {
                  return (ReflectedMappedPropertyParseResults) entry.getValue();
              }
          }
          return null;
      }
  
      /**
       * Returns <code>true</code> if the suffix is "s" or "Map".
       *  
       * @see org.apache.commons.clazz.reflect.ReflectedPropertyFactorySupport#isCorrectPluralSuffix(String, String)
       */
      protected boolean isCorrectPluralSuffix(String singular, String suffix){
          return super.isCorrectPluralSuffix(singular, suffix) || 
                  suffix.equals("Map");
      }
      
       
      /**
       * Finds a ReflectedMappedPropertyParseResults for the given
       * propertyName or creates a new one and puts it in the map.
       */
      protected ReflectedMappedPropertyParseResults getParseResults(
              ReflectedClazz clazz,
              Map parseResultMap,
              String propertyName) 
      {
          ReflectedMappedPropertyParseResults parseResults =
              (ReflectedMappedPropertyParseResults) parseResultMap.get(
                  propertyName);
          if (parseResults == null) {
              parseResults =
                  new ReflectedMappedPropertyParseResults(clazz, propertyName);
              parseResultMap.put(propertyName, parseResults);
          }
          return parseResults;
      }
      
      /**
       * Creates a new ReflectedMappedProperty based on parse results. 
       */
      protected ReflectedProperty createProperty(
          ReflectedClazz clazz,
          ReflectedPropertyParseResults parseResults)
      {
          ReflectedMappedProperty property =
              new ReflectedMappedProperty(clazz, parseResults.getPropertyName());
  
          ReflectedMappedPropertyParseResults parseResultsMapped =
                  (ReflectedMappedPropertyParseResults)parseResults;
  
          property.setAliases(parseResultsMapped.getAliases());                 
          property.setType(parseResultsMapped.getPropertyType());
          property.setKeyType(parseResultsMapped.getKeyType());
          property.setContentType(parseResultsMapped.getContentType());
          property.setReadMethod(parseResultsMapped.getReadMethod());
          property.setWriteMethod(parseResultsMapped.getWriteMethod());
          property.setGetMethod(parseResultsMapped.getGetMethod());
          property.setPutMethod(parseResultsMapped.getPutMethod());
          property.setRemoveMethod(parseResultsMapped.getRemoveMethod());
          property.setKeySetMethod(parseResultsMapped.getKeySetMethod());
          return property;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyParseResults.java
  
  Index: ReflectedMappedPropertyParseResults.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 java.lang.reflect.Method;
  import java.util.Map;
  
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.common.AccessorMethodParseResults;
  import org.apache.commons.clazz.reflect.common.ReflectedPropertyParseResults;
  
  /**
   * Holds parse results for individual accessor methods for a 
   * mapped property.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMappedPropertyParseResults.java,v 1.1 2002/12/06 01:12:49 dmitri Exp $
   */
  public class ReflectedMappedPropertyParseResults 
              extends ReflectedPropertyParseResults
  {
      private AccessorMethodParseResults getMethodParseResults;
      private AccessorMethodParseResults putMethodParseResults;
      private AccessorMethodParseResults removeMethodParseResults;
      private AccessorMethodParseResults keySetMethodParseResults;
  
      /**
       * Constructor for ReflectedMappedPropertyParseResults.
       */
      public ReflectedMappedPropertyParseResults(
              ReflectedClazz clazz, String propertyName) 
      {
          super(clazz, propertyName);
      }
      
      protected String getPropertyCategory(){
          return "mapped";
      }
  
      /**
       * Returns <code>true</code> if the property is 
       * java.util.Map or implements java.util.Map.
       */
      protected boolean isMap(){
          if (readMethodParseResults != null &&
                  isMap(readMethodParseResults.getType())){
              return true;
          }
          if (writeMethodParseResults != null &&
                  isMap(writeMethodParseResults.getType())){
              return true;
          }
          return false;        
      }
          
      private boolean isMap(Class javaClass){
          return javaClass != null && Map.class.isAssignableFrom(javaClass);
      }
      
      public Class getKeyType(){
          if (getMethodParseResults != null){
              return getMethodParseResults.getParameterType();
          }
          if (putMethodParseResults != null){
              return putMethodParseResults.getParameterType();
          }
          if (removeMethodParseResults != null){
              return removeMethodParseResults.getParameterType();
          }
          return null;        
      }
  
      public Class getContentType(){
          if (getMethodParseResults != null){
              return getMethodParseResults.getType();
          }
          if (putMethodParseResults != null){
              return putMethodParseResults.getType();
          }
          if (removeMethodParseResults != null){
              return removeMethodParseResults.getType();
          }
          return null;
          
      }
  
      public void setGetMethodParseResults(
                  AccessorMethodParseResults getMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.getMethodParseResults,
              getMethodParseResults);
          this.getMethodParseResults = getMethodParseResults;
      }
  
      public Method getGetMethod() {
          if (getMethodParseResults == null){
              return null;
          }
          return getMethodParseResults.getMethod();
      }
      
  
      public void setPutMethodParseResults(
                  AccessorMethodParseResults putMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.putMethodParseResults,
              putMethodParseResults);
          this.putMethodParseResults = putMethodParseResults;
      }
      
      public Method getPutMethod() {
          if (putMethodParseResults == null){
              return null;
          }
          return putMethodParseResults.getMethod();
      }
          
      public void setRemoveMethodParseResults(
                  AccessorMethodParseResults removeMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.removeMethodParseResults,
              removeMethodParseResults);
          this.removeMethodParseResults = removeMethodParseResults;
      }
      
      public Method getRemoveMethod() {
          if (removeMethodParseResults == null){
              return null;
          }
          return removeMethodParseResults.getMethod();
      }
      
      public void setKeySetMethodParseResults(
                  AccessorMethodParseResults keySetMethodParseResults) 
      {
          checkForExtraneousAccessor(
              this.keySetMethodParseResults,
              keySetMethodParseResults);
          this.keySetMethodParseResults = keySetMethodParseResults;
      }
      
      public Method getKeySetMethod() {
          if (keySetMethodParseResults == null){
              return null;
          }
          return keySetMethodParseResults.getMethod();
      }
      
      /**
       * Combines parse results from another instance of 
       * <code>ReflectedMappedPropertyParseResults</code> with
       * results contained by this object.
       * <p>
       * Node that the property name is not copied from the 
       * <code>other</code> object.
       */        
      public void merge(ReflectedMappedPropertyParseResults other){
          super.merge(other);
          if (other.readMethodParseResults != null){
              setReadMethodParseResults(other.readMethodParseResults);
          }
          if (other.writeMethodParseResults != null){
              setWriteMethodParseResults(other.writeMethodParseResults);
          }
          if (other.getMethodParseResults != null){
              setGetMethodParseResults(other.getMethodParseResults);
          }
          if (other.putMethodParseResults != null){
              setPutMethodParseResults(other.putMethodParseResults);
          }
          if (other.removeMethodParseResults != null){
              setRemoveMethodParseResults(other.removeMethodParseResults);
          }
          if (other.keySetMethodParseResults != null){
              setKeySetMethodParseResults(other.keySetMethodParseResults);
          }
      }
      
      protected void appendDescription(StringBuffer buffer){
          super.appendDescription(buffer);
          Class keyType = getKeyType();
          if (keyType != null){
              buffer.append("\n  [key type]       ");
              buffer.append(keyType.getName());
          }
          
          Class contentType = getContentType();
          if (contentType != null){
              buffer.append("\n  [content type]   ");
              buffer.append(contentType.getName());
          }
      }
      
      protected void appendMethodDescriptions(StringBuffer buffer){
          super.appendMethodDescriptions(buffer);
          if (getMethodParseResults != null){
              buffer.append("\n    [get~(key)]    ");
              buffer.append(getMethodParseResults.getMethod());
          }
          if (putMethodParseResults != null){
              buffer.append("\n    [set~(key,v)]  ");
              buffer.append(putMethodParseResults.getMethod());
          }
          if (removeMethodParseResults != null){
              buffer.append("\n    [remove~(key)] ");
              buffer.append(removeMethodParseResults.getMethod());
          }
          if (keySetMethodParseResults != null){
              buffer.append("\n    [get~KeySet()] ");
              buffer.append(keySetMethodParseResults.getMethod());
          }
      }
      
      public boolean checkConsistency(){        
          if (!super.checkConsistency()){
              return false;
          }
                  
          if (readMethodParseResults == null && getMethodParseResults == null){
              return false;
          }
  
          if (readMethodParseResults != null){
              Class type = readMethodParseResults.getType();
              if (writeMethodParseResults != null){
                  if (!type.equals(writeMethodParseResults.getType())){
                      return false;
                  }
              }
          }
                  
          Class keyType = null;
          Class contentType = null;
           
          if (getMethodParseResults != null){
              keyType = getMethodParseResults.getParameterType();
              contentType = getMethodParseResults.getType();
          }
          
          if (putMethodParseResults != null){
              if (keyType == null){
                  keyType = putMethodParseResults.getParameterType();
              }
              else {
                  if (!keyType.equals(putMethodParseResults.getParameterType())){
                      return false;
                  }
              }
              
              if (contentType == null){
                  contentType = putMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(
                          putMethodParseResults.getType())){
                      return false;
                  }
              }
          }
          
          if (removeMethodParseResults != null) {
              if (keyType != null
                  && !keyType.
                          equals(removeMethodParseResults.getParameterType())) {
                  return false;
              }
                          
              if (contentType != null){
                  Class removeType = removeMethodParseResults.getType(); 
                  if (removeType != null && !contentType.equals(removeType)){
                      return false;
                  }
              }
          }
          
          return true;
      }
          
      protected boolean appendInconsistencyDescriptions(StringBuffer buffer){
          if (!super.appendInconsistencyDescriptions(buffer)){
              return false;
          }        
          
          if (readMethodParseResults == null && getMethodParseResults == null){
              buffer.append(
                  "\n     - Does not have either get() or get(key) method");
              return true;
          }
  
          if (readMethodParseResults != null){
              Class type = readMethodParseResults.getType();
              if (writeMethodParseResults != null){
                  if (!type.equals(writeMethodParseResults.getType())){
                      buffer.append(
                          "\n     - Get() and set(v) types do not match");
                  }
              }
          }
          
          Class keyType = null;
          Class contentType = null;
           
          if (getMethodParseResults != null){
              keyType = getMethodParseResults.getParameterType();
              contentType = getMethodParseResults.getType();
          }
          
          if (putMethodParseResults != null){
              if (keyType == null){
                  keyType = putMethodParseResults.getParameterType();
              }
              else {
                  if (!keyType.equals(putMethodParseResults.getParameterType())){
                      buffer.append(
                          "\n     - Key type mismatch between "
                              + "get(key) and set(key,v)");
                  }
              }
              
              if (contentType == null){
                  contentType = putMethodParseResults.getType();
              }
              else {
                  if (!contentType.equals(
                          putMethodParseResults.getType())){
                      buffer.append(
                          "\n     - Content type mismatch between "
                              + "get(key) and set(key,v)");
                  }
              }
          }
          
          if (removeMethodParseResults != null) {
              if (keyType != null
                  && !keyType.
                          equals(removeMethodParseResults.getParameterType())) {
                  buffer.append(
                      "\n     - Key type mismatch between "
                          + "get(key) and remove(key)");
              }
                          
              if (contentType != null){
                  Class removeType = removeMethodParseResults.getType(); 
                  if (removeType != null && !contentType.equals(removeType)){
                      buffer.append(
                          "\n     - Content type mismatch between "
                              + "get(key) and set(key,v)");
                  }
              }
          }        
          return true;
      }  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/standard/StandardReflectedClazzLoader.java
  
  Index: StandardReflectedClazzLoader.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.common.GroupClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedClazz;
  import org.apache.commons.clazz.reflect.ReflectedClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedPropertyIntrospector;
  import org.apache.commons.clazz.reflect.common.*;
  
  /**
   * 
   *
   * @author Dmitri Plotnikov
   * @version $Revision: 1.1 $ $Date: 2002/12/06 01:12:50 $
   */
  public class StandardReflectedClazzLoader extends ReflectedClazzLoader {
  
      /**
       * The default list of introspectors consists of Indexed and Scalar property
       * introspectors.
       */
      private static final 
              ReflectedPropertyIntrospector[] STANDARD_PROPERTY_INTROSPECTORS =
          new ReflectedPropertyIntrospector[] {
              StandardReflectedListPropertyIntrospector.INTROSPECTOR,
              ReflectedScalarPropertyIntrospector.INTROSPECTOR };
  
      /**
       * Constructor for StandardReflectedClazzLoader.
       * @param group
       * @param classLoader
       */
      public StandardReflectedClazzLoader(
              GroupClazzLoader group,
              ClassLoader classLoader) 
      {
          super(group, classLoader);
      }
  
      /**
       * @see org.apache.commons.clazz.reflect.ReflectedClazzLoader#createClazz(org.apache.commons.clazz.ClazzLoader, java.lang.Class)
       */
      protected Clazz createClazz(ClazzLoader clazzLoader, Class javaClass) {
          return new ReflectedClazz(
              clazzLoader,
              javaClass,
              STANDARD_PROPERTY_INTROSPECTORS);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/java/org/apache/commons/clazz/reflect/standard/StandardReflectedListPropertyIntrospector.java
  
  Index: StandardReflectedListPropertyIntrospector.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 java.lang.reflect.Method;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.commons.clazz.reflect.*;
  import org.apache.commons.clazz.reflect.common.*;
  
  /**
   * A ReflectedPropertyIntrospector that discovers list (aka indexed) properties.
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: StandardReflectedListPropertyIntrospector.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class StandardReflectedListPropertyIntrospector
      extends ReflectedListPropertyIntrospectorSupport 
  {
  
      /**
       * The global instance of ReflectedListPropertyIntrospectorSupport that
       * should be used by ReflectedClass to create list properties.
     */
      public static final StandardReflectedListPropertyIntrospector INTROSPECTOR =
              new StandardReflectedListPropertyIntrospector();
   
      /**
       * Singleton - not supposed to be allocated by clients. Use
       * the <code>INTROSPECTOR</code> static field instead.
       */
      protected StandardReflectedListPropertyIntrospector(){
      }
      
      public void introspectProperties(
              ReflectedClazz clazz,
              Class javaClass,
              Map parseResultMap)
      {
          HashMap parseResultMapSingular = new HashMap();
          Method methods[] = javaClass.getMethods();
          ReflectedListPropertyParseResults parseResults;
          AccessorMethodParseResults results;
          for (int i = 0; i < methods.length; i++) {
              Method method = methods[i];
  
              results = parseReadMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setReadMethodParseResults(results);
                  continue;
              }
  
              results = parseWriteMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMap,
                          results.getPropertyName());
                  parseResults.setWriteMethodParseResults(results);
                  continue;
              }
  
              results = parseGetMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setGetMethodParseResults(results);
                  continue;
              }
              
              results = parseSetMethod(method);
              if (results != null){
                  parseResults =
                      getParseResults(
                          clazz,
                          parseResultMapSingular,
                          results.getPropertyName());
                  parseResults.setSetMethodParseResults(results);
                  continue;
              }            
          }
          
          Iterator iter = parseResultMap.entrySet().iterator();
          while (iter.hasNext()) {
              Map.Entry entry = (Map.Entry) iter.next();
              ReflectedListPropertyParseResults result = 
                  (ReflectedListPropertyParseResults) entry.getValue();
                  
              Class propertyType = result.getPropertyType();
              Class componentType = result.getContentType();
  
              if (propertyType != null
                  && (!propertyType.isArray()
                      || (componentType != null
                          && propertyType.getComponentType() != componentType))) {
                  iter.remove(); // @todo verify that this actually works
              }
          }
          
          mergeSingularMethods(parseResultMap, parseResultMapSingular);
      }
  
      /**
       * With the standard JavaBean indexed properties the plural form is the same
       * as the singular form.
       */
      protected boolean isCorrectPluralForm(String singular, String plural){
          return singular.equals(plural);
      }    
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/ClazzTest.java
  
  Index: ClazzTest.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;
  
  import org.apache.commons.clazz.bean.BeanClazzTest;
  import org.apache.commons.clazz.reflect.extended.ExtendedReflectedClazzTest;
  import org.apache.commons.clazz.reflect.standard.StandardReflectedClazzTest;
  
  import junit.framework.Test;
  import junit.framework.TestSuite;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ClazzTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class ClazzTest {
  
      public static Test suite() {
          TestSuite suite =
              new TestSuite("Test for org.apache.commons.clazz.*");
          suite.addTest(ExtendedReflectedClazzTest.suite());
          suite.addTest(StandardReflectedClazzTest.suite());
          suite.addTest(BeanClazzTest.suite());
          return suite;
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/ClazzTestSupport.java
  
  Index: ClazzTestSupport.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;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.List;
  
  import junit.framework.TestCase;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ClazzTestSupport.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class ClazzTestSupport extends TestCase {
  
      /**
       * Constructor for ClazzTestSupport.
       * @param name
       */
      public ClazzTestSupport(String name) {
          super(name);
      }
      
      public void assertPropertyList(
              String testName,
              String[] expectedNames,
              List properties)
      {
          List expectedList = Arrays.asList(expectedNames);
          Collections.sort(expectedList);
          List names = new ArrayList();
          for (Iterator iter = properties.iterator(); iter.hasNext();) {
              ClazzProperty property = (ClazzProperty) iter.next();
              names.add(property.getName());
          }
          Collections.sort(names);
  //        System.out.println("Expected: " + testName + expectedList);
  //        System.out.println("Actual:   " + testName + names);
          assertEquals(testName, expectedList, names);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/bean/BeanClazzLoaderTest.java
  
  Index: BeanClazzLoaderTest.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.ClazzProperty;
  
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzLoaderTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class BeanClazzLoaderTest extends TestCase {
  
      /**
       * Constructor for BeanClazzLoaderTest.
       * @param arg0
       */
      public BeanClazzLoaderTest(String arg0) {
          super(arg0);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(BeanClazzLoaderTest.suite());
      }
  
      public static TestSuite suite(){
          return new TestSuite(BeanClazzLoaderTest.class);
      }
  
      private Clazz defineClazz(){
          BeanClazz clazz =
              (BeanClazz) Clazz.getDefaultClazzLoader().defineClazz(
                  BeanClazzTest.TEST_CLAZZ_NAME,
                  BeanClazz.class);
          assertNotNull(clazz);
          ClazzProperty prop1 =
              new BeanClazzProperty(clazz, "integerProperty", "int");
          clazz.addDeclaredProperty(prop1);
  
          return clazz;
      }
             
      public void testDefineClazz() {
          Clazz clazz = defineClazz();
          assertNotNull(clazz);
      }
  
      public void testIsMember() {
      }
  
      public void testGetClazz() {
          defineClazz();
          Clazz clazz =
              Clazz.getDefaultClazzLoader().getClazzForName(BeanClazzTest.TEST_CLAZZ_NAME);
          assertNotNull(clazz);
      }
  
      public void testGetClazzName() {
      }
  
      public void testBeanClazzLoader() {
      }
  
      public void testGetClazzForName() {
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/bean/BeanClazzTest.java
  
  Index: BeanClazzTest.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 junit.framework.TestSuite;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzProperty;
  import org.apache.commons.clazz.ClazzTestSupport;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: BeanClazzTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class BeanClazzTest extends ClazzTestSupport 
  {
      
      public static final String TEST_PACKAGE = "clazz.test";
      public static final String TEST_SUPERCLAZZ_SHORT_NAME = "TestBase";
      public static final String TEST_CLAZZ_SHORT_NAME = "Test";
      public static final String TEST_SUPERCLAZZ_NAME =
          TEST_PACKAGE + "." + TEST_SUPERCLAZZ_SHORT_NAME;
      public static final String TEST_CLAZZ_NAME =
          TEST_PACKAGE + "." + TEST_CLAZZ_SHORT_NAME;
  
      private BeanClazz superClazz;
      private BeanClazz clazz;
      
      /**
       * Constructor for BeanClazzTest.
       * @param name
       */
      public BeanClazzTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(BeanClazzTest.suite());
      }
  
      public static TestSuite suite(){
          TestSuite suite = new TestSuite("Bean clazz tests");
          suite.addTestSuite(BeanClazzLoaderTest.class);
          suite.addTestSuite(BeanClazzTest.class);
          return suite;
      }
  
      public void setUp(){
          superClazz =         
              (BeanClazz) Clazz.getDefaultClazzLoader().defineClazz(
                  TEST_SUPERCLAZZ_NAME,
                  BeanClazz.class);
          superClazz.addDeclaredProperty(
              new BeanClazzProperty(superClazz));
          superClazz.addDeclaredProperty(
              new BeanClazzProperty(superClazz, "baseProperty"));
                  
          clazz =
              (BeanClazz) Clazz.getDefaultClazzLoader().defineClazz(
                  TEST_CLAZZ_NAME,
                  BeanClazz.class);                
          clazz.setSuperclazz(superClazz);
          
          clazz.addDeclaredProperty(
              new BeanClazzProperty(clazz));
          clazz.addDeclaredProperty(
              new BeanClazzProperty(clazz, "objectProperty"));
          clazz.addDeclaredProperty(
              new BeanClazzProperty(clazz, "integerProperty", "int"));
      }
      
      public void testGetName() {
          assertEquals("Clazz name", TEST_CLAZZ_NAME, clazz.getName());
      }
  
      public void testGetPackageName() {
          assertEquals("Package name", TEST_PACKAGE, clazz.getPackageName());
      }
  
      public void testGetShortClassName() {
          assertEquals(
              "Short name",
              TEST_CLAZZ_SHORT_NAME,
              clazz.getShortClassName());
      }
  
      public void testGetSuperclazz() {
          Clazz superClazz = clazz.getSuperclazz();
          assertNotNull(superClazz);
          assertEquals(
              "SuperClazz name ",
              TEST_SUPERCLAZZ_NAME,
              superClazz.getName());
      }
  
      public void testGetDeclaredProperties() {
          assertPropertyList(
              "Get properties",
              new String[]{
                  "integerProperty",
                  "objectProperty",
                  "property2"
              },
              clazz.getDeclaredProperties());       
      }
  
      public void testGetProperties() {
          assertPropertyList(
              "Get properties",
              new String[]{
                  "baseProperty",
                  "integerProperty",
                  "objectProperty",
                  "property1",
                  "property2",
              },
              clazz.getProperties());
      }
  
      public void testGetProperty() {        
          ClazzProperty property = clazz.getProperty("integerProperty");
          assertNotNull(property);
          assertEquals("Property name", "integerProperty", property.getName());
      }
  
      public void testGetPropertyFromSuperclazz() {
          ClazzProperty property = clazz.getProperty("baseProperty");
          assertNotNull(property);
          assertEquals("Property name", "baseProperty", property.getName());
      }
      
      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 BasicBean);
      }
  
      /*
       * Test for Object newInstance(Object[])
       */
      public void testNewInstanceObjectArray() {
      }
  
      public void testAddDeclaredProperty() {
      }
  
      public void testRemoveDeclaredProperty() {
      }
  
      public void testAddDeclaredOperation() {
      }
  
      public void testRemoveDeclaredOperation() {
      }
  
      public void testIsAssignableFrom() {
      }
  
  }
  
  
  
  1.2       +0 -0      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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  
  
  
  1.2       +15 -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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ReflectedClazzTestSupport.java	8 Nov 2002 14:29:36 -0000	1.1
  +++ ReflectedClazzTestSupport.java	6 Dec 2002 01:12:50 -0000	1.2
  @@ -55,28 +55,23 @@
   
   import java.lang.reflect.Method;
   import java.util.ArrayList;
  -import java.util.Arrays;
   import java.util.Collections;
  -import java.util.HashSet;
  -import java.util.Iterator;
   import java.util.List;
  -import java.util.Set;
   
   import org.apache.commons.clazz.Clazz;
  -import org.apache.commons.clazz.ClazzProperty;
  -
  -import junit.framework.TestCase;
  -import junit.framework.TestSuite;
  +import org.apache.commons.clazz.ClazzLoader;
  +import org.apache.commons.clazz.ClazzTestSupport;
   
   /**
    * 
    * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
    * @version $Id$
    */
  -public class ReflectedClazzTestSupport extends TestCase 
  +public abstract class ReflectedClazzTestSupport extends ClazzTestSupport
   {
       protected ReflectableInstance instance;
       protected Clazz clazz;
  +    private static boolean ENABLE_LOGGING = true;
       
       /**
        * Constructor for ReflectedClazzTestSupport.
  @@ -92,9 +87,18 @@
        */
       protected void setUp() throws Exception {
           instance = new ReflectableInstance();
  -        clazz = Clazz.getClazz(instance);
  -        clazz.enableLogging(clazz.getName());
  +        clazz = getClazzLoader().getClazz(instance);
  +        if (ENABLE_LOGGING){
  +            getClazzLoader().enableLogging(clazz.getName());
  +        }
       }
  +    
  +    /**
  +     * Override to test out different Clazz models.
  +     * 
  +     * @return ClazzLoader
  +     */
  +    protected abstract ClazzLoader getClazzLoader();
   
       protected void assertMethodSignature(
               String text,
  
  
  
  1.2       +0 -0      jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedSuperclazzInstance.java
  
  Index: ReflectedSuperclazzInstance.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/ReflectedSuperclazzInstance.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedClazzTest.java
  
  Index: ExtendedReflectedClazzTest.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 junit.framework.TestSuite;
  
  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;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ExtendedReflectedClazzTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class ExtendedReflectedClazzTest extends ReflectedClazzTestSupport {
  
      /**
       * Constructor for ExtendedReflectedClazzTest.
       * @param name
       */
      public ExtendedReflectedClazzTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(ExtendedReflectedClazzTest.suite());
      }
  
      public static TestSuite suite(){
          TestSuite suite = new TestSuite();
          suite.addTestSuite(ExtendedReflectedClazzTest.class);
          suite.addTestSuite(ExtendedReflectedListPropertyTest.class);
          suite.addTestSuite(ReflectedMappedPropertyTest.class);
          return suite;
      }
  
      protected ClazzLoader getClazzLoader(){
          return Clazz.getClazzLoader(Clazz.DEFAULT_CLAZZLOADER);
      }
      
      public void testGetSuperClazz() {
          assertEquals(
                  ReflectableInstance.class.getSuperclass().getName(), 
                  clazz.getSuperclazz().getName());
      }
  
       
      public void testGetProperties() {
          assertPropertyList(
              "Get properties",
              new String[]{
                  "baseProperty",
                  "booleanProperty",
                  "halfProperty",
                  "integerProperty",
                  "intArray",
                  "string",
                  "mappedBooleans",
                  "mappedInteger",
                  "mappedStrings",
                  "mappedIntegerKeys",
                  "mappedStringKeys",
                  "stringCount",
              },
              clazz.getProperties());
      }
  
      public void testGetPropertiesForSuperclazz() {
          assertPropertyList(
              "Get properties for superclazz",
              new String[]{
                  "baseProperty",
              },
              clazz.getSuperclazz().getProperties());
      }
  
      public void testGetDeclaredProperties() {
          assertPropertyList(
              "Get declared properties",
              new String[]{
                  "booleanProperty",
                  "halfProperty",
                  "integerProperty",
                  "intArray",
                  "string",
                  "mappedBooleans",
                  "mappedInteger",
                  "mappedStrings",
                  "mappedIntegerKeys", 
                  "mappedStringKeys",
                  "stringCount",
              },
              clazz.getDeclaredProperties());
      }
  
      public void testGetDeclaredPropertiesForSuperclazz() {
          assertPropertyList(
              "Get declared properties for superclazz",
              new String[]{
                  "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.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ExtendedReflectedListPropertyTest.java
  
  Index: ExtendedReflectedListPropertyTest.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 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;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ExtendedReflectedListPropertyTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class ExtendedReflectedListPropertyTest extends ReflectedClazzTestSupport
  {
      private ReflectedListProperty intArrayProperty;
      private ReflectedListProperty stringProperty;
      
      /**
       * Constructor for ReflectedPropertyMapTest.
       * @param name Is the test method name
       */
      public ExtendedReflectedListPropertyTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(ExtendedReflectedListPropertyTest.suite());
      }
  
      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.
       */
      public void testRecognitionOfListPropertyWithoutReadWriteMethods(){
          assertNull("Read method",
              stringProperty.getReadMethod());
              
          assertNull("Write method",
              stringProperty.getWriteMethod());
  
          assertMethodSignature("Get method",
              "getString(int)",
              stringProperty.getGetMethod());
  
          assertMethodSignature("Set method",
              "setString(int,java.lang.String)",
              stringProperty.getSetMethod());
              
          assertMethodSignature("Add method",
              "addString(java.lang.String)",
              stringProperty.getAddMethod());
              
          assertMethodSignature("Add(i) method",
              "addString(int,java.lang.String)",
              stringProperty.getAddIndexedMethod());
              
          assertMethodSignature("Remove method",
              "removeString(java.lang.String)",
              stringProperty.getRemoveMethod());            
  
          assertMethodSignature("Size method",
              "getStringCount()",
              stringProperty.getSizeMethod());            
      }
      
      /**
       * Checks the a property is recognized as List even if it
       * does not have parameterized get/set/remove methods.
       */
      public void testRecognitionOfListPropertyWithoutGetSetAddRemoveMethods(){            
          assertMethodSignature("Read method",
              "getIntArray()",
              intArrayProperty.getReadMethod());
              
          assertMethodSignature("Write method",
              "setIntArray([I)",
              intArrayProperty.getWriteMethod());
  
          assertNull("Get method",
              intArrayProperty.getGetMethod());
  
          assertNull("Set method",
              intArrayProperty.getSetMethod());
  
          assertNull("Add method",
              intArrayProperty.getAddMethod());
  
          assertNull("Add(i) method",
              intArrayProperty.getAddIndexedMethod());
  
          assertNull("Remove method",
              intArrayProperty.getRemoveMethod());
  
          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");
          instance.addString("bar");
          instance.addString("baz");
          instance.resetTrace();
          
          List list = (List)stringProperty.get(instance);
          int count = list.size();
          
          assertTrace(
              "getting size with count getter",
              "getStringCount()");
          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 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 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);
      }
  
      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));
      }
  
      /*
       * 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() {
      }
  
      /*
       * Test for ListIterator listIterator(int)
       */
      public void testListIteratorI() {
      }
  
      public void testSubList() {
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/extended/ReflectedMappedPropertyTest.java
  
  Index: ReflectedMappedPropertyTest.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 java.util.*;
  
  import junit.framework.TestSuite;
  
  import org.apache.commons.clazz.Clazz;
  import org.apache.commons.clazz.ClazzLoader;
  import org.apache.commons.clazz.reflect.ReflectedClazzTestSupport;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: ReflectedMappedPropertyTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class ReflectedMappedPropertyTest extends ReflectedClazzTestSupport
  {
      private ReflectedMappedProperty mappedStringsProperty;
      private ReflectedMappedProperty mappedIntegerProperty;
      private ReflectedMappedProperty mappedBooleansProperty;
      
      /**
       * Constructor for ReflectedPropertyMapTest.
       * @param name Is the test method name
       */
      public ReflectedMappedPropertyTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(ReflectedMappedPropertyTest.suite());
      }
  
      public static TestSuite suite(){
          return new TestSuite(ReflectedMappedPropertyTest.class);
      }
      
      public void setUp() throws Exception {
          super.setUp();
          mappedStringsProperty = 
              (ReflectedMappedProperty)clazz.getProperty("mappedStrings");
          mappedIntegerProperty = 
              (ReflectedMappedProperty)clazz.getProperty("mappedInteger");
          mappedBooleansProperty = 
              (ReflectedMappedProperty)clazz.getProperty("mappedBooleans");        
      }
  
      protected ClazzLoader getClazzLoader(){
          return Clazz.getClazzLoader(Clazz.DEFAULT_CLAZZLOADER);
      }
  
      /**
       * Checks the full set of methods recognized for a mapped property.
       */
      public void testRecognitionOfMappedPropertyMethods(){
              
          assertMethodSignature("Read method",
              "getMappedStrings()",
              mappedStringsProperty.getReadMethod());
              
          assertMethodSignature("Write method",
              "setMappedStrings(java.util.Map)",
              mappedStringsProperty.getWriteMethod());
  
          assertMethodSignature("Get method",
              "getMappedString(java.lang.String)",
              mappedStringsProperty.getGetMethod());
  
          assertMethodSignature("Put method",
              "setMappedString(java.lang.String,java.lang.String)",
              mappedStringsProperty.getPutMethod());
  
          assertMethodSignature("Remove method",
              "removeMappedString(java.lang.String)",
              mappedStringsProperty.getRemoveMethod());
              
          assertMethodSignature("KeySet method",
              "getMappedStringKeys()",
              mappedStringsProperty.getKeySetMethod());
      }
      
      /**
       * Checks the set of methods recognized for a mapped property that
       * does not have regular get/set methods.
       */
      public void testRecognitionOfMappedPropertyWithoutReadWriteMethods(){
          assertNull("Read method",
              mappedIntegerProperty.getReadMethod());
              
          assertNull("Write method",
              mappedIntegerProperty.getWriteMethod());
  
          assertMethodSignature("Get method",
              "getMappedInteger(java.lang.Integer)",
              mappedIntegerProperty.getGetMethod());
  
          assertMethodSignature("Put method",
              "setMappedInteger(java.lang.Integer,java.lang.Integer)",
              mappedIntegerProperty.getPutMethod());
  
          assertMethodSignature("Remove method",
              "removeMappedInteger(java.lang.Integer)",
              mappedIntegerProperty.getRemoveMethod());
  
          assertMethodSignature("KeySet method",
              "getMappedIntegerKeys()",
              mappedIntegerProperty.getKeySetMethod());
      }
      
      /**
       * Checks the a property is recognized as Mapped even if it
       * does not have specific get/set/remove methods.
       */
      public void testRecognitionOfMappedPropertyWithoutGetPutRemoveMethods(){
           assertMethodSignature("Read method",
              "getMappedBooleans()",
              mappedBooleansProperty.getReadMethod());
              
          assertMethodSignature("Write method",
              "setMappedBooleans(java.util.Map)",
              mappedBooleansProperty.getWriteMethod());
  
          assertNull("Get method",
              mappedBooleansProperty.getGetMethod());
  
          assertNull("Put method",
              mappedBooleansProperty.getPutMethod());
  
          assertNull("Remove method",
              mappedBooleansProperty.getRemoveMethod());
  
          assertNull("KeySet method",
              mappedBooleansProperty.getKeySetMethod());
      }
      
      public void testGetMappedPropertyValue(){
          Object result = mappedStringsProperty.get(instance);
          assertTraceEmpty(
              "getting mapped property value");
              
          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");
          
          assertTrace("getting value from empty map", "getMappedBooleans()");
          assertNull(value);
      }
  
      public void testGetWithSpecificAccessor() {
          instance.getMappedStrings().put("foo", "bar");
          instance.resetTrace();
  
          Map map = (Map) mappedStringsProperty.get(instance);
          Object value = map.get("foo");
  
          assertTrace(
              "getting value with specific getter",
              "getMappedString(String)");
          assertEquals("bar", value);
      }
  
      public void testGetWithDirectAccessor() {
          instance.setMappedBooleans(new HashMap());
          instance.getMappedBooleans().put("foo", Boolean.TRUE);
          instance.resetTrace();
  
          Map map = (Map) mappedBooleansProperty.get(instance);
          Object value = map.get("foo");
  
          assertTrace(
              "getting value with principal getter",
              "getMappedBooleans()");
          assertEquals(Boolean.TRUE, value);
      }
      
      public void testPutWithSpecificAccessor() {
          instance.getMappedStrings().put("foo", "bar");
          instance.resetTrace();
          
          Map map = (Map) mappedStringsProperty.get(instance);
          Object oldValue = map.put("foo", "baz");
          assertTrace(
              "setting value with specific setter",
              "getMappedString(String)",
              "setMappedString(String,String)");
          assertEquals("baz", instance.getMappedStrings().get("foo"));        
          assertEquals("bar", oldValue);        
      }
  
      public void testPutWithDirectAccessor() {
          instance.setMappedBooleans(new HashMap());
          instance.resetTrace();
          
          Map map = (Map) mappedBooleansProperty.get(instance);
          Object oldValue = map.put("foo", Boolean.TRUE);
          assertTrace(
              "setting value with principal setter",
              "getMappedBooleans()");
          assertEquals(Boolean.TRUE, instance.getMappedBooleans().get("foo"));        
          assertNull(oldValue);        
      }
  
      public void testPutEmptyMap() {
          Map map = (Map) mappedBooleansProperty.get(instance);
          Object oldValue = map.put("foo", Boolean.TRUE);
          assertTrace(
              "setting value with initially empty map",
              "getMappedBooleans()",
              "setMappedBooleans(Map)");
          assertEquals(Boolean.TRUE, instance.getMappedBooleans().get("foo"));        
          assertNull(oldValue);        
      }
  
      public void testIsEmpty() {
      }
  
      public void testKeySetWithSpecificAccessor() {
          instance.getMappedStrings().put("foo", "1");
          instance.getMappedStrings().put("bar", "2");
          instance.resetTrace();
          
          Map map = (Map) mappedStringsProperty.get(instance);
          Set keySet = map.keySet();
          assertTrace(
              "getting key set with specific setter",
              "getMappedStringKeys()");
          
          HashSet expected = new HashSet();
          expected.add("foo");
          expected.add("bar");
          
          assertEquals(expected, keySet);        
      }
  
      public void testKeySetWithPrincipalAccessor() {
          instance.setMappedBooleans(new HashMap());
          instance.getMappedBooleans().put("foo", Boolean.TRUE);
          instance.getMappedBooleans().put("bar", Boolean.FALSE);
          instance.resetTrace();
          
          Map map = (Map) mappedBooleansProperty.get(instance);
          Set keySet = map.keySet();
          assertTrace(
              "getting key set with principal setter",
              "getMappedBooleans()");
          
          HashSet expected = new HashSet();
          expected.add("foo");
          expected.add("bar");
          
          assertEquals(expected, keySet);        
      }
  
      public void testPutAll() {
      }
  
      public void testRemove() {
      }
  
      public void testSize() {
      }
  
      public void testValues() {
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedClazzTest.java
  
  Index: StandardReflectedClazzTest.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 junit.framework.TestSuite;
  
  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;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: StandardReflectedClazzTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class StandardReflectedClazzTest extends ReflectedClazzTestSupport {
  
      /**
       * Constructor for ExtendedReflectedClazzTest.
       * @param name
       */
      public StandardReflectedClazzTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(StandardReflectedClazzTest.suite());
      }
  
      public static TestSuite suite(){
          TestSuite suite = new TestSuite();
          suite.addTestSuite(StandardReflectedClazzTest.class);
          suite.addTestSuite(StandardReflectedListPropertyTest.class);
          return suite;
      }
  
      protected ClazzLoader getClazzLoader(){
          return Clazz.getClazzLoader(Clazz.STANDARD_CLAZZLOADER);
      }
      
      public void testGetSuperClazz() {
          assertEquals(
                  ReflectableInstance.class.getSuperclass().getName(), 
                  clazz.getSuperclazz().getName());
      }
  
       
      public void testGetProperties() {
          assertPropertyList(
              "Get properties",
              new String[]{
                  "baseProperty",
                  "booleanProperty",
                  "halfProperty",
                  "integerProperty",
                  "intArray",
                  "string",
                  "mappedBooleans",
  //                "mappedInteger",  // Not seen because of the Standard Model
                  "mappedStrings",
                  "mappedIntegerKeys",
                  "mappedStringKeys",
                  "stringCount",
              },
              clazz.getProperties());
      }
  
      public void testGetPropertiesForSuperclazz() {
          assertPropertyList(
              "Get properties for superclazz",
              new String[]{
                  "baseProperty",
              },
              clazz.getSuperclazz().getProperties());
      }
  
      public void testGetDeclaredProperties() {
          assertPropertyList(
              "Get declared properties",
              new String[]{
                  "booleanProperty",
                  "halfProperty",
                  "integerProperty",
                  "intArray",
                  "string",
                  "mappedBooleans",
  //                "mappedInteger",  // Not seen because of the Standard Model
                  "mappedStrings",
                  "mappedIntegerKeys", 
                  "mappedStringKeys",
                  "stringCount",
              },
              clazz.getDeclaredProperties());
      }
  
      public void testGetDeclaredPropertiesForSuperclazz() {
          assertPropertyList(
              "Get declared properties for superclazz",
              new String[]{
                  "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.1                  jakarta-commons-sandbox/clazz/src/test/org/apache/commons/clazz/reflect/standard/StandardReflectedListPropertyTest.java
  
  Index: StandardReflectedListPropertyTest.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 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;
  
  /**
   * 
   * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a>
   * @version $Id: StandardReflectedListPropertyTest.java,v 1.1 2002/12/06 01:12:50 dmitri Exp $
   */
  public class StandardReflectedListPropertyTest extends ReflectedClazzTestSupport
  {
      private ReflectedListProperty intArrayProperty;
      private ReflectedListProperty stringProperty;
      
      /**
       * Constructor for ReflectedPropertyMapTest.
       * @param name Is the test method name
       */
      public StandardReflectedListPropertyTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          junit.textui.TestRunner.run(StandardReflectedListPropertyTest.suite());
      }
  
      public static TestSuite suite(){
          return new TestSuite(StandardReflectedListPropertyTest.class);
      }
  
      protected ClazzLoader getClazzLoader(){
          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.
       */
      public void testRecognitionOfListPropertyWithoutReadWriteMethods(){
          assertNull("Read method",
              stringProperty.getReadMethod());
              
          assertNull("Write method",
              stringProperty.getWriteMethod());
  
          assertMethodSignature("Get method",
              "getString(int)",
              stringProperty.getGetMethod());
  
          assertMethodSignature("Set method",
              "setString(int,java.lang.String)",
              stringProperty.getSetMethod());
              
          assertNull("Add method",
              stringProperty.getAddMethod());
              
          assertNull("Add(i) method",
              stringProperty.getAddIndexedMethod());
              
          assertNull("Remove method",
              stringProperty.getRemoveMethod());            
  
          assertNull("Size method",
              stringProperty.getSizeMethod());            
      }
      
      /**
       * Checks the a property is recognized as List even if it
       * does not have parameterized get/set/remove methods.
       */
      public void testRecognitionOfListPropertyWithoutGetSetAddRemoveMethods(){            
          assertMethodSignature("Read method",
              "getIntArray()",
              intArrayProperty.getReadMethod());
              
          assertMethodSignature("Write method",
              "setIntArray([I)",
              intArrayProperty.getWriteMethod());
  
          assertNull("Get method",
              intArrayProperty.getGetMethod());
  
          assertNull("Set method",
              intArrayProperty.getSetMethod());
  
          assertNull("Add method",
              intArrayProperty.getAddMethod());
  
          assertNull("Add(i) method",
              intArrayProperty.getAddIndexedMethod());
  
          assertNull("Remove method",
              intArrayProperty.getRemoveMethod());
  
          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");
          instance.addString("bar");
          instance.addString("baz");
          instance.resetTrace();
          
          List list = (List)stringProperty.get(instance);
          boolean ex = false;
          try {
              list.size();
          }
          catch (Throwable t){
              ex = true;
          }
          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 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 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);
      }
  
      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));
      }
  
      /*
       * 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() {
      }
  
      /*
       * Test for ListIterator listIterator(int)
       */
      public void testListIteratorI() {
      }
  
      public void testSubList() {
      }
  }
  
  
  

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