/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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.
 */

package org.apache.myfaces.test.el;

import javax.el.ELContext;
import javax.el.PropertyNotWritableException;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;

/**
 * <p>Mock implementation of <code>ValueExpression</code> that wraps a variable.</p>
 */
public class MockVariableValueExpression extends ValueExpression {
    

    // ------------------------------------------------------------ Constructors


    /**
     * Serial version UID.
     */
    private static final long serialVersionUID = 4475919948345298291L;


    /**
     * <p>Construct a new expression for the specified instance.</p>
     *
     * @param instance Variable instance to be wrapped
     * @param expectedType Expected type of the result
     */
    public MockVariableValueExpression(Object instance, Class expectedType) {

        if (instance == null) {
            throw new NullPointerException("Instance cannot be null");
        }
        this.instance = instance;
        this.expectedType = expectedType;

    }


    // ------------------------------------------------------ Instance Variables


    /**
     * <p>The expected result type for <code>getValue()</code> calls.</p>
     */
    private Class expectedType = null;


    /**
     * <p>The variable instance being wrapped by this expression.</p>
     */
    private Object instance = null;


    // ------------------------------------------------------ Expression Methods


    /**
     * <p>Return <code>true</code> if this expression is equal to the
     * specified expression.</p>
     *
     * @param obj Object to be compared
     */
    public boolean equals(Object obj) {

        if ((obj != null) & (obj instanceof ValueExpression)) {
            return instance.toString().equals(((ValueExpression) obj).getExpressionString());
        } else {
            return false;
        }

    }


    /**
     * <p>Return the original String used to create this expression,
     * unmodified.</p>
     */
    public String getExpressionString() {

        return this.instance.toString();

    }


    /**
     * <p>Return the hash code for this expression.</p>
     */
    public int hashCode() {

        return this.instance.toString().hashCode();

    }


    /**
     * <p>Return <code>true</code> if the expression string for this expression
     * contains only literal text.</p>
     */
    public boolean isLiteralText() {

        return true;

    }


    // ------------------------------------------------- ValueExpression Methods


    /**
     * <p>Return the type that the result of this expression will
     * be coerced to.</p>
     */
    public Class getExpectedType() {

        return this.expectedType;

    }


    /**
     * <p>Evaluate this expression relative to the specified context,
     * and return the most general type that is acceptable for the
     * value passed in a <code>setValue()</code> call.</p>
     *
     * @param context ELContext for this evaluation
     */
    public Class getType(ELContext context) {

        if (context == null) {
            throw new NullPointerException();
        }
        return this.instance.getClass();

    }


    /**
     * <p>Evaluate this expression relative to the specified context,
     * and return the result.</p>
     *
     * @param context ELContext for this evaluation
     */
    public Object getValue(ELContext context) {

        if (context == null) {
            throw new NullPointerException();
        }
        FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
        return fcontext.getApplication().getExpressionFactory().coerceToType(instance, expectedType);

    }


    /**
     * <p>Evaluate this expression relative to the specified context,
     * and return <code>true</code> if a call to <code>setValue()</code>
     * will always fail.</p>
     *
     * @param context ELContext for this evaluation
     */
    public boolean isReadOnly(ELContext context) {

        if (context == null) {
            throw new NullPointerException();
        }
        return true;

    }



    /**
     * <p>Evaluate this expression relative to the specified context,
     * and set the result to the specified value.</p>
     *
     * @param context ELContext for this evaluation
     * @param value Value to which the result should be set
     */
    public void setValue(ELContext context, Object value) {

        if (context == null) {
            throw new NullPointerException();
        }

        throw new PropertyNotWritableException();

    }


}
