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 Object value =
156 _jsonWebServiceActionParameters.getParameter(parameterName);
157
158 Object parameterValue = null;
159
160 if (value != null) {
161 Class<?> parameterType = methodParameters[i].getType();
162
163 if (value.equals(Void.TYPE)) {
164 String parameterTypeName =
165 _jsonWebServiceActionParameters.getParameterTypeName(
166 parameterName);
167
168 if (parameterTypeName != null) {
169 ClassLoader classLoader = actionClass.getClassLoader();
170
171 parameterType = classLoader.loadClass(
172 parameterTypeName);
173 }
174
175 parameterValue = _createDefaultParameterValue(
176 parameterName, parameterType);
177 }
178 else if (parameterType.equals(Calendar.class)) {
179 Calendar calendar = Calendar.getInstance();
180
181 calendar.setLenient(false);
182 calendar.setTimeInMillis(Long.parseLong(value.toString()));
183
184 parameterValue = calendar;
185 }
186 else if (parameterType.equals(List.class)) {
187 List<?> list = JSONFactoryUtil.looseDeserialize(
188 value.toString(), ArrayList.class);
189
190 list = _generifyList(
191 list, methodParameters[i].getGenericTypes());
192
193 parameterValue = list;
194 }
195 else if (parameterType.equals(Locale.class)) {
196 parameterValue = LocaleUtil.fromLanguageId(
197 value.toString());
198 }
199 else if (parameterType.equals(Map.class)) {
200 Map<?, ?> map = JSONFactoryUtil.looseDeserialize(
201 value.toString(), HashMap.class);
202
203 map = _generifyMap(
204 map, methodParameters[i].getGenericTypes());
205
206 parameterValue = map;
207 }
208 else {
209 parameterValue = ReflectUtil.castType(value, parameterType);
210 }
211 }
212
213 if (parameterValue != null) {
214 List<KeyValue<String, Object>> innerParameters =
215 _jsonWebServiceActionParameters.getInnerParameters(
216 parameterName);
217
218 if (innerParameters != null) {
219 for (KeyValue<String, Object> innerParameter :
220 innerParameters) {
221
222 BeanUtil.setPropertySilent(
223 parameterValue, innerParameter.getKey(),
224 innerParameter.getValue());
225 }
226 }
227 }
228
229 parameters[i] = parameterValue;
230 }
231
232 return parameters;
233 }
234
235 private static Log _log = LogFactoryUtil.getLog(
236 JSONWebServiceActionImpl.class);
237
238 private JSONWebServiceActionConfig _jsonWebServiceActionConfig;
239 private JSONWebServiceActionParameters _jsonWebServiceActionParameters;
240
241 }