001/*
002 * (C) Copyright 2010 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.LinkedHashMap;
020import java.util.List;
021import java.util.Map;
022
023import javax.el.ValueExpression;
024import javax.el.VariableMapper;
025import javax.faces.context.FacesContext;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029
030/**
031 * Variable mapper that holds value expressions. It can be exposed to the request context after the JSF component tree
032 * build, so that {@link AliasValueExpression} instances can be resolved.
033 * <p>
034 * It also builds the {@link VariableMapper} to use when building the component tree, so that
035 * {@link AliasValueExpression} instances are kept in component attributes, even on ajax rerender.
036 *
037 * @author Anahide Tchertchian
038 * @since 5.4
039 */
040public class AliasVariableMapper extends VariableMapper {
041
042    private static final Log log = LogFactory.getLog(AliasVariableMapper.class);
043
044    public static final String REQUEST_MARKER = AliasVariableMapper.class.getName() + "_MARKER";
045
046    protected String id;
047
048    protected Map<String, ValueExpression> vars;
049
050    protected List<String> blockedPatterns;
051
052    public AliasVariableMapper() {
053        super();
054    }
055
056    public AliasVariableMapper(String id) {
057        super();
058        this.id = id;
059    }
060
061    public String getId() {
062        return id;
063    }
064
065    public void setId(String id) {
066        this.id = id;
067    }
068
069    @Override
070    public ValueExpression resolveVariable(String variable) {
071        ValueExpression ve = null;
072        if (vars != null) {
073            ve = vars.get(variable);
074        }
075        return ve;
076    }
077
078    @Override
079    public ValueExpression setVariable(String variable, ValueExpression expression) {
080        if (vars == null) {
081            vars = new LinkedHashMap<String, ValueExpression>();
082        }
083        return vars.put(variable, expression);
084    }
085
086    public boolean hasVariables(String variable) {
087        return vars != null && vars.containsKey(variable);
088    }
089
090    public VariableMapper getVariableMapperForBuild(VariableMapper orig) {
091        AliasVariableMapperWrapper vm = new AliasVariableMapperWrapper(orig, getBlockedPatterns());
092        Map<String, ValueExpression> vars = getVariables();
093        if (vars != null) {
094            String id = getId();
095            for (Map.Entry<String, ValueExpression> var : vars.entrySet()) {
096                vm.setVariable(var.getKey(), new AliasValueExpression(id, var.getKey()));
097            }
098        }
099        return vm;
100    }
101
102    public Map<String, ValueExpression> getVariables() {
103        return vars;
104    }
105
106    public List<String> getBlockedPatterns() {
107        return blockedPatterns;
108    }
109
110    public void setBlockedPatterns(List<String> blockedPatterns) {
111        this.blockedPatterns = blockedPatterns;
112    }
113
114    public static AliasVariableMapper getVariableMapper(FacesContext ctx, String id) {
115        NuxeoAliasBean a = lookupBean(ctx);
116        if (a != null) {
117            return a.get(id);
118        }
119        return null;
120    }
121
122    public static void exposeAliasesToRequest(FacesContext ctx, AliasVariableMapper vm) {
123        NuxeoAliasBean a = lookupBean(ctx);
124        if (a != null) {
125            a.add(vm);
126        }
127    }
128
129    public static void removeAliasesExposedToRequest(FacesContext ctx, String id) {
130        // do not remove aliases from bean anymore: bean is kept in request
131        // scope and will be emptied at the end of the request
132        // NuxeoAliasBean a = lookupBean(ctx);
133        // if (a != null) {
134        // a.remove(id);
135        // }
136        return;
137    }
138
139    protected static NuxeoAliasBean lookupBean(FacesContext ctx) {
140        String expr = "#{" + NuxeoAliasBean.NAME + "}";
141        NuxeoAliasBean bean = (NuxeoAliasBean) ctx.getApplication().evaluateExpressionGet(ctx, expr, Object.class);
142        if (bean == null) {
143            log.error("Managed bean not found: " + expr);
144            return null;
145        }
146        return bean;
147    }
148
149    @Override
150    public String toString() {
151        final StringBuilder buf = new StringBuilder();
152
153        buf.append(getClass().getSimpleName());
154        buf.append(" {");
155        buf.append(" id=");
156        buf.append(id);
157        buf.append(", vars=");
158        buf.append(vars);
159        buf.append('}');
160
161        return buf.toString();
162    }
163
164}