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 +}