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