ReflectUtil: Use collections to grow list and not manual array memory management

Fix usage in ApiDispatcher. Add two kinds of helpers:
- One that gets list of exclude cmd whose fields are not be included
- One that loops till a base class is asssignable from superclass

Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
Rohit Yadav 2013-01-23 13:53:00 -08:00
parent 34f3e1c9a1
commit 7a927e36f0
2 changed files with 34 additions and 18 deletions

View File

@ -27,6 +27,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
@ -190,8 +191,7 @@ public class ApiDispatcher {
}
}
Field[] fields = ReflectUtil.getAllFieldsForClass(cmd.getClass(),
new Class<?>[] {BaseCmd.class});
List<Field> fields = ReflectUtil.getAllFieldsForClass(cmd.getClass(), BaseCmd.class);
for (Field field : fields) {
PlugService plugServiceAnnotation = field.getAnnotation(PlugService.class);

View File

@ -19,7 +19,10 @@ package com.cloud.utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.cloud.utils.exception.CloudRuntimeException;
@ -87,26 +90,39 @@ public class ReflectUtil {
return isAsync;
}
// Returns all fields across the base class for a cmd
public static Field[] getAllFieldsForClass(Class<?> cmdClass,
Class<?>[] searchClasses) {
Field[] fields = cmdClass.getDeclaredFields();
// Returns all fields until a base class for a cmd class
public static List<Field> getAllFieldsForClass(Class<?> cmdClass,
Class<?> baseClass) {
List<Field> fields = new ArrayList<Field>();
Collections.addAll(fields, cmdClass.getDeclaredFields());
Class<?> superClass = cmdClass.getSuperclass();
while (baseClass.isAssignableFrom(superClass)) {
Field[] superClassFields = superClass.getDeclaredFields();
if (superClassFields != null)
Collections.addAll(fields, superClassFields);
superClass = superClass.getSuperclass();
}
return fields;
}
// Returns all unique fields except excludeClasses for a cmd class
public static Set<Field> getAllFieldsForClass(Class<?> cmdClass,
Class<?>[] excludeClasses) {
Set<Field> fields = new HashSet<Field>();
Collections.addAll(fields, cmdClass.getDeclaredFields());
Class<?> superClass = cmdClass.getSuperclass();
while (superClass != null && superClass != Object.class) {
String superName = superClass.getName();
for (Class<?> baseClass: searchClasses) {
if(!baseClass.isAssignableFrom(superClass))
continue;
if (!superName.equals(baseClass.getName())) {
Field[] superClassFields = superClass.getDeclaredFields();
if (superClassFields != null) {
Field[] tmpFields = new Field[fields.length + superClassFields.length];
System.arraycopy(fields, 0, tmpFields, 0, fields.length);
System.arraycopy(superClassFields, 0, tmpFields, fields.length, superClassFields.length);
fields = tmpFields;
}
}
boolean isNameEqualToSuperName = false;
for (Class<?> baseClass: excludeClasses)
if (superName.equals(baseClass.getName()))
isNameEqualToSuperName = true;
if (!isNameEqualToSuperName) {
Field[] superClassFields = superClass.getDeclaredFields();
if (superClassFields != null)
Collections.addAll(fields, superClassFields);
}
superClass = superClass.getSuperclass();
}