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

org.springjutsu.validation.spel.SPELResolver Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
/*
 * Copyright 2010-2013 Duplichien, Wicksell, Springjutsu.org
 *
 * 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 org.springjutsu.validation.spel;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.standard.SpelExpressionParser;

/**
 * A customizable resolver of SPEL Expressions.
 * @author Clark Duplichien
 */
public class SPELResolver {
	
	public static final String EXPRESSION_MATCHER = "\\$\\{(.(?!\\$\\{))+\\}";
	
	/**
	 * Evaluation context which will contain 
	 * request handler implementation-specific scopes.
	 */
	protected NamedScopeEvaluationContext scopedContext;
	
	/**
	 * Expression parser used to parse expressions.
	 */
	protected ExpressionParser expressionParser;
	
	/**
	 * Core model object.
	 */
	protected Object model;
	
	/**
	 * Initialize evaluation context and expression parser.
	 * Initializes property accessors and contexts.
	 * @param model the Model for this request 
	 */
	public SPELResolver(Object model) {
		this.model = model;
		reset();
	}
	
	/**
	 * Resets SPEL resolver to an initial state,
	 * in order to clear any customization or contexts
	 * added by validation contexts, etc.
	 */
	public void reset() {
		scopedContext = new NamedScopeEvaluationContext();
		expressionParser = new SpelExpressionParser();
		
		// init named contexts
		scopedContext.addContext("model", model);
	}
	
	/**
	 * Evaluates a SPEL expression within the
	 * current web context, returning the result.
	 * @param spel String SPEL expression
	 * @return result of evaluated SPEL expression.
	 */
	public Object getBySpel(String spel) {
		try {
			return expressionParser.parseExpression(spel).getValue(scopedContext);
			// TODO: pretty sure we can get around this expensive catch with an always-null property accessor.
		} catch (SpelEvaluationException see) {
			if (see.getMessage().contains("cannot be found")) {
				return null;
			} else {
				throw see;
			}
		}
	}
	
	/**
	 * Resolves one or more SPEL expressions in the given string.
	 * @param elContainng A string potentially containing one or more SPEL expressions
	 * @return Either an object represented by the expression (if the entire string
	 *  was an expression) or a new String with all SPEL expressions replaced by
	 *  the string value of the respective resolved objects.
	 */
	public Object resolveSPELString(String elContaining) {
		// if the whole thing is a single EL string, try to get the object.
		if (elContaining.matches(EXPRESSION_MATCHER)) {
			String resolvableElString = 
				elContaining.substring(2, elContaining.length() - 1) + "?: null";
			Object elResult = getBySpel(resolvableElString);
			return elResult;
		} else {
			// otherwise, do string value substitution to build a value.
			String elResolvable = elContaining;
			Matcher matcher = Pattern.compile(EXPRESSION_MATCHER).matcher(elResolvable);
			while (matcher.find()) {
				String elString = matcher.group();
				String resolvableElString = elString.substring(2, elString.length() - 1) + "?: null";
				Object elResult = getBySpel(resolvableElString);
				String resolvedElString = elResult != null ? String.valueOf(elResult) : "";
				elResolvable = elResolvable.replace(elString, resolvedElString);
				matcher.reset(elResolvable);
			}
			return elResolvable;
		}
	}
	
	/**
	 * Sets some object to the location specified by 
	 * a spel expression.
	 * @param spel String SPEL expression
	 * @param object some object to set at SPEL-specified location.
	 */
	public void setBySpel(String spel, Object object) {
		expressionParser.parseExpression(spel).setValue(scopedContext, object);		
	}

	public NamedScopeEvaluationContext getScopedContext() {
		return scopedContext;
	}

	public ExpressionParser getExpressionParser() {
		return expressionParser;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy