001: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
002: // Released under the terms of the GNU General Public License version 2 or later.
003: package fitnesse;
004:
005: import fit.*;
006: import java.lang.reflect.*;
007: import java.util.*;
008:
009: // This command-line tool takes in a fit.Fixture class name and prints out a FitNesse table template.
010: public class FixtureTemplateCreator {
011: public static void main(String[] args) throws Exception {
012: if (args.length < 1)
013: return;
014:
015: new FixtureTemplateCreator().run(args[0]);
016: }
017:
018: public void run(String fixtureName) throws Exception {
019: String defaultTableTemplate = "!|" + fixtureName + "|";
020:
021: try {
022: Class fixtureClass = ClassLoader.getSystemClassLoader()
023: .loadClass(fixtureName);
024: Object fixtureInstance = fixtureClass.newInstance();
025:
026: if (!Fixture.class.isInstance(fixtureInstance))
027: throw new InstantiationException();
028: else if (RowFixture.class.isInstance(fixtureInstance))
029: System.out.println(makeRowFixtureTemplate(
030: defaultTableTemplate, fixtureClass));
031: else if (ColumnFixture.class.isInstance(fixtureInstance))
032: System.out.println(makeColumnFixtureTemplate(
033: defaultTableTemplate, fixtureClass));
034: else
035: System.out.println(defaultTableTemplate);
036: } catch (ClassNotFoundException e) {
037: System.out.println("# Could not find " + fixtureName
038: + " in the classpath. #");
039: } catch (InstantiationException ie) {
040: System.out.println("# " + fixtureName
041: + " is not a valid fixture! #");
042: }
043: }
044:
045: private StringBuffer makeRowFixtureTemplate(
046: String defaultTableTemplate, Class fixtureClass) {
047: Class targetClass = getTargetClassFromRowFixture(fixtureClass);
048: return makeFixtureTemplate(defaultTableTemplate, targetClass,
049: Object.class);
050: }
051:
052: private StringBuffer makeColumnFixtureTemplate(
053: String defaultTableTemplate, Class fixtureClass) {
054: return makeFixtureTemplate(defaultTableTemplate, fixtureClass,
055: ColumnFixture.class);
056: }
057:
058: private StringBuffer makeFixtureTemplate(
059: String defaultTableTemplate, Class fixtureClass,
060: Class stopClass) {
061: StringBuffer tableTemplate = new StringBuffer(
062: defaultTableTemplate + "\n");
063: List publicFieldsFound = new ArrayList();
064: List publicMethodsFound = new ArrayList();
065: getPublicMembers(fixtureClass, publicFieldsFound,
066: publicMethodsFound, stopClass);
067: addCellsForColumnFixture(tableTemplate, publicFieldsFound,
068: publicMethodsFound);
069:
070: return tableTemplate;
071: }
072:
073: private void getPublicMembers(Class aClass, List publicFields,
074: List publicMethods, Class stopClass) {
075: Class currentClass = aClass;
076: while (currentClass != stopClass) {
077: Field[] fields = currentClass.getDeclaredFields();
078: for (int i = 0; i < fields.length; i++) {
079: Field field = fields[i];
080: if (Modifier.isPublic(field.getModifiers()))
081: publicFields.add(field);
082: }
083:
084: Method[] methods = currentClass.getDeclaredMethods();
085: for (int i = 0; i < methods.length; i++) {
086: Method method = methods[i];
087: String methodName = method.getName();
088: if ("reset".equals(methodName)
089: || "execute".equals(methodName))
090: continue;
091: if (Modifier.isAbstract(method.getModifiers()))
092: continue;
093: if (Modifier.isPublic(method.getModifiers()))
094: publicMethods.add(method);
095: }
096: currentClass = currentClass.getSuperclass();
097: }
098: }
099:
100: private void addCellsForColumnFixture(StringBuffer tableTemplate,
101: List publicFields, List publicMethods) {
102: StringBuffer headerRow = new StringBuffer("|");
103: StringBuffer valueRow = new StringBuffer("|");
104:
105: addCellsForFieldNamesAndTypes(publicFields, headerRow, valueRow);
106: addCellsForMethodNamesAndReturnTypes(publicMethods, headerRow,
107: valueRow);
108:
109: tableTemplate.append(headerRow).append("\n").append(valueRow)
110: .append("\n");
111: }
112:
113: private void addCellsForFieldNamesAndTypes(List publicFields,
114: StringBuffer headerRow, StringBuffer valueRow) {
115: for (Iterator f = publicFields.iterator(); f.hasNext();) {
116: Field field = (Field) f.next();
117: String name = field.getName();
118: String type = getShortClassName(field.getType().getName());
119:
120: String pad = createSpaces(Math.abs(name.length()
121: - type.length()));
122: if (name.length() < type.length())
123: name += pad;
124: else if (type.length() < name.length())
125: type += pad;
126:
127: headerRow.append(name).append("|");
128: valueRow.append(type).append("|");
129: }
130: }
131:
132: private void addCellsForMethodNamesAndReturnTypes(
133: List publicMethods, StringBuffer headerRow,
134: StringBuffer valueRow) {
135: for (Iterator m = publicMethods.iterator(); m.hasNext();) {
136: Method method = (Method) m.next();
137: String name = method.getName() + "()";
138: String type = getShortClassName(method.getReturnType()
139: .getName());
140: type = fixClassName(type);
141:
142: String pad = createSpaces(Math.abs(name.length()
143: - type.length()));
144: if (name.length() < type.length())
145: name += pad;
146: else if (type.length() < name.length())
147: type += pad;
148:
149: headerRow.append(name).append("|");
150: valueRow.append(type).append("|");
151: }
152: }
153:
154: private String createSpaces(int numSpaces) {
155: StringBuffer spaces = new StringBuffer("");
156: for (int j = 0; j < numSpaces; j++)
157: spaces.append(" ");
158: return spaces.toString();
159: }
160:
161: protected String getShortClassName(String fullyQualifiedClassName) {
162: String[] parts = fullyQualifiedClassName.split("\\.");
163: return parts[parts.length - 1];
164: }
165:
166: protected String fixClassName(String className) {
167: if (className.endsWith(";"))
168: className = className.substring(0, className.length() - 1)
169: + "[]";
170: return className;
171: }
172:
173: protected Class getTargetClassFromRowFixture(Class rowFixtureClass) {
174: Class targetClass = null;
175:
176: try {
177: Method method_getTargetClass = rowFixtureClass
178: .getMethod("getTargetClass");
179: targetClass = (Class) method_getTargetClass
180: .invoke(rowFixtureClass.newInstance());
181: } catch (NoSuchMethodException nsme) {
182: return null;
183: } catch (Exception e) {
184: e.printStackTrace();
185: return null;
186: }
187: return targetClass;
188: }
189: }
|