private void resolveToFunctionReturnType(String functionName) { JpqlFunction function = functions.get(functionName.toLowerCase()); if (function == null) { return; } List<PathPosition> currentPositions = pathPositions; int positionsSize = currentPositions.size(); for (int i = 0; i < positionsSize; i++) { PathPosition position = currentPositions.get(i); Class<?> returnType = function.getReturnType(position.getCurrentClass()); position.setAttribute(null); position.setCurrentType(metamodel.type(returnType)); } }
@Override public void visit(FunctionExpression expression) { String name = expression.getFunctionName(); if ("FUNCTION".equalsIgnoreCase(name)) { // Skip the function name resolveFirst(expression.getExpressions().subList(1, expression.getExpressions().size()), true); resolveToFunctionReturnType(((StringLiteral) expression.getExpressions().get(0)).getValue()); } else if (ExpressionUtils.isSizeFunction(expression)) { // According to our grammar, we can only get a path here currentPosition.setAttribute(null); currentPosition.setCurrentType(metamodel.type(Long.class)); } else { resolveFirst(expression.getExpressions(), true); resolveToFunctionReturnType(name); } }
@Override public void visit(ListIndexExpression expression) { expression.getPath().accept(this); Class<?> type = currentPosition.getRealCurrentClass(); if (!List.class.isAssignableFrom(type)) { invalid(expression, "Does not resolve to java.util.List!"); } else { currentPosition.setAttribute(new ListIndexAttribute<>((ListAttribute<?, ?>) currentPosition.getAttribute())); currentPosition.setValueType(null); currentPosition.setKeyType(metamodel.type(Integer.class)); } }
throw new IllegalArgumentException("Attribute '" + property + "' not found on type '" + JpaMetamodelUtils.getTypeName(currentPosition.getCurrentType()) + "'"); currentPosition.setAttribute(attribute); Type<?> type = getType(currentPosition.getCurrentType(), attribute); Type<?> valueType = null;
throw new IllegalArgumentException("Attribute '" + property + "' not found on type '" + JpaMetamodelUtils.getTypeName(currentPosition.getCurrentType()) + "'"); currentPosition.setAttribute(attribute); Type<?> type = getType(currentPosition.getCurrentType(), attribute); Type<?> valueType = null;
@Override public void visit(MapEntryExpression expression) { expression.getPath().accept(this); currentPosition.setAttribute(new MapEntryAttribute<>((MapAttribute<?, Object, ?>) currentPosition.getAttribute())); currentPosition.setCurrentType(metamodel.type(Map.Entry.class)); }
@Override public void visit(TrimExpression expression) { currentPosition.setAttribute(null); currentPosition.setCurrentType(metamodel.type(String.class)); }
@Override public void visit(MapEntryExpression expression) { expression.getPath().accept(this); if (!(currentPosition.getAttribute() instanceof MapAttribute<?, ?, ?>)) { invalid(expression, "Does not resolve to java.util.Map!"); } else { currentPosition.setAttribute(null); currentPosition.setCurrentType(metamodel.type(Map.Entry.class)); } }
@Override public void visit(ListIndexExpression expression) { expression.getPath().accept(this); if (!(currentPosition.getAttribute() instanceof ListAttribute<?, ?>)) { invalid(expression, "Does not resolve to java.util.List!"); } else { currentPosition.setAttribute(new ListIndexAttribute<>((ListAttribute<?, ?>) currentPosition.getAttribute())); currentPosition.setCurrentType(metamodel.type(Integer.class)); } }
@Override public void visit(TreatExpression expression) { EntityType<?> type = metamodel.getEntity(expression.getType()); currentPosition.setAttribute(null); currentPosition.setCurrentType(type); }
@Override public void visit(MapKeyExpression expression) { expression.getPath().accept(this); currentPosition.setAttribute(new MapKeyAttribute<>((MapAttribute<?, Object, ?>) currentPosition.getAttribute())); currentPosition.setValueType(null); }
@Override public void visit(MapKeyExpression expression) { expression.getPath().accept(this); currentPosition.setAttribute(new MapKeyAttribute<>((MapAttribute<?, Object, ?>) currentPosition.getAttribute())); currentPosition.setValueType(null); }
@Override public void visit(ListIndexExpression expression) { expression.getPath().accept(this); Class<?> type = currentPosition.getRealCurrentClass(); if (!List.class.isAssignableFrom(type)) { invalid(expression, "Does not resolve to java.util.List!"); } else { currentPosition.setAttribute(new ListIndexAttribute<>((ListAttribute<?, ?>) currentPosition.getAttribute())); currentPosition.setValueType(null); currentPosition.setKeyType(metamodel.type(Integer.class)); } }
@Override public void visit(MapKeyExpression expression) { expression.getPath().accept(this); if (!(currentPosition.getAttribute() instanceof MapAttribute<?, ?, ?>)) { invalid(expression, "Does not resolve to java.util.Map!"); } else { currentPosition.setAttribute(new MapKeyAttribute<>((MapAttribute<?, Object, ?>) currentPosition.getAttribute())); currentPosition.setCurrentType(((MapAttribute<?, Object, ?>) currentPosition.getAttribute()).getKeyType()); } }
@Override public void visit(MapEntryExpression expression) { expression.getPath().accept(this); currentPosition.setAttribute(new MapEntryAttribute<>((MapAttribute<?, Object, ?>) currentPosition.getAttribute())); currentPosition.setCurrentType(metamodel.type(Map.Entry.class)); }