src/jdk/internal/dynalink/beans/AbstractJavaLinker.java

changeset 101
f8221ce53c2e
parent 90
5a820fb11814
child 123
071e859b371e
     1.1 --- a/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java	Mon Feb 18 10:36:18 2013 +0100
     1.2 +++ b/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java	Mon Feb 18 16:00:15 2013 +0100
     1.3 @@ -103,7 +103,6 @@
     1.4  import jdk.internal.dynalink.support.Guards;
     1.5  import jdk.internal.dynalink.support.Lookup;
     1.6  
     1.7 -
     1.8  /**
     1.9   * A base class for both {@link StaticClassLinker} and {@link BeanLinker}. Deals with common aspects of property
    1.10   * exposure and method calls for both static and instance facets of a class.
    1.11 @@ -128,50 +127,46 @@
    1.12          this.assignableGuard = assignableGuard;
    1.13  
    1.14          final FacetIntrospector introspector = createFacetIntrospector();
    1.15 -        try {
    1.16 -            // Add methods and properties
    1.17 -            for(Method method: introspector.getMethods()) {
    1.18 -                final String name = method.getName();
    1.19 -                final MethodHandle methodHandle = introspector.unreflect(method);
    1.20 -                // Add method
    1.21 -                addMember(name, methodHandle, methods);
    1.22 -                // Add the method as a property getter and/or setter
    1.23 -                if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) {
    1.24 -                    // Property getter
    1.25 -                    setPropertyGetter(Introspector.decapitalize(name.substring(3)), introspector.unreflect(
    1.26 -                            getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
    1.27 -                } else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 &&
    1.28 -                        method.getReturnType() == boolean.class) {
    1.29 -                    // Boolean property getter
    1.30 -                    setPropertyGetter(Introspector.decapitalize(name.substring(2)), introspector.unreflect(
    1.31 -                            getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
    1.32 -                } else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) {
    1.33 -                    // Property setter
    1.34 -                    addMember(Introspector.decapitalize(name.substring(3)), methodHandle, propertySetters);
    1.35 -                }
    1.36 +        // Add methods and properties
    1.37 +        for(Method method: introspector.getMethods()) {
    1.38 +            final String name = method.getName();
    1.39 +            final MethodHandle methodHandle = introspector.unreflect(method);
    1.40 +            // Add method
    1.41 +            addMember(name, methodHandle, methods);
    1.42 +            // Add the method as a property getter and/or setter
    1.43 +            if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) {
    1.44 +                // Property getter
    1.45 +                setPropertyGetter(Introspector.decapitalize(name.substring(3)), introspector.unreflect(
    1.46 +                        getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
    1.47 +            } else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 &&
    1.48 +                    method.getReturnType() == boolean.class) {
    1.49 +                // Boolean property getter
    1.50 +                setPropertyGetter(Introspector.decapitalize(name.substring(2)), introspector.unreflect(
    1.51 +                        getMostGenericGetter(method)), ValidationType.INSTANCE_OF);
    1.52 +            } else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) {
    1.53 +                // Property setter
    1.54 +                addMember(Introspector.decapitalize(name.substring(3)), methodHandle, propertySetters);
    1.55              }
    1.56 +        }
    1.57  
    1.58 -            // Add field getter/setters as property getters/setters.
    1.59 -            for(Field field: introspector.getFields()) {
    1.60 -                final String name = field.getName();
    1.61 -                // Only add a property getter when one is not defined already as a getXxx()/isXxx() method.
    1.62 -                if(!propertyGetters.containsKey(name)) {
    1.63 -                    setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS);
    1.64 -                }
    1.65 -                if(!(Modifier.isFinal(field.getModifiers()) || propertySetters.containsKey(name))) {
    1.66 -                    addMember(name, introspector.unreflectSetter(field), propertySetters);
    1.67 -                }
    1.68 +        // Add field getter/setters as property getters/setters.
    1.69 +        for(Field field: introspector.getFields()) {
    1.70 +            final String name = field.getName();
    1.71 +            // Only add a property getter when one is not defined already as a getXxx()/isXxx() method.
    1.72 +            if(!propertyGetters.containsKey(name)) {
    1.73 +                setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS);
    1.74              }
    1.75 +            if(!(Modifier.isFinal(field.getModifiers()) || propertySetters.containsKey(name))) {
    1.76 +                addMember(name, introspector.unreflectSetter(field), propertySetters);
    1.77 +            }
    1.78 +        }
    1.79  
    1.80 -            // Add inner classes, but only those for which we don't hide a property with it
    1.81 -            for(Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) {
    1.82 -                final String name = innerClassSpec.getKey();
    1.83 -                if(!propertyGetters.containsKey(name)) {
    1.84 -                    setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
    1.85 -                }
    1.86 +        // Add inner classes, but only those for which we don't hide a property with it
    1.87 +        for(Map.Entry<String, MethodHandle> innerClassSpec: introspector.getInnerClassGetters().entrySet()) {
    1.88 +            final String name = innerClassSpec.getKey();
    1.89 +            if(!propertyGetters.containsKey(name)) {
    1.90 +                setPropertyGetter(name, innerClassSpec.getValue(), ValidationType.EXACT_CLASS);
    1.91              }
    1.92 -        } finally {
    1.93 -            introspector.close();
    1.94          }
    1.95      }
    1.96  
    1.97 @@ -394,10 +389,8 @@
    1.98                              IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
    1.99                  if(nextComponent == null) {
   1.100                      return getClassGuardedInvocationComponent(compositeSetter, type);
   1.101 -                } else {
   1.102 -                    return nextComponent.compose(compositeSetter, getClassGuard(type), clazz,
   1.103 -                            ValidationType.EXACT_CLASS);
   1.104                  }
   1.105 +                return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
   1.106              }
   1.107              case 3: {
   1.108                  // Must have two arguments: target object and property value
   1.109 @@ -474,10 +467,8 @@
   1.110                              IS_ANNOTATED_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
   1.111                  if(nextComponent == null) {
   1.112                      return getClassGuardedInvocationComponent(compositeGetter, type);
   1.113 -                } else {
   1.114 -                    return nextComponent.compose(compositeGetter, getClassGuard(type), clazz,
   1.115 -                            ValidationType.EXACT_CLASS);
   1.116                  }
   1.117 +                return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
   1.118              }
   1.119              case 3: {
   1.120                  // Must have exactly one argument: receiver
   1.121 @@ -521,8 +512,10 @@
   1.122              case NONE: {
   1.123                  return null;
   1.124              }
   1.125 +            default: {
   1.126 +                throw new AssertionError();
   1.127 +            }
   1.128          }
   1.129 -        throw new AssertionError();
   1.130      }
   1.131  
   1.132      private static final MethodHandle IS_DYNAMIC_METHOD_NOT_NULL = Guards.asType(Guards.isNotNull(),
   1.133 @@ -541,32 +534,30 @@
   1.134                  if(nextComponent == null) {
   1.135                      // No next component operation; just return a component for this operation.
   1.136                      return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
   1.137 -                } else {
   1.138 -                    // What's below is basically:
   1.139 -                    //   foldArguments(guardWithTest(isNotNull, identity, nextComponent.invocation), getter)
   1.140 -                    // only with a bunch of method signature adjustments. Basically, execute method getter; if
   1.141 -                    // it returns a non-null DynamicMethod, use identity to return it, otherwise delegate to
   1.142 -                    // nextComponent's invocation.
   1.143 +                }
   1.144  
   1.145 -                    final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType(
   1.146 -                            DynamicMethod.class));
   1.147 -                    // Since it is part of the foldArgument() target, it will have extra args that we need to drop.
   1.148 -                    final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments(
   1.149 -                            DYNAMIC_METHOD_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0,
   1.150 -                                    DynamicMethod.class));
   1.151 -                    final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation();
   1.152 -                    // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly
   1.153 -                    assert nextComponentInvocation.type().equals(type);
   1.154 -                    // Since it is part of the foldArgument() target, we have to drop an extra arg it receives.
   1.155 -                    final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0,
   1.156 -                            DynamicMethod.class);
   1.157 -                    // Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get)
   1.158 -                    final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
   1.159 -                            IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter);
   1.160 +                // What's below is basically:
   1.161 +                // foldArguments(guardWithTest(isNotNull, identity, nextComponent.invocation), getter) only with a
   1.162 +                // bunch of method signature adjustments. Basically, execute method getter; if it returns a non-null
   1.163 +                // DynamicMethod, use identity to return it, otherwise delegate to nextComponent's invocation.
   1.164  
   1.165 -                    return nextComponent.compose(compositeGetter, getClassGuard(type), clazz,
   1.166 -                            ValidationType.EXACT_CLASS);
   1.167 -                }
   1.168 +                final MethodHandle typedGetter = linkerServices.asType(getDynamicMethod, type.changeReturnType(
   1.169 +                        DynamicMethod.class));
   1.170 +                // Since it is part of the foldArgument() target, it will have extra args that we need to drop.
   1.171 +                final MethodHandle returnMethodHandle = linkerServices.asType(MethodHandles.dropArguments(
   1.172 +                        DYNAMIC_METHOD_IDENTITY, 1, type.parameterList()), type.insertParameterTypes(0,
   1.173 +                                DynamicMethod.class));
   1.174 +                final MethodHandle nextComponentInvocation = nextComponent.getGuardedInvocation().getInvocation();
   1.175 +                // The assumption is that getGuardedInvocationComponent() already asType()'d it correctly
   1.176 +                assert nextComponentInvocation.type().equals(type);
   1.177 +                // Since it is part of the foldArgument() target, we have to drop an extra arg it receives.
   1.178 +                final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0,
   1.179 +                        DynamicMethod.class);
   1.180 +                // Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get)
   1.181 +                final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
   1.182 +                        IS_DYNAMIC_METHOD_NOT_NULL, returnMethodHandle, nextCombinedInvocation), typedGetter);
   1.183 +
   1.184 +                return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
   1.185              }
   1.186              case 3: {
   1.187                  // Must have exactly one argument: receiver
   1.188 @@ -638,7 +629,7 @@
   1.189       * @return the dynamic method (either {@link SimpleDynamicMethod} or {@link OverloadedDynamicMethod}, or null if the
   1.190       * method with the specified name does not exist.
   1.191       */
   1.192 -    public DynamicMethod getDynamicMethod(String name) {
   1.193 +    DynamicMethod getDynamicMethod(String name) {
   1.194          return getDynamicMethod(name, methods);
   1.195      }
   1.196  
   1.197 @@ -687,4 +678,4 @@
   1.198              this.validationType = validationType;
   1.199          }
   1.200      }
   1.201 -}
   1.202 \ No newline at end of file
   1.203 +}

mercurial