Package org.eclipse.persistence.jpa.internal.jpql.parser

Source Code of org.eclipse.persistence.jpa.internal.jpql.parser.ExpressionRegistry

/*******************************************************************************
* Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation
*
******************************************************************************/
package org.eclipse.persistence.jpa.internal.jpql.parser;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.spi.IJPAVersion;

/**
* This registry initializes the singleton instances of various API required for parsing a JPQL
* query. It supports version 1.0 and 2.0 of the JPQL language as well as the
* EclipseLink's extension over the language.
*
* @version 2.3
* @since 2.3
* @author Pascal Filion
*/
@SuppressWarnings("nls")
final class ExpressionRegistry {

  /**
   * The map of {@link ExpressionFactory ExpressionFactories} that have been registered and
   * required for parsing a JPQL query, they are mapped with their unique identifier.
   */
  private Map<String, ExpressionFactory> expressionFactories;

  /**
   * The set of the JPQL identifiers defined by the grammar.
   */
  private Map<String, IdentifierRole> identifiers;

  /**
   * This table specify in which JPA version the identifiers was introduced.
   */
  private Map<String, IJPAVersion> identifiersVersions;

  /**
   * The {@link JPQLQueryBNF} unique identifiers mapped to the only instance of the BNF rule.
   */
  private Map<String, JPQLQueryBNF> queryBNFs;

  /**
   * Creates the only instance of <code>ExpressionRegistry</code>.
   */
  ExpressionRegistry() {
    super();
    initialize();
  }

  /**
   * Retrieves the registered {@link ExpressionFactory} that was registered for the given unique
   * identifier.
   *
   * @param expressionFactoryId The unique identifier of the {@link ExpressionFactory} to retrieve
   * @return The {@link ExpressionFactory} mapped with the given unique identifier
   */
  ExpressionFactory expressionFactory(String expressionFactoryId) {
    return expressionFactories.get(expressionFactoryId);
  }

  /**
   * Retrieves the {@link ExpressionFactory} that is responsible for creating the {@link Expression}
   * object that represents the given JPQL identifier.
   *
   * @param identifier The JPQL identifier for which its factory is searched
   * @return Either the {@link ExpressionFactory} that creates the {@link Expression} or
   * <code>null</code> if none was found
   */
  ExpressionFactory expressionFactoryForIdentifier(String identifier) {

    identifier = identifier.toUpperCase();

    if (Expression.SELECT.equalsIgnoreCase(identifier)) {
      return expressionFactory(SimpleSelectStatementFactory.ID);
    }

    for (ExpressionFactory expressionFactory : expressionFactories.values()) {
      boolean found = Arrays.binarySearch(expressionFactory.identifiers(), identifier) > -1;

      if (found) {
        return expressionFactory;
      }
    }

    return null;
  }

  /**
   * Retrieves the role of the given identifier. A role helps to describe the purpose of the
   * identifier in a query.
   *
   * @param identifier The identifier for which its role is requested
   * @return The role of the given identifier
   */
  IdentifierRole identifierRole(String identifier) {
    return identifiers.get(identifier.toUpperCase());
  }

  /**
   * Returns the JPQL identifiers defined for JPQL version 1.0 and 2.0.
   *
   * @return The set of identifiers
   */
  Collection<String> identifiers() {
    return identifiers.keySet();
  }

  /**
   * Retrieves the identifiers that are supported by the given BNF.
   *
   * @param queryBNFId The unique identifier of the BNF for which the supported identifiers are
   * requested
   * @return The list of JPQL identifiers that can be used with the BNF
   */
  Iterable<String> identifiers(String queryBNFId) {
    return queryBNF(queryBNFId).identifiers();
  }

  /**
   * Retrieves the JPA version in which the identifier was first introduced.
   *
   * @return The version in which the identifier was introduced
   */
  IJPAVersion identifierVersion(String identifier) {
    IJPAVersion version = identifiersVersions.get(identifier.toUpperCase());
    return (version != null) ? version : IJPAVersion.VERSION_1_0;
  }

  /**
   * Instantiates the only instance of various API used by the parser.
   */
  private void initialize() {
    queryBNFs           = new HashMap<String, JPQLQueryBNF>();
    identifiers         = new HashMap<String, IdentifierRole>();
    expressionFactories = new HashMap<String, ExpressionFactory>();
    identifiersVersions = new HashMap<String, IJPAVersion>();

    initializeIdentifiers();
    initializeExpressionFactories();
    initializeBNFs();

    identifiers = Collections.unmodifiableMap(identifiers);
  }

  /**
   * Creates a map where the key is a unique ID and the value is an {@link JPQLQueryBNF}
   * representing a portion of the JPQL grammar.
   */
  private void initializeBNFs() {
    registerBNF(new AbstractSchemaNameBNF());
    registerBNF(new AggregateExpressionBNF());
    registerBNF(new AllOrAnyExpressionBNF());
    registerBNF(new ArithmeticExpressionBNF());
    registerBNF(new ArithmeticFactorBNF());
    registerBNF(new ArithmeticPrimaryBNF());
    registerBNF(new ArithmeticTermBNF());
    registerBNF(new BadExpressionBNF());
    registerBNF(new BetweenExpressionBNF());
    registerBNF(new BooleanExpressionBNF());
    registerBNF(new BooleanLiteralBNF());
    registerBNF(new BooleanPrimaryBNF());
    registerBNF(new CaseExpressionBNF());
    registerBNF(new CaseOperandBNF());
    registerBNF(new CoalesceExpressionBNF());
    registerBNF(new CollectionMemberDeclarationBNF());
    registerBNF(new CollectionMemberExpressionBNF());
    registerBNF(new CollectionValuedPathExpressionBNF());
    registerBNF(new ComparisonExpressionBNF());
    registerBNF(new ConditionalExpressionBNF());
    registerBNF(new ConditionalFactorBNF());
    registerBNF(new ConditionalPrimaryBNF());
    registerBNF(new ConditionalTermBNF());
    registerBNF(new ConstructorExpressionBNF());
    registerBNF(new ConstructorItemBNF());
    registerBNF(new DatetimeExpressionBNF());
    registerBNF(new DateTimePrimaryBNF());
    registerBNF(new DateTimeTimestampLiteralBNF());
    registerBNF(new DeleteClauseBNF());
    registerBNF(new DeleteClauseRangeVariableDeclarationBNF());
    registerBNF(new DeleteStatementBNF());
    registerBNF(new DerivedCollectionMemberDeclarationBNF());
    registerBNF(new ElseExpressionBNF());
    registerBNF(new EmptyCollectionComparisonExpressionBNF());
    registerBNF(new EntityExpressionBNF());
    registerBNF(new EntityOrValueExpressionBNF());
    registerBNF(new EntityTypeExpressionBNF());
    registerBNF(new EntityTypeLiteralBNF());
    registerBNF(new EnumExpressionBNF());
    registerBNF(new EnumLiteralBNF());
    registerBNF(new EnumPrimaryBNF());
    registerBNF(new ExistsExpressionBNF());
    registerBNF(new FromClauseBNF());
    registerBNF(new FunctionsReturningDatetimeBNF());
    registerBNF(new FunctionsReturningNumericsBNF());
    registerBNF(new FunctionsReturningStringsBNF());
    registerBNF(new GeneralCaseExpressionBNF());
    registerBNF(new GeneralIdentificationVariableBNF());
    registerBNF(new GroupByClauseBNF());
    registerBNF(new GroupByItemBNF());
    registerBNF(new HavingClauseBNF());
    registerBNF(new IdentificationVariableBNF());
    registerBNF(new IdentificationVariableDeclarationBNF());
    registerBNF(new InExpressionBNF());
    registerBNF(new InExpressionExpressionBNF());
    registerBNF(new InItemBNF());
    registerBNF(new InputParameterBNF());
    registerBNF(new InternalBetweenExpressionBNF());
    registerBNF(new InternalCoalesceExpressionBNF());
    registerBNF(new InternalConcatExpressionBNF());
    registerBNF(new InternalCountBNF());
    registerBNF(new InternalEntityTypeExpressionBNF());
    registerBNF(new InternalFromClauseBNF());
    registerBNF(new InternalJoinBNF());
    registerBNF(new InternalOrderByClauseBNF());
    registerBNF(new InternalOrderByItemBNF());
    registerBNF(new InternalSimpleFromClauseBNF());
    registerBNF(new InternalUpdateClauseBNF());
    registerBNF(new InternalWhenClauseBNF());
    registerBNF(new JoinAssociationPathExpressionBNF());
    registerBNF(new JoinBNF());
    registerBNF(new JoinFetchBNF());
    registerBNF(new JPQLStatementBNF());
    registerBNF(new LikeExpressionBNF());
    registerBNF(new LiteralBNF());
    registerBNF(new NewValueBNF());
    registerBNF(new NullComparisonExpressionBNF());
    registerBNF(new NullIfExpressionBNF());
    registerBNF(new NumericLiteralBNF());
    registerBNF(new ObjectExpressionBNF());
    registerBNF(new OrderByClauseBNF());
    registerBNF(new OrderByItemBNF());
    registerBNF(new PatternValueBNF());
    registerBNF(new PreLiteralExpressionBNF());
    registerBNF(new QualifiedIdentificationVariableBNF());
    registerBNF(new RangeVariableDeclarationBNF());
    registerBNF(new ResultVariableBNF());
    registerBNF(new ScalarExpressionBNF());
    registerBNF(new SelectClauseBNF());
    registerBNF(new SelectExpressionBNF());
    registerBNF(new SelectItemBNF());
    registerBNF(new SelectStatementBNF());
    registerBNF(new SimpleArithmeticExpressionBNF());
    registerBNF(new SimpleCaseExpressionBNF());
    registerBNF(new SimpleConditionalExpressionBNF());
    registerBNF(new SimpleEntityExpressionBNF());
    registerBNF(new SimpleEntityOrValueExpressionBNF());
    registerBNF(new SimpleSelectClauseBNF());
    registerBNF(new SimpleSelectExpressionBNF());
    registerBNF(new SingleValuedObjectPathExpressionBNF());
    registerBNF(new SingleValuedPathExpressionBNF());
    registerBNF(new StateFieldPathExpressionBNF());
    registerBNF(new StringExpressionBNF());
    registerBNF(new StringLiteralBNF());
    registerBNF(new StringPrimaryBNF());
    registerBNF(new SubQueryBNF());
    registerBNF(new SubQueryFromClauseBNF());
    registerBNF(new SubSelectIdentificationVariableDeclarationBNF());
    registerBNF(new TypeExpressionBNF());
    registerBNF(new UpdateClauseBNF());
    registerBNF(new UpdateItemBNF());
    registerBNF(new UpdateItemStateFieldPathExpressionBNF());
    registerBNF(new UpdateStatementBNF());
    registerBNF(new WhenClauseBNF());
    registerBNF(new WhereClauseBNF());

    // EclipseLink's extension
    registerBNF(new FuncExpressionBNF());
    registerBNF(new FuncItemBNF());
    registerBNF(new TreatExpressionBNF());
  }

  /**
   * Creates a map where the key is an identifier and the value is an {@link ExpressionFactory}
   * responsible to create the actual {@link Expression}.
   */
  private void initializeExpressionFactories() {

    // JPA version 1.0
    registerFactory(new AbsExpressionFactory());
    registerFactory(new AbstractSchemaNameFactory());
    registerFactory(new AllOrAnyExpressionFactory());
    registerFactory(new AndExpressionFactory());
    registerFactory(new ArithmeticExpressionFactory());
    registerFactory(new AvgFunctionFactory());
    registerFactory(new BadExpressionFactory());
    registerFactory(new BetweenExpressionFactory());
    registerFactory(new CollectionMemberDeclarationFactory());
    registerFactory(new CollectionMemberExpressionFactory());
    registerFactory(new CollectionValuedPathExpressionFactory());
    registerFactory(new ComparisonExpressionFactory());
    registerFactory(new ConcatExpressionFactory());
    registerFactory(new ConstructorExpressionFactory());
    registerFactory(new CountFunctionFactory());
    registerFactory(new DateTimeFactory());
    registerFactory(new DeleteClauseFactory());
    registerFactory(new DeleteStatementFactory());
    registerFactory(new EmptyCollectionComparisonExpressionFactory());
    registerFactory(new ExistsExpressionFactory());
    registerFactory(new FromClauseFactory());
    registerFactory(new GroupByClauseFactory());
    registerFactory(new GroupByItemFactory());
    registerFactory(new HavingClauseFactory());
    registerFactory(new IdentificationVariableDeclarationFactory());
    registerFactory(new IdentificationVariableFactory());
    registerFactory(new InExpressionFactory());
    registerFactory(new InternalOrderByItemFactory());
    registerFactory(new IsExpressionFactory());
    registerFactory(new JoinFactory());
    registerFactory(new KeywordExpressionFactory());
    registerFactory(new LengthExpressionFactory());
    registerFactory(new LikeExpressionFactory());
    registerFactory(new LiteralExpressionFactory());
    registerFactory(new LocateExpressionFactory());
    registerFactory(new LowerExpressionFactory());
    registerFactory(new MaxFunctionFactory());
    registerFactory(new MinFunctionFactory());
    registerFactory(new ModExpressionFactory());
    registerFactory(new NotExpressionFactory());
    registerFactory(new NullComparisonExpressionFactory());
    registerFactory(new ObjectExpressionFactory());
    registerFactory(new OrderByClauseFactory());
    registerFactory(new OrderByItemFactory());
    registerFactory(new OrExpressionFactory());
    registerFactory(new PreLiteralExpressionFactory());
    registerFactory(new RangeVariableDeclarationFactory());
    registerFactory(new SelectClauseFactory());
    registerFactory(new SelectStatementFactory());
    registerFactory(new SimpleSelectStatementFactory());
    registerFactory(new SizeExpressionFactory());
    registerFactory(new SqrtExpressionFactory());
    registerFactory(new StateFieldPathExpressionFactory());
    registerFactory(new StringLiteralFactory());
    registerFactory(new SubstringExpressionFactory());
    registerFactory(new SumFunctionFactory());
    registerFactory(new TrimExpressionFactory());
    registerFactory(new UnknownExpressionFactory());
    registerFactory(new UpdateClauseFactory());
    registerFactory(new UpdateItemFactory());
    registerFactory(new UpdateItemStateFieldPathExpressionFactory());
    registerFactory(new UpdateStatementFactory());
    registerFactory(new UpperExpressionFactory());
    registerFactory(new WhereClauseFactory());

    // JPA version 2.0
    registerFactory(new CaseExpressionFactory());
    registerFactory(new CoalesceExpressionFactory());
    registerFactory(new EntityTypeLiteralFactory());
    registerFactory(new EntryExpressionFactory());
    registerFactory(new KeyExpressionFactory());
    registerFactory(new IndexExpressionFactory());
    registerFactory(new NullIfExpressionFactory());
    registerFactory(new ResultVariableFactory());
    registerFactory(new TypeExpressionFactory());
    registerFactory(new ValueExpressionFactory());
    registerFactory(new WhenClauseFactory());

    // EclipseLink's extension
    registerFactory(new FuncExpressionFactory());
    registerFactory(new TreatExpressionFactory());
  }

  /**
   * Creates the list of JPQL identifiers, which cannot be used as identification variables.
   */
  private void initializeIdentifiers() {

    // JPA version 1.0
    identifiers.put(Expression.ABS,                   IdentifierRole.FUNCTION);           // ABS(x)
    identifiers.put(Expression.ALL,                   IdentifierRole.FUNCTION);           // ALL(x)
    identifiers.put(Expression.AND,                   IdentifierRole.AGGREGATE);          // x AND y
    identifiers.put(Expression.ANY,                   IdentifierRole.FUNCTION);           // ANY(x)
    identifiers.put(Expression.AS,                    IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.ASC,                   IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.AVG,                   IdentifierRole.FUNCTION);           // AVG(x)
    identifiers.put(Expression.BETWEEN,               IdentifierRole.COMPOUND_FUNCTION)// x BETWEEN y AND z
    identifiers.put(Expression.BIT_LENGTH,            IdentifierRole.UNUSED);
    identifiers.put(Expression.BOTH,                  IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.CHAR_LENGTH,           IdentifierRole.UNUSED);
    identifiers.put(Expression.CHARACTER_LENGTH,      IdentifierRole.UNUSED);
    identifiers.put(Expression.CLASS,                 IdentifierRole.UNUSED);
    identifiers.put(Expression.CONCAT,                IdentifierRole.FUNCTION);           // CONCAT(x, y)
    identifiers.put(Expression.COUNT,                 IdentifierRole.FUNCTION);           // COUNT(x)
    identifiers.put(Expression.CURRENT_DATE,          IdentifierRole.FUNCTION);
    identifiers.put(Expression.CURRENT_TIME,          IdentifierRole.FUNCTION);
    identifiers.put(Expression.CURRENT_TIMESTAMP,     IdentifierRole.FUNCTION);
    identifiers.put(Expression.DELETE,                IdentifierRole.CLAUSE);
    identifiers.put(Expression.DELETE_FROM,           IdentifierRole.CLAUSE);
    identifiers.put(Expression.DESC,                  IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.DISTINCT,              IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.EMPTY,                 IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.ESCAPE,                IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.EXISTS,                IdentifierRole.FUNCTION);           // EXISTS(x)
    identifiers.put(Expression.FALSE,                 IdentifierRole.FUNCTION);
    identifiers.put(Expression.FETCH,                 IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.FROM,                  IdentifierRole.CLAUSE);
    identifiers.put(Expression.HAVING,                IdentifierRole.CLAUSE);
    identifiers.put(Expression.IN,                    IdentifierRole.COMPOUND_FUNCTION)// x IN { (y {, z}* | (s) | t }
    identifiers.put(Expression.INNER,                 IdentifierRole.COMPOUND_FUNCTION)// Part of JOIN
    identifiers.put(Expression.IS,                    IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.JOIN,                  IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.LEADING,               IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.LEFT,                  IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.LENGTH,                IdentifierRole.FUNCTION);           // LENGTH(x)
    identifiers.put(Expression.LIKE,                  IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.LOCATE,                IdentifierRole.FUNCTION);           // LOCATE(x, y [, z]))
    identifiers.put(Expression.LOWER,                 IdentifierRole.FUNCTION);           // LOWER(x)
    identifiers.put(Expression.MAX,                   IdentifierRole.FUNCTION);           // MAX(x)
    identifiers.put(Expression.MEMBER,                IdentifierRole.COMPOUND_FUNCTION)// x MEMBER y
    identifiers.put(Expression.MIN,                   IdentifierRole.FUNCTION);           // MIN(x)
    identifiers.put(Expression.MOD,                   IdentifierRole.FUNCTION);           // MOD(x, y)
    identifiers.put(Expression.NEW,                   IdentifierRole.FUNCTION);           // NEW x (y {, z}*)
    identifiers.put(Expression.NOT,                   IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.NULL,                  IdentifierRole.FUNCTION);
    identifiers.put(Expression.OBJECT,                IdentifierRole.FUNCTION);           // OBJECT(x)
    identifiers.put(Expression.OF,                    IdentifierRole.COMPOUND_FUNCTION)// Part of MEMBER [OF]
    identifiers.put(Expression.OR,                    IdentifierRole.AGGREGATE);          // x OR y
    identifiers.put(Expression.OUTER,                 IdentifierRole.COMPLETEMENT);       // Part of JOIN
    identifiers.put(Expression.POSITION,              IdentifierRole.UNUSED);
    identifiers.put(Expression.SELECT,                IdentifierRole.CLAUSE);
    identifiers.put(Expression.SET,                   IdentifierRole.CLAUSE);
    identifiers.put(Expression.SIZE,                  IdentifierRole.FUNCTION);           // SIZE(x)
    identifiers.put(Expression.SOME,                  IdentifierRole.FUNCTION);           // SOME(x)
    identifiers.put(Expression.SQRT,                  IdentifierRole.FUNCTION);           // SQRT(x)
    identifiers.put(Expression.SUBSTRING,             IdentifierRole.FUNCTION);           // SUBSTRING(x, y {, z})
    identifiers.put(Expression.SUM,                   IdentifierRole.FUNCTION);
    identifiers.put(Expression.TRAILING,              IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.TRIM,                  IdentifierRole.FUNCTION);           // TRIM([[x [c] FROM] y)
    identifiers.put(Expression.TRUE,                  IdentifierRole.FUNCTION);
    identifiers.put(Expression.UNKNOWN,               IdentifierRole.UNUSED);
    identifiers.put(Expression.UPDATE,                IdentifierRole.CLAUSE);
    identifiers.put(Expression.UPPER,                 IdentifierRole.FUNCTION);           // UPPER(x)
    identifiers.put(Expression.WHERE,                 IdentifierRole.CLAUSE);
    identifiers.put(Expression.PLUS,                  IdentifierRole.AGGREGATE);
    identifiers.put(Expression.MINUS,                 IdentifierRole.AGGREGATE);
    identifiers.put(Expression.MULTIPLICATION,        IdentifierRole.AGGREGATE);
    identifiers.put(Expression.DIVISION,              IdentifierRole.AGGREGATE);
    identifiers.put(Expression.LOWER_THAN,            IdentifierRole.AGGREGATE);
    identifiers.put(Expression.LOWER_THAN_OR_EQUAL,   IdentifierRole.AGGREGATE);
    identifiers.put(Expression.GREATER_THAN,          IdentifierRole.AGGREGATE);
    identifiers.put(Expression.GREATER_THAN_OR_EQUAL, IdentifierRole.AGGREGATE);
    identifiers.put(Expression.DIFFERENT,             IdentifierRole.AGGREGATE);
    identifiers.put(Expression.EQUAL,                 IdentifierRole.AGGREGATE);

    // Composite Identifiers
    identifiers.put(Expression.GROUP_BY,              IdentifierRole.CLAUSE);
    identifiers.put(Expression.LEFT_JOIN,             IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.LEFT_JOIN_FETCH,       IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.LEFT_OUTER_JOIN,       IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.LEFT_OUTER_JOIN_FETCH, IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.INNER_JOIN,            IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.INNER_JOIN_FETCH,      IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.IS_EMPTY,              IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.IS_NOT_EMPTY,          IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.IS_NOT_NULL,           IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.IS_NULL,               IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.JOIN_FETCH,            IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.MEMBER_OF,             IdentifierRole.COMPOUND_FUNCTION)// x NOT MEMBER OF y
    identifiers.put(Expression.NOT_BETWEEN,           IdentifierRole.COMPOUND_FUNCTION)// x NOT BETWEEN y AND z
    identifiers.put(Expression.NOT_EXISTS,            IdentifierRole.FUNCTION);           // NOT EXISTS(x)
    identifiers.put(Expression.NOT_IN,                IdentifierRole.COMPOUND_FUNCTION)// x NOT IN { (y {, z}* | (s) | t }
    identifiers.put(Expression.NOT_LIKE,              IdentifierRole.COMPOUND_FUNCTION)// x NOT LIKE y
    identifiers.put(Expression.NOT_MEMBER,            IdentifierRole.COMPOUND_FUNCTION)// x NOT MEMBER y
    identifiers.put(Expression.NOT_MEMBER_OF,         IdentifierRole.COMPOUND_FUNCTION)// x NOT MEMBER OF y
    identifiers.put(Expression.ORDER_BY,              IdentifierRole.CLAUSE);

    // Partial Identifiers
    identifiers.put("BY",                             IdentifierRole.CLAUSE);             // Part of GROUP BY, ORDER BY
    identifiers.put("DELETE",                         IdentifierRole.CLAUSE);             // Part of DELETE FROM
    identifiers.put("GROUP",                          IdentifierRole.CLAUSE);             // Part of GROUP BY
    identifiers.put("ORDER",                          IdentifierRole.CLAUSE);             // Part of ORDERY BY

    // JPA version 2.0
    identifiers.put(Expression.CASE,                  IdentifierRole.FUNCTION);           // ???
    identifiers.put(Expression.COALESCE,              IdentifierRole.FUNCTION);           // COALLESCE(x {, y}+)
    identifiers.put(Expression.ELSE,                  IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.END,                   IdentifierRole.COMPLETEMENT);
    identifiers.put(Expression.ENTRY,                 IdentifierRole.FUNCTION);           // ENTRY(x)
    identifiers.put(Expression.INDEX,                 IdentifierRole.FUNCTION);           // INDEX(x)
    identifiers.put(Expression.KEY,                   IdentifierRole.FUNCTION);           // KEY(x)
    identifiers.put(Expression.NULLIF,                IdentifierRole.FUNCTION);           // NULLIF(x, y)
    identifiers.put(Expression.THEN,                  IdentifierRole.COMPOUND_FUNCTION);
    identifiers.put(Expression.TYPE,                  IdentifierRole.FUNCTION);           // TYPE(x)
    identifiers.put(Expression.VALUE,                 IdentifierRole.FUNCTION);           // VALUE(x)
    identifiers.put(Expression.WHEN,                  IdentifierRole.COMPOUND_FUNCTION)// Part of CASE WHEN ELSE END

    identifiersVersions.put(Expression.CASE,          IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.COALESCE,      IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.ELSE,          IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.END,           IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.ENTRY,         IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.INDEX,         IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.KEY,           IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.NULLIF,        IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.THEN,          IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.TYPE,          IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.VALUE,         IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.WHEN,          IJPAVersion.VERSION_2_0);

    // EclipseLink's extensions
    identifiers.put(Expression.FUNC,                  IdentifierRole.FUNCTION);          // FUNC(n, x1, ..., x2)
    identifiers.put(Expression.TREAT,                 IdentifierRole.FUNCTION);          // TREAT(x TODO)

    identifiersVersions.put(Expression.FUNC,          IJPAVersion.VERSION_2_0);
    identifiersVersions.put(Expression.TREAT,         IJPAVersion.VERSION_2_0);
  }

  /**
   * Determines if the given word is a JPQL identifier. The check is case insensitive.
   *
   * @param word The word to test if it's a JPQL identifier
   * @return <code>true</code> if the word is an identifier, <code>false</code> otherwise
   */
  boolean isIdentifier(String word) {
    return identifiers.containsKey(word.toUpperCase());
  }

  /**
   * Retrieves the BNF object that was registered for the given unique identifier.
   *
   * @param queryBNFID The unique identifier of the {@link JPQLQueryBNF} to retrieve
   * @return The {@link JPQLQueryBNF} representing a section of the grammar
   */
  @SuppressWarnings("unchecked")
  <T extends JPQLQueryBNF> T queryBNF(String queryBNFID) {
    return (T) queryBNFs.get(queryBNFID);
  }

  /**
   * Registers the given {@link ExpressionFactory} by storing it for all its identifiers.
   *
   * @param expressionFactory The {@link ExpressionFactory} to store
   */
  private void registerBNF(JPQLQueryBNF queryBNF) {

    String id = queryBNF.getId();
    queryBNF = queryBNFs.put(id, queryBNF);

    if (queryBNF != null) {
      throw new IllegalArgumentException("A JPQLQueryBNF is already registered with the id " + id);
    }
  }

  /**
   * Registers the given {@link ExpressionFactory} by storing it for all its identifiers.
   *
   * @param expressionFactory The {@link ExpressionFactory} to store
   */
  private void registerFactory(ExpressionFactory expressionFactory) {

    String id = expressionFactory.getId();
    expressionFactory = expressionFactories.put(id, expressionFactory);

    if (expressionFactory != null) {
      throw new IllegalArgumentException("An ExpressionFactory is already registered with the id " + id);
    }
  }
}
TOP

Related Classes of org.eclipse.persistence.jpa.internal.jpql.parser.ExpressionRegistry

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.