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.util.ParamUtil;
29 import com.liferay.portal.kernel.util.StringUtil;
30 import com.liferay.portal.struts.JSONAction;
31 import com.liferay.portlet.tags.model.TagsAssetDisplay;
32 import com.liferay.portlet.tags.model.TagsAssetType;
33
34 import java.lang.reflect.InvocationTargetException;
35 import java.lang.reflect.Method;
36
37 import java.util.Date;
38 import java.util.HashMap;
39 import java.util.Map;
40
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46 import org.apache.struts.action.ActionForm;
47 import org.apache.struts.action.ActionMapping;
48
49
55 public class JSONServiceAction extends JSONAction {
56
57 public static JSONObject toJSONObject(TagsAssetDisplay assetDisplay) {
58 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
59
60 jsonObj.put("assetId", assetDisplay.getAssetId());
61 jsonObj.put("companyId", assetDisplay.getCompanyId());
62 jsonObj.put("userId", assetDisplay.getUserId());
63 jsonObj.put("userName", assetDisplay.getUserName());
64 jsonObj.put("createDate", assetDisplay.getCreateDate());
65 jsonObj.put("modifiedDate", assetDisplay.getModifiedDate());
66 jsonObj.put("classNameId", assetDisplay.getClassNameId());
67 jsonObj.put("className", assetDisplay.getClassName());
68 jsonObj.put("classPK", assetDisplay.getClassPK());
69 jsonObj.put("portletId", assetDisplay.getPortletId());
70 jsonObj.put("portletTitle", assetDisplay.getPortletTitle());
71 jsonObj.put("startDate", assetDisplay.getStartDate());
72 jsonObj.put("endDate", assetDisplay.getEndDate());
73 jsonObj.put("publishDate", assetDisplay.getPublishDate());
74 jsonObj.put("expirationDate", assetDisplay.getExpirationDate());
75 jsonObj.put("mimeType", assetDisplay.getMimeType());
76 jsonObj.put("title", assetDisplay.getTitle());
77 jsonObj.put("description", assetDisplay.getDescription());
78 jsonObj.put("summary", assetDisplay.getSummary());
79 jsonObj.put("url", assetDisplay.getUrl());
80 jsonObj.put("height", assetDisplay.getHeight());
81 jsonObj.put("width", assetDisplay.getWidth());
82 jsonObj.put("priority", assetDisplay.getPriority());
83 jsonObj.put("viewCount", assetDisplay.getViewCount());
84 jsonObj.put("tagsEntries", assetDisplay.getTagsEntries());
85
86 return jsonObj;
87 }
88
89 public static JSONObject toJSONObject(TagsAssetType assetType) {
90 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
91
92 jsonObj.put("classNameId", assetType.getClassNameId());
93 jsonObj.put("className", assetType.getClassName());
94 jsonObj.put("portletId", assetType.getPortletId());
95 jsonObj.put("portletTitle", assetType.getPortletTitle());
96
97 return jsonObj;
98 }
99
100 public String getJSON(
101 ActionMapping mapping, ActionForm form, HttpServletRequest request,
102 HttpServletResponse response)
103 throws Exception {
104
105 String className = ParamUtil.getString(request, "serviceClassName");
106 String methodName = ParamUtil.getString(request, "serviceMethodName");
107 String[] serviceParameters = StringUtil.split(
108 ParamUtil.getString(request, "serviceParameters"));
109 String[] serviceParameterTypes = StringUtil.split(
110 ParamUtil.getString(request, "serviceParameterTypes"));
111
112 if (!isValidRequest(request)) {
113 return null;
114 }
115
116 Class<?> classObj = Class.forName(className);
117
118 Object[] methodAndParameterTypes = getMethodAndParameterTypes(
119 classObj, methodName, serviceParameters, serviceParameterTypes);
120
121 if (methodAndParameterTypes != null) {
122 Method method = (Method)methodAndParameterTypes[0];
123 Class<?>[] parameterTypes = (Class[])methodAndParameterTypes[1];
124 Object[] args = new Object[serviceParameters.length];
125
126 for (int i = 0; i < serviceParameters.length; i++) {
127 args[i] = getArgValue(
128 request, classObj, methodName, serviceParameters[i],
129 parameterTypes[i]);
130
131 if (args[i] == null) {
132 return null;
133 }
134 }
135
136 try {
137 if (_log.isDebugEnabled()) {
138 _log.debug(
139 "Invoking class " + classObj + " on method " +
140 method.getName() + " with args " + args);
141 }
142
143 Object returnObj = method.invoke(classObj, args);
144
145 if (returnObj != null) {
146 if (returnObj instanceof JSONArray) {
147 JSONArray jsonArray = (JSONArray)returnObj;
148
149 return jsonArray.toString();
150 }
151 else if (returnObj instanceof JSONObject) {
152 JSONObject jsonObj = (JSONObject)returnObj;
153
154 return jsonObj.toString();
155 }
156 else if (returnObj instanceof Boolean ||
157 returnObj instanceof Double ||
158 returnObj instanceof Integer ||
159 returnObj instanceof Long ||
160 returnObj instanceof Short ||
161 returnObj instanceof String) {
162
163 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
164
165 jsonObj.put("returnValue", returnObj.toString());
166
167 return jsonObj.toString();
168 }
169 else {
170 String returnValue = getReturnValue(returnObj);
171
172 if (returnValue == null) {
173 _log.error(
174 "Unsupported return type for class " +
175 classObj + " and method " + methodName);
176 }
177
178 return returnValue;
179 }
180 }
181 else {
182 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
183
184 return jsonObj.toString();
185 }
186 }
187 catch (InvocationTargetException ite) {
188 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
189
190 jsonObj.put("exception", ite.getCause().toString());
191
192 return jsonObj.toString();
193 }
194 }
195
196 return null;
197 }
198
199 protected Object getArgValue(
200 HttpServletRequest request, Class<?> classObj, String methodName,
201 String parameter, Class<?> parameterType)
202 throws Exception {
203
204 String parameterTypeName = parameterType.getName();
205
206 if (parameterTypeName.equals("boolean") ||
207 parameterTypeName.equals(Boolean.class.getName())) {
208
209 return Boolean.valueOf(ParamUtil.getBoolean(request, parameter));
210 }
211 else if (parameterTypeName.equals("double") ||
212 parameterTypeName.equals(Double.class.getName())) {
213
214 return new Double(ParamUtil.getDouble(request, parameter));
215 }
216 else if (parameterTypeName.equals("int") ||
217 parameterTypeName.equals(Integer.class.getName())) {
218
219 return new Integer(ParamUtil.getInteger(request, parameter));
220 }
221 else if (parameterTypeName.equals("long") ||
222 parameterTypeName.equals(Long.class.getName())) {
223
224 return new Long(ParamUtil.getLong(request, parameter));
225 }
226 else if (parameterTypeName.equals("short") ||
227 parameterTypeName.equals(Short.class.getName())) {
228
229 return new Short(ParamUtil.getShort(request, parameter));
230 }
231 else if (parameterTypeName.equals(Date.class.getName())) {
232 return new Date(ParamUtil.getLong(request, parameter));
233 }
234 else if (parameterTypeName.equals(String.class.getName())) {
235 return ParamUtil.getString(request, parameter);
236 }
237 else if (parameterTypeName.equals("[Ljava.lang.String;")) {
238 return StringUtil.split(ParamUtil.getString(request, parameter));
239 }
240 else {
241 _log.error(
242 "Unsupported parameter type for class " + classObj +
243 ", method " + methodName + ", parameter " + parameter +
244 ", and type " + parameterTypeName);
245
246 return null;
247 }
248 }
249
250 protected Object[] getMethodAndParameterTypes(
251 Class<?> classObj, String methodName, String[] parameters,
252 String[] parameterTypes)
253 throws Exception {
254
255 String parameterNames = StringUtil.merge(parameters);
256
257 String key =
258 classObj.getName() + "_METHOD_NAME_" + methodName +
259 "_PARAMETERS_" + parameterNames;
260
261 Object[] methodAndParameterTypes = _methodCache.get(key);
262
263 if (methodAndParameterTypes != null) {
264 return methodAndParameterTypes;
265 }
266
267 Method method = null;
268 Class<?>[] methodParameterTypes = null;
269
270 Method[] methods = classObj.getMethods();
271
272 for (int i = 0; i < methods.length; i++) {
273 Method curMethod = methods[i];
274
275 if (curMethod.getName().equals(methodName)) {
276 Class<?>[] curParameterTypes = curMethod.getParameterTypes();
277
278 if (curParameterTypes.length == parameters.length) {
279 if ((parameterTypes.length > 0) &&
280 (parameterTypes.length == curParameterTypes.length)) {
281
282 boolean match = true;
283
284 for (int j = 0; j < parameterTypes.length; j++) {
285 String t1 = parameterTypes[j];
286 String t2 = curParameterTypes[j].getName();
287
288 if (!t1.equals(t2)) {
289 match = false;
290 }
291 }
292
293 if (match) {
294 method = curMethod;
295 methodParameterTypes = curParameterTypes;
296
297 break;
298 }
299 }
300 else if (method != null) {
301 _log.error(
302 "Obscure method name for class " + classObj +
303 ", method " + methodName + ", and parameters " +
304 parameterNames);
305
306 return null;
307 }
308 else {
309 method = curMethod;
310 methodParameterTypes = curParameterTypes;
311 }
312 }
313 }
314 }
315
316 if (method != null) {
317 methodAndParameterTypes =
318 new Object[] {method, methodParameterTypes};
319
320 _methodCache.put(key, methodAndParameterTypes);
321
322 return methodAndParameterTypes;
323 }
324 else {
325 _log.error(
326 "No method found for class " + classObj + ", method " +
327 methodName + ", and parameters " + parameterNames);
328
329 return null;
330 }
331 }
332
333 protected String getReturnValue(Object returnObj) throws Exception {
334 if (returnObj instanceof TagsAssetDisplay) {
335 return getReturnValue((TagsAssetDisplay)returnObj);
336 }
337 else if (returnObj instanceof TagsAssetDisplay[]) {
338 return getReturnValue((TagsAssetDisplay[])returnObj);
339 }
340 else if (returnObj instanceof TagsAssetType) {
341 return getReturnValue((TagsAssetType)returnObj);
342 }
343 else if (returnObj instanceof TagsAssetType[]) {
344 return getReturnValue((TagsAssetType[])returnObj);
345 }
346
347 return null;
348 }
349
350 protected String getReturnValue(TagsAssetDisplay assetDisplay)
351 throws Exception {
352
353 JSONObject jsonObj = toJSONObject(assetDisplay);
354
355 return jsonObj.toString();
356 }
357
358 protected String getReturnValue(TagsAssetDisplay[] assetDisplays)
359 throws Exception {
360
361 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
362
363 for (int i = 0; i < assetDisplays.length; i++) {
364 TagsAssetDisplay assetDisplay = assetDisplays[i];
365
366 jsonArray.put(toJSONObject(assetDisplay));
367 }
368
369 return jsonArray.toString();
370 }
371
372 protected String getReturnValue(TagsAssetType assetType)
373 throws Exception {
374
375 JSONObject jsonObj = toJSONObject(assetType);
376
377 return jsonObj.toString();
378 }
379
380 protected String getReturnValue(TagsAssetType[] assetTypes)
381 throws Exception {
382
383 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
384
385 for (int i = 0; i < assetTypes.length; i++) {
386 TagsAssetType assetType = assetTypes[i];
387
388 jsonArray.put(toJSONObject(assetType));
389 }
390
391 return jsonArray.toString();
392 }
393
394 protected boolean isValidRequest(HttpServletRequest request) {
395 String className = ParamUtil.getString(request, "serviceClassName");
396
397 if (className.contains(".service.http.") &&
398 className.endsWith("ServiceJSON")) {
399
400 return true;
401 }
402 else {
403 return false;
404 }
405 }
406
407 private static Log _log = LogFactory.getLog(JSONServiceAction.class);
408
409 private Map<String, Object[]> _methodCache =
410 new HashMap<String, Object[]>();
411
412 }