mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 15:55:55 +00:00
#593 - Refactor SPI - Move methods from ElPropertyValue to ExpressionPath
This commit is contained in:
@@ -6,6 +6,7 @@ import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanPersistListener;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.text.json.JsonReadOptions;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocumentMapping;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
|
||||
@@ -17,6 +18,11 @@ import java.util.Collection;
|
||||
*/
|
||||
public interface BeanType<T> {
|
||||
|
||||
/**
|
||||
* Return the short name of the bean type.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Return the full name of the bean type.
|
||||
*/
|
||||
@@ -53,12 +59,12 @@ public interface BeanType<T> {
|
||||
Property getWhenCreatedProperty();
|
||||
|
||||
/**
|
||||
* Return the SpiProperty for a property to read values from a bean.
|
||||
* Return the Property to read values from a bean.
|
||||
*/
|
||||
Property getProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Return the SpiExpressionPath for a given property path.
|
||||
* Return the ExpressionPath for a given property path.
|
||||
* <p>
|
||||
* This can return a property or nested property path.
|
||||
* </p>
|
||||
@@ -154,4 +160,28 @@ public interface BeanType<T> {
|
||||
*/
|
||||
T jsonRead(JsonParser parser, JsonReadOptions readOptions, Object objectMapper) throws IOException;
|
||||
|
||||
/**
|
||||
* Add the discriminator value to the query if needed.
|
||||
*/
|
||||
void addInheritanceWhere(SpiQuery<?> query);
|
||||
|
||||
/**
|
||||
* Return the root bean type for an inheritance hierarchy.
|
||||
*/
|
||||
BeanType<?> root();
|
||||
|
||||
/**
|
||||
* Return true if this bean type has an inheritance hierarchy.
|
||||
*/
|
||||
boolean hasInheritance();
|
||||
|
||||
/**
|
||||
* Return the discriminator column.
|
||||
*/
|
||||
String getDiscColumn();
|
||||
|
||||
/**
|
||||
* Create a bean given the discriminator value.
|
||||
*/
|
||||
T createBeanUsingDisc(Object discValue);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.avaje.ebean.plugin;
|
||||
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
|
||||
/**
|
||||
* A dot notation expression path.
|
||||
*/
|
||||
@@ -10,11 +12,46 @@ public interface ExpressionPath {
|
||||
*/
|
||||
boolean containsMany();
|
||||
|
||||
/**
|
||||
* Return the value from a given entity bean.
|
||||
*/
|
||||
Object pathGet(Object bean);
|
||||
|
||||
/**
|
||||
* Set a value to the bean for this expression path.
|
||||
*
|
||||
* @param bean the bean to set the value on
|
||||
* @param value the value to set
|
||||
*/
|
||||
void set(Object bean, Object value);
|
||||
void pathSet(Object bean, Object value);
|
||||
|
||||
/**
|
||||
* Convert the value to the expected type.
|
||||
* <p>
|
||||
* Typically useful for converting strings to the appropriate number type etc.
|
||||
* </p>
|
||||
*/
|
||||
Object convert(Object value);
|
||||
|
||||
/**
|
||||
* Return the default StringParser for the scalar property.
|
||||
*/
|
||||
StringParser getStringParser();
|
||||
|
||||
/**
|
||||
* For DateTime capable scalar types convert the long systemTimeMillis into
|
||||
* an appropriate java time (Date,Timestamp,Time,Calendar, JODA type etc).
|
||||
*/
|
||||
Object parseDateTime(long systemTimeMillis);
|
||||
|
||||
/**
|
||||
* Return true if the last type is "DateTime capable" - can support
|
||||
* {@link #parseDateTime(long)}.
|
||||
*/
|
||||
boolean isDateTimeCapable();
|
||||
|
||||
/**
|
||||
* Return the underlying JDBC type or 0 if this is not a scalar type.
|
||||
*/
|
||||
int getJdbcType();
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
*/
|
||||
private boolean isDocStoreNotify() {
|
||||
// Either queue or directly update the document store
|
||||
return docStoreMode != DocStoreMode.IGNORE;
|
||||
return docStoreMode != DocStoreMode.IGNORE || beanDescriptor.docStoreAdapter().hasEmbeddedInvalidation();
|
||||
}
|
||||
|
||||
public boolean isNotifyPersistListener() {
|
||||
|
||||
@@ -71,6 +71,8 @@ import com.avaje.ebeanservice.docstore.api.DocStoreBeanAdapter;
|
||||
import com.avaje.ebeanservice.docstore.api.DocStoreUpdateContext;
|
||||
import com.avaje.ebeanservice.docstore.api.DocStoreUpdates;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocMappingBuilder;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyType;
|
||||
import com.avaje.ebeanservice.docstore.api.mapping.DocumentMapping;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import org.slf4j.Logger;
|
||||
@@ -80,6 +82,7 @@ import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -358,12 +361,12 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
|
||||
private final String docStoreQueueId;
|
||||
|
||||
private DocumentMapping docMapping;
|
||||
|
||||
private final BeanDescriptorDraftHelp<T> draftHelp;
|
||||
private final BeanDescriptorCacheHelp<T> cacheHelp;
|
||||
private final BeanDescriptorJsonHelp<T> jsonHelp;
|
||||
private final DocStoreBeanAdapter<T> docStoreAdapter;
|
||||
private DocStoreBeanAdapter<T> docStoreAdapter;
|
||||
private DocumentMapping docMapping;
|
||||
|
||||
|
||||
private final String defaultSelectClause;
|
||||
|
||||
@@ -680,7 +683,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
namedUpdate.initialise(parser);
|
||||
}
|
||||
}
|
||||
docStoreAdapter.registerPaths();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -690,7 +692,11 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
for (int i = 0; i < propertiesMany.length; i++) {
|
||||
propertiesMany[i].initialisePostTarget();
|
||||
}
|
||||
if (inheritInfo != null && !inheritInfo.isRoot()) {
|
||||
docStoreAdapter = (DocStoreBeanAdapter<T>)inheritInfo.getRoot().getBeanDescriptor().docStoreAdapter();
|
||||
}
|
||||
docMapping = docStoreAdapter.createDocMapping();
|
||||
docStoreAdapter.registerPaths();
|
||||
}
|
||||
|
||||
public void initInheritInfo() {
|
||||
@@ -932,16 +938,44 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
/**
|
||||
* Build the Document mapping recursively with the given prefix relative to the root of the document.
|
||||
*/
|
||||
public void docStoreMapping(DocMappingBuilder mapping, String prefix) {
|
||||
public void docStoreMapping(final DocMappingBuilder mapping, final String prefix) {
|
||||
|
||||
if (prefix != null && idProperty != null) {
|
||||
// id property not included in the
|
||||
idProperty.docStoreMapping(mapping, prefix);
|
||||
}
|
||||
|
||||
if (inheritInfo != null) {
|
||||
String discCol = inheritInfo.getDiscriminatorColumn();
|
||||
if (Types.VARCHAR == inheritInfo.getDiscriminatorType()) {
|
||||
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.ENUM));
|
||||
} else {
|
||||
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.INTEGER));
|
||||
}
|
||||
}
|
||||
for (BeanProperty prop: propertiesNonTransient) {
|
||||
prop.docStoreMapping(mapping, prefix);
|
||||
}
|
||||
if (inheritInfo != null) {
|
||||
inheritInfo.visitChildren(new InheritInfoVisitor() {
|
||||
@Override
|
||||
public void visit(InheritInfo inheritInfo) {
|
||||
for (BeanProperty localProperty : inheritInfo.localProperties()) {
|
||||
localProperty.docStoreMapping(mapping, prefix);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the root bean type if part of inheritance hierarchy.
|
||||
*/
|
||||
public BeanType<?> root() {
|
||||
if (inheritInfo != null && !inheritInfo.isRoot()) {
|
||||
return inheritInfo.getRoot().getBeanDescriptor();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1539,7 +1573,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
}
|
||||
String[] splitBegin = SplitName.splitBegin(path);
|
||||
|
||||
BeanProperty beanProperty = propMap.get(splitBegin[0]);
|
||||
BeanProperty beanProperty = findBeanProperty(splitBegin[0]);
|
||||
if (beanProperty instanceof BeanPropertyAssoc<?>) {
|
||||
BeanPropertyAssoc<?> assocProp = (BeanPropertyAssoc<?>) beanProperty;
|
||||
return assocProp.getTargetDescriptor().getBeanDescriptor(splitBegin[1]);
|
||||
@@ -1709,7 +1743,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
|
||||
@Override
|
||||
public Property getProperty(String propName) {
|
||||
return getBeanProperty(propName);
|
||||
return findBeanProperty(propName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1976,6 +2010,30 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
return inheritInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasInheritance() {
|
||||
return inheritInfo != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDiscColumn() {
|
||||
return inheritInfo.getDiscriminatorColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createBeanUsingDisc(Object discValue) {
|
||||
InheritInfo type = inheritInfo.getType(discValue.toString());
|
||||
return (T)type.getBeanDescriptor().createBean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInheritanceWhere(SpiQuery<?> query) {
|
||||
if (inheritInfo != null && !inheritInfo.isRoot()) {
|
||||
query.where().eq(inheritInfo.getDiscriminatorColumn(), inheritInfo.getDiscriminatorValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is an embedded bean.
|
||||
*/
|
||||
|
||||
@@ -162,23 +162,22 @@ public final class BeanFkeyProperty implements ElPropertyValue {
|
||||
throw new RuntimeException("ElPropertyDeploy only - not implemented");
|
||||
}
|
||||
|
||||
public Object elConvertType(Object value) {
|
||||
@Override
|
||||
public Object convert(Object value) {
|
||||
throw new RuntimeException("ElPropertyDeploy only - not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object bean, Object value) {
|
||||
public void pathSet(Object bean, Object value) {
|
||||
throw new RuntimeException("ElPropertyDeploy only - not implemented");
|
||||
}
|
||||
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate) {
|
||||
throw new RuntimeException("ElPropertyDeploy only - not implemented");
|
||||
}
|
||||
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
@Override
|
||||
public Object pathGet(Object bean) {
|
||||
throw new RuntimeException("ElPropertyDeploy only - not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object elGetReference(EntityBean bean) {
|
||||
throw new RuntimeException("ElPropertyDeploy only - not implemented");
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
}
|
||||
}
|
||||
|
||||
public Object elConvertType(Object value) {
|
||||
public Object convert(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -775,25 +775,20 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object bean, Object value) {
|
||||
public void pathSet(Object bean, Object value) {
|
||||
|
||||
// convert for Enums etc
|
||||
Object logicalVal = convertToLogicalType(value);
|
||||
elSetValue((EntityBean) bean, logicalVal, true);
|
||||
}
|
||||
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate) {
|
||||
if (bean != null) {
|
||||
// Not using setValueIntercept at this stage
|
||||
setValue(bean, value);
|
||||
Object logicalVal = convertToLogicalType(value);
|
||||
setValue((EntityBean)bean, logicalVal);
|
||||
}
|
||||
}
|
||||
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
@Override
|
||||
public Object pathGet(Object bean) {
|
||||
if (bean == null) {
|
||||
return null;
|
||||
}
|
||||
return getValueIntercept(bean);
|
||||
return getValueIntercept((EntityBean)bean);
|
||||
}
|
||||
|
||||
public Object elGetReference(EntityBean bean) {
|
||||
@@ -1330,7 +1325,7 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
* Return true if this is a String Id property and should be treated as a code by the document store.
|
||||
*/
|
||||
private boolean isStringId(DocPropertyType type) {
|
||||
return DocPropertyType.STRING == type && id;
|
||||
return DocPropertyType.STRING == type && (id || discriminator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ public class BeanPropertyCompoundScalar extends BeanProperty {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
return getValue(bean);
|
||||
public Object pathGet(Object bean) {
|
||||
return ctProperty.getValue(bean);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -145,6 +145,13 @@ public class InheritInfo {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the local properties for this node in the hierarchy.
|
||||
*/
|
||||
public BeanProperty[] localProperties() {
|
||||
return descriptor.propertiesLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bean property additionally looking in the sub types.
|
||||
*/
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.avaje.ebeaninternal.server.el;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
|
||||
/**
|
||||
* Comparator based on a ElGetValue.
|
||||
*/
|
||||
@@ -23,16 +21,14 @@ public final class ElComparatorProperty<T> implements Comparator<T>, ElComparato
|
||||
|
||||
public int compare(T o1, T o2) {
|
||||
|
||||
Object val1 = elGetValue.elGetValue((EntityBean) o1);
|
||||
Object val2 = elGetValue.elGetValue((EntityBean) 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.elGetValue((EntityBean) o2);
|
||||
|
||||
Object val2 = elGetValue.pathGet(o2);
|
||||
return compareValues(value, val2);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public final class ElFilter<T> implements Filter<T> {
|
||||
private Object convertValue(String propertyName, Object value) {
|
||||
// convert type of value to match expected type
|
||||
ElPropertyValue elGetValue = beanDescriptor.getElGetValue(propertyName);
|
||||
return elGetValue.elConvertType(value);
|
||||
return elGetValue.convert(value);
|
||||
}
|
||||
|
||||
private ElComparator<T> getElComparator(String propertyName) {
|
||||
@@ -87,8 +87,8 @@ public final class ElFilter<T> implements Filter<T> {
|
||||
public Filter<T> between(String propertyName, Object min, Object max) {
|
||||
|
||||
ElPropertyValue elGetValue = getElGetValue(propertyName);
|
||||
min = elGetValue.elConvertType(min);
|
||||
max = elGetValue.elConvertType(max);
|
||||
min = elGetValue.convert(min);
|
||||
max = elGetValue.convert(max);
|
||||
|
||||
ElComparator<T> elComparator = getElComparator(propertyName);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String) elGetValue.elGetValue((EntityBean) bean);
|
||||
String v = (String) elGetValue.pathGet(bean);
|
||||
return pattern.matcher(v).matches();
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String) elGetValue.elGetValue((EntityBean) bean);
|
||||
String v = (String) elGetValue.pathGet(bean);
|
||||
return value.equalsIgnoreCase(v);
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class ElMatchBuilder {
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
|
||||
String v = (String) elGetValue.elGetValue((EntityBean) bean);
|
||||
String v = (String) elGetValue.pathGet(bean);
|
||||
return charMatch.startsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class ElMatchBuilder {
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
|
||||
String v = (String) elGetValue.elGetValue((EntityBean) bean);
|
||||
String v = (String) elGetValue.pathGet(bean);
|
||||
return charMatch.endsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String) elGetValue.elGetValue((EntityBean) bean);
|
||||
String v = (String) elGetValue.pathGet(bean);
|
||||
return value.startsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String) elGetValue.elGetValue((EntityBean) bean);
|
||||
String v = (String) elGetValue.pathGet(bean);
|
||||
return value.endsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
return (null == elGetValue.elGetValue((EntityBean) bean));
|
||||
return (null == elGetValue.pathGet(bean));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
return (null != elGetValue.elGetValue((EntityBean) bean));
|
||||
return (null != elGetValue.pathGet(bean));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ class ElMatchBuilder {
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
|
||||
Object value = elGetValue.elGetValue((EntityBean) bean);
|
||||
Object value = elGetValue.pathGet(bean);
|
||||
return value != null && set.contains(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,20 +220,19 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
return scalarType;
|
||||
}
|
||||
|
||||
public Object elConvertType(Object value) {
|
||||
public Object convert(Object value) {
|
||||
// just convert using the last one in the chain
|
||||
return lastElPropertyValue.elConvertType(value);
|
||||
return lastElPropertyValue.convert(value);
|
||||
}
|
||||
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
|
||||
@Override
|
||||
public Object pathGet(Object bean) {
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
bean = (EntityBean) chain[i].elGetValue(bean);
|
||||
bean = chain[i].pathGet(bean);
|
||||
if (bean == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -245,39 +244,25 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
prevBean = (EntityBean) chain[i].elGetReference(prevBean);
|
||||
}
|
||||
// try the last step in the chain
|
||||
return chain[last].elGetValue(prevBean);
|
||||
return chain[last].pathGet(prevBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object bean, Object value) {
|
||||
elSetValue((EntityBean)bean, value, true);
|
||||
}
|
||||
public void pathSet(Object bean, Object value) {
|
||||
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate) {
|
||||
|
||||
EntityBean prevBean = bean;
|
||||
if (populate) {
|
||||
for (int i = 0; i < last; i++) {
|
||||
// always return non null prevBean
|
||||
prevBean = (EntityBean) chain[i].elGetReference(prevBean);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < last; i++) {
|
||||
// always return non null prevBean
|
||||
prevBean = (EntityBean) chain[i].elGetValue(prevBean);
|
||||
if (prevBean == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
EntityBean prevBean = (EntityBean)bean;
|
||||
for (int i = 0; i < last; i++) {
|
||||
// always return non null prevBean
|
||||
prevBean = (EntityBean) chain[i].elGetReference(prevBean);
|
||||
}
|
||||
if (prevBean != null) {
|
||||
if (lastBeanProperty != null) {
|
||||
// last chain element maps to a real scalar property
|
||||
lastBeanProperty.setValueIntercept(prevBean, value);
|
||||
lastBeanProperty.pathSet(prevBean, value);
|
||||
|
||||
} else {
|
||||
// a non-scalar property of a Compound value object
|
||||
lastElPropertyValue.elSetValue(prevBean, value, populate);
|
||||
lastElPropertyValue.pathSet(prevBean, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,53 +60,10 @@ public interface ElPropertyValue extends ElPropertyDeploy, ExpressionPath {
|
||||
*/
|
||||
int getDeployOrder();
|
||||
|
||||
/**
|
||||
* Return the default StringParser for the scalar property.
|
||||
*/
|
||||
StringParser getStringParser();
|
||||
|
||||
/**
|
||||
* Return true if the last type is "DateTime capable" - can support
|
||||
* {@link #parseDateTime(long)}.
|
||||
*/
|
||||
boolean isDateTimeCapable();
|
||||
|
||||
/**
|
||||
* Return the underlying JDBC type or 0 if this is not a scalar type.
|
||||
*/
|
||||
int getJdbcType();
|
||||
|
||||
/**
|
||||
* For DateTime capable scalar types convert the long systemTimeMillis into
|
||||
* an appropriate java time (Date,Timestamp,Time,Calendar, JODA type etc).
|
||||
*/
|
||||
Object parseDateTime(long systemTimeMillis);
|
||||
|
||||
/**
|
||||
* Return the value from a given entity bean.
|
||||
*/
|
||||
Object elGetValue(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Return the value ensuring objects prior to the top scalar property are
|
||||
* automatically populated.
|
||||
*/
|
||||
Object elGetReference(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Set a value given a root level bean.
|
||||
* <p>
|
||||
* If populate then
|
||||
* </p>
|
||||
*/
|
||||
void elSetValue(EntityBean bean, Object value, boolean populate);
|
||||
|
||||
/**
|
||||
* Convert the value to the expected type.
|
||||
* <p>
|
||||
* Typically useful for converting strings to the appropriate number type
|
||||
* etc.
|
||||
* </p>
|
||||
*/
|
||||
Object elConvertType(Object value);
|
||||
}
|
||||
|
||||
@@ -230,7 +230,6 @@ public final class CQueryPlanStats {
|
||||
return queryPlan.isAutoTuned();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getQueryPlanHash() {
|
||||
return queryPlan.getPlanKey().toString();
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.Locale;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.plugin.ExpressionPath;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.TimeStringParser;
|
||||
@@ -24,8 +25,7 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author rbygrave
|
||||
* Implementation of the CsvReader
|
||||
*/
|
||||
public class TCsvReader<T> implements CsvReader<T> {
|
||||
|
||||
@@ -55,9 +55,6 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
|
||||
private boolean addPropertiesFromHeader;
|
||||
|
||||
// private String addHeaderDateTimeFormat;
|
||||
// private Locale addHeaderLocale;
|
||||
|
||||
public TCsvReader(EbeanServer server, BeanDescriptor<T> descriptor) {
|
||||
this.server = server;
|
||||
this.descriptor = descriptor;
|
||||
@@ -114,11 +111,10 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
|
||||
public void addDateTime(String propertyName, String dateTimeFormat, Locale locale) {
|
||||
|
||||
ElPropertyValue elProp = descriptor.getElGetValue(propertyName);
|
||||
ExpressionPath elProp = descriptor.getExpressionPath(propertyName);
|
||||
if (!elProp.isDateTimeCapable()) {
|
||||
throw new TextException("Property " + propertyName + " is not DateTime capable");
|
||||
}
|
||||
|
||||
if (dateTimeFormat == null) {
|
||||
dateTimeFormat = getDefaultDateTimeFormat(elProp.getJdbcType());
|
||||
}
|
||||
@@ -150,7 +146,7 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
|
||||
public void addProperty(String propertyName, StringParser parser) {
|
||||
|
||||
ElPropertyValue elProp = descriptor.getElGetValue(propertyName);
|
||||
ExpressionPath elProp = descriptor.getExpressionPath(propertyName);
|
||||
if (parser == null) {
|
||||
parser = elProp.getStringParser();
|
||||
}
|
||||
@@ -214,7 +210,7 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
callback.end(row);
|
||||
|
||||
} catch (Exception e) {
|
||||
// notify that an error occured so that any
|
||||
// notify that an error occurred so that any
|
||||
// transaction can be rolled back if required
|
||||
callback.endWithError(row, e);
|
||||
throw e;
|
||||
@@ -285,26 +281,23 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
*/
|
||||
public static class CsvColumn {
|
||||
|
||||
private final ElPropertyValue elProp;
|
||||
private final ExpressionPath path;
|
||||
private final StringParser parser;
|
||||
private final boolean ignore;
|
||||
|
||||
/**
|
||||
* Constructor for the IGNORE column.
|
||||
*/
|
||||
private CsvColumn() {
|
||||
this.elProp = null;
|
||||
this.path = null;
|
||||
this.parser = null;
|
||||
this.ignore = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a property and parser.
|
||||
*/
|
||||
public CsvColumn(ElPropertyValue elProp, StringParser parser) {
|
||||
this.elProp = elProp;
|
||||
public CsvColumn(ExpressionPath path, StringParser parser) {
|
||||
this.path = path;
|
||||
this.parser = parser;
|
||||
this.ignore = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -312,9 +305,9 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
*/
|
||||
public void convertAndSet(String strValue, EntityBean bean) {
|
||||
|
||||
if (!ignore) {
|
||||
if (parser != null && path != null) {
|
||||
Object value = parser.parse(strValue);
|
||||
elProp.elSetValue(bean, value, true);
|
||||
path.pathSet(bean, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,19 +320,19 @@ public class TCsvReader<T> implements CsvReader<T> {
|
||||
private static class DateTimeParser implements StringParser {
|
||||
|
||||
private final DateFormat dateFormat;
|
||||
private final ElPropertyValue elProp;
|
||||
private final ExpressionPath path;
|
||||
private final String format;
|
||||
|
||||
DateTimeParser(DateFormat dateFormat, String format, ElPropertyValue elProp) {
|
||||
DateTimeParser(DateFormat dateFormat, String format, ExpressionPath path) {
|
||||
this.dateFormat = dateFormat;
|
||||
this.elProp = elProp;
|
||||
this.path = path;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public Object parse(String value) {
|
||||
try {
|
||||
Date dt = dateFormat.parse(value);
|
||||
return elProp.parseDateTime(dt.getTime());
|
||||
return path.parseDateTime(dt.getTime());
|
||||
|
||||
} catch (ParseException e) {
|
||||
throw new TextException("Error parsing [" + value + "] using format[" + format + "]", e);
|
||||
|
||||
@@ -28,7 +28,8 @@ public class CtCompoundPropertyElAdapter implements ElPropertyValue {
|
||||
this.deployOrder = deployOrder;
|
||||
}
|
||||
|
||||
public Object elConvertType(Object value) {
|
||||
@Override
|
||||
public Object convert(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -36,16 +37,13 @@ public class CtCompoundPropertyElAdapter implements ElPropertyValue {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
@Override
|
||||
public Object pathGet(Object bean) {
|
||||
return prop.getValue(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object bean, Object value) {
|
||||
elSetValue((EntityBean) bean, value, true);
|
||||
}
|
||||
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate) {
|
||||
public void pathSet(Object bean, Object value) {
|
||||
prop.setValue(bean, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -113,4 +113,9 @@ public interface DocStoreBeanAdapter<T> extends BeanDocType<T> {
|
||||
* </p>
|
||||
*/
|
||||
String rawProperty(String property);
|
||||
|
||||
/**
|
||||
* Return true if this bean type as embedded invalidate registered.
|
||||
*/
|
||||
boolean hasEmbeddedInvalidation();
|
||||
}
|
||||
|
||||
+48
-28
@@ -4,12 +4,15 @@ import com.avaje.ebean.FetchPath;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.annotation.DocStore;
|
||||
import com.avaje.ebean.annotation.DocStoreMode;
|
||||
import com.avaje.ebean.plugin.BeanType;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequest;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfoVisitor;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
|
||||
import com.avaje.ebeanservice.docstore.api.DocStoreBeanAdapter;
|
||||
import com.avaje.ebeanservice.docstore.api.DocStoreUpdateContext;
|
||||
@@ -41,11 +44,6 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
*/
|
||||
protected final boolean mapped;
|
||||
|
||||
/**
|
||||
* Nested path properties defining the doc structure for indexing.
|
||||
*/
|
||||
protected final DocStructure docStructure;
|
||||
|
||||
/**
|
||||
* Identifier used in the queue system to identify the index.
|
||||
*/
|
||||
@@ -87,18 +85,28 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
*/
|
||||
protected final List<DocStoreEmbeddedInvalidation> embeddedInvalidation = new ArrayList<DocStoreEmbeddedInvalidation>();
|
||||
|
||||
protected final PathProperties pathProps;
|
||||
|
||||
/**
|
||||
* Map of properties to 'raw' properties.
|
||||
*/
|
||||
private Map<String, String> sortableMap;
|
||||
protected Map<String, String> sortableMap;
|
||||
|
||||
/**
|
||||
* Nested path properties defining the doc structure for indexing.
|
||||
*/
|
||||
protected DocStructure docStructure;
|
||||
|
||||
protected DocumentMapping documentMapping;
|
||||
|
||||
private boolean registerPaths;
|
||||
|
||||
public DocStoreBeanBaseAdapter(BeanDescriptor<T> desc, DeployBeanDescriptor<T> deploy) {
|
||||
|
||||
this.desc = desc;
|
||||
this.server = desc.getEbeanServer();
|
||||
this.mapped = deploy.isDocStoreMapped();
|
||||
this.docStructure = (!mapped) ? null : derivePathProperties(deploy);
|
||||
this.pathProps = deploy.getDocStorePathProperties();
|
||||
this.docStore = deploy.getDocStore();
|
||||
this.queueId = derive(desc, deploy.getDocStoreQueueId());
|
||||
this.indexName = derive(desc, deploy.getDocStoreIndexName());
|
||||
@@ -108,28 +116,30 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
this.delete = deploy.getDocStoreDeleteEvent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEmbeddedInvalidation() {
|
||||
return !embeddedInvalidation.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentMapping createDocMapping() {
|
||||
|
||||
if (documentMapping != null) {
|
||||
return documentMapping;
|
||||
}
|
||||
|
||||
if (!mapped) return null;
|
||||
|
||||
PathProperties paths = docStructure.doc();
|
||||
this.docStructure = derivePathProperties(pathProps);
|
||||
|
||||
DocMappingBuilder mappingBuilder = new DocMappingBuilder(paths, docStore);
|
||||
DocMappingBuilder mappingBuilder = new DocMappingBuilder(docStructure.doc(), docStore);
|
||||
desc.docStoreMapping(mappingBuilder, null);
|
||||
|
||||
mappingBuilder.applyMapping();
|
||||
prepareMapping(mappingBuilder);
|
||||
|
||||
sortableMap = mappingBuilder.collectSortable();
|
||||
|
||||
docStructure.prepareMany(desc);
|
||||
|
||||
return mappingBuilder.create(queueId, indexName, indexType);
|
||||
}
|
||||
|
||||
protected void prepareMapping(DocMappingBuilder mappingBuilder) {
|
||||
// do nothing by default
|
||||
documentMapping = mappingBuilder.create(queueId, indexName, indexType);
|
||||
return documentMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,7 +169,7 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
*/
|
||||
@Override
|
||||
public void registerPaths() {
|
||||
if (mapped) {
|
||||
if (mapped && !registerPaths) {
|
||||
Collection<PathProperties.Props> pathProps = docStructure.doc().getPathProps();
|
||||
for (PathProperties.Props pathProp : pathProps) {
|
||||
String path = pathProp.getPath();
|
||||
@@ -170,6 +180,7 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
targetDesc.docStoreAdapter().registerInvalidationPath(desc.getDocStoreQueueId(), fullPath, pathProp.getProperties());
|
||||
}
|
||||
}
|
||||
registerPaths = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,13 +234,8 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
* Return the pathProperties which defines the JSON document to index.
|
||||
* This can add derived/embedded/nested parts to the document.
|
||||
*/
|
||||
protected DocStructure derivePathProperties(DeployBeanDescriptor<T> deploy) {
|
||||
protected DocStructure derivePathProperties(PathProperties pathProps) {
|
||||
|
||||
if (!mapped) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PathProperties pathProps = deploy.getDocStorePathProperties();
|
||||
boolean includeByDefault = (pathProps == null);
|
||||
if (pathProps == null) {
|
||||
pathProps = new PathProperties();
|
||||
@@ -238,13 +244,27 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
return getDocStructure(pathProps, includeByDefault);
|
||||
}
|
||||
|
||||
protected DocStructure getDocStructure(PathProperties pathProps, boolean includeByDefault) {
|
||||
protected DocStructure getDocStructure(PathProperties pathProps, final boolean includeByDefault) {
|
||||
|
||||
final DocStructure docStructure = new DocStructure(pathProps);
|
||||
|
||||
DocStructure docStructure = new DocStructure(pathProps);
|
||||
BeanProperty[] properties = desc.propertiesNonTransient();
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
properties[i].docStoreInclude(includeByDefault, docStructure);
|
||||
}
|
||||
|
||||
InheritInfo inheritInfo = desc.getInheritInfo();
|
||||
if (inheritInfo != null) {
|
||||
inheritInfo.visitChildren(new InheritInfoVisitor() {
|
||||
@Override
|
||||
public void visit(InheritInfo inheritInfo) {
|
||||
for (BeanProperty localProperty : inheritInfo.localProperties()) {
|
||||
localProperty.docStoreInclude(includeByDefault, docStructure);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return docStructure;
|
||||
}
|
||||
|
||||
@@ -293,7 +313,7 @@ public abstract class DocStoreBeanBaseAdapter<T> implements DocStoreBeanAdapter<
|
||||
/**
|
||||
* Return the supplied value or default to the bean name lower case.
|
||||
*/
|
||||
protected String derive(BeanDescriptor<T> desc, String suppliedValue) {
|
||||
protected String derive(BeanType<?> desc, String suppliedValue) {
|
||||
return (suppliedValue != null && suppliedValue.length() > 0) ? suppliedValue : desc.getName().toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ public class DocStructure {
|
||||
public <T> void prepareMany(BeanDescriptor<T> desc) {
|
||||
Set<String> strings = embedded.keySet();
|
||||
for (String prop : strings) {
|
||||
BeanPropertyAssoc<?> embProp = (BeanPropertyAssoc<?>)desc.getBeanProperty(prop);
|
||||
BeanPropertyAssoc<?> embProp = (BeanPropertyAssoc<?>)desc.findBeanProperty(prop);
|
||||
if (embProp.isMany()) {
|
||||
prepare(prop, embProp);
|
||||
}
|
||||
|
||||
@@ -3,17 +3,24 @@ package com.avaje.ebean.plugin;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.FetchPath;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import com.avaje.tests.inheritance.Stockforecast;
|
||||
import com.avaje.tests.model.basic.Car;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import com.avaje.tests.model.basic.Order;
|
||||
import com.avaje.tests.model.basic.OrderDetail;
|
||||
import com.avaje.tests.model.basic.Person;
|
||||
import com.avaje.tests.model.basic.Product;
|
||||
import com.avaje.tests.model.basic.Vehicle;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class BeanTypeTest {
|
||||
@@ -189,4 +196,48 @@ public class BeanTypeTest {
|
||||
public void docStoreUpdateEmbedded() throws Exception {
|
||||
beanType(Order.class).docStore().updateEmbedded(1, "customer", "someJson", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasInheritance_when_not() {
|
||||
assertFalse(beanType(Order.class).hasInheritance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasInheritance_when_root() {
|
||||
assertTrue(beanType(Vehicle.class).hasInheritance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasInheritance_when_leaf() {
|
||||
assertTrue(beanType(Car.class).hasInheritance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDiscColumn_when_default() {
|
||||
assertEquals(beanType(Car.class).getDiscColumn(),"dtype");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDiscColumn_when_set() {
|
||||
assertEquals(beanType(Stockforecast.class).getDiscColumn(),"type");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createBeanUsingDisc_when_set() {
|
||||
Vehicle vehicle = beanType(Vehicle.class).createBeanUsingDisc("C");
|
||||
assertTrue(vehicle instanceof Car);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addInheritanceWhere_when_leaf() {
|
||||
Query<Vehicle> query = server.find(Vehicle.class);
|
||||
beanType(Car.class).addInheritanceWhere((SpiQuery<?>)query);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addInheritanceWhere_when_root() {
|
||||
Query<Vehicle> query = server.find(Vehicle.class);
|
||||
beanType(Vehicle.class).addInheritanceWhere((SpiQuery<?>)query);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class ExpressionPathTest {
|
||||
|
||||
BeanType<Order> beanType = beanType(Order.class);
|
||||
Order order = new Order();
|
||||
beanType.getExpressionPath("id").set(order, 42);
|
||||
beanType.getExpressionPath("id").pathSet(order, 42);
|
||||
assertThat(order.getId()).isEqualTo(42);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class ExpressionPathTest {
|
||||
|
||||
BeanType<Order> beanType = beanType(Order.class);
|
||||
Order order = new Order();
|
||||
beanType.getExpressionPath("customer.name").set(order, "Rob");
|
||||
beanType.getExpressionPath("customer.name").pathSet(order, "Rob");
|
||||
assertThat(order.getCustomer().getName()).isEqualTo("Rob");
|
||||
}
|
||||
|
||||
|
||||
@@ -2,62 +2,67 @@ package com.avaje.tests.ddd.iud;
|
||||
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.plugin.BeanType;
|
||||
import com.avaje.ebean.plugin.ExpressionPath;
|
||||
import com.avaje.ebean.plugin.SpiServer;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.tests.model.ddd.DPerson;
|
||||
import com.avaje.tests.model.ivo.CMoney;
|
||||
import com.avaje.tests.model.ivo.Money;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Currency;
|
||||
|
||||
public class TestDPersonEl extends TestCase {
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
public void test() throws IOException {
|
||||
public class TestDPersonEl {
|
||||
|
||||
Currency NZD = Currency.getInstance("NZD");
|
||||
|
||||
DPerson p = new DPerson();
|
||||
p.setFirstName("first");
|
||||
p.setLastName("last");
|
||||
p.setSalary(new Money("12200"));
|
||||
p.setCmoney(new CMoney(new Money("12"), NZD));
|
||||
|
||||
SpiEbeanServer server = (SpiEbeanServer)Ebean.getServer(null);
|
||||
|
||||
BeanDescriptor<DPerson> descriptor = server.getBeanDescriptor(DPerson.class);
|
||||
|
||||
ElPropertyValue elCmoney = descriptor.getElGetValue("cmoney");
|
||||
// ElPropertyValue elCmoneyAmt = descriptor.getElGetValue("cmoney.amount");
|
||||
// ElPropertyValue elCmoneyCur = descriptor.getElGetValue("cmoney.currency");
|
||||
|
||||
JsonContext jsonContext = server.json();
|
||||
String json = jsonContext.toJson(p);
|
||||
|
||||
DPerson bean = jsonContext.toBean(DPerson.class, json);
|
||||
Assert.assertEquals("first", bean.getFirstName());
|
||||
Assert.assertEquals(new Money("12200"), bean.getSalary());
|
||||
Assert.assertEquals(new Money("12"), bean.getCmoney().getAmount());
|
||||
Assert.assertEquals(NZD, bean.getCmoney().getCurrency());
|
||||
|
||||
|
||||
EntityBean entityBean = (EntityBean)p;
|
||||
|
||||
Object cmoney = elCmoney.elGetValue(entityBean);
|
||||
// Object amt = elCmoneyAmt.elGetValue(entityBean);
|
||||
// Object cur = elCmoneyCur.elGetValue(entityBean);
|
||||
|
||||
Assert.assertNotNull(cmoney);
|
||||
// Assert.assertEquals(new Money("12"), amt);
|
||||
// Assert.assertEquals(NZD, cur);
|
||||
|
||||
p.setCmoney(null);
|
||||
Assert.assertNull(p.getCmoney());
|
||||
@Test
|
||||
public void test() throws IOException {
|
||||
|
||||
Currency NZD = Currency.getInstance("NZD");
|
||||
|
||||
DPerson p = new DPerson();
|
||||
p.setFirstName("first");
|
||||
p.setLastName("last");
|
||||
p.setSalary(new Money("12200"));
|
||||
p.setCmoney(new CMoney(new Money("12"), NZD));
|
||||
|
||||
SpiServer server = Ebean.getDefaultServer().getPluginApi();
|
||||
|
||||
BeanType<DPerson> descriptor = server.getBeanType(DPerson.class);
|
||||
|
||||
|
||||
JsonContext jsonContext = server.json();
|
||||
String json = jsonContext.toJson(p);
|
||||
|
||||
DPerson bean = jsonContext.toBean(DPerson.class, json);
|
||||
assertEquals("first", bean.getFirstName());
|
||||
assertEquals(new Money("12200"), bean.getSalary());
|
||||
assertEquals(new Money("12"), bean.getCmoney().getAmount());
|
||||
assertEquals(NZD, bean.getCmoney().getCurrency());
|
||||
|
||||
|
||||
EntityBean entityBean = (EntityBean) p;
|
||||
|
||||
ExpressionPath elCmoney = descriptor.getExpressionPath("cmoney");
|
||||
ExpressionPath elCmoneyAmt = descriptor.getExpressionPath("cmoney.amount");
|
||||
ExpressionPath elCmoneyCur = descriptor.getExpressionPath("cmoney.currency");
|
||||
|
||||
Object cmoney = elCmoney.pathGet(entityBean);
|
||||
Object amt = elCmoneyAmt.pathGet(entityBean);
|
||||
Object cur = elCmoneyCur.pathGet(entityBean);
|
||||
|
||||
assertNotNull(cmoney);
|
||||
assertEquals(new Money("12"), amt);
|
||||
assertEquals(NZD, cur);
|
||||
|
||||
p.setCmoney(null);
|
||||
assertNull(p.getCmoney());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.avaje.tests.el;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.tests.model.basic.Address;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
|
||||
public class TestElGetReference extends TestCase {
|
||||
|
||||
|
||||
public void test() {
|
||||
|
||||
Address a = new Address();
|
||||
a.setId((short)12);
|
||||
a.setLine1("line1");
|
||||
a.setCity("Auckland");
|
||||
|
||||
Customer c0 = new Customer();
|
||||
c0.setBillingAddress(a);
|
||||
|
||||
Customer c1 = new Customer();
|
||||
|
||||
SpiEbeanServer server = (SpiEbeanServer)Ebean.getServer(null);
|
||||
BeanDescriptor<Customer> descriptor = server.getBeanDescriptor(Customer.class);
|
||||
|
||||
ElPropertyValue elProp = descriptor.getElGetValue("billingAddress.id");
|
||||
ElPropertyValue addrLine1Prop = descriptor.getElGetValue("billingAddress.line1");
|
||||
ElPropertyValue addrCityProp = descriptor.getElGetValue("billingAddress.city");
|
||||
|
||||
elProp.elGetReference((EntityBean)c0);
|
||||
elProp.elGetReference((EntityBean)c1);
|
||||
|
||||
addrLine1Prop.elSetValue((EntityBean)c1, "12 someplace", true);
|
||||
addrCityProp.elSetValue((EntityBean)c1, "Auckland", true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.avaje.tests.el;
|
||||
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.plugin.BeanType;
|
||||
import com.avaje.ebean.plugin.ExpressionPath;
|
||||
import com.avaje.ebean.plugin.SpiServer;
|
||||
import com.avaje.tests.model.basic.Address;
|
||||
import com.avaje.tests.model.basic.Country;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestPathExpression {
|
||||
|
||||
final BeanType<Customer> beanType;
|
||||
final ExpressionPath billingId;
|
||||
final ExpressionPath line1;
|
||||
final ExpressionPath city;
|
||||
|
||||
public TestPathExpression() {
|
||||
SpiServer server = Ebean.getDefaultServer().getPluginApi();
|
||||
beanType = server.getBeanType(Customer.class);
|
||||
billingId = beanType.getExpressionPath("billingAddress.id");
|
||||
line1 = beanType.getExpressionPath("billingAddress.line1");
|
||||
city = beanType.getExpressionPath("billingAddress.city");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathSet() {
|
||||
|
||||
Customer c1 = new Customer();
|
||||
line1.pathSet(c1, "12 someplace");
|
||||
city.pathSet(c1, "Auckland");
|
||||
billingId.pathSet(c1, 4);
|
||||
|
||||
beanType.getExpressionPath("id").pathSet(c1, 42L);
|
||||
beanType.getExpressionPath("name").pathSet(c1, "jimmy");
|
||||
beanType.getExpressionPath("status").pathSet(c1, "ACTIVE");
|
||||
beanType.getExpressionPath("billingAddress.country.code").pathSet(c1, "NZ");
|
||||
beanType.getExpressionPath("billingAddress.country.name").pathSet(c1, "New Zealand");
|
||||
|
||||
|
||||
assertEquals(c1.getId(), Integer.valueOf(42));
|
||||
assertEquals(c1.getName(), "jimmy");
|
||||
assertEquals(c1.getStatus(), Customer.Status.ACTIVE);
|
||||
assertEquals(c1.getBillingAddress().getLine1(), "12 someplace");
|
||||
assertEquals(c1.getBillingAddress().getCity(), "Auckland");
|
||||
assertEquals(c1.getBillingAddress().getId(), Short.valueOf("4"));
|
||||
|
||||
assertEquals(c1.getBillingAddress().getCountry().getCode(), "NZ");
|
||||
assertEquals(c1.getBillingAddress().getCountry().getName(), "New Zealand");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathGet() {
|
||||
|
||||
Address billingAddress = new Address();
|
||||
billingAddress.setId((short)12);
|
||||
billingAddress.setLine1("line1");
|
||||
billingAddress.setCity("Auckland");
|
||||
|
||||
Country nz = new Country();
|
||||
nz.setCode("NZ");
|
||||
nz.setName("New Zealand");
|
||||
billingAddress.setCountry(nz);
|
||||
|
||||
Customer c0 = new Customer();
|
||||
c0.setBillingAddress(billingAddress);
|
||||
|
||||
EntityBean e0 = (EntityBean)c0;
|
||||
assertEquals(line1.pathGet(e0), "line1");
|
||||
assertEquals(city.pathGet(e0), "Auckland");
|
||||
assertEquals(billingId.pathGet(e0), Short.valueOf("12"));
|
||||
|
||||
|
||||
assertEquals(beanType.getExpressionPath("billingAddress.country.code").pathGet(e0), "NZ");
|
||||
assertEquals(beanType.getExpressionPath("billingAddress.country.name").pathGet(e0), "New Zealand");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user