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

mybatis / mybatis-3 / 2596

02 Jan 2025 08:49PM UTC coverage: 87.522% (-0.004%) from 87.526%
2596

push

github

web-flow
Merge pull request #3372 from harawata/drop-java8-fallback

Drop java8 fallback

3633 of 4401 branches covered (82.55%)

14 of 16 new or added lines in 9 files covered. (87.5%)

9 existing lines in 2 files now uncovered.

9574 of 10939 relevant lines covered (87.52%)

0.88 hits per line

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

88.57
/src/main/java/org/apache/ibatis/binding/MapperProxy.java
1
/*
2
 *    Copyright 2009-2025 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.apache.ibatis.binding;
17

18
import java.io.Serializable;
19
import java.lang.invoke.MethodHandle;
20
import java.lang.invoke.MethodHandles;
21
import java.lang.invoke.MethodHandles.Lookup;
22
import java.lang.invoke.MethodType;
23
import java.lang.reflect.InvocationHandler;
24
import java.lang.reflect.InvocationTargetException;
25
import java.lang.reflect.Method;
26
import java.util.Map;
27

28
import org.apache.ibatis.reflection.ExceptionUtil;
29
import org.apache.ibatis.session.SqlSession;
30

31
/**
32
 * @author Clinton Begin
33
 * @author Eduardo Macarron
34
 */
35
public class MapperProxy<T> implements InvocationHandler, Serializable {
36

37
  private static final long serialVersionUID = -4724728412955527868L;
38
  private static final Method privateLookupInMethod;
39
  private final SqlSession sqlSession;
40
  private final Class<T> mapperInterface;
41
  private final Map<Method, MapperMethodInvoker> methodCache;
42

43
  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethodInvoker> methodCache) {
1✔
44
    this.sqlSession = sqlSession;
1✔
45
    this.mapperInterface = mapperInterface;
1✔
46
    this.methodCache = methodCache;
1✔
47
  }
1✔
48

49
  static {
50
    try {
51
      privateLookupInMethod = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
1✔
52
    } catch (NoSuchMethodException e) {
×
NEW
53
      throw new IllegalStateException(
×
54
          "There is no 'privateLookupIn(Class, Lookup)' method in java.lang.invoke.MethodHandles.", e);
55
    }
1✔
56
  }
1✔
57

58
  @Override
59
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
60
    try {
61
      if (Object.class.equals(method.getDeclaringClass())) {
1✔
62
        return method.invoke(this, args);
1✔
63
      }
64
      return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
1✔
65
    } catch (Throwable t) {
1✔
66
      throw ExceptionUtil.unwrapThrowable(t);
1✔
67
    }
68
  }
69

70
  private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
71
    try {
72
      return methodCache.computeIfAbsent(method, m -> {
1✔
73
        if (!m.isDefault()) {
1✔
74
          return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
1✔
75
        }
76
        try {
77
          return new DefaultMethodInvoker(getMethodHandleJava9(method));
1✔
NEW
78
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
×
UNCOV
79
          throw new RuntimeException(e);
×
80
        }
81
      });
82
    } catch (RuntimeException re) {
1✔
83
      Throwable cause = re.getCause();
1✔
84
      throw cause == null ? re : cause;
1!
85
    }
86
  }
87

88
  private MethodHandle getMethodHandleJava9(Method method)
89
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
90
    final Class<?> declaringClass = method.getDeclaringClass();
1✔
91
    return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup())).findSpecial(
1✔
92
        declaringClass, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()),
1✔
93
        declaringClass);
94
  }
95

96
  interface MapperMethodInvoker {
97
    Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable;
98
  }
99

100
  private static class PlainMethodInvoker implements MapperMethodInvoker {
101
    private final MapperMethod mapperMethod;
102

103
    public PlainMethodInvoker(MapperMethod mapperMethod) {
1✔
104
      this.mapperMethod = mapperMethod;
1✔
105
    }
1✔
106

107
    @Override
108
    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
109
      return mapperMethod.execute(sqlSession, args);
1✔
110
    }
111
  }
112

113
  private static class DefaultMethodInvoker implements MapperMethodInvoker {
114
    private final MethodHandle methodHandle;
115

116
    public DefaultMethodInvoker(MethodHandle methodHandle) {
1✔
117
      this.methodHandle = methodHandle;
1✔
118
    }
1✔
119

120
    @Override
121
    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
122
      return methodHandle.bindTo(proxy).invokeWithArguments(args);
1✔
123
    }
124
  }
125
}
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