001package edu.pdx.cs410J.examples;
002
003import java.io.*;
004import java.lang.reflect.*;
005
006/**
007 * This class demonstrates Java's reflection mechanism by loading a
008 * class and then printing out information about its fields and
009 * methods.
010 *
011 * @author David Whitlock
012 */
013public class Reflect {
014
015  private static PrintWriter out = new PrintWriter(System.out, true);
016  private static PrintWriter err = new PrintWriter(System.err, true);
017
018  /**
019   * Displays usage information about this program.
020   */
021  private static void usage() {
022    err.println("usage: java Reflect className");
023    System.exit(1);
024  }
025
026  /**
027   * Returns a <code>String</code> representing a given set of access
028   * modifiers.
029   */
030  private static String modifiersString(int modifiers) {
031    StringBuffer sb = new StringBuffer();
032
033    if (Modifier.isPublic(modifiers)) {
034      sb.append("public ");
035    } 
036
037    if (Modifier.isProtected(modifiers)) {
038      sb.append("protected ");
039    }
040
041    if (Modifier.isPrivate(modifiers)) {
042      sb.append("private ");
043    }
044
045    if (Modifier.isStatic(modifiers)) {
046      sb.append("static ");
047    }
048
049    if (Modifier.isFinal(modifiers)) {
050      sb.append("final ");
051    }
052
053    if (Modifier.isNative(modifiers)) {
054      sb.append("native ");
055    }
056
057    if (Modifier.isAbstract(modifiers)) {
058      sb.append("abstract ");
059    }
060
061    if (Modifier.isSynchronized(modifiers)) {
062      sb.append("synchronized ");
063    }
064
065    if (Modifier.isVolatile(modifiers)) {
066      sb.append("volatile ");
067    }
068
069    return sb.toString();
070  }
071
072  /**
073   * Returns a string representation of a class name.  Takes array
074   * classes into account.
075   */
076  private static String getTypeName(Class type) {
077    String typeName;
078    if (type.isArray()) {
079      typeName = type.getComponentType().getName() + "[]";
080
081    } else {
082      typeName = type.getName();
083    }
084
085    return typeName;
086  }
087
088  /**
089   * Reads a class name from the command line, loads it and prints out
090   * information about it.
091   */
092  public static void main(String[] args) {
093    if (args.length < 1) {
094      err.println("** Missing class name");
095      usage();
096    }
097
098    Class c = null;
099
100    try {
101      c = Class.forName(args[0]);
102
103    } catch (ClassNotFoundException ex) {
104      err.println("** Could not find class " + args[0]);
105    }
106
107    // Print name of class and its superclass
108    out.print(modifiersString(c.getModifiers()));
109    out.println("class " + getTypeName(c));
110    if (c.getSuperclass() != null) {
111      out.print("    extends " + getTypeName(c.getSuperclass()));
112    }
113    out.println("");
114
115    // Print out any interfaces class implements
116    Class[] interfaces = c.getInterfaces();
117    if (interfaces.length > 0) {
118      out.print("    implements ");
119      for (int i = 0; i < interfaces.length; i++) {
120        out.print(interfaces[i].getName());
121
122        if(i < interfaces.length - 1) {
123          out.print(", ");
124        }
125      }
126      out.println("");
127    }
128
129    out.println("{");
130
131    // Print descriptions of fields (not including inherited fields)
132    Field[] fields = c.getDeclaredFields();
133    for (int i = 0; i < fields.length; i++) {
134      Field field = fields[i];
135
136      out.print("  " + modifiersString(field.getModifiers()));
137
138      String typeName = getTypeName(field.getType());
139      
140      out.println(typeName + " " + field.getName() + ";");
141    }
142    
143    out.println("");
144
145    // Print description of constructors
146    Constructor[] constructors = c.getDeclaredConstructors();
147    for (int i = 0; i < constructors.length; i++) {
148      Constructor con = constructors[i];
149
150      out.print("  " + modifiersString(con.getModifiers()));
151      out.print(con.getName() + "(");
152
153      Class[] params = con.getParameterTypes();
154      for (int j = 0; j < params.length; j++) {
155        Class param = params[j];
156        out.print(getTypeName(param));
157
158        if(j < params.length - 1) {
159          out.print(", ");
160        }
161      }
162
163      out.print(")");
164
165      Class[] exceptions = con.getExceptionTypes();
166      if (exceptions.length > 0) {
167        out.print("\n    throws ");
168        for(int j = 0; j < exceptions.length; j++) {
169          Class ex = exceptions[j];
170          out.print(getTypeName(ex));
171          if (j < exceptions.length - 1) {
172            out.print(", ");
173          }
174        }
175      }
176      out.println(";");
177    }
178
179    out.println("");
180
181    // Print description of methods
182    Method[] methods = c.getDeclaredMethods();
183    for (int i = 0; i < methods.length; i++) {
184      Method method = methods[i];
185
186      out.print("  " + modifiersString(method.getModifiers()));
187      out.print(getTypeName(method.getReturnType()) + " ");
188      out.print(method.getName() + "(");
189
190      Class[] params = method.getParameterTypes();
191      for (int j = 0; j < params.length; j++) {
192        Class param = params[j];
193        out.print(getTypeName(param));
194
195        if (j < params.length - 1) {
196          out.print(", ");
197        }
198      }
199
200      out.print(")");
201
202      Class[] exceptions = method.getExceptionTypes();
203      if (exceptions.length > 0) {
204        out.print("\n    throws ");
205        for (int j = 0; j < exceptions.length; j++) {
206          Class ex = exceptions[j];
207          out.print(getTypeName(ex));
208          if (j < exceptions.length - 1) {
209            out.print(", ");
210          }
211        }
212      }
213      out.println(";");
214    }
215
216    // All done
217    out.println("}");
218  }
219
220}