`UberInterceptorMetaClass.groovy`
`001 /* 002 * Copyright 2007-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License") 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.codehaus.griffon.runtime.builder 017 018 import griffon.util.MethodUtils 019 import java.lang.reflect.InvocationTargetException 020 import org.codehaus.groovy.runtime.InvokerHelper 021 import org.slf4j.Logger 022 import org.slf4j.LoggerFactory 023 024 /** 025 * @author Danno Ferrin 026 * @author Andres Almiray 027 */ 028 class UberInterceptorMetaClass extends DelegatingMetaClass { 029 private static final Logger LOG = LoggerFactory.getLogger(UberInterceptorMetaClass) 030 UberBuilder factory 031 032 UberInterceptorMetaClass(MetaClass delegate, UberBuilder factory) { 033 super(delegate) 034 this.factory = factory 035 } 036 037 private Object doInvokeInstanceMethod(Object object, String methodName, Object arguments) { 038 Class klass = object instanceof Class ? object : object.getClass() 039 try { 040 return MethodUtils.invokeMethod(object, methodName, arguments) 041 } catch (NoSuchMethodException nsme) { 042 throw new MissingMethodException(methodName, klass, [arguments] as Object[]) 043 } catch (IllegalAccessException iae) { 044 throw new MissingMethodException(methodName, klass, [arguments] as Object[]) 045 } catch (InvocationTargetException ite) { 046 throw new MissingMethodException(methodName, klass, [arguments] as Object[]) 047 } 048 } 049 050 private Object doInvokeInstanceMethod(Object object, String methodName, Object[] arguments) { 051 Class klass = object instanceof Class ? object : object.getClass() 052 try { 053 return MethodUtils.invokeMethod(object, methodName, arguments) 054 } catch (NoSuchMethodException nsme) { 055 throw new MissingMethodException(methodName, klass, arguments) 056 } catch (IllegalAccessException iae) { 057 throw new MissingMethodException(methodName, klass, arguments) 058 } catch (InvocationTargetException ite) { 059 throw new MissingMethodException(methodName, klass, arguments) 060 } 061 } 062 063 private Object doInvokeStaticMethod(Object object, String methodName, Object[] arguments) { 064 Class klass = object instanceof Class ? object : object.getClass() 065 try { 066 return MethodUtils.invokeStaticMethod(klass, methodName, arguments) 067 } catch (NoSuchMethodException nsme) { 068 throw new MissingMethodException(methodName, klass, arguments) 069 } catch (IllegalAccessException iae) { 070 throw new MissingMethodException(methodName, klass, arguments) 071 } catch (InvocationTargetException ite) { 072 throw new MissingMethodException(methodName, klass, arguments) 073 } 074 } 075 076 private Object invokeFactoryMethod(String methodName, Object arguments, MissingMethodException mme) { 077 try { 078 return factory.invokeMethod(methodName, arguments) 079 } catch (MissingMethodException mme2) { 080 if (mme2.method != methodName) { 081 throw mme2 082 } 083 // chain secondary exception 084 Throwable root = mme 085 while (root.getCause() != null) { 086 root = root.getCause() 087 } 088 root.initCause(mme2) 089 // throw original 090 throw mme 091 } 092 } 093 094 private Object invokeFactoryMethod(String methodName, Object[] arguments, MissingMethodException mme) { 095 try { 096 return factory.invokeMethod(methodName, arguments) 097 } catch (MissingMethodException mme2) { 098 if (mme2.method != methodName) { 099 throw mme2 100 } 101 // chain secondary exception 102 Throwable root = mme 103 while (root.getCause() != null) { 104 root = root.getCause() 105 } 106 root.initCause(mme2) 107 // throw original 108 throw mme 109 } 110 } 111 112 private void exceptionIfMethodNotFound(String methodName, MissingMethodException mme) { 113 if (mme.method != methodName) { 114 throw mme 115 } 116 } 117 118 Object invokeMethod(Object object, String methodName, Object arguments) { 119 // try { 120 // return invokeMethod(object, methodName, arguments); 121 // } catch (MissingMethodException mme) { 122 // exceptionIfMethodNotFound(methodName, mme); 123 try { 124 return delegate.invokeMethod(object, methodName, arguments) 125 } catch (MissingMethodException mme2) { 126 exceptionIfMethodNotFound(methodName, mme2); 127 // attempt method resolution 128 for (UberBuilderRegistration reg in factory.builderRegistration) { 129 try { 130 def builder = reg.builder 131 if (!builder.getMetaClass().respondsTo(builder, methodName).isEmpty()) { 132 return InvokerHelper.invokeMethod(builder, methodName, arguments) 133 } 134 } catch (MissingMethodException mme3) { 135 exceptionIfMethodNotFound(methodName, mme3); 136 // drop the exception, there will be many 137 } 138 } 139 // dispatch to factories if it is not a literal method 140 return invokeFactoryMethod(methodName, arguments, mme2) 141 } 142 // } 143 } 144 145 Object invokeMethod(Object object, String methodName, Object[] arguments) { 146 // try { 147 // return invokeMethod(object, methodName, arguments); 148 // } catch (MissingMethodException mme) { 149 // exceptionIfMethodNotFound(methodName, mme); 150 try { 151 return delegate.invokeMethod(object, methodName, arguments) 152 } catch (MissingMethodException mme2) { 153 exceptionIfMethodNotFound(methodName, mme2); 154 // attempt method resolution 155 for (UberBuilderRegistration reg in factory.builderRegistration) { 156 try { 157 def builder = reg.builder 158 if (!builder.getMetaClass().respondsTo(builder, methodName).isEmpty()) { 159 return InvokerHelper.invokeMethod(builder, methodName, arguments) 160 } 161 } catch (MissingMethodException mme3) { 162 exceptionIfMethodNotFound(methodName, mme3); 163 // drop the exception, there will be many 164 } 165 } 166 // dispatch to factories if it is not a literal method 167 return invokeFactoryMethod(methodName, arguments, mme2) 168 } 169 // } 170 } 171 172 Object invokeStaticMethod(Object object, String methodName, Object[] arguments) { 173 try { 174 if (object instanceof Class) { 175 return doInvokeInstanceMethod(object, methodName, arguments) 176 } else { 177 return doInvokeStaticMethod(object, methodName, arguments) 178 } 179 } catch (MissingMethodException mme) { 180 exceptionIfMethodNotFound(methodName, mme); 181 try { 182 return delegate.invokeMethod(object, methodName, arguments) 183 } catch (MissingMethodException mme2) { 184 exceptionIfMethodNotFound(methodName, mme2); 185 186 // attempt method resolution 187 for (UberBuilderRegistration reg in factory.builderRegistration) { 188 try { 189 def builder = reg.builder 190 if (!builder.getMetaClass().respondsTo(builder, methodName).isEmpty()) { 191 return InvokerHelper.invokeMethod(builder, methodName, arguments) 192 } 193 } catch (MissingMethodException mme3) { 194 exceptionIfMethodNotFound(methodName, mme3); 195 196 // drop the exception, there will be many 197 } 198 } 199 // dispatch to factories if it is not a literal method 200 return invokeFactoryMethod(methodName, arguments, mme2) 201 } 202 } 203 } 204 205 Object getProperty(Object o, String s) { 206 try { 207 return super.getProperty(o, s) 208 } catch (MissingPropertyException mpe) { 209 return factory.getProperty(s) 210 } 211 } 212 213 void setProperty(Object o, String s, Object o1) { 214 try { 215 super.setProperty(o, s, o1) 216 } catch (MissingPropertyException mpe) { 217 factory.setProperty(s, o1) 218 } 219 } 220 }`