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 statement, Statement variableStatement, Object result)
166 throws Exception {
167
168 result = _populateFlags(statement, result);
169
170 String name = variableStatement.getName();
171
172 Object variableResult = _executeStatement(variableStatement);
173
174 Map<String, Object> map = _convertObjectToMap(result);
175
176 map.put(name.substring(1), variableResult);
177
178 return map;
179 }
180
181 private Object _addVariableStatementList(
182 Statement statement, Statement variableStatement, Object result,
183 List<Object> results)
184 throws Exception {
185
186 List<Object> list = _convertObjectToList(result);
187
188 for (Object object : list) {
189 if (object instanceof List) {
190 Object value = _addVariableStatementList(
191 statement, variableStatement, object, results);
192
193 results.add(value);
194 }
195 else {
196 Object value = _addVariableStatement(
197 statement, variableStatement, object);
198
199 results.add(value);
200 }
201 }
202
203 return results;
204 }
205
206 private List<Object> _convertObjectToList(Object object) {
207 if (!(object instanceof List)) {
208 String json = JSONFactoryUtil.looseSerialize(object);
209
210 object = JSONFactoryUtil.looseDeserialize(json, ArrayList.class);
211 }
212
213 return (List<Object>)object;
214 }
215
216 private Map<String, Object> _convertObjectToMap(Object object) {
217 if (!(object instanceof Map)) {
218 String json = JSONFactoryUtil.looseSerialize(object);
219
220 object = JSONFactoryUtil.looseDeserialize(json, HashMap.class);
221 }
222
223 return (Map<String, Object>)object;
224 }
225
226 private Object _executeStatement(Statement statement) throws Exception {
227 JSONWebServiceAction jsonWebServiceAction =
228 JSONWebServiceActionsManagerUtil.getJSONWebServiceAction(
229 _request, statement.getMethod(), null,
230 statement.getParameterMap());
231
232 Object result = jsonWebServiceAction.invoke();
233
234 result = _filterResult(statement, result);
235
236 List<Statement> variableStatements = statement.getVariableStatements();
237
238 if (variableStatements != null) {
239 for (Statement variableStatement : variableStatements) {
240 if (result instanceof List) {
241 result = _addVariableStatementList(
242 statement, variableStatement, result,
243 new ArrayList<Object>());
244 }
245 else {
246 result = _addVariableStatement(
247 statement, variableStatement, result);
248 }
249 }
250 }
251
252 return result;
253 }
254
255 private Object _filterResult(Statement statement, Object result) {
256 if (result instanceof List) {
257 result = _filterResultList(
258 statement, result, new ArrayList<Object>());
259 }
260 else {
261 result = _filterResultObject(statement, result);
262 }
263
264 return result;
265 }
266
267 private Object _filterResultList(
268 Statement statement, Object result, List<Object> results) {
269
270 List<Object> list = _convertObjectToList(result);
271
272 for (Object object : list) {
273 Object value = _filterResultObject(statement, object);
274
275 results.add(value);
276 }
277
278 return results;
279 }
280
281 private Object _filterResultObject(Statement statement, Object result) {
282 if (result == null) {
283 return result;
284 }
285
286 String[] whitelist = statement.getWhitelist();
287
288 if (whitelist == null) {
289 return result;
290 }
291
292 Map<String, Object> map = _convertObjectToMap(result);
293
294 Map<String, Object> whitelistMap = new HashMap<String, Object>(
295 whitelist.length);
296
297 for (String key : whitelist) {
298 Object value = map.get(key);
299
300 whitelistMap.put(key, value);
301 }
302
303 return whitelistMap;
304 }
305
306 private Statement _parseStatement(
307 String assignment, Map<String, Object> parameterMap) {
308
309 Statement statement = new Statement();
310
311 _statements.add(statement);
312
313 int x = assignment.indexOf(StringPool.EQUAL);
314
315 if (x == -1) {
316 statement.setMethod(assignment.trim());
317 }
318 else {
319 String name = assignment.substring(0, x).trim();
320
321 int y = name.indexOf(StringPool.OPEN_BRACKET);
322
323 if (y != -1) {
324 String whitelistString = name.substring(
325 y + 1, name.length() - 1);
326
327 String[] whiteList = StringUtil.split(whitelistString);
328
329 for (int i = 0; i < whiteList.length; i++) {
330 whiteList[i] = whiteList[i].trim();
331 }
332
333 statement.setWhitelist(whiteList);
334
335 name = name.substring(0, y);
336 }
337
338 statement.setName(name);
339
340 statement.setMethod(assignment.substring(x + 1).trim());
341 }
342
343 statement.setParameterMap(parameterMap);
344
345 Set<String> keySet = parameterMap.keySet();
346
347 Iterator<String> iterator = keySet.iterator();
348
349 while (iterator.hasNext()) {
350 String key = iterator.next();
351
352 if (key.startsWith(StringPool.AT)) {
353 String value = (String)parameterMap.get(key);
354
355 iterator.remove();
356
357 List<Flag> flags = statement.getFlags();
358
359 if (flags == null) {
360 flags = new ArrayList<Flag>();
361
362 statement.setFlags(flags);
363 }
364
365 Flag flag = new Flag();
366
367 flag.setKey(key.substring(1));
368 flag.setValue(value);
369
370 flags.add(flag);
371 }
372 else if (key.startsWith(StringPool.DOLLAR)) {
373 Map<String, Object> map = (Map<String, Object>)parameterMap.get(
374 key);
375
376 iterator.remove();
377
378 List<Statement> variableStatements =
379 statement.getVariableStatements();
380
381 if (variableStatements == null) {
382 variableStatements = new ArrayList<Statement>();
383
384 statement.setVariableStatements(variableStatements);
385 }
386
387 Statement variableStatement = _parseStatement(key, map);
388
389 variableStatements.add(variableStatement);
390 }
391 }
392
393 return statement;
394 }
395
396 private Object _populateFlags(Statement statement, Object result) {
397 if (result instanceof List) {
398 result = _populateFlagsList(
399 statement.getName(), result, new ArrayList<Object>());
400 }
401 else {
402 _populateFlagsObject(statement.getName(), result);
403 }
404
405 return result;
406 }
407
408 private List<Object> _populateFlagsList(
409 String name, Object result, List<Object> results) {
410
411 List<Object> list = _convertObjectToList(result);
412
413 for (Object object : list) {
414 if (object instanceof List) {
415 Object value = _populateFlagsList(name, object, results);
416
417 results.add(value);
418 }
419 else {
420 _populateFlagsObject(name, object);
421
422 results.add(object);
423 }
424 }
425
426 return results;
427 }
428
429 private void _populateFlagsObject(String name, Object object) {
430 if (name == null) {
431 return;
432 }
433
434 name = name.concat(StringPool.PERIOD);
435
436 for (Statement statement : _statements) {
437 List<Flag> flags = statement.getFlags();
438
439 if (flags == null) {
440 continue;
441 }
442
443 for (Flag flag : flags) {
444 String value = flag.getValue();
445
446 if ((value == null) || !value.startsWith(name)) {
447 continue;
448 }
449
450 Map<String, Object> parameterMap = statement.getParameterMap();
451
452 Object propertyValue = BeanUtil.getDeclaredProperty(
453 object, value.substring(name.length()));
454
455 parameterMap.put(flag.getKey(), propertyValue);
456 }
457 }
458 }
459
460 private String _command;
461 private HttpServletRequest _request;
462 private List<Statement> _statements = new ArrayList<Statement>();
463
464 private class Flag extends KeyValue<String, String> {
465 }
466
467 private class Statement {
468
469 public List<Flag> getFlags() {
470 return _flags;
471 }
472
473 public String getMethod() {
474 return _method;
475 }
476
477 public String getName() {
478 return _name;
479 }
480
481 public Map<String, Object> getParameterMap() {
482 return _parameterMap;
483 }
484
485 public List<Statement> getVariableStatements() {
486 return _variableStatements;
487 }
488
489 public String[] getWhitelist() {
490 return _whitelist;
491 }
492
493 public void setFlags(List<Flag> flags) {
494 _flags = flags;
495 }
496
497 public void setMethod(String method) {
498 _method = method;
499 }
500
501 public void setName(String name) {
502 _name = name;
503 }
504
505 public void setParameterMap(Map<String, Object> parameterMap) {
506 _parameterMap = parameterMap;
507 }
508
509 public void setVariableStatements(List<Statement> variableStatements) {
510 _variableStatements = variableStatements;
511 }
512
513 public void setWhitelist(String[] whitelist) {
514 _whitelist = whitelist;
515 }
516
517 private List<Flag> _flags;
518 private String _method;
519 private String _name;
520 private Map<String, Object> _parameterMap;
521 private List<Statement> _variableStatements;
522 private String[] _whitelist;
523
524 }
525
526 }