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}