001// ______________________________________________________ 002// Generated by sql2java - https://github.com/10km/sql2java-2-6-7 (custom branch) 003// modified by guyadong from 004// sql2java original version https://sourceforge.net/projects/sql2java/ 005// JDBC driver used at code generation time: com.mysql.jdbc.Driver 006// template: tablelistener.java.vm 007// ______________________________________________________ 008package net.gdface.facelog.db; 009 010import java.util.LinkedHashSet; 011import java.util.LinkedList; 012import java.util.Set; 013import java.util.concurrent.Executor; 014 015import net.gdface.facelog.db.exception.RuntimeDaoException; 016 017/** 018 * Listener that is notified of table changes. 019 * @author guyadong 020 */ 021public interface TableListener<B>{ 022 /** 023 * This adapter class provides default implementations for the 024 * methods declared by the {@link TableListener} interface.<br> 025 * 026 * @author guyadong 027 */ 028 public static class Adapter<B> implements TableListener<B>{ 029 030 @Override 031 public void beforeInsert(B bean)throws RuntimeDaoException {} 032 033 @Override 034 public void afterInsert(B bean)throws RuntimeDaoException {} 035 036 @Override 037 public void beforeUpdate(B bean)throws RuntimeDaoException {} 038 039 @Override 040 public void afterUpdate(B bean)throws RuntimeDaoException {} 041 042 @Override 043 public void beforeDelete(B bean)throws RuntimeDaoException {} 044 045 @Override 046 public void afterDelete(B bean)throws RuntimeDaoException {} 047 048 @Override 049 public void done()throws RuntimeDaoException {} 050 } 051 /** 052 * Invoked just before inserting a B record into the database. 053 * 054 * @param bean the B that is about to be inserted 055 * @throws RuntimeDaoException 056 */ 057 public void beforeInsert(B bean)throws RuntimeDaoException; 058 059 060 /** 061 * Invoked just after a B record is inserted in the database. 062 * 063 * @param bean the B that was just inserted 064 * @throws RuntimeDaoException 065 */ 066 public void afterInsert(B bean)throws RuntimeDaoException; 067 068 069 /** 070 * Invoked just before updating a B record in the database. 071 * 072 * @param bean the B that is about to be updated 073 * @throws RuntimeDaoException 074 */ 075 public void beforeUpdate(B bean)throws RuntimeDaoException; 076 077 078 /** 079 * Invoked just after updating a B record in the database. 080 * 081 * @param bean the B that was just updated 082 * @throws RuntimeDaoException 083 */ 084 public void afterUpdate(B bean)throws RuntimeDaoException; 085 086 087 /** 088 * Invoked just before deleting a B record in the database. 089 * 090 * @param bean the B that is about to be deleted 091 * @throws RuntimeDaoException 092 */ 093 public void beforeDelete(B bean)throws RuntimeDaoException; 094 095 096 /** 097 * Invoked just after deleting a B record in the database. 098 * 099 * @param bean the B that was just deleted 100 * @throws RuntimeDaoException 101 */ 102 public void afterDelete(B bean)throws RuntimeDaoException; 103 104 /** 105 * Invoked in finally block, just after insert,update,delete. 106 * 107 * @throws RuntimeDaoException 108 */ 109 public void done()throws RuntimeDaoException; 110 111 /** 112 * listener event:<br> 113 * {@code INSERT} insert a bean<br> 114 * {@code UPDATE} update a bean<br> 115 * {@code DELETE} delete a bean<br> 116 * {@code UPDATE_BEFORE} before updating a bean<br> 117 * @author guyadong 118 * 119 */ 120 public static enum Event{ 121 /** insert a bean */INSERT, 122 /** update a bean */UPDATE, 123 /** delete a bean */DELETE, 124 /** before updating a bean */UPDATE_BEFORE,; 125 /** 126 * fire current event by {@link ListenerContainer} 127 * @param container 128 * @param bean 129 * @throws RuntimeDaoException 130 */ 131 public <B> void fire(ListenerContainer<B> container,B bean)throws RuntimeDaoException { 132 if(null == container || null == bean){ 133 return; 134 } 135 switch(this){ 136 case INSERT: 137 container.afterInsert(bean); 138 break; 139 case UPDATE: 140 container.afterUpdate(bean); 141 break; 142 case DELETE: 143 container.afterDelete(bean); 144 break; 145 case UPDATE_BEFORE: 146 container.beforeUpdate(bean); 147 break; 148 default: 149 break; 150 } 151 } 152 public <B extends BaseBean<B>> void fire(TableManager<B > manager,B bean)throws RuntimeDaoException { 153 if(null == manager || null == bean){ 154 return; 155 } 156 manager.fire(this, bean); 157 } 158 } 159 /** 160 * container for multiple listener management 161 * @author guyadong 162 */ 163 public static class ListenerContainer <B> implements TableListener<B> { 164 private final Set<TableListener<B>> listeners = new LinkedHashSet<TableListener<B>>(16); 165 private static final InheritableThreadLocal<LinkedList<Runnable>> commitTasks = new InheritableThreadLocal<>(); 166 167 public static final TransactionListener TRANSACTION_LISTENER = new TransactionListener() { 168 169 @Override 170 public void beginTransaction() { 171 commitTasks.set(new LinkedList<Runnable>()); 172 } 173 174 @Override 175 public void endTransaction(boolean commit) { 176 if(commit){ 177 if(null == commitTasks.get()){ 178 throw new IllegalStateException("'beginTransaction' must be called firstly"); 179 } 180 for (Runnable task : commitTasks.get()) { 181 task.run(); 182 } 183 } 184 commitTasks.remove(); 185 } 186 }; 187 public ListenerContainer() { 188 } 189 190 private static void runTask(Runnable task){ 191 if(commitTasks.get() != null){ 192 commitTasks.get().add(task); 193 }else { 194 task.run(); 195 } 196 } 197 @Override 198 public void beforeInsert(B bean)throws RuntimeDaoException{ 199 synchronized (listeners) { 200 for(TableListener<B> listener:listeners){ 201 try{ 202 listener.beforeInsert(bean); 203 }catch(Exception e){ 204 System.out.printf("beforeInsert listener error:%s\n",e.getMessage()); 205 } 206 } 207 } 208 } 209 210 @Override 211 public void afterInsert(final B bean)throws RuntimeDaoException{ 212 synchronized (listeners) { 213 for(final TableListener<B> listener:listeners){ 214 runTask(new Runnable() { 215 216 @Override 217 public void run() { 218 try{ 219 listener.afterInsert(bean); 220 }catch(Exception e){ 221 System.out.printf("afterInsert listener error:%s\n",e.getMessage()); 222 } 223 } 224 }); 225 226 } 227 } 228 } 229 230 @Override 231 public void beforeUpdate(B bean)throws RuntimeDaoException{ 232 synchronized (listeners) { 233 for(TableListener<B> listener:listeners){ 234 try{ 235 listener.beforeUpdate(bean); 236 }catch(Exception e){ 237 System.out.printf("beforeUpdate listener error:%s\n",e.getMessage()); 238 } 239 } 240 } 241 } 242 243 @Override 244 public void afterUpdate(final B bean)throws RuntimeDaoException{ 245 synchronized (listeners) { 246 for(final TableListener<B> listener:listeners){ 247 runTask(new Runnable() { 248 249 @Override 250 public void run() { 251 try{ 252 listener.afterUpdate(bean); 253 }catch(Exception e){ 254 System.out.printf("afterUpdate listener error:%s\n",e.getMessage()); 255 } 256 } 257 }); 258 259 } 260 } 261 } 262 263 @Override 264 public void beforeDelete(B bean)throws RuntimeDaoException{ 265 synchronized (listeners) { 266 for(TableListener<B> listener:listeners){ 267 try{ 268 listener.beforeDelete(bean); 269 }catch(Exception e){ 270 System.out.printf("beforeDelete listener error:%s\n",e.getMessage()); 271 } 272 } 273 } 274 } 275 276 @Override 277 public void afterDelete(final B bean)throws RuntimeDaoException{ 278 synchronized (listeners) { 279 for(final TableListener<B> listener:listeners){ 280 runTask(new Runnable() { 281 282 @Override 283 public void run() { 284 try{ 285 listener.afterDelete(bean); 286 }catch(Exception e){ 287 System.out.printf("afterDelete listener error:%s\n",e.getMessage()); 288 } 289 } 290 }); 291 292 } 293 } 294 } 295 296 @Override 297 public void done()throws RuntimeDaoException{ 298 synchronized (listeners) { 299 for(TableListener<B> listener:listeners){ 300 try{ 301 listener.done(); 302 }catch(Exception e){ 303 System.out.printf("done listener error:%s\n",e.getMessage()); 304 } 305 } 306 } 307 } 308 /** 309 * determine if the container is empty. 310 * @return 311 */ 312 public boolean isEmpty() { 313 return listeners.isEmpty(); 314 } 315 /** 316 * determine if the {@code listener} be added. 317 * @param listener 318 * @return {@code true} if {@code listener} exists in container 319 */ 320 public boolean contains(TableListener<B> listener) { 321 synchronized (listeners) { 322 return listeners.contains(listener); 323 } 324 } 325 /** 326 * add {@code listener} into container 327 * @return {@code true} if add successfully. 328 */ 329 public boolean add(TableListener<B> listener) { 330 synchronized (listeners) { 331 return null == listener ? false : listeners.add(listener); 332 } 333 } 334 /** 335 * remove {@code listener} from container 336 * @param listener instance that will be removed. 337 * @return {@code true} if remove successfully. 338 */ 339 public boolean remove(TableListener<B> listener) { 340 synchronized (listeners) { 341 return null == listener? false : listeners.remove(listener); 342 } 343 } 344 /** remove all listeners in container */ 345 public void clear() { 346 synchronized (listeners) { 347 listeners.clear(); 348 } 349 } 350 } 351 /** 352 * decorator of a {@link TableListener}<br> 353 * run {@code delegate} in {@link Executor} 354 * @author guyadong 355 * 356 * @param <B> 357 */ 358 public static class DecoratorExecutorListener<B> implements TableListener<B>{ 359 private final TableListener<B> delegate; 360 private static final Executor DIRECT_EXECUTOR= new Executor(){ 361 @Override 362 public void execute(Runnable command) { 363 command.run(); 364 }}; 365 public DecoratorExecutorListener(TableListener<B> delegate) { 366 if(null == delegate){ 367 throw new NullPointerException(); 368 } 369 this.delegate = delegate; 370 } 371 /** return a {@link Executor} instance for execute task */ 372 protected Executor getExecutor() { 373 return DIRECT_EXECUTOR; 374 } 375 public TableListener<B> delegate(){ 376 return delegate; 377 } 378 protected void onException(Exception e){ 379 e.printStackTrace(); 380 } 381 @Override 382 public void beforeInsert(final B bean) throws RuntimeDaoException { 383 getExecutor().execute(new Runnable(){ 384 @Override 385 public void run() { 386 try{ 387 delegate.beforeDelete(bean); 388 }catch(Exception e){ 389 onException(e); 390 } 391 }}); 392 } 393 394 @Override 395 public void afterInsert(final B bean) throws RuntimeDaoException { 396 getExecutor().execute(new Runnable(){ 397 @Override 398 public void run() { 399 try{ 400 delegate.afterInsert(bean); 401 }catch(Exception e){ 402 onException(e); 403 } 404 }}); 405 } 406 407 @Override 408 public void beforeUpdate(final B bean) throws RuntimeDaoException { 409 getExecutor().execute(new Runnable(){ 410 @Override 411 public void run() { 412 try{ 413 delegate.beforeUpdate(bean); 414 }catch(Exception e){ 415 onException(e); 416 } 417 }}); 418 } 419 420 @Override 421 public void afterUpdate(final B bean) throws RuntimeDaoException { 422 getExecutor().execute(new Runnable(){ 423 @Override 424 public void run() { 425 try{ 426 delegate.afterUpdate(bean); 427 }catch(Exception e){ 428 onException(e); 429 } 430 }}); 431 } 432 433 @Override 434 public void beforeDelete(final B bean) throws RuntimeDaoException { 435 getExecutor().execute(new Runnable(){ 436 @Override 437 public void run() { 438 try{ 439 delegate.beforeDelete(bean); 440 }catch(Exception e){ 441 onException(e); 442 } 443 }}); 444 } 445 446 @Override 447 public void afterDelete(final B bean) throws RuntimeDaoException { 448 getExecutor().execute(new Runnable(){ 449 @Override 450 public void run() { 451 try{ 452 delegate.afterDelete(bean); 453 }catch(Exception e){ 454 onException(e); 455 } 456 }}); 457 } 458 459 @Override 460 public void done() throws RuntimeDaoException { 461 getExecutor().execute(new Runnable(){ 462 @Override 463 public void run() { 464 try{ 465 delegate.done(); 466 }catch(Exception e){ 467 onException(e); 468 } 469 }}); 470 } 471 } 472 public static interface TransactionListener{ 473 public void beginTransaction(); 474 public void endTransaction(boolean commit); 475 } 476} 477