1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 package org.jomc.standalone.ri;
38
39 import java.util.Stack;
40 import javax.naming.Context;
41 import javax.naming.InitialContext;
42 import javax.naming.NamingException;
43 import javax.persistence.EntityManager;
44 import javax.transaction.HeuristicMixedException;
45 import javax.transaction.HeuristicRollbackException;
46 import javax.transaction.InvalidTransactionException;
47 import javax.transaction.NotSupportedException;
48 import javax.transaction.RollbackException;
49 import javax.transaction.Status;
50 import javax.transaction.SystemException;
51 import javax.transaction.Transaction;
52 import javax.transaction.TransactionManager;
53 import javax.transaction.TransactionRequiredException;
54 import org.jomc.ObjectManagementException;
55 import org.jomc.model.Instance;
56 import org.jomc.ri.DefaultInvocation;
57 import org.jomc.ri.DefaultInvoker;
58 import org.jomc.standalone.model.MethodType;
59 import org.jomc.standalone.model.MethodsType;
60 import org.jomc.standalone.model.ParameterType;
61 import org.jomc.standalone.model.ParametersType;
62 import static org.jomc.standalone.model.TransactionAttributeType.*;
63 import org.jomc.standalone.model.TransactionType;
64 import org.jomc.spi.Invocation;
65 import org.jomc.standalone.model.ExceptionType;
66 import org.jomc.standalone.model.ExceptionsType;
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
98
99
100 public class StandaloneInvoker extends DefaultInvoker
101 {
102
103
104
105
106 private static final ThreadLocal<ThreadState> CURRENT = new ThreadLocal<ThreadState>()
107 {
108
109 @Override
110 public ThreadState initialValue()
111 {
112 return new ThreadState();
113 }
114
115 };
116
117 private StandaloneEnvironment standaloneEnvironment;
118
119 private Context standaloneContext;
120
121 @Override
122 public Invocation preInvoke( final Invocation invocation )
123 {
124 try
125 {
126 final FrameState currentFrame = this.createFrameState( invocation );
127 invocation.getContext().put( FrameState.class, currentFrame );
128
129 final FrameState previousFrame =
130 CURRENT.get().getFrames().isEmpty() ? null : CURRENT.get().getFrames().peek();
131
132 if ( previousFrame != null )
133 {
134 currentFrame.setRollback( previousFrame.isRollback() );
135 }
136
137 CURRENT.get().getFrames().push( currentFrame );
138
139 final int status = this.getTransactionManager().getStatus();
140
141 switch ( currentFrame.getMethodType().getTransaction().getType() )
142 {
143 case MANDATORY:
144 if ( status != Status.STATUS_ACTIVE )
145 {
146 final TransactionRequiredException e =
147 new TransactionRequiredException( this.getIllegalTransactionMessage(
148 this.getLocale(), invocation.getMethod().getName(), this.getStatusName( status ) ) );
149
150 e.fillInStackTrace();
151 invocation.setResult( e );
152 }
153 break;
154
155 case NEVER:
156 if ( status != Status.STATUS_NO_TRANSACTION )
157 {
158 final NotSupportedException e =
159 new NotSupportedException( this.getIllegalTransactionMessage(
160 this.getLocale(), invocation.getMethod().getName(), this.getStatusName( status ) ) );
161
162 e.fillInStackTrace();
163 invocation.setResult( e );
164 }
165 break;
166
167 case NOT_SUPPORTED:
168 if ( status == Status.STATUS_ACTIVE )
169 {
170 currentFrame.setSuspendedTransaction( this.getTransactionManager().suspend() );
171 }
172
173 break;
174
175 case REQUIRED:
176 if ( status == Status.STATUS_NO_TRANSACTION )
177 {
178 this.getTransactionManager().begin();
179 currentFrame.setTransactionInitiator( true );
180 this.getEntityManager().joinTransaction();
181 }
182 else if ( status != Status.STATUS_ACTIVE )
183 {
184 final SystemException e = new SystemException( this.getIllegalTransactionMessage(
185 this.getLocale(), invocation.getMethod().getName(), this.getStatusName( status ) ) );
186
187 e.fillInStackTrace();
188 invocation.setResult( e );
189 }
190
191 break;
192
193 case REQUIRES_NEW:
194 if ( status == Status.STATUS_ACTIVE )
195 {
196 currentFrame.setSuspendedTransaction( this.getTransactionManager().suspend() );
197 }
198 else if ( status != Status.STATUS_NO_TRANSACTION )
199 {
200 final SystemException e = new SystemException( this.getIllegalTransactionMessage(
201 this.getLocale(), invocation.getMethod().getName(), this.getStatusName( status ) ) );
202
203 e.fillInStackTrace();
204 invocation.setResult( e );
205 }
206
207 this.getTransactionManager().begin();
208 currentFrame.setTransactionInitiator( true );
209 this.getEntityManager().joinTransaction();
210 break;
211
212 case SUPPORTS:
213 break;
214
215 default:
216 final SystemException e = new SystemException( this.getUnsupportedTransactionMessage(
217 this.getLocale(), invocation.getMethod().getName(),
218 currentFrame.getMethodType().getTransaction().getType().toString() ) );
219
220 e.fillInStackTrace();
221 invocation.setResult( e );
222
223 }
224 }
225 catch ( final NamingException e )
226 {
227 invocation.setResult( e );
228 }
229 catch ( final NotSupportedException e )
230 {
231 invocation.setResult( e );
232 }
233 catch ( final SystemException e )
234 {
235 invocation.setResult( e );
236 }
237
238 return invocation;
239 }
240
241 @Override
242 public Invocation postInvoke( final Invocation invocation )
243 {
244 final FrameState frame = CURRENT.get().getFrames().pop();
245
246 try
247 {
248 if ( frame.isTransactionInitiator() )
249 {
250 if ( frame.isRollback() )
251 {
252 this.getTransactionManager().rollback();
253 }
254 else
255 {
256 this.getTransactionManager().commit();
257 }
258 }
259 }
260 catch ( final NamingException e )
261 {
262 invocation.setResult( e );
263 }
264 catch ( final SystemException e )
265 {
266 invocation.setResult( e );
267 }
268 catch ( final RollbackException e )
269 {
270 invocation.setResult( e );
271 }
272 catch ( final HeuristicMixedException e )
273 {
274 invocation.setResult( e );
275 }
276 catch ( final HeuristicRollbackException e )
277 {
278 invocation.setResult( e );
279 }
280 finally
281 {
282 try
283 {
284 if ( frame.getSuspendedTransaction() != null )
285 {
286 this.getTransactionManager().resume( frame.getSuspendedTransaction() );
287 }
288 }
289 catch ( final NamingException e )
290 {
291 invocation.setResult( e );
292 }
293 catch ( final InvalidTransactionException e )
294 {
295 invocation.setResult( e );
296 }
297 catch ( final SystemException e )
298 {
299 invocation.setResult( e );
300 }
301 }
302
303 return invocation;
304 }
305
306 @Override
307 public void handleException( final Invocation invocation, final Throwable t )
308 {
309 super.handleException( invocation, t );
310
311 final FrameState frameState = (FrameState) invocation.getContext().get( FrameState.class );
312 final ClassLoader classLoader = (ClassLoader) invocation.getContext().get( DefaultInvocation.CLASSLOADER_KEY );
313
314 try
315 {
316 ExceptionType handledException =
317 frameState.getMethodType().getExceptions().getException( invocation.getResult().getClass().getName() );
318
319 if ( handledException == null )
320 {
321 for ( ExceptionType e : frameState.getMethodType().getExceptions().getException() )
322 {
323 final Class handledExceptionClass = Class.forName( e.getClazz(), true, classLoader );
324
325 if ( handledExceptionClass.isAssignableFrom( invocation.getResult().getClass() ) )
326 {
327 handledException = e;
328 break;
329 }
330 }
331 }
332
333 if ( handledException != null )
334 {
335 if ( !frameState.isRollback() )
336 {
337 frameState.setRollback( handledException.isRollback() );
338 }
339
340 if ( handledException.getTargetClass() != null )
341 {
342 final Throwable targetException =
343 (Throwable) Class.forName( handledException.getTargetClass(), true, classLoader ).newInstance();
344
345 targetException.initCause( (Throwable) invocation.getResult() );
346 targetException.fillInStackTrace();
347 invocation.setResult( targetException );
348 }
349 }
350 else if ( frameState.getMethodType().getExceptions().getDefaultException() != null )
351 {
352 final Throwable defaultException = (Throwable) Class.forName(
353 frameState.getMethodType().getExceptions().getDefaultException().getClazz(), true, classLoader ).
354 newInstance();
355
356 defaultException.initCause( (Throwable) invocation.getResult() );
357 defaultException.fillInStackTrace();
358 invocation.setResult( defaultException );
359
360 if ( !frameState.isRollback() )
361 {
362 frameState.setRollback(
363 frameState.getMethodType().getExceptions().getDefaultException().isRollback() );
364
365 }
366 }
367 }
368 catch ( final InstantiationException e )
369 {
370 final ObjectManagementException oe = new ObjectManagementException( e );
371 oe.fillInStackTrace();
372 invocation.setResult( oe );
373 frameState.setRollback( true );
374 }
375 catch ( final IllegalAccessException e )
376 {
377 final ObjectManagementException oe = new ObjectManagementException( e );
378 oe.fillInStackTrace();
379 invocation.setResult( oe );
380 frameState.setRollback( true );
381 }
382 catch ( final ClassNotFoundException e )
383 {
384 final ObjectManagementException oe = new ObjectManagementException( e );
385 oe.fillInStackTrace();
386 invocation.setResult( oe );
387 frameState.setRollback( true );
388 }
389 }
390
391 public MethodType getMethodType( final Invocation invocation )
392 {
393 MethodType methodType = null;
394 final Instance instance = (Instance) invocation.getContext().get( DefaultInvocation.INSTANCE_KEY );
395
396 ExceptionsType defaultExceptions = new ExceptionsType();
397 TransactionType defaultTransaction = new TransactionType();
398 defaultTransaction.setType( SUPPORTS );
399
400 if ( instance != null )
401 {
402 final MethodsType methodsType = instance.getAnyObject( MethodsType.class );
403
404 if ( methodsType != null )
405 {
406 if ( methodsType.getTransaction() != null )
407 {
408 defaultTransaction = methodsType.getTransaction();
409 }
410 if ( methodsType.getExceptions() != null )
411 {
412 defaultExceptions = methodsType.getExceptions();
413 }
414
415 methodType = methodsType.getMethod(
416 invocation.getMethod().getName(), invocation.getMethod().getParameterTypes() );
417
418 }
419 }
420
421 if ( methodType != null )
422 {
423 if ( methodType.getTransaction() == null )
424 {
425 methodType.setTransaction( defaultTransaction );
426 }
427 if ( methodType.getExceptions() == null )
428 {
429 methodType.setExceptions( defaultExceptions );
430 }
431 else
432 {
433 for ( ExceptionType e : defaultExceptions.getException() )
434 {
435 if ( methodType.getExceptions().getException( e.getClazz() ) == null )
436 {
437 methodType.getExceptions().getException().add( e );
438 }
439 }
440
441 if ( methodType.getExceptions().getDefaultException() == null )
442 {
443 methodType.getExceptions().setDefaultException( defaultExceptions.getDefaultException() );
444 }
445 }
446 }
447 else
448 {
449 methodType = new MethodType();
450 methodType.setName( invocation.getMethod().getName() );
451 methodType.setTransaction( defaultTransaction );
452 methodType.setExceptions( defaultExceptions );
453
454 final ParametersType parametersType = new ParametersType();
455
456 for ( Class clazz : invocation.getMethod().getParameterTypes() )
457 {
458 final ParameterType parameterType = new ParameterType();
459 parameterType.setType( clazz.getName() );
460 parametersType.getParameter().add( parameterType );
461 }
462
463 if ( !parametersType.getParameter().isEmpty() )
464 {
465 methodType.setParameters( parametersType );
466 }
467 }
468
469 return methodType;
470 }
471
472 private StandaloneEnvironment getStandaloneEnvironment()
473 {
474 if ( this.standaloneEnvironment == null )
475 {
476 this.standaloneEnvironment = new StandaloneEnvironment();
477 }
478
479 return this.standaloneEnvironment;
480 }
481
482 private Context getStandaloneContext() throws NamingException
483 {
484 if ( this.standaloneContext == null )
485 {
486 this.standaloneContext = new InitialContext();
487 }
488
489 return this.standaloneContext;
490 }
491
492 private TransactionManager getTransactionManager() throws NamingException
493 {
494 return (TransactionManager) this.getStandaloneContext().lookup(
495 this.getStandaloneEnvironment().getTransactionManagerJndiName() );
496
497 }
498
499 private EntityManager getEntityManager() throws NamingException
500 {
501 return (EntityManager) this.getStandaloneContext().lookup(
502 this.getStandaloneEnvironment().getEntityManagerJndiName() );
503
504 }
505
506 private FrameState createFrameState( final Invocation invocation )
507 {
508 final FrameState frame = new FrameState();
509 frame.setMethodType( this.getMethodType( invocation ) );
510 return frame;
511 }
512
513 private String getStatusName( final int status ) throws SystemException, NamingException
514 {
515 switch ( status )
516 {
517 case Status.STATUS_ACTIVE:
518 return "STATUS_ACTIVE";
519
520 case Status.STATUS_COMMITTED:
521 return "STATUS_COMMITTED";
522
523 case Status.STATUS_COMMITTING:
524 return "STATUS_COMMITTING";
525
526 case Status.STATUS_MARKED_ROLLBACK:
527 return "STATUS_MARKED_ROLLBACK";
528
529 case Status.STATUS_NO_TRANSACTION:
530 return "STATUS_NO_TRANSACTION";
531
532 case Status.STATUS_PREPARED:
533 return "STATUS_PREPARED";
534
535 case Status.STATUS_PREPARING:
536 return "STATUS_PREPARING";
537
538 case Status.STATUS_ROLLEDBACK:
539 return "STATUS_ROLLEDBACK";
540
541 case Status.STATUS_ROLLING_BACK:
542 return "STATUS_ROLLING_BACK";
543
544 default:
545 return "STATUS_UNKNOWN";
546
547 }
548 }
549
550
551
552
553
554 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
555 public StandaloneInvoker()
556 {
557
558 super();
559
560 }
561
562
563
564
565
566
567
568
569
570
571
572
573 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
574 private java.util.Locale getLocale()
575 {
576 final java.util.Locale _d = (java.util.Locale) org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getDependency( this, "Locale" );
577 assert _d != null : "'Locale' dependency not found.";
578 return _d;
579 }
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
601 private String getIllegalTransactionMessage( final java.util.Locale locale, final java.lang.String methodName, final java.lang.String statusName )
602 {
603 final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "illegalTransactionMessage", locale, methodName, statusName );
604 assert _m != null : "'illegalTransactionMessage' message not found.";
605 return _m;
606 }
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
622 private String getUnsupportedTransactionMessage( final java.util.Locale locale, final java.lang.String methodName, final java.lang.String transactionAttribute )
623 {
624 final String _m = org.jomc.ObjectManagerFactory.getObjectManager( this.getClass().getClassLoader() ).getMessage( this, "unsupportedTransactionMessage", locale, methodName, transactionAttribute );
625 assert _m != null : "'unsupportedTransactionMessage' message not found.";
626 return _m;
627 }
628
629
630 }
631
632 class ThreadState
633 {
634
635 private Stack<FrameState> frames;
636
637 ThreadState()
638 {
639 super();
640 }
641
642 public Stack<FrameState> getFrames()
643 {
644 if ( this.frames == null )
645 {
646 this.frames = new Stack<FrameState>();
647 }
648
649 return this.frames;
650 }
651
652 }
653
654 class FrameState
655 {
656
657 private MethodType methodType;
658
659 private Transaction suspendedTransaction;
660
661 private boolean transactionInitiator;
662
663 private boolean rollback;
664
665 FrameState()
666 {
667 super();
668 }
669
670 public MethodType getMethodType()
671 {
672 return this.methodType;
673 }
674
675 public void setMethodType( final MethodType value )
676 {
677 this.methodType = value;
678 }
679
680 public Transaction getSuspendedTransaction()
681 {
682 return this.suspendedTransaction;
683 }
684
685 public void setSuspendedTransaction( final Transaction value )
686 {
687 this.suspendedTransaction = value;
688 }
689
690 public boolean isTransactionInitiator()
691 {
692 return this.transactionInitiator;
693 }
694
695 public void setTransactionInitiator( final boolean value )
696 {
697 this.transactionInitiator = value;
698 }
699
700 public boolean isRollback()
701 {
702 return this.rollback;
703 }
704
705 public void setRollback( final boolean value )
706 {
707 this.rollback = value;
708 }
709
710 }