001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.platform.ui.web.binding.alias;
018
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.el.ELException;
024import javax.el.ValueExpression;
025import javax.el.VariableMapper;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.jboss.el.ValueExpressionLiteral;
030
031/**
032 * @since 5.6
033 */
034@SuppressWarnings({ "unchecked", "rawtypes" })
035public class AliasVariableMapperWrapper extends VariableMapper {
036
037    private static final Log log = LogFactory.getLog(AliasVariableMapperWrapper.class);
038
039    protected final VariableMapper orig;
040
041    protected final List<String> blockedPatterns;
042
043    protected Map vars;
044
045    public AliasVariableMapperWrapper(VariableMapper orig, List<String> blockedPatterns) {
046        super();
047        this.orig = orig;
048        this.blockedPatterns = blockedPatterns;
049    }
050
051    /**
052     * First tries to resolve against the inner Map, then the wrapped ValueExpression, unless target is an
053     * {@link AliasVariableMapper} that blocks this variable pattern.
054     */
055    @Override
056    public ValueExpression resolveVariable(String variable) {
057        ValueExpression ve = null;
058        try {
059            if (vars != null) {
060                ve = (ValueExpression) vars.get(variable);
061            }
062            if (ve == null) {
063                // resolve to a value expression resolving to null if variable
064                // is supposed to be blocked
065                if (variable != null && blockedPatterns != null) {
066                    for (String blockedPattern : blockedPatterns) {
067                        if (blockedPattern == null) {
068                            continue;
069                        }
070                        boolean doBlock = false;
071                        if (blockedPattern.endsWith("*")) {
072                            String pattern = blockedPattern.substring(0, blockedPattern.length() - 1);
073                            if (variable.startsWith(pattern)) {
074                                doBlock = true;
075                            }
076                        } else if (blockedPattern.equals(variable)) {
077                            doBlock = true;
078                        }
079                        if (doBlock) {
080                            if (log.isDebugEnabled()) {
081                                log.debug(String.format("Blocked expression var='%s'", variable));
082                            }
083                            return getNullValueExpression();
084                        }
085                    }
086                }
087                return orig.resolveVariable(variable);
088            }
089            return ve;
090        } catch (StackOverflowError e) {
091            throw new ELException("Could not Resolve Variable [Overflow]: " + variable, e);
092        }
093    }
094
095    protected ValueExpression getNullValueExpression() {
096        return new ValueExpressionLiteral(null, Object.class);
097    }
098
099    @Override
100    public ValueExpression setVariable(String variable, ValueExpression expression) {
101        if (vars == null) {
102            vars = new HashMap();
103        }
104        return (ValueExpression) vars.put(variable, expression);
105    }
106
107}