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

alibaba / jetcache / #405

16 Apr 2024 05:58AM UTC coverage: 0.0% (-88.9%) from 88.866%
#405

push

areyouok
add encoding to fix coverage report

0 of 5353 relevant lines covered (0.0%)

0.0 hits per line

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

0.0
/jetcache-anno/src/main/java/com/alicp/jetcache/anno/method/CacheHandler.java
1
/**
2
 * Created on  13-09-09 15:59
3
 */
4
package com.alicp.jetcache.anno.method;
5

6
import com.alicp.jetcache.AbstractCache;
7
import com.alicp.jetcache.Cache;
8
import com.alicp.jetcache.CacheInvokeException;
9
import com.alicp.jetcache.CacheLoader;
10
import com.alicp.jetcache.ProxyCache;
11
import com.alicp.jetcache.anno.support.CacheContext;
12
import com.alicp.jetcache.anno.support.CacheInvalidateAnnoConfig;
13
import com.alicp.jetcache.anno.support.CacheUpdateAnnoConfig;
14
import com.alicp.jetcache.anno.support.CachedAnnoConfig;
15
import com.alicp.jetcache.anno.support.ConfigMap;
16
import com.alicp.jetcache.event.CacheLoadEvent;
17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19

20
import java.lang.reflect.Array;
21
import java.lang.reflect.InvocationHandler;
22
import java.lang.reflect.Method;
23
import java.util.ArrayList;
24
import java.util.Arrays;
25
import java.util.HashMap;
26
import java.util.HashSet;
27
import java.util.List;
28
import java.util.Map;
29
import java.util.Set;
30
import java.util.function.Supplier;
31

32
/**
33
 * @author huangli
34
 */
35
public class CacheHandler implements InvocationHandler {
36
    private static Logger logger = LoggerFactory.getLogger(CacheHandler.class);
×
37

38
    private Object src;
39
    private Supplier<CacheInvokeContext> contextSupplier;
40
    private String[] hiddenPackages;
41
    private ConfigMap configMap;
42

43
    private static class CacheContextSupport extends CacheContext {
44

45
        public CacheContextSupport() {
46
            super(null, null, null);
×
47
        }
×
48

49
        static void _enable() {
50
            enable();
×
51
        }
×
52

53
        static void _disable() {
54
            disable();
×
55
        }
×
56

57
        static boolean _isEnabled() {
58
            return isEnabled();
×
59
        }
60
    }
61

62
    public CacheHandler(Object src, ConfigMap configMap, Supplier<CacheInvokeContext> contextSupplier, String[] hiddenPackages) {
×
63
        this.src = src;
×
64
        this.configMap = configMap;
×
65
        this.contextSupplier = contextSupplier;
×
66
        this.hiddenPackages = hiddenPackages;
×
67
    }
×
68

69
    @Override
70
    public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
71
        CacheInvokeContext context = null;
×
72

73
        String sig = ClassUtil.getMethodSig(method);
×
74
        CacheInvokeConfig cac = configMap.getByMethodInfo(sig);
×
75
        if (cac != null) {
×
76
            context = contextSupplier.get();
×
77
            context.setCacheInvokeConfig(cac);
×
78
        }
79
        if (context == null) {
×
80
            return method.invoke(src, args);
×
81
        } else {
82
            context.setInvoker(() -> method.invoke(src, args));
×
83
            context.setHiddenPackages(hiddenPackages);
×
84
            context.setArgs(args);
×
85
            context.setMethod(method);
×
86
            return invoke(context);
×
87
        }
88
    }
89

90
    public static Object invoke(CacheInvokeContext context) throws Throwable {
91
        if (context.getCacheInvokeConfig().isEnableCacheContext()) {
×
92
            try {
93
                CacheContextSupport._enable();
×
94
                return doInvoke(context);
×
95
            } finally {
96
                CacheContextSupport._disable();
×
97
            }
98
        } else {
99
            return doInvoke(context);
×
100
        }
101
    }
102

103
    private static Object doInvoke(CacheInvokeContext context) throws Throwable {
104
        CacheInvokeConfig cic = context.getCacheInvokeConfig();
×
105
        CachedAnnoConfig cachedConfig = cic.getCachedAnnoConfig();
×
106
        if (cachedConfig != null && (cachedConfig.isEnabled() || CacheContextSupport._isEnabled())) {
×
107
            return invokeWithCached(context);
×
108
        } else if (cic.getInvalidateAnnoConfigs() != null || cic.getUpdateAnnoConfig() != null) {
×
109
            return invokeWithInvalidateOrUpdate(context);
×
110
        } else {
111
            return invokeOrigin(context);
×
112
        }
113
    }
114

115
    private static Object invokeWithInvalidateOrUpdate(CacheInvokeContext context) throws Throwable {
116
        Object originResult = invokeOrigin(context);
×
117
        context.setResult(originResult);
×
118
        CacheInvokeConfig cic = context.getCacheInvokeConfig();
×
119

120
        if (cic.getInvalidateAnnoConfigs() != null) {
×
121
            doInvalidate(context, cic.getInvalidateAnnoConfigs());
×
122
        }
123
        CacheUpdateAnnoConfig updateAnnoConfig = cic.getUpdateAnnoConfig();
×
124
        if (updateAnnoConfig != null) {
×
125
            doUpdate(context, updateAnnoConfig);
×
126
        }
127

128
        return originResult;
×
129
    }
130

131
    private static Iterable toIterable(Object obj) {
132
        if (obj.getClass().isArray()) {
×
133
            if (obj instanceof Object[]) {
×
134
                return Arrays.asList((Object[]) obj);
×
135
            } else {
136
                List list = new ArrayList();
×
137
                int len = Array.getLength(obj);
×
138
                for (int i = 0; i < len; i++) {
×
139
                    list.add(Array.get(obj, i));
×
140
                }
141
                return list;
×
142
            }
143
        } else if (obj instanceof Iterable) {
×
144
            return (Iterable) obj;
×
145
        } else {
146
            return null;
×
147
        }
148
    }
149

150
    private static void doInvalidate(CacheInvokeContext context, List<CacheInvalidateAnnoConfig> annoConfig) {
151
        for (CacheInvalidateAnnoConfig config : annoConfig) {
×
152
            doInvalidate(context, config);
×
153
        }
×
154
    }
×
155

156
    private static void doInvalidate(CacheInvokeContext context, CacheInvalidateAnnoConfig annoConfig) {
157
        Cache cache = context.getCacheFunction().apply(context, annoConfig);
×
158
        if (cache == null) {
×
159
            return;
×
160
        }
161
        boolean condition = ExpressionUtil.evalCondition(context, annoConfig);
×
162
        if (!condition) {
×
163
            return;
×
164
        }
165
        Object key = ExpressionUtil.evalKey(context, annoConfig);
×
166
        if (key == null) {
×
167
            return;
×
168
        }
169
        if (annoConfig.isMulti()) {
×
170
            Iterable it = toIterable(key);
×
171
            if (it == null) {
×
172
                logger.error("jetcache @CacheInvalidate key is not instance of Iterable or array: " + annoConfig.getDefineMethod());
×
173
                return;
×
174
            }
175
            Set keys = new HashSet();
×
176
            it.forEach(k -> keys.add(k));
×
177
            cache.removeAll(keys);
×
178
        } else {
×
179
            cache.remove(key);
×
180
        }
181
    }
×
182

183
    private static void doUpdate(CacheInvokeContext context, CacheUpdateAnnoConfig updateAnnoConfig) {
184
        Cache cache = context.getCacheFunction().apply(context, updateAnnoConfig);
×
185
        if (cache == null) {
×
186
            return;
×
187
        }
188
        boolean condition = ExpressionUtil.evalCondition(context, updateAnnoConfig);
×
189
        if (!condition) {
×
190
            return;
×
191
        }
192
        Object key = ExpressionUtil.evalKey(context, updateAnnoConfig);
×
193
        Object value = ExpressionUtil.evalValue(context, updateAnnoConfig);
×
194
        if (key == null || value == ExpressionUtil.EVAL_FAILED) {
×
195
            return;
×
196
        }
197
        if (updateAnnoConfig.isMulti()) {
×
198
            if (value == null) {
×
199
                return;
×
200
            }
201
            Iterable keyIt = toIterable(key);
×
202
            Iterable valueIt = toIterable(value);
×
203
            if (keyIt == null) {
×
204
                logger.error("jetcache @CacheUpdate key is not instance of Iterable or array: " + updateAnnoConfig.getDefineMethod());
×
205
                return;
×
206
            }
207
            if (valueIt == null) {
×
208
                logger.error("jetcache @CacheUpdate value is not instance of Iterable or array: " + updateAnnoConfig.getDefineMethod());
×
209
                return;
×
210
            }
211

212
            List keyList = new ArrayList();
×
213
            List valueList = new ArrayList();
×
214
            keyIt.forEach(o -> keyList.add(o));
×
215
            valueIt.forEach(o -> valueList.add(o));
×
216
            if (keyList.size() != valueList.size()) {
×
217
                logger.error("jetcache @CacheUpdate key size not equals with value size: " + updateAnnoConfig.getDefineMethod());
×
218
                return;
×
219
            } else {
220
                Map m = new HashMap();
×
221
                for (int i = 0; i < valueList.size(); i++) {
×
222
                    m.put(keyList.get(i), valueList.get(i));
×
223
                }
224
                cache.putAll(m);
×
225
            }
226
        } else {
×
227
            cache.put(key, value);
×
228
        }
229
    }
×
230

231
    private static Object invokeWithCached(CacheInvokeContext context)
232
            throws Throwable {
233
        CacheInvokeConfig cic = context.getCacheInvokeConfig();
×
234
        CachedAnnoConfig cac = cic.getCachedAnnoConfig();
×
235
        Cache cache = context.getCacheFunction().apply(context, cac);
×
236
        if (cache == null) {
×
237
            logger.error("no cache with name: " + context.getMethod());
×
238
            return invokeOrigin(context);
×
239
        }
240

241
        Object key = ExpressionUtil.evalKey(context, cic.getCachedAnnoConfig());
×
242
        if (key == null) {
×
243
            return loadAndCount(context, cache, key);
×
244
        }
245

246
        if (!ExpressionUtil.evalCondition(context, cic.getCachedAnnoConfig())) {
×
247
            return loadAndCount(context, cache, key);
×
248
        }
249

250
        try {
251
            CacheLoader loader = new CacheLoader() {
×
252
                @Override
253
                public Object load(Object k) throws Throwable {
254
                    Object result = invokeOrigin(context);
×
255
                    context.setResult(result);
×
256
                    return result;
×
257
                }
258

259
                @Override
260
                public boolean vetoCacheUpdate() {
261
                    return !ExpressionUtil.evalPostCondition(context, cic.getCachedAnnoConfig());
×
262
                }
263
            };
264
            Object result = cache.computeIfAbsent(key, loader);
×
265
            return result;
×
266
        } catch (CacheInvokeException e) {
×
267
            throw e.getCause();
×
268
        }
269
    }
270

271
    private static Object loadAndCount(CacheInvokeContext context, Cache cache, Object key) throws Throwable {
272
        long t = System.currentTimeMillis();
×
273
        Object v = null;
×
274
        boolean success = false;
×
275
        try {
276
            v = invokeOrigin(context);
×
277
            success = true;
×
278
        } finally {
279
            t = System.currentTimeMillis() - t;
×
280
            CacheLoadEvent event = new CacheLoadEvent(cache, t, key, v, success);
×
281
            while (cache instanceof ProxyCache) {
×
282
                cache = ((ProxyCache) cache).getTargetCache();
×
283
            }
284
            if (cache instanceof AbstractCache) {
×
285
                ((AbstractCache) cache).notify(event);
×
286
            }
287
        }
288
        return v;
×
289
    }
290

291
    private static Object invokeOrigin(CacheInvokeContext context) throws Throwable {
292
        return context.getInvoker().invoke();
×
293
    }
294

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

© 2026 Coveralls, Inc