package com.puppycrawl.tools.checkstyle;

import java.util.Map;

import com.puppycrawl.tools.checkstyle.api.CheckstyleException;

/**
 * A factory for creating objects by mapping a name to a class name.
 * <code>MappedObjectFactory</code> has no public constructor..
 * @author Rick Giles
 * @version 4-Dec-2002
 */
public class PackageObjectFactory
{
    /**
     * Creates a new <code>MappedObjectFactory</code> instance.
     */    
    private PackageObjectFactory()
    {
    }

    /**
     * Creates a new instance of a class. Determines the name of the
     * class to instantiate by mapping a given name to a class name,
     *  using a provided <code>Map</code>.
     * @param aMap the mapping from aName to a class name.
     * @param aLoader the <code>ClassLoader</code> to create the instance with.
     * @param aName the name to map to the class name.
     * @return the <code>Object</code> created by aLoader after mapping
     * aName to a class name.
     * @throws CheckstyleException if an error occurs.
     */            
    private Object doMakeObject(String[] aPackages, ClassLoader aLoader,
            String aName)
        throws CheckstyleException
    {
        Object retVal = null;
        //try aName first
        try {
            return createObject(aLoader, aName);
        }
        catch (CheckstyleException ex) {
            retVal = null;
        }
        //now try packages
        for (int i = 0; i < aPackages.length; i++) {
            final String className = aPackages[i] + aName;
            try {
                return createObject(aLoader, className);
            }
            catch (CheckstyleException ex) {
                retVal = null;
            }
        }   
        throw new CheckstyleException(
            "Unable to instantiate " + aName);
    }

    /**
     * Creates a new instance of a named class.
     * @param aLoader the <code>ClassLoader</code> to create the instance with.
     * @param aClassName the name of the class to instantiate.
     * @return the <code>Object</code> created by aLoader.
     * @throws CheckstyleException if an error occurs.
     */
    private Object createObject(ClassLoader aLoader, String aClassName)
        throws CheckstyleException
    {
        try {
            final Class clazz = Class.forName(aClassName, true, aLoader);
            return clazz.newInstance();
        }
        catch (ClassNotFoundException e) {
            throw new CheckstyleException(
                "Unable to find class for " + aClassName);
        }
        catch (InstantiationException e) {
            throw new CheckstyleException(
                "Unable to instantiate " + aClassName);
        }
        catch (IllegalAccessException e) {
            throw new CheckstyleException(
                "Unable to instantiate " + aClassName);
        }
    } 
    
    /**
     * Creates a new instance of a class. Determines the name of the
     * class to instantiate by mapping a given name to a class name,
     *  using a provided <code>Map</code>.
     * @param aMap the mapping from aName to a class name.
     * @param aLoader the <code>ClassLoader</code> to create the instance with.
     * @param aName the name that will be mapped to the name of a class.
     * @return the <code>Object</code> created by aLoader after mapping
     * aName to a class name.
     * @throws CheckstyleException if an error occurs.
     */
    public static Object makeObject(String[] aPackages, ClassLoader aLoader,
        String aClassName)
        throws CheckstyleException
    {
        final PackageObjectFactory factory = new PackageObjectFactory();
        return factory.doMakeObject(aPackages, aLoader, aClassName);
    }
}

@@ -39,31 +39,8 @@
 e;%0A%0A
-import java.util.Map;%0A%0A
 impo
@@ -142,41 +142,36 @@
 cts 
-by mapping a name to a class
+from package names and
  name
+s
 .%0A *
@@ -173,30 +173,31 @@
 s.%0A * %3Ccode%3E
-Mapped
+Package
 ObjectFactor
@@ -231,17 +231,16 @@
 tructor.
-.
 %0A * @aut
@@ -356,14 +356,15 @@
 ode%3E
-Mapped
+Package
 Obje
@@ -494,36 +494,46 @@
 e of a class
-. Determines
+ from a given name. If
  the name of
@@ -534,77 +534,119 @@
 ame 
-of the
+is
 %0A     *
+ a
  class
- to instantiate by mapping a given name to
+name, creates an instance of the named class. Otherwise, creates%0A     * an instance of
  a class
  nam
@@ -645,115 +645,156 @@
 lass
- 
 name
-,%0A     *  using a provided %3Ccode%3EMap%3C/code%3E.%0A     * @param aMap the mapping from aName to a class
+ obtained by concatenating the given%0A     * to a package name from a given list of package names. %0A     * @param aPackages list of package
  name
+s
 .%0A  
@@ -904,32 +904,18 @@
 ame 
-to map to the
+of a
  class
- name
 .%0A  
@@ -973,51 +973,8 @@
 ader
- after mapping%0A     * aName to a class name
 .%0A  
@@ -2912,20 +2912,30 @@
 lass
-. Determines
+ from a given name. If
  the
@@ -2944,77 +2944,119 @@
 ame 
-of the
+is
 %0A     *
+ a
  class
- to instantiate by mapping a given name to
+name, creates an instance of the named class. Otherwise, creates%0A     * an instance of
  a class
  nam
@@ -3055,115 +3055,156 @@
 lass
- 
 name
-,%0A     *  using a provided %3Ccode%3EMap%3C/code%3E.%0A     * @param aMap the mapping from aName to a class
+ obtained by concatenating the given%0A     * to a package name from a given list of package names. %0A     * @param aPackages list of package
  name
+s
 .%0A  
@@ -3314,40 +3314,8 @@
 ame 
-that will be mapped to the name 
 of a
@@ -3383,51 +3383,8 @@
 ader
- after mapping%0A     * aName to a class name
 .%0A  
@@ -3439,24 +3439,36 @@
 urs.%0A     */
+            
 %0A    public 
@@ -3541,37 +3541,32 @@
         String a
-Class
 Name)%0A        th
@@ -3726,21 +3726,16 @@
 oader, a
-Class
 Name);%0A 

Correct Javadoc