📄 metaclassimpl.java
字号:
if (method!=null) return delegateMetaClass.invokeMethod(delegate,methodName,arguments); } if (method==null) { // still no methods found, test if delegate or owner are GroovyObjects // and invoke the method on them if so. MissingMethodException last = null; if (owner!=closure && (owner instanceof GroovyObject)) { try { GroovyObject go = (GroovyObject) owner; return go.invokeMethod(methodName,arguments); } catch (MissingMethodException mme) { if (last==null) last = mme; } } if (delegate!=closure && (delegate instanceof GroovyObject)) { try { GroovyObject go = (GroovyObject) delegate; return go.invokeMethod(methodName,arguments); } catch (MissingMethodException mme) { last = mme; } } if (last!=null) throw last; } } if (method != null) { return MetaClassHelper.doMethodInvoke(object, method, arguments); } else { // if no method was found, try to find a closure defined as a field of the class and run it try { Object value = this.getProperty(object, methodName); if (value instanceof Closure) { // This test ensures that value != this If you ever change this ensure that value != this Closure closure = (Closure) value; MetaClass delegateMetaClass = registry.getMetaClass(closure.getClass()); return delegateMetaClass.invokeMethod(closure,"doCall",arguments); } } catch (MissingPropertyException mpe) {} throw new MissingMethodException(methodName, theClass, arguments); } } public MetaMethod retrieveMethod(Object owner, String methodName, Object[] arguments) { // lets try use the cache to find the method MethodKey methodKey = new TemporaryMethodKey(methodName, arguments); MetaMethod method = (MetaMethod) methodCache.get(methodKey); if (method == null) { method = pickMethod(owner, methodName, arguments); if (method != null && method.isCacheable()) { methodCache.put(methodKey.createCopy(), method); } } return method; } public MetaMethod retrieveMethod(String methodName, Class[] arguments) { // lets try use the cache to find the method MethodKey methodKey = new TemporaryMethodKey(methodName, arguments); MetaMethod method = (MetaMethod) methodCache.get(methodKey); if (method == null) { method = pickMethod(methodName, arguments); // todo shall call pickStaticMethod also? if (method != null && method.isCacheable()) { methodCache.put(methodKey.createCopy(), method); } } return method; } public Constructor retrieveConstructor(Class[] arguments) { Constructor constructor = (Constructor) chooseMethod("<init>", constructors, arguments, false); if (constructor != null) { return constructor; } else { constructor = (Constructor) chooseMethod("<init>", constructors, arguments, true); if (constructor != null) { return constructor; } } return null; } public MetaMethod retrieveStaticMethod(String methodName, Class[] arguments) { MethodKey methodKey = new TemporaryMethodKey(methodName, arguments); MetaMethod method = (MetaMethod) staticMethodCache.get(methodKey); if (method == null) { method = pickStaticMethod(methodName, arguments); if (method != null) { staticMethodCache.put(methodKey.createCopy(), method); } } return method; } /** * Picks which method to invoke for the given object, method name and arguments */ public MetaMethod pickMethod(Object object, String methodName, Object[] arguments) { MetaMethod method = null; List methods = getMethods(methodName); if (!methods.isEmpty()) { Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments); method = (MetaMethod) chooseMethod(methodName, methods, argClasses, true); if (method == null) { int size = (arguments != null) ? arguments.length : 0; if (size == 1) { Object firstArgument = arguments[0]; if (firstArgument instanceof List) { // lets coerce the list arguments into an array of // arguments // e.g. calling JFrame.setLocation( [100, 100] ) List list = (List) firstArgument; arguments = list.toArray(); argClasses = MetaClassHelper.convertToTypeArray(arguments); method = (MetaMethod) chooseMethod(methodName, methods, argClasses, true); if (method==null) return null; return new TransformMetaMethod(method) { public Object invoke(Object object, Object[] arguments) throws Exception { Object firstArgument = arguments[0]; List list = (List) firstArgument; arguments = list.toArray(); return super.invoke(object, arguments); } }; } } } } return method; } /** * pick a method in a strict manner, i.e., without reinterpreting the first List argument. * this method is used only by ClassGenerator for static binding * @param methodName * @param arguments * @return */ public MetaMethod pickMethod(String methodName, Class[] arguments) { MetaMethod method = null; List methods = getMethods(methodName); if (!methods.isEmpty()) { method = (MetaMethod) chooseMethod(methodName, methods, arguments, false);//no coersion at classgen time.// if (method == null) {// method = (MetaMethod) chooseMethod(methodName, methods, arguments, true);// } } return method; } public Object invokeStaticMethod(Object object, String methodName, Object[] arguments) { if (log.isLoggable(Level.FINER)){ MetaClassHelper.logMethodCall(object, methodName, arguments); } if (arguments==null) arguments = EMPTY_ARGUMENTS; // lets try use the cache to find the method MethodKey methodKey = new TemporaryMethodKey(methodName, arguments); MetaMethod method = (MetaMethod) staticMethodCache.get(methodKey); if (method == null) { method = pickStaticMethod(object, methodName, arguments); if (method != null) { staticMethodCache.put(methodKey.createCopy(), method); } } if (method != null) { return MetaClassHelper.doMethodInvoke(object, method, arguments); } throw new MissingMethodException(methodName, theClass, arguments); } private MetaMethod pickStaticMethod(Object object, String methodName, Object[] arguments) { MetaMethod method = null; List methods = getStaticMethods(methodName); if (!methods.isEmpty()) { method = (MetaMethod) chooseMethod(methodName, methods, MetaClassHelper.convertToTypeArray(arguments), false); } if (method == null && theClass != Class.class) { MetaClass classMetaClass = registry.getMetaClass(Class.class); method = classMetaClass.pickMethod(object, methodName, arguments); } if (method == null) { method = (MetaMethod) chooseMethod(methodName, methods, MetaClassHelper.convertToTypeArray(arguments), true); } return method; } private MetaMethod pickStaticMethod(String methodName, Class[] arguments) { MetaMethod method = null; List methods = getStaticMethods(methodName); if (!methods.isEmpty()) { method = (MetaMethod) chooseMethod(methodName, methods, arguments, false);//disabled to keep consistant with the original version of pickStatciMethod// if (method == null) {// method = (MetaMethod) chooseMethod(methodName, methods, arguments, true);// } } if (method == null && theClass != Class.class) { MetaClass classMetaClass = registry.getMetaClass(Class.class); method = classMetaClass.pickMethod(methodName, arguments); } return method; } public Object invokeConstructor(Object[] arguments) { if (arguments==null) arguments = EMPTY_ARGUMENTS; Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments); Constructor constructor = (Constructor) chooseMethod("<init>", constructors, argClasses, false); if (constructor != null) { return MetaClassHelper.doConstructorInvoke(constructor, arguments); } else { constructor = (Constructor) chooseMethod("<init>", constructors, argClasses, true); if (constructor != null) { return MetaClassHelper.doConstructorInvoke(constructor, arguments); } } if (arguments.length == 1) { Object firstArgument = arguments[0]; if (firstArgument instanceof Map) { constructor = (Constructor) chooseMethod("<init>", constructors, MetaClassHelper.EMPTY_TYPE_ARRAY, false); if (constructor != null) { Object bean = MetaClassHelper.doConstructorInvoke(constructor, MetaClassHelper.EMPTY_ARRAY); setProperties(bean, ((Map) firstArgument)); return bean; } } } throw new GroovyRuntimeException( "Could not find matching constructor for: " + theClass.getName() + "("+InvokerHelper.toTypeString(arguments)+")"); } public Object invokeConstructorAt(Class at, Object[] arguments) { if (arguments==null) arguments = EMPTY_ARGUMENTS; Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments); Constructor constructor = (Constructor) chooseMethod("<init>", constructors, argClasses, false); if (constructor != null) { return doConstructorInvokeAt(at, constructor, arguments); } else { constructor = (Constructor) chooseMethod("<init>", constructors, argClasses, true); if (constructor != null) { return doConstructorInvokeAt(at, constructor, arguments); } } if (arguments.length == 1) { Object firstArgument = arguments[0]; if (firstArgument instanceof Map) { constructor = (Constructor) chooseMethod("<init>", constructors, MetaClassHelper.EMPTY_TYPE_ARRAY, false); if (constructor != null) { Object bean = doConstructorInvokeAt(at, constructor, MetaClassHelper.EMPTY_ARRAY); setProperties(bean, ((Map) firstArgument)); return bean; } } } throw new GroovyRuntimeException( "Could not find matching constructor for: " + theClass.getName() + "("+InvokerHelper.toTypeString(arguments)+")"); } /** * Sets a number of bean properties from the given Map where the keys are * the String names of properties and the values are the values of the * properties to set */ public void setProperties(Object bean, Map map) { for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { Map.Entry entry = (Map.Entry) iter.next(); String key = entry.getKey().toString(); Object value = entry.getValue(); try { setProperty(bean, key, value); } catch (GroovyRuntimeException e) { // lets ignore missing properties /** todo should replace this code with a getMetaProperty(key) != null check i.e. don't try and set a non-existent property */ } } } /** * @return the given property's value on the object */ public Object getProperty(final Object object, final String property) { // look for the property in our map MetaProperty mp = (MetaProperty) propertyMap.get(property); if (mp != null) { try { //System.out.println("we found a metaproperty for " + theClass.getName() + // "." + property); // delegate the get operation to the metaproperty return mp.getProperty(object); } catch(Exception e) { throw new GroovyRuntimeException("Cannot read property: " + property); } } if (genericGetMethod == null) { // Make sure there isn't a generic method in the "use" cases List possibleGenericMethods = getMethods("get"); if (possibleGenericMethods != null) { for (Iterator i = possibleGenericMethods.iterator(); i.hasNext(); ) { MetaMethod mmethod = (MetaMethod) i.next(); Class[] paramTypes = mmethod.getParameterTypes(); if (paramTypes.length == 1 && paramTypes[0] == String.class) { Object[] arguments = {property}; Object answer = MetaClassHelper.doMethodInvoke(object, mmethod, arguments); return answer; } } } } else { Object[] arguments = { property }; Object answer = MetaClassHelper.doMethodInvoke(object, genericGetMethod, arguments); // jes bug? a property retrieved via a generic get() can't have a null value?
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -