| /******************************************************************************* |
| * 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.core.resources.IProject; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.jst.jsf.common.internal.types.ValueType; |
| import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory; |
| import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver; |
| import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext; |
| import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils; |
| import org.eclipse.jst.jsf.validation.internal.el.diagnostics.DiagnosticFactory; |
| import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserConstants; |
| import org.eclipse.jst.jsp.core.internal.java.jspel.Token; |
| import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion; |
| |
| /** |
| * Represents an abstract EL binary operator that always |
| * takes arguments and produces a single results |
| * |
| * @author cbateman |
| * |
| */ |
| public abstract class BinaryOperator |
| { |
| /** |
| * the factory used to construct diagnostics |
| */ |
| protected final DiagnosticFactory _diagnosticFactory; |
| |
| /** |
| * @param operatorToken |
| * @param diagnosticFactory |
| * @param context -- the current EL document context; must not be null |
| * @return a binary operator based on the provided token |
| * @throws IllegalArgumentException if the token is not a recognized |
| * EL binary operator token or if context is null |
| */ |
| public static BinaryOperator getBinaryOperator(Token operatorToken, DiagnosticFactory diagnosticFactory, IStructuredDocumentContext context) |
| { |
| if (context == null) |
| { |
| throw new IllegalArgumentException("Context must not be null"); //$NON-NLS-1$ |
| } |
| final String facetVersion = determineJSFVersion(context); |
| |
| switch (operatorToken.kind) |
| { |
| case JSPELParserConstants.AND1: |
| case JSPELParserConstants.AND2: |
| return new AndBinaryOperator(diagnosticFactory); |
| |
| case JSPELParserConstants.OR1: |
| case JSPELParserConstants.OR2: |
| return new OrBinaryOperator(diagnosticFactory); |
| |
| case JSPELParserConstants.EQ1: |
| case JSPELParserConstants.EQ2: |
| return new EqualsBinaryRelationalOperator(diagnosticFactory,facetVersion); |
| |
| case JSPELParserConstants.NEQ1: |
| case JSPELParserConstants.NEQ2: |
| return new NotEqualsBinaryRelationalOperator(diagnosticFactory,facetVersion); |
| |
| case JSPELParserConstants.GT1: |
| case JSPELParserConstants.GT2: |
| return new GreaterThanRelationalBinaryOperator(diagnosticFactory,facetVersion); |
| |
| case JSPELParserConstants.GE1: |
| case JSPELParserConstants.GE2: |
| return new GreaterThanEqRelationalBinaryOperator(diagnosticFactory,facetVersion); |
| |
| case JSPELParserConstants.LT1: |
| case JSPELParserConstants.LT2: |
| return new LessThanRelationalBinaryOperator(diagnosticFactory,facetVersion); |
| |
| case JSPELParserConstants.LE1: |
| case JSPELParserConstants.LE2: |
| return new LessThanEqRelationalBinaryOperator(diagnosticFactory,facetVersion); |
| |
| case JSPELParserConstants.PLUS: |
| return new AddArithmeticBinaryOperator(diagnosticFactory); |
| |
| case JSPELParserConstants.MINUS: |
| return new SubtractArithmeticBinaryOperator(diagnosticFactory); |
| |
| case JSPELParserConstants.MULTIPLY: |
| return new MultiplyArithmeticBinaryOperator(diagnosticFactory); |
| |
| case JSPELParserConstants.DIVIDE1: |
| case JSPELParserConstants.DIVIDE2: |
| return new DivArithmeticBinaryOperator(diagnosticFactory); |
| |
| case JSPELParserConstants.MODULUS1: |
| case JSPELParserConstants.MODULUS2: |
| return new ModArithmeticBinaryOperator(diagnosticFactory); |
| } |
| |
| throw new IllegalArgumentException("Unknown binary operator: "+operatorToken.image); //$NON-NLS-1$ |
| } |
| |
| /** |
| * |
| * Constructor |
| */ |
| BinaryOperator(DiagnosticFactory diagnosticFactory) |
| { |
| /* no construction or sub-classing outside package*/ |
| _diagnosticFactory = diagnosticFactory; |
| } |
| |
| /** |
| * If both arguments are literals and the operation can be performed, then |
| * the return must be a new LiteralType transformed using this operator. |
| * |
| * If one or both of the arg is not a literal and the operaton can be performed, then |
| * the return is a new ValueType transformed per the rules of the operator |
| * |
| * If the operation cannot be performed on ValueType, return null |
| * |
| * @param firstArg |
| * @param secondArg |
| * @return a new value type after the operation is performed |
| */ |
| public abstract ValueType performOperation(ValueType firstArg, ValueType secondArg); |
| |
| |
| /** |
| * @param firstArg |
| * @param secondArg |
| * @return a Diagnostic interpreting whether it is valid to perform the |
| * operation on the two arguments |
| */ |
| public abstract Diagnostic validate(ValueType firstArg, ValueType secondArg); |
| |
| private static String determineJSFVersion(IStructuredDocumentContext context) |
| { |
| final IWorkspaceContextResolver wkResolver = |
| IStructuredDocumentContextResolverFactory. |
| INSTANCE.getWorkspaceContextResolver(context); |
| |
| IProject project = wkResolver.getProject(); |
| |
| IProjectFacetVersion projectVersion = JSFAppConfigUtils.getProjectFacet(project); |
| |
| if (projectVersion != null) |
| { |
| return projectVersion.getVersionString(); |
| } |
| |
| return null; |
| } |
| } |