javax.el.StandardELContext Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2012 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 javax.el;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Method;
/**
* A standard ELContext suitable for use in a stand alone environment.
* This class provides a default implementation of an ELResolver that contains
* a number of useful ELResolvers. It also provides local repositories for
* the FunctionMapper, VariableMapper, and BeanNameResolver.
*
* @since EL 3.0
*/
public class StandardELContext extends ELContext {
/*
* The ELResolver for this ELContext.
*/
private ELResolver elResolver;
/*
* The list of the custom ELResolvers added to the ELResolvers.
* An ELResolver is added to the list when addELResolver is called.
*/
private CompositeELResolver customResolvers;
/*
* The ELResolver implementing the query operators.
*/
private ELResolver streamELResolver;
/*
* The FunctionMapper for this ELContext.
*/
private FunctionMapper functionMapper;
/*
* The pre-confured init function map;
*/
private Map initFunctionMap;
/*
* The VariableMapper for this ELContext.
*/
private VariableMapper variableMapper;
/*
* If non-null, indicates the presence of a delegate ELContext.
* When a Standard is constructed from another ELContext, there is no
* easy way to get its private context map, therefore delegation is needed.
*/
private ELContext delegate = null;
/**
* A bean repository local to this context
*/
private Map beans = new HashMap();
/**
* Construct a default ELContext for a stand-alone environment.
* @param factory The ExpressionFactory
*/
public StandardELContext(ExpressionFactory factory) {
this.streamELResolver = factory.getStreamELResolver();
initFunctionMap = factory.getInitFunctionMap();
}
/**
* Construct a StandardELContext from another ELContext.
* @param context The ELContext that acts as a delegate in most cases
*/
public StandardELContext(ELContext context) {
this.delegate = context;
// Copy all attributes except map and resolved
CompositeELResolver elr = new CompositeELResolver();
elr.add(new BeanNameELResolver(new LocalBeanNameResolver()));
customResolvers = new CompositeELResolver();
elr.add(customResolvers);
elr.add(context.getELResolver());
elResolver = elr;
functionMapper = context.getFunctionMapper();
variableMapper = context.getVariableMapper();
setLocale(context.getLocale());
}
@Override
public void putContext(Class key, Object contextObject) {
if (delegate !=null) {
delegate.putContext(key, contextObject);
} else {
super.putContext(key, contextObject);
}
}
@Override
public Object getContext(Class key) {
if (delegate !=null) {
return delegate.getContext(key);
} else {
return super.getContext(key);
}
}
/**
* Construct (if needed) and return a default ELResolver.
* Retrieves the ELResolver
associated with this context.
* This is a CompositeELResover
consists of an ordered list of
* ELResolver
s.
*
* - A {@link BeanNameELResolver} for beans defined locally
* - Any custom
ELResolver
s
* - An
ELResolver
supporting the collection operations
* - A {@link StaticFieldELResolver} for resolving static fields
* - A {@link MapELResolver} for resolving Map properties
* - A {@link ResourceBundleELResolver} for resolving ResourceBundle properties
* - A {@link ListELResolver} for resolving List properties
* - An {@link ArrayELResolver} for resolving array properties
* - A {@link BeanELResolver} for resolving bean properties
*
*
* @return The ELResolver for this context.
*/
@Override
public ELResolver getELResolver() {
if (elResolver == null) {
CompositeELResolver resolver = new CompositeELResolver();
resolver.add(new BeanNameELResolver(new LocalBeanNameResolver()));
customResolvers = new CompositeELResolver();
resolver.add(customResolvers);
if (streamELResolver != null) {
resolver.add(streamELResolver);
}
resolver.add(new StaticFieldELResolver());
resolver.add(new MapELResolver());
resolver.add(new ResourceBundleELResolver());
resolver.add(new ListELResolver());
resolver.add(new ArrayELResolver());
resolver.add(new BeanELResolver());
elResolver = resolver;
}
return elResolver;
}
/**
* Add a custom ELResolver to the context. The list of the custom
* ELResolvers will be accessed in the order they are added.
* A custom ELResolver added to the context cannot be removed.
* @param cELResolver The new ELResolver to be added to the context
*/
public void addELResolver(ELResolver cELResolver) {
getELResolver(); // make sure elResolver is constructed
customResolvers.add(cELResolver);
}
/**
* Get the local bean repository
* @return the bean repository
*/
Map getBeans() {
return beans;
}
/**
* Construct (if needed) and return a default FunctionMapper.
* @return The default FunctionMapper
*/
@Override
public FunctionMapper getFunctionMapper() {
if (functionMapper == null) {
functionMapper = new DefaultFunctionMapper(initFunctionMap);
}
return functionMapper;
}
/**
* Construct (if needed) and return a default VariableMapper() {
* @return The default Variable
*/
@Override
public VariableMapper getVariableMapper() {
if (variableMapper == null) {
variableMapper = new DefaultVariableMapper();
}
return variableMapper;
}
private static class DefaultFunctionMapper extends FunctionMapper {
private Map functions = null;
DefaultFunctionMapper(Map initMap){
functions = (initMap == null)?
new HashMap():
new HashMap(initMap);
}
@Override
public Method resolveFunction(String prefix, String localName) {
return functions.get(prefix + ":" + localName);
}
@Override
public void mapFunction(String prefix, String localName, Method meth){
functions.put(prefix + ":" + localName, meth);
}
}
private static class DefaultVariableMapper extends VariableMapper {
private Map variables = null;
@Override
public ValueExpression resolveVariable (String variable) {
if (variables == null) {
return null;
}
return variables.get(variable);
}
@Override
public ValueExpression setVariable(String variable,
ValueExpression expression) {
if (variables == null) {
variables = new HashMap();
}
ValueExpression prev = null;
if (expression == null) {
prev = variables.remove(variable);
} else {
prev = variables.put(variable, expression);
}
return prev;
}
}
private class LocalBeanNameResolver extends BeanNameResolver {
@Override
public boolean isNameResolved(String beanName) {
return beans.containsKey(beanName);
}
@Override
public Object getBean(String beanName) {
return beans.get(beanName);
}
@Override
public void setBeanValue(String beanName, Object value) {
beans.put(beanName, value);
}
@Override
public boolean isReadOnly(String beanName) {
return false;
}
@Override
public boolean canCreateBean(String beanName) {
return true;
}
}
}