#919 - io.ebean package initial

This commit is contained in:
Rob Bygrave
2016-12-11 23:23:22 +13:00
parent 5821dc96b9
commit 971e2dc91b
2134 changed files with 10721 additions and 8652 deletions
@@ -0,0 +1,59 @@
package io.ebeaninternal.server.el;
/**
* Case insensitive string matching.
* <p>
* Provides an alternative to using regular expressions.
* </p>
*/
public final class CharMatch {
private final char[] upperChars;
private final int maxLength;
public CharMatch(String s) {
this.upperChars = s.toUpperCase().toCharArray();
this.maxLength = upperChars.length;
}
public boolean startsWith(String other) {
if (other == null || other.length() < maxLength) {
return false;
}
char ta[] = other.toCharArray();
int pos = -1;
while (++pos < maxLength) {
char c1 = upperChars[pos];
char c2 = Character.toUpperCase(ta[pos]);
if (c1 != c2) {
return false;
}
}
return true;
}
public boolean endsWith(String other) {
if (other == null || other.length() < maxLength) {
return false;
}
char ta[] = other.toCharArray();
int offset = ta.length - maxLength;
int pos = maxLength;
while (--pos >= 0) {
char c1 = upperChars[pos];
char c2 = Character.toUpperCase(ta[offset + pos]);
if (c1 != c2) {
return false;
}
}
return true;
}
}
@@ -0,0 +1,20 @@
package io.ebeaninternal.server.el;
import java.util.Comparator;
/**
* Comparator for use with the expression objects.
*/
public interface ElComparator<T> extends Comparator<T> {
/**
* Compare given 2 beans.
*/
int compare(T o1, T o2);
/**
* Compare with a fixed value to a given bean.
*/
int compareValue(Object value, T o2);
}
@@ -0,0 +1,44 @@
package io.ebeaninternal.server.el;
import java.util.Comparator;
/**
* Comparator based on multiple ordered comparators.
* <p>
* eg. "name, orderDate desc, id"
* </p>
*/
public final class ElComparatorCompound<T> implements Comparator<T>, ElComparator<T> {
private final ElComparator<T>[] array;
public ElComparatorCompound(ElComparator<T>[] array) {
this.array = array;
}
public int compare(T o1, T o2) {
for (ElComparator<T> anArray : array) {
int ret = anArray.compare(o1, o2);
if (ret != 0) {
return ret;
}
}
return 0;
}
public int compareValue(Object value, T o2) {
for (ElComparator<T> anArray : array) {
int ret = anArray.compareValue(value, o2);
if (ret != 0) {
return ret;
}
}
return 0;
}
}
@@ -0,0 +1,49 @@
package io.ebeaninternal.server.el;
import java.util.Comparator;
/**
* Comparator based on a ElGetValue.
*/
public final class ElComparatorProperty<T> implements Comparator<T>, ElComparator<T> {
private final ElPropertyValue elGetValue;
private final int nullOrder;
private final int asc;
public ElComparatorProperty(ElPropertyValue elGetValue, boolean ascending, boolean nullsHigh) {
this.elGetValue = elGetValue;
this.asc = ascending ? 1 : -1;
this.nullOrder = asc * (nullsHigh ? 1 : -1);
}
public int compare(T o1, T o2) {
Object val1 = elGetValue.pathGet(o1);
Object val2 = elGetValue.pathGet(o2);
return compareValues(val1, val2);
}
public int compareValue(Object value, T o2) {
Object val2 = elGetValue.pathGet(o2);
return compareValues(value, val2);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public int compareValues(Object val1, Object val2) {
if (val1 == null) {
return val2 == null ? 0 : nullOrder;
}
if (val2 == null) {
return -1 * nullOrder;
}
Comparable c = (Comparable) val1;
return asc * c.compareTo(val2);
}
}
@@ -0,0 +1,249 @@
package io.ebeaninternal.server.el;
import io.ebean.Filter;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Default implementation of the Filter interface.
*/
public final class ElFilter<T> implements Filter<T> {
private final BeanDescriptor<T> beanDescriptor;
private final ArrayList<ElMatcher<T>> matches = new ArrayList<>();
private int maxRows;
private String sortByClause;
public ElFilter(BeanDescriptor<T> beanDescriptor) {
this.beanDescriptor = beanDescriptor;
}
private Object convertValue(String propertyName, Object value) {
// convert type of value to match expected type
ElPropertyValue elGetValue = beanDescriptor.getElGetValue(propertyName);
return elGetValue.convert(value);
}
private ElComparator<T> getElComparator(String propertyName) {
return beanDescriptor.getElComparator(propertyName);
}
private ElPropertyValue getElGetValue(String propertyName) {
return beanDescriptor.getElGetValue(propertyName);
}
public Filter<T> sort(String sortByClause) {
this.sortByClause = sortByClause;
return this;
}
protected boolean isMatch(T bean) {
for (ElMatcher<T> matcher : matches) {
if (!matcher.isMatch(bean)) {
return false;
}
}
return true;
}
public Filter<T> in(String propertyName, Set<?> matchingValues) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.InSet<>(matchingValues, elGetValue));
return this;
}
public Filter<T> eq(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Eq<>(value, comparator));
return this;
}
public Filter<T> ne(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Ne<>(value, comparator));
return this;
}
public Filter<T> between(String propertyName, Object min, Object max) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
min = elGetValue.convert(min);
max = elGetValue.convert(max);
ElComparator<T> elComparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Between<>(min, max, elComparator));
return this;
}
public Filter<T> gt(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Gt<>(value, comparator));
return this;
}
public Filter<T> ge(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Ge<>(value, comparator));
return this;
}
public Filter<T> ieq(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.Ieq<>(elGetValue, value));
return this;
}
public Filter<T> isNotNull(String propertyName) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IsNotNull<>(elGetValue));
return this;
}
public Filter<T> isNull(String propertyName) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IsNull<>(elGetValue));
return this;
}
public Filter<T> le(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Le<>(value, comparator));
return this;
}
public Filter<T> lt(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Lt<>(value, comparator));
return this;
}
public Filter<T> regex(String propertyName, String regEx) {
return regex(propertyName, regEx, 0);
}
public Filter<T> regex(String propertyName, String regEx, int options) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.RegularExpr<>(elGetValue, regEx, options));
return this;
}
public Filter<T> contains(String propertyName, String value) {
String quote = ".*" + Pattern.quote(value) + ".*";
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.RegularExpr<>(elGetValue, quote, 0));
return this;
}
public Filter<T> icontains(String propertyName, String value) {
String quote = ".*" + Pattern.quote(value) + ".*";
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.RegularExpr<>(elGetValue, quote, Pattern.CASE_INSENSITIVE));
return this;
}
public Filter<T> endsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.EndsWith<>(elGetValue, value));
return this;
}
public Filter<T> startsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.StartsWith<>(elGetValue, value));
return this;
}
public Filter<T> iendsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IEndsWith<>(elGetValue, value));
return this;
}
public Filter<T> istartsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IStartsWith<>(elGetValue, value));
return this;
}
public Filter<T> maxRows(int maxRows) {
this.maxRows = maxRows;
return this;
}
public List<T> filter(List<T> list) {
if (sortByClause != null) {
// create shallow copy and sort
list = new ArrayList<>(list);
beanDescriptor.sort(list, sortByClause);
}
ArrayList<T> filterList = new ArrayList<>();
for (T t : list) {
if (isMatch(t)) {
filterList.add(t);
if (maxRows > 0 && filterList.size() >= maxRows) {
break;
}
}
}
return filterList;
}
}
@@ -0,0 +1,282 @@
package io.ebeaninternal.server.el;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Contains the various ElMatcher implementations.
*/
class ElMatchBuilder {
/**
* Case insensitive equals.
*/
static class RegularExpr<T> implements ElMatcher<T> {
final ElPropertyValue elGetValue;
final String value;
final Pattern pattern;
RegularExpr(ElPropertyValue elGetValue, String value, int options) {
this.elGetValue = elGetValue;
this.value = value;
this.pattern = Pattern.compile(value, options);
}
public boolean isMatch(T bean) {
String v = (String) elGetValue.pathGet(bean);
return pattern.matcher(v).matches();
}
}
/**
* Case insensitive equals.
*/
static abstract class BaseString<T> implements ElMatcher<T> {
final ElPropertyValue elGetValue;
final String value;
public BaseString(ElPropertyValue elGetValue, String value) {
this.elGetValue = elGetValue;
this.value = value;
}
public abstract boolean isMatch(T bean);
}
static class Ieq<T> extends BaseString<T> {
Ieq(ElPropertyValue elGetValue, String value) {
super(elGetValue, value);
}
public boolean isMatch(T bean) {
String v = (String) elGetValue.pathGet(bean);
return value.equalsIgnoreCase(v);
}
}
/**
* Case insensitive starts with matcher.
*/
static class IStartsWith<T> implements ElMatcher<T> {
final ElPropertyValue elGetValue;
final CharMatch charMatch;
IStartsWith(ElPropertyValue elGetValue, String value) {
this.elGetValue = elGetValue;
this.charMatch = new CharMatch(value);
}
public boolean isMatch(T bean) {
String v = (String) elGetValue.pathGet(bean);
return charMatch.startsWith(v);
}
}
/**
* Case insensitive ends with matcher.
*/
static class IEndsWith<T> implements ElMatcher<T> {
final ElPropertyValue elGetValue;
final CharMatch charMatch;
IEndsWith(ElPropertyValue elGetValue, String value) {
this.elGetValue = elGetValue;
this.charMatch = new CharMatch(value);
}
public boolean isMatch(T bean) {
String v = (String) elGetValue.pathGet(bean);
return charMatch.endsWith(v);
}
}
static class StartsWith<T> extends BaseString<T> {
StartsWith(ElPropertyValue elGetValue, String value) {
super(elGetValue, value);
}
public boolean isMatch(T bean) {
String v = (String) elGetValue.pathGet(bean);
return value.startsWith(v);
}
}
static class EndsWith<T> extends BaseString<T> {
EndsWith(ElPropertyValue elGetValue, String value) {
super(elGetValue, value);
}
public boolean isMatch(T bean) {
String v = (String) elGetValue.pathGet(bean);
return value.endsWith(v);
}
}
static class IsNull<T> implements ElMatcher<T> {
final ElPropertyValue elGetValue;
public IsNull(ElPropertyValue elGetValue) {
this.elGetValue = elGetValue;
}
public boolean isMatch(T bean) {
return (null == elGetValue.pathGet(bean));
}
}
static class IsNotNull<T> implements ElMatcher<T> {
final ElPropertyValue elGetValue;
public IsNotNull(ElPropertyValue elGetValue) {
this.elGetValue = elGetValue;
}
public boolean isMatch(T bean) {
return (null != elGetValue.pathGet(bean));
}
}
static abstract class Base<T> implements ElMatcher<T> {
final Object filterValue;
final ElComparator<T> comparator;
public Base(Object filterValue, ElComparator<T> comparator) {
this.filterValue = filterValue;
this.comparator = comparator;
}
public abstract boolean isMatch(T value);
}
static class InSet<T> implements ElMatcher<T> {
final Set<?> set;
final ElPropertyValue elGetValue;
@SuppressWarnings({"unchecked", "rawtypes"})
public InSet(Set<?> set, ElPropertyValue elGetValue) {
this.set = new HashSet(set);
this.elGetValue = elGetValue;
}
public boolean isMatch(T bean) {
Object value = elGetValue.pathGet(bean);
return value != null && set.contains(value);
}
}
/**
* Equal To.
*/
static class Eq<T> extends Base<T> {
public Eq(Object filterValue, ElComparator<T> comparator) {
super(filterValue, comparator);
}
public boolean isMatch(T value) {
return comparator.compareValue(filterValue, value) == 0;
}
}
/**
* Not Equal To.
*/
static class Ne<T> extends Base<T> {
public Ne(Object filterValue, ElComparator<T> comparator) {
super(filterValue, comparator);
}
public boolean isMatch(T value) {
return comparator.compareValue(filterValue, value) != 0;
}
}
/**
* Between.
*/
static class Between<T> implements ElMatcher<T> {
final Object min;
final Object max;
final ElComparator<T> comparator;
Between(Object min, Object max, ElComparator<T> comparator) {
this.min = min;
this.max = max;
this.comparator = comparator;
}
public boolean isMatch(T value) {
return (comparator.compareValue(min, value) <= 0
&& comparator.compareValue(max, value) >= 0);
}
}
/**
* Greater Than.
*/
static class Gt<T> extends Base<T> {
Gt(Object filterValue, ElComparator<T> comparator) {
super(filterValue, comparator);
}
public boolean isMatch(T value) {
return comparator.compareValue(filterValue, value) == -1;
}
}
/**
* Greater Than or Equal To.
*/
static class Ge<T> extends Base<T> {
Ge(Object filterValue, ElComparator<T> comparator) {
super(filterValue, comparator);
}
public boolean isMatch(T value) {
return comparator.compareValue(filterValue, value) >= 0;
}
}
/**
* Less Than or Equal To.
*/
static class Le<T> extends Base<T> {
Le(Object filterValue, ElComparator<T> comparator) {
super(filterValue, comparator);
}
public boolean isMatch(T value) {
return comparator.compareValue(filterValue, value) <= 0;
}
}
/**
* Less Than.
*/
static class Lt<T> extends Base<T> {
Lt(Object filterValue, ElComparator<T> comparator) {
super(filterValue, comparator);
}
public boolean isMatch(T value) {
return comparator.compareValue(filterValue, value) == 1;
}
}
}
@@ -0,0 +1,12 @@
package io.ebeaninternal.server.el;
/**
* Interface for defining matches for filter expressions.
*/
public interface ElMatcher<T> {
/**
* Return true if the bean matches the expression.
*/
boolean isMatch(T bean);
}
@@ -0,0 +1,277 @@
package io.ebeaninternal.server.el;
import io.ebean.bean.EntityBean;
import io.ebean.text.StringParser;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.lib.util.StringHelper;
import io.ebeaninternal.server.query.SplitName;
import io.ebeaninternal.server.type.ScalarType;
import java.util.Arrays;
/**
* A ElGetValue based on a chain of properties.
* <p>
* Used to get the value for an compound expression like customer.name or
* customer.shippingAddress.city etc.
* </p>
* <p>
* Note that if any element in the chain returns null, then null is returned and
* no further processing of the chain occurs.
* </p>
*/
public class ElPropertyChain implements ElPropertyValue {
private final String prefix;
private final String placeHolder;
private final String placeHolderEncrypted;
private final String name;
private final String expression;
private final boolean containsMany;
private final ElPropertyValue[] chain;
private final boolean assocId;
private final int last;
private final BeanProperty lastBeanProperty;
private final ScalarType<?> scalarType;
private final ElPropertyValue lastElPropertyValue;
public ElPropertyChain(boolean containsMany, boolean embedded, String expression, ElPropertyValue[] chain) {
this.containsMany = containsMany;
this.chain = chain;
this.expression = expression;
int dotPos = expression.lastIndexOf('.');
if (dotPos > -1) {
this.name = expression.substring(dotPos + 1);
if (embedded) {
int embPos = expression.lastIndexOf('.', dotPos - 1);
this.prefix = embPos == -1 ? null : expression.substring(0, embPos);
} else {
this.prefix = expression.substring(0, dotPos);
}
} else {
this.prefix = null;
this.name = expression;
}
this.assocId = chain[chain.length - 1].isAssocId();
this.last = chain.length - 1;
this.lastBeanProperty = chain[chain.length - 1].getBeanProperty();
if (lastBeanProperty != null) {
this.scalarType = lastBeanProperty.getScalarType();
} else {
// case for nested compound type (non-scalar)
this.scalarType = null;
}
this.lastElPropertyValue = chain[chain.length - 1];
this.placeHolder = getElPlaceHolder(prefix, lastElPropertyValue, false);
this.placeHolderEncrypted = getElPlaceHolder(prefix, lastElPropertyValue, true);
}
public String toString() {
return "expr:" + expression + " chain:" + Arrays.toString(chain);
}
@Override
public boolean isAggregation() {
return false;
}
private String getElPlaceHolder(String prefix, ElPropertyValue lastElPropertyValue, boolean encrypted) {
if (prefix == null) {
return lastElPropertyValue.getElPlaceholder(encrypted);
}
String el = lastElPropertyValue.getElPlaceholder(encrypted);
if (!el.contains("${}")) {
// typically a secondary table property
return StringHelper.replaceString(el, "${", "${" + prefix + ".");
} else {
return StringHelper.replaceString(el, ROOT_ELPREFIX, "${" + prefix + "}");
}
}
/**
* Return true if there is a many property from sinceProperty to
* the end of this chain.
*/
public boolean containsManySince(String sinceProperty) {
if (sinceProperty == null) {
return containsMany;
}
if (!expression.startsWith(sinceProperty)) {
return containsMany;
}
int i = 1 + SplitName.count(sinceProperty);
for (; i < chain.length; i++) {
if (chain[i].getBeanProperty().containsMany()) {
return true;
}
}
return false;
}
@Override
public boolean containsFormulaWithJoin() {
// Not cascading the check at this stage
return false;
}
public boolean containsMany() {
return containsMany;
}
public String getElPrefix() {
return prefix;
}
public String getName() {
return name;
}
public String getElName() {
return expression;
}
public String getElPlaceholder(boolean encrypted) {
return encrypted ? placeHolderEncrypted : placeHolder;
}
public boolean isDbEncrypted() {
return lastElPropertyValue.isDbEncrypted();
}
public boolean isLocalEncrypted() {
return lastElPropertyValue.isLocalEncrypted();
}
@Override
public String getAssocIsEmpty(SpiExpressionRequest request, String path) {
return lastElPropertyValue.getAssocIsEmpty(request, path);
}
public Object[] getAssocIdValues(EntityBean bean) {
// Don't navigate the object graph as bean
// is assumed to be the appropriate type
return lastElPropertyValue.getAssocIdValues(bean);
}
public String getAssocIdExpression(String prefix, String operator) {
return lastElPropertyValue.getAssocIdExpression(expression, operator);
}
public String getAssocIdInExpr(String prefix) {
return lastElPropertyValue.getAssocIdInExpr(prefix);
}
public String getAssocIdInValueExpr(int size) {
return lastElPropertyValue.getAssocIdInValueExpr(size);
}
@Override
public boolean isAssocMany() {
return lastElPropertyValue.isAssocMany();
}
public boolean isAssocId() {
return assocId;
}
public boolean isAssocProperty() {
for (ElPropertyValue aChain : chain) {
if (aChain.isAssocProperty()) {
return true;
}
}
return false;
}
public String getDbColumn() {
return lastElPropertyValue.getDbColumn();
}
public BeanProperty getBeanProperty() {
return lastBeanProperty;
}
public boolean isDateTimeCapable() {
return scalarType != null && scalarType.isDateTimeCapable();
}
public int getJdbcType() {
return scalarType == null ? 0 : scalarType.getJdbcType();
}
public Object parseDateTime(long systemTimeMillis) {
return scalarType.convertFromMillis(systemTimeMillis);
}
public StringParser getStringParser() {
return scalarType;
}
public Object convert(Object value) {
// just convert using the last one in the chain
return lastElPropertyValue.convert(value);
}
@Override
public Object pathGet(Object bean) {
for (ElPropertyValue aChain : chain) {
bean = aChain.pathGet(bean);
if (bean == null) {
return null;
}
}
return bean;
}
@Override
public Object pathGetNested(Object bean) {
Object prevBean = bean;
for (int i = 0; i < last; i++) {
// always return non null prevBean
prevBean = chain[i].pathGetNested(prevBean);
}
// try the last step in the chain
return chain[last].pathGet(prevBean);
}
@Override
public void pathSet(Object bean, Object value) {
Object prevBean = bean;
for (int i = 0; i < last; i++) {
prevBean = chain[i].pathGetNested(prevBean);
}
if (prevBean != null) {
if (lastBeanProperty != null) {
// last chain element maps to a real scalar property
lastBeanProperty.pathSet(prevBean, value);
} else {
// a non-scalar property of a Compound value object
lastElPropertyValue.pathSet(prevBean, value);
}
}
}
}
@@ -0,0 +1,64 @@
package io.ebeaninternal.server.el;
import java.util.ArrayList;
import java.util.List;
/**
* Utility object used to build a ElPropertyChain.
* <p>
* Builds a ElPropertyChain based on a chain of properties with dot separators.
* </p>
* <p>
* This can navigate an object graph based on dot notation such as
* order.customer.name.
* </p>
*/
public class ElPropertyChainBuilder {
private final String expression;
private final List<ElPropertyValue> chain = new ArrayList<>();
private final boolean embedded;
private boolean containsMany;
/**
* Create with the original expression.
*/
public ElPropertyChainBuilder(boolean embedded, String expression) {
this.embedded = embedded;
this.expression = expression;
}
public boolean isContainsMany() {
return containsMany;
}
public void setContainsMany() {
this.containsMany = true;
}
public String getExpression() {
return expression;
}
/**
* Add a ElGetValue element to the chain.
*/
public ElPropertyChainBuilder add(ElPropertyValue element) {
if (element == null) {
throw new NullPointerException("element null in expression " + expression);
}
chain.add(element);
return this;
}
/**
* Build the immutable ElGetChain from the build information.
*/
public ElPropertyChain build() {
return new ElPropertyChain(containsMany, embedded, expression, chain.toArray(new ElPropertyValue[chain.size()]));
}
}
@@ -0,0 +1,77 @@
package io.ebeaninternal.server.el;
import io.ebeaninternal.server.deploy.BeanProperty;
/**
* Used to parse expressions in queries (where, orderBy etc).
* <p>
* Maps an expression to deployment information such as
* the DB column and elPrefix/elPlaceHolder is used determine
* joins and set place holders for table alias'.
* </p>
*/
public interface ElPropertyDeploy {
/**
* This is the elPrefix for all root level properties.
*/
String ROOT_ELPREFIX = "${}";
/**
* Return true if the property is a formula with a join clause.
*/
boolean containsFormulaWithJoin();
/**
* Return true if there is a property on the path that is a many property.
*/
boolean containsMany();
/**
* Return true if there is a property is on the path after sinceProperty
* that is a 'many' property.
*/
boolean containsManySince(String sinceProperty);
/**
* Return the prefix path of the property.
* <p>
* This is use to determine joins required to support
* this property.
* </p>
*/
String getElPrefix();
/**
* Return the place holder in the form of ${elPrefix}dbColumn.
* <p>
* The ${elPrefix} is replaced by the appropriate table alias.
* </p>
*/
String getElPlaceholder(boolean encrypted);
/**
* Return the name of the property.
*/
String getName();
/**
* The ElPrefix plus name.
*/
String getElName();
/**
* Return the deployment db column for this property.
*/
String getDbColumn();
/**
* Return the underlying bean property.
*/
BeanProperty getBeanProperty();
/**
* Return true if this is an aggregation property.
*/
boolean isAggregation();
}
@@ -0,0 +1,60 @@
package io.ebeaninternal.server.el;
import io.ebean.plugin.ExpressionPath;
import io.ebeaninternal.api.SpiExpressionRequest;
/**
* The expression language object that can get values.
* <p>
* This can be used for local sorting and filtering.
* </p>
*/
public interface ElPropertyValue extends ElPropertyDeploy, ExpressionPath {
/**
* Return the logical id value expression taking into account embedded id's.
*/
String getAssocIdInValueExpr(int size);
/**
* Return the logical id in expression taking into account embedded id's.
*/
String getAssocIdInExpr(String prefix);
/**
* Return the logical where clause to support "Is empty".
*/
String getAssocIsEmpty(SpiExpressionRequest request, String path);
/**
* Return true if this is an ManyToOne or OneToOne associated bean property.
*/
boolean isAssocId();
/**
* Return true if the property is a OneToMany or ManyToMany associated bean property.
*/
boolean isAssocMany();
/**
* Return true if any path of this path contains a Associated One or Many.
*/
boolean isAssocProperty();
/**
* Return true if the property is encrypted via Java.
*/
boolean isLocalEncrypted();
/**
* Return true if the property is encrypted in the DB.
*/
boolean isDbEncrypted();
/**
* Return the value ensuring objects prior to the top scalar property are
* automatically populated.
*/
Object pathGetNested(Object bean);
}
@@ -0,0 +1 @@
package io.ebeaninternal.server.el;