/******************************************************************************* | |
* Copyright (c) 2012, 2013 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.jpql.parser; | |
import org.eclipse.persistence.jpa.jpql.Assert; | |
import org.eclipse.persistence.jpa.jpql.ExpressionTools; | |
import org.eclipse.persistence.jpa.jpql.WordParser; | |
/** | |
* This {@link FunctionExpressionFactory} creates a new {@link FunctionExpression} when the portion | |
* of the query to parse starts with an identifier related to a SQL function. | |
* | |
* @see FunctionExpression | |
* | |
* @version 2.5 | |
* @since 2.4 | |
* @author James | |
*/ | |
@SuppressWarnings("nls") | |
public final class FunctionExpressionFactory extends ExpressionFactory { | |
/** | |
* The number of {@link ParameterCount parameters} a {@link FunctionExpression} can have. | |
*/ | |
private ParameterCount parameterCount; | |
/** | |
* The unique identifier of the {@link JPQLQueryBNF} that will be used to parse the arguments of | |
* the function expression. | |
*/ | |
private String parameterQueryBNFId; | |
/** | |
* The unique identifier for this {@link FunctionExpressionFactory}. | |
*/ | |
public static final String ID = Expression.FUNCTION; | |
/** | |
* Creates a new <code>FunctionExpressionFactory</code>. | |
* | |
* @param id The unique identifier of this factory | |
* @param parameterCount The number of {@link ParameterCount parameters} a {@link | |
* FunctionExpression} can have | |
* @param parameterQueryBNFId The unique identifier of the {@link JPQLQueryBNF} that will be used | |
* to parse the arguments of the function expression | |
* @param identifiers The JPQL identifiers handled by this factory | |
*/ | |
public FunctionExpressionFactory(String id, | |
ParameterCount parameterCount, | |
String parameterQueryBNFId, | |
String... identifiers) { | |
super(id, identifiers); | |
setParameterCount(parameterCount); | |
setParameterQueryBNFId(parameterQueryBNFId); | |
} | |
/** | |
* Creates a new <code>FunctionExpressionFactory</code>. | |
* | |
* @param id The unique identifier of this factory | |
* @param identifiers The JPQL identifiers handled by this factory | |
*/ | |
public FunctionExpressionFactory(String id, String... identifiers) { | |
this(id, ParameterCount.ZERO_OR_MANY, FunctionItemBNF.ID, identifiers); | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override | |
protected AbstractExpression buildExpression(AbstractExpression parent, | |
WordParser wordParser, | |
String word, | |
JPQLQueryBNF queryBNF, | |
AbstractExpression expression, | |
boolean tolerant) { | |
// Search for the constant that is registered with this factory | |
String identifier = null; | |
for (String possibleIdentifier : identifiers()) { | |
if (possibleIdentifier.equalsIgnoreCase(word)) { | |
identifier = possibleIdentifier; | |
break; | |
} | |
} | |
// No constant was found | |
if (identifier == null) { | |
return null; | |
} | |
// Make sure the new function is a real expression and not a variable name. | |
// Example: SELECT column FROM Column column | |
if (ExpressionTools.isFunctionExpression(wordParser, identifier)) { | |
expression = new FunctionExpression(parent, identifier, parameterCount, parameterQueryBNFId); | |
expression.parse(wordParser, tolerant); | |
return expression; | |
} | |
return null; | |
} | |
/** | |
* Sets the number of parameters a {@link FunctionExpression} can have, which will be during | |
* validation. | |
* | |
* @param parameterCount The number of parameters | |
*/ | |
public void setParameterCount(ParameterCount parameterCount) { | |
Assert.isNotNull(parameterCount, "The ParameterCount cannot be null"); | |
this.parameterCount = parameterCount; | |
} | |
/** | |
* Sets the BNF that will be used when parsing the function's arguments. | |
* | |
* @param parameterQueryBNFId The unique identifier of the {@link JPQLQueryBNF} that will be used | |
* to parse the arguments of the function expression | |
*/ | |
public void setParameterQueryBNFId(String parameterQueryBNFId) { | |
Assert.isNotNull(parameterQueryBNFId, "The JPQLQueryBNF for the parameters cannot be null"); | |
this.parameterQueryBNFId = parameterQueryBNFId; | |
} | |
/** | |
* The number of parameters a {@link FunctionExpression} can have. | |
*/ | |
public enum ParameterCount { | |
/** | |
* Only one parameter is allowed. | |
*/ | |
ONE, | |
/** | |
* [1, n] are allowed. | |
*/ | |
ONE_OR_MANY, | |
/** | |
* No parameters are allowed. | |
*/ | |
ZERO, | |
/** | |
* [0, n] are allowed. | |
*/ | |
ZERO_OR_MANY, | |
/** | |
* [0, 1] are allowed. | |
*/ | |
ZERO_OR_ONE | |
} | |
} |