1 package org.springframework.web.servlet.view.json.writer.sojo;
2
3 import java.beans.PropertyEditor;
4 import java.util.Date;
5
6 import net.sf.sojo.common.WalkerInterceptor;
7 import net.sf.sojo.core.Constants;
8 import net.sf.sojo.core.UniqueIdGenerator;
9 import net.sf.sojo.interchange.SerializerException;
10 import net.sf.sojo.util.Util;
11
12 import org.springframework.beans.PropertyEditorRegistry;
13 import org.springframework.web.servlet.view.json.JsonStringWriter;
14
15 public class JsonViewWalkerInterceptor implements WalkerInterceptor {
16
17
18 private StringBuffer jsonString = new StringBuffer();
19 private boolean ignoreNullValues = true;
20 private PropertyEditorRegistry propertyEditorRegistry;
21 private String objectName;
22 private boolean convertAllMapValues;
23 private String keepValueTypesMode;
24
25 public String getJsonString() {
26 return jsonString.toString();
27 }
28
29 public boolean getIgnoreNullValues() {
30 return ignoreNullValues;
31 }
32
33 public void setIgnoreNullValues(boolean ignoreNullValues) {
34 this.ignoreNullValues = ignoreNullValues;
35 }
36
37 public void startWalk(Object pvStartObject) {
38 jsonString = new StringBuffer();
39 }
40
41 public void endWalk() {
42 Util.delLastComma(jsonString);
43 }
44
45
46
47
48
49
50
51 public static String handleControlCharacterBack(final String pvValue) {
52
53 if (pvValue == null) {
54 return null;
55 }
56 StringBuffer sb = new StringBuffer();
57 int l = pvValue.length();
58 char c;
59 for (int i=0; i<l; i++) {
60 c = pvValue.charAt(i);
61 switch (c) {
62 case 0:
63 break;
64 case '\n':
65 case '\r':
66 case '\t':
67 sb.append(c);
68 break;
69 case '\\':
70 i++;
71 c = pvValue.charAt(i);
72 switch (c) {
73 case 'b':
74 sb.append('\b');
75 break;
76 case 't':
77 sb.append('\t');
78 break;
79 case 'n':
80 sb.append('\n');
81 break;
82 case 'f':
83 sb.append('\f');
84 break;
85 case 'r':
86 sb.append('\r');
87 break;
88
89
90
91
92
93
94 default:
95 sb.append(c);
96 }
97 break;
98 default:
99 sb.append(c);
100 }
101 }
102 return sb.toString();
103 }
104
105
106
107
108
109
110
111 public static Object handleControlCharacter(final Object pvValue) {
112 Object lvReturn = pvValue;
113 if (lvReturn != null && lvReturn.getClass().equals(String.class)) {
114 String lvString = lvReturn.toString();
115
116 int len = lvString.length();
117
118
119
120
121 char vorgChar;
122 char c = 0;
123 StringBuffer sb = new StringBuffer(len + 4);
124
125 for (int i = 0; i < len; i++) {
126 vorgChar = c;
127 c = lvString.charAt(i);
128 switch (c) {
129 case '\\':
130 sb.append("\\\\");
131 break;
132 case '"':
133 sb.append('\\').append(c);
134 break;
135 case '/':
136 sb.append('\\').append(c);
137 break;
138 case '\b':
139 sb.append("\\b");
140 break;
141 case '\t':
142 sb.append("\\t");
143 break;
144 case '\n':
145 sb.append("\\n");
146 break;
147 case '\f':
148 sb.append("\\f");
149 break;
150 case '\r':
151 sb.append("\\r");
152 break;
153 default:
154
155
156
157
158 sb.append(c);
159
160 }
161 }
162 return sb.toString();
163 } else {
164 return lvReturn;
165 }
166 }
167
168 public String handleSimpleJsonValue(Object pvValue, String path){
169 Object convertedValue = convertJsonValue(pvValue, path);
170 return handleJsonValue (convertedValue );
171 }
172
173 public String handleJsonValue (Object pvValue) {
174 String s = "";
175 if (pvValue != null) {
176 Object o = handleControlCharacter(pvValue);
177 s = object2StringWithDoubleQuote(o);
178 }
179 return s;
180 }
181
182 public String object2StringWithDoubleQuote(Object pvObject) {
183 StringBuffer s = new StringBuffer("");
184 if(JsonStringWriter.MODE_KEEP_VALUETYPES_BOOLEANS.equals(keepValueTypesMode)){
185 if(pvObject.getClass().equals(Boolean.class))
186 s.append(pvObject);
187 else
188 s.append("\"").append(pvObject).append("\"");
189 }else if(JsonStringWriter.MODE_KEEP_VALUETYPES_ALL.equals(keepValueTypesMode)){
190 if (pvObject.getClass().equals(String.class) || pvObject.getClass().equals(Character.class) || Date.class.isAssignableFrom(pvObject.getClass())) {
191 s.append("\"").append(pvObject).append("\"");
192 }else {
193 s.append(pvObject);
194 }
195 }else
196 s.append("\"").append(pvObject).append("\"");
197
198 return s.toString();
199 }
200
201
202
203 private Object convertJsonValue(Object pvValue, String path) {
204 if(path != null && propertyEditorRegistry != null && (convertAllMapValues || path.startsWith("("+ objectName + ")."))){
205 String p = path.replaceAll("^\\("+ objectName + "\\).","").replaceAll("\\).\\[","\\)\\[");
206 PropertyEditor ce = propertyEditorRegistry.findCustomEditor(pvValue.getClass(), p);
207 if(ce == null)
208 return pvValue;
209 else{
210 ce.setValue(pvValue);
211 return ce.getAsText();
212 }
213
214 }else
215 return pvValue;
216 }
217
218
219
220 public boolean visitElement(Object pvKey, int pvIndex, Object pvValue, int pvType, String pvPath, int pvNumberOfRecursion) {
221
222 if ( pvPath.indexOf("class") >= 0 || pvPath.indexOf(UniqueIdGenerator.UNIQUE_ID_PROPERTY) >= 0) {
223 return false;
224 }
225 if (pvType == Constants.TYPE_SIMPLE) {
226 if (pvKey != null && pvKey.getClass().equals(String.class)) {
227 jsonString.append(handleJsonValue(pvKey)).append(":");
228 } else if (pvKey != null) {
229 throw new SerializerException("JSON support only properties/keys from type String and not: '" + pvKey.getClass().getName() + "' (" + pvKey + ")");
230 }
231 jsonString.append(handleSimpleJsonValue(pvValue, pvPath)).append(",");
232 }
233
234
235 else if (pvType == Constants.TYPE_NULL) {
236 if("".equals(pvPath))
237 jsonString.append("null");
238 else if (!getIgnoreNullValues()) {
239 jsonString.append(handleJsonValue(pvKey)).append(":null,");
240 }
241 }
242
243
244 else if (pvKey != null && pvValue != null) {
245 if (pvKey != null && pvKey.getClass().equals(String.class)) {
246 jsonString.append(handleJsonValue(pvKey)).append(":");
247 } else {
248 throw new SerializerException("JSON support only properties/keys from type String and not: '" + pvKey.getClass().getName() + "' (" + pvKey + ")");
249 }
250 }
251
252 return false;
253 }
254
255
256 public void visitIterateableElement(Object pvValue, int pvType, String pvPath, int pvBeginEnd) {
257
258 if (pvBeginEnd == Constants.ITERATOR_BEGIN) {
259
260 if (pvType == Constants.TYPE_ITERATEABLE) {
261
262 jsonString.append("[");
263 } else if (pvType == Constants.TYPE_MAP) {
264 jsonString.append("{");
265 }
266 } else if (pvBeginEnd == Constants.ITERATOR_END) {
267 Util.delLastComma(jsonString);
268 if (pvType == Constants.TYPE_ITERATEABLE) {
269 jsonString.append("],");
270 } else if (pvType == Constants.TYPE_MAP) {
271 jsonString.append("},");
272 }
273 }
274 }
275
276
277 public void setPropertyEditorRegistry(
278 PropertyEditorRegistry propertyEditorRegistry) {
279 this.propertyEditorRegistry = propertyEditorRegistry;
280 }
281
282 public void setObjectName(String objectName) {
283 this.objectName = objectName;
284 }
285
286 public void setConvertAllMapValues(boolean convertAllMapValues) {
287 this.convertAllMapValues = convertAllMapValues;
288 }
289
290 public void setKeepValueTypesMode(String keepValueTypesMode) {
291 this.keepValueTypesMode = keepValueTypesMode;
292 }
293
294
295
296
297
298
299
300
301 }