/** {@inheritDoc} */ @Override public Expression buildSelectionCriteria( String entityName, String selectionCriteria, AbstractSession session) { try { // Create the parsed tree representation of the selection criteria JPQLExpression jpqlExpression = new JPQLExpression( selectionCriteria, DefaultEclipseLinkJPQLGrammar.instance(), ConditionalExpressionBNF.ID, isTolerant()); // Caches the info and add a virtual range variable declaration JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar()); queryContext.cache(session, null, jpqlExpression, selectionCriteria); queryContext.addRangeVariableDeclaration(entityName, "this"); // Validate the JPQL query, which will use the JPQL grammar matching the validation // level, for now, only validate the query statement because there could be an unknown // ending that is an order by clause validate(queryContext, jpqlExpression.getQueryStatement()); // Create the Expression representing the selection criteria return queryContext.buildExpression(jpqlExpression.getQueryStatement()); } catch (JPQLException exception) { throw exception; } catch (Exception exception) { throw buildUnexpectedException(selectionCriteria, exception); } }
private DatabaseQuery populateQueryImp( CharSequence jpqlQuery, DatabaseQuery query, AbstractSession session) { try { // Parse the JPQL query with the most recent JPQL grammar JPQLExpression jpqlExpression = new JPQLExpression(jpqlQuery, DefaultEclipseLinkJPQLGrammar.instance(), isTolerant()); // Create a context that caches the information contained in the JPQL query // (especially from the FROM clause) JPQLQueryContext queryContext = new JPQLQueryContext(jpqlGrammar()); queryContext.cache(session, query, jpqlExpression, jpqlQuery); // Validate the JPQL query, which will use the JPQL grammar matching the validation level validate(queryContext, jpqlExpression); // Create the DatabaseQuery by visiting the parsed tree DatabaseQueryVisitor visitor = new DatabaseQueryVisitor(queryContext, jpqlQuery); jpqlExpression.accept(visitor); // Add the input parameter types to the DatabaseQuery if (query == null) { query = queryContext.getDatabaseQuery(); addArguments(queryContext, query); } return query; } catch (JPQLException exception) { throw exception; } catch (Exception exception) { throw buildUnexpectedException(jpqlQuery, exception); } }
/** {@inheritDoc} */ @Override public void visit(SelectStatement expression) { ObjectLevelReadQuery query = queryContext.getDatabaseQuery(); // Create and prepare the query if (query == null) { query = buildReadAllQuery(expression); queryContext.setDatabasQuery(query); query.setJPQLString(jpqlQuery); ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true); } // Now populate it expression.accept(buildVisitor(query)); }
/** {@inheritDoc} */ @Override public void visit(UpdateStatement expression) { UpdateAllQuery query = queryContext.getDatabaseQuery(); // Create and prepare the query if (query == null) { query = new UpdateAllQuery(); queryContext.setDatabasQuery(query); query.setJPQLString(jpqlQuery); ((JPQLCallQueryMechanism) query.getQueryMechanism()).getJPQLCall().setIsParsed(true); } query.setSession(queryContext.getSession()); query.setShouldDeferExecutionInUOW(false); // Now populate it UpdateQueryVisitor visitor = new UpdateQueryVisitor(queryContext, query); expression.accept(visitor); }
/** * Creates a {@link JPQLException} indicating the problems with the JPQL query. * * @param queryContext The {@link JPQLQueryContext} containing the information about the JPQL * query * @param problems The {@link JPQLQueryProblem problems} found in the JPQL query that are * translated into an exception * @param messageKey The key used to retrieve the localized message * @return The {@link JPQLException} indicating the problems with the JPQL query */ private JPQLException buildException( JPQLQueryContext queryContext, Collection<JPQLQueryProblem> problems, String messageKey) { ResourceBundle bundle = resourceBundle(); StringBuilder sb = new StringBuilder(); for (JPQLQueryProblem problem : problems) { // Retrieve the localized message String message; try { message = bundle.getString(problem.getMessageKey()); } catch (NullPointerException e) { // In case the resource bundle was not updated message = problem.getMessageKey(); } // Now format the localized message String[] arguments = problem.getMessageArguments(); if (arguments.length > 0) { message = MessageFormat.format(message, (Object[]) arguments); } // Append the description sb.append("\n"); sb.append("["); sb.append(problem.getStartPosition()); sb.append(", "); sb.append(problem.getEndPosition()); sb.append("] "); sb.append(message); } String errorMessage = bundle.getString(messageKey); errorMessage = MessageFormat.format(errorMessage, queryContext.getJPQLQuery(), sb); return new JPQLException(errorMessage); }