mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#377 - Add back support for JsonWriteBeanVisitor
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
/**
|
||||
* Allows for customising the JSON write processing.
|
||||
* <p>
|
||||
* You can use this to add raw JSON content via {@link JsonWriter}.
|
||||
* <p>
|
||||
* You register a JsonWriteBeanVisitor with {@link JsonWriteOptions}.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* the type of entity bean
|
||||
*
|
||||
* @see JsonWriteOptions
|
||||
*/
|
||||
public interface JsonWriteBeanVisitor<T> {
|
||||
|
||||
/**
|
||||
* Visit the bean that has just been writing it's content to JSON. You can
|
||||
* write your own additional JSON content to the JsonWriter if you wish.
|
||||
*
|
||||
* @param bean
|
||||
* the bean that has been writing it's content
|
||||
* @param jsonWriter
|
||||
* the JsonWriter which you can append custom json content to if you
|
||||
* wish.
|
||||
*/
|
||||
void visit(T bean, JsonWriter jsonWriter);
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package com.avaje.ebean.text.json;
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides options for customising the JSON write process.
|
||||
* <p>
|
||||
@@ -18,6 +21,8 @@ public class JsonWriteOptions {
|
||||
|
||||
protected JsonConfig.Include include;
|
||||
|
||||
protected Map<String, JsonWriteBeanVisitor<?>> visitorMap;
|
||||
|
||||
/**
|
||||
* Parse and return a PathProperties from nested string format like
|
||||
* (a,b,c(d,e),f(g)) where "c" is a path containing "d" and "e" and "f" is a
|
||||
@@ -67,6 +72,31 @@ public class JsonWriteOptions {
|
||||
this.include = include;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JsonWriteBeanVisitor for the root level.
|
||||
*/
|
||||
public JsonWriteOptions setRootPathVisitor(JsonWriteBeanVisitor<?> visitor) {
|
||||
return setPathVisitor(null, visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JsonWriteBeanVisitor for the given path.
|
||||
*/
|
||||
public JsonWriteOptions setPathVisitor(String path, JsonWriteBeanVisitor<?> visitor) {
|
||||
if (visitorMap == null) {
|
||||
visitorMap = new HashMap<String, JsonWriteBeanVisitor<?>>();
|
||||
}
|
||||
visitorMap.put(path, visitor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Map of registered JsonWriteBeanVisitor's by path.
|
||||
*/
|
||||
public Map<String, JsonWriteBeanVisitor<?>> getVisitorMap() {
|
||||
return visitorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the jackson object mapper to use.
|
||||
* <p/>
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Wraps an underlying JsonGenerator taking into account null suppression and exposing isIncludeEmpty() etc.
|
||||
*/
|
||||
public interface JsonWriter {
|
||||
|
||||
/**
|
||||
* Return the Jackson core JsonGenerator.
|
||||
*/
|
||||
JsonGenerator gen();
|
||||
|
||||
/**
|
||||
* Return true if null values should be included in JSON output.
|
||||
*/
|
||||
boolean isIncludeNull();
|
||||
|
||||
/**
|
||||
* Return true if empty collections should be included in the JSON output.
|
||||
*/
|
||||
boolean isIncludeEmpty();
|
||||
|
||||
/**
|
||||
* Write a field name followed by object start.
|
||||
*/
|
||||
void writeStartObject(String key);
|
||||
|
||||
/**
|
||||
* Write a object start.
|
||||
*/
|
||||
void writeStartObject();
|
||||
|
||||
/**
|
||||
* Write a object end.
|
||||
*/
|
||||
void writeEndObject();
|
||||
|
||||
/**
|
||||
* Write a field name followed by array start.
|
||||
*/
|
||||
void writeStartArray(String key);
|
||||
|
||||
/**
|
||||
* Write a array start.
|
||||
*/
|
||||
void writeStartArray();
|
||||
|
||||
/**
|
||||
* Write a array end.
|
||||
*/
|
||||
void writeEndArray();
|
||||
|
||||
/**
|
||||
* Write the field name.
|
||||
*/
|
||||
void writeFieldName(String name);
|
||||
|
||||
/**
|
||||
* Write a null value taking into account null value suppression.
|
||||
*/
|
||||
void writeNullField(String name);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, int value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, short value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, long value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, double value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, float value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, BigDecimal value);
|
||||
|
||||
/**
|
||||
* Write a sting field.
|
||||
*/
|
||||
void writeStringField(String name, String value);
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinary(InputStream is, int length);
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinaryField(String name, byte[] value);
|
||||
|
||||
/**
|
||||
* Write a boolean field.
|
||||
*/
|
||||
void writeBooleanField(String name, boolean value);
|
||||
|
||||
/**
|
||||
* Write a boolean value (typically inside a list).
|
||||
*/
|
||||
void writeBoolean(boolean value);
|
||||
|
||||
/**
|
||||
* Write a string value (typically inside a list).
|
||||
*/
|
||||
void writeString(String value);
|
||||
|
||||
/**
|
||||
* Write a int value (typically inside a list).
|
||||
*/
|
||||
void writeNumber(int value);
|
||||
|
||||
/**
|
||||
* Write a long value (typically inside a list).
|
||||
*/
|
||||
void writeNumber(long value);
|
||||
|
||||
/**
|
||||
* Write a BigDecimal value (typically inside a list).
|
||||
*/
|
||||
void writeNumber(BigDecimal value);
|
||||
|
||||
/**
|
||||
* Write a null value.
|
||||
*/
|
||||
void writeNull();
|
||||
|
||||
/**
|
||||
* Method that will force generator to copy
|
||||
* input text verbatim with <b>no</b> modifications (including
|
||||
* that no escaping is done and no separators are added even
|
||||
* if context [array, object] would otherwise require such).
|
||||
* If such separators are desired, use
|
||||
* {@link #writeRawValue(String)} instead.
|
||||
*/
|
||||
void writeRaw(String text);
|
||||
|
||||
/**
|
||||
* Method that will force generator to copy
|
||||
* input text verbatim without any modifications, but assuming
|
||||
* it must constitute a single legal JSON value (number, string,
|
||||
* boolean, null, Array or List). Assuming this, proper separators
|
||||
* are added if and as needed (comma or colon), and generator
|
||||
* state updated to reflect this.
|
||||
*/
|
||||
void writeRawValue(String text);
|
||||
}
|
||||
@@ -141,11 +141,11 @@ public final class BeanListHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
if (!list.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.writeStartArray(name);
|
||||
ctx.beginAssocMany(name);
|
||||
for (int j = 0; j < list.size(); j++) {
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean) list.get(j));
|
||||
}
|
||||
ctx.writeEndArray();
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,12 +179,12 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
if (!map.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.writeStartArray(name);
|
||||
ctx.beginAssocMany(name);
|
||||
for (Entry<?, ?> entry : map.entrySet()) {
|
||||
//FIXME: json write map key ...
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean) entry.getValue());
|
||||
}
|
||||
ctx.writeEndArray();
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,11 +140,11 @@ public final class BeanSetHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
if (!set.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.writeStartArray(name);
|
||||
ctx.beginAssocMany(name);
|
||||
for (Object bean : set) {
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean) bean);
|
||||
}
|
||||
ctx.writeEndArray();
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +286,8 @@ public class DJsonContext implements JsonContext {
|
||||
|
||||
private WriteJson createWriteJson(JsonGenerator gen, JsonWriteOptions options) {
|
||||
PathProperties pathProps = (options == null) ? null : options.getPathProperties();
|
||||
return new WriteJson(server, gen, pathProps, determineObjectMapper(options), determineInclude(options));
|
||||
Map<String, JsonWriteBeanVisitor<?>> visitors = (options == null) ? null : options.getVisitorMap();
|
||||
return new WriteJson(server, gen, pathProps, visitors, determineObjectMapper(options), determineInclude(options));
|
||||
}
|
||||
|
||||
private <T> void toJsonFromCollection(Collection<T> collection, String key, JsonGenerator gen, JsonWriteOptions options) throws IOException {
|
||||
|
||||
@@ -3,10 +3,12 @@ package com.avaje.ebeaninternal.server.text.json;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebean.text.json.JsonIOException;
|
||||
import com.avaje.ebean.text.json.JsonWriteBeanVisitor;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.type.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.util.ArrayStack;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -21,11 +23,13 @@ import java.util.Set;
|
||||
public class WriteJson implements JsonWriter {
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
|
||||
private final JsonGenerator generator;
|
||||
|
||||
|
||||
private final PathProperties pathProperties;
|
||||
|
||||
private final Map<String, JsonWriteBeanVisitor<?>> visitors;
|
||||
|
||||
private final PathStack pathStack;
|
||||
|
||||
private final ArrayStack<Object> parentBeans;
|
||||
@@ -37,10 +41,13 @@ public class WriteJson implements JsonWriter {
|
||||
/**
|
||||
* Construct for full bean use (normal).
|
||||
*/
|
||||
public WriteJson(SpiEbeanServer server, JsonGenerator generator, PathProperties pathProperties, Object objectMapper, JsonConfig.Include include){
|
||||
public WriteJson(SpiEbeanServer server, JsonGenerator generator, PathProperties pathProperties,
|
||||
Map<String, JsonWriteBeanVisitor<?>> visitors, Object objectMapper, JsonConfig.Include include) {
|
||||
|
||||
this.server = server;
|
||||
this.generator = generator;
|
||||
this.pathProperties = pathProperties;
|
||||
this.visitors = visitors;
|
||||
this.objectMapper = objectMapper;
|
||||
this.include = include;
|
||||
this.parentBeans = new ArrayStack<Object>();
|
||||
@@ -50,9 +57,10 @@ public class WriteJson implements JsonWriter {
|
||||
/**
|
||||
* Construct for Json scalar use.
|
||||
*/
|
||||
public WriteJson(JsonGenerator generator, JsonConfig.Include include){
|
||||
public WriteJson(JsonGenerator generator, JsonConfig.Include include) {
|
||||
this.generator = generator;
|
||||
this.include = include;
|
||||
this.visitors = null;
|
||||
this.server = null;
|
||||
this.pathProperties = null;
|
||||
this.objectMapper = null;
|
||||
@@ -74,72 +82,253 @@ public class WriteJson implements JsonWriter {
|
||||
return include != JsonConfig.Include.NON_EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonGenerator gen() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFieldName(String name) throws IOException {
|
||||
generator.writeFieldName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNullField(String name) throws IOException {
|
||||
if (isIncludeNull()) {
|
||||
generator.writeNullField(name);
|
||||
public void writeStartObject(String key) {
|
||||
try {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartObject();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Long value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeStartObject() {
|
||||
try {
|
||||
generator.writeStartObject();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Double value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeEndObject() {
|
||||
try {
|
||||
generator.writeEndObject();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, int value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeStartArray(String key) {
|
||||
try {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Short value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeStartArray() {
|
||||
try {
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEndArray() {
|
||||
try {
|
||||
generator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRaw(String text) {
|
||||
try {
|
||||
generator.writeRaw(text);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRawValue(String text) {
|
||||
try {
|
||||
generator.writeRawValue(text);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFieldName(String name) {
|
||||
try {
|
||||
generator.writeFieldName(name);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNullField(String name) {
|
||||
if (isIncludeNull()) {
|
||||
try {
|
||||
generator.writeNullField(name);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, long value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, double value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, int value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, short value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Float value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeNumberField(String name, float value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, BigDecimal value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeNumberField(String name, BigDecimal value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStringField(String name, String value) throws IOException {
|
||||
generator.writeStringField(name, value);
|
||||
public void writeStringField(String name, String value) {
|
||||
try {
|
||||
generator.writeStringField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinary(InputStream is, int length) throws IOException {
|
||||
generator.writeBinary(is, length);
|
||||
public void writeBinary(InputStream is, int length) {
|
||||
try {
|
||||
generator.writeBinary(is, length);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinaryField(String name, byte[] value) throws IOException {
|
||||
generator.writeBinaryField(name, value);
|
||||
public void writeBinaryField(String name, byte[] value) {
|
||||
try {
|
||||
generator.writeBinaryField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBooleanField(String name, Boolean value) throws IOException {
|
||||
generator.writeBooleanField(name, value);
|
||||
public void writeBooleanField(String name, boolean value) {
|
||||
try {
|
||||
generator.writeBooleanField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean value) {
|
||||
try {
|
||||
generator.writeBoolean(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
try {
|
||||
generator.writeString(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumber(int value) {
|
||||
try {
|
||||
generator.writeNumber(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumber(long value) {
|
||||
try {
|
||||
generator.writeNumber(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumber(BigDecimal value) {
|
||||
try {
|
||||
generator.writeNumber(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNull() {
|
||||
try {
|
||||
generator.writeNull();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isParentBean(Object bean) {
|
||||
@@ -164,65 +353,90 @@ public class WriteJson implements JsonWriter {
|
||||
pathStack.pop();
|
||||
}
|
||||
|
||||
public void beginAssocMany(String key) {
|
||||
try {
|
||||
pathStack.pushPathKey(key);
|
||||
generator.writeFieldName(key);
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void endAssocMany() {
|
||||
try {
|
||||
pathStack.pop();
|
||||
generator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public WriteBean createWriteBean(BeanDescriptor<?> desc, EntityBean bean) {
|
||||
|
||||
String path = pathStack.peekWithNull();
|
||||
JsonWriteBeanVisitor visitor = (visitors == null) ? null : visitors.get(path);
|
||||
if (pathProperties == null) {
|
||||
return new WriteBean(desc, bean);
|
||||
return new WriteBean(desc, bean, visitor);
|
||||
}
|
||||
|
||||
|
||||
boolean explicitAllProps = false;
|
||||
Set<String> currentIncludeProps = pathProperties.get(pathStack.peekWithNull());
|
||||
Set<String> currentIncludeProps = pathProperties.get(path);
|
||||
if (currentIncludeProps != null) {
|
||||
explicitAllProps = currentIncludeProps.contains("*");
|
||||
if (explicitAllProps || currentIncludeProps.isEmpty()) {
|
||||
currentIncludeProps = null;
|
||||
}
|
||||
}
|
||||
return new WriteBean(desc, explicitAllProps, currentIncludeProps, bean);
|
||||
return new WriteBean(desc, explicitAllProps, currentIncludeProps, bean, visitor);
|
||||
}
|
||||
|
||||
public void writeValueUsingObjectMapper(String name, Object value) throws IOException {
|
||||
public void writeValueUsingObjectMapper(String name, Object value) {
|
||||
|
||||
if (!isIncludeEmpty()) {
|
||||
// check for suppression of empty collection or map
|
||||
if (value instanceof Collection && ((Collection)value).isEmpty()) {
|
||||
if (value instanceof Collection && ((Collection) value).isEmpty()) {
|
||||
// suppress empty collection
|
||||
return;
|
||||
} else if (value instanceof Map && ((Map)value).isEmpty()) {
|
||||
} else if (value instanceof Map && ((Map) value).isEmpty()) {
|
||||
// suppress empty map
|
||||
return;
|
||||
}
|
||||
}
|
||||
generator.writeFieldName(name);
|
||||
objectMapper().writeValue(generator, value);
|
||||
try {
|
||||
generator.writeFieldName(name);
|
||||
objectMapper().writeValue(generator, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectMapper objectMapper() {
|
||||
if (objectMapper == null) {
|
||||
throw new IllegalStateException(
|
||||
"Jackson ObjectMapper required but not set. Expected to be set on either"
|
||||
+" serverConfig");
|
||||
throw new IllegalStateException("Jackson ObjectMapper required but not set. Expected to be set on either serverConfig");
|
||||
}
|
||||
return (ObjectMapper)objectMapper;
|
||||
return (ObjectMapper) objectMapper;
|
||||
}
|
||||
|
||||
public static class WriteBean {
|
||||
|
||||
|
||||
final boolean explicitAllProps;
|
||||
final Set<String> currentIncludeProps;
|
||||
final BeanDescriptor<?> desc;
|
||||
final EntityBean currentBean;
|
||||
|
||||
WriteBean(BeanDescriptor<?> desc, EntityBean currentBean){
|
||||
this(desc, false, null, currentBean);
|
||||
final JsonWriteBeanVisitor visitor;
|
||||
|
||||
WriteBean(BeanDescriptor<?> desc, EntityBean currentBean, JsonWriteBeanVisitor visitor) {
|
||||
this(desc, false, null, currentBean, visitor);
|
||||
}
|
||||
|
||||
WriteBean(BeanDescriptor<?> desc, boolean explicitAllProps, Set<String> currentIncludeProps, EntityBean currentBean) {
|
||||
WriteBean(BeanDescriptor<?> desc, boolean explicitAllProps, Set<String> currentIncludeProps, EntityBean currentBean, JsonWriteBeanVisitor visitor) {
|
||||
super();
|
||||
this.desc = desc;
|
||||
this.currentBean = currentBean;
|
||||
this.explicitAllProps = explicitAllProps;
|
||||
this.currentIncludeProps = currentIncludeProps;
|
||||
this.visitor = visitor;
|
||||
}
|
||||
|
||||
private boolean isReferenceOnly() {
|
||||
@@ -251,34 +465,43 @@ public class WriteJson implements JsonWriter {
|
||||
}
|
||||
}
|
||||
|
||||
public void write(WriteJson writeJson) throws IOException {
|
||||
|
||||
BeanProperty beanProp = desc.getIdProperty();
|
||||
if (beanProp != null) {
|
||||
if (isIncludeProperty(beanProp)) {
|
||||
beanProp.jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isReferenceOnly()) {
|
||||
// render all the properties and invoke lazy loading if required
|
||||
BeanProperty[] props = desc.propertiesNonTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
@SuppressWarnings("unchecked")
|
||||
public void write(WriteJson writeJson) {
|
||||
|
||||
try {
|
||||
BeanProperty beanProp = desc.getIdProperty();
|
||||
if (beanProp != null) {
|
||||
if (isIncludeProperty(beanProp)) {
|
||||
beanProp.jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
props = desc.propertiesTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeTransientProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
|
||||
if (!isReferenceOnly()) {
|
||||
// render all the properties and invoke lazy loading if required
|
||||
BeanProperty[] props = desc.propertiesNonTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
props = desc.propertiesTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeTransientProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (visitor != null) {
|
||||
visitor.visit(currentBean, writeJson);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Boolean includeMany(String key) {
|
||||
if (pathProperties != null) {
|
||||
String fullPath = pathStack.peekFullPath(key);
|
||||
@@ -287,15 +510,19 @@ public class WriteJson implements JsonWriter {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void toJson(String name, Collection<?> c) throws IOException {
|
||||
public void toJson(String name, Collection<?> c) {
|
||||
|
||||
beginAssocMany(name);
|
||||
try {
|
||||
beginAssocMany(name);
|
||||
|
||||
for (Object bean : c) {
|
||||
BeanDescriptor<?> d = getDescriptor(bean.getClass());
|
||||
d.jsonWrite(this, (EntityBean)bean, null);
|
||||
for (Object bean : c) {
|
||||
BeanDescriptor<?> d = getDescriptor(bean.getClass());
|
||||
d.jsonWrite(this, (EntityBean) bean, null);
|
||||
}
|
||||
endAssocMany();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
endAssocMany();
|
||||
}
|
||||
|
||||
private <T> BeanDescriptor<T> getDescriptor(Class<T> cls) {
|
||||
@@ -306,36 +533,5 @@ public class WriteJson implements JsonWriter {
|
||||
return d;
|
||||
}
|
||||
|
||||
public void beginAssocMany(String key) throws IOException {
|
||||
pathStack.pushPathKey(key);
|
||||
generator.writeFieldName(key);
|
||||
generator.writeStartArray();
|
||||
}
|
||||
|
||||
public void endAssocMany() throws IOException {
|
||||
pathStack.pop();
|
||||
generator.writeEndArray();
|
||||
}
|
||||
|
||||
public void writeStartArray(String key) throws IOException {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartArray();
|
||||
}
|
||||
|
||||
public void writeStartObject(String key) throws IOException {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartObject();
|
||||
}
|
||||
|
||||
public void writeEndObject() throws IOException {
|
||||
generator.writeEndObject();
|
||||
}
|
||||
|
||||
public void writeEndArray() throws IOException {
|
||||
generator.writeEndArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Wraps an underlying JsonGenerator taking into account null suppression and exposing isIncludeEmpty() etc.
|
||||
*/
|
||||
public interface JsonWriter {
|
||||
|
||||
/**
|
||||
* Return the Jackson core JsonGenerator.
|
||||
*/
|
||||
JsonGenerator gen();
|
||||
|
||||
/**
|
||||
* Return true if null values should be included in JSON output.
|
||||
*/
|
||||
boolean isIncludeNull();
|
||||
|
||||
/**
|
||||
* Return true if empty collections should be included in the JSON output.
|
||||
*/
|
||||
boolean isIncludeEmpty();
|
||||
|
||||
/**
|
||||
* Write the field name.
|
||||
*/
|
||||
void writeFieldName(String name) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a null value taking into account null value suppression.
|
||||
*/
|
||||
void writeNullField(String name) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, int value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Short value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Long value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Double value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Float value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, BigDecimal value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a sting field.
|
||||
*/
|
||||
void writeStringField(String name, String value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinary(InputStream is, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinaryField(String name, byte[] value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a boolean field.
|
||||
*/
|
||||
void writeBooleanField(String name, Boolean value) throws IOException;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.StringFormatter;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.EJson;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.EJson;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -26,6 +26,10 @@ public class ArrayStack<E> {
|
||||
this.list = new ArrayList<E>();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return list.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes an item onto the top of this stack.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user