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

org.thymeleaf.standard.expression.OGNLContextPropertyAccessor Maven / Gradle / Ivy

Go to download

Modern server-side Java template engine for both web and standalone environments

There is a newer version: 3.1.3.RELEASE
Show newest version

/*
 * =============================================================================
 *
 *   Copyright (c) 2011-2016, The THYMELEAF team (http://www.thymeleaf.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.thymeleaf.standard.expression;

import java.util.Map;

import ognl.OgnlContext;
import ognl.OgnlException;
import ognl.PropertyAccessor;
import ognl.enhance.UnsupportedCompilationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.IContext;

/**
 * 

* Implementation of {@code PropertyAccessor} that allows OGNL to access the contents of {@link IContext} * implementations as if they were a Map. *

*

* Note this accessor also has to take care of variable access restrictions (like e.g. forbidding access to * the request parameters in unescaped text or in preprocessing expressions). *

*

* Note a class with this name existed since 2.0, but it was completely reimplemented * in Thymeleaf 3.0 *

* * @author Michal Kreuzman * @author Daniel Fernández * @see PropertyAccessor * @since 3.0.0 */ public final class OGNLContextPropertyAccessor implements PropertyAccessor { private static final Logger LOGGER = LoggerFactory.getLogger(OGNLContextPropertyAccessor.class); public static final String RESTRICT_REQUEST_PARAMETERS = "%RESTRICT_REQUEST_PARAMETERS%"; static final String REQUEST_PARAMETERS_RESTRICTED_VARIABLE_NAME = "param"; OGNLContextPropertyAccessor() { super(); } public Object getProperty(final Map ognlContext, final Object target, final Object name) throws OgnlException { if (!(target instanceof IContext)) { throw new IllegalStateException( "Wrong target type. This property accessor is only usable for " + IContext.class.getName() + " implementations, and " + "in this case the target object is " + (target == null? "null" : ("of class " + target.getClass().getName()))); } if (REQUEST_PARAMETERS_RESTRICTED_VARIABLE_NAME.equals(name) && ognlContext != null && ognlContext.containsKey(RESTRICT_REQUEST_PARAMETERS)) { throw new OgnlException( "Access to variable \"" + name + "\" is forbidden in this context. Note some restrictions apply to " + "variable access. For example, accessing request parameters is forbidden in preprocessing and " + "unescaped expressions, and also in fragment inclusion specifications."); } final String propertyName = (name == null? null : name.toString()); // 'execInfo' translation from context variable to expression object - deprecated and to be removed in 3.1 final Object execInfoResult = checkExecInfo(propertyName, ognlContext); if (execInfoResult != null) { return execInfoResult; } /* * NOTE we do not check here whether we are being asked for the 'locale', 'request', 'response', etc. * because there already are specific expression objects for the most important of them, which should * be used instead: #locale, #httpServletRequest, #httpSession, etc. * The variables maps should just be used as a map, without exposure of its more-internal methods... */ final IContext context = (IContext) target; return context.getVariable(propertyName); } /** * Translation from 'execInfo' context variable (${execInfo}) to 'execInfo' expression object (${#execInfo}), needed * since 3.0.0. * * Note this is expressed as a separate method in order to mark this as deprecated and make it easily locatable. * * @param propertyName the name of the property being accessed (we are looking for 'execInfo'). * @param context the expression context, which should contain the expression objects. * @deprecated created (and deprecated) in 3.0.0 in order to support automatic conversion of calls to the 'execInfo' * context variable (${execInfo}) into the 'execInfo' expression object (${#execInfo}), which is its * new only valid form. This method, along with the infrastructure for execInfo conversion in * StandardExpressionUtils#mightNeedExpressionObjects(...) will be removed in 3.1. */ @Deprecated private static Object checkExecInfo(final String propertyName, final Map context) { if ("execInfo".equals(propertyName)) { LOGGER.warn( "[THYMELEAF][{}] Found Thymeleaf Standard Expression containing a call to the context variable " + "\"execInfo\" (e.g. \"${execInfo.templateName}\"), which has been deprecated. The " + "Execution Info should be now accessed as an expression object instead " + "(e.g. \"${#execInfo.templateName}\"). Deprecated use is still allowed, but will be removed " + "in future versions of Thymeleaf.", TemplateEngine.threadIndex()); return context.get("execInfo"); } return null; } public void setProperty(final Map context, final Object target, final Object name, final Object value) throws OgnlException { // IVariablesMap implementations should never be set values from OGNL expressions throw new UnsupportedOperationException("Cannot set values into VariablesMap instances from OGNL Expressions"); } public String getSourceAccessor(final OgnlContext context, final Object target, final Object index) { // This method is called during OGNL's bytecode enhancement optimizations in order to determine better- // performing methods to access the properties of an object. It's been written trying to mimic // what is done at MapPropertyAccessor#getSourceAccessor() method, removing all the parts related to indexed // access, which do not apply to IVariablesMap implementations. context.setCurrentAccessor(IContext.class); context.setCurrentType(Object.class); return ".getVariable(" + index + ")"; } public String getSourceSetter(final OgnlContext context, final Object target, final Object index) { // This method is called during OGNL's bytecode enhancement optimizations in order to determine better- // performing methods to access the properties of an object. Given IVariablesMap implementations should never // be set any values from OGNL, this exception should never be thrown anyway. throw new UnsupportedCompilationException( "Setting expression for " + context.getCurrentObject() + " with index of " + index + " cannot " + "be computed. IVariablesMap implementations are considered read-only by OGNL."); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy