1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassDataCache.java Tue May 07 19:01:14 2013 +0200
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassDataCache.java Wed May 08 17:47:47 2013 +0200
1.3 @@ -67,44 +67,143 @@
1.4 return findField(getClassData(startingClass), name, signature);
1.5 }
1.6
1.7 - MethodData findMethod(ClassData currentClass,
1.8 + MethodData findMethod(final ClassData startingClass,
1.9 final String name,
1.10 final String signature) throws IOException {
1.11 + final FindFirstTraversalCallback<MethodData> ffTraversalCallback =
1.12 + new FindFirstTraversalCallback<MethodData>();
1.13 +
1.14 + findMethods(startingClass, name, signature, ffTraversalCallback);
1.15 + return ffTraversalCallback.getFirst();
1.16 + }
1.17 +
1.18 + FieldData findField(final ClassData startingClass,
1.19 + final String name,
1.20 + final String signature) throws IOException {
1.21 + final FindFirstTraversalCallback<FieldData> ffTraversalCallback =
1.22 + new FindFirstTraversalCallback<FieldData>();
1.23 +
1.24 + findFields(startingClass, name, signature, ffTraversalCallback);
1.25 + return ffTraversalCallback.getFirst();
1.26 + }
1.27 +
1.28 + void findMethods(final ClassData startingClass,
1.29 + final String methodName,
1.30 + final String methodSignature,
1.31 + final TraversalCallback<MethodData> mdTraversalCallback)
1.32 + throws IOException {
1.33 + traverseHierarchy(
1.34 + startingClass,
1.35 + new FindMethodsTraversalCallback(methodName, methodSignature,
1.36 + mdTraversalCallback));
1.37 + }
1.38 +
1.39 + void findFields(final ClassData startingClass,
1.40 + final String fieldName,
1.41 + final String fieldSignature,
1.42 + final TraversalCallback<FieldData> fdTraversalCallback)
1.43 + throws IOException {
1.44 + traverseHierarchy(
1.45 + startingClass,
1.46 + new FindFieldsTraversalCallback(fieldName, fieldSignature,
1.47 + fdTraversalCallback));
1.48 + }
1.49 +
1.50 + private boolean traverseHierarchy(
1.51 + ClassData currentClass,
1.52 + final TraversalCallback<ClassData> cdTraversalCallback)
1.53 + throws IOException {
1.54 while (currentClass != null) {
1.55 - final MethodData methodData =
1.56 - currentClass.findMethod(name, signature);
1.57 - if (methodData != null) {
1.58 - return methodData;
1.59 + if (!cdTraversalCallback.traverse(currentClass)) {
1.60 + return false;
1.61 + }
1.62 +
1.63 + for (final String superIfaceName:
1.64 + currentClass.getSuperInterfaces()) {
1.65 + if (!traverseHierarchy(getClassData(superIfaceName),
1.66 + cdTraversalCallback)) {
1.67 + return false;
1.68 + }
1.69 }
1.70
1.71 final String superClassName = currentClass.getSuperClassName();
1.72 if (superClassName == null) {
1.73 break;
1.74 }
1.75 +
1.76 currentClass = getClassData(superClassName);
1.77 }
1.78
1.79 - return null;
1.80 + return true;
1.81 }
1.82
1.83 - FieldData findField(ClassData currentClass,
1.84 - final String name,
1.85 - final String signature) throws IOException {
1.86 - while (currentClass != null) {
1.87 - final FieldData fieldData =
1.88 - currentClass.findField(name, signature);
1.89 - if (fieldData != null) {
1.90 - return fieldData;
1.91 - }
1.92 + interface TraversalCallback<T> {
1.93 + boolean traverse(T object);
1.94 + }
1.95
1.96 - final String superClassName = currentClass.getSuperClassName();
1.97 - if (superClassName == null) {
1.98 - break;
1.99 - }
1.100 - currentClass = getClassData(superClassName);
1.101 + private final class FindFirstTraversalCallback<T>
1.102 + implements TraversalCallback<T> {
1.103 + private T firstObject;
1.104 +
1.105 + @Override
1.106 + public boolean traverse(final T object) {
1.107 + firstObject = object;
1.108 + return false;
1.109 }
1.110
1.111 - return null;
1.112 + public T getFirst() {
1.113 + return firstObject;
1.114 + }
1.115 + }
1.116 +
1.117 + private final class FindMethodsTraversalCallback
1.118 + implements TraversalCallback<ClassData> {
1.119 + private final String methodName;
1.120 + private final String methodSignature;
1.121 + private final TraversalCallback<MethodData> mdTraversalCallback;
1.122 +
1.123 + public FindMethodsTraversalCallback(
1.124 + final String methodName,
1.125 + final String methodSignature,
1.126 + final TraversalCallback<MethodData> mdTraversalCallback) {
1.127 + this.methodName = methodName;
1.128 + this.methodSignature = methodSignature;
1.129 + this.mdTraversalCallback = mdTraversalCallback;
1.130 + }
1.131 +
1.132 + @Override
1.133 + public boolean traverse(final ClassData classData) {
1.134 + final MethodData methodData =
1.135 + classData.findMethod(methodName, methodSignature);
1.136 + return (methodData != null)
1.137 + ? mdTraversalCallback.traverse(methodData)
1.138 + : true;
1.139 + }
1.140 + }
1.141 +
1.142 + private final class FindFieldsTraversalCallback
1.143 + implements TraversalCallback<ClassData> {
1.144 + private final String fieldName;
1.145 + private final String fieldSignature;
1.146 + private final TraversalCallback<FieldData> fdTraversalCallback;
1.147 +
1.148 + public FindFieldsTraversalCallback(
1.149 + final String fieldName,
1.150 + final String fieldSignature,
1.151 + final TraversalCallback<FieldData> fdTraversalCallback) {
1.152 + this.fieldName = fieldName;
1.153 + this.fieldSignature = fieldSignature;
1.154 + this.fdTraversalCallback = fdTraversalCallback;
1.155 + }
1.156 +
1.157 + @Override
1.158 + public boolean traverse(final ClassData classData) {
1.159 + final FieldData fieldData =
1.160 + classData.findField(fieldName, fieldSignature);
1.161 + return (fieldData != null)
1.162 + ? fdTraversalCallback.traverse(fieldData)
1.163 + : true;
1.164 + }
1.165 }
1.166
1.167 private static InputStream loadClass(Bck2Brwsr.Resources l, String name)