001
014
015 package com.liferay.portal.jsonwebservice.action;
016
017 import com.liferay.portal.kernel.json.JSONFactoryUtil;
018 import com.liferay.portal.kernel.json.JSONSerializable;
019 import com.liferay.portal.kernel.json.JSONSerializer;
020 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceAction;
021 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionMapping;
022 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionsManagerUtil;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025
026 import java.io.IOException;
027
028 import java.util.ArrayList;
029 import java.util.HashMap;
030 import java.util.Iterator;
031 import java.util.List;
032 import java.util.Map;
033 import java.util.Set;
034
035 import javax.servlet.http.HttpServletRequest;
036
037 import jodd.bean.BeanUtil;
038
039 import jodd.servlet.ServletUtil;
040
041 import jodd.util.KeyValue;
042
043
047 public class JSONWebServiceInvokerAction implements JSONWebServiceAction {
048
049 public JSONWebServiceInvokerAction(HttpServletRequest request) {
050 _request = request;
051
052 _command = request.getParameter("cmd");
053
054 if (_command == null) {
055 try {
056 _command = ServletUtil.readRequestBody(request);
057 }
058 catch (IOException ioe) {
059 throw new IllegalArgumentException(ioe);
060 }
061 }
062 }
063
064 public JSONWebServiceActionMapping getJSONWebServiceActionMapping() {
065 return null;
066 }
067
068 public Object invoke() throws Exception {
069 Object command = JSONFactoryUtil.looseDeserializeSafe(_command);
070
071 List<Object> list = null;
072
073 boolean batchMode = false;
074
075 if (command instanceof List) {
076 list = (List<Object>)command;
077
078 batchMode = true;
079 }
080 else if (command instanceof Map) {
081 list = new ArrayList<Object>(1);
082
083 list.add(command);
084
085 batchMode = false;
086 }
087 else {
088 throw new IllegalArgumentException();
089 }
090
091 for (int i = 0; i < list.size(); i++) {
092 Map<String, Map<String, Object>> map =
093 (Map<String, Map<String, Object>>)list.get(i);
094
095 if (map.isEmpty()) {
096 throw new IllegalArgumentException();
097 }
098
099 Set<Map.Entry<String, Map<String, Object>>> entrySet =
100 map.entrySet();
101
102 Iterator<Map.Entry<String, Map<String, Object>>> iterator =
103 entrySet.iterator();
104
105 Map.Entry<String, Map<String, Object>> entry = iterator.next();
106
107 Statement statement = _parseStatement(
108 entry.getKey(), entry.getValue());
109
110 Object result = _executeStatement(statement);
111
112 list.set(i, result);
113 }
114
115 Object result = null;
116
117 if (batchMode == false) {
118 result = list.get(0);
119 }
120 else {
121 result = list;
122 }
123
124 return new InvokerResult(result);
125 }
126
127 public class InvokerResult implements JSONSerializable {
128
129 public String toJSONString() {
130 if (_result == null) {
131 return JSONFactoryUtil.getNullJSON();
132 }
133
134 JSONSerializer jsonSerializer =
135 JSONFactoryUtil.createJSONSerializer();
136
137 jsonSerializer.exclude("*.class");
138
139 for (Statement statement : _statements) {
140 String name = statement.getName();
141
142 if (name == null) {
143 continue;
144 }
145
146 jsonSerializer.include(name.substring(1));
147 }
148
149 return jsonSerializer.serialize(_result);
150 }
151
152 public Object getResult() {
153 return _result;
154 }
155
156 private InvokerResult(Object result) {
157 _result = result;
158 }
159
160 private Object _result;
161
162 }
163
164 private Object _addVariableStatement(
165 Statement variableStatement, Object result)
166 throws Exception {
167
168 String name = variableStatement.getName();
169
170 Object variableResult = _executeStatement(variableStatement);
171
172 Map<String, Object> map = _convertObjectToMap(result);
173
174 map.put(name.substring(1), variableResult);
175
176 return map;
177 }
178
179 private Object _addVariableStatementList(
180 Statement variableStatement, Object result, List<Object> results)
181 throws Exception {
182
183 List<Object> list = _convertObjectToList(result);
184
185 for (Object object : list) {
186 if (object instanceof List) {
187 Object value = _addVariableStatementList(
188 variableStatement, object, results);
189
190 results.add(value);
191 }
192 else {
193 Object value = _addVariableStatement(variableStatement, object);
194
195 results.add(value);
196 }
197 }
198
199 return results;
200 }
201
202 private List<Object> _convertObjectToList(Object object) {
203 if (!(object instanceof List)) {
204 String json = JSONFactoryUtil.looseSerialize(object);
205
206 object = JSONFactoryUtil.looseDeserialize(json, ArrayList.class);
207 }
208
209 return (List<Object>)object;
210 }
211
212 private Map<String, Object> _convertObjectToMap(Object object) {
213 if (!(object instanceof Map)) {
214 String json = JSONFactoryUtil.looseSerialize(object);
215
216 object = JSONFactoryUtil.looseDeserialize(json, HashMap.class);
217 }
218
219 return (Map<String, Object>)object;
220 }
221
222 private Object _executeStatement(Statement statement) throws Exception {
223 JSONWebServiceAction jsonWebServiceAction =
224 JSONWebServiceActionsManagerUtil.getJSONWebServiceAction(
225 _request, statement.getMethod(), null,
226 statement.getParameterMap());
227
228 Object result = jsonWebServiceAction.invoke();
229
230 if (result instanceof List) {
231 result = _populateFlagsList(
232 statement.getName(), result, new ArrayList<Object>());
233
234 result = _filterResultList(
235 statement, result, new ArrayList<Object>());
236 }
237 else {
238 _populateFlags(statement.getName(), result);
239
240 result = _filterResult(statement, result);
241 }
242
243 List<Statement> variableStatements = statement.getVariableStatements();
244
245 if (variableStatements != null) {
246 for (Statement variableStatement : variableStatements) {
247 if (result instanceof List) {
248 result = _addVariableStatementList(
249 variableStatement, result, new ArrayList<Object>());
250 }
251 else {
252 result = _addVariableStatement(variableStatement, result);
253 }
254 }
255 }
256
257 return result;
258 }
259
260 private Object _filterResult(Statement statement, Object result) {
261 if (result == null) {
262 return result;
263 }
264
265 String[] whitelist = statement.getWhitelist();
266
267 if (whitelist == null) {
268 return result;
269 }
270
271 Map<String, Object> map = _convertObjectToMap(result);
272
273 Map<String, Object> whitelistMap = new HashMap<String, Object>(
274 whitelist.length);
275
276 for (String key : whitelist) {
277 Object value = map.get(key);
278
279 whitelistMap.put(key, value);
280 }
281
282 return whitelistMap;
283 }
284
285 private Object _filterResultList(
286 Statement statement, Object result, List<Object> results) {
287
288 List<Object> list = _convertObjectToList(result);
289
290 for (Object object : list) {
291 Object value = _filterResult(statement, object);
292
293 results.add(value);
294 }
295
296 return results;
297 }
298
299 private Statement _parseStatement(
300 String assignment, Map<String, Object> parameterMap) {
301
302 Statement statement = new Statement();
303
304 _statements.add(statement);
305
306 int x = assignment.indexOf(StringPool.EQUAL);
307
308 if (x == -1) {
309 statement.setMethod(assignment.trim());
310 }
311 else {
312 String name = assignment.substring(0, x).trim();
313
314 int y = name.indexOf(StringPool.OPEN_BRACKET);
315
316 if (y != -1) {
317 String whitelistString = name.substring(
318 y + 1, name.length() - 1);
319
320 String[] whiteList = StringUtil.split(whitelistString);
321
322 for (int i = 0; i < whiteList.length; i++) {
323 whiteList[i] = whiteList[i].trim();
324 }
325
326 statement.setWhitelist(whiteList);
327
328 name = name.substring(0, y);
329 }
330
331 statement.setName(name);
332
333 statement.setMethod(assignment.substring(x + 1).trim());
334 }
335
336 statement.setParameterMap(parameterMap);
337
338 Set<String> keySet = parameterMap.keySet();
339
340 Iterator<String> iterator = keySet.iterator();
341
342 while (iterator.hasNext()) {
343 String key = iterator.next();
344
345 if (key.startsWith(StringPool.AT)) {
346 String value = (String)parameterMap.get(key);
347
348 iterator.remove();
349
350 List<Flag> flags = statement.getFlags();
351
352 if (flags == null) {
353 flags = new ArrayList<Flag>();
354
355 statement.setFlags(flags);
356 }
357
358 Flag flag = new Flag();
359
360 flag.setKey(key.substring(1));
361 flag.setValue(value);
362
363 flags.add(flag);
364 }
365 else if (key.startsWith(StringPool.DOLLAR)) {
366 Map<String, Object> map = (Map<String, Object>)parameterMap.get(
367 key);
368
369 iterator.remove();
370
371 List<Statement> variableStatements =
372 statement.getVariableStatements();
373
374 if (variableStatements == null) {
375 variableStatements = new ArrayList<Statement>();
376
377 statement.setVariableStatements(variableStatements);
378 }
379
380 Statement variableStatement = _parseStatement(key, map);
381
382 variableStatements.add(variableStatement);
383 }
384 }
385
386 return statement;
387 }
388
389 private void _populateFlags(String name, Object object) {
390 if (name == null) {
391 return;
392 }
393
394 name = name.concat(StringPool.PERIOD);
395
396 for (Statement statement : _statements) {
397 List<Flag> flags = statement.getFlags();
398
399 if (flags == null) {
400 continue;
401 }
402
403 for (Flag flag : flags) {
404 String value = flag.getValue();
405
406 if ((value == null) || !value.startsWith(name)) {
407 continue;
408 }
409
410 Map<String, Object> parameterMap = statement.getParameterMap();
411
412 Object propertyValue = BeanUtil.getDeclaredProperty(
413 object, value.substring(name.length()));
414
415 parameterMap.put(flag.getKey(), propertyValue);
416
417 flag.setValue(null);
418 }
419 }
420 }
421
422 private List<Object> _populateFlagsList(
423 String name, Object result, List<Object> results) {
424
425 List<Object> list = _convertObjectToList(result);
426
427 for (Object object : list) {
428 if (object instanceof List) {
429 Object value = _populateFlagsList(name, object, results);
430
431 results.add(value);
432 }
433 else {
434 _populateFlags(name, object);
435
436 results.add(object);
437 }
438 }
439
440 return results;
441 }
442
443 private String _command;
444 private HttpServletRequest _request;
445 private List<Statement> _statements = new ArrayList<Statement>();
446
447 private class Flag extends KeyValue<String, String> {
448 }
449
450 private class Statement {
451
452 public List<Flag> getFlags() {
453 return _flags;
454 }
455
456 public String getMethod() {
457 return _method;
458 }
459
460 public String getName() {
461 return _name;
462 }
463
464 public Map<String, Object> getParameterMap() {
465 return _parameterMap;
466 }
467
468 public List<Statement> getVariableStatements() {
469 return _variableStatements;
470 }
471
472 public String[] getWhitelist() {
473 return _whitelist;
474 }
475
476 public void setFlags(List<Flag> flags) {
477 _flags = flags;
478 }
479
480 public void setMethod(String method) {
481 _method = method;
482 }
483
484 public void setName(String name) {
485 _name = name;
486 }
487
488 public void setParameterMap(Map<String, Object> parameterMap) {
489 _parameterMap = parameterMap;
490 }
491
492 public void setVariableStatements(List<Statement> variableStatements) {
493 _variableStatements = variableStatements;
494 }
495
496 public void setWhitelist(String[] whitelist) {
497 _whitelist = whitelist;
498 }
499
500 private List<Flag> _flags;
501 private String _method;
502 private String _name;
503 private Map<String, Object> _parameterMap;
504 private List<Statement> _variableStatements;
505 private String[] _whitelist;
506
507 }
508
509 }