001 // SECTION-START[License Header]
002 // <editor-fold defaultstate="collapsed" desc=" Generated License ">
003 /*
004 * Copyright (c) 2010 The JOMC Project
005 * Copyright (c) 2005 Christian Schulte <schulte2005@users.sourceforge.net>
006 * All rights reserved.
007 *
008 * Redistribution and use in source and binary forms, with or without
009 * modification, are permitted provided that the following conditions
010 * are met:
011 *
012 * o Redistributions of source code must retain the above copyright
013 * notice, this list of conditions and the following disclaimer.
014 *
015 * o Redistributions in binary form must reproduce the above copyright
016 * notice, this list of conditions and the following disclaimer in
017 * the documentation and/or other materials provided with the
018 * distribution.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
029 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
030 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 *
032 * $Id: StandaloneInvoker.java 2242 2010-06-29 07:54:56Z schulte2005 $
033 *
034 */
035 // </editor-fold>
036 // SECTION-END
037 package org.jomc.standalone.ri;
038
039 import java.util.Stack;
040 import javax.naming.Context;
041 import javax.naming.InitialContext;
042 import javax.naming.NamingException;
043 import javax.persistence.EntityManager;
044 import javax.transaction.HeuristicMixedException;
045 import javax.transaction.HeuristicRollbackException;
046 import javax.transaction.InvalidTransactionException;
047 import javax.transaction.NotSupportedException;
048 import javax.transaction.RollbackException;
049 import javax.transaction.Status;
050 import javax.transaction.SystemException;
051 import javax.transaction.Transaction;
052 import javax.transaction.TransactionManager;
053 import javax.transaction.TransactionRequiredException;
054 import org.jomc.ObjectManagementException;
055 import org.jomc.model.Instance;
056 import org.jomc.ri.DefaultInvocation;
057 import org.jomc.ri.DefaultInvoker;
058 import org.jomc.standalone.model.MethodType;
059 import org.jomc.standalone.model.MethodsType;
060 import org.jomc.standalone.model.ParameterType;
061 import org.jomc.standalone.model.ParametersType;
062 import static org.jomc.standalone.model.TransactionAttributeType.*;
063 import org.jomc.standalone.model.TransactionType;
064 import org.jomc.spi.Invocation;
065 import org.jomc.standalone.model.ExceptionType;
066 import org.jomc.standalone.model.ExceptionsType;
067
068 // SECTION-START[Documentation]
069 // <editor-fold defaultstate="collapsed" desc=" Generated Documentation ">
070 /**
071 * Standalone {@code Invoker}.
072 * <p><b>Specifications</b><ul>
073 * <li>{@code 'org.jomc.spi.Invoker'} {@code (org.jomc.spi.Invoker)} {@code 1.0} {@code Multiton}</li>
074 * </ul></p>
075 * <p><b>Dependencies</b><ul>
076 * <li>"{@link #getLocale Locale}"<blockquote>
077 * Dependency on {@code 'java.util.Locale'} {@code (java.util.Locale)} at specification level 1.1 bound to an instance.</blockquote></li>
078 * </ul></p>
079 * <p><b>Messages</b><ul>
080 * <li>"{@link #getIllegalTransactionMessage illegalTransactionMessage}"<table>
081 * <tr><td valign="top">English:</td><td valign="top"><pre>Cannot invoke method ''{0}'' with a ''{1}'' transaction context.</pre></td></tr>
082 * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Die Methode ''{0}'' kann nicht in einem ''{1}'' Transaktions-Kontext ausgeführt werden.</pre></td></tr>
083 * </table>
084 * <li>"{@link #getUnsupportedTransactionMessage unsupportedTransactionMessage}"<table>
085 * <tr><td valign="top">English:</td><td valign="top"><pre>Unsupported transaction attribute ''{1}'' invoking method ''{0}''.</pre></td></tr>
086 * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Ungültiges Transaktions-Attribut ''{1}'' bei der Ausführung von Methode ''{0}''.</pre></td></tr>
087 * </table>
088 * </ul></p>
089 *
090 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a> 1.0
091 * @version $Id: StandaloneInvoker.java 2242 2010-06-29 07:54:56Z schulte2005 $
092 */
093 // </editor-fold>
094 // SECTION-END
095 // SECTION-START[Annotations]
096 // <editor-fold defaultstate="collapsed" desc=" Generated Annotations ">
097 @javax.annotation.Generated( value = "org.jomc.tools.SourceFileProcessor 1.0", comments = "See http://jomc.sourceforge.net/jomc/1.0/jomc-tools" )
098 // </editor-fold>
099 // SECTION-END
100 public class StandaloneInvoker extends DefaultInvoker
101 {
102 // SECTION-START[Invoker]
103 // SECTION-END
104 // SECTION-START[StandaloneInvoker]
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 // SECTION-END
550 // SECTION-START[Constructors]
551 // <editor-fold defaultstate="collapsed" desc=" Generated Constructors ">
552
553 /** Creates a new {@code StandaloneInvoker} instance. */
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 // SECTION-START[Default Constructor]
558 super();
559 // SECTION-END
560 }
561 // </editor-fold>
562 // SECTION-END
563 // SECTION-START[Dependencies]
564 // <editor-fold defaultstate="collapsed" desc=" Generated Dependencies ">
565
566 /**
567 * Gets the {@code Locale} dependency.
568 * <p>This method returns the {@code 'default'} object of the {@code 'java.util.Locale'} {@code (java.util.Locale)} specification at specification level 1.1.</p>
569 * <p>That specification does not apply to any scope. A new object is returned whenever requested and bound to this instance.</p>
570 * @return The {@code Locale} dependency.
571 * @throws org.jomc.ObjectManagementException if getting the dependency instance fails.
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 // </editor-fold>
581 // SECTION-END
582 // SECTION-START[Properties]
583 // SECTION-END
584 // SECTION-START[Messages]
585 // <editor-fold defaultstate="collapsed" desc=" Generated Messages ">
586
587 /**
588 * Gets the text of the {@code illegalTransactionMessage} message.
589 * <p><b>Templates</b><br/><table>
590 * <tr><td valign="top">English:</td><td valign="top"><pre>Cannot invoke method ''{0}'' with a ''{1}'' transaction context.</pre></td></tr>
591 * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Die Methode ''{0}'' kann nicht in einem ''{1}'' Transaktions-Kontext ausgeführt werden.</pre></td></tr>
592 * </table></p>
593 * @param locale The locale of the message to return.
594 * @param methodName Format argument.
595 * @param statusName Format argument.
596 * @return The text of the {@code illegalTransactionMessage} message.
597 *
598 * @throws org.jomc.ObjectManagementException if getting the message instance fails.
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 * Gets the text of the {@code unsupportedTransactionMessage} message.
610 * <p><b>Templates</b><br/><table>
611 * <tr><td valign="top">English:</td><td valign="top"><pre>Unsupported transaction attribute ''{1}'' invoking method ''{0}''.</pre></td></tr>
612 * <tr><td valign="top">Deutsch:</td><td valign="top"><pre>Ungültiges Transaktions-Attribut ''{1}'' bei der Ausführung von Methode ''{0}''.</pre></td></tr>
613 * </table></p>
614 * @param locale The locale of the message to return.
615 * @param methodName Format argument.
616 * @param transactionAttribute Format argument.
617 * @return The text of the {@code unsupportedTransactionMessage} message.
618 *
619 * @throws org.jomc.ObjectManagementException if getting the message instance fails.
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 // </editor-fold>
629 // SECTION-END
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 }