org.eclipse.persistence.internal.jpa.jpql.Declaration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 2011, 2021 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 v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation
//
package org.eclipse.persistence.internal.jpa.jpql;
import java.util.Collections;
import java.util.List;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpression;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.mappings.DatabaseMapping;
/**
* A Declaration
is the corresponding representation of a single declaration defined in
* the FROM
clause of a query.
*
* @version 2.5
* @since 2.4
* @author Pascal Filion
*/
abstract class Declaration implements JPQLQueryDeclaration {
/**
* TODO.
*/
Expression baseExpression;
/**
* The declaration expression, which is either an {@link org.eclipse.persistence.jpa.jpql.parser.
* IdentificationVariableDeclaration IdentificationVariableDeclaration} or a {@link
* org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration CollectionMemberDeclaration}
* when part of a FROM clause, otherwise it's either the {@link org.eclipse.persistence.
* jpa.jpql.parser.DeleteClause DeleteClause} or the {@link org.eclipse.persistence.jpa.jpql.
* parser.UpdateClause UpdateClause}.
*/
Expression declarationExpression;
/**
* The cached {@link ClassDescriptor} that represents this {@link Declaration}'s "root" path.
*/
private ClassDescriptor descriptor;
/**
* The {@link IdentificationVariable} used to declare a "root" object.
*/
IdentificationVariable identificationVariable;
/**
* The cached {@link DatabaseMapping} if this {@link Declaration}'s "root" path points to a
* mapping, otherwise it will be null
.
*/
private DatabaseMapping mapping;
/**
* The {@link JPQLQueryContext} is used to query information about the application metadata and
* cached information.
*/
final JPQLQueryContext queryContext;
/**
* The {@link org.eclipse.persistence.expressions.Expression Expression} representing the
* information of this {@link Declaration}.
*/
private org.eclipse.persistence.expressions.Expression queryExpression;
/**
* The "root" object for objects which may not be reachable by navigation, it is either the
* abstract schema name (entity name), a derived path expression (which is only defined in a
* subquery) or null
if this {@link Declaration} is a collection member declaration.
*/
String rootPath;
/**
* Creates a new Declaration
.
*
* @param queryContext The context used to query information about the application metadata and
* cached information
*/
Declaration(JPQLQueryContext queryContext) {
super();
this.queryContext = queryContext;
}
/**
* Creates the Expression {@link Expression} for this {@link Declaration}.
*
* @return A new {@link org.eclipse.persistence.expressions.Expression Expression}
*/
abstract org.eclipse.persistence.expressions.Expression buildQueryExpression();
@Override
public Expression getBaseExpression() {
return baseExpression;
}
@Override
public Expression getDeclarationExpression() {
return declarationExpression;
}
/**
* Returns the {@link ClassDescriptor} that represents this {@link Declaration}'s "root" path.
*
* @return The descriptor of the "root" path
*/
final ClassDescriptor getDescriptor() {
if (descriptor == null) {
descriptor = resolveDescriptor();
}
return descriptor;
}
@Override
public List getJoins() {
return Collections.emptyList();
}
/**
* Returns the {@link DatabaseMapping} that this {@link Declaration} represents, which may be
* null
in the case it does not represent one.
*
* @return Either the {@link DatabaseMapping} of the "root" path, or null
if the
* "root" path is not a mapping
*/
final DatabaseMapping getMapping() {
if (mapping == null) {
mapping = resolveMapping();
}
return mapping;
}
/**
* Returns the Expression {@link Expression} for this {@link Declaration}.
*
* @return The {@link org.eclipse.persistence.expressions.Expression Expression} representing the
* information of this {@link Declaration}
*/
final org.eclipse.persistence.expressions.Expression getQueryExpression() {
if (queryExpression == null) {
// First create the Expression
queryExpression = buildQueryExpression();
// Cache the base expression with its identification variable as well
queryContext.addQueryExpressionImp(getVariableName(), queryExpression);
}
return queryExpression;
}
@Override
public final String getVariableName() {
if (identificationVariable == null) {
return ExpressionTools.EMPTY_STRING;
}
return identificationVariable.getVariableName();
}
@Override
public boolean hasJoins() {
return false;
}
/**
* Resolves this {@link Declaration} and returns the associated {@link ClassDescriptor}. For a
* {@link RangeVariableDeclaration}, this will return the actual descriptor for the entity. For
* a mapping, this will return the reference descriptor.
*
* @return The descriptor associated with this declaration
*/
abstract ClassDescriptor resolveDescriptor();
/**
* Resolves this {@link Declaration} and returns the associated {@link DatabaseMapping} if this
* represents a path expression. In the case of a {@link RangeVariableDeclaration}, this will
* return null
.
*
* @return The mapping associated with this declaration
*/
abstract DatabaseMapping resolveMapping();
@Override
public String toString() {
if (declarationExpression != null) {
return declarationExpression.toParsedText();
}
StringBuilder sb = new StringBuilder();
sb.append(rootPath);
if (identificationVariable != null) {
sb.append(AbstractExpression.SPACE);
sb.append(identificationVariable.getText());
}
return sb.toString();
}
}