30
30
31
31
import java .lang .reflect .*;
32
32
import java .util .ArrayList ;
33
+ import java .util .HashSet ;
34
+ import java .util .Iterator ;
33
35
import java .util .List ;
34
36
import java .util .Set ;
35
37
@@ -56,7 +58,21 @@ private StructureFieldOrderInspector(){}
56
58
*/
57
59
public static void batchCheckStructureGetFieldOrder (final Class <?> classDeclaredInSourceTreeToSearch ,
58
60
final List <String > ignoreConstructorError ) {
59
- final Set <Class <? extends Structure >> classes = StructureFieldOrderInspector .findSubTypesOfStructure (classDeclaredInSourceTreeToSearch );
61
+ batchCheckStructureGetFieldOrder (classDeclaredInSourceTreeToSearch , ignoreConstructorError , false );
62
+ }
63
+
64
+ /**
65
+ * Search for Structure sub types in the source tree of the given class, and validate the getFieldOrder() method,
66
+ * and collects all errors into one exception.
67
+ *
68
+ * @param classDeclaredInSourceTreeToSearch a class who's source tree will be searched for Structure sub types.
69
+ * @param ignoreConstructorError list of classname prefixes for which to ignore construction errors.
70
+ * @param onlyInnerClasses limit scan to inner classes of the supplied class
71
+ */
72
+ public static void batchCheckStructureGetFieldOrder (final Class <?> classDeclaredInSourceTreeToSearch ,
73
+ final List <String > ignoreConstructorError ,
74
+ final boolean onlyInnerClasses ) {
75
+ final Set <Class <? extends Structure >> classes = StructureFieldOrderInspector .findSubTypesOfStructure (classDeclaredInSourceTreeToSearch , onlyInnerClasses );
60
76
61
77
final List <Throwable > problems = new ArrayList <Throwable >();
62
78
@@ -96,7 +112,7 @@ public static void checkStructureGetFieldOrder(final Class<?> classDeclaredInSou
96
112
/**
97
113
* Find all classes that extend {@link Structure}.
98
114
*/
99
- public static Set <Class <? extends Structure >> findSubTypesOfStructure (final Class <?> classDeclaredInSourceTreeToSearch ) {
115
+ public static Set <Class <? extends Structure >> findSubTypesOfStructure (final Class <?> classDeclaredInSourceTreeToSearch , boolean onlyInnerClasses ) {
100
116
101
117
// use: http://code.google.com/p/reflections/
102
118
@@ -105,9 +121,24 @@ public static Set<Class<? extends Structure>> findSubTypesOfStructure(final Clas
105
121
.setUrls (ClasspathHelper .forClass (classDeclaredInSourceTreeToSearch ))
106
122
);
107
123
108
- return reflections .getSubTypesOf (Structure .class );
124
+ Set <Class <? extends Structure >> types = new HashSet <Class <? extends Structure >>(reflections .getSubTypesOf (Structure .class ));
125
+ if (onlyInnerClasses ) {
126
+ Iterator <Class <? extends Structure >> it = types .iterator ();
127
+ while (it .hasNext ()) {
128
+ if (! (it .next ().getEnclosingClass () == classDeclaredInSourceTreeToSearch )) {
129
+ it .remove ();
130
+ }
131
+ }
132
+ }
133
+ return types ;
109
134
}
110
135
136
+ /**
137
+ * Find all classes that extend {@link Structure}.
138
+ */
139
+ public static Set <Class <? extends Structure >> findSubTypesOfStructure (final Class <?> classDeclaredInSourceTreeToSearch ) {
140
+ return findSubTypesOfStructure (classDeclaredInSourceTreeToSearch , false );
141
+ }
111
142
112
143
public static void checkMethodGetFieldOrder (final Class <? extends Structure > structureSubType ,
113
144
final List <String > ignoreConstructorError ) {
@@ -119,9 +150,6 @@ public static void checkMethodGetFieldOrder(final Class<? extends Structure> str
119
150
return ;
120
151
}
121
152
122
- final Method methodGetFieldOrder = getMethodGetFieldOrder (structureSubType );
123
-
124
-
125
153
if (Modifier .isAbstract (structureSubType .getModifiers ())) {
126
154
// do not try to construct abstract Structure sub types
127
155
return ;
@@ -161,58 +189,27 @@ public static void checkMethodGetFieldOrder(final Class<? extends Structure> str
161
189
throw new RuntimeException ("Could not instantiate Structure sub type: " + structureSubType .getName (), e );
162
190
}
163
191
164
- if (!methodGetFieldOrder .isAccessible ()) {
165
- methodGetFieldOrder .setAccessible (true );
166
- }
167
- final List <?> methodCallFieldList ;
168
- try {
169
- methodCallFieldList = (List <?>) methodGetFieldOrder .invoke (structure );
170
- } catch (IllegalAccessException e ) {
171
- throw new RuntimeException ("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType .getName (), e );
172
- } catch (InvocationTargetException e ) {
173
- throw new RuntimeException ("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType .getName (), e );
174
- }
192
+ final List <String > methodCallFieldOrder = structure .getFieldOrder ();
175
193
176
- final Field [] actualFields = structureSubType . getFields (); // include fields from super classes
177
- final List <String > actualFieldNames = new ArrayList <String >(actualFields .length );
194
+ final List < Field > actualFields = structure . getFieldList ();
195
+ final List <String > actualFieldNames = new ArrayList <String >(actualFields .size () );
178
196
for (final Field field : actualFields ) {
179
197
// ignore static fields
180
198
if (!Modifier .isStatic (field .getModifiers ())) {
181
199
final String actualFieldName = field .getName ();
182
- if (!methodCallFieldList .contains (actualFieldName )) {
183
- throw new IllegalArgumentException (structureSubType .getName () + ".getFieldOrder() [" + methodCallFieldList
200
+ if (!methodCallFieldOrder .contains (actualFieldName )) {
201
+ throw new IllegalArgumentException (structureSubType .getName () + ".getFieldOrder() [" + methodCallFieldOrder
184
202
+ "] does not include declared field: " + actualFieldName );
185
203
}
186
204
actualFieldNames .add (actualFieldName );
187
205
}
188
206
}
189
207
190
- for (final Object methodCallField : methodCallFieldList ) {
208
+ for (final String methodCallField : methodCallFieldOrder ) {
191
209
if (!actualFieldNames .contains (methodCallField )) {
192
- throw new IllegalArgumentException (structureSubType .getName () + ".getFieldOrder() [" + methodCallFieldList
210
+ throw new IllegalArgumentException (structureSubType .getName () + ".getFieldOrder() [" + methodCallFieldOrder
193
211
+ "] includes undeclared field: " + methodCallField );
194
212
}
195
213
}
196
214
}
197
-
198
- /**
199
- * Find the getFieldOrder() method in the given class, or any of it's parents.
200
- * @param structureSubType a structure sub type
201
- * @return the getFieldOrder() method found in the given class, or any of it's parents.
202
- */
203
- private static Method getMethodGetFieldOrder (Class <? extends Structure > structureSubType ) {
204
- final Method methodGetFieldOrder ;
205
- try {
206
- methodGetFieldOrder = structureSubType .getDeclaredMethod ("getFieldOrder" , new Class []{});
207
- } catch (NoSuchMethodException e ) {
208
- if (structureSubType .getSuperclass () != null ) {
209
- // look for method in parent
210
- return getMethodGetFieldOrder ((Class <? extends Structure >) structureSubType .getSuperclass ());
211
- }
212
- throw new IllegalArgumentException ("The Structure sub type: " + structureSubType .getName ()
213
- + " must define the method: getFieldOrder()."
214
- + " See the javadoc for Structure.getFieldOrder() for details." , e );
215
- }
216
- return methodGetFieldOrder ;
217
- }
218
215
}
0 commit comments