org.nuxeo.ecm.platform.ui.web.binding.MetaValueExpression.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.platform.ui.web.binding.MetaValueExpression.java

Source

/*
 * (C) Copyright 2007 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Nuxeo - initial API and implementation
 *
 * $Id: MetaValueExpression.java 28491 2008-01-04 19:04:30Z sfermigier $
 */

package org.nuxeo.ecm.platform.ui.web.binding;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils;

/**
 * Meta value expression used to invoke the EL expression that is already the result of a value expression.
 *
 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
 */
public class MetaValueExpression extends ValueExpression implements Serializable {

    private static final long serialVersionUID = -2721042412903607760L;

    private static final Log log = LogFactory.getLog(MetaValueExpression.class);

    private ValueExpression originalValueExpression;

    private FunctionMapper fnMapper;

    private VariableMapper varMapper;

    private Class<?> expectedType;

    /**
     * @see {@link #MetaValueExpression(ValueExpression, FunctionMapper, VariableMapper)}
     */
    public MetaValueExpression(ValueExpression originalValueExpression) {
        this(originalValueExpression, null, null, Object.class);
    }

    public MetaValueExpression(ValueExpression originalValueExpression, FunctionMapper fnMapper,
            VariableMapper varMapper) {
        this(originalValueExpression, fnMapper, varMapper, Object.class);
    }

    public MetaValueExpression(ValueExpression originalValueExpression, FunctionMapper fnMapper,
            VariableMapper varMapper, Class<?> expectedType) {
        this.originalValueExpression = originalValueExpression;
        this.fnMapper = fnMapper;
        this.varMapper = varMapper;
        this.expectedType = expectedType;
    }

    // Expression interface

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof MetaValueExpression)) {
            return false;
        }
        MetaValueExpression other = (MetaValueExpression) obj;
        return originalValueExpression.equals(other.originalValueExpression);
    }

    @Override
    public int hashCode() {
        return originalValueExpression.hashCode();
    }

    @Override
    public String getExpressionString() {
        return originalValueExpression.getExpressionString();
    }

    @Override
    public boolean isLiteralText() {
        // XXX should invoke first
        return originalValueExpression.isLiteralText();
    }

    // ValueExpression interface

    @Override
    public Class<?> getExpectedType() {
        // XXX should invoke first
        return originalValueExpression.getExpectedType();
    }

    private ELContext getLocalContext(ELContext context) {
        if (fnMapper == null && varMapper == null) {
            return context;
        }
        return new org.nuxeo.ecm.platform.ui.web.binding.EvaluationContext(context, fnMapper, varMapper);
    }

    @Override
    public Class<?> getType(ELContext context) {
        ELContext nxcontext = getLocalContext(context);
        // XXX should invoke first...
        return originalValueExpression.getType(nxcontext);
    }

    @Override
    public Object getValue(ELContext context) {
        ELContext nxcontext = getLocalContext(context);
        Object res = null;
        if (originalValueExpression != null) {
            res = originalValueExpression.getValue(nxcontext);
            if (res instanceof String) {
                String expression = (String) res;
                if (ComponentTagUtils.isValueReference(expression)) {
                    FacesContext faces = FacesContext.getCurrentInstance();
                    Application app = faces.getApplication();
                    ExpressionFactory factory = app.getExpressionFactory();
                    ValueExpression newExpr = factory.createValueExpression(nxcontext, expression, expectedType);
                    try {
                        res = newExpr.getValue(nxcontext);
                    } catch (ELException err) {
                        log.error("Error processing expression " + expression + ": " + err);
                        res = null;
                    }
                } else {
                    res = expression;
                }
            }
        }
        return res;
    }

    @Override
    public boolean isReadOnly(ELContext context) {
        return true;
    }

    @Override
    public void setValue(ELContext context, Object value) {
        // do nothing
    }

    // Externalizable interface

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        originalValueExpression = (ValueExpression) in.readObject();
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(originalValueExpression);
    }

}