001package gu.sql2java;
002
003import java.lang.reflect.Array;
004import java.lang.reflect.InvocationHandler;
005import java.lang.reflect.InvocationTargetException;
006import java.lang.reflect.Method;
007import java.lang.reflect.Modifier;
008import java.lang.reflect.Proxy;
009import java.lang.reflect.Type;
010import java.util.Arrays;
011import java.util.Collection;
012import java.util.Comparator;
013import java.util.List;
014import java.util.Map;
015import java.util.regex.Matcher;
016import java.util.regex.Pattern;
017
018import com.google.common.base.Function;
019import com.google.common.base.Throwables;
020import com.google.common.collect.Lists;
021import com.google.common.collect.Maps;
022import gu.sql2java.BaseBean;
023import gu.sql2java.ForeignKeyMetaData;
024import gu.sql2java.IndexMetaData;
025import gu.sql2java.RowMetaData;
026
027import static com.google.common.base.Preconditions.*;
028import static gu.sql2java.NameUtilities.*;
029import static com.google.common.base.MoreObjects.*;
030import static gu.sql2java.SimpleLog.*;
031import static gu.sql2java.Managers.*;
032
033/**
034 * 基于{@link BaseTableManager}实例代理实现接口<I> <br>
035 * 
036 * @author guyadong
037 *
038 * @param <I> 接口类型
039 */
040public class TableManagerDecorator<I extends TableManager<?>> implements InvocationHandler{
041        private final Class<I> interfaceClass;
042        final BaseTableManager<? extends BaseBean> delegate;    
043        private final Map<Method, Invoker> invokers = Maps.newLinkedHashMap();
044        @SuppressWarnings("rawtypes")
045        private final Class<? extends BaseTableManager> implClass;
046        final RowMetaData metaData; 
047        private static boolean debug = false;
048        /**
049         * 构造方法
050         * 
051         * @param interfaceClass 接口类
052         * @param delegate 实现接口的实例
053         */
054        TableManagerDecorator(Class<I> interfaceClass, BaseTableManager<? extends BaseBean> delegate) {
055                checkType(interfaceClass,delegate);
056                this.interfaceClass = interfaceClass;
057                this.delegate = delegate;
058                this.implClass = delegate.getClass();
059                this.metaData = delegate.metaData;
060                try {
061                        compile();
062                } catch (Exception e) {
063                        Throwables.throwIfUnchecked(e);
064                        throw new RuntimeException(e);
065                }
066        }
067        /**
068         * 构造方法
069         * 
070         * @param interfaceClass 接口类
071         * @param tablename 接口类对应的表名
072         */
073        TableManagerDecorator(Class<I> interfaceClass, String tablename) {
074                this(interfaceClass,new BaseTableManager<BaseBean>(tablename));
075        }
076
077        @Override
078        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
079                return checkNotNull(invokers.get(method),"UNSUPPORT method %s",method).invoke(args);
080        }
081        
082        /**
083         * @return 根据当前对象创建新的接口实例{@link Proxy}
084         */
085        public final I proxyInstance(){
086                return interfaceClass.cast(Proxy.newProxyInstance(
087                                interfaceClass.getClassLoader(),
088                                new Class<?>[]{ interfaceClass},
089                                this));
090        }
091        
092        @Override
093        public String toString(){
094                StringBuffer builder = new StringBuffer();
095                String simulateClassName = interfaceClass.getSimpleName() + "Decorator";
096                String simulateTableManagerClass = BaseTableManager.class.getName() + "<"  + metaData.beanType.getName() + ">";
097                builder.append("class ").append(simulateClassName).append(" implements ").append(interfaceClass.getName()).append("{\n");
098                builder.append("    private final ").append(simulateTableManagerClass).append(" delegate;\n");
099                builder.append("    public ").append(simulateClassName).append("(").append(simulateTableManagerClass).append(" delegate){\n");
100                builder.append("        this.delegate = delegate\n");
101                builder.append("    }\n");
102                for(Invoker invoker:invokers.values()){
103                        builder.append(invoker);
104                }
105                builder.append("}\n");
106                return builder.toString();
107        }
108        /**
109         * 检查参数类型合法性,不匹配则抛出异常
110         * @param interfaceClass
111         * @param delegate
112         */
113        private static void checkType(Class<?> interfaceClass, BaseTableManager<?> delegate){
114                checkArgument(interfaceClass != null, "interfaceClass is null");
115                checkArgument(delegate != null, "delegate is null");
116                checkArgument(delegate.metaData.managerInterfaceClass.equals(interfaceClass), 
117                                "MISMATCH interface class of delegate(%s) with %s",
118                                delegate.metaData.managerInterfaceClass.getSimpleName(),
119                                interfaceClass.getName());
120        }
121        /**
122         * 创建{@code interfaceClass}接口实例
123         * @param interfaceClass 接口类
124         * @param delegate 代理类实例 
125         * @return {@code interfaceClass}接口实例
126         */
127        static final <I extends TableManager<?>>I makeInterfaceInstance(Class<I> interfaceClass,BaseTableManager<?> delegate){
128                return new TableManagerDecorator<I>(interfaceClass,delegate).proxyInstance();
129        }
130        /**
131         * 创建{@code interfaceClass}接口实例
132         * @param interfaceClass 接口类
133         * @param tablename 接口类对应的表名
134         * @return {@code interfaceClass}接口实例
135         */
136        static final <I extends TableManager<?>>I makeInterfaceInstance(Class<I> interfaceClass,String tablename){
137                return new TableManagerDecorator<I>(interfaceClass,tablename).proxyInstance();
138        }
139        /**
140         * 创建接口实例
141         * @param delegate 代理类实例 
142         * @return 接口实例
143         */
144        static final <I extends TableManager<?>>TableManager<?> makeInterfaceInstance(BaseTableManager<?> delegate){
145                checkArgument(delegate != null ,"delegate is null");
146                checkArgument(delegate.metaData.managerInterfaceClass != null,"delegate.metaData.managerInterfaceClass is null");
147                return makeInterfaceInstance(delegate.metaData.managerInterfaceClass,delegate);
148        }
149        /**
150         * 创建接口实例
151         * @param tablename 接口类对应的表名
152         * @return 接口实例
153         */
154        static final <I extends TableManager<?>>TableManager<?> makeInterfaceInstance(String tablename){
155                return makeInterfaceInstance(getBaseTableManager(tablename));
156        }
157        /**
158         * 设置是否输出调试信息标志
159         * @param debug 
160         */
161        static void setDebug(boolean debug) {
162                TableManagerDecorator.debug = debug;
163        }
164
165        private static final String M_LOADBYPRIMARYKEY = "loadByPrimaryKey";
166        private static final String D_LOADBYPKS = "loadByPks";
167        private static final String M_LOADBYPRIMARYKEYCHECKED = "loadByPrimaryKeyChecked";
168        private static final String M_EXISTSPRIMARYKEY = "existsPrimaryKey";
169        private static final String M_CHECKDUPLICATE = "checkDuplicate";
170        private static final String D_CHECKDUPLICATEBYPK = "checkDuplicateByPk";
171        private static final String M_DELETEBYPRIMARYKEY = "deleteByPrimaryKey";
172        private static final String D_DELETEBYPKS = "deleteByPks";
173        private static final String M_TOPRIMARYKEYLIST = "toPrimaryKeyList";
174        private static final String P_ADDJUNCTION = "addJunction(With(\\w+))?";
175        private static final String D_ADDJUNCTION = "addJunction";
176        private static final String P_DELETEJUNCTION = "deleteJunction(With(\\w+))?";
177        private static final String D_DELETEJUNCTION = "deleteJunction";
178        private static final String P_GETIMPORTEDBEANS = "get(\\w+)sBy(\\w+)$";
179        private static final String D_GETIMPORTEDBEANS = "getImportedBeans";
180        private static final String P_GETIMPORTEDBEANSASLIST = "get(\\w+)sBy(\\w+)AsList";
181        private static final String D_GETIMPORTEDBEANSASLIST = "getImportedBeansAsList";
182        private static final String P_DELETEIMPORTEDBEANS = "delete(\\w+)sBy(\\w+)";
183        private static final String D_DELETEIMPORTEDBEANS = "deleteImportedBeans";
184        private static final String P_SETIMPORTEDBEANS = "set(\\w+)sBy(\\w+)";
185        private static final String D_SETIMPORTEDBEANS = "setImportedBeans";
186        private static final String M_SAVE = "save";
187        private static final String D_SAVEFULLY = "saveFully";
188        private static final String M_SAVEASTRANSACTION = "saveAsTransaction";
189        private static final String D_SAVEFULLYASTRANSACTION = "saveFullyAsTransaction";
190        private static final String P_GETREFERENCEDBEAN = "getReferencedBy(\\w+)";
191        private static final String D_GETREFERENCEDBEAN = "getReferencedBean";
192        private static final String P_SETREFERENCEDBEAN = "setReferencedBy(\\w+)";
193        private static final String D_SETREFERENCEDBEAN = "setReferencedBean";
194        private static final String P_LOADBYINDEX = "loadByIndex(\\w+)";
195        private static final String D_LOADBYINDEX = "loadByIndex";
196        private static final String P_LOADUNIQUEBYINDEXCHECKED = "loadByIndex(\\w+)Checked";
197        private static final String D_LOADUNIQUEBYINDEXCHECKED = "loadUniqueByIndexChecked";
198        private static final String D_LOADBYINDEXFORINDICES = "loadByIndexForIndices";
199        private static final String D_LOADUNIQUEBYINDEX = "loadUniqueByIndex";
200        private static final String P_LOADBYINDEXASLIST = "loadByIndex(\\w+)AsList";
201        private static final String D_LOADBYINDEXASLIST = "loadByIndexAsList";
202        private static final String P_DELETEBYINDEX = "deleteByIndex(\\w+)";
203        private static final String D_DELETEBYINDEX = "deleteByIndex";
204        private static final String P_LOADVIAJUNCTIONASLIST = "loadVia(\\w+)AsList";
205        private static final String D_LOADVIAJUNCTIONASLIST = "loadViaJunctionAsList";
206        private static final String P_LISTOFSELFREF = "listOf(\\w+)";
207        private static final String D_LISTOFSELFREF = "listOfSelfRef";
208        private static final String P_LEVELOFSELFREF = "levelOf(\\w+)";
209        private static final String D_LEVELOFSELFREF = "levelOfSelfRef";
210        private static final String P_ISCYCLEOFSELFREF = "isCycleOn(\\w+)";
211        private static final String D_ISCYCLEOFSELFREF = "isCycleOfSelfRef";
212        private static final String P_CHECKCYCLEOFSELFREF = "checkCycleOf(\\w+)";
213        private static final String D_CHECKCYCLEOFSELFREF = "checkCycleOfSelfRef";
214        private static final String P_TOPOFSELFREF = "topOf(\\w+)";
215        private static final String D_TOPOFSELFREF = "topOfSelfRef";
216        private static final String P_CHILDLISTOFSELFREF = "childListBy(\\w+)";
217        private static final String D_CHILDLISTOFSELFREF = "childListOfSelfRef";
218        
219        private static final Comparator<Method> METHOD_COMPARATOR = new Comparator<Method>() {
220                @Override
221                public int compare(Method o1, Method o2) {
222                        return signatureOf(o1).compareTo(signatureOf(o2));
223                }
224        };
225        private static boolean declaredBySuper(Method method,Class<?> superClazz){
226                if(method.getDeclaringClass().equals(superClazz)){
227                        return true;
228                }
229                for(Class<?> clazz:superClazz.getInterfaces()){
230                        if(declaredBySuper(method,clazz)){
231                                return true;
232                        }
233                }
234                return false;
235        } 
236        /**
237         * 向上递归查找指定的方法,找不到指定的方法则抛出异常
238         * @param clazz
239         * @param name
240         * @param parameterTypes
241         * @return 方法对象
242         * @throws NoSuchMethodException 找不到指定的方法
243         * @throws SecurityException
244         */
245        private static Method recursiveGetDeclaredMethod(Class<?> clazz,String name, Class<?>... parameterTypes)
246                throws NoSuchMethodException, SecurityException {
247                try {
248                        return clazz.getDeclaredMethod(name, parameterTypes);
249                } catch (NoSuchMethodException e) {
250                        Class<?> superClass = clazz.getSuperclass();
251                        if(null != superClass){
252                                return recursiveGetDeclaredMethod(superClass,name,parameterTypes);
253                        }
254                        throw e;
255                }
256        }
257        
258        /**
259         * 在代理类({@link #implClass})查找指定的方法,找不到指定的方法则抛出异常
260         * @param name
261         * @param parameterTypes
262         * @return 方法对象
263         * @throws NoSuchMethodException 找不到指定的方法
264         * @throws SecurityException
265         */
266        private Method getDeclaredMethod(String name, Class<?>... parameterTypes)
267                throws NoSuchMethodException, SecurityException {
268                return recursiveGetDeclaredMethod(implClass, name, parameterTypes);
269        }
270        private NoSuchMethodException makeNoSuchMethodException(Method def){
271                return new NoSuchMethodException(logString("NO FOUND MATCHED METHOD for %s in %s",def,implClass));
272        }
273        private Invoker compile(Method def) throws NoSuchMethodException, SecurityException{
274                Method impl;
275                String name = def.getName();
276                if(declaredBySuper(def,TableManager.class)){
277                        impl = BaseTableManager.class.getDeclaredMethod(name, def.getParameterTypes());
278                        return new MethodInvoker(def, impl, delegate);
279                }
280                
281                switch(name){
282                case M_LOADBYPRIMARYKEY:
283                        return loadByPrimaryKey(def);
284                case M_LOADBYPRIMARYKEYCHECKED:
285                        impl = getDeclaredMethod(M_LOADBYPRIMARYKEYCHECKED, Object[].class);
286                        return new MethodInvoker(def, impl, delegate);
287                case M_EXISTSPRIMARYKEY:
288                        impl = getDeclaredMethod(M_EXISTSPRIMARYKEY, Object[].class);
289                        return new MethodInvoker(def, impl, delegate);
290                case M_CHECKDUPLICATE:
291                        impl = getDeclaredMethod(D_CHECKDUPLICATEBYPK, Object.class);
292                        return new MethodInvoker(def, impl, delegate);
293                case M_DELETEBYPRIMARYKEY:
294                        return deleteByPrimaryKey(def);
295                case M_TOPRIMARYKEYLIST:
296                        return toPrimaryKeyList(def);
297                case M_SAVE:
298                        return saveFully(def);
299                case M_SAVEASTRANSACTION:
300                        return saveFullyAsTransaction(def);
301                default:
302                        if(name.matches(P_ADDJUNCTION)){
303                                return addJunction(def);
304                        }
305                        if(name.matches(P_DELETEJUNCTION)){
306                                return deleteJunction(def);
307                        }
308                        if(name.matches(P_GETIMPORTEDBEANSASLIST)){
309                                return getImportedBeansAsList(def);
310                        }
311                        if(name.matches(P_GETIMPORTEDBEANS)){
312                                return getImportedBeans(def);
313                        }
314                        if(name.matches(P_DELETEIMPORTEDBEANS)){
315                                return deleteImportedBeans(def);
316                        }
317                        if(name.matches(P_SETIMPORTEDBEANS)){
318                                return setImportedBeans(def);
319                        }
320                        if(name.matches(P_GETREFERENCEDBEAN)){
321                                return getReferencedBean(def);
322                        }
323                        if(name.matches(P_SETREFERENCEDBEAN)){
324                                return setReferencedBean(def);
325                        }
326                        if(name.matches(P_LOADBYINDEXASLIST)){
327                                return loadByIndexAsList(def);
328                        }
329                        if(name.matches(P_LOADUNIQUEBYINDEXCHECKED)){
330                                return loadUniqueByIndexChecked(def);
331                        }
332                        if(name.matches(P_LOADBYINDEX)){
333                                return loadByIndex(def);
334                        }
335
336                        if(name.matches(P_DELETEBYINDEX)){
337                                return deleteByIndex(def);
338                        }
339                        if(name.matches(P_LOADVIAJUNCTIONASLIST)){
340                                return loadViaJunctionAsList(def);
341                        }
342                        if(name.matches(P_LISTOFSELFREF)){
343                                return listOfSelfRef(def);
344                        }
345                        if(name.matches(P_LEVELOFSELFREF)){
346                                return levelOfSelfRef(def);
347                        }
348                        if(name.matches(P_ISCYCLEOFSELFREF)){
349                                return isCycleOfSelfRef(def);
350                        }
351                        if(name.matches(P_CHECKCYCLEOFSELFREF)){
352                                return checkCycleOfSelfRef(def);
353                        }
354                        
355                        if(name.matches(P_TOPOFSELFREF)){
356                                return topOfSelfRef(def);
357                        }
358                        if(name.matches(P_CHILDLISTOFSELFREF)){
359                                return childListOfSelfRef(def);
360                        }
361                        throw new IllegalArgumentException(logString("NO SUCH METHOD maped %s",def.getName()));
362                }               
363        }
364        
365        private void addObjectInvoker(String methodName,Class<?>...parameterTypes) throws NoSuchMethodException, SecurityException{
366                Method method = Object.class.getMethod(methodName, parameterTypes);
367                ObjectInvoker objectInvoker = new ObjectInvoker(method);
368                invokers.put(method, objectInvoker);
369                if(debug){
370                        log("{}",objectInvoker);
371                }
372        }
373        private void compile(Method[] methods) throws NoSuchMethodException, SecurityException{
374                Arrays.sort(methods,METHOD_COMPARATOR);
375                for(Method method : methods){
376                        Invoker invokder = compile(method);
377                        invokers.put(method, invokder);
378//                      Invoker old = invokers.put(method, invokder);
379//                      checkState(old == null,"duplicated entry for method %s",signatureOf(method));
380                        if(debug){
381                                log("{}",invokder);
382                        }
383                }
384        }
385        private void compile() throws NoSuchMethodException, SecurityException{
386                addObjectInvoker("toString");
387                addObjectInvoker("hashCode");
388                addObjectInvoker("equals",Object.class);
389                compile(TableManager.class.getMethods());
390                compile(interfaceClass.getDeclaredMethods());
391        }
392    //////////////////////////////////////
393    // PRIMARY KEY METHODS
394    //////////////////////////////////////
395        
396        private MethodInvoker loadByPrimaryKey(Method def) throws NoSuchMethodException, SecurityException{
397                Method impl;
398                Class<?>[] paramTypes = def.getParameterTypes();
399                checkArgument(paramTypes.length == metaData.primaryKeyCount,"only %s parameter required for %s",metaData.primaryKeyCount,def);
400                if(Arrays.equals(metaData.primaryKeyTypes, paramTypes)){
401                        impl = getDeclaredMethod(M_LOADBYPRIMARYKEY, Object[].class);
402                }else {
403                        if(metaData.primaryKeyCount == 1){
404                                if(Collection.class.isAssignableFrom(paramTypes[0])){
405                                        impl = getDeclaredMethod(D_LOADBYPKS, Collection.class);
406                                }else{
407                                        Class<?> pkType = metaData.columnTypeOf(metaData.primaryKeyIds[0]);
408                                        Object pkArray = Array.newInstance(pkType, 0);
409                                        if(paramTypes[0] == pkArray.getClass()){
410                                                impl = getDeclaredMethod(D_LOADBYPKS, Object[].class);
411                                        }else {
412                                                throw makeNoSuchMethodException(def);
413                                        }
414                                }
415                        }else{
416                                throw makeNoSuchMethodException(def);
417                        }
418                }
419                return new MethodInvoker(def, impl, delegate);
420        }
421        private MethodInvoker deleteByPrimaryKey(Method def) throws NoSuchMethodException, SecurityException{
422                Method impl;
423                Class<?>[] paramTypes = def.getParameterTypes();
424                checkArgument(paramTypes.length == metaData.primaryKeyCount,"%s parameter required for %s",metaData.primaryKeyCount,def);
425                if(Arrays.equals(metaData.primaryKeyTypes, paramTypes)){
426                        impl = getDeclaredMethod(M_DELETEBYPRIMARYKEY, Object[].class);
427                }else {
428                        if(Collection.class.isAssignableFrom(paramTypes[0])){
429                                impl = getDeclaredMethod(D_DELETEBYPKS, Collection.class);
430                        }else{
431                                Class<?> pkType = metaData.columnTypeOf(metaData.primaryKeyIds[0]);
432                                Object pkArray = Array.newInstance(pkType, 0);
433                                if(paramTypes[0] == pkArray.getClass()){
434                                        impl = getDeclaredMethod(D_DELETEBYPKS, Object[].class);
435                                }else {
436                                        throw makeNoSuchMethodException(def);                                   
437                                }
438                        }
439                }
440                return new MethodInvoker(def, impl, delegate);
441        }
442        
443    //////////////////////////////////////
444    // GET/SET IMPORTED KEY BEAN METHOD
445    //////////////////////////////////////
446        
447        private MethodInvoker getImportedBeans(Method def)throws NoSuchMethodException, SecurityException{
448                Class<?>[] paramTypes = def.getParameterTypes();
449                String methodName = def.getName();
450                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
451                Pattern pattern = Pattern.compile(P_GETIMPORTEDBEANS);
452                Matcher matcher = pattern.matcher(methodName);
453                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_GETIMPORTEDBEANS);
454                String importeBeanName = matcher.group(1);
455                String readableName = matcher.group(2);
456                ForeignKeyMetaData importedKey = RowMetaData.getForeignKey(importeBeanName,readableName);
457                Method impl = getDeclaredMethod(D_GETIMPORTEDBEANS, 
458                                paramBuilder().add(importedKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
459                return new MethodInvoker(def, impl, delegate, importedKey.name);
460        }
461
462        private MethodInvoker getImportedBeansAsList(Method def)throws NoSuchMethodException, SecurityException{
463                Class<?>[] paramTypes = def.getParameterTypes();
464                String methodName = def.getName();
465                checkArgument(paramTypes.length == 1 || paramTypes.length == 3,"only 1 or 3 parameter required for %s",signatureOf(def));
466                Pattern pattern = Pattern.compile(P_GETIMPORTEDBEANSASLIST);
467                Matcher matcher = pattern.matcher(methodName);
468                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_GETIMPORTEDBEANSASLIST);
469                String importeBeanName = matcher.group(1);
470                String readableName = matcher.group(2);
471                ForeignKeyMetaData importedKey = RowMetaData.getForeignKey(importeBeanName,readableName);
472                Method impl = getDeclaredMethod(D_GETIMPORTEDBEANSASLIST, 
473                                paramBuilder().add(importedKey.name.getClass(),paramTypes).genericNormalize(1,Object[].class).build());
474                return new MethodInvoker(def, impl, delegate, importedKey.name);
475        }
476        private MethodInvoker deleteImportedBeans(Method def)throws NoSuchMethodException, SecurityException{
477                Class<?>[] paramTypes = def.getParameterTypes();
478                String methodName = def.getName();
479                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
480                Pattern pattern = Pattern.compile(P_DELETEIMPORTEDBEANS);
481                Matcher matcher = pattern.matcher(methodName);
482                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_DELETEIMPORTEDBEANS);
483                String importeBeanName = matcher.group(1);
484                String readableName = matcher.group(2);
485                ForeignKeyMetaData importedKey = RowMetaData.getForeignKey(importeBeanName,readableName);
486                Method impl = getDeclaredMethod(D_DELETEIMPORTEDBEANS, 
487                                paramBuilder().add(importedKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
488                return new MethodInvoker(def, impl, delegate, importedKey.name);
489        }
490        private MethodInvoker setImportedBeans(Method def)throws NoSuchMethodException, SecurityException{
491                Class<?>[] paramTypes = def.getParameterTypes();
492                String methodName = def.getName();
493                checkArgument(paramTypes.length == 2,"2 parameter required for %s",def.getName());
494                Pattern pattern = Pattern.compile(P_SETIMPORTEDBEANS);
495                Matcher matcher = pattern.matcher(methodName);
496                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_SETIMPORTEDBEANS);
497                String importeBeanName = matcher.group(1);
498                String readableName = matcher.group(2);
499                ForeignKeyMetaData importedKey = RowMetaData.getForeignKey(importeBeanName,readableName);
500                Method impl = getDeclaredMethod(D_SETIMPORTEDBEANS, 
501                                paramBuilder().add(importedKey.name.getClass(),wrapBaseBean(paramTypes)).build());
502                return new MethodInvoker(def, impl, delegate, importedKey.name);
503        }
504        
505    //_____________________________________________________________________
506    //
507    // SAVE 
508    //_____________________________________________________________________
509        
510        private MethodInvoker saveFully(Method def)throws NoSuchMethodException, SecurityException{
511                Class<?>[] paramTypes = def.getParameterTypes();
512                int paramCount = metaData.foreignKeys.size() + metaData.getImportedKeys().size() + 1;
513                checkArgument(paramTypes.length == paramCount,"%s parameter required for %s",paramCount,def.getName());         
514                Method impl = getDeclaredMethod(D_SAVEFULLY, BaseBean.class,Object[].class);
515
516                return new SaveFullyInvoker(def, impl);
517        }
518        private MethodInvoker saveFullyAsTransaction(Method def)throws NoSuchMethodException, SecurityException{
519                Class<?>[] paramTypes = def.getParameterTypes();
520                int paramCount = metaData.foreignKeys.size() + metaData.getImportedKeys().size() + 1;
521                checkArgument(paramTypes.length == paramCount,"%s parameter required for %s",paramCount,def.getName());
522                Method impl = getDeclaredMethod(D_SAVEFULLYASTRANSACTION, BaseBean.class,Object[].class);
523                return new SaveFullyInvoker(def, impl);
524        }
525        
526    //////////////////////////////////////
527    // GET/SET FOREIGN KEY BEAN METHOD
528    //////////////////////////////////////
529        
530        private MethodInvoker getReferencedBean(Method def)throws NoSuchMethodException, SecurityException{
531                Class<?>[] paramTypes = def.getParameterTypes();
532                String methodName = def.getName();
533                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
534                Pattern pattern = Pattern.compile(P_GETREFERENCEDBEAN);
535                Matcher matcher = pattern.matcher(methodName);
536                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_GETREFERENCEDBEAN);
537                String readableName = matcher.group(1);
538                ForeignKeyMetaData foreignKey = metaData.getForeignKeyByRn(readableName);
539                Method impl = getDeclaredMethod(D_GETREFERENCEDBEAN, foreignKey.name.getClass(), BaseBean.class);
540                return new MethodInvoker(def, impl, delegate, foreignKey.name);
541        }
542        private MethodInvoker setReferencedBean(Method def)throws NoSuchMethodException, SecurityException{
543                Class<?>[] paramTypes = def.getParameterTypes();
544                String methodName = def.getName();
545                checkArgument(paramTypes.length == 2,"2 parameter required for %s",def.getName());
546                Pattern pattern = Pattern.compile(P_SETREFERENCEDBEAN);
547                Matcher matcher = pattern.matcher(methodName);
548                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_SETREFERENCEDBEAN);
549                String readableName = matcher.group(1);
550                ForeignKeyMetaData foreignKey = metaData.getForeignKeyByRn(readableName);
551                Method impl = getDeclaredMethod(D_SETREFERENCEDBEAN, 
552                                paramBuilder().add(foreignKey.name.getClass(),wrapBaseBean(paramTypes)).build());
553                return new MethodInvoker(def, impl, delegate, foreignKey.name);
554        }
555        
556    //_____________________________________________________________________
557    //
558    // USING INDICES
559    //_____________________________________________________________________
560        
561        private MethodInvoker loadByIndex(Method def)throws NoSuchMethodException, SecurityException{
562                Method impl;
563                Class<?>[] paramTypes = def.getParameterTypes();
564                String methodName = def.getName();
565                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
566                Pattern pattern = Pattern.compile(P_LOADBYINDEX);
567                Matcher matcher = pattern.matcher(methodName);
568                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_LOADBYINDEX);
569                String readableName = matcher.group(1);
570                IndexMetaData index = metaData.getIndexCheckedByRn(readableName);
571                if(index.unique){
572                        Object indexArray = Array.newInstance(metaData.columnTypeOf(metaData.indexIdArray(index.name)[0]), 0);
573                        if(paramTypes[0].equals(indexArray.getClass()) && index.columns.size() == 1){
574                                impl = getDeclaredMethod(D_LOADBYINDEXFORINDICES, index.name.getClass(), Object[].class);
575                        } else if(Collection.class.equals(paramTypes[0]) && index.columns.size() == 1){
576                                        impl = getDeclaredMethod(D_LOADBYINDEXFORINDICES, index.name.getClass(), Collection.class);
577                        }else if(Arrays.equals(metaData.indexTypeArray(index.name), paramTypes)){
578                                impl = getDeclaredMethod(D_LOADUNIQUEBYINDEX, index.name.getClass(), Object[].class);
579                        } else{
580                                throw makeNoSuchMethodException(def);
581                        }
582                }else{
583                        impl = getDeclaredMethod(D_LOADBYINDEX, index.name.getClass(), Object[].class);
584                }
585                return new MethodInvoker(def, impl, delegate, index.name);
586        }
587        private MethodInvoker loadUniqueByIndexChecked(Method def)throws NoSuchMethodException, SecurityException{
588                Method impl;
589                Class<?>[] paramTypes = def.getParameterTypes();
590                String methodName = def.getName();
591                Pattern pattern = Pattern.compile(P_LOADUNIQUEBYINDEXCHECKED);
592                Matcher matcher = pattern.matcher(methodName);
593                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_LOADUNIQUEBYINDEXCHECKED);
594                String readableName = matcher.group(1);
595                IndexMetaData index = metaData.getIndexCheckedByRn(readableName);
596                if(Arrays.equals(metaData.indexTypeArray(index.name), paramTypes)){
597                        impl = getDeclaredMethod(D_LOADUNIQUEBYINDEXCHECKED, index.name.getClass(), Object[].class);
598                } else{
599                        throw makeNoSuchMethodException(def);
600                }
601                return new MethodInvoker(def, impl, delegate, index.name);
602        }
603        private MethodInvoker loadByIndexAsList(Method def)throws NoSuchMethodException, SecurityException{
604                Class<?>[] paramTypes = def.getParameterTypes();
605                String methodName = def.getName();
606                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
607                Pattern pattern = Pattern.compile(P_LOADBYINDEXASLIST);
608                Matcher matcher = pattern.matcher(methodName);
609                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_LOADBYINDEXASLIST);
610                String readableName = matcher.group(1);
611                IndexMetaData index = metaData.getIndexCheckedByRn(readableName);
612                Method impl = getDeclaredMethod(D_LOADBYINDEXASLIST, index.name.getClass(), Object[].class);
613                return new MethodInvoker(def, impl, delegate, index.name);
614        }
615        private MethodInvoker deleteByIndex(Method def)throws NoSuchMethodException, SecurityException{
616                Class<?>[] paramTypes = def.getParameterTypes();
617                String methodName = def.getName();
618                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
619                Pattern pattern = Pattern.compile(P_DELETEBYINDEX);
620                Matcher matcher = pattern.matcher(methodName);
621                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_DELETEBYINDEX);
622                String readableName = matcher.group(1);
623                IndexMetaData index = metaData.getIndexCheckedByRn(readableName);
624                Method impl = getDeclaredMethod(D_DELETEBYINDEX, index.name.getClass(), Object[].class);
625                return new MethodInvoker(def, impl, delegate, index.name);
626        }
627        
628    //_____________________________________________________________________
629    //
630    // MANY TO MANY: LOAD OTHER BEAN VIA JUNCTION TABLE
631    //_____________________________________________________________________
632        
633        private MethodInvoker loadViaJunctionAsList(Method def)throws NoSuchMethodException, SecurityException{
634                Class<?>[] paramTypes = def.getParameterTypes();
635                String methodName = def.getName();
636                checkArgument(paramTypes.length == 1 || paramTypes.length == 3,"1 or 3 parameter required for %s",def.getName());
637                Pattern pattern = Pattern.compile(P_LOADVIAJUNCTIONASLIST);
638                Matcher matcher = pattern.matcher(methodName);
639                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_LOADVIAJUNCTIONASLIST);
640                String coreClassName = matcher.group(1);
641                String junctionTable = RowMetaData.getRowMetaDataByCoreClassName(coreClassName).tablename;
642                paramBuilder().add(junctionTable.getClass(),wrapBaseBean(paramTypes)).build();
643                Method impl = getDeclaredMethod(D_LOADVIAJUNCTIONASLIST, 
644                                paramBuilder().add(junctionTable.getClass(),wrapBaseBean(paramTypes)).build());
645                return new MethodInvoker(def, impl, delegate, junctionTable);
646        }
647        private MethodInvoker addJunction(Method def) throws NoSuchMethodException, SecurityException{
648                String name = def.getName();
649                Type[] gTypes = def.getGenericParameterTypes();
650                Class<?>[] paramTypes = def.getParameterTypes();
651                checkArgument(paramTypes.length == 2,"only 2 parameter required for %s",name);
652                RowMetaData junctionTable = metaData.getJunctionTableFor(gTypes[1]);
653                Method impl = getDeclaredMethod(D_ADDJUNCTION, 
654                                paramBuilder().add(junctionTable.tablename.getClass(),wrapBaseBean(paramTypes)).build());
655                return new MethodInvoker(def, impl, delegate, junctionTable.tablename);
656        }
657
658        private MethodInvoker deleteJunction(Method def) throws NoSuchMethodException, SecurityException{
659                Type[] gTypes = def.getGenericParameterTypes();
660                Class<?>[] paramTypes = def.getParameterTypes();
661                checkArgument(paramTypes.length == 2,"only 2 parameter required for %s",def.getName());
662                RowMetaData junctionTable = metaData.getJunctionTableFor(gTypes[1]);
663                Method impl = getDeclaredMethod(D_DELETEJUNCTION, 
664                                paramBuilder().add(junctionTable.tablename.getClass(),wrapBaseBean(paramTypes)).build());
665                return new MethodInvoker(def, impl, delegate, junctionTable.tablename);
666        }
667
668        private MethodInvoker toPrimaryKeyList(Method def) throws NoSuchMethodException, SecurityException{
669                Method impl;
670                Class<?>[] paramTypes = def.getParameterTypes();
671                Class<?> pkType = metaData.columnTypeOf(metaData.primaryKeyIds[0]);
672                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
673                if(Collection.class.isAssignableFrom(paramTypes[0])){
674                        impl = getDeclaredMethod(M_TOPRIMARYKEYLIST, Class.class,Collection.class);
675                }else{                  
676                        Object beanArray = Array.newInstance(metaData.beanType, 0);
677                        if(paramTypes[0] == beanArray.getClass()){
678                                impl = getDeclaredMethod(M_TOPRIMARYKEYLIST, Class.class,BaseBean[].class);
679                        }else {
680                                throw makeNoSuchMethodException(def);
681                        }
682                }
683                return new MethodInvoker(def, impl, delegate, pkType);
684        }
685
686    //_____________________________________________________________________
687    //
688    // SELF-REFERENCE
689    //_____________________________________________________________________
690        
691        private MethodInvoker listOfSelfRef(Method def) throws NoSuchMethodException, SecurityException{
692                Class<?>[] paramTypes = def.getParameterTypes();
693                String methodName = def.getName();
694                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
695                Pattern pattern = Pattern.compile(P_LISTOFSELFREF);
696                Matcher matcher = pattern.matcher(methodName);
697                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_LISTOFSELFREF);
698                String readableName = matcher.group(1);
699                ForeignKeyMetaData selfRefKey = metaData.getSelfRefKeyByRn(readableName);
700                Method impl = getDeclaredMethod(D_LISTOFSELFREF, 
701                                paramBuilder().add(selfRefKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
702                return new MethodInvoker(def, impl, delegate, selfRefKey.name);
703        }
704        private MethodInvoker levelOfSelfRef(Method def) throws NoSuchMethodException, SecurityException{
705                Class<?>[] paramTypes = def.getParameterTypes();
706                String methodName = def.getName();
707                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
708                Pattern pattern = Pattern.compile(P_LEVELOFSELFREF);
709                Matcher matcher = pattern.matcher(methodName);
710                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_LEVELOFSELFREF);
711                String readableName = matcher.group(1);
712                ForeignKeyMetaData selfRefKey = metaData.getSelfRefKeyByRn(readableName);
713                Method impl = getDeclaredMethod(D_LEVELOFSELFREF, 
714                                paramBuilder().add(selfRefKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
715                return new MethodInvoker(def, impl, delegate, selfRefKey.name);
716        }
717        private MethodInvoker isCycleOfSelfRef(Method def) throws NoSuchMethodException, SecurityException{
718                Class<?>[] paramTypes = def.getParameterTypes();
719                String methodName = def.getName();
720                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
721                Pattern pattern = Pattern.compile(P_ISCYCLEOFSELFREF);
722                Matcher matcher = pattern.matcher(methodName);
723                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_ISCYCLEOFSELFREF);
724                String readableName = matcher.group(1);
725                ForeignKeyMetaData selfRefKey = metaData.getSelfRefKeyByRn(readableName);
726                Method impl = getDeclaredMethod(D_ISCYCLEOFSELFREF, 
727                                paramBuilder().add(selfRefKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
728                return new MethodInvoker(def, impl, delegate, selfRefKey.name);
729        }
730        private MethodInvoker checkCycleOfSelfRef(Method def) throws NoSuchMethodException, SecurityException{
731                Class<?>[] paramTypes = def.getParameterTypes();
732                String methodName = def.getName();
733                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
734                Pattern pattern = Pattern.compile(P_CHECKCYCLEOFSELFREF);
735                Matcher matcher = pattern.matcher(methodName);
736                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_CHECKCYCLEOFSELFREF);
737                String readableName = matcher.group(1);
738                ForeignKeyMetaData selfRefKey = metaData.getSelfRefKeyByRn(readableName);
739                Method impl = getDeclaredMethod(D_CHECKCYCLEOFSELFREF, 
740                                paramBuilder().add(selfRefKey.name.getClass(),paramTypes).genericNormalize(1, Object.class).build());
741                return new MethodInvoker(def, impl, delegate, selfRefKey.name);
742        }
743        private MethodInvoker topOfSelfRef(Method def) throws NoSuchMethodException, SecurityException{
744                Class<?>[] paramTypes = def.getParameterTypes();
745                String methodName = def.getName();
746                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
747                Pattern pattern = Pattern.compile(P_TOPOFSELFREF);
748                Matcher matcher = pattern.matcher(methodName);
749                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_TOPOFSELFREF);
750                String readableName = matcher.group(1);
751                ForeignKeyMetaData selfRefKey = metaData.getSelfRefKeyByRn(readableName);
752                Method impl = getDeclaredMethod(D_TOPOFSELFREF, 
753                                paramBuilder().add(selfRefKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
754                return new MethodInvoker(def, impl, delegate, selfRefKey.name);
755        }
756        private MethodInvoker childListOfSelfRef(Method def) throws NoSuchMethodException, SecurityException{
757                Class<?>[] paramTypes = def.getParameterTypes();
758                String methodName = def.getName();
759                checkArgument(paramTypes.length == 1,"only 1 parameter required for %s",def.getName());
760                Pattern pattern = Pattern.compile(P_CHILDLISTOFSELFREF);
761                Matcher matcher = pattern.matcher(methodName);
762                checkArgument(matcher.matches(),"INVALID method name pattern,%s required",P_CHILDLISTOFSELFREF);
763                String readableName = matcher.group(1);
764                ForeignKeyMetaData selfRefKey = metaData.getSelfRefKeyByRn(readableName);
765                Method impl = getDeclaredMethod(D_CHILDLISTOFSELFREF, 
766                                paramBuilder().add(selfRefKey.name.getClass(),paramTypes).genericNormalize(1, Object[].class).build());
767                return new MethodInvoker(def, impl, delegate, selfRefKey.name);
768        }
769
770        private static final boolean isVoid(Class<?> clazz){
771                return "void".equals(clazz.getName());
772        }
773        
774        private static final Class<?> wrapBaseBean(Class<?> type){
775                if(null != type){
776                        if(type.isArray()){
777                                Class<?> componentType = wrapBaseBean(type.getComponentType());
778                                if(componentType != type.getComponentType()){
779                                        return Array.newInstance(componentType, 0).getClass();
780                                }
781                                return type;
782                        }else{
783                                if(BaseBean.class.isAssignableFrom(type)){
784                                        return BaseBean.class;
785                                }
786                                return type;
787                        }
788                }
789                return type;
790        }
791        private static final Class<?>[] wrapBaseBean(Class<?>... types){
792                if(null != types){
793                        for(int i=0;i<types.length;++i){
794                                types[i] = wrapBaseBean(types[i]);
795                        }
796                }
797                return types;
798        }
799        static class ParamTypeBuilder{
800                List<Class<?>> builder = Lists.newLinkedList();
801
802                ParamTypeBuilder add(Class<?>type){
803                        builder.add(type);
804                        return this;
805                }
806                ParamTypeBuilder add(Class<?>[]types,int start){
807                        builder.addAll(Arrays.asList(Arrays.copyOfRange(types, start, types.length)));
808                        return this;
809                }
810                ParamTypeBuilder add(Class<?> type,Class<?> ...types){
811                        builder.add(type);
812                        builder.addAll(Arrays.asList(types));
813                        return this;
814                }
815                /**
816                 * 对象索引指定的类型进行泛型归一化<br>
817                 * 如果为{@link BaseBean}的子类则改为{@link BaseBean},否则改为{@code normalClass} 
818                 * @param index
819                 * @param normalizeClass 归一化类型
820                 * @return 当前对象
821                 */
822                ParamTypeBuilder genericNormalize(int index,Class<?> normalizeClass){
823                        try {
824                                Class<?> type = builder.get(index);
825                                if(BaseBean.class.isAssignableFrom(type)){
826                                        builder.set(index, BaseBean.class);
827                                }else{
828                                        builder.set(index, normalizeClass);
829                                }
830                        } catch (IndexOutOfBoundsException e) {
831                                throw new IllegalArgumentException(logString("INVALID index %s for  parameter types array", index));
832                        }
833                        return this;
834                }
835                Class<?>[] build(){
836                        return builder.toArray(new Class<?>[0]);
837                }
838        }
839        private static ParamTypeBuilder paramBuilder(){
840                return new ParamTypeBuilder();
841        }
842        
843        /**
844         * 调用执行方法调用,剥离封装在{@link InvocationTargetException}中的方法调用异常直接抛出
845         * @param method 方法对象(不可为{@code null})
846         * @param obj 方法调用对象
847         * @param input 方法调用参数
848         * @return 方法调用返回值
849         * @throws Throwable
850         */
851        private static Object stripedInvoke(Method method,Object obj,Object... input) throws Throwable {
852                try {
853                        return method.invoke(obj, input);
854                } catch (InvocationTargetException e) {
855                        Throwable te = e.getTargetException();
856                        if(te != null){
857                                if(debug){
858                                        log("InvocationTargetException:{}",te.toString());
859                                }
860                                /** 剥离出方法调用中产生的异常直接抛出 */ 
861                                throw te;
862                        }else{
863                                log(e.toString());
864                                throw e;
865                        }
866                }
867        }
868        /**
869         * 方法调用接口
870         * @author guyadong
871         */
872        interface Invoker {
873                static final Object[] EMPTY_OBJECT_ARRAY = new Object[]{};
874                /**
875                 * 执行方法调用
876                 * @param input 输入参数数组
877                 * @return 调用返回值
878                 * @throws Throwable 方法调用抛出异常
879                 */
880                Object invoke(Object[] input) throws Throwable;
881        }
882        private class ObjectInvoker implements Invoker{
883                final Method method;
884                ObjectInvoker(Method method) {
885                        this.method = method;
886                }
887                @Override
888                public Object invoke(Object[] input) throws Throwable {
889                        return stripedInvoke(method, delegate, firstNonNull(input,EMPTY_OBJECT_ARRAY));
890                }
891                @Override
892                public String toString() {
893                        StringBuilder builder = new StringBuilder();
894                        builder.append("\n");
895                        builder.append("    @Override\n");
896                        builder.append("    public ").append(signatureOf(method,true,true)).append("{\n");
897                        builder.append("        ");
898                        if(!isVoid(method.getReturnType())){
899                                builder.append("return ");
900                        }
901                        builder.append("delegate.").append(method.getName()).append("(");
902                        Class<?>[] paramTypes = method.getParameterTypes();
903                        for(int j = 0; j < paramTypes.length;++j){
904                                if(j > 0){
905                                        builder.append(",");
906                                }
907                                builder.append("arg").append(j);
908                        }
909                        builder.append(");\n");
910                        builder.append("    }\n");
911                        return builder.toString();
912                }
913                
914        }
915        /**
916         * 方法调用对象,用于封装执行方法调用时的所有信息
917         * @author guyadong
918         *
919         */
920        private class  MethodInvoker implements Invoker {
921                /** 接口方法  */
922                final Method def;
923                /** {@link  #manager}中与接口方法({@link #def})对应的实现方法  */
924                final Method impl;
925                /**  执行方法调用的对象 */
926                protected final BaseTableManager<? extends BaseBean> manager;
927                /**  执行方法调用时除原有传入参数之外的附加参数列表(排在原输入参数之前) */
928                protected final Object[] additionalParams;
929                /** 调用参数转换器,用于生成调用方法({@link #impl})的参数 */
930                private final Function<Object[], Object[]> argsMaker;
931                /**
932                 * @param def 接口方法
933                 * @param impl 实现方法
934                 * @param manager 执行调用的对象
935                 * @param additionalParams 附加参数列表
936                 */
937                private MethodInvoker(Method def, Method impl,BaseTableManager<? extends BaseBean> manager, Object... additionalParams) {
938                        this.def = def;
939                        this.impl = impl;
940                        if(!Modifier.isPublic(impl.getModifiers())){
941                                /** 非public方法必须设置为可访问 */
942                                impl.setAccessible(true);       
943                        }                       
944                        this.manager = checkNotNull(manager,"manager is null");
945                        this.additionalParams = firstNonNull(additionalParams, EMPTY_OBJECT_ARRAY);
946                        Class<?>[] paramTypes = impl.getParameterTypes();
947                        if(paramTypes.length == additionalParams.length + 1 && Object[].class.equals(paramTypes[additionalParams.length])){
948                                argsMaker = vaArgsMaker;
949                        }else if(additionalParams.length == 0){
950                                argsMaker = defaultArgsMaker;
951                        }else {
952                                argsMaker = addparamArgsMaker;
953                        }
954                }
955                /** 默认参数转换器,不对输入参数做任何修改原样返回 */
956                private final Function<Object[], Object[]> defaultArgsMaker = new Function<Object[], Object[]>() {
957                        
958                        @Override
959                        public Object[] apply(Object[] input) {
960                                return input;
961                        }
962                };
963                /** 有附加参数的参数转换器,创建新的Object数组,将附加参数,原输入参数顺序复制到新数组返回 */
964                private final Function<Object[], Object[]> addparamArgsMaker = new Function<Object[], Object[]>() {
965                        @Override
966                        public Object[] apply(Object[] input) {
967                                Object[] args = new Object[additionalParams.length + input.length];
968                                System.arraycopy(additionalParams, 0, args, 0, additionalParams.length);
969                                System.arraycopy(input, 0, args, additionalParams.length, input.length);
970                                return args;
971                        }
972                };
973                /** 
974                 * 输入参数为变长参数数组的参数转换器, 创建新的Object数组,
975                 * 将附加参数复制到新数组,并将输入参数数组做为一个整体添加到新数组最后返回 
976                 */
977                private final Function<Object[], Object[]> vaArgsMaker = new Function<Object[], Object[]>() {
978                        @Override
979                        public Object[] apply(Object[] input){
980                                Class<?>[] paramTypes = impl.getParameterTypes();
981                                Object[] args = new Object[paramTypes.length];
982                                System.arraycopy(additionalParams, 0, args, 0, additionalParams.length);
983                                args[additionalParams.length] = input;
984                                return args;
985                        }
986                };
987                @Override
988                public Object invoke(Object[] input) throws Throwable {
989                        return stripedInvoke(impl, manager, argsMaker.apply(firstNonNull(input, EMPTY_OBJECT_ARRAY)));
990                }               
991                @Override
992                public String toString() {
993                        
994                        StringBuilder builder = new StringBuilder();
995                        builder.append("\n");
996                        builder.append("    @Override\n");
997                        builder.append("    public ").append(signatureOf(def,true,true)).append("{\n");
998                        builder.append("        ");
999                        if(!isVoid(def.getReturnType())){
1000                                builder.append("return ");
1001                        }
1002                        builder.append(manager == delegate? "delegate.": BaseTableManager.class.getName()+".instanceOf(" + manager.getClass().getName() + ".class).");
1003                        builder.append(impl.getName());
1004                        builder.append("(");
1005                        int i=0;
1006                        for(; i < additionalParams.length;++i){
1007                                if(i>0){
1008                                        builder.append(",");
1009                                }
1010                                if(additionalParams[i] instanceof String){
1011                                        builder.append("\"" + additionalParams[i]  + "\"");
1012                                } else if(additionalParams[i] instanceof Class){
1013                                        builder.append(((Class<?>)additionalParams[i]).getName()  + ".class");
1014                                }else {
1015                                        builder.append(additionalParams[i]);
1016                                }
1017                        }
1018                        Class<?>[] paramTypes = def.getParameterTypes();
1019                        for(int j = 0;  j < paramTypes.length; ++j){
1020                                if(i++ > 0){
1021                                        builder.append(",");
1022                                }
1023                                builder.append("arg").append(j);
1024                        }
1025                        builder.append(");\n");
1026                        builder.append("    }\n");
1027                        return builder.toString();
1028                }
1029        }
1030        private class SaveFullyInvoker extends MethodInvoker{
1031                /**
1032                 * @param def 接口方法
1033                 * @param impl 实现方法
1034                 */
1035                private SaveFullyInvoker(Method def, Method impl) {
1036                        super(def, impl, delegate);
1037                }
1038
1039                @Override
1040                public Object invoke(Object[] input) throws Throwable {
1041                        return stripedInvoke(impl, manager, input[0],Arrays.copyOfRange(input, 1, input.length));
1042                }
1043                
1044                @Override
1045                public String toString() {
1046                        
1047                        StringBuilder builder = new StringBuilder();
1048                        builder.append("\n");
1049                        builder.append("    @Override\n");
1050                        builder.append("    public ").append(signatureOf(def,true,true)).append("{\n");
1051                        builder.append("        ").append("return ").append("delegate.").append(impl.getName()).append("(");
1052                        Class<?>[] paramTypes = def.getParameterTypes();
1053                        builder.append("arg0,new Object[]{");
1054                        for(int j = 0;  j < paramTypes.length; ++j){
1055                                if(j>0){
1056                                        builder.append(", ");
1057                                }
1058                                builder.append("arg").append(j);
1059                        }
1060                        builder.append("});\n");
1061                        builder.append("    }\n");
1062                        return builder.toString();
1063                }
1064        }
1065}