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

aspectran / aspectran / #4014

25 Jan 2025 04:30PM CUT coverage: 35.455% (+0.008%) from 35.447%
#4014

push

github

topframe
Update

24 of 52 new or added lines in 13 files covered. (46.15%)

2 existing lines in 2 files now uncovered.

14289 of 40302 relevant lines covered (35.45%)

0.35 hits per line

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

9.44
/core/src/main/java/com/aspectran/core/activity/AdviceActivity.java
1
/*
2
 * Copyright (c) 2008-2025 The Aspectran Project
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
 *     http://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 com.aspectran.core.activity;
17

18
import com.aspectran.core.activity.aspect.AdviceConstraintViolationException;
19
import com.aspectran.core.activity.aspect.AspectAdviceException;
20
import com.aspectran.core.activity.aspect.AspectAdviceResult;
21
import com.aspectran.core.activity.process.action.ActionExecutionException;
22
import com.aspectran.core.activity.process.action.Executable;
23
import com.aspectran.core.activity.process.result.ContentResult;
24
import com.aspectran.core.activity.process.result.ProcessResult;
25
import com.aspectran.core.component.aspect.AspectAdviceRulePostRegister;
26
import com.aspectran.core.component.aspect.AspectAdviceRuleRegistry;
27
import com.aspectran.core.component.aspect.pointcut.Pointcut;
28
import com.aspectran.core.context.ActivityContext;
29
import com.aspectran.core.context.asel.token.TokenEvaluator;
30
import com.aspectran.core.context.rule.AspectAdviceRule;
31
import com.aspectran.core.context.rule.AspectRule;
32
import com.aspectran.core.context.rule.ExceptionRule;
33
import com.aspectran.core.context.rule.ExceptionThrownRule;
34
import com.aspectran.core.context.rule.SettingsAdviceRule;
35
import com.aspectran.core.context.rule.TransletRule;
36
import com.aspectran.core.context.rule.type.ActionType;
37
import com.aspectran.core.context.rule.type.AspectAdviceType;
38
import com.aspectran.core.context.rule.type.MethodType;
39
import com.aspectran.utils.annotation.jsr305.NonNull;
40
import com.aspectran.utils.logging.Logger;
41
import com.aspectran.utils.logging.LoggerFactory;
42

43
import java.util.HashSet;
44
import java.util.List;
45
import java.util.Map;
46
import java.util.Set;
47

48
/**
49
 * Abstract activity for executing advice injected between actions.
50
 *
51
 * <p>Created: 2016. 9. 10.</p>
52
 */
53
public abstract class AdviceActivity extends AbstractActivity {
54

55
    private static final Logger logger = LoggerFactory.getLogger(AdviceActivity.class);
1✔
56

57
    private AspectAdviceRuleRegistry aspectAdviceRuleRegistry;
58

59
    private Set<AspectRule> relevantAspectRules;
60

61
    private Set<AspectAdviceRule> executedAdviceRules;
62

63
    private AspectAdviceType currentAdviceType;
64

65
    private AspectAdviceRule currentAdviceRule;
66

67
    private AspectAdviceResult aspectAdviceResult;
68

69
    /**
70
     * Instantiates a new AdviceActivity.
71
     * @param context the activity context
72
     */
73
    public AdviceActivity(ActivityContext context) {
74
        super(context);
1✔
75
    }
1✔
76

77
    @Override
78
    @SuppressWarnings("unchecked")
79
    public <V> V getSetting(String name) {
80
        V value = super.getSetting(name);
1✔
81
        if (value != null) {
1✔
82
            return value;
1✔
83
        }
84
        if (aspectAdviceRuleRegistry != null && aspectAdviceRuleRegistry.getSettingsAdviceRuleList() != null) {
1✔
85
            for (SettingsAdviceRule settingsAdviceRule : aspectAdviceRuleRegistry.getSettingsAdviceRuleList()) {
×
86
                value = settingsAdviceRule.getSetting(name);
×
87
                if (value != null && isAcceptable(settingsAdviceRule.getAspectRule())) {
×
88
                    if (value instanceof String str) {
×
89
                        return (V)TokenEvaluator.evaluate(str, this);
×
90
                    } else {
91
                        return value;
×
92
                    }
93
                }
94
            }
×
95
        }
96
        return null;
1✔
97
    }
98

99
    protected void prepareAspectAdviceRules(@NonNull TransletRule transletRule, String requestName) {
100
        AspectAdviceRuleRegistry aarr;
101
        if (transletRule.hasPathVariables() || getActivityContext().getAspectRuleRegistry().hasNewAspectRules()) {
1✔
102
            AspectAdviceRulePostRegister postRegister = new AspectAdviceRulePostRegister();
×
103
            for (AspectRule aspectRule : getActivityContext().getAspectRuleRegistry().getAspectRules()) {
×
104
                if (!aspectRule.isBeanRelevant()) {
×
105
                    Pointcut pointcut = aspectRule.getPointcut();
×
106
                    if (pointcut == null || pointcut.matches(requestName)) {
×
107
                        postRegister.register(aspectRule);
×
108
                    }
109
                }
110
            }
×
111
            aarr = postRegister.getAspectAdviceRuleRegistry();
×
112
        } else {
×
113
            aarr = transletRule.replicateAspectAdviceRuleRegistry();
1✔
114
        }
115
        if (aarr != null) {
1✔
116
            if (this.aspectAdviceRuleRegistry != null) {
×
117
                this.aspectAdviceRuleRegistry.merge(aarr);
×
118
            } else {
119
                this.aspectAdviceRuleRegistry = aarr;
×
120
            }
121
        }
122
    }
1✔
123

124
    protected void setCurrentAdviceType(AspectAdviceType aspectAdviceType) {
125
        this.currentAdviceType = aspectAdviceType;
1✔
126
    }
1✔
127

128
    @Override
129
    public void registerAspectAdviceRule(AspectRule aspectRule)
130
            throws AdviceConstraintViolationException, AspectAdviceException {
131
        if (currentAdviceType == null) {
×
132
            AdviceConstraintViolationException ex = new AdviceConstraintViolationException();
×
133
            String msg = "Advice can not be registered at an UNKNOWN activity phase";
×
134
            msg = ex.addViolation(aspectRule, msg);
×
135
            logger.error(msg);
×
136
            throw ex;
×
137
        }
138

139
        if (currentAdviceType == AspectAdviceType.THROWN) {
×
140
            AdviceConstraintViolationException ex = new AdviceConstraintViolationException();
×
141
            String msg = "Advice can not be registered at the THROWN activity phase";
×
142
            msg = ex.addViolation(aspectRule, msg);
×
143
            logger.error(msg);
×
144
            throw ex;
×
145
        }
146

147
        if (relevantAspectRules != null && relevantAspectRules.contains(aspectRule)) {
×
148
            return;
×
149
        }
150

151
        touchRelevantAspectRules().add(aspectRule);
×
152
        touchAspectAdviceRuleRegistry().register(aspectRule);
×
153

154
        List<AspectAdviceRule> aspectAdviceRuleList = aspectRule.getAspectAdviceRuleList();
×
155
        if (aspectAdviceRuleList != null) {
×
156
            if (currentAdviceType == AspectAdviceType.FINALLY) {
×
157
                // Exception thrown when registering BEFORE or AFTER advice in the FINALLY activity phase
158
                AdviceConstraintViolationException ex = null;
×
159
                for (AspectAdviceRule adviceRule : aspectAdviceRuleList) {
×
160
                    AspectAdviceType adviceType = adviceRule.getAspectAdviceType();
×
161
                    if (adviceType == AspectAdviceType.BEFORE || adviceType == AspectAdviceType.AFTER) {
×
162
                        if (ex == null) {
×
163
                            ex = new AdviceConstraintViolationException();
×
164
                        }
165
                        String msg = "BEFORE or AFTER advice should never be registered after the FINALLY activity phase";
×
166
                        msg = ex.addViolation(aspectRule, msg);
×
167
                        if (msg != null) {
×
168
                            logger.error(msg);
×
169
                        }
170
                    }
171
                }
×
172
                if (ex != null) {
×
173
                    throw ex;
×
174
                }
175
            }
176
            if (currentAdviceRule != null) {
×
177
                AspectAdviceRule adviceRule1 = currentAdviceRule;
×
178
                AspectAdviceType adviceType1 = adviceRule1.getAspectAdviceType();
×
179
                for (AspectAdviceRule adviceRule2 : aspectAdviceRuleList) {
×
180
                    AspectAdviceType adviceType2 = adviceRule2.getAspectAdviceType();
×
181
                    if (adviceType1 == adviceType2) {
×
182
                        int order1 = adviceRule1.getAspectRule().getOrder();
×
183
                        int order2 = adviceRule2.getAspectRule().getOrder();
×
184
                        if (adviceType1 == AspectAdviceType.BEFORE) {
×
185
                            if (order2 < order1) {
×
186
                                executeAdvice(adviceRule2, true);
×
187
                            }
188
                        } else {
189
                            if (order2 > order1) {
×
190
                                executeAdvice(adviceRule2, true);
×
191
                            }
192
                        }
193
                    } else if (adviceType2 == AspectAdviceType.BEFORE) {
×
194
                        executeAdvice(adviceRule2, true);
×
195
                    }
196
                }
×
197
            } else {
×
198
                for (AspectAdviceRule aspectAdviceRule : aspectAdviceRuleList) {
×
199
                    if (aspectAdviceRule.getAspectAdviceType() == AspectAdviceType.BEFORE) {
×
200
                        executeAdvice(aspectAdviceRule, true);
×
201
                    }
202
                }
×
203
            }
204
        }
205
    }
×
206

207
    @Override
208
    public void registerSettingsAdviceRule(SettingsAdviceRule settingsAdviceRule) {
209
        if (relevantAspectRules != null && relevantAspectRules.contains(settingsAdviceRule.getAspectRule())) {
×
210
            return;
×
211
        }
212
        touchRelevantAspectRules().add(settingsAdviceRule.getAspectRule());
×
213
        touchAspectAdviceRuleRegistry().addAspectAdviceRule(settingsAdviceRule);
×
214
    }
×
215

216
    @Override
217
    public void executeAdvice(List<AspectAdviceRule> aspectAdviceRuleList, boolean throwable)
218
            throws AspectAdviceException {
219
        if (aspectAdviceRuleList != null && !aspectAdviceRuleList.isEmpty()) {
1✔
220
            while (true) {
221
                AspectAdviceRule target = null;
×
222
                if (executedAdviceRules == null) {
×
223
                    target = aspectAdviceRuleList.get(0);
×
224
                } else {
225
                    for (AspectAdviceRule aspectAdviceRule : aspectAdviceRuleList) {
×
226
                        if (!executedAdviceRules.contains(aspectAdviceRule)) {
×
227
                            target = aspectAdviceRule;
×
228
                            break;
×
229
                        }
230
                    }
×
231
                }
232
                if (target != null) {
×
233
                    executeAdvice(target, throwable);
×
234
                } else {
235
                    break;
236
                }
237
            }
×
238
        }
239
    }
1✔
240

241
    @Override
242
    public void executeAdvice(@NonNull AspectAdviceRule aspectAdviceRule, boolean throwable)
243
            throws AspectAdviceException {
244
        if (aspectAdviceRule.getAspectRule().isDisabled() || !isAcceptable(aspectAdviceRule.getAspectRule())) {
×
245
            touchExecutedAspectAdviceRules().add(aspectAdviceRule);
×
246
            return;
×
247
        }
248

249
        if (isExceptionRaised() && aspectAdviceRule.getExceptionRule() != null) {
×
250
            try {
251
                handleException(aspectAdviceRule.getExceptionRule());
×
252
            } catch (Exception e) {
×
253
                if (aspectAdviceRule.getAspectRule().isIsolated()) {
×
254
                    logger.error("Failed to execute isolated advice action " + aspectAdviceRule, e);
×
255
                } else {
256
                    if (throwable) {
×
257
                        throw new AspectAdviceException("Failed to execute advice action " +
×
258
                                aspectAdviceRule, aspectAdviceRule, e);
259
                    } else {
260
                        logger.error("Failed to execute advice action " + aspectAdviceRule, e);
×
261
                    }
262
                }
263
            }
×
264
        }
265

266
        touchExecutedAspectAdviceRules().add(aspectAdviceRule);
×
267

268
        Executable action = aspectAdviceRule.getAdviceAction();
×
269
        if (action != null) {
×
270
            if (logger.isDebugEnabled()) {
×
271
                logger.debug("Advice " + AspectAdviceRule.toString(action, aspectAdviceRule));
×
272
            }
273

274
            AspectAdviceRule oldAdviceRule = currentAdviceRule;
×
275
            currentAdviceRule = aspectAdviceRule;
×
276
            try {
277
                Object adviceBean = getAspectAdviceBean(aspectAdviceRule.getAspectId());
×
278
                if (adviceBean == null) {
×
279
                    if (aspectAdviceRule.getAdviceBeanClass() != null) {
×
280
                        try {
NEW
281
                            adviceBean = getBean(aspectAdviceRule.getAdviceBeanClass());
×
NEW
282
                        } catch (Exception e) {
×
NEW
283
                            logger.error("Failed to load advice bean " + aspectAdviceRule, e);
×
NEW
284
                        }
×
285
                    } else if (aspectAdviceRule.getAdviceBeanId() != null) {
×
286
                        try {
NEW
287
                            adviceBean = getBean(aspectAdviceRule.getAdviceBeanId());
×
NEW
288
                        } catch (Exception e) {
×
NEW
289
                            logger.error("Failed to load advice bean " + aspectAdviceRule, e);
×
NEW
290
                        }
×
291
                    }
292
                    putAspectAdviceBean(aspectAdviceRule.getAspectId(), adviceBean);
×
293
                }
294

295
                Object resultValue = action.execute(this);
×
296
                if (!action.isHidden() && resultValue != null && resultValue != Void.TYPE) {
×
297
                    putAspectAdviceResult(aspectAdviceRule, resultValue);
×
298
                    if (action.getActionType() == ActionType.ECHO) {
×
299
                        if (action.getActionId() != null) {
×
300
                            getRequestAdapter().setAttribute(action.getActionId(), resultValue);
×
301
                        } else {
302
                            @SuppressWarnings("unchecked")
303
                            Map<String, Object> echos = (Map<String, Object>)resultValue;
×
304
                            for (Map.Entry<String, Object> item : echos.entrySet()) {
×
305
                                getRequestAdapter().setAttribute(item.getKey(), item.getValue());
×
306
                            }
×
307
                        }
308
                    }
309
                }
310
            } catch (Exception e) {
×
311
                if (aspectAdviceRule.getAspectRule().isIsolated()) {
×
312
                    logger.error("Failed to execute isolated advice action " + aspectAdviceRule, e);
×
313
                } else {
314
                    setRaisedException(e);
×
315
                    if (throwable) {
×
316
                        throw new AspectAdviceException("Failed to execute advice action " +
×
317
                                aspectAdviceRule, aspectAdviceRule, e);
318
                    } else {
319
                        logger.error("Failed to execute advice action " + aspectAdviceRule, e);
×
320
                    }
321
                }
322
            } finally {
323
                currentAdviceRule = oldAdviceRule;
×
324
            }
325
        }
326
    }
×
327

328
    private boolean isAcceptable(@NonNull AspectRule aspectRule) {
329
        if (aspectRule.getMethods() != null) {
×
330
            if (!hasTranslet()) {
×
331
                return false;
×
332
            }
333
            MethodType requestMethod = getTranslet().getRequestMethod();
×
334
            if (requestMethod == null || !requestMethod.containsTo(aspectRule.getMethods())) {
×
335
                return false;
×
336
            }
337
        }
338
        if (aspectRule.getHeaders() != null) {
×
339
            for (String header : aspectRule.getHeaders()) {
×
340
                if (getRequestAdapter().containsHeader(header)) {
×
341
                    return true;
×
342
                }
343
            }
344
            return false;
×
345
        }
346
        return true;
×
347
    }
348

349
    @Override
350
    public void handleException(List<ExceptionRule> exceptionRuleList) throws ActionExecutionException {
351
        if (exceptionRuleList != null) {
×
352
            for (ExceptionRule exceptionRule : exceptionRuleList) {
×
353
                handleException(exceptionRule);
×
354
            }
×
355
        }
356
    }
×
357

358
    protected ExceptionThrownRule handleException(ExceptionRule exceptionRule) throws ActionExecutionException {
359
        if (exceptionRule != null) {
×
360
            ExceptionThrownRule exceptionThrownRule = exceptionRule.getExceptionThrownRule(getRaisedException());
×
361
            if (exceptionThrownRule != null) {
×
362
                Executable action = exceptionThrownRule.getAction();
×
363
                if (action != null) {
×
364
                    if (logger.isDebugEnabled()) {
×
365
                        logger.debug("Advice " + action);
×
366
                    }
367
                    try {
368
                        Object resultValue = action.execute(this);
×
369
                        if (hasTranslet() && !action.isHidden() && resultValue != Void.TYPE) {
×
370
                            if (resultValue instanceof ProcessResult processResult) {
×
371
                                getTranslet().setProcessResult(processResult);
×
372
                            } else {
373
                                ProcessResult processResult = getTranslet().getProcessResult();
×
374
                                ContentResult contentResult;
375
                                if (processResult == null) {
×
376
                                    processResult = new ProcessResult(1);
×
377
                                    contentResult = new ContentResult(processResult, 1);
×
378
                                    getTranslet().setProcessResult(processResult);
×
379
                                } else {
380
                                    contentResult = processResult.lastContentResult();
×
381
                                    if (contentResult == null) {
×
382
                                        contentResult = new ContentResult(processResult, 1);
×
383
                                    }
384
                                }
385
                                contentResult.addActionResult(action, resultValue);
×
386
                            }
387
                        }
388
                    } catch (Exception e) {
×
389
                        setRaisedException(e);
×
390
                        throw new ActionExecutionException("Failed to execute exception handling advice action " +
×
391
                                action, e);
392
                    }
×
393
                }
394
                return exceptionThrownRule;
×
395
            }
396
        }
397
        return null;
×
398
    }
399

400
    protected List<AspectAdviceRule> getBeforeAdviceRuleList() {
401
        if (aspectAdviceRuleRegistry != null) {
1✔
402
            return aspectAdviceRuleRegistry.getBeforeAdviceRuleList();
×
403
        } else {
404
            return null;
1✔
405
        }
406
    }
407

408
    protected List<AspectAdviceRule> getAfterAdviceRuleList() {
409
        if (aspectAdviceRuleRegistry != null) {
1✔
410
            return aspectAdviceRuleRegistry.getAfterAdviceRuleList();
×
411
        } else {
412
            return null;
1✔
413
        }
414
    }
415

416
    protected List<AspectAdviceRule> getFinallyAdviceRuleList() {
417
        if (aspectAdviceRuleRegistry != null) {
1✔
418
            return aspectAdviceRuleRegistry.getFinallyAdviceRuleList();
×
419
        } else {
420
            return null;
1✔
421
        }
422
    }
423

424
    protected List<ExceptionRule> getExceptionRuleList() {
425
        if (aspectAdviceRuleRegistry != null) {
×
426
            return aspectAdviceRuleRegistry.getExceptionRuleList();
×
427
        } else {
428
            return null;
×
429
        }
430
    }
431

432
    /**
433
     * Gets the aspect advice bean.
434
     * @param <V> the type of the advice bean
435
     * @param aspectId the aspect id
436
     * @return the aspect advice bean
437
     */
438
    @Override
439
    @SuppressWarnings("unchecked")
440
    public <V> V getAspectAdviceBean(String aspectId) {
441
        return (aspectAdviceResult != null ? (V)aspectAdviceResult.getAspectAdviceBean(aspectId) : null);
×
442
    }
443

444
    /**
445
     * Puts the aspect advice bean.
446
     * @param aspectId the aspect id
447
     * @param adviceBean the advice bean
448
     */
449
    protected void putAspectAdviceBean(String aspectId, Object adviceBean) {
450
        if (aspectAdviceResult == null) {
×
451
            aspectAdviceResult = new AspectAdviceResult();
×
452
        }
453
        aspectAdviceResult.putAspectAdviceBean(aspectId, adviceBean);
×
454
    }
×
455

456
    /**
457
     * Gets the before advice result.
458
     * @param <V> the result type of the before advice
459
     * @param aspectId the aspect id
460
     * @return the before advice result
461
     */
462
    @Override
463
    @SuppressWarnings("unchecked")
464
    public <V> V getBeforeAdviceResult(String aspectId) {
465
        return (aspectAdviceResult != null ? (V)aspectAdviceResult.getBeforeAdviceResult(aspectId) : null);
×
466
    }
467

468
    /**
469
     * Gets the after advice result.
470
     * @param <V> the result type of the after advice
471
     * @param aspectId the aspect id
472
     * @return the after advice result
473
     */
474
    @Override
475
    @SuppressWarnings("unchecked")
476
    public <V> V getAfterAdviceResult(String aspectId) {
477
        return (aspectAdviceResult != null ? (V)aspectAdviceResult.getAfterAdviceResult(aspectId) : null);
×
478
    }
479

480
    /**
481
     * Gets the around advice result.
482
     * @param <V> the result type of the around advice
483
     * @param aspectId the aspect id
484
     * @return the around advice result
485
     */
486
    @Override
487
    @SuppressWarnings("unchecked")
488
    public <V> V getAroundAdviceResult(String aspectId) {
489
        return (aspectAdviceResult != null ? (V)aspectAdviceResult.getAroundAdviceResult(aspectId) : null);
×
490
    }
491

492
    /**
493
     * Gets the final advice result.
494
     * @param <V> the result type of the final advice
495
     * @param aspectId the aspect id
496
     * @return the result of the final advice
497
     */
498
    @Override
499
    @SuppressWarnings("unchecked")
500
    public <V> V getFinallyAdviceResult(String aspectId) {
501
        return (aspectAdviceResult != null ? (V)aspectAdviceResult.getFinallyAdviceResult(aspectId) : null);
×
502
    }
503

504
    /**
505
     * Puts the result of the advice.
506
     * @param aspectAdviceRule the aspect advice rule
507
     * @param adviceActionResult the advice action result
508
     */
509
    protected void putAspectAdviceResult(AspectAdviceRule aspectAdviceRule, Object adviceActionResult) {
510
        if (aspectAdviceResult == null) {
×
511
            aspectAdviceResult = new AspectAdviceResult();
×
512
        }
513
        aspectAdviceResult.putAspectAdviceResult(aspectAdviceRule, adviceActionResult);
×
514
    }
×
515

516
    private AspectAdviceRuleRegistry touchAspectAdviceRuleRegistry() {
517
        if (aspectAdviceRuleRegistry == null) {
×
518
            aspectAdviceRuleRegistry = new AspectAdviceRuleRegistry();
×
519
        }
520
        return aspectAdviceRuleRegistry;
×
521
    }
522

523
    private Set<AspectRule> touchRelevantAspectRules() {
524
        if (relevantAspectRules == null) {
×
525
            relevantAspectRules = new HashSet<>();
×
526
        }
527
        return relevantAspectRules;
×
528
    }
529

530
    private Set<AspectAdviceRule> touchExecutedAspectAdviceRules() {
531
        if (executedAdviceRules == null) {
×
532
            executedAdviceRules = new HashSet<>();
×
533
        }
534
        return executedAdviceRules;
×
535
    }
536

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