1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.web.servlet.view.json.writer.sojo;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23
24 import net.sf.sojo.common.ObjectUtil;
25 import net.sf.sojo.common.WalkerInterceptor;
26 import net.sf.sojo.core.Constants;
27 import net.sf.sojo.core.conversion.ComplexBean2MapConversion;
28 import net.sf.sojo.core.filter.ClassPropertyFilterHandler;
29 import net.sf.sojo.core.reflect.ReflectionHelper;
30 import net.sf.sojo.util.ArrayIterator;
31
32
33
34
35
36
37
38
39 public class MapGraphWalker {
40
41 @SuppressWarnings("unchecked")
42 private List interceptorList = new ArrayList();
43 private ObjectUtil objectUtil = new ObjectUtil(false);
44 private int numberOfRecursion = 0;
45 private boolean ignoreNullValues = true;
46 private String excludedProperties[] = null;
47 private String objectName;
48 public MapGraphWalker() {
49 setIgnoreNullValues(true);
50 }
51
52 public MapGraphWalker(ClassPropertyFilterHandler pvFilterHandler) {
53 this();
54 this.objectUtil.setClassPropertyFilterHandler(pvFilterHandler);
55 }
56
57 public ObjectUtil getObjectUtil() { return objectUtil; }
58
59 public void setExcludedProperties(String[] pvExcludedProperties) {
60 excludedProperties = pvExcludedProperties;
61 }
62
63 public void setIgnoreNullValues(boolean pvBoolean) {
64 ignoreNullValues = pvBoolean;
65 ComplexBean2MapConversion lvBean2MapConversion = new ComplexBean2MapConversion();
66 lvBean2MapConversion.setIgnoreNullValues(ignoreNullValues);
67 objectUtil.getConverter().replaceConversion(lvBean2MapConversion);
68 }
69
70 @SuppressWarnings("unchecked")
71 public void addInterceptor(WalkerInterceptor pvInterceptor) {
72 interceptorList.add(pvInterceptor);
73 }
74 public int getInterceptorSize() {
75 return interceptorList.size();
76 }
77 public void removeInterceptorByNumber(int pvPosition) {
78 interceptorList.remove(pvPosition);
79 }
80
81 private boolean fireVisitElementEvent(Object pvKey, int pvIndex, Object pvValue, int pvType, String pvPath, int pvNumberOfRecursion) {
82 for (int i=0; i<interceptorList.size(); i++) {
83 boolean b = ((WalkerInterceptor) interceptorList.get(i)).visitElement(pvKey, pvIndex, pvValue, pvType, pvPath, pvNumberOfRecursion);
84 if (b == true) {
85 return true;
86 }
87 }
88 return false;
89 }
90
91 private void fireVisitIterateableElement(Object pvValue, int pvType, String pvPath, int pvBeginEnd) {
92 for (int i=0; i<interceptorList.size(); i++) {
93 ((WalkerInterceptor) interceptorList.get(i)).visitIterateableElement(pvValue, pvType, pvPath, pvBeginEnd);
94 }
95 }
96
97
98
99 private void fireStartWalk(Object pvStartObject) {
100 for (int i=0; i<interceptorList.size(); i++) {
101 ((WalkerInterceptor) interceptorList.get(i)).startWalk(pvStartObject);
102 }
103 }
104
105 private void fireEndWalk() {
106 for (int i=0; i<interceptorList.size(); i++) {
107 ((WalkerInterceptor) interceptorList.get(i)).endWalk();
108 }
109 }
110
111 public int getNumberOfRecursion() { return numberOfRecursion; }
112
113 public void walk(Object pvObject) {
114 numberOfRecursion = 0;
115 fireStartWalk(pvObject);
116 walkInternal(null, Constants.INVALID_INDEX, pvObject, "");
117 fireEndWalk();
118 }
119
120 public String removeLastPointOnPath(String pvPath) {
121 String lvPath = pvPath;
122 if (lvPath.endsWith(".")) {
123 lvPath = lvPath.substring(0, lvPath.length() - 1);
124 }
125 return lvPath;
126 }
127
128
129 public boolean isPropertyExcluded(String property){
130 String prob = removeLastPointOnPath(property);
131 if(excludedProperties == null || excludedProperties.length == 0)
132 return false;
133
134 for(String excluded: excludedProperties){
135
136 if(excluded != null && excluded.equals(prob))
137 return true;
138 if(!excluded.startsWith("(") && ("("+ objectName + ")." + excluded).equals(prob))
139 return true;
140 }
141
142 return false;
143 }
144
145 @SuppressWarnings("unchecked")
146 private void walkInternal(Object pvKey, int pvIndex, Object pvValue, String pvPath) {
147 numberOfRecursion++;
148
149 if(!isPropertyExcluded(pvPath)){
150 if (pvValue == null) {
151 fireVisitElementEvent(pvKey, pvIndex, null, Constants.TYPE_NULL, removeLastPointOnPath(pvPath), numberOfRecursion);
152 } else if (ReflectionHelper.isSimpleType(pvValue)) {
153 fireVisitElementEvent(pvKey, pvIndex, pvValue, Constants.TYPE_SIMPLE, removeLastPointOnPath(pvPath), numberOfRecursion);
154 }
155
156
157 else if (ReflectionHelper.isMapType(pvValue)) {
158 Map lvMap = (Map) pvValue;
159 boolean lvCancel = fireVisitElementEvent(pvKey, pvIndex, pvValue, Constants.TYPE_MAP, pvPath + "()", numberOfRecursion);
160 if (ReflectionHelper.isComplexMapType(pvValue)) {
161 if (pvPath.length() > 0 && pvPath.endsWith(".") == false) { pvPath = pvPath + "."; }
162 mapWalker(lvMap, pvPath, false, lvCancel);
163 } else {
164 mapWalker(lvMap, pvPath, true, lvCancel);
165 }
166 }
167
168
169 else if (ReflectionHelper.isIterateableType(pvValue)) {
170 boolean lvCancel = fireVisitElementEvent(pvKey, pvIndex, pvValue, Constants.TYPE_ITERATEABLE, pvPath + "[]", numberOfRecursion);
171 iteratorWalker(pvValue, pvPath, lvCancel);
172 }
173
174
175 else {
176 pvPath = removeLastPointOnPath(pvPath);
177 Object lvSimple = objectUtil.makeSimple(pvValue, excludedProperties);
178 if("".equals(pvKey) || pvKey == null)
179 walkInternal(null, Constants.INVALID_INDEX, lvSimple, pvPath);
180 else
181 walkInternal(pvKey, Constants.INVALID_INDEX, lvSimple, pvPath);
182 }
183 }
184 }
185
186 @SuppressWarnings("unchecked")
187 private void iteratorWalker(Object pvValue , String pvPath, boolean pvCancel) {
188 if(!isPropertyExcluded(pvPath)){
189 if (pvCancel == false) {
190 int lvIndex = Constants.INVALID_INDEX;
191
192 Iterator lvIterator = null;
193 if (pvValue.getClass().isArray()) {
194 lvIterator = new ArrayIterator(pvValue);
195 } else {
196 Collection lvCollection = (Collection) pvValue;
197 lvIterator = lvCollection.iterator();
198 }
199
200 fireVisitIterateableElement(pvValue, Constants.TYPE_ITERATEABLE, pvPath, Constants.ITERATOR_BEGIN);
201 while (lvIterator.hasNext()) {
202 Object o = lvIterator.next();
203 lvIndex++;
204 StringBuffer sb = new StringBuffer(pvPath);
205 sb.append("[").append(lvIndex).append("]");
206 sb.append(".");
207 walkInternal(null, lvIndex, o, sb.toString());
208 }
209 fireVisitIterateableElement(pvValue, Constants.TYPE_ITERATEABLE, pvPath, Constants.ITERATOR_END);
210 }
211 }
212 }
213
214 @SuppressWarnings("unchecked")
215 private void mapWalker(Map pvMap, String pvPath, boolean pvWithBrackets, boolean pvCancel) {
216 if(!isPropertyExcluded(pvPath)){
217 if (pvCancel == false) {
218 fireVisitIterateableElement(pvMap, Constants.TYPE_MAP, pvPath, Constants.ITERATOR_BEGIN);
219 Iterator lvIterator = pvMap.entrySet().iterator();
220 while (lvIterator.hasNext()) {
221 Map.Entry lvEntry = (Map.Entry) lvIterator.next();
222 Object lvKey = lvEntry.getKey();
223 Object lvValue = lvEntry.getValue();
224 StringBuffer sb = new StringBuffer(pvPath);
225 if (pvWithBrackets) {
226 sb.append("(").append(lvKey).append(")");
227 sb.append(".");
228 } else {
229 sb.append(lvKey);
230 }
231 walkInternal(lvKey, Constants.INVALID_INDEX, lvValue, sb.toString());
232 }
233 fireVisitIterateableElement(pvMap, Constants.TYPE_MAP, pvPath, Constants.ITERATOR_END);
234 }
235 }
236 }
237
238 public void setObjectName(String objectName) {
239 this.objectName = objectName;
240 }
241
242
243 }