001package gu.sql2java; 002import java.lang.reflect.ParameterizedType; 003import java.lang.reflect.Type; 004import java.util.ArrayList; 005import java.util.Collection; 006import java.util.HashMap; 007import java.util.List; 008import java.util.Map; 009import java.util.Map.Entry; 010 011import static com.google.common.base.Preconditions.*; 012/** 013 * 014 * @author guyadong 015 * 016 * @param <L> left type 017 * @param <R> right type 018 */ 019public interface IBeanConverter<L,R> { 020 021 /** 022 * Default abstract implementation of {@link IBeanConverter}<br> 023 * 024 * @author guyadong 025 * 026 * @param <L> left type 027 * @param <R> right type 028 */ 029 public static abstract class AbstractHandle <L,R>implements IBeanConverter<L, R> { 030 /** L type */ 031 protected final Class<?> leftType; 032 /** R type */ 033 protected final Class<?> rightType; 034 private static Class<?> getRawClass(Type type){ 035 if(type instanceof Class<?>){ 036 return (Class<?>) type; 037 } else if(type instanceof ParameterizedType){ 038 return getRawClass(((ParameterizedType) type).getRawType()); 039 } else{ 040 throw new IllegalArgumentException("invalid type"); 041 } 042 } 043 public AbstractHandle() { 044 Type superClass = getClass().getGenericSuperclass(); 045 this.leftType = getRawClass(((ParameterizedType) superClass).getActualTypeArguments()[0]); 046 this.rightType = getRawClass(((ParameterizedType) superClass).getActualTypeArguments()[1]); 047 } 048 public AbstractHandle(Class<L> leftClass,Class<R> rightClass) { 049 this.leftType = checkNotNull(leftClass,"leftClass is null"); 050 this.rightType = checkNotNull(rightClass,"rightClass is null"); 051 } 052 /** 053 * copy right TO left, left and right must not be null 054 * @param left 055 * @param right 056 */ 057 protected abstract void doFromRight(L left, R right); 058 /** 059 * copy left TO right, left and right must not be null 060 * @param left 061 * @param right 062 */ 063 protected abstract void doToRight(L left, R right); 064 /** 065 * Creates a new L instance by calling constructor with an empty argument list<br> 066 * you must override the method if the L class haven't default constructor. 067 * @return 068 */ 069 @SuppressWarnings("unchecked") 070 protected L newInstanceL(){ return (L) newInstance(this.leftType); } 071 /** 072 * Creates a new R instance by calling constructor with an empty argument list<br> 073 * you must override the method if the R class haven't default constructor. 074 * @return 075 */ 076 @SuppressWarnings("unchecked") 077 protected R newInstanceR(){ return (R) newInstance(this.rightType); } 078 079 protected static<T> T newInstance(Class<T>clazz){ 080 try { 081 return (T) clazz.newInstance(); 082 } catch (InstantiationException e) { 083 throw new RuntimeException(e); 084 } catch (IllegalAccessException e) { 085 throw new RuntimeException(e); 086 } 087 } 088 @Override 089 public L fromRight(L left, R right) { 090 if(null != right && null != left){ 091 this.doFromRight(left, right); 092 } 093 return left; 094 } 095 096 @Override 097 public R toRight(L left, R right) { 098 if(null != left && null != right){ 099 this.doToRight(left, right); 100 } 101 return right; 102 } 103 104 @Override 105 public L fromRight(R bean) { 106 return null == bean? null : fromRight(newInstanceL(),bean); 107 } 108 109 @Override 110 public R toRight(L bean) { 111 return null == bean? null : toRight(bean,newInstanceR()); 112 } 113 114 @Override 115 public R[] toRight(L[] lefts, R[] rights) { 116 if(null != lefts && null != rights){ 117 if( lefts.length != rights.length){ 118 throw new IllegalArgumentException("mismatched length between left and right array"); 119 } 120 for(int i=0;i<lefts.length;++i){ 121 this.toRight(lefts[i],rights[i]); 122 } 123 } 124 return rights; 125 } 126 127 @Override 128 public L[] fromRight(L[] lefts, R[] rights) { 129 if(null != rights && null != lefts){ 130 if( lefts.length != rights.length){ 131 throw new IllegalArgumentException("mismatched length between left and right array"); 132 } 133 for(int i=0;i<lefts.length;++i){ 134 this.fromRight(lefts[i],rights[i]); 135 } 136 } 137 return lefts; 138 } 139 140 @SuppressWarnings("unchecked") 141 @Override 142 public R[] toRight(L[] lefts) { 143 R[] rights = null; 144 if(null != lefts){ 145 rights = (R[])java.lang.reflect.Array.newInstance(rightType,lefts.length) ; 146 for(int i=0;i<lefts.length;++i){ 147 rights[i] = toRight(lefts[i]); 148 } 149 } 150 return rights; 151 } 152 153 @SuppressWarnings("unchecked") 154 @Override 155 public L[] fromRight(R[] rights) { 156 L[] lefts = null; 157 if(null != rights){ 158 lefts = (L[])java.lang.reflect.Array.newInstance(leftType,rights.length) ; 159 for(int i=0;i<rights.length;++i){ 160 lefts[i] = fromRight(rights[i]); 161 } 162 } 163 return lefts; 164 } 165 166 @Override 167 public List<R> toRight(Collection<L> beans) { 168 if(null==beans){ 169 return null; 170 } 171 ArrayList<R> rights = new ArrayList<R>(beans.size()); 172 for(L g:beans){ 173 rights.add(this.toRight(g)); 174 } 175 return rights; 176 } 177 178 @Override 179 public List<L> fromRight(Collection<R> beans) { 180 if(null==beans){ 181 return null; 182 } 183 ArrayList<L> lefts = new ArrayList<L>(beans.size()); 184 for(R n:beans){ 185 lefts.add(this.fromRight(n)); 186 } 187 return lefts; 188 } 189 190 @Override 191 public List<R> toRight(List<L> lefts, List<R> rights) { 192 if(null != lefts && null != rights){ 193 if( lefts.size() != rights.size()){ 194 throw new IllegalArgumentException("mismatched length between left and right list"); 195 } 196 for(int i=0;i<lefts.size();++i){ 197 this.toRight(lefts.get(i),rights.get(i)); 198 } 199 } 200 return rights; 201 } 202 203 @Override 204 public List<L> fromRight(List<L> lefts, List<R> rights) { 205 if(null != rights && null != lefts){ 206 if( lefts.size() != rights.size()){ 207 throw new IllegalArgumentException("mismatched length between left and right list"); 208 } 209 for(int i=0;i<lefts.size();++i){ 210 this.fromRight(lefts.get(i),rights.get(i)); 211 } 212 } 213 return lefts; 214 } 215 216 @Override 217 public List<R> toRight(List<L> lefts) { 218 List<R> rights = null; 219 if(null != lefts ){ 220 rights = new ArrayList<>(); 221 for(L l:lefts){ 222 rights.add(toRight(l)); 223 } 224 } 225 return rights; 226 } 227 228 @Override 229 public List<L> fromRight(List<R> rights) { 230 List<L> lefts = null; 231 if(null != rights ){ 232 lefts = new ArrayList<>(); 233 for(R r:rights){ 234 lefts.add(fromRight(r)); 235 } 236 } 237 return lefts; 238 } 239 @Override 240 public<V> Map<R,V> toRightKey(Map<L,V> lmap) { 241 if(null == lmap){ 242 return null; 243 } 244 HashMap<R,V> rmap = new HashMap<R,V>(16); 245 for(Entry<L, V> entry:lmap.entrySet()){ 246 rmap.put(this.toRight(entry.getKey()),entry.getValue()); 247 } 248 return rmap; 249 } 250 @Override 251 public<K> Map<K,R> toRightValue(Map<K,L> lmap) { 252 if(null == lmap){ 253 return null; 254 } 255 HashMap<K, R> rmap = new HashMap<K, R>(16); 256 for(Entry<K, L> entry:lmap.entrySet()){ 257 rmap.put(entry.getKey(), this.toRight(entry.getValue())); 258 } 259 return rmap; 260 } 261 @Override 262 public<V> Map<L,V> fromRightKey(Map<R,V> rmap) { 263 if(null == rmap){ 264 return null; 265 } 266 HashMap<L,V> lmap = new HashMap<L,V>(16); 267 for(Entry<R, V> entry:rmap.entrySet()){ 268 lmap.put(this.fromRight(entry.getKey()),entry.getValue()); 269 } 270 return lmap; 271 } 272 @Override 273 public<K> Map<K,L> fromRightValue(Map<K,R> rmap) { 274 if(null == rmap){ 275 return null; 276 } 277 HashMap<K, L> lmap = new HashMap<K, L>(16); 278 for(Entry<K, R> entry:rmap.entrySet()){ 279 lmap.put(entry.getKey(), this.fromRight(entry.getValue())); 280 } 281 return lmap; 282 } 283 @Override 284 public Map<R,R> toRight(Map<L,L> lmap) { 285 if(null == lmap){ 286 return null; 287 } 288 HashMap<R,R> rmap = new HashMap<R,R>(16); 289 for(Entry<L, L> entry:lmap.entrySet()){ 290 rmap.put(this.toRight(entry.getKey()),this.toRight(entry.getValue())); 291 } 292 return rmap; 293 } 294 @Override 295 public Map<L,L> fromRight(Map<R,R> rmap) { 296 if(null == rmap){ 297 return null; 298 } 299 HashMap<L,L> lmap = new HashMap<L,L>(16); 300 for(Entry<R, R> entry:rmap.entrySet()){ 301 lmap.put(this.fromRight(entry.getKey()),this.fromRight(entry.getValue())); 302 } 303 return lmap; 304 } 305 } 306 307 /** 308 * copy right TO left 309 * @param left 310 * @param right 311 * @return left,or new instance if left is null 312 */ 313 public L fromRight(L left, R right); 314 315 /** 316 * copy left TO right 317 * @param left 318 * @param right 319 * @return right,or new instance if right is null 320 */ 321 public R toRight(L left, R right); 322 /** 323 * return an new instance converted from R bean 324 * @param bean 325 * @return L bean 326 */ 327 public L fromRight(R bean); 328 /** 329 * return an new instance converted from L bean 330 * @param bean 331 * @return R bean 332 */ 333 public R toRight( L bean); 334 /** 335 * copy rights TO lefts 336 * @param lefts 337 * @param rights 338 * @return lefts,or new array if lefts is null 339 */ 340 public L[] fromRight(L[] lefts,R[] rights); 341 /** 342 * copy lefts TO rights 343 * @param lefts 344 * @param rights 345 * @return rights,or new array if rights is null 346 */ 347 public R[] toRight(L[] lefts,R[] rights); 348 /** 349 * return an new array converted from R beans 350 * @param beans 351 * @return L bean array 352 */ 353 public L[] fromRight(R[] beans); 354 /** 355 * an new array converted from L beans 356 * @param beans 357 * @return R bean array 358 */ 359 public R[] toRight(L[] beans); 360 /** 361 * copy rights TO lefts 362 * @param lefts 363 * @param rights 364 * @return lefts,or new array if lefts is null 365 */ 366 public List<L> fromRight(List<L> lefts,List<R> rights); 367 /** 368 * copy lefts TO rights 369 * @param lefts 370 * @param rights 371 * @return rights,or new array if rights is null 372 */ 373 public List<R> toRight(List<L> lefts,List<R> rights); 374 /** 375 * return an new list converted from R beans 376 * @param beans 377 * @return L bean list 378 */ 379 public List<L> fromRight(List<R> beans); 380 /** 381 * return an new list converted from L beans 382 * @param beans 383 * @return R bean list 384 */ 385 public List<R> toRight(List<L> beans); 386 /** 387 * return an new list converted from R beans 388 * @param beans 389 * @return L bean list 390 */ 391 public List<L> fromRight(Collection<R> beans); 392 /** 393 * an new list converted from L beans 394 * @param beans 395 * @return R bean list 396 */ 397 public List<R> toRight(Collection<L> beans); 398 399 /** 400 * return an new map with R key converted from map with L key 401 * @param lmap 402 * @return Map with R key 403 */ 404 public <V> Map<R,V> toRightKey(Map<L,V> lmap); 405 /** 406 * return an new map with R value converted from map with L value 407 * @param lmap 408 * @return Map with R value 409 */ 410 public <K> Map<K,R> toRightValue(Map<K,L> lmap); 411 /** 412 * return an new map with L key converted from map with R key 413 * @param rmap 414 * @return Map with L key 415 */ 416 public <V> Map<L,V> fromRightKey(Map<R,V> rmap); 417 /** 418 * return an new map with L value converted from map with R value 419 * @param rmap 420 * @return Map with L value 421 */ 422 public <K> Map<K,L> fromRightValue(Map<K,R> rmap); 423 /** 424 * an new map with R key and R value converted from map with L key and L value 425 * @param lmap 426 * @return Map with R key and value 427 */ 428 public Map<R,R> toRight(Map<L,L> lmap); 429 /** 430 * return an new map with L key and L value converted from map with R key and R value 431 * @param rmap 432 * @return Map with L key and value 433 */ 434 public Map<L,L> fromRight(Map<R,R> rmap); 435}