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