WW-3780 makes JSON plugin more extendable

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1307897 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Lukasz Lenart
2012-03-31 20:39:53 +00:00
parent 2d5fdbe6dd
commit c71a8dfd2d
4 changed files with 60 additions and 55 deletions
@@ -32,7 +32,7 @@ import java.util.Map;
* Deserializes and object from a JSON string
* </p>
*/
class JSONReader {
public class JSONReader {
private static final Object OBJECT_END = new Object();
private static final Object ARRAY_END = new Object();
private static final Object COLON = new Object();
@@ -55,13 +55,13 @@ class JSONReader {
private Object token;
private StringBuilder buf = new StringBuilder();
private char next() {
protected char next() {
this.c = this.it.next();
return this.c;
}
private void skipWhiteSpace() {
protected void skipWhiteSpace() {
while (Character.isWhitespace(this.c)) {
this.next();
}
@@ -74,7 +74,7 @@ class JSONReader {
return this.read();
}
private Object read() throws JSONException {
protected Object read() throws JSONException {
Object ret;
this.skipWhiteSpace();
@@ -125,7 +125,7 @@ class JSONReader {
}
@SuppressWarnings("unchecked")
private Map object() throws JSONException {
protected Map object() throws JSONException {
Map ret = new HashMap();
Object next = this.read();
if (next != OBJECT_END) {
@@ -151,12 +151,12 @@ class JSONReader {
return ret;
}
private JSONException buildInvalidInputException() {
protected JSONException buildInvalidInputException() {
return new JSONException("Input string is not well formed JSON (invalid char " + this.c + ")");
}
@SuppressWarnings("unchecked")
private List array() throws JSONException {
protected List array() throws JSONException {
List ret = new ArrayList();
Object value = this.read();
@@ -174,7 +174,7 @@ class JSONReader {
return ret;
}
private Object number() {
protected Object number() {
this.buf.setLength(0);
boolean toDouble = false;
@@ -208,7 +208,7 @@ class JSONReader {
}
}
private Object string(char quote) {
protected Object string(char quote) {
this.buf.setLength(0);
while ((this.c != quote) && (this.c != CharacterIterator.DONE)) {
@@ -234,22 +234,22 @@ class JSONReader {
return this.buf.toString();
}
private void add(char cc) {
protected void add(char cc) {
this.buf.append(cc);
this.next();
}
private void add() {
protected void add() {
this.add(this.c);
}
private void addDigits() {
protected void addDigits() {
while (Character.isDigit(this.c)) {
this.add();
}
}
private char unicode() {
protected char unicode() {
int value = 0;
for (int i = 0; i < 4; ++i) {
@@ -119,7 +119,7 @@ public class JSONResult implements Result {
/**
* Sets a comma-delimited list of wildcard expressions to match properties
* that should be excluded from the JSON output.
*
*
* @param commaDelim A comma-delimited list of wildcard patterns
*/
public void setExcludeWildcards(String commaDelim) {
@@ -174,14 +174,14 @@ public class JSONResult implements Result {
}
}
private Object readRootObject(ActionInvocation invocation) {
protected Object readRootObject(ActionInvocation invocation) {
if (enableSMD) {
return buildSMDObject(invocation);
}
return findRootObject(invocation);
}
private Object findRootObject(ActionInvocation invocation) {
protected Object findRootObject(ActionInvocation invocation) {
Object rootObject;
if (this.root != null) {
ValueStack stack = invocation.getStack();
@@ -192,15 +192,13 @@ public class JSONResult implements Result {
return rootObject;
}
private String createJSONString(HttpServletRequest request, Object rootObject) throws JSONException {
String json;
json = JSONUtil.serialize(rootObject, excludeProperties, includeProperties, ignoreHierarchy,
enumAsBean, excludeNullProperties);
protected String createJSONString(HttpServletRequest request, Object rootObject) throws JSONException {
String json = JSONUtil.serialize(rootObject, excludeProperties, includeProperties, ignoreHierarchy, enumAsBean, excludeNullProperties);
json = addCallbackIfApplicable(request, json);
return json;
}
private boolean enableGzip(HttpServletRequest request) {
protected boolean enableGzip(HttpServletRequest request) {
return enableGZIP && JSONUtil.isGzipInRequest(request);
}
@@ -51,7 +51,9 @@ import java.util.zip.GZIPOutputStream;
* Wrapper for JSONWriter with some utility methods.
*/
public class JSONUtil {
final static String RFC3339_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
public final static String RFC3339_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
private static final Logger LOG = LoggerFactory.getLogger(JSONUtil.class);
/**
@@ -64,7 +66,6 @@ public class JSONUtil {
*/
public static String serialize(Object object) throws JSONException {
JSONWriter writer = new JSONWriter();
return writer.write(object);
}
@@ -459,9 +460,9 @@ public class JSONUtil {
if (!existingPatterns.containsKey(patternExpr)) {
existingPatterns.put(patternExpr, patternExpr);
if (isIndexedProperty(patternPiece, type, includePatternData)) {
addPattern(results, patternExpr.substring(0, patternExpr.lastIndexOf(includePatternData.get(ARRAY_BEGIN_STRING).get(type))), type, includePatternData);
addPattern(results, patternExpr.substring(0, patternExpr.lastIndexOf(includePatternData.get(ARRAY_BEGIN_STRING).get(type))), type);
}
addPattern(results, patternExpr, type, includePatternData);
addPattern(results, patternExpr, type);
}
return patternExpr;
}
@@ -473,13 +474,11 @@ public class JSONUtil {
return patternPiece.endsWith(includePatternData.get(ARRAY_END_STRING).get(type));
}
private static void addPattern(List<Pattern> results, String pattern, String type, Map<String, Map<String, String>> includePatternData) {
results.add(
type == REGEXP_PATTERN ?
Pattern.compile(pattern) :
WildcardUtil.compileWildcardPattern(pattern));
private static void addPattern(List<Pattern> results, String pattern, String type) {
results.add(REGEXP_PATTERN.equals(type) ? Pattern.compile(pattern) : WildcardUtil.compileWildcardPattern(pattern));
if (LOG.isDebugEnabled()) {
LOG.debug("Adding include " + (type == REGEXP_PATTERN ? "property" : "wildcard") + " expression: " + pattern);
LOG.debug("Adding include " + (REGEXP_PATTERN.equals(type) ? "property" : "wildcard") + " expression: " + pattern);
}
}
}
@@ -46,7 +46,8 @@ import java.util.regex.Pattern;
* references are detected they will be nulled out.
* </p>
*/
class JSONWriter {
public class JSONWriter {
private static final Logger LOG = LoggerFactory.getLogger(JSONWriter.class);
/**
@@ -99,7 +100,7 @@ class JSONWriter {
/**
* Detect cyclic references
*/
private void value(Object object, Method method) throws JSONException {
protected void value(Object object, Method method) throws JSONException {
if (object == null) {
this.add("null");
@@ -129,7 +130,7 @@ class JSONWriter {
/**
* Serialize object into json
*/
private void process(Object object, Method method) throws JSONException {
protected void process(Object object, Method method) throws JSONException {
this.stack.push(object);
if (object instanceof Class) {
@@ -157,16 +158,23 @@ class JSONWriter {
} else if (object instanceof Enum) {
this.enumeration((Enum) object);
} else {
this.bean(object);
processCustom(object, method);
}
this.stack.pop();
}
/**
* Serialize custom object into json
*/
protected void processCustom(Object object, Method method) throws JSONException {
this.bean(object);
}
/**
* Instrospect bean and serialize its properties
*/
private void bean(Object object) throws JSONException {
protected void bean(Object object) throws JSONException {
this.add("{");
BeanInfo info;
@@ -233,7 +241,7 @@ class JSONWriter {
this.add("}");
}
private Object getBridgedValue(Method baseAccessor, Object value) throws InstantiationException, IllegalAccessException {
protected Object getBridgedValue(Method baseAccessor, Object value) throws InstantiationException, IllegalAccessException {
JSONFieldBridge fieldBridgeAnn = baseAccessor.getAnnotation(JSONFieldBridge.class);
if (fieldBridgeAnn != null) {
Class impl = fieldBridgeAnn.impl();
@@ -251,7 +259,7 @@ class JSONWriter {
return value;
}
private Method findBaseAccessor(Class clazz, Method accessor) {
protected Method findBaseAccessor(Class clazz, Method accessor) {
Method baseAccessor = null;
if (clazz.getName().indexOf("$$EnhancerByCGLIB$$") > -1) {
try {
@@ -279,7 +287,7 @@ class JSONWriter {
* Instrospect an Enum and serialize it as a name/value pair or as a bean
* including all its own properties
*/
private void enumeration(Enum enumeration) throws JSONException {
protected void enumeration(Enum enumeration) throws JSONException {
if (enumAsBean) {
this.bean(enumeration);
} else {
@@ -287,7 +295,7 @@ class JSONWriter {
}
}
private boolean shouldExcludeProperty(PropertyDescriptor prop) throws SecurityException,
protected boolean shouldExcludeProperty(PropertyDescriptor prop) throws SecurityException,
NoSuchFieldException {
String name = prop.getName();
@@ -296,23 +304,23 @@ class JSONWriter {
}
private String expandExpr(int i) {
protected String expandExpr(int i) {
return this.exprStack + "[" + i + "]";
}
private String expandExpr(String property) {
protected String expandExpr(String property) {
if (this.exprStack.length() == 0)
return property;
return this.exprStack + "." + property;
}
private String setExprStack(String expr) {
protected String setExprStack(String expr) {
String s = this.exprStack;
this.exprStack = expr;
return s;
}
private boolean shouldExcludeProperty(String expr) {
protected boolean shouldExcludeProperty(String expr) {
if (this.excludeProperties != null) {
for (Pattern pattern : this.excludeProperties) {
if (pattern.matcher(expr).matches()) {
@@ -341,7 +349,7 @@ class JSONWriter {
/**
* Add name/value pair to buffer
*/
private boolean add(String name, Object value, Method method, boolean hasData) throws JSONException {
protected boolean add(String name, Object value, Method method, boolean hasData) throws JSONException {
if (excludeNullProperties && value == null) {
return false;
}
@@ -359,7 +367,7 @@ class JSONWriter {
/**
* Add map to buffer
*/
private void map(Map map, Method method) throws JSONException {
protected void map(Map map, Method method) throws JSONException {
this.add("{");
Iterator it = map.entrySet().iterator();
@@ -411,7 +419,7 @@ class JSONWriter {
/**
* Add date to buffer
*/
private void date(Date date, Method method) {
protected void date(Date date, Method method) {
JSON json = null;
if (method != null)
json = method.getAnnotation(JSON.class);
@@ -426,7 +434,7 @@ class JSONWriter {
/**
* Add array to buffer
*/
private void array(Iterator it, Method method) throws JSONException {
protected void array(Iterator it, Method method) throws JSONException {
this.add("[");
boolean hasData = false;
@@ -456,7 +464,7 @@ class JSONWriter {
/**
* Add array to buffer
*/
private void array(Object object, Method method) throws JSONException {
protected void array(Object object, Method method) throws JSONException {
this.add("[");
int length = Array.getLength(object);
@@ -487,14 +495,14 @@ class JSONWriter {
/**
* Add boolean to buffer
*/
private void bool(boolean b) {
protected void bool(boolean b) {
this.add(b ? "true" : "false");
}
/**
* escape characters
*/
private void string(Object obj) {
protected void string(Object obj) {
this.add('"');
CharacterIterator it = new StringCharacterIterator(obj.toString());
@@ -529,14 +537,14 @@ class JSONWriter {
/**
* Add object to buffer
*/
private void add(Object obj) {
protected void add(Object obj) {
this.buf.append(obj);
}
/**
* Add char to buffer
*/
private void add(char c) {
protected void add(char c) {
this.buf.append(c);
}
@@ -545,7 +553,7 @@ class JSONWriter {
*
* @param c character to be encoded
*/
private void unicode(char c) {
protected void unicode(char c) {
this.add("\\u");
int n = c;
@@ -574,7 +582,7 @@ class JSONWriter {
this.enumAsBean = enumAsBean;
}
private static class JSONAnnotationFinder {
protected static class JSONAnnotationFinder {
private boolean serialize = true;
private Method accessor;
private String name;