1
22
23 package com.liferay.portal.action;
24
25 import com.liferay.portal.kernel.json.JSONArray;
26 import com.liferay.portal.kernel.json.JSONException;
27 import com.liferay.portal.kernel.json.JSONFactoryUtil;
28 import com.liferay.portal.kernel.json.JSONObject;
29 import com.liferay.portal.kernel.log.Log;
30 import com.liferay.portal.kernel.log.LogFactoryUtil;
31 import com.liferay.portal.kernel.util.ArrayUtil;
32 import com.liferay.portal.kernel.util.GetterUtil;
33 import com.liferay.portal.kernel.util.MethodInvoker;
34 import com.liferay.portal.kernel.util.MethodWrapper;
35 import com.liferay.portal.kernel.util.ParamUtil;
36 import com.liferay.portal.kernel.util.StringUtil;
37 import com.liferay.portal.kernel.util.Validator;
38 import com.liferay.portal.model.BaseModel;
39 import com.liferay.portal.struts.JSONAction;
40 import com.liferay.portlet.tags.model.TagsAssetDisplay;
41 import com.liferay.portlet.tags.model.TagsAssetType;
42
43 import java.lang.reflect.InvocationTargetException;
44 import java.lang.reflect.Method;
45
46 import java.util.Date;
47 import java.util.HashMap;
48 import java.util.List;
49 import java.util.Map;
50
51 import javax.servlet.http.HttpServletRequest;
52 import javax.servlet.http.HttpServletResponse;
53
54 import org.apache.struts.action.ActionForm;
55 import org.apache.struts.action.ActionMapping;
56
57
63 public class JSONServiceAction extends JSONAction {
64
65 public static JSONObject toJSONObject(TagsAssetDisplay assetDisplay) {
66 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
67
68 jsonObj.put("assetId", assetDisplay.getAssetId());
69 jsonObj.put("companyId", assetDisplay.getCompanyId());
70 jsonObj.put("userId", assetDisplay.getUserId());
71 jsonObj.put("userName", assetDisplay.getUserName());
72 jsonObj.put("createDate", assetDisplay.getCreateDate());
73 jsonObj.put("modifiedDate", assetDisplay.getModifiedDate());
74 jsonObj.put("classNameId", assetDisplay.getClassNameId());
75 jsonObj.put("className", assetDisplay.getClassName());
76 jsonObj.put("classPK", assetDisplay.getClassPK());
77 jsonObj.put("portletId", assetDisplay.getPortletId());
78 jsonObj.put("portletTitle", assetDisplay.getPortletTitle());
79 jsonObj.put("startDate", assetDisplay.getStartDate());
80 jsonObj.put("endDate", assetDisplay.getEndDate());
81 jsonObj.put("publishDate", assetDisplay.getPublishDate());
82 jsonObj.put("expirationDate", assetDisplay.getExpirationDate());
83 jsonObj.put("mimeType", assetDisplay.getMimeType());
84 jsonObj.put("title", assetDisplay.getTitle());
85 jsonObj.put("description", assetDisplay.getDescription());
86 jsonObj.put("summary", assetDisplay.getSummary());
87 jsonObj.put("url", assetDisplay.getUrl());
88 jsonObj.put("height", assetDisplay.getHeight());
89 jsonObj.put("width", assetDisplay.getWidth());
90 jsonObj.put("priority", assetDisplay.getPriority());
91 jsonObj.put("viewCount", assetDisplay.getViewCount());
92 jsonObj.put("tagsEntries", assetDisplay.getTagsEntries());
93
94 return jsonObj;
95 }
96
97 public static JSONObject toJSONObject(TagsAssetType assetType) {
98 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
99
100 jsonObj.put("classNameId", assetType.getClassNameId());
101 jsonObj.put("className", assetType.getClassName());
102 jsonObj.put("portletId", assetType.getPortletId());
103 jsonObj.put("portletTitle", assetType.getPortletTitle());
104
105 return jsonObj;
106 }
107
108 public String getJSON(
109 ActionMapping mapping, ActionForm form, HttpServletRequest request,
110 HttpServletResponse response)
111 throws Exception {
112
113 String className = ParamUtil.getString(request, "serviceClassName");
114 String methodName = ParamUtil.getString(request, "serviceMethodName");
115 String[] serviceParameters = getStringArrayFromJSON(
116 request, "serviceParameters");
117 String[] serviceParameterTypes = getStringArrayFromJSON(
118 request, "serviceParameterTypes");
119
120 if (!isValidRequest(request)) {
121 return null;
122 }
123
124 Class<?> classObj = Class.forName(className);
125
126 Object[] methodAndParameterTypes = getMethodAndParameterTypes(
127 classObj, methodName, serviceParameters, serviceParameterTypes);
128
129 if (methodAndParameterTypes != null) {
130 Method method = (Method)methodAndParameterTypes[0];
131 Class<?>[] parameterTypes = (Class[])methodAndParameterTypes[1];
132 Object[] args = new Object[serviceParameters.length];
133
134 for (int i = 0; i < serviceParameters.length; i++) {
135 args[i] = getArgValue(
136 request, classObj, methodName, serviceParameters[i],
137 parameterTypes[i]);
138
139 }
140
141 try {
142 if (_log.isDebugEnabled()) {
143 _log.debug(
144 "Invoking class " + classObj + " on method " +
145 method.getName() + " with args " + args);
146 }
147
148 Object returnObj = method.invoke(classObj, args);
149
150 if (returnObj != null) {
151 return getReturnValue(returnObj);
152 }
153 else {
154 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
155
156 return jsonObj.toString();
157 }
158 }
159 catch (Exception e) {
160 _log.error(e, e);
161
162 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
163
164 if (e instanceof InvocationTargetException) {
165 jsonObj.put("exception", e.getCause().toString());
166 }
167 else {
168 jsonObj.put("exception", e.getMessage());
169 }
170
171 return jsonObj.toString();
172 }
173 }
174
175 return null;
176 }
177
178 protected Object getArgValue(
179 HttpServletRequest request, Class<?> classObj, String methodName,
180 String parameter, Class<?> parameterType)
181 throws Exception {
182
183 String parameterTypeName = parameterType.getName();
184
185 String value = ParamUtil.getString(request, parameter);
186
187 if (Validator.isNull(value) &&
188 !parameterTypeName.equals("[Ljava.lang.String;")) {
189
190 return null;
191 }
192 else if (parameterTypeName.equals("boolean") ||
193 parameterTypeName.equals(Boolean.class.getName())) {
194
195 return Boolean.valueOf(ParamUtil.getBoolean(request, parameter));
196 }
197 else if (parameterTypeName.equals("double") ||
198 parameterTypeName.equals(Double.class.getName())) {
199
200 return new Double(ParamUtil.getDouble(request, parameter));
201 }
202 else if (parameterTypeName.equals("int") ||
203 parameterTypeName.equals(Integer.class.getName())) {
204
205 return new Integer(ParamUtil.getInteger(request, parameter));
206 }
207 else if (parameterTypeName.equals("long") ||
208 parameterTypeName.equals(Long.class.getName())) {
209
210 return new Long(ParamUtil.getLong(request, parameter));
211 }
212 else if (parameterTypeName.equals("short") ||
213 parameterTypeName.equals(Short.class.getName())) {
214
215 return new Short(ParamUtil.getShort(request, parameter));
216 }
217 else if (parameterTypeName.equals(Date.class.getName())) {
218 return new Date(ParamUtil.getLong(request, parameter));
219 }
220 else if (parameterTypeName.equals(String.class.getName())) {
221 return value;
222 }
223 else if (parameterTypeName.equals("[Z")) {
224 return ParamUtil.getBooleanValues(request, parameter);
225 }
226 else if (parameterTypeName.equals("[D")) {
227 return ParamUtil.getDoubleValues(request, parameter);
228 }
229 else if (parameterTypeName.equals("[F")) {
230 return ParamUtil.getFloatValues(request, parameter);
231 }
232 else if (parameterTypeName.equals("[I")) {
233 return ParamUtil.getIntegerValues(request, parameter);
234 }
235 else if (parameterTypeName.equals("[J")) {
236 return ParamUtil.getLongValues(request, parameter);
237 }
238 else if (parameterTypeName.equals("[S")) {
239 return ParamUtil.getShortValues(request, parameter);
240 }
241 else if (parameterTypeName.equals("[Ljava.lang.String;")) {
242 return StringUtil.split(value);
243 }
244 else if (parameterTypeName.equals("[[Z")) {
245 String[] values = request.getParameterValues(parameter);
246
247 if ((values != null) && (values.length > 0)) {
248 String[] values0 = StringUtil.split(values[0]);
249
250 boolean[][] doubleArray =
251 new boolean[values.length][values0.length];
252
253 for (int i = 0; i < values.length; i++) {
254 String[] curValues = StringUtil.split(values[i]);
255
256 for (int j = 0; j < curValues.length; j++) {
257 doubleArray[i][j] = GetterUtil.getBoolean(curValues[j]);
258 }
259 }
260
261 return doubleArray;
262 }
263 else {
264 return new boolean[0][0];
265 }
266 }
267 else if (parameterTypeName.equals("[[D")) {
268 String[] values = request.getParameterValues(parameter);
269
270 if ((values != null) && (values.length > 0)) {
271 String[] values0 = StringUtil.split(values[0]);
272
273 double[][] doubleArray =
274 new double[values.length][values0.length];
275
276 for (int i = 0; i < values.length; i++) {
277 String[] curValues = StringUtil.split(values[i]);
278
279 for (int j = 0; j < curValues.length; j++) {
280 doubleArray[i][j] = GetterUtil.getDouble(curValues[j]);
281 }
282 }
283
284 return doubleArray;
285 }
286 else {
287 return new double[0][0];
288 }
289 }
290 else if (parameterTypeName.equals("[[F")) {
291 String[] values = request.getParameterValues(parameter);
292
293 if ((values != null) && (values.length > 0)) {
294 String[] values0 = StringUtil.split(values[0]);
295
296 float[][] doubleArray =
297 new float[values.length][values0.length];
298
299 for (int i = 0; i < values.length; i++) {
300 String[] curValues = StringUtil.split(values[i]);
301
302 for (int j = 0; j < curValues.length; j++) {
303 doubleArray[i][j] = GetterUtil.getFloat(curValues[j]);
304 }
305 }
306
307 return doubleArray;
308 }
309 else {
310 return new float[0][0];
311 }
312 }
313 else if (parameterTypeName.equals("[[I")) {
314 String[] values = request.getParameterValues(parameter);
315
316 if ((values != null) && (values.length > 0)) {
317 String[] values0 = StringUtil.split(values[0]);
318
319 int[][] doubleArray =
320 new int[values.length][values0.length];
321
322 for (int i = 0; i < values.length; i++) {
323 String[] curValues = StringUtil.split(values[i]);
324
325 for (int j = 0; j < curValues.length; j++) {
326 doubleArray[i][j] = GetterUtil.getInteger(curValues[j]);
327 }
328 }
329
330 return doubleArray;
331 }
332 else {
333 return new int[0][0];
334 }
335 }
336 else if (parameterTypeName.equals("[[J")) {
337 String[] values = request.getParameterValues(parameter);
338
339 if ((values != null) && (values.length > 0)) {
340 String[] values0 = StringUtil.split(values[0]);
341
342 long[][] doubleArray =
343 new long[values.length][values0.length];
344
345 for (int i = 0; i < values.length; i++) {
346 String[] curValues = StringUtil.split(values[i]);
347
348 for (int j = 0; j < curValues.length; j++) {
349 doubleArray[i][j] = GetterUtil.getLong(curValues[j]);
350 }
351 }
352
353 return doubleArray;
354 }
355 else {
356 return new long[0][0];
357 }
358 }
359 else if (parameterTypeName.equals("[[S")) {
360 String[] values = request.getParameterValues(parameter);
361
362 if ((values != null) && (values.length > 0)) {
363 String[] values0 = StringUtil.split(values[0]);
364
365 short[][] doubleArray =
366 new short[values.length][values0.length];
367
368 for (int i = 0; i < values.length; i++) {
369 String[] curValues = StringUtil.split(values[i]);
370
371 for (int j = 0; j < curValues.length; j++) {
372 doubleArray[i][j] = GetterUtil.getShort(curValues[j]);
373 }
374 }
375
376 return doubleArray;
377 }
378 else {
379 return new short[0][0];
380 }
381 }
382 else if (parameterTypeName.equals("[[Ljava.lang.String")) {
383 String[] values = request.getParameterValues(parameter);
384
385 if ((values != null) && (values.length > 0)) {
386 String[] values0 = StringUtil.split(values[0]);
387
388 String[][] doubleArray =
389 new String[values.length][values0.length];
390
391 for (int i = 0; i < values.length; i++) {
392 doubleArray[i] = StringUtil.split(values[i]);
393 }
394
395 return doubleArray;
396 }
397 else {
398 return new String[0][0];
399 }
400 }
401 else {
402 _log.error(
403 "Unsupported parameter type for class " + classObj +
404 ", method " + methodName + ", parameter " + parameter +
405 ", and type " + parameterTypeName);
406
407 return null;
408 }
409 }
410
411 protected Object[] getMethodAndParameterTypes(
412 Class<?> classObj, String methodName, String[] parameters,
413 String[] parameterTypes)
414 throws Exception {
415
416 String parameterNames = StringUtil.merge(parameters);
417
418 String key =
419 classObj.getName() + "_METHOD_NAME_" + methodName +
420 "_PARAMETERS_" + parameterNames;
421
422 Object[] methodAndParameterTypes = _methodCache.get(key);
423
424 if (methodAndParameterTypes != null) {
425 return methodAndParameterTypes;
426 }
427
428 Method method = null;
429 Class<?>[] methodParameterTypes = null;
430
431 Method[] methods = classObj.getMethods();
432
433 for (int i = 0; i < methods.length; i++) {
434 Method curMethod = methods[i];
435
436 if (curMethod.getName().equals(methodName)) {
437 Class<?>[] curParameterTypes = curMethod.getParameterTypes();
438
439 if (curParameterTypes.length == parameters.length) {
440 if ((parameterTypes.length > 0) &&
441 (parameterTypes.length == curParameterTypes.length)) {
442
443 boolean match = true;
444
445 for (int j = 0; j < parameterTypes.length; j++) {
446 String t1 = parameterTypes[j];
447 String t2 = curParameterTypes[j].getName();
448
449 if (!t1.equals(t2)) {
450 match = false;
451 }
452 }
453
454 if (match) {
455 method = curMethod;
456 methodParameterTypes = curParameterTypes;
457
458 break;
459 }
460 }
461 else if (method != null) {
462 _log.error(
463 "Obscure method name for class " + classObj +
464 ", method " + methodName + ", and parameters " +
465 parameterNames);
466
467 return null;
468 }
469 else {
470 method = curMethod;
471 methodParameterTypes = curParameterTypes;
472 }
473 }
474 }
475 }
476
477 if (method != null) {
478 methodAndParameterTypes =
479 new Object[] {method, methodParameterTypes};
480
481 _methodCache.put(key, methodAndParameterTypes);
482
483 return methodAndParameterTypes;
484 }
485 else {
486 _log.error(
487 "No method found for class " + classObj + ", method " +
488 methodName + ", and parameters " + parameterNames);
489
490 return null;
491 }
492 }
493
494 protected String getReturnValue(Object returnObj) throws Exception {
495 if ((returnObj instanceof Boolean) || (returnObj instanceof Double) ||
496 (returnObj instanceof Integer) || (returnObj instanceof Long) ||
497 (returnObj instanceof Short) || (returnObj instanceof String)) {
498
499 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
500
501 jsonObj.put("returnValue", returnObj.toString());
502
503 return jsonObj.toString();
504 }
505 else if (returnObj instanceof BaseModel<?>) {
506 String serlializerClassName = getSerializerClassName(returnObj);
507
508 MethodWrapper methodWrapper = new MethodWrapper(
509 serlializerClassName, "toJSONObject", returnObj);
510
511 JSONObject jsonObj = (JSONObject)MethodInvoker.invoke(
512 methodWrapper, false);
513
514 return jsonObj.toString();
515 }
516 else if (returnObj instanceof BaseModel<?>[]) {
517 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
518
519 BaseModel<?>[] returnArray = (BaseModel[])returnObj;
520
521 if (returnArray.length > 0) {
522 BaseModel<?> returnItem0 = returnArray[0];
523
524 String serializerClassName = getSerializerClassName(
525 returnItem0);
526
527 MethodWrapper methodWrapper = new MethodWrapper(
528 serializerClassName, "toJSONArray", returnObj);
529
530 jsonArray = (JSONArray)MethodInvoker.invoke(
531 methodWrapper, false);
532 }
533
534 return jsonArray.toString();
535 }
536 else if (returnObj instanceof BaseModel<?>[][]) {
537 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
538
539 BaseModel<?>[][] returnArray = (BaseModel<?>[][])returnObj;
540
541 if ((returnArray.length > 0) &&
542 (returnArray[0].length > 0)) {
543
544 BaseModel<?> returnItem0 = returnArray[0][0];
545
546 String serializerClassName = getSerializerClassName(
547 returnItem0);
548
549 MethodWrapper methodWrapper = new MethodWrapper(
550 serializerClassName, "toJSONArray", returnObj);
551
552 jsonArray = (JSONArray)MethodInvoker.invoke(
553 methodWrapper, false);
554 }
555
556 return jsonArray.toString();
557 }
558 else if (returnObj instanceof List<?>) {
559 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
560
561 List<Object> returnList = (List<Object>)returnObj;
562
563 if (!returnList.isEmpty()) {
564 Object returnItem0 = returnList.get(0);
565
566 String serlializerClassName = getSerializerClassName(
567 returnItem0);
568
569 MethodWrapper methodWrapper = new MethodWrapper(
570 serlializerClassName, "toJSONArray", returnObj);
571
572 jsonArray = (JSONArray)MethodInvoker.invoke(
573 methodWrapper, false);
574 }
575
576 return jsonArray.toString();
577 }
578 else if (returnObj instanceof JSONArray) {
579 JSONArray jsonArray = (JSONArray)returnObj;
580
581 return jsonArray.toString();
582 }
583 else if (returnObj instanceof JSONObject) {
584 JSONObject jsonObj = (JSONObject)returnObj;
585
586 return jsonObj.toString();
587 }
588 else if (returnObj instanceof TagsAssetDisplay) {
589 return getReturnValue((TagsAssetDisplay)returnObj);
590 }
591 else if (returnObj instanceof TagsAssetDisplay[]) {
592 return getReturnValue((TagsAssetDisplay[])returnObj);
593 }
594 else if (returnObj instanceof TagsAssetType) {
595 return getReturnValue((TagsAssetType)returnObj);
596 }
597 else if (returnObj instanceof TagsAssetType[]) {
598 return getReturnValue((TagsAssetType[])returnObj);
599 }
600 else {
601 return JSONFactoryUtil.serialize(returnObj);
602 }
603 }
604
605 protected String getReturnValue(TagsAssetDisplay assetDisplay)
606 throws Exception {
607
608 JSONObject jsonObj = toJSONObject(assetDisplay);
609
610 return jsonObj.toString();
611 }
612
613 protected String getReturnValue(TagsAssetDisplay[] assetDisplays)
614 throws Exception {
615
616 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
617
618 for (int i = 0; i < assetDisplays.length; i++) {
619 TagsAssetDisplay assetDisplay = assetDisplays[i];
620
621 jsonArray.put(toJSONObject(assetDisplay));
622 }
623
624 return jsonArray.toString();
625 }
626
627 protected String getReturnValue(TagsAssetType assetType)
628 throws Exception {
629
630 JSONObject jsonObj = toJSONObject(assetType);
631
632 return jsonObj.toString();
633 }
634
635 protected String getReturnValue(TagsAssetType[] assetTypes)
636 throws Exception {
637
638 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
639
640 for (int i = 0; i < assetTypes.length; i++) {
641 TagsAssetType assetType = assetTypes[i];
642
643 jsonArray.put(toJSONObject(assetType));
644 }
645
646 return jsonArray.toString();
647 }
648
649 protected String getSerializerClassName(Object obj) {
650 String serlializerClassName = StringUtil.replace(
651 obj.getClass().getName(),
652 new String[] {".model.impl.", "Impl"},
653 new String[] {".service.http.", "JSONSerializer"});
654
655 return serlializerClassName;
656 }
657
658 protected String[] getStringArrayFromJSON(
659 HttpServletRequest request, String param)
660 throws JSONException {
661
662 String json = ParamUtil.getString(request, param, "[]");
663
664 JSONArray jsonArray = JSONFactoryUtil.createJSONArray(json);
665
666 return ArrayUtil.toStringArray(jsonArray);
667 }
668
669 protected boolean isValidRequest(HttpServletRequest request) {
670 String className = ParamUtil.getString(request, "serviceClassName");
671
672 if (className.contains(".service.") &&
673 className.endsWith("ServiceUtil") &&
674 !className.endsWith("LocalServiceUtil")) {
675
676 return true;
677 }
678 else {
679 return false;
680 }
681 }
682
683 private static Log _log = LogFactoryUtil.getLog(JSONServiceAction.class);
684
685 private Map<String, Object[]> _methodCache =
686 new HashMap<String, Object[]>();
687
688 }