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

com.sun.faces.el.ELUtils Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.faces.el;

import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.context.flash.FlashELResolver;
import com.sun.faces.mgbean.BeanManager;
import com.sun.faces.util.MessageUtils;

import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.ResourceBundleELResolver;
import javax.el.ValueExpression;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.el.EvaluationException;
import javax.faces.el.PropertyResolver;
import javax.faces.el.ReferenceSyntaxException;
import javax.faces.el.VariableResolver;
import javax.faces.component.UIViewRoot;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 

Utility class for EL related methods.

*/ public class ELUtils { /** * Helps to determine if a EL expression represents a composite component * EL expression. */ private static final Pattern COMPOSITE_COMPONENT_EXPRESSION = Pattern.compile(".(?:[ ]+|[\\[{,(])cc[.].+[}]"); /** * Used to determine if EL method arguments are being passed to a * composite component lookup expression. * * For example: * * #{cc.attrs.label('foo')} * * is illegal, while: * * #{cc.attrs.bean.label('foo')} * * is legal. */ private static final Pattern COMPOSITE_COMPONENT_LOOKUP_WITH_ARGS = Pattern.compile("(?:[ ]+|[\\[{,(])cc[.]attrs[.]\\w+[(].+[)]"); /** * Use to determine if an expression being considered as a * MethodExpression is a simple lookup (i.e. #{cc.attrs.myaction}). */ private static final Pattern METHOD_EXPRESSION_LOOKUP = Pattern.compile(".[{]cc[.]attrs[.]\\w+[}]"); private static final String APPLICATION_SCOPE = "applicationScope"; private static final String SESSION_SCOPE = "sessionScope"; private static final String REQUEST_SCOPE = "requestScope"; private static final String VIEW_SCOPE = "viewScope"; private static final String COOKIE_IMPLICIT_OBJ = "cookie"; private static final String FACES_CONTEXT_IMPLICIT_OBJ = "facesContext"; private static final String HEADER_IMPLICIT_OBJ = "header"; private static final String HEADER_VALUES_IMPLICIT_OBJ = "headerValues"; private static final String INIT_PARAM_IMPLICIT_OBJ = "initParam"; private static final String PARAM_IMPLICIT_OBJ = "param"; private static final String PARAM_VALUES_IMPLICIT_OBJ = "paramValues"; private static final String VIEW_IMPLICIT_OBJ = "view"; public enum Scope { NONE("none"), REQUEST("request"), VIEW("view"), SESSION("session"), APPLICATION("application"); String scope; Scope(String scope) { this.scope = scope; } public String toString() { return scope; } } public static final ArrayELResolver ARRAY_RESOLVER = new ArrayELResolver(); public static final BeanELResolver BEAN_RESOLVER = new BeanELResolver(); public static final FacesResourceBundleELResolver FACES_BUNDLE_RESOLVER = new FacesResourceBundleELResolver(); public static final ImplicitObjectELResolverForJsp IMPLICIT_JSP_RESOLVER = new ImplicitObjectELResolverForJsp(); public static final ImplicitObjectELResolver IMPLICIT_RESOLVER = new ImplicitObjectELResolver(); public static final FlashELResolver FLASH_RESOLVER = new FlashELResolver(); public static final ListELResolver LIST_RESOLVER = new ListELResolver(); public static final ManagedBeanELResolver MANAGED_BEAN_RESOLVER = new ManagedBeanELResolver(); public static final MapELResolver MAP_RESOLVER = new MapELResolver(); public static final ResourceBundleELResolver BUNDLE_RESOLVER = new ResourceBundleELResolver(); public static final ScopedAttributeELResolver SCOPED_RESOLVER = new ScopedAttributeELResolver(); public static final ResourceELResolver RESOURCE_RESOLVER = new ResourceELResolver(); public static final CompositeComponentAttributesELResolver COMPOSITE_COMPONENT_ATTRIBUTES_EL_RESOLVER = new CompositeComponentAttributesELResolver(); // ------------------------------------------------------------ Constructors private ELUtils() { throw new IllegalStateException(); } // ---------------------------------------------------------- Public Methods public static boolean isCompositeComponentExpr(String expression) { // TODO we should be trying to re-use the Matcher by calling // m.reset(expression); Matcher m = COMPOSITE_COMPONENT_EXPRESSION.matcher(expression); return m.find(); } public static boolean isCompositeComponentMethodExprLookup(String expression) { Matcher m = METHOD_EXPRESSION_LOOKUP.matcher(expression); return m.matches(); } public static boolean isCompositeComponentLookupWithArgs(String expression) { // TODO we should be trying to re-use the Matcher by calling // m.reset(expression); Matcher m = COMPOSITE_COMPONENT_LOOKUP_WITH_ARGS.matcher(expression); return m.find(); } /** *

Create the ELResolver chain for programmatic EL calls.

* @param composite a CompositeELResolver * @param associate our ApplicationAssociate */ public static void buildFacesResolver(FacesCompositeELResolver composite, ApplicationAssociate associate) { if (associate == null) { String message = MessageUtils.getExceptionMessageString (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "associate"); throw new NullPointerException(message); } if (composite == null) { String message = MessageUtils.getExceptionMessageString (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "composite"); throw new NullPointerException(message); } composite.addRootELResolver(IMPLICIT_RESOLVER); composite.add(FLASH_RESOLVER); composite.addPropertyELResolver(COMPOSITE_COMPONENT_ATTRIBUTES_EL_RESOLVER); addELResolvers(composite, associate.getELResolversFromFacesConfig()); addVariableResolvers(composite, FacesCompositeELResolver.ELResolverChainType.Faces, associate); addPropertyResolvers(composite, associate); composite.add(associate.getApplicationELResolvers()); composite.addRootELResolver(MANAGED_BEAN_RESOLVER); composite.addPropertyELResolver(RESOURCE_RESOLVER); composite.addPropertyELResolver(BUNDLE_RESOLVER); composite.addRootELResolver(FACES_BUNDLE_RESOLVER); composite.addPropertyELResolver(MAP_RESOLVER); composite.addPropertyELResolver(LIST_RESOLVER); composite.addPropertyELResolver(ARRAY_RESOLVER); composite.addPropertyELResolver(BEAN_RESOLVER); composite.addRootELResolver(SCOPED_RESOLVER); } /** *

Create the ELResolver chain for JSP.

* @param composite a CompositeELResolver * @param associate our ApplicationAssociate */ public static void buildJSPResolver(FacesCompositeELResolver composite, ApplicationAssociate associate) { if (associate == null) { String message = MessageUtils.getExceptionMessageString (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "associate"); throw new NullPointerException(message); } if (composite == null) { String message = MessageUtils.getExceptionMessageString (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "composite"); throw new NullPointerException(message); } composite.addRootELResolver(IMPLICIT_JSP_RESOLVER); composite.add(FLASH_RESOLVER); composite.addRootELResolver(MANAGED_BEAN_RESOLVER); composite.addPropertyELResolver(RESOURCE_RESOLVER); composite.addRootELResolver(FACES_BUNDLE_RESOLVER); addELResolvers(composite, associate.getELResolversFromFacesConfig()); addVariableResolvers(composite, FacesCompositeELResolver.ELResolverChainType.JSP, associate); addPropertyResolvers(composite, associate); composite.add(associate.getApplicationELResolvers()); } public static Object evaluateValueExpression(ValueExpression expression, ELContext elContext) { if (expression.isLiteralText()) { return expression.getExpressionString(); } else { return expression.getValue(elContext); } } /** * @param associate the ApplicationAssociate * @param provideDefault whether or not to return a * DummpyPropertyResolverImpl * @return the PropertyResolvers set via * {@link javax.faces.application.Application#setPropertyResolver(javax.faces.el.PropertyResolver)} * or, if that is null, return the PropertyResolver * chain from the parsed configuration resources. If either of those are * null, and provideDefault is true, * return the DummyPropertyResolverImpl. */ @SuppressWarnings("deprecation") public static PropertyResolver getDelegatePR(ApplicationAssociate associate, boolean provideDefault) { PropertyResolver pr = associate.getLegacyPropertyResolver(); if (pr == null) { pr = associate.getLegacyPRChainHead(); if (pr == null && provideDefault) { pr = new DummyPropertyResolverImpl(); } } return pr; } /** * @param associate the ApplicationAssociate * @param provideDefault whether or not to return a * DummpyPropertyResolverImpl * @return the VariableResolvers set via * {@link javax.faces.application.Application#setVariableResolver(javax.faces.el.VariableResolver)} * or, if that is null, return the VariableResolver * chain from the parsed configuration resources. If either of those are * null, , and provideDefault is true, * return the ChainAwareVariableResolver. */ @SuppressWarnings("deprecation") public static VariableResolver getDelegateVR(ApplicationAssociate associate, boolean provideDefault) { VariableResolver vr = associate.getLegacyVariableResolver(); if (vr == null) { vr = associate.getLegacyVRChainHead(); if (vr == null && provideDefault) { vr = new ChainAwareVariableResolver(); } } return vr; } /** * @param expressionString the expression string, with delimiters * intact. * @return a List of expressions from the expressionString * @throws ReferenceSyntaxException if the expression string is invalid */ @SuppressWarnings("deprecation") public static List getExpressionsFromString(String expressionString) throws ReferenceSyntaxException { if (null == expressionString) { return Collections.emptyList(); } //noinspection CollectionWithoutInitialCapacity List result = new ArrayList(); int i, j, len = expressionString.length(), cur = 0; while (cur < len && -1 != (i = expressionString.indexOf("#{", cur))) { if (-1 == (j = expressionString.indexOf('}', i + 2))) { throw new ReferenceSyntaxException( MessageUtils.getExceptionMessageString( MessageUtils.INVALID_EXPRESSION_ID, expressionString)); } cur = j + 1; result.add(expressionString.substring(i, cur)); } return result; } /** *

This method is used by the ManagedBeanFactory to ensure that * properties set by an expression point to an object with an * accepted lifespan.

* *

get the scope of the expression. Return null if * it isn't scoped

* *

For example, the expression: * sessionScope.TestBean.one should return "session" * as the scope.

* * @param valueBinding the expression * * @param outString an allocated String Array into which we put the * first segment. * * @return the scope of the expression * * @throws ReferenceSyntaxException if valueBinding is syntactically invalid */ @SuppressWarnings("deprecation") public static ELUtils.Scope getScope(String valueBinding, String[] outString) throws ReferenceSyntaxException { if (valueBinding == null || 0 == valueBinding.length()) { return null; } valueBinding = stripBracketsIfNecessary(valueBinding); int segmentIndex = getFirstSegmentIndex(valueBinding); //examine first segment and see if it is a scope String identifier = valueBinding; if (segmentIndex > 0) { //get first segment designated by a "." or "[" identifier = valueBinding.substring(0, segmentIndex); } //check to see if the identifier is a named scope. FacesContext context = FacesContext.getCurrentInstance(); ExternalContext ec = context.getExternalContext(); if (null != outString) { outString[0] = identifier; } if (REQUEST_SCOPE.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (VIEW_SCOPE.equalsIgnoreCase(identifier)) { return Scope.VIEW; } if (SESSION_SCOPE.equalsIgnoreCase(identifier)) { return Scope.SESSION; } if (APPLICATION_SCOPE.equalsIgnoreCase(identifier)) { return Scope.APPLICATION; } // handle implicit objects if (INIT_PARAM_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.APPLICATION; } if (COOKIE_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (FACES_CONTEXT_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (HEADER_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (HEADER_VALUES_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (PARAM_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (PARAM_VALUES_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } if (VIEW_IMPLICIT_OBJ.equalsIgnoreCase(identifier)) { return Scope.REQUEST; } Map requestMap = ec.getRequestMap(); if (requestMap != null && requestMap.containsKey(identifier)) { return Scope.REQUEST; } UIViewRoot root = context.getViewRoot(); if (root != null) { Map viewMap = root.getViewMap(false); if (viewMap != null && viewMap.containsKey(identifier)) { return Scope.VIEW; } } Map sessionMap = ec.getSessionMap(); if (sessionMap != null && sessionMap.containsKey(identifier)) { return Scope.SESSION; } Map appMap = ec.getApplicationMap(); if (appMap != null && appMap.containsKey(identifier)) { return Scope.APPLICATION; } //not present in any scope return null; } /** * Create a ValueExpression with the expected type of * Object.class * @param expression an EL expression * @return a new ValueExpression instance based off the * provided valueRef */ public static ValueExpression createValueExpression(String expression) { return createValueExpression(expression, Object.class); } public static ValueExpression createValueExpression(String expression, Class expectedType) { FacesContext context = FacesContext.getCurrentInstance(); return context.getApplication().getExpressionFactory(). createValueExpression(context.getELContext(), expression, expectedType); } public static Object coerce(Object value, Class toType) { FacesContext context = FacesContext.getCurrentInstance(); return context.getApplication().getExpressionFactory().coerceToType(value, toType); } public static Scope getScope(String scope) { for (Scope s : Scope.values()) { if (s.toString().equals(scope)) { return s; } } return null; } // --------------------------------------------------------- Private Methods /** *

Add the ELResolvers from the provided list * to the target CompositeELResolver.

* * @param target the CompositeELResolver to which * the ELResolvers will be added. * @param resolvers a List of ELResolvers */ private static void addELResolvers(CompositeELResolver target, List resolvers) { if (resolvers != null && !resolvers.isEmpty()) { for (ELResolver resolver : resolvers) { target.add(resolver); } } } /** *

Add any PropertyResolvers to the specified * CompositeELResolver.

* @param target the CompositeELResolver to which * the PropertyResolvers will be added. * @param associate our ApplicationAssociate */ @SuppressWarnings("deprecation") private static void addPropertyResolvers(CompositeELResolver target, ApplicationAssociate associate) { PropertyResolver pr = getDelegatePR(associate, false); if (pr != null) { target.add(new PropertyResolverChainWrapper(pr)); } } /** *

Add any VariableResolvers to the specified * CompositeELResolver.

* @param target the CompositeELResolver to which * the VariableResolvers will be added. * @param associate our ApplicationAssociate */ @SuppressWarnings("deprecation") private static void addVariableResolvers(FacesCompositeELResolver target, FacesCompositeELResolver.ELResolverChainType chainType, ApplicationAssociate associate) { VariableResolver vr = getDelegateVR(associate, true); if (vr != null) { VariableResolverChainWrapper vrChainWrapper = new VariableResolverChainWrapper(vr); target.addRootELResolver(vrChainWrapper); if (chainType == FacesCompositeELResolver.ELResolverChainType.JSP) { associate.setLegacyVRChainHeadWrapperForJsp(vrChainWrapper); } else { associate.setLegacyVRChainHeadWrapperForFaces(vrChainWrapper); } } } /** *

* The the first segment of a String tokenized by a "." or "[" * * @param valueBinding the expression from which the first segment * will be obtained * @return index of the first occurrence of . or [ */ private static int getFirstSegmentIndex(String valueBinding) { int segmentIndex = valueBinding.indexOf('.'); int bracketIndex = valueBinding.indexOf('['); //there is no "." in the valueBinding so take the bracket value if (segmentIndex < 0) { segmentIndex = bracketIndex; } else { //if there is a bracket proceed if (bracketIndex > 0) { //if the bracket index is before the "." then //get the bracket index if (segmentIndex > bracketIndex) { segmentIndex = bracketIndex; } } } return segmentIndex; } @SuppressWarnings("deprecation") private static String stripBracketsIfNecessary(String expression) throws ReferenceSyntaxException { assert (null != expression); // look for invalid expressions if (expression.charAt(0) == '#') { if (expression.charAt(1) != '{') { throw new ReferenceSyntaxException(MessageUtils.getExceptionMessageString( MessageUtils.INVALID_EXPRESSION_ID, expression)); } int len = expression.length(); if (expression.charAt(len - 1) != '}') { throw new ReferenceSyntaxException(MessageUtils.getExceptionMessageString( MessageUtils.INVALID_EXPRESSION_ID, expression)); } expression = expression.substring(2, len - 1); } return expression; } public static Scope getScopeForExpression(String expression) { if (SharedUtils.isMixedExpression(expression)) { return (getNarrowestScopeFromExpression(expression)); } else { return (getScopeForSingleExpression(expression)); } } @SuppressWarnings("deprecation") public static boolean hasValidLifespan(Scope expressionScope, Scope beanScope) throws EvaluationException { //if the managed bean's scope is "none" but the scope of the //referenced object is not "none", scope is invalid if (beanScope == Scope.NONE) { return expressionScope == Scope.NONE; } //if the managed bean's scope is "request" it is able to refer //to objects in any scope if (beanScope == Scope.REQUEST) { return true; } //if the managed bean's scope is "view" it is able to refer to //objects in other "view", "session", "application" or "none" scopes. if (beanScope == Scope.VIEW) { return expressionScope != Scope.REQUEST; } //if the managed bean's scope is "session" it is able to refer //to objects in other "session", "application", or "none" scopes if (beanScope == Scope.SESSION) { return !(expressionScope == Scope.REQUEST || expressionScope == Scope.VIEW); } //if the managed bean's scope is "application" it is able to refer //to objects in other "application", or "none" scopes if (beanScope == Scope.APPLICATION) { return !(expressionScope == Scope.REQUEST || expressionScope == Scope.VIEW || expressionScope == Scope.SESSION); } //the managed bean is required to be in either "request", "view", // "session", "application", or "none" scopes. One of the previous decision //statements must be true. //noinspection ConstantConditions assert (false); return false; } @SuppressWarnings("deprecation") public static ELUtils.Scope getScopeForSingleExpression(String value) throws EvaluationException { String[] firstSegment = new String[1]; ELUtils.Scope valueScope = ELUtils.getScope(value, firstSegment); if (null == valueScope) { // Perhaps the bean hasn't been created yet. See what its // scope would be when it is created. if (firstSegment[0] != null) { BeanManager manager = ApplicationAssociate.getCurrentInstance().getBeanManager(); if (manager.isManaged(firstSegment[0])) { valueScope = ELUtils.getScope(manager.getBuilder(firstSegment[0]).getScope()); } } else { // we are referring to a bean that doesn't exist in the // configuration file. Give it a wide scope... valueScope = Scope.APPLICATION; } } return valueScope; } @SuppressWarnings("deprecation") public static Scope getNarrowestScopeFromExpression(String expression) throws ReferenceSyntaxException { // break the argument expression up into its component // expressions, ignoring literals. List expressions = ELUtils.getExpressionsFromString(expression); int shortestScope = Scope.NONE.ordinal(); Scope result = Scope.NONE; for (String expr : expressions) { // loop over the expressions Scope lScope = getScopeForSingleExpression(expr); // don't consider none if (null == lScope || lScope == Scope.NONE) { continue; } int currentScope = lScope.ordinal(); // if we have no basis for comparison if (Scope.NONE.ordinal() == shortestScope) { shortestScope = currentScope; result = lScope; } else { // we have a basis for comparison if (currentScope < shortestScope) { shortestScope = currentScope; result = lScope; } } } return result; } public static boolean isScopeValid(String scopeName) { if (scopeName == null) { return false; } for (Scope scope : Scope.values()) { if (scopeName.equals(scope.toString())) { return true; } } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy