rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassDataCache.java
branchclosure
changeset 1087 d868b5a67b9b
parent 1085 6a4ef883e233
child 1787 ea12a3bb4b33
     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)