001
014
015 package com.liferay.portal.jsonwebservice;
016
017 import com.liferay.portal.kernel.json.JSONFactoryUtil;
018 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceAction;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.LocaleUtil;
022 import com.liferay.portal.kernel.util.MethodParameter;
023 import com.liferay.portal.service.ServiceContext;
024
025 import java.lang.reflect.Method;
026
027 import java.util.ArrayList;
028 import java.util.Calendar;
029 import java.util.HashMap;
030 import java.util.List;
031 import java.util.Locale;
032 import java.util.Map;
033
034 import jodd.bean.BeanUtil;
035
036 import jodd.util.KeyValue;
037 import jodd.util.ReflectUtil;
038
039
042 public class JSONWebServiceActionImpl implements JSONWebServiceAction {
043
044 public JSONWebServiceActionImpl(
045 JSONWebServiceActionConfig jsonWebServiceActionConfig,
046 JSONWebServiceActionParameters jsonWebServiceActionParameters) {
047
048 _jsonWebServiceActionConfig = jsonWebServiceActionConfig;
049 _jsonWebServiceActionParameters = jsonWebServiceActionParameters;
050 }
051
052 public Object invoke() throws Exception {
053 JSONRPCRequest jsonRpcRequest =
054 _jsonWebServiceActionParameters.getJSONRPCRequest();
055
056 if (jsonRpcRequest == null) {
057 return _invokeActionMethod();
058 }
059
060 Object result = null;
061 Exception exception = null;
062
063 try {
064 result = _invokeActionMethod();
065 }
066 catch (Exception e) {
067 exception = e;
068
069 _log.error(e, e);
070 }
071
072 return new JSONRPCResponse(jsonRpcRequest, result, exception);
073 }
074
075 private Object _createDefaultParameterValue(
076 String parameterName, Class<?> parameterType)
077 throws Exception {
078
079 if (parameterName.equals("serviceContext") &&
080 parameterType.equals(ServiceContext.class)) {
081
082 return new ServiceContext();
083 }
084
085 return parameterType.newInstance();
086 }
087
088 private List<?> _generifyList(List<?> list, Class<?>[] types) {
089 if (types == null) {
090 return list;
091 }
092
093 if (types.length != 1) {
094 return list;
095 }
096
097 List<Object> newList = new ArrayList<Object>(list.size());
098
099 for (Object entry : list) {
100 if (entry != null) {
101 entry = ReflectUtil.castType(entry, types[0]);
102 }
103
104 newList.add(entry);
105 }
106
107 return newList;
108 }
109
110 private Map<?, ?> _generifyMap(Map<?, ?> map, Class<?>[] types) {
111 if (types == null) {
112 return map;
113 }
114
115 if (types.length != 2) {
116 return map;
117 }
118
119 Map<Object, Object> newMap = new HashMap<Object, Object>(map.size());
120
121 for (Map.Entry<?, ?> entry : map.entrySet()) {
122 Object key = ReflectUtil.castType(entry.getKey(), types[0]);
123
124 Object value = entry.getValue();
125
126 if (value != null) {
127 value = ReflectUtil.castType(value, types[1]);
128 }
129
130 newMap.put(key, value);
131 }
132
133 return newMap;
134 }
135
136 private Object _invokeActionMethod() throws Exception {
137 Method actionMethod = _jsonWebServiceActionConfig.getActionMethod();
138
139 Class<?> actionClass = _jsonWebServiceActionConfig.getActionClass();
140
141 Object[] parameters = _prepareParameters(actionClass);
142
143 return actionMethod.invoke(actionClass, parameters);
144 }
145
146 private Object[] _prepareParameters(Class<?> actionClass) throws Exception {
147 MethodParameter[] methodParameters =
148 _jsonWebServiceActionConfig.getMethodParameters();
149
150 Object[] parameters = new Object[methodParameters.length];
151
152 for (int i = 0; i < methodParameters.length; i++) {
153 String parameterName = methodParameters[i].getName();
154
155 parameterName = CamelCaseUtil.normalizeCamelCase(parameterName);
156
157 Object value = _jsonWebServiceActionParameters.getParameter(
158 parameterName);
159
160 Object parameterValue = null;
161
162 if (value != null) {
163 Class<?> parameterType = methodParameters[i].getType();
164
165 if (value.equals(Void.TYPE)) {
166 String parameterTypeName =
167 _jsonWebServiceActionParameters.getParameterTypeName(
168 parameterName);
169
170 if (parameterTypeName != null) {
171 ClassLoader classLoader = actionClass.getClassLoader();
172
173 parameterType = classLoader.loadClass(
174 parameterTypeName);
175 }
176
177 parameterValue = _createDefaultParameterValue(
178 parameterName, parameterType);
179 }
180 else if (parameterType.equals(Calendar.class)) {
181 Calendar calendar = Calendar.getInstance();
182
183 calendar.setLenient(false);
184 calendar.setTimeInMillis(Long.parseLong(value.toString()));
185
186 parameterValue = calendar;
187 }
188 else if (parameterType.equals(List.class)) {
189 List<?> list = JSONFactoryUtil.looseDeserialize(
190 value.toString(), ArrayList.class);
191
192 list = _generifyList(
193 list, methodParameters[i].getGenericTypes());
194
195 parameterValue = list;
196 }
197 else if (parameterType.equals(Locale.class)) {
198 parameterValue = LocaleUtil.fromLanguageId(
199 value.toString());
200 }
201 else if (parameterType.equals(Map.class)) {
202 Map<?, ?> map = JSONFactoryUtil.looseDeserialize(
203 value.toString(), HashMap.class);
204
205 map = _generifyMap(
206 map, methodParameters[i].getGenericTypes());
207
208 parameterValue = map;
209 }
210 else {
211 parameterValue = ReflectUtil.castType(value, parameterType);
212 }
213 }
214
215 if (parameterValue != null) {
216 List<KeyValue<String, Object>> innerParameters =
217 _jsonWebServiceActionParameters.getInnerParameters(
218 parameterName);
219
220 if (innerParameters != null) {
221 for (KeyValue<String, Object> innerParameter :
222 innerParameters) {
223
224 BeanUtil.setPropertySilent(
225 parameterValue, innerParameter.getKey(),
226 innerParameter.getValue());
227 }
228 }
229 }
230
231 parameters[i] = parameterValue;
232 }
233
234 return parameters;
235 }
236
237 private static Log _log = LogFactoryUtil.getLog(
238 JSONWebServiceActionImpl.class);
239
240 private JSONWebServiceActionConfig _jsonWebServiceActionConfig;
241 private JSONWebServiceActionParameters _jsonWebServiceActionParameters;
242
243 }