• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / guice / #1210

04 Nov 2023 08:23PM CUT coverage: 80.045%. Remained the same
#1210

Pull #633

github

web-flow
Merge 9d1860fb9 into 408340d1e
Pull Request #633: [pom] Sortpom

1408 of 1759 relevant lines covered (80.05%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.51
/src/main/java/org/mybatis/guice/transactional/TxTransactionalMethodInterceptor.java
1
/*
2
 *    Copyright 2009-2023 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.mybatis.guice.transactional;
17

18
import static java.lang.String.format;
19

20
import jakarta.ejb.ApplicationException;
21
import jakarta.inject.Inject;
22
import jakarta.inject.Provider;
23
import jakarta.transaction.TransactionManager;
24

25
import java.lang.annotation.Annotation;
26
import java.lang.reflect.Method;
27

28
import javax.transaction.xa.XAResource;
29

30
import org.aopalliance.intercept.MethodInterceptor;
31
import org.aopalliance.intercept.MethodInvocation;
32
import org.apache.ibatis.logging.Log;
33
import org.apache.ibatis.logging.LogFactory;
34
import org.mybatis.guice.transactional.Transactional.TxType;
35

36
/**
37
 * Method interceptor for {@link Transactional} annotation.
38
 */
39
public class TxTransactionalMethodInterceptor implements MethodInterceptor {
40
  /**
41
   * This class logger.
42
   */
43
  private final Log log = LogFactory.getLog(getClass());
1✔
44

45
  @Inject
46
  private TransactionManager manager;
47

48
  @Inject
49
  private Provider<XAResource> xaResourceProvider;
50

51
  public TxTransactionalMethodInterceptor() {
1✔
52
  }
1✔
53

54
  private boolean isApplicationExceptionAvailable() {
55
    try {
56
      Class.forName("jakarta.ejb.ApplicationException");
1✔
57
      return true;
1✔
58
    } catch (ClassNotFoundException e) {
×
59
      return false;
×
60
    }
61
  }
62

63
  private <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationClass) {
64
    Class<?> current = clazz;
1✔
65
    A annotation = null;
1✔
66
    while (annotation == null && current != null) {
1✔
67
      annotation = current.getAnnotation(annotationClass);
1✔
68
      current = current.getSuperclass();
1✔
69
    }
70
    return annotation;
1✔
71
  }
72

73
  /**
74
   * {@inheritDoc}
75
   */
76
  @Override
77
  public Object invoke(MethodInvocation invocation) throws Throwable {
78
    Method interceptedMethod = invocation.getMethod();
1✔
79
    Transactional transactional = interceptedMethod.getAnnotation(Transactional.class);
1✔
80

81
    // The annotation may be present at the class level instead
82
    if (transactional == null) {
1✔
83
      transactional = interceptedMethod.getDeclaringClass().getAnnotation(Transactional.class);
×
84
    }
85

86
    String debugPrefix = null;
1✔
87
    if (this.log.isDebugEnabled()) {
1✔
88
      debugPrefix = String.format("[Intercepted method: %s]", interceptedMethod.toGenericString());
×
89
    }
90

91
    boolean needsRollback = transactional.rollbackOnly();
1✔
92
    Object object = null;
1✔
93
    TransactionAttribute attribute = null;
1✔
94

95
    if (manager != null) {
1✔
96
      TxType txType = transactional.value();
1✔
97
      if (TxType.REQUIRED.equals(txType)) {
1✔
98
        attribute = TransactionAttribute.REQUIRED;
1✔
99
      } else if (TxType.REQUIRES_NEW.equals(txType)) {
1✔
100
        attribute = TransactionAttribute.REQUIRESNEW;
1✔
101
      } else if (TxType.MANDATORY.equals(txType)) {
×
102
        attribute = TransactionAttribute.MANDATORY;
×
103
      } else if (TxType.SUPPORTS.equals(txType)) {
×
104
        attribute = TransactionAttribute.SUPPORTS;
×
105
      } else if (TxType.NOT_SUPPORTED.equals(txType)) {
×
106
        attribute = null; // FIXME add implementation
×
107
      } else if (TxType.NEVER.equals(txType)) {
×
108
        attribute = TransactionAttribute.NEVER;
×
109
      }
110
    }
111

112
    if (attribute == null) {
1✔
113
      if (log.isDebugEnabled()) {
×
114
        log.debug(format("%s - skip Tx Transaction", debugPrefix));
×
115
      }
116

117
      // without Tx
118
      try {
119
        object = invocation.proceed();
×
120
      } catch (Throwable t) {
×
121
        throw t;
×
122
      }
×
123
    } else {
124
      if (log.isDebugEnabled()) {
1✔
125
        log.debug(format("%s - Tx Transaction %s begin", debugPrefix, attribute.name()));
×
126
      }
127

128
      // with Tx
129
      TransactionToken tranToken = attribute.begin(manager);
1✔
130

131
      log.debug("enlistResource XASqlSessionManager");
1✔
132
      XAResource xaRes = xaResourceProvider.get();
1✔
133
      tranToken.getActiveTransaction().enlistResource(xaRes);
1✔
134

135
      try {
136
        if (log.isDebugEnabled()) {
1✔
137
          log.debug(format("%s - Tx Transaction %s (CompletionAllowed %s) call method", debugPrefix, attribute.name(),
×
138
              tranToken.isCompletionAllowed()));
×
139
        }
140
        object = invocation.proceed();
1✔
141

142
        if (needsRollback) {
1✔
143
          manager.setRollbackOnly();
×
144
        }
145

146
      } catch (Throwable t) {
1✔
147
        if (log.isDebugEnabled()) {
1✔
148
          log.debug(format("%s - Tx Transaction %s (CompletionAllowed %s) rolling back", debugPrefix, attribute.name(),
×
149
              tranToken.isCompletionAllowed()));
×
150
        }
151
        if (isApplicationExceptionAvailable()) {
1✔
152
          ApplicationException ae = t.getClass().getAnnotation(ApplicationException.class);
1✔
153
          ApplicationException parentAe = findAnnotation(t.getClass().getSuperclass(), ApplicationException.class);
1✔
154
          if ((ae == null && parentAe == null) || (ae != null && ae.rollback())
1✔
155
              || (parentAe != null && (!parentAe.inherited() || parentAe.rollback()))) {
1✔
156
            manager.setRollbackOnly();
1✔
157
          }
158
        } else {
1✔
159
          manager.setRollbackOnly();
×
160
        }
161
        throw t;
1✔
162
      } finally {
163
        if (log.isDebugEnabled()) {
1✔
164
          log.debug(format("%s - Tx Transaction %s (CompletionAllowed %s) finish", debugPrefix, attribute.name(),
×
165
              tranToken.isCompletionAllowed()));
×
166
        }
167
        attribute.finish(manager, tranToken);
1✔
168
      }
169
    }
170
    return object;
1✔
171
  }
172

173
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc