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

mybatis / mybatis-3 / 2571

01 Jan 2025 07:01AM UTC coverage: 87.397% (+0.04%) from 87.359%
2571

Pull #3372

github

web-flow
Merge d02328e9f into d21e71b56
Pull Request #3372: Drop java8 fallback

3518 of 4265 branches covered (82.49%)

15 of 17 new or added lines in 9 files covered. (88.24%)

6 existing lines in 2 files now uncovered.

9369 of 10720 relevant lines covered (87.4%)

0.87 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-2024 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.",
55
          e);
1✔
56
    }
1✔
57
  }
58

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

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

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

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

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

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

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

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

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

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