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

mybatis / mybatis-3 / #3369

09 Dec 2023 10:12PM CUT coverage: 86.597%. Remained the same
#3369

push

github

web-flow
Merge pull request #3035 from hazendaz/master

[ognl] Update to 3.4.2 along with Map to OgnlContext changes

3492 of 4271 branches covered (0.0%)

1 of 1 new or added line in 1 file covered. (100.0%)

9278 of 10714 relevant lines covered (86.6%)

0.87 hits per line

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

0.0
/src/main/java/org/apache/ibatis/executor/loader/cglib/CglibProxyFactory.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.cglib;
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 net.sf.cglib.proxy.Callback;
24
import net.sf.cglib.proxy.Enhancer;
25
import net.sf.cglib.proxy.MethodInterceptor;
26
import net.sf.cglib.proxy.MethodProxy;
27

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

42
/**
43
 * @author Clinton Begin
44
 *
45
 * @deprecated Since 3.5.10, use Javassist instead.
46
 */
47
@Deprecated
48
public class CglibProxyFactory implements ProxyFactory {
49

50
  private static final String FINALIZE_METHOD = "finalize";
51
  private static final String WRITE_REPLACE_METHOD = "writeReplace";
52

53
  public CglibProxyFactory() {
×
54
    try {
55
      Resources.classForName("net.sf.cglib.proxy.Enhancer");
×
56
    } catch (Throwable e) {
×
57
      throw new IllegalStateException(
×
58
          "Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath.", e);
59
    }
×
60
  }
×
61

62
  @Override
63
  public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration,
64
      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
65
    return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory,
×
66
        constructorArgTypes, constructorArgs);
67
  }
68

69
  public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
70
      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
71
    return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes,
×
72
        constructorArgs);
73
  }
74

75
  static Object createStaticProxy(Class<?> type, Callback callback, List<Class<?>> constructorArgTypes,
76
      List<Object> constructorArgs) {
77
    LogHolder.log.warn("CglibProxyFactory is deprecated. Use another proxy factory implementation.");
×
78
    Enhancer enhancer = new Enhancer();
×
79
    enhancer.setCallback(callback);
×
80
    enhancer.setSuperclass(type);
×
81
    try {
82
      type.getDeclaredMethod(WRITE_REPLACE_METHOD);
×
83
      // ObjectOutputStream will call writeReplace of objects returned by writeReplace
84
      if (LogHolder.log.isDebugEnabled()) {
×
85
        LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
×
86
      }
87
    } catch (NoSuchMethodException e) {
×
88
      enhancer.setInterfaces(new Class[] { WriteReplaceInterface.class });
×
89
    } catch (SecurityException e) {
×
90
      // nothing to do here
91
    }
×
92
    Object enhanced;
93
    if (constructorArgTypes.isEmpty()) {
×
94
      enhanced = enhancer.create();
×
95
    } else {
96
      Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
×
97
      Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
×
98
      enhanced = enhancer.create(typesArray, valuesArray);
×
99
    }
100
    return enhanced;
×
101
  }
102

103
  private static class EnhancedResultObjectProxyImpl implements MethodInterceptor {
104

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

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

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

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

175
  private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy
176
      implements MethodInterceptor {
177

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

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

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

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

208
  private static class LogHolder {
209
    private static final Log log = LogFactory.getLog(CglibProxyFactory.class);
×
210
  }
211

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