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