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.MethodInvoker;
31 import com.liferay.portal.kernel.util.MethodWrapper;
32 import com.liferay.portal.kernel.util.ParamUtil;
33 import com.liferay.portal.kernel.util.StringUtil;
34 import com.liferay.portal.kernel.util.Validator;
35 import com.liferay.portal.model.BaseModel;
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
139 try {
140 if (_log.isDebugEnabled()) {
141 _log.debug(
142 "Invoking class " + classObj + " on method " +
143 method.getName() + " with args " + args);
144 }
145
146 Object returnObj = method.invoke(classObj, args);
147
148 if (returnObj != null) {
149 if (returnObj instanceof BaseModel) {
150 String serlializerClassName = getSerializerClassName(
151 returnObj);
152
153 MethodWrapper methodWrapper = new MethodWrapper(
154 serlializerClassName, "toJSONObject", returnObj);
155
156 JSONObject jsonObj = (JSONObject)MethodInvoker.invoke(
157 methodWrapper, false);
158
159 return jsonObj.toString();
160 }
161 else if (returnObj instanceof List) {
162 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
163
164 List<Object> returnList = (List<Object>)returnObj;
165
166 if (!returnList.isEmpty()) {
167 Object returnItem0 = returnList.get(0);
168
169 String serlializerClassName =
170 getSerializerClassName(returnItem0);
171
172 MethodWrapper methodWrapper = new MethodWrapper(
173 serlializerClassName, "toJSONArray", returnObj);
174
175 jsonArray = (JSONArray)MethodInvoker.invoke(
176 methodWrapper, false);
177 }
178
179 return jsonArray.toString();
180 }
181 else if (returnObj instanceof JSONArray) {
182 JSONArray jsonArray = (JSONArray)returnObj;
183
184 return jsonArray.toString();
185 }
186 else if (returnObj instanceof JSONObject) {
187 JSONObject jsonObj = (JSONObject)returnObj;
188
189 return jsonObj.toString();
190 }
191 else if (returnObj instanceof Boolean ||
192 returnObj instanceof Double ||
193 returnObj instanceof Integer ||
194 returnObj instanceof Long ||
195 returnObj instanceof Short ||
196 returnObj instanceof String) {
197
198 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
199
200 jsonObj.put("returnValue", returnObj.toString());
201
202 return jsonObj.toString();
203 }
204 else {
205 String returnValue = getReturnValue(returnObj);
206
207 if (returnValue == null) {
208 _log.error(
209 "Unsupported return type for class " +
210 classObj + " and method " + methodName);
211 }
212
213 return returnValue;
214 }
215 }
216 else {
217 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
218
219 return jsonObj.toString();
220 }
221 }
222 catch (Exception e) {
223 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
224
225 if (e instanceof InvocationTargetException) {
226 jsonObj.put("exception", e.getCause().toString());
227 }
228 else {
229 jsonObj.put("exception", e.getMessage());
230 }
231
232 return jsonObj.toString();
233 }
234 }
235
236 return null;
237 }
238
239 protected Object getArgValue(
240 HttpServletRequest request, Class<?> classObj, String methodName,
241 String parameter, Class<?> parameterType)
242 throws Exception {
243
244 String parameterTypeName = parameterType.getName();
245
246 String value = ParamUtil.getString(request, parameter);
247
248 if (Validator.isNull(value) &&
249 !parameterTypeName.equals("[Ljava.lang.String;")) {
250
251 return null;
252 }
253 else if (parameterTypeName.equals("boolean") ||
254 parameterTypeName.equals(Boolean.class.getName())) {
255
256 return Boolean.valueOf(ParamUtil.getBoolean(request, parameter));
257 }
258 else if (parameterTypeName.equals("double") ||
259 parameterTypeName.equals(Double.class.getName())) {
260
261 return new Double(ParamUtil.getDouble(request, parameter));
262 }
263 else if (parameterTypeName.equals("int") ||
264 parameterTypeName.equals(Integer.class.getName())) {
265
266 return new Integer(ParamUtil.getInteger(request, parameter));
267 }
268 else if (parameterTypeName.equals("long") ||
269 parameterTypeName.equals(Long.class.getName())) {
270
271 return new Long(ParamUtil.getLong(request, parameter));
272 }
273 else if (parameterTypeName.equals("short") ||
274 parameterTypeName.equals(Short.class.getName())) {
275
276 return new Short(ParamUtil.getShort(request, parameter));
277 }
278 else if (parameterTypeName.equals(Date.class.getName())) {
279 return new Date(ParamUtil.getLong(request, parameter));
280 }
281 else if (parameterTypeName.equals(String.class.getName())) {
282 return value;
283 }
284 else if (parameterTypeName.equals("[Ljava.lang.String;")) {
285 return StringUtil.split(value);
286 }
287 else if (parameterTypeName.equals("[Z")) {
288 return ParamUtil.getBooleanValues(request, parameter);
289 }
290 else if (parameterTypeName.equals("[D")) {
291 return ParamUtil.getDoubleValues(request, parameter);
292 }
293 else if (parameterTypeName.equals("[F")) {
294 return ParamUtil.getFloatValues(request, parameter);
295 }
296 else if (parameterTypeName.equals("[I")) {
297 return ParamUtil.getIntegerValues(request, parameter);
298 }
299 else if (parameterTypeName.equals("[J")) {
300 return ParamUtil.getLongValues(request, parameter);
301 }
302 else if (parameterTypeName.equals("[S")) {
303 return ParamUtil.getShortValues(request, parameter);
304 }
305 else {
306 _log.error(
307 "Unsupported parameter type for class " + classObj +
308 ", method " + methodName + ", parameter " + parameter +
309 ", and type " + parameterTypeName);
310
311 return null;
312 }
313 }
314
315 protected Object[] getMethodAndParameterTypes(
316 Class<?> classObj, String methodName, String[] parameters,
317 String[] parameterTypes)
318 throws Exception {
319
320 String parameterNames = StringUtil.merge(parameters);
321
322 String key =
323 classObj.getName() + "_METHOD_NAME_" + methodName +
324 "_PARAMETERS_" + parameterNames;
325
326 Object[] methodAndParameterTypes = _methodCache.get(key);
327
328 if (methodAndParameterTypes != null) {
329 return methodAndParameterTypes;
330 }
331
332 Method method = null;
333 Class<?>[] methodParameterTypes = null;
334
335 Method[] methods = classObj.getMethods();
336
337 for (int i = 0; i < methods.length; i++) {
338 Method curMethod = methods[i];
339
340 if (curMethod.getName().equals(methodName)) {
341 Class<?>[] curParameterTypes = curMethod.getParameterTypes();
342
343 if (curParameterTypes.length == parameters.length) {
344 if ((parameterTypes.length > 0) &&
345 (parameterTypes.length == curParameterTypes.length)) {
346
347 boolean match = true;
348
349 for (int j = 0; j < parameterTypes.length; j++) {
350 String t1 = parameterTypes[j];
351 String t2 = curParameterTypes[j].getName();
352
353 if (!t1.equals(t2)) {
354 match = false;
355 }
356 }
357
358 if (match) {
359 method = curMethod;
360 methodParameterTypes = curParameterTypes;
361
362 break;
363 }
364 }
365 else if (method != null) {
366 _log.error(
367 "Obscure method name for class " + classObj +
368 ", method " + methodName + ", and parameters " +
369 parameterNames);
370
371 return null;
372 }
373 else {
374 method = curMethod;
375 methodParameterTypes = curParameterTypes;
376 }
377 }
378 }
379 }
380
381 if (method != null) {
382 methodAndParameterTypes =
383 new Object[] {method, methodParameterTypes};
384
385 _methodCache.put(key, methodAndParameterTypes);
386
387 return methodAndParameterTypes;
388 }
389 else {
390 _log.error(
391 "No method found for class " + classObj + ", method " +
392 methodName + ", and parameters " + parameterNames);
393
394 return null;
395 }
396 }
397
398 protected String getReturnValue(Object returnObj) throws Exception {
399 if (returnObj instanceof TagsAssetDisplay) {
400 return getReturnValue((TagsAssetDisplay)returnObj);
401 }
402 else if (returnObj instanceof TagsAssetDisplay[]) {
403 return getReturnValue((TagsAssetDisplay[])returnObj);
404 }
405 else if (returnObj instanceof TagsAssetType) {
406 return getReturnValue((TagsAssetType)returnObj);
407 }
408 else if (returnObj instanceof TagsAssetType[]) {
409 return getReturnValue((TagsAssetType[])returnObj);
410 }
411 else {
412 return JSONFactoryUtil.serialize(returnObj);
413 }
414 }
415
416 protected String getReturnValue(TagsAssetDisplay assetDisplay)
417 throws Exception {
418
419 JSONObject jsonObj = toJSONObject(assetDisplay);
420
421 return jsonObj.toString();
422 }
423
424 protected String getReturnValue(TagsAssetDisplay[] assetDisplays)
425 throws Exception {
426
427 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
428
429 for (int i = 0; i < assetDisplays.length; i++) {
430 TagsAssetDisplay assetDisplay = assetDisplays[i];
431
432 jsonArray.put(toJSONObject(assetDisplay));
433 }
434
435 return jsonArray.toString();
436 }
437
438 protected String getReturnValue(TagsAssetType assetType)
439 throws Exception {
440
441 JSONObject jsonObj = toJSONObject(assetType);
442
443 return jsonObj.toString();
444 }
445
446 protected String getReturnValue(TagsAssetType[] assetTypes)
447 throws Exception {
448
449 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
450
451 for (int i = 0; i < assetTypes.length; i++) {
452 TagsAssetType assetType = assetTypes[i];
453
454 jsonArray.put(toJSONObject(assetType));
455 }
456
457 return jsonArray.toString();
458 }
459
460 protected String getSerializerClassName(Object obj) {
461 String serlializerClassName = StringUtil.replace(
462 obj.getClass().getName(),
463 new String[] {".model.impl.", "Impl"},
464 new String[] {".service.http.", "JSONSerializer"});
465
466 return serlializerClassName;
467 }
468
469 protected boolean isValidRequest(HttpServletRequest request) {
470 String className = ParamUtil.getString(request, "serviceClassName");
471
472 if (className.contains(".service.") &&
473 className.endsWith("ServiceUtil") &&
474 !className.endsWith("LocalServiceUtil")) {
475
476 return true;
477 }
478 else {
479 return false;
480 }
481 }
482
483 private static Log _log = LogFactoryUtil.getLog(JSONServiceAction.class);
484
485 private Map<String, Object[]> _methodCache =
486 new HashMap<String, Object[]>();
487
488 }