Class JpqlExecutionService
java.lang.Object
io.jmix.aitools.dataload.execution.JpqlExecutionService
Validates, repairs and executes a generated JPQL query, returning the fetched rows.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static final recordRows fetched for a query plus a flag telling whether more results are available beyond them. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected AccessManagerprotected JpqlAccessSupportprotected AiToolsDataLoadPropertiesprotected DataManagerprotected JpqlParameterConversionServiceprotected Metadataprotected MetadataToolsprotected QueryTransformerFactoryprotected JpqlValidationAndRepairService -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected StringapplyAccessConstraints(GeneratedJpqlResult generatedResult) Applies the current user's access constraints to the generated query, returning the text to execute: the query itself, or the query with the row-level conditions of the entities it reads woven in.protected JpqlExecutionService.ExecutionRowscreateExecutionRows(List<Map<String, @Nullable Object>> rows, boolean hasMore) execute(JpqlExecutionRequest request) Validates, repairs if needed and executes the query described by the request.protected JpqlExecutionService.ExecutionRowsexecuteQuery(JpqlExecutionRequest request, GeneratedJpqlResult generatedJpqlResult, Map<String, Object> executionParameters, Integer maxResults, @Nullable Integer firstResult) protected IntegergetEffectiveMaxResult(@Nullable Integer maxResults) protected booleanisHiddenSelectedPath(QueryParser.QueryPath queryPath) resolveDeniedSelectedIndexes(String jpqlQuery) Resolves the positions of the selected columns the current user is not allowed to read.resolveExcludedSelectedIndexes(String jpqlQuery) Resolves the positions of the selected columns that must be dropped from the result: those the current user is not allowed to read, plus those mapping to an attribute hidden from the AI (annotatedSecretorExcludeFromAi).resolveHiddenSelectedIndexes(String jpqlQuery) Resolves the positions of the selected columns that map to an attribute hidden from the AI (annotatedSecretorExcludeFromAi).retainPermittedProperties(List<String> resultProperties, List<Integer> excludedSelectedIndexes) Returns the result properties that stay in the result, dropping the ones at the excluded select positions (denied by security or mapping to an attribute hidden from the AI).retainProperties(List<Map<String, @Nullable Object>> rows, List<String> resultProperties, List<String> retainedProperties) Rebuilds each row keeping only the retained properties, in their original order.protected List<JpqlExecutionParameter> toExecutionParameters(GeneratedJpqlResult generatedJpqlResult) toValueRow(KeyValueEntity keyValueEntity, List<String> resultProperties) protected GeneratedJpqlResultwithJpql(GeneratedJpqlResult generatedResult, String jpql) Returns the generated result with the given text to execute.
-
Field Details
-
validateAndRepair
-
accessSupport
-
jpqlParameterConversionService
-
dataLoadProperties
-
dataManager
-
accessManager
-
queryTransformerFactory
-
metadata
-
metadataTools
-
-
Constructor Details
-
JpqlExecutionService
public JpqlExecutionService()
-
-
Method Details
-
execute
Validates, repairs if needed and executes the query described by the request.This method runs the full pipeline: it validates and (if needed) repairs the query, enforces data-access constraints for every entity the query reads (see
JpqlAccessSupport), converts the parameters to their Java types and runs the query throughUnconstrainedDataManager.loadValues(io.jmix.core.ValueLoadContext). One extra row is fetched to detect whether more results are available. A query that cannot be narrowed as the current user's permissions require is not executed; the result carries the reason as its execution error.- Parameters:
request- query to execute together with its parameters and paging hints- Returns:
- result with the fetched rows on success, or with validation/execution failure details
- Throws:
AccessDeniedException- if the current user may not read an entity the query reads
-
applyAccessConstraints
Applies the current user's access constraints to the generated query, returning the text to execute: the query itself, or the query with the row-level conditions of the entities it reads woven in.- Parameters:
generatedResult- validated generated query with its parameters- Returns:
- the text to execute
- Throws:
AccessDeniedException- if the current user may not read an entity the query readsJpqlAccessConstraintException- if the query cannot be narrowed as the user's permissions require, or the constraints cannot be applied to it
-
withJpql
Returns the generated result with the given text to execute. The result returned to the caller keeps the validated text, so the model never sees the row-level conditions applied for execution.- Parameters:
generatedResult- validated generated resultjpql- text to execute- Returns:
- the generated result itself when the text is unchanged, otherwise a copy carrying the text
-
toExecutionParameters
protected List<JpqlExecutionParameter> toExecutionParameters(GeneratedJpqlResult generatedJpqlResult) -
resolveDeniedSelectedIndexes
Resolves the positions of the selected columns the current user is not allowed to read.- Parameters:
jpqlQuery- query whose data access is being checked- Returns:
- positions (in select-clause order) of the denied columns, or an empty list if all selected columns are readable
- Throws:
AccessDeniedException- if the current user cannot read the queried entity
-
resolveExcludedSelectedIndexes
Resolves the positions of the selected columns that must be dropped from the result: those the current user is not allowed to read, plus those mapping to an attribute hidden from the AI (annotatedSecretorExcludeFromAi). The hidden-attribute guard is defense in depth — such an attribute is already unknown to introspection and rejected by JPQL validation — so its value is never returned even if a query reaches execution through another path.- Parameters:
jpqlQuery- query whose selected columns are being resolved- Returns:
- positions (in select-clause order) of the columns to drop, without duplicates
- Throws:
AccessDeniedException- if the current user cannot read the queried entity
-
resolveHiddenSelectedIndexes
Resolves the positions of the selected columns that map to an attribute hidden from the AI (annotatedSecretorExcludeFromAi).- Parameters:
jpqlQuery- query whose selected columns are being inspected- Returns:
- positions (in select-clause order) of the hidden columns, or an empty list when the query cannot be parsed
-
isHiddenSelectedPath
-
retainPermittedProperties
protected List<String> retainPermittedProperties(List<String> resultProperties, List<Integer> excludedSelectedIndexes) Returns the result properties that stay in the result, dropping the ones at the excluded select positions (denied by security or mapping to an attribute hidden from the AI).- Parameters:
resultProperties- result property names in select-clause orderexcludedSelectedIndexes- positions of the columns to drop- Returns:
- the retained property names, in their original order
-
retainProperties
protected List<Map<String,@Nullable Object>> retainProperties(List<Map<String, @Nullable Object>> rows, List<String> resultProperties, List<String> retainedProperties) Rebuilds each row keeping only the retained properties, in their original order. Null values are kept distinct from empty strings.- Parameters:
rows- fetched rows keyed by all result propertiesresultProperties- all result property names the rows are keyed byretainedProperties- property names to keep in the output rows- Returns:
- rows containing only the retained properties, or the original rows if nothing is dropped
-
executeQuery
protected JpqlExecutionService.ExecutionRows executeQuery(JpqlExecutionRequest request, GeneratedJpqlResult generatedJpqlResult, Map<String, Object> executionParameters, Integer maxResults, @Nullable Integer firstResult) -
toValueRow
-
getEffectiveMaxResult
-
createExecutionRows
protected JpqlExecutionService.ExecutionRows createExecutionRows(List<Map<String, @Nullable Object>> rows, boolean hasMore)
-