Skip to content

Commit

Permalink
deeper method searching
Browse files Browse the repository at this point in the history
  • Loading branch information
n9Mtq4 committed Jun 24, 2015
1 parent a1bb859 commit 1cb02ab
Showing 1 changed file with 88 additions and 5 deletions.
93 changes: 88 additions & 5 deletions src/com/n9mtq4/reflection/ReflectionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2282,6 +2282,67 @@ private static void checkDirectory(File directory, String pckgname, ArrayList<Cl
}
}

/**
* Produce a List<String> which contains every combination which can be
* made by taking one String from each inner String array within the
* provided two-dimensional String array.
* @param twoDimArray a two-dimensional String array which contains
* String arrays of variable length.
* @return a List which contains every String which can be formed by taking
* one String from each String array within the specified two-dimensional
* array.<br>
* Slightly modified code from
* Bobulous @ https://stackoverflow.com/questions/15868914/how-to-get-2d-array-possible-combinations/15869610
*/
private static List<List<Class>> combinations(ArrayList<ArrayList<Class>> twoDimArray) {
// TODO: find a better algorithm
// keep track of the size of each inner String array
int sizeArray[] = new int[twoDimArray.size()];

// keep track of the index of each inner String array which will be used
// to make the next combination
int counterArray[] = new int[twoDimArray.size()];

// Discover the size of each inner array and populate sizeArray.
// Also calculate the total number of combinations possible using the
// inner String array sizes.
int totalCombinationCount = 1;
for(int i = 0; i < twoDimArray.size(); ++i) {
sizeArray[i] = twoDimArray.get(i).size();
totalCombinationCount *= twoDimArray.get(i).size();
}

// Store the combinations in a List of String objects
List<List<Class>> combinationList = new ArrayList<List<Class>>(totalCombinationCount);

for (int countdown = totalCombinationCount; countdown > 0; --countdown) {
// Run through the inner arrays, grabbing the member from the index
// specified by the counterArray for each inner array, and build a
// combination string.
ArrayList<Class> obs = new ArrayList<Class>();
for(int i = 0; i < twoDimArray.size(); ++i) {
obs.add(twoDimArray.get(i).get(counterArray[i]));
}
combinationList.add(obs); // add new combination to list

// Now we need to increment the counterArray so that the next
// combination is taken on the next iteration of this loop.
for(int incIndex = twoDimArray.size() - 1; incIndex >= 0; --incIndex) {
if(counterArray[incIndex] + 1 < sizeArray[incIndex]) {
++counterArray[incIndex];
// None of the indices of higher significance need to be
// incremented, so jump out of this for loop at this point.
break;
}
// The index at this position is at its max value, so zero it
// and continue this loop to increment the index which is more
// significant than this one.
counterArray[incIndex] = 0;
}
}
return combinationList;
}

// end stuff not written by me

/**
Expand Down Expand Up @@ -2400,12 +2461,12 @@ public static Field getAllDeclaredField(String name, Class clazz) throws NoSuchF
}

public static Method[] getAllDeclaredMethods(Class clazz) {
ArrayList<Field> methods = new ArrayList<Field>();
ArrayList<Method> methods = new ArrayList<Method>();

// loop through all super classes until getSuperClass == null
Class currentClass = clazz;
while (currentClass != null) {
methods.addAll(Arrays.asList(currentClass.getDeclaredFields()));
methods.addAll(Arrays.asList(currentClass.getDeclaredMethods()));
currentClass = currentClass.getSuperclass();
}

Expand All @@ -2430,18 +2491,40 @@ public static Method getAllDeclaredMethod(String name, Class[] params, Class cla
}

// if there is only one possible method
if (possibleMethods.size() == 1 && possibleMethods.get(0).getParameterTypes().length == params.length) {
if (possibleMethods.size() == 1 && possibleMethods.get(0).getParameterCount() == params.length) {
return possibleMethods.get(0);
}

// if there are more than one, try to isolate by number of params
ArrayList<Method> nPossibleMethods = new ArrayList<Method>();
for (Method method : possibleMethods) {
if (method.getParameterTypes().length != params.length) possibleMethods.remove(method);
if (method.getParameterCount() == params.length) nPossibleMethods.add(method);
}
possibleMethods = nPossibleMethods;
if (possibleMethods.size() == 1) return possibleMethods.get(0);

// if there are still more than one, try to narrow it down by superclasses
// TODO: search superclasses of params to find a viable method
// get all the superclasses for the list of params
// this following code is TERRIBLE, but it (sometimes) works
ArrayList<ArrayList<Class>> superClasses = new ArrayList<ArrayList<Class>>();
ArrayList<Class> classes = new ArrayList<Class>();
for (Class c : params) {
Class currentClass1 = c;
while (currentClass1 != null) {
classes.add(currentClass1);
currentClass1 = currentClass1.getSuperclass();
}
superClasses.add(classes);
}

List<List<Class>> combinations = combinations(superClasses);
for (List<Class> combination : combinations) {
Class[] c = combination.toArray(new Class[combination.size()]);
try {
Method m = findAllDeclaredMethodByParams(name, c, clazz);
return m;
}catch (NoSuchMethodException e) {}
}

currentClass = currentClass.getSuperclass();
}
Expand Down

0 comments on commit 1cb02ab

Please sign in to comment.