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

com.aspectran.core.context.asel.TokenizedExpression Maven / Gradle / Ivy

There is a newer version: 8.1.5
Show 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.context.asel;

import com.aspectran.core.activity.Activity;
import com.aspectran.core.context.asel.token.Token;
import com.aspectran.core.context.asel.token.TokenEvaluator;
import com.aspectran.core.context.asel.token.TokenParser;
import com.aspectran.core.context.rule.type.TokenType;
import com.aspectran.utils.Assert;
import com.aspectran.utils.StringUtils;
import com.aspectran.utils.ToStringBuilder;
import com.aspectran.utils.annotation.jsr305.NonNull;
import com.aspectran.utils.annotation.jsr305.Nullable;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 

Created: 2024. 11. 26.

*/ public class TokenizedExpression implements ExpressionEvaluator { private static final String TOKEN_VAR_REF_SYMBOL = "#"; private static final String TOKEN_VAR_NAME_PREFIX = "__"; private static final String TOKEN_VAR_NAME_SUFFIX = TOKEN_VAR_NAME_PREFIX; private final String expression; private String substitutedExpression; private Object parsedExpression; private Token[] tokens; private Map tokenVars; private Set tokenVarNames; public TokenizedExpression(String expression) throws ExpressionParserException { this.expression = expression; parseExpression(); } @Override @Nullable public String getExpressionString() { return expression; } @Override @Nullable public String getSubstitutedExpression() { return substitutedExpression; } @Override @Nullable public Object getParsedExpression() { return parsedExpression; } @Override @Nullable public Token[] getTokens() { return tokens; } @Override @Nullable public Set getTokenVarNames() { return tokenVarNames; } public boolean hasTokenVars() { return (tokenVarNames != null && !tokenVarNames.isEmpty()); } private void parseExpression() throws ExpressionParserException { Token[] tokens = TokenParser.makeTokens(expression, true); Map tokenVars = null; String substitutedExpression = null; if (tokens != null && tokens.length > 0) { tokenVars = new HashMap<>(); if (tokens.length == 1) { Token token = tokens[0]; if (token.getType() == TokenType.TEXT) { substitutedExpression = token.getDefaultValue(); } else { String tokenVarName = createTokenVarName(token); tokenVars.putIfAbsent(tokenVarName, token); substitutedExpression = createTokenVarRefName(tokenVarName); } } else { StringBuilder sb = new StringBuilder(); for (Token token : tokens) { if (token.getType() == TokenType.TEXT) { sb.append(token.getDefaultValue()); } else { String tokenVarName = createTokenVarName(token); tokenVars.putIfAbsent(tokenVarName, token); substitutedExpression = createTokenVarRefName(tokenVarName); sb.append(substitutedExpression); } } substitutedExpression = sb.toString(); } } this.tokens = tokens; this.tokenVars = (tokenVars != null && !tokenVars.isEmpty() ? Collections.unmodifiableMap(tokenVars) : null); this.tokenVarNames = (tokenVars != null && !tokenVars.isEmpty() ? Collections.unmodifiableSet(tokenVars.keySet()) : null); this.substitutedExpression = substitutedExpression; if (substitutedExpression != null) { try { this.parsedExpression = Ognl.parseExpression(substitutedExpression); } catch (OgnlException e) { throw new ExpressionParserException(expression, e); } } } @Override public Object evaluate(Activity activity, OgnlContext ognlContext) { return evaluate(activity, ognlContext, null, null); } @Override public Object evaluate(Activity activity, OgnlContext ognlContext, Object root) { return evaluate(activity, ognlContext, root, null); } @Override public Object evaluate(Activity activity, OgnlContext ognlContext, Object root, Class resultType) { Assert.notNull(activity, "activity must not be null"); Assert.notNull(ognlContext, "ognlContext must not be null"); if (getParsedExpression() == null) { return null; } try { preProcess(activity, ognlContext); Object value = Ognl.getValue(getParsedExpression(), ognlContext, root, resultType); return postProcess(activity, ognlContext, value); } catch (Exception e) { throw new ExpressionEvaluationException(getExpressionString(), e); } } private void preProcess(Activity activity, OgnlContext ognlContext) { if (hasTokenVars()) { TokenEvaluator tokenEvaluator = activity.getTokenEvaluator(); resolveTokenVariables(ognlContext, tokenEvaluator); } } private Object postProcess(Activity activity, OgnlContext ognlContext, Object value) { if (getTokenVarNames() != null && value instanceof String str) { for (String tokenVarName : getTokenVarNames()) { String tokenVarRefName = createTokenVarRefName(tokenVarName); if (str.contains(tokenVarRefName)) { Object tokenValue = ognlContext.get(tokenVarName); String replacement; if (tokenValue != null) { replacement = ToStringBuilder.toString(tokenValue, activity.getStringifyContext()); } else { replacement = StringUtils.EMPTY; } str = str.replace(tokenVarRefName, replacement); } } return str; } else { return value; } } private void resolveTokenVariables(OgnlContext ognlContext, TokenEvaluator tokenEvaluator) { for (Map.Entry entry : tokenVars.entrySet()) { String tokenVarName = entry.getKey(); Token token = entry.getValue(); Object value = tokenEvaluator.evaluate(token); ognlContext.put(tokenVarName, value); } } @NonNull private static String createTokenVarName(Token token) { return TOKEN_VAR_NAME_PREFIX + createTokenName(token) + TOKEN_VAR_NAME_SUFFIX; } @NonNull private static String createTokenVarRefName(String tokenVarName) { return TOKEN_VAR_REF_SYMBOL + tokenVarName; } @NonNull private static String createTokenName(@NonNull Token token) { int hashCode = token.hashCode(); if (hashCode >= 0) { return Long.toString(hashCode, 32); } else { return Long.toString(hashCode & 0x7fffffff, 32); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy