All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aspectran.core.activity.AdviceActivity Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2025 The Aspectran Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.aspectran.core.activity;

import com.aspectran.core.activity.aspect.AdviceConstraintViolationException;
import com.aspectran.core.activity.aspect.AdviceException;
import com.aspectran.core.activity.aspect.AdviceResult;
import com.aspectran.core.activity.process.action.ActionExecutionException;
import com.aspectran.core.activity.process.action.AnnotatedAdviceAction;
import com.aspectran.core.activity.process.action.Executable;
import com.aspectran.core.activity.process.result.ContentResult;
import com.aspectran.core.activity.process.result.ProcessResult;
import com.aspectran.core.component.aspect.AdviceRulePostRegister;
import com.aspectran.core.component.aspect.AdviceRuleRegistry;
import com.aspectran.core.component.aspect.pointcut.Pointcut;
import com.aspectran.core.context.ActivityContext;
import com.aspectran.core.context.asel.token.TokenEvaluator;
import com.aspectran.core.context.rule.AdviceRule;
import com.aspectran.core.context.rule.AspectRule;
import com.aspectran.core.context.rule.ExceptionRule;
import com.aspectran.core.context.rule.ExceptionThrownRule;
import com.aspectran.core.context.rule.SettingsAdviceRule;
import com.aspectran.core.context.rule.TransletRule;
import com.aspectran.core.context.rule.type.ActionType;
import com.aspectran.core.context.rule.type.AdviceType;
import com.aspectran.core.context.rule.type.MethodType;
import com.aspectran.utils.annotation.jsr305.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Abstract activity for executing advice injected between actions.
 *
 * 

Created: 2016. 9. 10.

*/ public abstract class AdviceActivity extends AbstractActivity { private static final Logger logger = LoggerFactory.getLogger(AdviceActivity.class); private AdviceRuleRegistry adviceRuleRegistry; private Set relevantAspectRules; private Set executedAdviceRules; private AdviceType currentAdviceType; private AdviceRule currentAdviceRule; private AdviceResult adviceResult; /** * Instantiates a new AdviceActivity. * @param context the activity context */ public AdviceActivity(ActivityContext context) { super(context); } @Override @SuppressWarnings("unchecked") public V getSetting(String name) { V value = super.getSetting(name); if (value != null) { return value; } if (adviceRuleRegistry != null && adviceRuleRegistry.getSettingsAdviceRuleList() != null) { for (SettingsAdviceRule settingsAdviceRule : adviceRuleRegistry.getSettingsAdviceRuleList()) { value = settingsAdviceRule.getSetting(name); if (value != null && isAcceptable(settingsAdviceRule.getAspectRule())) { if (value instanceof String str) { return (V)TokenEvaluator.evaluate(str, this); } else { return value; } } } } return null; } protected void prepareAdviceRules(@NonNull TransletRule transletRule, String requestName) { AdviceRuleRegistry adviceRuleRegistryToUse; if (transletRule.hasPathVariables() || getActivityContext().getAspectRuleRegistry().hasNewAspectRules()) { AdviceRulePostRegister postRegister = new AdviceRulePostRegister(); for (AspectRule aspectRule : getActivityContext().getAspectRuleRegistry().getAspectRules()) { if (!aspectRule.isBeanRelevant()) { Pointcut pointcut = aspectRule.getPointcut(); if (pointcut == null || pointcut.matches(requestName)) { postRegister.register(aspectRule); } } } adviceRuleRegistryToUse = postRegister.getAdviceRuleRegistry(); } else { adviceRuleRegistryToUse = transletRule.replicateAdviceRuleRegistry(); } if (adviceRuleRegistryToUse != null) { if (this.adviceRuleRegistry != null) { this.adviceRuleRegistry.merge(adviceRuleRegistryToUse); } else { this.adviceRuleRegistry = adviceRuleRegistryToUse; } } } protected void setCurrentAdviceType(AdviceType adviceType) { this.currentAdviceType = adviceType; } @Override public void registerAdviceRule(AspectRule aspectRule) throws AdviceConstraintViolationException, AdviceException { if (currentAdviceType == null) { AdviceConstraintViolationException ex = new AdviceConstraintViolationException(); String msg = "Advice can not be registered at an UNKNOWN activity phase"; msg = ex.addViolation(aspectRule, msg); logger.error(msg); throw ex; } if (currentAdviceType == AdviceType.THROWN) { AdviceConstraintViolationException ex = new AdviceConstraintViolationException(); String msg = "Advice can not be registered at the THROWN activity phase"; msg = ex.addViolation(aspectRule, msg); logger.error(msg); throw ex; } if (relevantAspectRules != null && relevantAspectRules.contains(aspectRule)) { return; } touchRelevantAspectRules().add(aspectRule); touchAdviceRuleRegistry().register(aspectRule); List adviceRuleList = aspectRule.getAdviceRuleList(); if (adviceRuleList != null) { if (currentAdviceType == AdviceType.FINALLY) { // Exception thrown when registering BEFORE or AFTER advice in the FINALLY activity phase AdviceConstraintViolationException ex = null; for (AdviceRule adviceRule : adviceRuleList) { AdviceType adviceType = adviceRule.getAdviceType(); if (adviceType == AdviceType.BEFORE || adviceType == AdviceType.AFTER) { if (ex == null) { ex = new AdviceConstraintViolationException(); } String msg = "BEFORE or AFTER advice should never be registered after the FINALLY activity phase"; msg = ex.addViolation(aspectRule, msg); if (msg != null) { logger.error(msg); } } } if (ex != null) { throw ex; } } if (currentAdviceRule != null) { AdviceRule adviceRule1 = currentAdviceRule; AdviceType adviceType1 = adviceRule1.getAdviceType(); for (AdviceRule adviceRule2 : adviceRuleList) { AdviceType adviceType2 = adviceRule2.getAdviceType(); if (adviceType1 == adviceType2) { int order1 = adviceRule1.getAspectRule().getOrder(); int order2 = adviceRule2.getAspectRule().getOrder(); if (adviceType1 == AdviceType.BEFORE) { if (order2 < order1) { executeAdvice(adviceRule2); } } else { if (order2 > order1) { executeAdvice(adviceRule2); } } } else if (adviceType2 == AdviceType.BEFORE) { executeAdvice(adviceRule2); } } } else { for (AdviceRule adviceRule : adviceRuleList) { if (adviceRule.getAdviceType() == AdviceType.BEFORE) { executeAdvice(adviceRule); } } } } } @Override public void registerSettingsAdviceRule(SettingsAdviceRule settingsAdviceRule) { if (relevantAspectRules != null && relevantAspectRules.contains(settingsAdviceRule.getAspectRule())) { return; } touchRelevantAspectRules().add(settingsAdviceRule.getAspectRule()); touchAdviceRuleRegistry().addAdviceRule(settingsAdviceRule); } @Override public void executeAdvice(List adviceRuleList) throws AdviceException { if (adviceRuleList != null && !adviceRuleList.isEmpty()) { while (true) { AdviceRule adviceRuleToUse = null; if (executedAdviceRules == null) { adviceRuleToUse = adviceRuleList.get(0); } else { for (AdviceRule adviceRule : adviceRuleList) { if (!executedAdviceRules.contains(adviceRule)) { adviceRuleToUse = adviceRule; break; } } } if (adviceRuleToUse != null) { executeAdvice(adviceRuleToUse); } else { break; } } } } @Override public void executeAdvice(@NonNull AdviceRule adviceRule) throws AdviceException { if (adviceRule.getAspectRule().isDisabled() || !isAcceptable(adviceRule.getAspectRule())) { touchExecutedAdviceRules().add(adviceRule); return; } // for Finally thrown if (isExceptionRaised() && adviceRule.getExceptionRule() != null) { try { handleException(adviceRule.getExceptionRule()); } catch (Exception e) { if (adviceRule.getAspectRule().isIsolated()) { logger.error("Failed to execute isolated advice action {}", adviceRule, e); } else if (adviceRule.getAdviceType() == AdviceType.FINALLY) { logger.error("Failed to execute advice action {}", adviceRule, e); } else { throw new AdviceException("Failed to execute advice action " + adviceRule, adviceRule, e); } } } touchExecutedAdviceRules().add(adviceRule); Executable action = adviceRule.getAdviceAction(); if (action != null) { if (logger.isDebugEnabled()) { logger.debug("Advice {}", AdviceRule.toString(action, adviceRule)); } AdviceRule oldAdviceRule = currentAdviceRule; currentAdviceRule = adviceRule; try { Object adviceBean = getAdviceBean(adviceRule.getAspectId()); if (adviceBean == null) { resolveAdviceBean(adviceRule); } Object resultValue = action.execute(this); if (!action.isHidden() && resultValue != null && resultValue != Void.TYPE) { putAdviceResult(adviceRule, resultValue); if (action.getActionType() == ActionType.ECHO) { if (action.getActionId() != null) { getRequestAdapter().setAttribute(action.getActionId(), resultValue); } else { @SuppressWarnings("unchecked") Map echos = (Map)resultValue; for (Map.Entry item : echos.entrySet()) { getRequestAdapter().setAttribute(item.getKey(), item.getValue()); } } } } } catch (Exception e) { if (adviceRule.getAspectRule().isIsolated()) { logger.error("Failed to execute isolated advice action {}", adviceRule, e); } else { setRaisedException(e); if (adviceRule.getAdviceType() == AdviceType.FINALLY) { logger.error("Failed to execute advice action {}", adviceRule, e); } else { throw new AdviceException("Failed to execute advice action " + adviceRule, adviceRule, e); } } } finally { currentAdviceRule = oldAdviceRule; } } } private boolean isAcceptable(@NonNull AspectRule aspectRule) { if (aspectRule.getMethods() != null) { if (!hasTranslet()) { return false; } MethodType requestMethod = getTranslet().getRequestMethod(); if (requestMethod == null || !requestMethod.containsTo(aspectRule.getMethods())) { return false; } } if (aspectRule.getHeaders() != null) { for (String header : aspectRule.getHeaders()) { if (getRequestAdapter().containsHeader(header)) { return true; } } return false; } return true; } @Override public void handleException(List exceptionRuleList) throws ActionExecutionException { if (exceptionRuleList != null) { for (ExceptionRule exceptionRule : exceptionRuleList) { handleException(exceptionRule); } } } protected ExceptionThrownRule handleException(ExceptionRule exceptionRule) throws ActionExecutionException { if (exceptionRule != null) { ExceptionThrownRule exceptionThrownRule = exceptionRule.getExceptionThrownRule(getRaisedException()); if (exceptionThrownRule != null) { Executable action = exceptionThrownRule.getAction(); if (action != null) { if (logger.isDebugEnabled()) { logger.debug("Advice {}", action); } try { if (action.getActionType() == ActionType.INVOKE_ANNOTATED_ADVICE) { AdviceRule adviceRule = ((AnnotatedAdviceAction)action).getAdviceRule(); Object adviceBean = getAdviceBean(adviceRule.getAspectId()); if (adviceBean == null) { resolveAdviceBean(adviceRule); } } Object resultValue = action.execute(this); if (hasTranslet() && !action.isHidden() && resultValue != Void.TYPE) { if (resultValue instanceof ProcessResult processResult) { getTranslet().setProcessResult(processResult); } else { ProcessResult processResult = getTranslet().getProcessResult(); ContentResult contentResult; if (processResult == null) { processResult = new ProcessResult(1); contentResult = new ContentResult(processResult, 1); getTranslet().setProcessResult(processResult); } else { contentResult = processResult.lastContentResult(); if (contentResult == null) { contentResult = new ContentResult(processResult, 1); } } contentResult.addActionResult(action, resultValue); } } } catch (Exception e) { throw new ActionExecutionException("Failed to execute exception handling advice action " + action, e); } } return exceptionThrownRule; } } return null; } protected List getBeforeAdviceRuleList() { if (adviceRuleRegistry != null) { return adviceRuleRegistry.getBeforeAdviceRuleList(); } else { return null; } } protected List getAfterAdviceRuleList() { if (adviceRuleRegistry != null) { return adviceRuleRegistry.getAfterAdviceRuleList(); } else { return null; } } protected List getFinallyAdviceRuleList() { if (adviceRuleRegistry != null) { return adviceRuleRegistry.getFinallyAdviceRuleList(); } else { return null; } } protected List getExceptionRuleList() { if (adviceRuleRegistry != null) { return adviceRuleRegistry.getExceptionRuleList(); } else { return null; } } /** * Gets the advice bean. * @param the type of the advice bean * @param aspectId the aspect id * @return the advice bean */ @Override @SuppressWarnings("unchecked") public V getAdviceBean(String aspectId) { return (adviceResult != null ? (V) adviceResult.getAdviceBean(aspectId) : null); } /** * Puts the advice bean. * @param aspectId the aspect id * @param adviceBean the advice bean */ private void putAdviceBean(String aspectId, Object adviceBean) { if (adviceResult == null) { adviceResult = new AdviceResult(); } adviceResult.putAdviceBean(aspectId, adviceBean); } private void resolveAdviceBean(@NonNull AdviceRule adviceRule) { Object adviceBean = getAdviceBean(adviceRule.getAspectId()); if (adviceBean == null) { if (adviceRule.getAdviceBeanClass() != null) { try { adviceBean = getBean(adviceRule.getAdviceBeanClass()); } catch (Exception e) { logger.error("Failed to resolve advice bean {}", adviceRule, e); } } else if (adviceRule.getAdviceBeanId() != null) { try { adviceBean = getBean(adviceRule.getAdviceBeanId()); } catch (Exception e) { logger.error("Failed to resolve advice bean {}", adviceRule, e); } } putAdviceBean(adviceRule.getAspectId(), adviceBean); } } /** * Gets the before advice result. * @param the result type of the before advice * @param aspectId the aspect id * @return the before advice result */ @Override @SuppressWarnings("unchecked") public V getBeforeAdviceResult(String aspectId) { return (adviceResult != null ? (V) adviceResult.getBeforeAdviceResult(aspectId) : null); } /** * Gets the after advice result. * @param the result type of the after advice * @param aspectId the aspect id * @return the after advice result */ @Override @SuppressWarnings("unchecked") public V getAfterAdviceResult(String aspectId) { return (adviceResult != null ? (V) adviceResult.getAfterAdviceResult(aspectId) : null); } /** * Gets the around advice result. * @param the result type of the around advice * @param aspectId the aspect id * @return the around advice result */ @Override @SuppressWarnings("unchecked") public V getAroundAdviceResult(String aspectId) { return (adviceResult != null ? (V) adviceResult.getAroundAdviceResult(aspectId) : null); } /** * Gets the final advice result. * @param the result type of the final advice * @param aspectId the aspect id * @return the result of the final advice */ @Override @SuppressWarnings("unchecked") public V getFinallyAdviceResult(String aspectId) { return (adviceResult != null ? (V) adviceResult.getFinallyAdviceResult(aspectId) : null); } /** * Puts the result of the advice. * @param adviceRule the advice rule * @param adviceActionResult the advice action result */ protected void putAdviceResult(AdviceRule adviceRule, Object adviceActionResult) { if (adviceResult == null) { adviceResult = new AdviceResult(); } adviceResult.putAdviceResult(adviceRule, adviceActionResult); } private AdviceRuleRegistry touchAdviceRuleRegistry() { if (adviceRuleRegistry == null) { adviceRuleRegistry = new AdviceRuleRegistry(); } return adviceRuleRegistry; } private Set touchRelevantAspectRules() { if (relevantAspectRules == null) { relevantAspectRules = new HashSet<>(); } return relevantAspectRules; } private Set touchExecutedAdviceRules() { if (executedAdviceRules == null) { executedAdviceRules = new HashSet<>(); } return executedAdviceRules; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy