mirror of
https://github.com/apache/struts.git
synced 2026-08-07 15:46:57 +00:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user