ix.util.reflect
Class ClassFinder

java.lang.Object
  extended by ix.util.reflect.ClassFinder
Direct Known Subclasses:
DashSyntaxClassFinder

public class ClassFinder
extends java.lang.Object

Converts between class names (Strings) and classes. Note that a single ClassFinder maps in both directions to make it easier to create mappings that are consistent.

Explicit mappings and "imports" may be specified; otherwise fully qualified names must be used.

A ClassFinder may use a different naming convention than Java provided that there are String-to-String mappings in both directions between any special "external" names and ordinary Java names.

This class does not yet handle array classes.


Nested Class Summary
protected static class ClassFinder.Import
          Internal class that performs the name-to-class mapping that corresponds to a single import specification.
 
Field Summary
protected  java.util.Map classToName
           
protected  java.util.Map classToNameCache
           
protected  java.util.List imports
           
protected  java.util.Map nameToClass
           
protected  java.util.Map nameToClassCache
           
 
Constructor Summary
ClassFinder()
           
ClassFinder(ClassFinder base)
           
 
Method Summary
 void addImport(java.lang.String name)
          Records an import that allows a class name or names to be used without package-qualification.
protected  void addInitialImports()
          Adds the initial set of imports.
protected  void addInitialNames()
          Adds the initial set of name mappings.
 void addName(java.lang.String name, java.lang.Class c)
          Adds an explicit mapping in both directions between a name and a class.
protected  void cacheBothWays(java.lang.String name, java.lang.Class c)
          Caches the mapping from name to class and from class to name.
 java.lang.Class classForName(java.lang.String name)
          Returns the class that corresponds to the name, as determined by any imports or explicit mappings.
protected  boolean classHasShortName(java.lang.Class c, java.lang.String shortExternal)
           
protected static void do_main(ClassFinder cf)
          A test loop that asks the user for a name and prints the corresponding class (or else null) as determined by the ClassFinder.
 java.lang.String externalFieldName(java.lang.String javaName)
          Returns the external name that corresponds to a Java field name.
 java.lang.String externalName(java.lang.String javaName)
          Returns the external name that corresponds to a Java class name.
protected  java.lang.Class findImportClass(java.lang.String name)
          Tries to find a class by asking each import in turn.
 java.lang.String javaFieldName(java.lang.String externalName)
          Returns the Java name that corresponds to an external field name.
 java.lang.String javaName(java.lang.String externalName)
          Returns the Java name that corresponds to an external class name.
static void main(java.lang.String[] argv)
          Simple main program for testing.
 java.lang.String nameForClass(java.lang.Class c)
          Returns the best name that this ClassFinder would map to the specified class, where a plain class name counts as better than a package-qualified one.
 void preLoad(java.util.List expectedClasses)
           
static java.lang.Class tryClassForName(java.lang.String name)
          Like Class.forName(String) but returns null if the class cannot be found.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

imports

protected java.util.List imports

nameToClass

protected java.util.Map nameToClass

classToName

protected java.util.Map classToName

nameToClassCache

protected java.util.Map nameToClassCache

classToNameCache

protected java.util.Map classToNameCache
Constructor Detail

ClassFinder

public ClassFinder()

ClassFinder

public ClassFinder(ClassFinder base)
Method Detail

addInitialNames

protected void addInitialNames()
Adds the initial set of name mappings.


addInitialImports

protected void addInitialImports()
Adds the initial set of imports. These are:
   java.lang.*
   java.util.*
 


addImport

public void addImport(java.lang.String name)
Records an import that allows a class name or names to be used without package-qualification. The import is specified as either a fully qualified Java class name or a package name suffixed by ".*", as in the Java import statement.


addName

public void addName(java.lang.String name,
                    java.lang.Class c)
Adds an explicit mapping in both directions between a name and a class. This takes precedence over all other ways of determining those relationships.

Parameters:
name - an external name for a class.
c - a class

cacheBothWays

protected void cacheBothWays(java.lang.String name,
                             java.lang.Class c)
Caches the mapping from name to class and from class to name. This method must be used with care, because it's possible for more than one name to map to the same class: for example, a fully-qualified name, and a short, packageless name. There may even be more than one short name that works. A ClassFinder that has lower-case (e.g. "dash-syntax") external names may convert to Java names by capitalizing some letters, but leaving any existing capitals in place. It might thus accept both "Issue" and "issue".


preLoad

public void preLoad(java.util.List expectedClasses)

javaName

public java.lang.String javaName(java.lang.String externalName)
Returns the Java name that corresponds to an external class name. The method in the ClassFinder class returns the name unchanged, but it may be overridden in subclasses.


javaFieldName

public java.lang.String javaFieldName(java.lang.String externalName)
Returns the Java name that corresponds to an external field name. The method in the ClassFinder class just calls the method javaName(String), but it may be overridden in subclasses in which the conversion for class names cannot be used for fields.


externalName

public java.lang.String externalName(java.lang.String javaName)
Returns the external name that corresponds to a Java class name. The method in the ClassFinder class returns the name unchanged, but it may be overridden in subclasses.


externalFieldName

public java.lang.String externalFieldName(java.lang.String javaName)
Returns the external name that corresponds to a Java field name. The method in this class calls externalName(String), but it may be overridden in subclasses in which the conversion for class names cannot be used for fields.


classForName

public java.lang.Class classForName(java.lang.String name)
Returns the class that corresponds to the name, as determined by any imports or explicit mappings. Fully qualified names may also be used. The mapping from name to class is cached, but not the mapping the other way, because more than one name might map to the same class. (See cacheBothWays(String, Class) for an explanation.)

Parameters:
name - an external name for a class.
Returns:
a Class or null.

findImportClass

protected java.lang.Class findImportClass(java.lang.String name)
Tries to find a class by asking each import in turn.

Parameters:
name - a Java name for a class.
Returns:
a class or null.
Throws:
java.lang.RuntimeException - if more than one import can find a class.

tryClassForName

public static java.lang.Class tryClassForName(java.lang.String name)
Like Class.forName(String) but returns null if the class cannot be found.

Parameters:
name - a Java name for a class.
Returns:
a class or null.

nameForClass

public java.lang.String nameForClass(java.lang.Class c)
Returns the best name that this ClassFinder would map to the specified class, where a plain class name counts as better than a package-qualified one. Since the result is the best name and hence we'd return it again if called again, we cache it as the name for this class; and since we know it's a name for the class, we can cache in the name-to-class direction as well.

Returns:
an external name for the class.
See Also:
cacheBothWays(String, Class)

classHasShortName

protected boolean classHasShortName(java.lang.Class c,
                                    java.lang.String shortExternal)

main

public static void main(java.lang.String[] argv)
Simple main program for testing. This method calls do_main(ClassFinder) with an instance of this class as the finder.


do_main

protected static void do_main(ClassFinder cf)
A test loop that asks the user for a name and prints the corresponding class (or else null) as determined by the ClassFinder. When the result is not null, it also prints the ClassFinder's "best" name for that class.