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