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