co.streamx.fluent.JPA.DSLInterpreterHelpers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fluent-jpa Show documentation
Show all versions of fluent-jpa Show documentation
Fluent query implementation for JPA repositories
The newest version!
package co.streamx.fluent.JPA;
import static co.streamx.fluent.JPA.JPAHelpers.wrap;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import co.streamx.fluent.extree.expression.ConstantExpression;
import co.streamx.fluent.extree.expression.Expression;
import co.streamx.fluent.extree.expression.ExpressionType;
import co.streamx.fluent.extree.expression.InvocationExpression;
import co.streamx.fluent.extree.expression.LambdaExpression;
import co.streamx.fluent.extree.expression.ParameterExpression;
import co.streamx.fluent.notation.Context;
import co.streamx.fluent.notation.ParameterContext;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
interface DSLInterpreterHelpers {
@RequiredArgsConstructor
final class DynamicConstant implements UnboundCharSequence {
private CharSequence string;
@Getter
private final Object value;
private final DSLInterpreter dsl;
private void lazyInit() {
if (string == null) {
if (value instanceof CharSequence || value instanceof Character) {
// wrap with quotes and escape existing quotes
StringBuilder out = new StringBuilder().append(DSLInterpreter.SINGLE_QUOTE_CHAR);
if (value instanceof CharSequence)
out.append((CharSequence) value);
else
out.append((char) value);
for (int i = out.length() - 1; i > 0; i--) {
if (out.charAt(i) == DSLInterpreter.SINGLE_QUOTE_CHAR)
out.insert(i, DSLInterpreter.SINGLE_QUOTE_CHAR);
}
string = out.append(DSLInterpreter.SINGLE_QUOTE_CHAR);
} else
string = String.valueOf(value);
}
}
public CharSequence registerAsParameter() {
return dsl.registerParameter(value);
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public int length() {
lazyInit();
return string.length();
}
@Override
public char charAt(int index) {
lazyInit();
return string.charAt(index);
}
@Override
public CharSequence subSequence(int start,
int end) {
lazyInit();
return string.subSequence(start, end);
}
@Override
public String toString() {
lazyInit();
return string.toString();
}
}
@RequiredArgsConstructor
@Getter
final class PackedInitializers implements UnboundCharSequence {
private final List expressions;
List> compiled;
private final List, CharSequence>> producers;
private final List it;
private List itDecoded;
private final DSLInterpreter dsl;
public List getInitializers() {
if (itDecoded != null)
return itDecoded;
return itDecoded = getInitializers(it, 0);
}
public List getInitializers(CharSequence seq,
int limit) {
CharSequence[] seqs = new CharSequence[it.size()];
Arrays.fill(seqs, seq);
return getInitializers(Arrays.asList(seqs), limit);
}
public List getInitializers(Object value,
int limit) {
if (limit <= 0)
limit = producers.size() + limit;
Object[] t = { value };
return compiled().stream()
.limit(limit)
.map(f -> f.apply(t))
.map(p -> dsl.registerParameter(p))
.collect(Collectors.toList());
}
private List getInitializers(List it,
int limit) {
if (limit <= 0)
limit = producers.size() + limit;
return producers.stream().limit(limit).map(pe -> pe.apply(it)).collect(Collectors.toList());
}
private List> compiled() {
if (compiled == null)
compiled = expressions.stream()
.map(e -> ((InvocationExpression) e).getTarget())
.map(ie -> ie instanceof LambdaExpression ? ((LambdaExpression>) ie).compile()
: LambdaExpression.compile(ie))
.collect(Collectors.toList());
return compiled;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public int length() {
throw new IllegalStateException();
}
@Override
public char charAt(int index) {
throw new IllegalStateException();
}
@Override
public CharSequence subSequence(int start,
int end) {
throw new IllegalStateException();
}
@Override
public String toString() {
throw new IllegalStateException();
}
}
@Getter
@RequiredArgsConstructor
final class RequiresParenthesesInAS implements Wrapped {
private final CharSequence wrapped;
@Override
public String toString() {
return getWrapped().toString();
}
}
@Getter
@RequiredArgsConstructor
final class View {
private final PackedInitializers packed;
private CharSequence columns;
private List allColumns;
private CharSequence selfSelect;
public CharSequence getColumn(CharSequence p,
int i) {
getColumns();
try {
if (i < 0)
i += allColumns.size();
return new StringBuilder(p).append(DSLInterpreter.SEP_AS_SEP).append(allColumns.get(i));
} catch (IndexOutOfBoundsException ioobe) {
throw TranslationError.ALIAS_NOT_SPECIFIED.getError(ioobe, i);
}
}
public CharSequence getColumns() {
if (this.columns != null)
return this.columns;
allColumns = packed.getInitializers("", 0);
return this.columns = join(allColumns, false);
}
private String join(List columns, boolean aliased) {
Iterable it = aliased
? () -> IntStream.range(0, columns.size()).mapToObj(i -> getColumn(columns.get(i), i)).iterator()
: columns;
return String.join(DSLInterpreter.COMMA_CHAR + DSLInterpreter.KEYWORD_DELIMITER, it);
}
public CharSequence getSelect() {
if (selfSelect != null)
return selfSelect;
return selfSelect = join(packed.getInitializers(), false);
}
public CharSequence getSelect(CharSequence seq,
int limit,
boolean aliased) {
return join(packed.getInitializers(seq, limit), aliased);
}
public CharSequence getSelect(Object value,
int limit,
boolean aliased) {
return join(packed.getInitializers(value, limit), aliased);
}
}
interface Wrapped extends UnboundCharSequence {
CharSequence getWrapped();
@Override
default boolean isEmpty() {
return length() != 0;
}
@Override
default int length() {
return getWrapped().length();
}
@Override
default char charAt(int index) {
return getWrapped().charAt(index);
}
@Override
default CharSequence subSequence(int start,
int end) {
return getWrapped().subSequence(start, end);
}
}
@RequiredArgsConstructor
@Getter
final class ParameterRef implements Wrapped {
private CharSequence seq;
private final Object value;
private final List