Package org.eclipse.jst.jsf.validation.internal.el.operators

Source Code of org.eclipse.jst.jsf.validation.internal.el.operators.TernaryChoiceOperator

/*******************************************************************************
* Copyright (c) 2006 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Cameron Bateman/Oracle - initial API and implementation
*   
********************************************************************************/

package org.eclipse.jst.jsf.validation.internal.el.operators;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jst.jsf.common.internal.types.IAssignable;
import org.eclipse.jst.jsf.common.internal.types.LiteralType;
import org.eclipse.jst.jsf.common.internal.types.TypeCoercer;
import org.eclipse.jst.jsf.common.internal.types.TypeCoercionException;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.internal.types.TypeTransformer;
import org.eclipse.jst.jsf.common.internal.types.ValueType;
import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory;

/**
* Represents the ternary choice op in EL: a ? b :c
* Based on JSP.2.3.8
*
* @author cbateman
*
*/
public class TernaryChoiceOperator
{
    private final DiagnosticFactory     _diagnosticFactory;
   
   
    /**
     * @param diagnosticFactory
     */
    public TernaryChoiceOperator(DiagnosticFactory diagnosticFactory)
    {
        super();
        _diagnosticFactory = diagnosticFactory;
    }

    /**
     * @param choiceArg
     * @param whenTrueArg
     * @param whenFalseArg
     * @return the result of the choice arguments or null if indeterminant
     */
    public ValueType perform(ValueType choiceArg, ValueType whenTrueArg, ValueType whenFalseArg)
    {
        final boolean isChoiceBoolean =
            TypeCoercer.canCoerceToBoolean(TypeTransformer.transformBoxPrimitives(choiceArg.getSignature()));
       
        if (isChoiceBoolean)
        {
            if (choiceArg instanceof LiteralType)
            {
                try
                {
                    Boolean result = ((LiteralType)choiceArg).coerceToBoolean();
                   
                    if (result != null)
                    {
                        return result.booleanValue() ? whenTrueArg : whenFalseArg;
                    }
                }
                catch (TypeCoercionException tce)
                {
                    return null;
                }
            }
           
            final String boxedWhenTrueArg =
                TypeTransformer.transformBoxPrimitives(whenTrueArg.getSignature());
           
            final String boxedWhenFalseArg =
                TypeTransformer.transformBoxPrimitives(whenFalseArg.getSignature());
            // check if the two results are the same type
            // TODO: could increase accuracy by appoximating type:i.e. if both
            // are numeric etc.
            if (boxedWhenTrueArg.equals(boxedWhenFalseArg))
            {
                return new ValueType(whenTrueArg, IAssignable.ASSIGNMENT_TYPE_RHS);
            }

            // otherwise, we have no idea what the resulting type is
            return null;
        }
       
        // if choice is not boolean, then can't resolve
        return null;
    }
   
    /**
     * @param choiceArg
     * @return a diagnostic validating the choice expr with these arguments
     */
    public Diagnostic validate(ValueType choiceArg)
    {
      if (TypeConstants.TYPE_JAVAOBJECT.equals(choiceArg.getSignature())) {
        return Diagnostic.OK_INSTANCE;
      }

        final boolean isChoiceBoolean =
            TypeCoercer.canCoerceToBoolean(TypeTransformer.transformBoxPrimitives(choiceArg.getSignature()));
       
        if (isChoiceBoolean)
        {
            if (choiceArg instanceof LiteralType)
            {
                try
                {
                    Boolean result = ((LiteralType)choiceArg).coerceToBoolean();
                   
                    if (result != null)
                    {
                        String whichSelected = result.booleanValue() ? "first" : "second"; //$NON-NLS-1$ //$NON-NLS-2$
                        return _diagnosticFactory.
                            create_TERNARY_OP_CHOICE_IS_ALWAYS_SAME
                                (result.booleanValue(), whichSelected);
                    }
                }
                catch (TypeCoercionException tce)
                {
                    return _diagnosticFactory.
                        create_TERNARY_OP_CANNOT_COERCE_CHOICE_TO_BOOLEAN();
                }
            }

            // in both the case where the two arguments are the same and when
            // they are different types, the best we can say is "OK", since
            // we really don't know
            return Diagnostic.OK_INSTANCE;
        }
       
        // if choice is not boolean, then can't resolve
        return _diagnosticFactory.
            create_TERNARY_OP_CANNOT_COERCE_CHOICE_TO_BOOLEAN();
    }
}
TOP

Related Classes of org.eclipse.jst.jsf.validation.internal.el.operators.TernaryChoiceOperator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.