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.ParamUtil;
31 import com.liferay.portal.kernel.util.StringUtil;
32 import com.liferay.portal.kernel.util.Validator;
33 import com.liferay.portal.service.ServiceContext;
34 import com.liferay.portal.service.ServiceContextUtil;
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.Date;
43 import java.util.HashMap;
44 import java.util.Map;
45
46 import javax.servlet.http.HttpServletRequest;
47 import javax.servlet.http.HttpServletResponse;
48
49 import org.apache.struts.action.ActionForm;
50 import org.apache.struts.action.ActionMapping;
51
52
59 public class JSONServiceAction extends JSONAction {
60
61 public static JSONObject toJSONObject(TagsAssetDisplay assetDisplay) {
62 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
63
64 jsonObj.put("assetId", assetDisplay.getAssetId());
65 jsonObj.put("companyId", assetDisplay.getCompanyId());
66 jsonObj.put("userId", assetDisplay.getUserId());
67 jsonObj.put("userName", assetDisplay.getUserName());
68 jsonObj.put("createDate", assetDisplay.getCreateDate());
69 jsonObj.put("modifiedDate", assetDisplay.getModifiedDate());
70 jsonObj.put("classNameId", assetDisplay.getClassNameId());
71 jsonObj.put("className", assetDisplay.getClassName());
72 jsonObj.put("classPK", assetDisplay.getClassPK());
73 jsonObj.put("portletId", assetDisplay.getPortletId());
74 jsonObj.put("portletTitle", assetDisplay.getPortletTitle());
75 jsonObj.put("startDate", assetDisplay.getStartDate());
76 jsonObj.put("endDate", assetDisplay.getEndDate());
77 jsonObj.put("publishDate", assetDisplay.getPublishDate());
78 jsonObj.put("expirationDate", assetDisplay.getExpirationDate());
79 jsonObj.put("mimeType", assetDisplay.getMimeType());
80 jsonObj.put("title", assetDisplay.getTitle());
81 jsonObj.put("description", assetDisplay.getDescription());
82 jsonObj.put("summary", assetDisplay.getSummary());
83 jsonObj.put("url", assetDisplay.getUrl());
84 jsonObj.put("height", assetDisplay.getHeight());
85 jsonObj.put("width", assetDisplay.getWidth());
86 jsonObj.put("priority", assetDisplay.getPriority());
87 jsonObj.put("viewCount", assetDisplay.getViewCount());
88 jsonObj.put("tagsEntries", assetDisplay.getTagsEntries());
89
90 return jsonObj;
91 }
92
93 public static JSONObject toJSONObject(TagsAssetType assetType) {
94 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
95
96 jsonObj.put("classNameId", assetType.getClassNameId());
97 jsonObj.put("className", assetType.getClassName());
98 jsonObj.put("portletId", assetType.getPortletId());
99 jsonObj.put("portletTitle", assetType.getPortletTitle());
100
101 return jsonObj;
102 }
103
104 public String getJSON(
105 ActionMapping mapping, ActionForm form, HttpServletRequest request,
106 HttpServletResponse response)
107 throws Exception {
108
109 String className = ParamUtil.getString(request, "serviceClassName");
110 String methodName = ParamUtil.getString(request, "serviceMethodName");
111 String[] serviceParameters = StringUtil.split(
112 ParamUtil.getString(request, "serviceParameters"));
113 String[] serviceParameterTypes = StringUtil.split(
114 ParamUtil.getString(request, "serviceParameterTypes"));
115
116 if (!isValidRequest(request)) {
117 return null;
118 }
119
120 Class<?> classObj = Class.forName(className);
121
122 Object[] methodAndParameterTypes = getMethodAndParameterTypes(
123 classObj, methodName, serviceParameters, serviceParameterTypes);
124
125 if (methodAndParameterTypes != null) {
126 Method method = (Method)methodAndParameterTypes[0];
127 Class<?>[] parameterTypes = (Class[])methodAndParameterTypes[1];
128 Object[] args = new Object[serviceParameters.length];
129
130 for (int i = 0; i < serviceParameters.length; i++) {
131 args[i] = getArgValue(
132 request, classObj, methodName, serviceParameters[i],
133 parameterTypes[i]);
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 String value = ParamUtil.getString(request, parameter);
207
208 if (Validator.isNull(value) &&
209 !parameterTypeName.equals("[Ljava.lang.String;")) {
210
211 return null;
212 }
213 else if (parameterTypeName.equals("boolean") ||
214 parameterTypeName.equals(Boolean.class.getName())) {
215
216 return Boolean.valueOf(ParamUtil.getBoolean(request, parameter));
217 }
218 else if (parameterTypeName.equals("double") ||
219 parameterTypeName.equals(Double.class.getName())) {
220
221 return new Double(ParamUtil.getDouble(request, parameter));
222 }
223 else if (parameterTypeName.equals("int") ||
224 parameterTypeName.equals(Integer.class.getName())) {
225
226 return new Integer(ParamUtil.getInteger(request, parameter));
227 }
228 else if (parameterTypeName.equals("long") ||
229 parameterTypeName.equals(Long.class.getName())) {
230
231 return new Long(ParamUtil.getLong(request, parameter));
232 }
233 else if (parameterTypeName.equals("short") ||
234 parameterTypeName.equals(Short.class.getName())) {
235
236 return new Short(ParamUtil.getShort(request, parameter));
237 }
238 else if (parameterTypeName.equals(Date.class.getName())) {
239 return new Date(ParamUtil.getLong(request, parameter));
240 }
241 else if (parameterTypeName.equals(ServiceContext.class.getName())) {
242 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(value);
243
244 jsonObject.put("javaClass", ServiceContext.class.getName());
245
246 return ServiceContextUtil.deserialize(jsonObject);
247 }
248 else if (parameterTypeName.equals(String.class.getName())) {
249 return value;
250 }
251 else if (parameterTypeName.equals("[Ljava.lang.String;")) {
252 return StringUtil.split(value);
253 }
254 else {
255 _log.error(
256 "Unsupported parameter type for class " + classObj +
257 ", method " + methodName + ", parameter " + parameter +
258 ", and type " + parameterTypeName);
259
260 return null;
261 }
262 }
263
264 protected Object[] getMethodAndParameterTypes(
265 Class<?> classObj, String methodName, String[] parameters,
266 String[] parameterTypes)
267 throws Exception {
268
269 String parameterNames = StringUtil.merge(parameters);
270
271 String key =
272 classObj.getName() + "_METHOD_NAME_" + methodName +
273 "_PARAMETERS_" + parameterNames;
274
275 Object[] methodAndParameterTypes = _methodCache.get(key);
276
277 if (methodAndParameterTypes != null) {
278 return methodAndParameterTypes;
279 }
280
281 Method method = null;
282 Class<?>[] methodParameterTypes = null;
283
284 Method[] methods = classObj.getMethods();
285
286 for (int i = 0; i < methods.length; i++) {
287 Method curMethod = methods[i];
288
289 if (curMethod.getName().equals(methodName)) {
290 Class<?>[] curParameterTypes = curMethod.getParameterTypes();
291
292 if (curParameterTypes.length == parameters.length) {
293 if ((parameterTypes.length > 0) &&
294 (parameterTypes.length == curParameterTypes.length)) {
295
296 boolean match = true;
297
298 for (int j = 0; j < parameterTypes.length; j++) {
299 String t1 = parameterTypes[j];
300 String t2 = curParameterTypes[j].getName();
301
302 if (!t1.equals(t2)) {
303 match = false;
304 }
305 }
306
307 if (match) {
308 method = curMethod;
309 methodParameterTypes = curParameterTypes;
310
311 break;
312 }
313 }
314 else if (method != null) {
315 _log.error(
316 "Obscure method name for class " + classObj +
317 ", method " + methodName + ", and parameters " +
318 parameterNames);
319
320 return null;
321 }
322 else {
323 method = curMethod;
324 methodParameterTypes = curParameterTypes;
325 }
326 }
327 }
328 }
329
330 if (method != null) {
331 methodAndParameterTypes =
332 new Object[] {method, methodParameterTypes};
333
334 _methodCache.put(key, methodAndParameterTypes);
335
336 return methodAndParameterTypes;
337 }
338 else {
339 _log.error(
340 "No method found for class " + classObj + ", method " +
341 methodName + ", and parameters " + parameterNames);
342
343 return null;
344 }
345 }
346
347 protected String getReturnValue(Object returnObj) throws Exception {
348 if (returnObj instanceof TagsAssetDisplay) {
349 return getReturnValue((TagsAssetDisplay)returnObj);
350 }
351 else if (returnObj instanceof TagsAssetDisplay[]) {
352 return getReturnValue((TagsAssetDisplay[])returnObj);
353 }
354 else if (returnObj instanceof TagsAssetType) {
355 return getReturnValue((TagsAssetType)returnObj);
356 }
357 else if (returnObj instanceof TagsAssetType[]) {
358 return getReturnValue((TagsAssetType[])returnObj);
359 }
360
361 return null;
362 }
363
364 protected String getReturnValue(TagsAssetDisplay assetDisplay)
365 throws Exception {
366
367 JSONObject jsonObj = toJSONObject(assetDisplay);
368
369 return jsonObj.toString();
370 }
371
372 protected String getReturnValue(TagsAssetDisplay[] assetDisplays)
373 throws Exception {
374
375 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
376
377 for (int i = 0; i < assetDisplays.length; i++) {
378 TagsAssetDisplay assetDisplay = assetDisplays[i];
379
380 jsonArray.put(toJSONObject(assetDisplay));
381 }
382
383 return jsonArray.toString();
384 }
385
386 protected String getReturnValue(TagsAssetType assetType)
387 throws Exception {
388
389 JSONObject jsonObj = toJSONObject(assetType);
390
391 return jsonObj.toString();
392 }
393
394 protected String getReturnValue(TagsAssetType[] assetTypes)
395 throws Exception {
396
397 JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
398
399 for (int i = 0; i < assetTypes.length; i++) {
400 TagsAssetType assetType = assetTypes[i];
401
402 jsonArray.put(toJSONObject(assetType));
403 }
404
405 return jsonArray.toString();
406 }
407
408 protected boolean isValidRequest(HttpServletRequest request) {
409 String className = ParamUtil.getString(request, "serviceClassName");
410
411 if (className.contains(".service.http.") &&
412 className.endsWith("ServiceJSON")) {
413
414 return true;
415 }
416 else {
417 return false;
418 }
419 }
420
421 private static Log _log = LogFactoryUtil.getLog(JSONServiceAction.class);
422
423 private Map<String, Object[]> _methodCache =
424 new HashMap<String, Object[]>();
425
426 }