View Javadoc

1   package net.sf.crispy.impl.rest;
2   
3   import java.lang.reflect.Method;
4   import java.util.ArrayList;
5   import java.util.Hashtable;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Map;
9   import java.util.TreeMap;
10  import java.util.Vector;
11  import java.util.Map.Entry;
12  
13  import net.sf.crispy.impl.http.Constant;
14  import net.sf.crispy.util.Converter;
15  import net.sf.crispy.util.Invoker;
16  import net.sf.crispy.util.Util;
17  
18  public class ParameterDeserializer {
19  	
20  	public static Map convertString2Map (String pvParamStr) {
21  		String lvParams[] = pvParamStr.split("&");
22  		Map lvMap = new Hashtable(lvParams.length);
23  		for (int i = 0; i < lvParams.length; i++) {
24  			String lvKeyVal[] = lvParams[i].split("=");
25  			String lvValue[] = (String[]) lvMap.get(lvKeyVal[0]);
26  			if (lvValue == null) {
27  				lvMap.put(lvKeyVal[0], new String[] {lvKeyVal[1]});
28  			} else {
29  				String lvNewValue [] = new String[lvValue.length + 1];
30  				for (int j = 0; j < lvValue.length; j++) {
31  					lvNewValue[j] = lvValue[j];
32  				}
33  				lvNewValue[lvValue.length] = lvKeyVal[1];
34  				lvMap.put(lvKeyVal[0], lvNewValue);
35  			}
36  			
37  		}
38  		return lvMap;
39  	}
40  	
41  
42  	public Object deserialize(final Map pvParamMap) throws Exception {
43  		Map lvMap = new Hashtable();
44  		Map lvRefMap = new TreeMap();
45  		pvParamMap.remove(Constant.PARAM_TYPES);
46  
47  		Iterator itMap = pvParamMap.entrySet().iterator();
48  		while (itMap.hasNext()) {
49  			Map.Entry lvMapEntry = (Entry) itMap.next();
50  			String lvKey = (String) lvMapEntry.getKey();
51  			Object o = lvMapEntry.getValue();
52  			String lvValue[] = null;
53  			if (o.getClass().isArray()) { 
54  				lvValue = (String[]) pvParamMap.get(lvKey); 
55  				}
56  				else {
57  					lvValue = new String[] { o.toString() };
58  				}
59  
60  			// Parameter einsammeln
61  			// alles was vor dem Unterstrich ist, gehoert zu einer Klasse
62  			// param0_name und param0_vorname werden in eine Gruppe (Map) unter dem Namen param0 abgelegt
63  			String lvParam[] = lvKey.split(ParameterSerializer.DELIMITTER);
64  			Map lvClassMap = (Map) lvMap.get(lvParam[0]);
65  			if (lvClassMap == null) { lvClassMap = new Hashtable(); }
66  			
67  			switch (lvParam.length) {
68  				// simple Parameter
69  				case 1:
70  					lvClassMap.put(lvParam[0], lvValue[0]);
71  					break;
72  				case 2:
73  					// param1_name="Peter" --> name=Peter
74  					lvClassMap.put(lvParam[1], lvValue[0]);
75  					break;
76  					
77  				// References (MAP, MAPSIMPLE, LIST)
78  				case 3:
79  					lvRefMap.put(lvKey, lvValue);
80  					break;
81  
82  				// param1_MAP_childrenMap_Node2
83  				case 4:
84  					lvRefMap.put(lvKey, lvValue);
85  					break;
86  					
87  				default:
88  					// lvClassMap.put(lvParam[1], lvValue[0]);
89  					System.out.println("???? ParameterDeserializer: " + lvParam.length 
90  							+ " --> " + Util.array2String(lvParam)
91  							+ " --> " + Util.array2String(lvValue));
92  					break;
93  			}
94  			if (lvClassMap.size() > 0) { lvMap.put(lvParam[0], lvClassMap); }
95  		} // WHILE
96  		
97  		// aus einzelnen werten wieder ein Objekt bauen
98  		itMap = lvMap.entrySet().iterator();
99  		// sortieren der Attribute param0, param1, param2, ...
100 		Map lvParamObject = new TreeMap();
101 		while(itMap.hasNext()) {
102 			Map.Entry lvMapEntry = (Entry) itMap.next();
103 			String lvKey = (String) lvMapEntry.getKey();
104 			Map lvClassMap = (Map) lvMapEntry.getValue();
105 			String lvClassStr = (String) lvClassMap.get("class");
106 			if (lvClassStr != null) {
107 				Class lvClass = Class.forName(lvClassStr);
108 				// alle Properties in den richtigen datentyp umwandeln
109 				Iterator itClassMap = lvClassMap.entrySet().iterator();
110 				while (itClassMap.hasNext()) {
111 					Map.Entry lvMapEntry_Class = (Entry) itClassMap.next();
112 					String lvKeyClassMap = (String) lvMapEntry_Class.getKey();
113 					if (!(lvKeyClassMap.equals("class"))) {
114 						Object lvValue = lvMapEntry_Class.getValue();
115 						
116 						if (lvKeyClassMap.startsWith(Converter.HASH_CODE_KEY)) {
117 							 lvClassMap.put(lvKeyClassMap, lvValue);
118 						} else if (lvValue.toString().startsWith(Converter.HASH_CODE_KEY)) {
119 							 lvClassMap.put(lvKeyClassMap, lvValue);
120 						} else {
121 							// alle setter aufrufen, um die Werte zu setzen
122 							String lvProperty = "set" + lvKeyClassMap.substring(0,1).toUpperCase() + lvKeyClassMap.substring(1);
123 							Vector v = new Vector(1);
124 							v.add(lvValue);
125 							Method lvMethod = Invoker.findMethod(lvClass, lvProperty, v);
126 							lvValue = Converter.convertStringParams2MethodParams(lvMethod, v)[0];
127 							lvValue = new Converter().makeSimple(lvValue);
128 							lvClassMap.put(lvKeyClassMap, lvValue);
129 						}
130 						
131 					}
132 				} // WHILE
133 				// einzelne Instancen erzeugen
134 				lvParamObject.put(lvKey, lvClassMap);
135 				
136 			} // IF lvClassStr != null 
137 			// einfache Parameter
138 			else if (lvClassMap.size() > 0) {
139 					String lvSimpleKey = (String) lvClassMap.keySet().iterator().next();
140 					lvParamObject.put(lvSimpleKey, lvClassMap.get(lvSimpleKey));
141 			}
142 			
143 		} // WHILE
144 
145 		// ----- alle Referenzen zwischen den Objeten wieder aufbauen -----
146 		Iterator it = lvRefMap.entrySet().iterator();
147 		List lvDelList = new ArrayList();
148 		
149 		while (it.hasNext()) {
150 			Map.Entry lvMapEntry = (Entry) it.next();
151 			String lvKey = (String) lvMapEntry.getKey();
152 			Object lvRefValue = lvMapEntry.getValue();
153 			String lvValues[] = (String[]) lvRefValue;
154 			String lvParam[] = lvKey.split(ParameterSerializer.DELIMITTER);
155 			
156 			Vector lvParamVector = null;
157 			
158 			for (int i = 0; i < lvValues.length; i++) {
159 				String lvValue = lvValues[i];	
160 				Object o = lvParamObject.get(lvValue);
161 				
162 				if (lvParam[1].equals(ParameterSerializer.LIST)) {
163 					Object ob = lvParamObject.get(lvParam[0]);
164 					
165 					// Referenz finden
166 					Map m = findListReferences(lvMap, lvValue);
167 					if (ob == null) {
168 						if (lvParamVector == null) {lvParamVector = new Vector(); }
169 						if ((m != null) && (m.size() > 0)) {
170 							lvParamVector.add(m);
171 							lvDelList.add(lvValue);
172 						} else { 
173 							lvParamVector.add(lvValue);
174 						}
175 						lvParamObject.put(lvParam[0], lvParamVector);
176 					}
177 					else if (ob instanceof Vector) {
178 						lvParamVector = (Vector) ob;
179 						// Wert setzen
180 						if ((m != null) && (m.size() > 0)) { lvParamVector.add(m); }
181 							// Referenz setzen
182 							else {  lvParamVector.add(lvValue); }
183 						lvParamObject.put(lvParam[0], lvParamVector);
184 						lvDelList.add(lvValue);
185 					}
186 					else {
187 						Map lvMap2 = (Map) ob;
188 						lvParamVector = (Vector) lvMap2.get(lvParam[2]);
189 						if (lvParamVector == null) {lvParamVector = new Vector(); }
190 						// Referenz setzen
191 						if (lvValue.startsWith(Converter.HASH_CODE_KEY)) { lvParamVector.add(lvValue); }
192 							// Wert setzen
193 							else { 
194 								// Wert setzen
195 								if ((m != null) && (m.size() > 0)) { lvParamVector.add(m); }
196 								// Referenz setzen
197 								else {  lvParamVector.add(lvValue); }
198 							}
199 						lvMap2.put(lvParam[2], lvParamVector);
200 						lvParamObject.put(lvParam[0], lvMap2);
201 						lvDelList.add(lvValue);
202 					}
203 				} // IF LIST
204 				
205 				else if (lvParam[1].equals(ParameterSerializer.MAPSIMPLE)) {
206 					Map lvParamMap = (Map) lvParamObject.get(lvParam[0]);
207 					if (lvParamMap == null) { lvParamMap =  new Hashtable(); }
208 					// handelt es sich um eine Referenz?
209 					Map m = findListReferences(lvParamObject, lvValue);
210 					if ((m != null) && (m.size() > 0)) { lvParamMap.put(lvParam[2], m); }
211 						// sonst ist es ein Wert
212 						else { lvParamMap.put(lvParam[2], lvValue); }
213 					if (lvParamMap.size() > 0) {
214 						lvParamObject.remove(lvValue);
215 						lvParamObject.put(lvParam[0], lvParamMap); 
216 					}
217 				} // ELSE IF MAPSIMPLE
218 				
219 				else if (lvParam[1].equals(ParameterSerializer.MAP)) {
220 					// Referenz finden
221 					if (lvMap.get(lvParam[0]) != null) {
222 						Map m = findMapReferences(lvRefMap, lvMap, lvValue);
223 						if ((m != null) && (m.size() > 0)){
224 //							System.out.println("--- " + lvParam[0] + ": " + lvMap.get(lvParam[0]));
225 							String lvMapKey = lvKey.split(ParameterSerializer.DELIMITTER)[2];
226 							
227 							Iterator lvIterator = m.keySet().iterator();
228 							while (lvIterator.hasNext()) {
229 								String lvDelKey = lvValue + ParameterSerializer.DELIMITTER  
230 										+ ParameterSerializer.MAP + ParameterSerializer.DELIMITTER + lvMapKey
231 										+ ParameterSerializer.DELIMITTER + lvIterator.next();
232 								Object obj = lvRefMap.get(lvDelKey);
233 								if (obj != null) {
234 									lvDelKey = ((String[]) obj)[0];
235 									lvDelList.add(lvDelKey);
236 								}
237 							}
238 							((Map) lvParamObject.get(lvParam[0])).put(lvMapKey, m);
239 						}
240 					}
241 				} // ELSE IF MAP
242 				
243 				else if (o != null) {
244 					System.out.println("---- Invalid type in param (ParameterDeserializer): " + lvParam[1] + " -- " + o);
245 				}
246 				else {
247 					System.out.println("????????????? ParameterDeserializer");
248 				}
249 			} // FOR
250 		} // WHILE
251 		
252 		
253 		// Alle durch referenzen ersetzten Objekte Loeschen
254 		for (Iterator iter = lvDelList.iterator(); iter.hasNext();) {
255 			String lvDel = (String) iter.next();
256 			lvParamObject.remove(lvDel);
257 		}
258 
259 		
260 		 // System.out.println("PARAM-MAP-AFTER: " + lvParamObject);
261 		
262 		// ----- richtige Reihenfolge herstellen und als return zurueckgeben -----
263 		Vector lvRetVec = new Vector();
264 		it = lvParamObject.keySet().iterator();
265 		while (it.hasNext()) {
266 			Object lvKey = it.next();
267 			Object lvValue = lvParamObject.get(lvKey);
268 			lvValue = new Converter().makeComplex(lvValue);
269 			lvRetVec.add(lvValue);
270 		}
271 
272 		
273 		if (lvRetVec.size() == 1) { return lvRetVec.get(0); }
274 			else { return lvRetVec; }
275 	}
276 	
277 	
278 	public Map findListReferences (Map pvClassMap, String pvFindString) {
279 		Map ret = new Hashtable();
280 		Map lvMap = (Map) pvClassMap.get(pvFindString);
281 		// z.B.: param0_LIST_children=param2
282 		if (lvMap != null) {  return lvMap;  }
283 			// z.B.: param4_LIST_children=~hashCode~8029412 -> bereits bekanntes Objekt suchen
284 			else {
285 				String lvSearchHashCode = null;
286 				if (pvFindString.indexOf(Converter.HASH_CODE_KEY) == 0) {
287 					lvSearchHashCode =  pvFindString.substring(Converter.HASH_CODE_KEY.length());
288 					Iterator it2 = pvClassMap.entrySet().iterator();
289 					while (it2.hasNext()) {
290 						Map.Entry lvMapEntry = (Entry) it2.next();
291 						Map lvValue2 = (Map) lvMapEntry.getValue();
292 						Object o = lvValue2.get(Converter.HASH_CODE_KEY);
293 						if ((o != null) && (o.equals(lvSearchHashCode))) {
294 							return lvValue2;
295 						}
296 					}
297 				}
298 			} // ELSE
299 		return ret;
300 	}
301 	
302 	public Map findMapReferences (Map pvRefMap, Map pvClassMap, String pvFindString) {
303 		Iterator it = pvRefMap.entrySet().iterator();
304 		Map ret = new Hashtable();
305 		while (it.hasNext()) {
306 			Map.Entry lvMapEntry = (Entry) it.next();
307 			String lvKey = (String) lvMapEntry.getKey();
308 			String lvValue[] = (String[]) lvMapEntry.getValue();
309 			if (lvKey.startsWith(pvFindString)) {
310 				String lvNewMapKey = lvKey.split(ParameterSerializer.DELIMITTER)[3];
311 				String lvFindRefKey[] = (String[]) pvRefMap.get(lvKey);
312 				if (lvFindRefKey[0].startsWith(Converter.HASH_CODE_KEY)) {
313 					ret.put(lvNewMapKey, lvFindRefKey[0]);
314 				} else {
315 					ret.put(lvNewMapKey, pvClassMap.get(lvFindRefKey[0]));
316 				}
317 			}
318 		} // WHILE
319 		return ret;
320 	}
321 		
322 }