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

mybatis / mybatis-3 / #2968

pending completion
#2968

push

github

web-flow
Merge pull request #2792 from hazendaz/formatting

[ci] Formatting

84 of 84 new or added lines in 23 files covered. (100.0%)

9412 of 10781 relevant lines covered (87.3%)

0.87 hits per line

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

89.19
/src/main/java/org/apache/ibatis/executor/loader/javassist/JavassistProxyFactory.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.apache.ibatis.executor.loader.javassist;
17

18
import java.lang.reflect.Method;
19
import java.util.List;
20
import java.util.Map;
21
import java.util.Set;
22

23
import javassist.util.proxy.MethodHandler;
24
import javassist.util.proxy.Proxy;
25
import javassist.util.proxy.ProxyFactory;
26

27
import org.apache.ibatis.executor.ExecutorException;
28
import org.apache.ibatis.executor.loader.AbstractEnhancedDeserializationProxy;
29
import org.apache.ibatis.executor.loader.AbstractSerialStateHolder;
30
import org.apache.ibatis.executor.loader.ResultLoaderMap;
31
import org.apache.ibatis.executor.loader.WriteReplaceInterface;
32
import org.apache.ibatis.io.Resources;
33
import org.apache.ibatis.logging.Log;
34
import org.apache.ibatis.logging.LogFactory;
35
import org.apache.ibatis.reflection.ExceptionUtil;
36
import org.apache.ibatis.reflection.factory.ObjectFactory;
37
import org.apache.ibatis.reflection.property.PropertyCopier;
38
import org.apache.ibatis.reflection.property.PropertyNamer;
39
import org.apache.ibatis.session.Configuration;
40

41
/**
42
 * @author Eduardo Macarron
43
 */
44
public class JavassistProxyFactory implements org.apache.ibatis.executor.loader.ProxyFactory {
45

46
  private static final String FINALIZE_METHOD = "finalize";
47
  private static final String WRITE_REPLACE_METHOD = "writeReplace";
48

49
  public JavassistProxyFactory() {
1✔
50
    try {
51
      Resources.classForName("javassist.util.proxy.ProxyFactory");
1✔
52
    } catch (Throwable e) {
×
53
      throw new IllegalStateException(
×
54
          "Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.", e);
55
    }
1✔
56
  }
1✔
57

58
  @Override
59
  public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration,
60
      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
61
    return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory,
1✔
62
        constructorArgTypes, constructorArgs);
63
  }
64

65
  public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
66
      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
67
    return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes,
1✔
68
        constructorArgs);
69
  }
70

71
  static Object createStaticProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes,
72
      List<Object> constructorArgs) {
73

74
    ProxyFactory enhancer = new ProxyFactory();
1✔
75
    enhancer.setSuperclass(type);
1✔
76

77
    try {
78
      type.getDeclaredMethod(WRITE_REPLACE_METHOD);
1✔
79
      // ObjectOutputStream will call writeReplace of objects returned by writeReplace
80
      if (LogHolder.log.isDebugEnabled()) {
1✔
81
        LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
×
82
      }
83
    } catch (NoSuchMethodException e) {
1✔
84
      enhancer.setInterfaces(new Class[] { WriteReplaceInterface.class });
1✔
85
    } catch (SecurityException e) {
×
86
      // nothing to do here
87
    }
1✔
88

89
    Object enhanced;
90
    Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
1✔
91
    Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
1✔
92
    try {
93
      enhanced = enhancer.create(typesArray, valuesArray);
1✔
94
    } catch (Exception e) {
×
95
      throw new ExecutorException("Error creating lazy proxy.  Cause: " + e, e);
×
96
    }
1✔
97
    ((Proxy) enhanced).setHandler(callback);
1✔
98
    return enhanced;
1✔
99
  }
100

101
  private static class EnhancedResultObjectProxyImpl implements MethodHandler {
102

103
    private final Class<?> type;
104
    private final ResultLoaderMap lazyLoader;
105
    private final boolean aggressive;
106
    private final Set<String> lazyLoadTriggerMethods;
107
    private final ObjectFactory objectFactory;
108
    private final List<Class<?>> constructorArgTypes;
109
    private final List<Object> constructorArgs;
110

111
    private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration,
112
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
1✔
113
      this.type = type;
1✔
114
      this.lazyLoader = lazyLoader;
1✔
115
      this.aggressive = configuration.isAggressiveLazyLoading();
1✔
116
      this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
1✔
117
      this.objectFactory = objectFactory;
1✔
118
      this.constructorArgTypes = constructorArgTypes;
1✔
119
      this.constructorArgs = constructorArgs;
1✔
120
    }
1✔
121

122
    public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration,
123
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
124
      final Class<?> type = target.getClass();
1✔
125
      EnhancedResultObjectProxyImpl callback = new EnhancedResultObjectProxyImpl(type, lazyLoader, configuration,
1✔
126
          objectFactory, constructorArgTypes, constructorArgs);
127
      Object enhanced = createStaticProxy(type, callback, constructorArgTypes, constructorArgs);
1✔
128
      PropertyCopier.copyBeanProperties(type, target, enhanced);
1✔
129
      return enhanced;
1✔
130
    }
131

132
    @Override
133
    public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
134
      final String methodName = method.getName();
1✔
135
      try {
136
        synchronized (lazyLoader) {
1✔
137
          if (WRITE_REPLACE_METHOD.equals(methodName)) {
1✔
138
            Object original;
139
            if (constructorArgTypes.isEmpty()) {
1✔
140
              original = objectFactory.create(type);
1✔
141
            } else {
142
              original = objectFactory.create(type, constructorArgTypes, constructorArgs);
1✔
143
            }
144
            PropertyCopier.copyBeanProperties(type, enhanced, original);
1✔
145
            if (lazyLoader.size() > 0) {
1✔
146
              return new JavassistSerialStateHolder(original, lazyLoader.getProperties(), objectFactory,
1✔
147
                  constructorArgTypes, constructorArgs);
148
            } else {
149
              return original;
1✔
150
            }
151
          } else {
152
            if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
1✔
153
              if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
1✔
154
                lazyLoader.loadAll();
1✔
155
              } else if (PropertyNamer.isSetter(methodName)) {
1✔
156
                final String property = PropertyNamer.methodToProperty(methodName);
1✔
157
                lazyLoader.remove(property);
1✔
158
              } else if (PropertyNamer.isGetter(methodName)) {
1✔
159
                final String property = PropertyNamer.methodToProperty(methodName);
1✔
160
                if (lazyLoader.hasLoader(property)) {
1✔
161
                  lazyLoader.load(property);
1✔
162
                }
163
              }
164
            }
165
          }
166
        }
1✔
167
        return methodProxy.invoke(enhanced, args);
1✔
168
      } catch (Throwable t) {
×
169
        throw ExceptionUtil.unwrapThrowable(t);
×
170
      }
171
    }
172
  }
173

174
  private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy
175
      implements MethodHandler {
176

177
    private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
178
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
179
      super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
1✔
180
    }
1✔
181

182
    public static Object createProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
183
        ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
184
      final Class<?> type = target.getClass();
1✔
185
      EnhancedDeserializationProxyImpl callback = new EnhancedDeserializationProxyImpl(type, unloadedProperties,
1✔
186
          objectFactory, constructorArgTypes, constructorArgs);
187
      Object enhanced = createStaticProxy(type, callback, constructorArgTypes, constructorArgs);
1✔
188
      PropertyCopier.copyBeanProperties(type, target, enhanced);
1✔
189
      return enhanced;
1✔
190
    }
191

192
    @Override
193
    public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
194
      final Object o = super.invoke(enhanced, method, args);
1✔
195
      return o instanceof AbstractSerialStateHolder ? o : methodProxy.invoke(o, args);
1✔
196
    }
197

198
    @Override
199
    protected AbstractSerialStateHolder newSerialStateHolder(Object userBean,
200
        Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
201
        List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
202
      return new JavassistSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes,
1✔
203
          constructorArgs);
204
    }
205
  }
206

207
  private static class LogHolder {
208
    private static final Log log = LogFactory.getLog(JavassistProxyFactory.class);
1✔
209
  }
210

211
}
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