001/*
002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Stephane Lacoin (Nuxeo EP Software Engineer)
018 */
019package org.nuxeo.ecm.platform.el;
020
021import static java.util.stream.Collectors.toUnmodifiableMap;
022
023import java.lang.reflect.Method;
024import java.lang.reflect.Modifier;
025import java.util.HashMap;
026import java.util.Map;
027import java.util.function.Function;
028import java.util.stream.Stream;
029
030import javax.el.ELContext;
031import javax.el.ELResolver;
032import javax.el.FunctionMapper;
033import javax.el.ValueExpression;
034import javax.el.VariableMapper;
035
036public class ExpressionContext extends ELContext {
037
038    private static final Map<String, Method> DEFAULT_FUNCTIONS = //
039            Stream.of(Functions.class.getMethods())
040                  .filter(m -> Modifier.isStatic(m.getModifiers()))
041                  .collect(toUnmodifiableMap(m -> "nx:" + m.getName(), Function.identity()));
042
043    private static class MyVariableMapper extends VariableMapper {
044
045        protected final Map<String, ValueExpression> map = new HashMap<>();
046
047        @Override
048        public ValueExpression resolveVariable(String variable) {
049            return map.get(variable);
050        }
051
052        @Override
053        public ValueExpression setVariable(String variable, ValueExpression expression) {
054            return map.put(variable, expression);
055        }
056    }
057
058    private static class MyFunctionMapper extends FunctionMapper {
059
060        private final Map<String, Method> map = new HashMap<>();
061
062        @Override
063        public Method resolveFunction(String prefix, String localName) {
064            String key = prefix + ":" + localName;
065            return map.getOrDefault(key, DEFAULT_FUNCTIONS.get(key));
066        }
067
068        @Override
069        public void mapFunction(String prefix, String localName, Method method) {
070            map.put(prefix + ":" + localName, method);
071        }
072    }
073
074    protected final ELResolver resolver = new ExpressionResolver();
075
076    protected final FunctionMapper functionMapper = new MyFunctionMapper();
077
078    protected final VariableMapper variableMapper = new MyVariableMapper();
079
080    @Override
081    public ELResolver getELResolver() {
082        return resolver;
083    }
084
085    @Override
086    public FunctionMapper getFunctionMapper() {
087        return functionMapper;
088    }
089
090    @Override
091    public VariableMapper getVariableMapper() {
092        return variableMapper;
093    }
094
095}