mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
WIP on JSON refactor
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package com.avaje.ebean.json;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
|
||||
public class EJson {
|
||||
|
||||
public static String write(Object object) {
|
||||
return EJsonWriter.write(object);
|
||||
}
|
||||
|
||||
public static void write(Object object, Writer writer) {
|
||||
EJsonWriter.write(object, writer);
|
||||
}
|
||||
|
||||
public static void write(Object object, JsonGenerator jsonGenerator) {
|
||||
EJsonWriter.write(object, jsonGenerator);
|
||||
}
|
||||
|
||||
public static Map<String,Object> parseObject(String json) {
|
||||
return EJsonReader.parseObject(json);
|
||||
}
|
||||
|
||||
public static List<Object> parseList(String json) {
|
||||
return EJsonReader.parseList(json);
|
||||
}
|
||||
|
||||
public static Object parse(String json) {
|
||||
return EJsonReader.parse(json);
|
||||
}
|
||||
|
||||
public static Object parse(Reader reader) {
|
||||
return EJsonReader.parse(reader);
|
||||
}
|
||||
|
||||
public static Object parse(JsonParser parser) {
|
||||
return EJsonReader.parse(parser);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package com.avaje.ebean.json;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
public class EJsonReader {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> parseObject(String json) {
|
||||
return (Map<String, Object>) parse(json);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Object> parseList(String json) {
|
||||
return (List<Object>) parse(json);
|
||||
}
|
||||
|
||||
public static Object parse(String json) {
|
||||
return parse(new StringReader(json));
|
||||
}
|
||||
|
||||
public static Object parse(Reader reader) {
|
||||
return parse(Json.createParser(reader));
|
||||
}
|
||||
|
||||
public static Object parse(JsonParser parser) {
|
||||
return new EJsonReader(parser).parseJson();
|
||||
}
|
||||
|
||||
private final JsonParser parser;
|
||||
|
||||
private Stack stack;
|
||||
|
||||
private Context currentContext;
|
||||
|
||||
|
||||
EJsonReader(JsonParser parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
private void startArray() {
|
||||
stack.push(currentContext);
|
||||
currentContext = new ArrayContext();
|
||||
}
|
||||
|
||||
private void startObject() {
|
||||
stack.push(currentContext);
|
||||
currentContext = new ObjectContext();
|
||||
}
|
||||
|
||||
private void endArray() {
|
||||
end();
|
||||
}
|
||||
|
||||
private void endObject() {
|
||||
end();
|
||||
}
|
||||
|
||||
private void end() {
|
||||
if (!stack.isEmpty()) {
|
||||
currentContext = stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private void setValue(Object value) {
|
||||
currentContext.setValue(value);
|
||||
}
|
||||
|
||||
private void setValueNull() {
|
||||
currentContext.setValueNull();
|
||||
}
|
||||
|
||||
private Object parseJson() {
|
||||
|
||||
if (!parser.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Event event = parser.next();
|
||||
if (Event.VALUE_NULL == event) {
|
||||
// it is just a null value
|
||||
return null;
|
||||
}
|
||||
Object simpleValue = getSimpleValue(event);
|
||||
if (simpleValue != null) {
|
||||
// it is a simple string, number or boolean
|
||||
return simpleValue;
|
||||
}
|
||||
|
||||
stack = new Stack();
|
||||
// it is a object or array, process the first event
|
||||
processEvent(event);
|
||||
|
||||
// process the rest of the object or array
|
||||
while (parser.hasNext()) {
|
||||
processEvent(parser.next());
|
||||
}
|
||||
|
||||
return currentContext.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the event is a value rather than object or array.
|
||||
* <p>
|
||||
* If just a value then return that value else return null.
|
||||
*/
|
||||
private Object getSimpleValue(Event event) {
|
||||
|
||||
switch (event) {
|
||||
case VALUE_STRING:
|
||||
return parser.getString();
|
||||
|
||||
case VALUE_NUMBER:
|
||||
if (parser.isIntegralNumber()) {
|
||||
return parser.getLong();
|
||||
} else {
|
||||
return parser.getBigDecimal();
|
||||
}
|
||||
|
||||
case VALUE_TRUE:
|
||||
return Boolean.TRUE;
|
||||
|
||||
case VALUE_FALSE:
|
||||
return Boolean.FALSE;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the event for objects and arrays.
|
||||
*/
|
||||
private void processEvent(Event event) {
|
||||
switch (event) {
|
||||
|
||||
case START_ARRAY:
|
||||
startArray();
|
||||
break;
|
||||
|
||||
case START_OBJECT:
|
||||
startObject();
|
||||
break;
|
||||
|
||||
case KEY_NAME:
|
||||
currentContext.setKey(parser.getString());
|
||||
break;
|
||||
|
||||
case VALUE_STRING:
|
||||
setValue(parser.getString());
|
||||
break;
|
||||
|
||||
case VALUE_NUMBER:
|
||||
if (parser.isIntegralNumber()) {
|
||||
setValue(parser.getLong());
|
||||
} else {
|
||||
setValue(parser.getBigDecimal());
|
||||
}
|
||||
break;
|
||||
|
||||
case VALUE_TRUE:
|
||||
setValue(Boolean.TRUE);
|
||||
break;
|
||||
|
||||
case VALUE_FALSE:
|
||||
setValue(Boolean.FALSE);
|
||||
break;
|
||||
|
||||
case VALUE_NULL:
|
||||
setValueNull();
|
||||
break;
|
||||
|
||||
case END_OBJECT:
|
||||
endObject();
|
||||
break;
|
||||
|
||||
case END_ARRAY:
|
||||
endArray();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Stack {
|
||||
|
||||
private Context head;
|
||||
|
||||
private void push(Context context) {
|
||||
if (context != null) {
|
||||
context.next = head;
|
||||
head = context;
|
||||
}
|
||||
}
|
||||
|
||||
private Context pop() {
|
||||
if (head == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
Context temp = head;
|
||||
head = head.next;
|
||||
return temp;
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
return head == null;
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class Context {
|
||||
Context next;
|
||||
abstract Object getValue();
|
||||
abstract void setKey(String key);
|
||||
abstract void setValue(Object value);
|
||||
abstract void setValueNull();
|
||||
}
|
||||
|
||||
private static class ObjectContext extends Context {
|
||||
|
||||
private final Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
private String key;
|
||||
|
||||
Object getValue() {
|
||||
return map;
|
||||
}
|
||||
|
||||
void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
void setValue(Object value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
void setValueNull() {
|
||||
map.put(key, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrayContext extends Context {
|
||||
|
||||
private final List<Object> values = new ArrayList<Object>();
|
||||
|
||||
Object getValue() {
|
||||
return values;
|
||||
}
|
||||
|
||||
void setValue(Object value) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
void setValueNull() {
|
||||
// ignore
|
||||
}
|
||||
void setKey(String key) {
|
||||
// not expected
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package com.avaje.ebean.json;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.stream.JsonGenerator;
|
||||
|
||||
class EJsonWriter {
|
||||
|
||||
public static String write(Object object) {
|
||||
StringWriter writer = new StringWriter(200);
|
||||
write(object, writer);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public static void write(Object object, Writer writer) {
|
||||
JsonGenerator generator = Json.createGenerator(writer);
|
||||
write(object, generator);
|
||||
generator.close();
|
||||
}
|
||||
|
||||
public static void write(Object object, JsonGenerator jsonGenerator) {
|
||||
new EJsonWriter(jsonGenerator).writeJson(object);
|
||||
}
|
||||
|
||||
private final JsonGenerator jsonGenerator;
|
||||
|
||||
private EJsonWriter(JsonGenerator jsonGenerator) {
|
||||
this.jsonGenerator = jsonGenerator;
|
||||
}
|
||||
|
||||
private void writeJson(Object object) {
|
||||
writeJson(null, object);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void writeJson(String name, Object object) {
|
||||
if (object == null) {
|
||||
writeNull(name);
|
||||
|
||||
} else if (object instanceof Map) {
|
||||
writeMap(name, (Map<Object, Object>) object);
|
||||
|
||||
} else if (object instanceof Collection) {
|
||||
writeCollection(name, (Collection<Object>) object);
|
||||
|
||||
} else if (object instanceof Boolean) {
|
||||
writeBoolean(name, (Boolean) object);
|
||||
|
||||
} else if (object instanceof Number) {
|
||||
writeNumber(name, (Number) object);
|
||||
|
||||
} else if (object instanceof Date) {
|
||||
writeDate(name, (Date) object);
|
||||
|
||||
} else if (object instanceof String) {
|
||||
writeString(name, (String) object);
|
||||
|
||||
} else {
|
||||
writeString(name, object.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeBoolean(String name, Boolean object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write(object);
|
||||
} else {
|
||||
jsonGenerator.write(name, object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeDate(String name, Date object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write(object.getTime());
|
||||
} else {
|
||||
jsonGenerator.write(name, object.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeNumber(String name, Number object) {
|
||||
|
||||
if (object instanceof Long) {
|
||||
writeLong(name, object);
|
||||
|
||||
} else if (object instanceof Integer) {
|
||||
writeInteger(name, object);
|
||||
|
||||
} else if (object instanceof Double) {
|
||||
writeDouble(name, object);
|
||||
|
||||
} else if (object instanceof BigDecimal) {
|
||||
writeBigDecimal(name, object);
|
||||
|
||||
} else if (object instanceof BigInteger) {
|
||||
writeBigInteger(name, object);
|
||||
|
||||
} else {
|
||||
writeGeneralNumber(name, object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeGeneralNumber(String name, Number object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write(new BigDecimal(object.toString()));
|
||||
} else {
|
||||
jsonGenerator.write(name, new BigDecimal(object.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeBigDecimal(String name, Number object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write((BigDecimal) object);
|
||||
} else {
|
||||
jsonGenerator.write(name, (BigDecimal) object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeBigInteger(String name, Number object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write((BigInteger) object);
|
||||
} else {
|
||||
jsonGenerator.write(name, (BigInteger) object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeDouble(String name, Number object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write((Double) object);
|
||||
} else {
|
||||
jsonGenerator.write(name, (Double) object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLong(String name, Number object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write((Long) object);
|
||||
} else {
|
||||
jsonGenerator.write(name, (Long) object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeInteger(String name, Number object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write((Integer) object);
|
||||
} else {
|
||||
jsonGenerator.write(name, (Integer) object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeNull(String name) {
|
||||
if (name == null) {
|
||||
jsonGenerator.writeNull();
|
||||
} else {
|
||||
jsonGenerator.writeNull(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeString(String name, String object) {
|
||||
if (name == null) {
|
||||
jsonGenerator.write(object);
|
||||
} else {
|
||||
jsonGenerator.write(name, object);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeCollection(String name, Collection<Object> collection) {
|
||||
if (name == null) {
|
||||
jsonGenerator.writeStartObject();
|
||||
} else {
|
||||
jsonGenerator.writeStartArray(name);
|
||||
}
|
||||
for (Object object : collection) {
|
||||
writeJson(null, object);
|
||||
}
|
||||
jsonGenerator.writeEnd();
|
||||
}
|
||||
|
||||
private void writeMap(String name, Map<Object, Object> map) {
|
||||
|
||||
if (name == null) {
|
||||
jsonGenerator.writeStartObject();
|
||||
} else {
|
||||
jsonGenerator.writeStartObject(name);
|
||||
}
|
||||
Set<Entry<Object, Object>> entrySet = map.entrySet();
|
||||
for (Entry<Object, Object> entry : entrySet) {
|
||||
writeJson(entry.getKey().toString(), entry.getValue());
|
||||
}
|
||||
jsonGenerator.writeEnd();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -195,12 +196,12 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
/**
|
||||
* Inheritance information. Server side only.
|
||||
*/
|
||||
private final InheritInfo inheritInfo;
|
||||
protected final InheritInfo inheritInfo;
|
||||
|
||||
/**
|
||||
* Derived list of properties that make up the unique id.
|
||||
*/
|
||||
private final BeanProperty idProperty;
|
||||
protected final BeanProperty idProperty;
|
||||
private final int idPropertyIndex;
|
||||
|
||||
/**
|
||||
@@ -327,7 +328,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
private final boolean cacheSharableBeans;
|
||||
|
||||
private final BeanDescriptorCacheHelp<T> cacheHelp;
|
||||
|
||||
private final BeanDescriptorJsonHelp<T> jsonHelp;
|
||||
|
||||
private final String defaultSelectClause;
|
||||
private final Set<String> defaultSelectClauseSet;
|
||||
|
||||
@@ -422,7 +424,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
|
||||
this.cacheSharableBeans = noRelationships && deploy.getCacheOptions().isReadOnly();
|
||||
this.cacheHelp = new BeanDescriptorCacheHelp<T>(this, owner.getCacheManager(), deploy.getCacheOptions(), cacheSharableBeans, propertiesOneImported);
|
||||
|
||||
this.jsonHelp = new BeanDescriptorJsonHelp<T>(this);
|
||||
|
||||
// Check if there are no cascade save associated beans ( subject to change
|
||||
// in initialiseOther()). Note that if we are in an inheritance hierarchy
|
||||
@@ -2198,88 +2200,12 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
beanVisitor.visit((T) bean, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T jsonReadBean(ReadJsonContext ctx, String path) {
|
||||
ReadBeanState beanState = jsonRead(ctx, path);
|
||||
if (beanState == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (T) beanState.getBean();
|
||||
}
|
||||
}
|
||||
|
||||
public ReadBeanState jsonRead(ReadJsonContext ctx, String path) {
|
||||
if (!ctx.readObjectBegin()) {
|
||||
// the object is null
|
||||
return null;
|
||||
}
|
||||
|
||||
if (inheritInfo == null) {
|
||||
return jsonReadObject(ctx, path);
|
||||
|
||||
} else {
|
||||
|
||||
// check for the discriminator value to determine the correct sub type
|
||||
String discColumn = inheritInfo.getRoot().getDiscriminatorColumn();
|
||||
|
||||
if (!ctx.readKeyNext()) {
|
||||
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
|
||||
throw new TextException(msg);
|
||||
}
|
||||
|
||||
String propName = ctx.getTokenKey();
|
||||
String discValue;
|
||||
if (propName.equalsIgnoreCase(discColumn)) {
|
||||
discValue = ctx.readScalarValue();
|
||||
if (!ctx.readValueNext()) {
|
||||
// Expected to read a comma to setup for reading the real properties of the bean
|
||||
String msg = "Error reading inheritance discriminator [" + discColumn + "]. Expected more json name values?";
|
||||
throw new TextException(msg);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Assume that the we are just reading using this bean type
|
||||
// Push the token key back so that it is re-read as it is one
|
||||
// of the real properties of the bean itself
|
||||
ctx.pushTokenKey();
|
||||
discValue = inheritInfo.getDiscriminatorStringValue();
|
||||
}
|
||||
|
||||
// determine the sub type for this particular json object
|
||||
InheritInfo localInheritInfo = inheritInfo.readType(discValue);
|
||||
BeanDescriptor<?> localDescriptor = localInheritInfo.getBeanDescriptor();
|
||||
return localDescriptor.jsonReadObject(ctx, path);
|
||||
}
|
||||
|
||||
public T jsonRead(JsonParser parser, String path) {
|
||||
return jsonHelp.jsonRead(parser, path);
|
||||
}
|
||||
|
||||
private ReadBeanState jsonReadObject(ReadJsonContext ctx, String path) {
|
||||
|
||||
EntityBean bean = createEntityBean();
|
||||
ctx.pushBean(bean, path, this);
|
||||
|
||||
do {
|
||||
if (!ctx.readKeyNext()) {
|
||||
break;
|
||||
} else {
|
||||
// we read a property key ...
|
||||
String propName = ctx.getTokenKey();
|
||||
BeanProperty p = getBeanProperty(propName);
|
||||
if (p != null) {
|
||||
p.jsonRead(ctx, bean);
|
||||
ctx.setProperty(propName);
|
||||
} else {
|
||||
// unknown property key ...
|
||||
ctx.readUnmappedJson(propName);
|
||||
}
|
||||
|
||||
if (!ctx.readValueNext()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
|
||||
return ctx.popBeanState();
|
||||
protected T jsonReadObject(JsonParser parser, String path) {
|
||||
return jsonHelp.jsonReadObject(parser, path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.json.EJson;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriteBeanVisitor;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext.WriteBeanState;
|
||||
|
||||
public class BeanDescriptorJsonHelp<T> {
|
||||
|
||||
private final BeanDescriptor<T> desc;
|
||||
private final InheritInfo inheritInfo;
|
||||
|
||||
public BeanDescriptorJsonHelp(BeanDescriptor<T> desc) {
|
||||
this.desc = desc;
|
||||
this.inheritInfo = desc.inheritInfo;
|
||||
}
|
||||
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, EntityBean bean) {
|
||||
|
||||
if (bean != null) {
|
||||
|
||||
ctx.writeStartObject();
|
||||
//WriteBeanState prevState = ctx.pushBeanState(bean);
|
||||
|
||||
if (inheritInfo != null) {
|
||||
InheritInfo localInheritInfo = inheritInfo.readType(bean.getClass());
|
||||
String discValue = localInheritInfo.getDiscriminatorStringValue();
|
||||
String discColumn = localInheritInfo.getDiscriminatorColumn();
|
||||
ctx.write(discColumn, discValue);
|
||||
//ctx.appendDiscriminator(discColumn, discValue);
|
||||
|
||||
BeanDescriptor<?> localDescriptor = localInheritInfo.getBeanDescriptor();
|
||||
localDescriptor.jsonWriteProperties(ctx, bean);
|
||||
|
||||
} else {
|
||||
jsonWriteProperties(ctx, bean);
|
||||
}
|
||||
|
||||
//ctx.pushPreviousState(prevState);
|
||||
//ctx.appendObjectEnd();
|
||||
ctx.writeEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void jsonWriteProperties(JsonGenerator ctx, EntityBean bean) {
|
||||
|
||||
//JsonWriteBeanVisitor<T> beanVisitor = (JsonWriteBeanVisitor<T>) ctx.getBeanVisitor();
|
||||
|
||||
Set<String> props = ctx.getIncludeProperties();
|
||||
|
||||
boolean explicitAllProps;
|
||||
if (props == null) {
|
||||
explicitAllProps = false;
|
||||
} else {
|
||||
explicitAllProps = props.contains("*");
|
||||
if (explicitAllProps || props.isEmpty()) {
|
||||
props = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (desc.idProperty != null) {
|
||||
Object idValue = desc.idProperty.getValue(bean);
|
||||
if (idValue != null) {
|
||||
if (props == null || props.contains(idProperty.getName())) {
|
||||
idProperty.jsonWrite(ctx, bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!explicitAllProps && props == null) {
|
||||
// just render the loaded properties
|
||||
props = ((EntityBean)bean)._ebean_getIntercept().getLoadedPropertyNames();
|
||||
}
|
||||
if (props != null) {
|
||||
// render only the appropriate properties (when not all properties)
|
||||
for (String prop : props) {
|
||||
BeanProperty p = getBeanProperty(prop);
|
||||
if (p != null && !p.isId()) {
|
||||
p.jsonWrite(ctx, bean);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (explicitAllProps || !isReference(bean._ebean_getIntercept())) {
|
||||
// render all the properties and invoke lazy loading if required
|
||||
for (int j = 0; j < propertiesNonTransient.length; j++) {
|
||||
propertiesNonTransient[j].jsonWrite(ctx, bean);
|
||||
}
|
||||
for (int j = 0; j < propertiesTransient.length; j++) {
|
||||
propertiesTransient[j].jsonWrite(ctx, bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (beanVisitor != null) {
|
||||
beanVisitor.visit((T) bean, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T jsonRead(JsonParser parser, String path) {
|
||||
|
||||
if (!parser.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
Event event = parser.next();
|
||||
if (Event.VALUE_NULL == event || Event.END_ARRAY == event) {
|
||||
return null;
|
||||
}
|
||||
if (Event.START_OBJECT != event) {
|
||||
throw new RuntimeException("Unexpected token "+event+" - expecting start_object at: "+parser.getLocation());
|
||||
}
|
||||
|
||||
if (desc.inheritInfo == null) {
|
||||
return jsonReadObject(parser, path);
|
||||
}
|
||||
|
||||
|
||||
// check for the discriminator value to determine the correct sub type
|
||||
String discColumn = inheritInfo.getRoot().getDiscriminatorColumn();
|
||||
|
||||
if (!parser.hasNext() || ((event = parser.next()) != Event.KEY_NAME)) {
|
||||
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
|
||||
throw new TextException(msg);
|
||||
}
|
||||
|
||||
String propName = parser.getString();
|
||||
if (!propName.equalsIgnoreCase(discColumn)) {
|
||||
String msg = "Error reading inheritance discriminator, expected property ["+discColumn+"] but got [" + propName + "] ?";
|
||||
throw new TextException(msg);
|
||||
}
|
||||
|
||||
if (!parser.hasNext() || ((event = parser.next()) != Event.VALUE_STRING)) {
|
||||
String msg = "Error reading inheritance discriminator - expected value_string token but got [" + event + "] at ["+parser.getLocation()+"]?";
|
||||
throw new TextException(msg);
|
||||
}
|
||||
|
||||
String discValue = parser.getString();
|
||||
|
||||
// determine the sub type for this particular json object
|
||||
InheritInfo localInheritInfo = inheritInfo.readType(discValue);
|
||||
BeanDescriptor<?> localDescriptor = localInheritInfo.getBeanDescriptor();
|
||||
return (T) localDescriptor.jsonReadObject(parser, path);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T jsonReadObject(JsonParser parser, String path) {
|
||||
|
||||
EntityBean bean = desc.createEntityBean();
|
||||
//ctx.pushBean(bean, path, this);
|
||||
|
||||
do {
|
||||
|
||||
if (parser.hasNext()) {
|
||||
Event event = parser.next();
|
||||
if (Event.KEY_NAME == event) {
|
||||
String key = parser.getString();
|
||||
BeanProperty p = desc.getBeanProperty(key);
|
||||
if (p != null) {
|
||||
p.jsonRead(parser, bean);
|
||||
|
||||
} else {
|
||||
Object rawValue = EJson.parse(parser);
|
||||
// unknown property key ...
|
||||
//ctx.readUnmappedJson(propName);
|
||||
}
|
||||
|
||||
} else if (Event.END_OBJECT == event) {
|
||||
break;
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected token "+event+" - expecting key or end_object at: "+parser.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
} while (true);
|
||||
|
||||
return (T)bean;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,9 @@ import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
@@ -18,7 +21,6 @@ import com.avaje.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.text.StringFormatter;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
@@ -30,7 +32,6 @@ import com.avaje.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import com.avaje.ebeaninternal.server.query.SqlJoinType;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
|
||||
import com.avaje.ebeaninternal.server.text.json.ReadJsonContext;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
@@ -1173,6 +1174,22 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void jsonWrite(JsonGenerator ctx, EntityBean bean) {
|
||||
if(!jsonSerialize){
|
||||
return;
|
||||
}
|
||||
Object value = getValueIntercept(bean);
|
||||
if (value == null) {
|
||||
ctx.writeNull(name);
|
||||
} else {
|
||||
scalarType.jsonWrite(ctx, name, value);
|
||||
//ctx.appendNameValue(name, scalarType, value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
|
||||
if(!jsonSerialize){
|
||||
@@ -1186,22 +1203,39 @@ public class BeanProperty implements ElPropertyValue {
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonRead(ReadJsonContext ctx, EntityBean bean) {
|
||||
if(!jsonDeserialize){
|
||||
return;
|
||||
}
|
||||
String jsonValue;
|
||||
try {
|
||||
jsonValue = ctx.readScalarValue();
|
||||
} catch (TextException e){
|
||||
throw new TextException("Error reading property "+getFullBeanName(), e);
|
||||
}
|
||||
Object objValue;
|
||||
if (jsonValue == null) {
|
||||
objValue = null;
|
||||
} else {
|
||||
objValue = scalarType.jsonFromString(jsonValue, ctx.getValueAdapter());
|
||||
}
|
||||
setValue(bean, objValue);
|
||||
// public void jsonRead(ReadJsonContext ctx, EntityBean bean) {
|
||||
// if(!jsonDeserialize){
|
||||
// return;
|
||||
// }
|
||||
// String jsonValue;
|
||||
// try {
|
||||
// jsonValue = ctx.readScalarValue();
|
||||
// } catch (TextException e){
|
||||
// throw new TextException("Error reading property "+getFullBeanName(), e);
|
||||
// }
|
||||
// Object objValue;
|
||||
// if (jsonValue == null) {
|
||||
// objValue = null;
|
||||
// } else {
|
||||
// objValue = scalarType.jsonFromString(jsonValue, ctx.getValueAdapter());
|
||||
// }
|
||||
// setValue(bean, objValue);
|
||||
// }
|
||||
|
||||
public void jsonRead(JsonParser ctx, EntityBean bean) {
|
||||
if (!jsonDeserialize) {
|
||||
return;
|
||||
}
|
||||
if (!ctx.hasNext()) {
|
||||
throw new RuntimeException(ctx.getLocation().toString());
|
||||
}
|
||||
Event event = ctx.next();
|
||||
if (Event.VALUE_NULL == event) {
|
||||
setValue(bean, null);
|
||||
} else {
|
||||
Object objValue = scalarType.jsonRead(ctx, event);
|
||||
setValue(bean, objValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -40,6 +41,8 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BeanPropertyAssocMany.class);
|
||||
|
||||
private final BeanPropertyAssocManyJsonHelp jsonHelp;
|
||||
|
||||
/**
|
||||
* Join for manyToMany intersection table.
|
||||
*/
|
||||
@@ -91,7 +94,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
/**
|
||||
* Property on the 'child' bean that links back to the 'master'.
|
||||
*/
|
||||
private BeanPropertyAssocOne<?> childMasterProperty;
|
||||
protected BeanPropertyAssocOne<?> childMasterProperty;
|
||||
|
||||
private boolean embeddedExportedProperties;
|
||||
|
||||
@@ -116,6 +119,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
this.intersectionJoin = deploy.createIntersectionTableJoin();
|
||||
this.inverseJoin = deploy.createInverseTableJoin();
|
||||
this.modifyListenMode = deploy.getModifyListenMode();
|
||||
this.jsonHelp = new BeanPropertyAssocManyJsonHelp(this);
|
||||
}
|
||||
|
||||
public void initialise() {
|
||||
@@ -900,37 +904,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonRead(ReadJsonContext ctx, EntityBean bean){
|
||||
if(!this.jsonDeserialize){
|
||||
return;
|
||||
}
|
||||
if (!ctx.readArrayBegin()) {
|
||||
// the array is null
|
||||
return;
|
||||
}
|
||||
|
||||
Object collection = help.createEmpty(false);
|
||||
BeanCollectionAdd add = getBeanCollectionAdd(collection, null);
|
||||
do {
|
||||
ReadBeanState detailBeanState = targetDescriptor.jsonRead(ctx, name);
|
||||
if (detailBeanState == null){
|
||||
// probably empty array
|
||||
break;
|
||||
}
|
||||
EntityBean detailBean = (EntityBean)detailBeanState.getBean();
|
||||
add.addBean(detailBean);
|
||||
|
||||
if (bean != null && childMasterProperty != null){
|
||||
// bind detail bean back to master via mappedBy property
|
||||
childMasterProperty.setValue(detailBean, bean);
|
||||
detailBeanState.setLoaded(childMasterProperty.getName());
|
||||
}
|
||||
|
||||
if (!ctx.readArrayNext()){
|
||||
break;
|
||||
}
|
||||
} while(true);
|
||||
|
||||
setValue(bean, collection);
|
||||
public void jsonRead(JsonParser parser, EntityBean parentBean) {
|
||||
jsonHelp.jsonRead(parser, parentBean);
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.bean.BeanCollectionAdd;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
|
||||
public class BeanPropertyAssocManyJsonHelp {
|
||||
|
||||
private final BeanPropertyAssocMany<?> many;
|
||||
|
||||
public BeanPropertyAssocManyJsonHelp(BeanPropertyAssocMany<?> many) {
|
||||
this.many = many;
|
||||
}
|
||||
|
||||
public void jsonRead(JsonParser parser, EntityBean parentBean) {
|
||||
|
||||
if (!this.many.jsonDeserialize || !parser.hasNext()) {
|
||||
return;
|
||||
}
|
||||
Event event = parser.next();
|
||||
if (Event.VALUE_NULL == event) {
|
||||
return;
|
||||
}
|
||||
if (Event.START_ARRAY != event) {
|
||||
throw new TextException("Unexpected token "+event+" - expecting start_array at: "+parser.getLocation());
|
||||
}
|
||||
|
||||
Object collection = many.createEmpty(false);
|
||||
BeanCollectionAdd add = many.getBeanCollectionAdd(collection, null);
|
||||
do {
|
||||
EntityBean detailBean = (EntityBean)many.targetDescriptor.jsonRead(parser, many.name);
|
||||
if (detailBean == null) {
|
||||
// read the entire array
|
||||
break;
|
||||
}
|
||||
add.addBean(detailBean);
|
||||
|
||||
if (parentBean != null && many.childMasterProperty != null) {
|
||||
// bind detail bean back to master via mappedBy property
|
||||
many.childMasterProperty.setValue(detailBean, parentBean);
|
||||
}
|
||||
} while (true);
|
||||
|
||||
many.setValue(parentBean, collection);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
@@ -854,13 +855,13 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void jsonRead(ReadJsonContext ctx, EntityBean bean){
|
||||
if (targetDescriptor != null) {
|
||||
T assocBean = targetDescriptor.jsonReadBean(ctx, name);
|
||||
setValue(bean, assocBean);
|
||||
}
|
||||
public void jsonRead(JsonParser parser, EntityBean bean) {
|
||||
if (targetDescriptor != null) {
|
||||
T assocBean = targetDescriptor.jsonRead(parser, name);
|
||||
setValue(bean, assocBean);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReference(Object detailBean) {
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
public class EJsonReader {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> parseObject(String json) {
|
||||
return (Map<String, Object>) parse(json);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Object> parseList(String json) {
|
||||
return (List<Object>) parse(json);
|
||||
}
|
||||
|
||||
public static Object parse(String json) {
|
||||
return parse(new StringReader(json));
|
||||
}
|
||||
|
||||
public static Object parse(Reader reader) {
|
||||
return parse(Json.createParser(reader));
|
||||
}
|
||||
|
||||
public static Object parse(JsonParser parser) {
|
||||
return new EJsonReader(parser).parseJson();
|
||||
}
|
||||
|
||||
private final JsonParser parser;
|
||||
|
||||
private final Stack stack = new Stack();
|
||||
|
||||
private Context currentContext;
|
||||
|
||||
|
||||
EJsonReader(JsonParser parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
private void startArray() {
|
||||
stack.push(currentContext);
|
||||
currentContext = new ArrayContext();
|
||||
}
|
||||
|
||||
private void startObject() {
|
||||
stack.push(currentContext);
|
||||
currentContext = new ObjectContext();
|
||||
}
|
||||
|
||||
private void endArray() {
|
||||
end();
|
||||
}
|
||||
|
||||
private void endObject() {
|
||||
end();
|
||||
}
|
||||
|
||||
private void end() {
|
||||
|
||||
if (!stack.isEmpty()) {
|
||||
currentContext = stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private void setValue(Object value) {
|
||||
currentContext.setValue(value);
|
||||
}
|
||||
|
||||
private void setValueNull() {
|
||||
currentContext.setValueNull();
|
||||
}
|
||||
|
||||
private Object parseJson() {
|
||||
|
||||
while (parser.hasNext()) {
|
||||
Event event = parser.next();
|
||||
switch (event) {
|
||||
|
||||
case START_ARRAY:
|
||||
startArray();
|
||||
break;
|
||||
|
||||
case START_OBJECT:
|
||||
startObject();
|
||||
break;
|
||||
|
||||
case KEY_NAME:
|
||||
currentContext.setKey(parser.getString());
|
||||
break;
|
||||
|
||||
case VALUE_STRING:
|
||||
setValue(parser.getString());
|
||||
break;
|
||||
|
||||
case VALUE_NUMBER:
|
||||
if (parser.isIntegralNumber()) {
|
||||
setValue(parser.getLong());
|
||||
} else {
|
||||
setValue(parser.getBigDecimal());
|
||||
}
|
||||
break;
|
||||
|
||||
case VALUE_TRUE:
|
||||
setValue(Boolean.TRUE);
|
||||
break;
|
||||
|
||||
case VALUE_FALSE:
|
||||
setValue(Boolean.FALSE);
|
||||
break;
|
||||
|
||||
case VALUE_NULL:
|
||||
setValueNull();
|
||||
break;
|
||||
|
||||
case END_OBJECT:
|
||||
endObject();
|
||||
break;
|
||||
|
||||
case END_ARRAY:
|
||||
endArray();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return currentContext.getValue();
|
||||
}
|
||||
|
||||
private static final class Stack {
|
||||
|
||||
private Context head;
|
||||
|
||||
private void push(Context context) {
|
||||
if (context != null) {
|
||||
context.next = head;
|
||||
head = context;
|
||||
}
|
||||
}
|
||||
|
||||
private Context pop() {
|
||||
if (head == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
Context temp = head;
|
||||
head = head.next;
|
||||
return temp;
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
return head == null;
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class Context {
|
||||
Context next;
|
||||
abstract Object getValue();
|
||||
abstract void setKey(String key);
|
||||
abstract void setValue(Object value);
|
||||
abstract void setValueNull();
|
||||
}
|
||||
|
||||
private static class ObjectContext extends Context {
|
||||
|
||||
private String key;
|
||||
|
||||
Map<String, Object> map = new LinkedHashMap<String,Object>();
|
||||
|
||||
Object getValue() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
void setValue(Object value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
void setValueNull() {
|
||||
map.put(key, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrayContext extends Context {
|
||||
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
|
||||
Object getValue() {
|
||||
return values;
|
||||
}
|
||||
|
||||
void setValue(Object value) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
void setValueNull() {
|
||||
}
|
||||
void setKey(String key) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
|
||||
public class ReadJson {
|
||||
|
||||
JsonParser parser;
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.text.json;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
@@ -11,6 +12,10 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
@@ -48,12 +53,13 @@ public class DJsonContext implements JsonContext {
|
||||
return server.isSupportedType(genericType);
|
||||
}
|
||||
|
||||
private ReadJsonSource createReader(Reader jsonReader) {
|
||||
return new ReadJsonSourceReader(jsonReader, 256, 512);
|
||||
private JsonParser createReader(Reader jsonReader) {
|
||||
return Json.createParser(jsonReader);
|
||||
//return new ReadJsonSourceReader(jsonReader, 256, 512);
|
||||
}
|
||||
|
||||
public <T> T toBean(Class<T> cls, String json){
|
||||
return toBean(cls, new ReadJsonSourceString(json), null);
|
||||
return toBean(cls, new StringReader(json), null);
|
||||
}
|
||||
|
||||
public <T> T toBean(Class<T> cls, Reader jsonReader) {
|
||||
@@ -61,26 +67,33 @@ public class DJsonContext implements JsonContext {
|
||||
}
|
||||
|
||||
public <T> T toBean(Class<T> cls, String json, JsonReadOptions options){
|
||||
return toBean(cls, new ReadJsonSourceString(json), options);
|
||||
return toBean(cls, new StringReader(json), options);
|
||||
}
|
||||
|
||||
public <T> T toBean(Class<T> cls, Reader jsonReader, JsonReadOptions options) {
|
||||
return toBean(cls, createReader(jsonReader), options);
|
||||
}
|
||||
|
||||
private <T> T toBean(Class<T> cls, ReadJsonSource src, JsonReadOptions options){
|
||||
// private <T> T toBean(Class<T> cls, ReadJsonSource src, JsonReadOptions options){
|
||||
//
|
||||
// BeanDescriptor<T> d = getDecriptor(cls);
|
||||
// ReadJsonContext ctx = new ReadJsonContext(src, dfltValueAdapter, options);
|
||||
// return d.jsonReadBean(ctx, null);
|
||||
// }
|
||||
|
||||
BeanDescriptor<T> d = getDecriptor(cls);
|
||||
ReadJsonContext ctx = new ReadJsonContext(src, dfltValueAdapter, options);
|
||||
return d.jsonReadBean(ctx, null);
|
||||
private <T> T toBean(Class<T> cls, JsonParser parser, JsonReadOptions options) {
|
||||
|
||||
BeanDescriptor<T> d = getDecriptor(cls);
|
||||
// ReadJsonContext ctx = new ReadJsonContext(src, dfltValueAdapter, options);
|
||||
return d.jsonRead(parser, null);
|
||||
}
|
||||
|
||||
|
||||
public <T> List<T> toList(Class<T> cls, String json){
|
||||
return toList(cls, new ReadJsonSourceString(json), null);
|
||||
return toList(cls, new StringReader(json), null);
|
||||
}
|
||||
|
||||
public <T> List<T> toList(Class<T> cls, String json, JsonReadOptions options){
|
||||
return toList(cls, new ReadJsonSourceString(json), options);
|
||||
return toList(cls, new StringReader(json), options);
|
||||
}
|
||||
|
||||
public <T> List<T> toList(Class<T> cls, Reader jsonReader){
|
||||
@@ -91,26 +104,36 @@ public class DJsonContext implements JsonContext {
|
||||
return toList(cls, createReader(jsonReader), options);
|
||||
}
|
||||
|
||||
private <T> List<T> toList(Class<T> cls, ReadJsonSource src, JsonReadOptions options){
|
||||
private <T> List<T> toList(Class<T> cls, JsonParser src, JsonReadOptions options){
|
||||
|
||||
try {
|
||||
BeanDescriptor<T> d = getDecriptor(cls);
|
||||
|
||||
List<T> list = new ArrayList<T>();
|
||||
|
||||
ReadJsonContext ctx = new ReadJsonContext(src, dfltValueAdapter, options);
|
||||
ctx.readArrayBegin();
|
||||
//ReadJsonContext ctx = new ReadJsonContext(src, dfltValueAdapter, options);
|
||||
if (!src.hasNext()) {
|
||||
return list;
|
||||
}
|
||||
Event event = src.next();
|
||||
if (event != Event.START_ARRAY) {
|
||||
throw new TextException("Expecting start_array event but got ["+event+"] at ["+src.getLocation()+"]");
|
||||
}
|
||||
//ctx.readArrayBegin();
|
||||
do {
|
||||
T bean = d.jsonReadBean(ctx, null);
|
||||
if (bean != null){
|
||||
T bean = d.jsonRead(src, null);
|
||||
if (bean == null){
|
||||
break;
|
||||
} else {
|
||||
list.add(bean);
|
||||
}
|
||||
if (!ctx.readArrayNext()){
|
||||
break;
|
||||
}
|
||||
// if (!ctx.readArrayNext()){
|
||||
// break;
|
||||
// }
|
||||
} while(true);
|
||||
|
||||
return list;
|
||||
|
||||
} catch (RuntimeException e){
|
||||
throw new TextException("Error parsing "+src, e);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.StringFormatter;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
@@ -192,5 +196,9 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
public Object readData(DataInput dataInput) throws IOException;
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object v) throws IOException;
|
||||
|
||||
public Object jsonRead(JsonParser ctx, Event event);
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value);
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.sql.Date;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
|
||||
@@ -61,6 +65,24 @@ public abstract class ScalarTypeBaseDate<T> extends ScalarTypeBase<T> {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
if (ctx.isIntegralNumber()) {
|
||||
long millis = ctx.getLong();
|
||||
return parseDateTime(millis);
|
||||
} else {
|
||||
String string = ctx.getString();
|
||||
throw new RuntimeException("convert "+string);
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
long millis = convertToMillis(value);
|
||||
ctx.write(name, millis);
|
||||
}
|
||||
|
||||
public abstract long convertToMillis(Object value);
|
||||
|
||||
@Override
|
||||
public String jsonToString(T value, JsonValueAdapter ctx) {
|
||||
Date date = convertToDate(value);
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
|
||||
@@ -19,6 +23,8 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
super(type, jdbcNative, jdbcType);
|
||||
}
|
||||
|
||||
public abstract long convertToMillis(Object value);
|
||||
|
||||
public abstract Timestamp convertToTimestamp(T t);
|
||||
|
||||
public abstract T convertFromTimestamp(Timestamp ts);
|
||||
@@ -42,6 +48,23 @@ public abstract class ScalarTypeBaseDateTime<T> extends ScalarTypeBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
if (ctx.isIntegralNumber()) {
|
||||
long millis = ctx.getLong();
|
||||
return parseDateTime(millis);
|
||||
} else {
|
||||
String string = ctx.getString();
|
||||
throw new RuntimeException("convert "+string);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
long millis = convertToMillis(value);
|
||||
ctx.write(name, millis);
|
||||
}
|
||||
|
||||
public String formatValue(T t) {
|
||||
Timestamp ts = convertToTimestamp(t);
|
||||
return ts.toString();
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
@@ -115,4 +119,13 @@ public abstract class ScalarTypeBaseVarchar<T> extends ScalarTypeBase<T> {
|
||||
dataOutput.writeUTF(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return parse(ctx.getString());
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, format(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,14 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -74,5 +79,15 @@ public class ScalarTypeBigDecimal extends ScalarTypeBase<BigDecimal> {
|
||||
public boolean isDateTimeCapable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getBigDecimal();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (BigDecimal)value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,9 +3,14 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -286,6 +291,15 @@ public class ScalarTypeBoolean {
|
||||
dataOutput.writeBoolean(val.booleanValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return Event.VALUE_TRUE == event ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (Boolean)value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -39,7 +42,13 @@ public class ScalarTypeByte extends ScalarTypeBase<Byte> {
|
||||
}
|
||||
|
||||
|
||||
public String formatValue(Byte t) {
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
public String formatValue(Byte t) {
|
||||
return t.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
|
||||
/**
|
||||
@@ -41,7 +44,12 @@ public abstract class ScalarTypeBytesBase extends ScalarTypeBase<byte[]> {
|
||||
}
|
||||
|
||||
|
||||
public String formatValue(byte[] t) {
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
public String formatValue(byte[] t) {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
|
||||
@@ -65,6 +69,11 @@ public class ScalarTypeBytesEncrypted implements ScalarType<byte[]> {
|
||||
baseType.loadIgnore(dataReader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
throw new TextException("Not supported");
|
||||
}
|
||||
|
||||
public String format(Object v) {
|
||||
throw new RuntimeException("Not used");
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ public class ScalarTypeCalendar extends ScalarTypeBaseDateTime<Calendar> {
|
||||
return calendar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((Calendar) value).getTimeInMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertToTimestamp(Calendar t) {
|
||||
return new Timestamp(t.getTimeInMillis());
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -70,4 +73,10 @@ public class ScalarTypeChar extends ScalarTypeBaseVarchar<Character> {
|
||||
return EscapeJson.escapeQuote(value.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -70,4 +75,12 @@ public class ScalarTypeCharArray extends ScalarTypeBaseVarchar<char[]>{
|
||||
return EscapeJson.escapeQuote(String.valueOf(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getString().toCharArray();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, String.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
@@ -42,6 +43,10 @@ public class ScalarTypeClass extends ScalarTypeBaseVarchar<Class> {
|
||||
throw new PersistenceException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, formatValue((Class<?>)value));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.util.Currency;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
/**
|
||||
* ScalarType for java.util.Currency which converts to and from a VARCHAR database column.
|
||||
*/
|
||||
@@ -33,5 +37,13 @@ public class ScalarTypeCurrency extends ScalarTypeBaseVarchar<Currency> {
|
||||
public Currency parse(String value) {
|
||||
return Currency.getInstance(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return parse(ctx.getString());
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, formatValue((Currency)value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,13 @@ public class ScalarTypeDate extends ScalarTypeBaseDate<java.sql.Date> {
|
||||
public ScalarTypeDate() {
|
||||
super(Date.class, true, Types.DATE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((Date)value).getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date convertFromDate(Date date) {
|
||||
return date;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,11 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Currency;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -82,4 +87,13 @@ public class ScalarTypeDouble extends ScalarTypeBase<Double> {
|
||||
dataOutput.writeDouble(value.doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getBigDecimal().doubleValue();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (Double)value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
|
||||
@@ -31,7 +35,12 @@ public class ScalarTypeEncryptedWrapper<T> implements ScalarType<T> {
|
||||
public boolean isDirty(Object value) {
|
||||
return wrapped.isDirty(value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return wrapped.jsonRead(ctx, event);
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
return wrapped.readData(dataInput);
|
||||
}
|
||||
@@ -126,4 +135,7 @@ public class ScalarTypeEncryptedWrapper<T> implements ScalarType<T> {
|
||||
return wrapped.jsonFromString(value, ctx);
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
wrapped.jsonWrite(ctx, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
|
||||
@@ -225,6 +229,17 @@ public class ScalarTypeEnumStandard {
|
||||
public boolean isDateTimeCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
|
||||
String val = ctx.getString();
|
||||
return parse(val);
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, formatValue(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonFromString(String value, JsonValueAdapter ctx) {
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -81,4 +85,13 @@ public class ScalarTypeFloat extends ScalarTypeBase<Float> {
|
||||
dataOutput.writeFloat(value.floatValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getBigDecimal().floatValue();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (Float)value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
@@ -71,4 +75,14 @@ public class ScalarTypeInteger extends ScalarTypeBase<Integer> {
|
||||
public Integer jsonFromString(String value, JsonValueAdapter ctx) {
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return Integer.valueOf(ctx.getInt());
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (Integer)value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.sql.Date;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.joda.time.DateMidnight;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -19,6 +20,11 @@ public class ScalarTypeJodaDateMidnight extends ScalarTypeBaseDate<DateMidnight>
|
||||
super(DateMidnight.class, false, Types.DATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((DateMidnight) value).getMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateMidnight convertFromDate(Date ts) {
|
||||
return new DateMidnight(ts.getTime());
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -16,6 +17,11 @@ public class ScalarTypeJodaDateTime extends ScalarTypeBaseDateTime<DateTime> {
|
||||
super(DateTime.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((DateTime) value).getMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTime convertFromTimestamp(Timestamp ts) {
|
||||
return new DateTime(ts.getTime());
|
||||
|
||||
@@ -17,6 +17,11 @@ public class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate<LocalDate> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((LocalDate)value).toDateMidnight().getMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate convertFromDate(Date ts) {
|
||||
return new LocalDate(((java.util.Date)ts).getTime());
|
||||
}
|
||||
|
||||
@@ -16,7 +16,14 @@ public class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDat
|
||||
super(LocalDateTime.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((LocalDateTime)value).toDateTime().getMillis();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public LocalDateTime convertFromTimestamp(Timestamp ts) {
|
||||
return new LocalDateTime(ts.getTime());
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import org.joda.time.DateMidnight;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.LocalTime;
|
||||
|
||||
@@ -20,7 +24,7 @@ public class ScalarTypeJodaLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
public ScalarTypeJodaLocalTime() {
|
||||
super(LocalTime.class, false, Types.TIME);
|
||||
}
|
||||
|
||||
|
||||
public void bind(DataBind b, LocalTime value) throws SQLException {
|
||||
if (value == null){
|
||||
b.setNull(Types.TIME);
|
||||
@@ -61,8 +65,21 @@ public class ScalarTypeJodaLocalTime extends ScalarTypeBase<LocalTime> {
|
||||
public LocalTime parse(String value) {
|
||||
return new LocalTime(value);
|
||||
}
|
||||
|
||||
public LocalTime parseDateTime(long systemTimeMillis) {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
if (ctx.isIntegralNumber()) {
|
||||
long millis = ctx.getLong();
|
||||
return parseDateTime(millis);
|
||||
} else {
|
||||
String string = ctx.getString();
|
||||
throw new RuntimeException("convert "+string);
|
||||
}
|
||||
}
|
||||
|
||||
public LocalTime parseDateTime(long systemTimeMillis) {
|
||||
return new LocalTime(systemTimeMillis);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -73,4 +77,13 @@ public class ScalarTypeLong extends ScalarTypeBase<Long> {
|
||||
dataOutput.writeLong(value.longValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getLong();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (Long)value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.math.BigInteger;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -80,4 +84,13 @@ public class ScalarTypeMathBigInteger extends ScalarTypeBase<BigInteger> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getBigDecimal().toBigInteger();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (BigInteger)value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
|
||||
|
||||
/**
|
||||
@@ -63,6 +66,12 @@ public class ScalarTypePostgresHstore extends ScalarTypeBase<Map> {
|
||||
public Map toBeanType(Object value) {
|
||||
return (Map)value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatValue(Map v) {
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
@@ -74,4 +78,13 @@ public class ScalarTypeShort extends ScalarTypeBase<Short> {
|
||||
dataOutput.writeShort(value.shortValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return (short)ctx.getInt();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (Short)value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
@@ -92,5 +96,12 @@ public class ScalarTypeString extends ScalarTypeBase<String> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return ctx.getString();
|
||||
}
|
||||
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, (String)value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.sql.SQLException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -75,5 +79,15 @@ public class ScalarTypeTime extends ScalarTypeBase<Time> {
|
||||
dataOutput.writeUTF(format(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return parse(ctx.getString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, value.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
@@ -15,6 +16,11 @@ public class ScalarTypeTimestamp extends ScalarTypeBaseDateTime<Timestamp> {
|
||||
super(Timestamp.class, true, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return ((Timestamp)value).getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp convertFromTimestamp(Timestamp ts) {
|
||||
return ts;
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
|
||||
/**
|
||||
@@ -40,4 +43,10 @@ public class ScalarTypeURL extends ScalarTypeBaseVarchar<URL> {
|
||||
throw new TextException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return parse(ctx.getString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
public class ScalarTypeUUIDBinary extends ScalarTypeBase<UUID> {
|
||||
|
||||
protected ScalarTypeUUIDBinary() {
|
||||
@@ -138,4 +142,14 @@ public class ScalarTypeUUIDBinary extends ScalarTypeBase<UUID> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return UUID.fromString(ctx.getString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object value) {
|
||||
ctx.write(name, value.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
|
||||
/**
|
||||
@@ -44,4 +47,9 @@ public class ScalarTypeUUIDVarchar extends ScalarTypeBaseVarchar<UUID> {
|
||||
return UUID.fromString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
return UUID.fromString(ctx.getString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,12 @@ public class ScalarTypeUtilDate {
|
||||
public TimestampType() {
|
||||
super(java.util.Date.class, false, Types.TIMESTAMP);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
return BasicTypeConverter.toTimestamp(value).getTime();
|
||||
}
|
||||
|
||||
public java.util.Date read(DataReader dataReader) throws SQLException {
|
||||
Timestamp timestamp = dataReader.getTimestamp();
|
||||
if (timestamp == null) {
|
||||
@@ -69,7 +74,15 @@ public class ScalarTypeUtilDate {
|
||||
super(Date.class, false, Types.DATE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long convertToMillis(Object value) {
|
||||
java.sql.Date date = BasicTypeConverter.toDate(value);
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Date convertFromDate(java.sql.Date ts) {
|
||||
return new java.util.Date(ts.getTime());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.json.stream.JsonGenerator;
|
||||
import javax.json.stream.JsonParser;
|
||||
import javax.json.stream.JsonParser.Event;
|
||||
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.text.json.JsonValueAdapter;
|
||||
import com.avaje.ebeaninternal.server.text.json.WriteJsonBuffer;
|
||||
@@ -180,5 +184,20 @@ public class ScalarTypeWrapper<B, S> implements ScalarType<B> {
|
||||
S s = scalarType.jsonFromString(value, ctx);
|
||||
return converter.wrapValue(s);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object jsonRead(JsonParser ctx, Event event) {
|
||||
Object object = scalarType.jsonRead(ctx, event);
|
||||
return converter.wrapValue((S)object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(JsonGenerator ctx, String name, Object beanValue) {
|
||||
S unwrapValue = converter.unwrapValue((B)beanValue);
|
||||
scalarType.jsonWrite(ctx, name, unwrapValue);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user