blob: d7209cd00006bd7ad2a7f8e24986e4fcd35b7af6 [file] [log] [blame]
/*
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 IBM Corporation. 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.jpa.jpql;
import java.util.List;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
/**
* This helper is used by {@link AbstractSemanticValidator} in order to retrieve JPA information.
* This helper allows third party adopter to write an instance of this helper that directly access
* the JPA information without having to implement Hermes SPI, which can improve performance.
* <p>
* {@link org.eclipse.persistence.jpa.jpql.tools.GenericSemanticValidatorHelper
* GenericSemanticValidatorHelper} is a default implementation that uses Hermes SPI.
* <p>
* Provisional API: This interface is part of an interim API that is still under development and
* expected to change significantly before reaching stability. It is available at this early stage
* to solicit feedback from pioneering adopters on the understanding that any code that uses this
* API will almost certainly be broken (repeatedly) as the API evolves.
*
* @version 2.5
* @since 2.4
* @author Pascal Filion
*/
public interface SemanticValidatorHelper {
/**
* Collects the identification variables that are defined in the <code>FROM</code> clause of the
* current query and from the parent queries.
*
* @param identificationVariables The {@link Map} used to store the variables
*/
void collectAllDeclarationIdentificationVariables(Map<String, List<IdentificationVariable>> identificationVariables);
/**
* Collects the identification variables that are defined in the <code>FROM</code> clause of the
* current query.
*
* @param identificationVariables The {@link Map} used to store the variables
*/
void collectLocalDeclarationIdentificationVariables(Map<String, List<IdentificationVariable>> identificationVariables);
/**
* Disposes this context, which is the current context being used by a subquery. Once it is
* disposed, any information retrieved will be for the subquery's parent query.
*/
void disposeSubqueryContext();
/**
* Returns the name of the all entities that are present in the context of a persistence unit.
*
* @return The list of entity names
*/
String[] entityNames();
/**
* Returns the ordered list of {@link JPQLQueryDeclaration}, which contain the information
* contained in the query's <code>FROM</code> clause.
*
* @return The list of {@link JPQLQueryDeclaration} of the current query that was parsed and from
* the parent queries
*/
List<JPQLQueryDeclaration> getAllDeclarations();
/**
* Returns the constructors for the given type. All public, protected, default (package) access,
* and private constructors should be included.
* <p>
* If it was going through Hermes SPI, the type of the argument would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IType IType} and the return type would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IConstructor IConstructor}.
*
* @return The declared constructors
*/
Object[] getConstructors(Object type);
/**
* Returns the ordered list of {@link JPQLQueryDeclaration}, which contain the information
* contained in the query's <code>FROM</code> clause.
*
* @return The list of {@link JPQLQueryDeclaration} of the current query that was parsed
*/
List<? extends JPQLQueryDeclaration> getDeclarations();
/**
* Retrieves the embeddable with the given type.
*
* @param type The Java type of the embeddable to retrieve
* @return The embeddable for the given type if it's representing an embeddable; <code>null</code>
* otherwise
*/
Object getEmbeddable(Object type);
/**
* Retrieves the entity with the given entity name.
*
* @param entityName The abstract schema name of the entity to retrieve
* @return The entity with the given name; <code>null</code> otherwise
*/
Object getEntityNamed(String entityName);
/**
* Returns the constant names for the given {@link Enum} type.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @param type The {@link Enum} type
* @return The list of constant names
*/
String[] getEnumConstants(Object type);
/**
* Returns the {@link JPQLGrammar} that defines how the JPQL query was parsed.
*
* @return The {@link JPQLGrammar} that was used to parse the JPQL query
*/
JPQLGrammar getGrammar();
/**
* Returns the managed type by resolving the given {@link Expression}.
* <p>
* If it was going through Hermes SPI, the return type would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IManagedType IManagedType}.
*/
Object getManagedType(Expression expression);
/**
* Returns the mapping with the given name.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IManagedType IManagedType}
* and the return type would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param managedType The managed type that has a mapping with the given name
* @param name The name of the mapping to retrieve
* @return Either the mapping or <code>null</code> if it could not be found
*/
Object getMappingNamed(Object managedType, String name);
/**
* Returns the type of the given mapping object.
* <p>
* If it was going through Hermes SPI, the type of the argument would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping} and the return type
* would be {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @param mapping The mapping object
* @return The type of the given mapping
*/
Object getMappingType(Object mapping);
/**
* Returns the list of type declarations representing the given constructor's parameter types.
* If this is the default constructor, then an empty array should be returned.
* <p>
* If it was going through Hermes SPI, the type of the argument would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IConstructor IConstructor} and the return type would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration ITypeDeclaration}.
*
* @param constructor The constructor to return its parameter types
* @return The list of parameter types or an empty list
*/
Object[] getMethodParameterTypeDeclarations(Object constructor);
/**
* Returns the reference managed type from the given relationship mapping.
* <p>
* If it was going through Hermes SPI, the type of the argument would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping} and the return type would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.IManagedType IManagedType}.
*
* @param relationshipMapping The relationship mapping
* @return The managed type referenced by the given relationship mapping
*/
Object getReferenceManagedType(Object relationshipMapping);
/**
* Returns the type by resolving the given {@link Expression}.
* <p>
* If it was going through Hermes SPI, the return type would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @param expression The {@link Expression} to resolve
* @return The type of the given {@link Expression} or <code>null</code> if it could not be
* validated
*/
Object getType(Expression expression);
/**
* Returns the type defined for the Java member.
* <p>
* If it was going through Hermes SPI, the type of the argument would be {@link
* org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration ITypeDeclaration} and the return type would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @return The type defined for the Java member
*/
Object getType(Object typeDeclaration);
/**
* Retrieves the class with the given fully qualified name.
* <p>
* If it was going through Hermes SPI, an {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType
* IType} would be returned.
*
* @param typeName The fully qualified name of the class to retrieve
* @return The class to retrieve
*/
Object getType(String typeName);
/**
* Returns the type declaration for the given {@link Expression}'s type.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration ITypeDeclaration}.
*
* @param expression The {@link Expression} to resolve
* @return Either the type declaration that was resolved for the given {@link Expression}
*/
Object getTypeDeclaration(Expression expression);
/**
* Returns the helper that gives access to the most common class metadata.
*
* @return A helper containing a collection of methods related to class metadata
*/
ITypeHelper getTypeHelper();
/**
* Returns the fully qualified class name of the given type.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @param type The type to retrieve its name
* @return The name of the class represented by this one
*/
String getTypeName(Object type);
/**
* Determines whether type 1 is an instance of type 2.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @param type1 The type to check if it is an instance of type 2
* @param type2 The type used to determine if the class represented by type 1 is an instance
* of with one
* @return <code>true</code> if type 1 is an instance of the type 2; <code>false</code> otherwise
*/
boolean isAssignableTo(Object type1, Object type2);
/**
* Determines whether the given identification variable is defining a join or a collection member
* declaration expressions.
*
* @param variableName The identification variable to check for what it maps
* @return <code>true</code> if the given identification variable maps a collection-valued field
* defined in a <code>JOIN</code> or <code>IN</code> expression; <code>false</code> if it's not
* defined or it's mapping an abstract schema name
*/
boolean isCollectionIdentificationVariable(String variableName);
/**
* Determines whether the given mapping is a collection type mapping.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param mapping The mapping object to verify if it represents a collection mapping
* @return <code>true</code> if the given mapping is a collection mapping; <code>false</code>
* otherwise
*/
boolean isCollectionMapping(Object mapping);
/**
* Determines whether the given mapping is an embeddable type mapping.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param mapping The mapping object to verify if it represents an embeddable mapping
* @return <code>true</code> if the given mapping is an embeddable mapping; <code>false</code>
* otherwise
*/
boolean isEmbeddableMapping(Object mapping);
/**
* Determines whether the given type represents an {@link Enum}.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @return <code>true</code> if the given type is an {@link Enum}; <code>false</code> otherwise
*/
boolean isEnumType(Object type);
/**
* Determines whether an identification variable can be used in a comparison expression when the
* operator is either {@literal '<', '<=', '>', '>='}.
*
* @param expression The {@link IdentificationVariable} that is mapped to either an entity, a
* singled-object value field, a collection-valued object field
* @return <code>true</code> if it can be used in a ordering comparison expression; <code>false</code>
* if it can't
*/
boolean isIdentificationVariableValidInComparison(IdentificationVariable expression);
/**
* Determines whether the given managed type actually exists.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IManagedType IManagedType}.
*
* @return <code>true</code> if the given managed type can be located; <code>false</code> if it
* could not be found
*/
boolean isManagedTypeResolvable(Object managedType);
/**
* Determines whether the given mapping is a property type mapping.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param mapping The mapping object to verify if it represents a property mapping
* @return <code>true</code> if the given mapping is a property mapping; <code>false</code> otherwise
*/
boolean isPropertyMapping(Object mapping);
/**
* Determines whether the given mapping is a relationship type mapping.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param mapping The mapping object to verify if it represents a relationship mapping
* @return <code>true</code> if the given mapping is a relationship mapping; <code>false</code> otherwise
*/
boolean isRelationshipMapping(Object mapping);
/**
* Determines if the given variable is a result variable.
*
* @param variableName The variable to check if it's a result variable
* @return <code>true</code> if the given variable is defined as a result variable;
* <code>false</code> otherwise
*/
boolean isResultVariable(String variableName);
/**
* Determines whether the given mapping is a transient attribute.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param mapping The mapping object to verify if it represents a transient attribute
* @return <code>true</code> if the given attribute is a transient mapping; <code>false</code> otherwise
*/
boolean isTransient(Object mapping);
/**
* Determines whether type declaration 1 is an instance of type declaration 2.
* <p>
* If it was going through Hermes SPI, the type of the arguments would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration ITypeDeclaration}.
*
* @param typeDeclaration1 The type declaration to check if it is an instance of type declaration 2
* @param typeDeclaration2 The type used to determine if the class represented by type
* declaration 1 is an instance of with one
* @return <code>true</code> if type declaration 1 is an instance of the type declaration 2;
* <code>false</code> otherwise
*/
boolean isTypeDeclarationAssignableTo(Object typeDeclaration1, Object typeDeclaration2);
/**
* Determines whether the given type actually exists.
* <p>
* If it was going through Hermes SPI, the type of the argument would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IType IType}.
*
* @return <code>true</code> if the actual class exists; <code>false</code> otherwise
*/
boolean isTypeResolvable(Object type);
/**
* Changes the state of this helper to use the given subquery.
*
* @param expression The parsed tree representation of the subquery that will become the current query
* @see #disposeSubqueryContext()
*/
void newSubqueryContext(SimpleSelectStatement expression);
/**
* Returns the mapping for the field represented by the given {@link Expression}.
* <p>
* If it was going through Hermes SPI, the return type would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param expression The {@link Expression} representing a state field path expression or a
* collection-valued path expression
* @return Either the mapping or <code>null</code> if none exists
*/
Object resolveMapping(Expression expression);
/**
* Returns the mapping that should be a persistence field from the entity defined by the given
* identification variable.
* <p>
* If it was going through Hermes SPI, the return type would be
* {@link org.eclipse.persistence.jpa.jpql.tools.spi.IMapping IMapping}.
*
* @param identificationVariable The identification variable that is defined in the <code>FROM</code>
* clause of the query (which can be in the current subquery) or in one of the parent queries.
* @param name The name of the persistent field to retrieve
* @return The persistence field with the given name or <code>null</code> if it could not be found
*/
Object resolveMapping(String identificationVariable, String name);
}