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