001
014
015 package com.liferay.portal.jsonwebservice;
016
017 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceAction;
018 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionMapping;
019 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionsManager;
020 import com.liferay.portal.kernel.servlet.HttpMethods;
021 import com.liferay.portal.kernel.util.BinarySearch;
022 import com.liferay.portal.kernel.util.CharPool;
023 import com.liferay.portal.kernel.util.ContextPathUtil;
024 import com.liferay.portal.kernel.util.GetterUtil;
025 import com.liferay.portal.kernel.util.MethodParameter;
026 import com.liferay.portal.kernel.util.SortedArrayList;
027 import com.liferay.portal.kernel.util.StringPool;
028 import com.liferay.portal.util.PortalUtil;
029 import com.liferay.portal.util.PropsValues;
030
031 import java.lang.reflect.Method;
032
033 import java.util.ArrayList;
034 import java.util.Iterator;
035 import java.util.List;
036
037 import javax.servlet.ServletContext;
038 import javax.servlet.http.HttpServletRequest;
039 import javax.servlet.http.HttpSession;
040
041
044 public class JSONWebServiceActionsManagerImpl
045 implements JSONWebServiceActionsManager {
046
047 public JSONWebServiceAction getJSONWebServiceAction(
048 HttpServletRequest request) {
049
050 String path = GetterUtil.getString(request.getPathInfo());
051
052 String method = GetterUtil.getString(request.getMethod());
053
054 String pathParameters = null;
055
056 JSONRPCRequest jsonRpcRequest = null;
057
058 int pathParametersIndex = _getPathParametersIndex(path);
059
060 if (pathParametersIndex != -1) {
061 pathParameters = path.substring(pathParametersIndex);
062
063 path = path.substring(0, pathParametersIndex);
064 }
065 else {
066 if (method.equals(HttpMethods.POST) &&
067 !PortalUtil.isMultipartRequest(request)) {
068
069 jsonRpcRequest = JSONRPCRequest.detectJSONRPCRequest(request);
070
071 if (jsonRpcRequest != null) {
072 path += StringPool.SLASH + jsonRpcRequest.getMethod();
073
074 method = null;
075 }
076 }
077 }
078
079 JSONWebServiceActionParameters jsonWebServiceActionParameters =
080 new JSONWebServiceActionParameters();
081
082 jsonWebServiceActionParameters.collectAll(
083 request, pathParameters, jsonRpcRequest);
084
085 String[] parameterNames =
086 jsonWebServiceActionParameters.getParameterNames();
087
088 HttpSession session = request.getSession();
089
090 ServletContext servletContext = session.getServletContext();
091
092 String servletContextPath = ContextPathUtil.getContextPath(
093 servletContext);
094
095 int jsonWebServiceActionConfigIndex =
096 _getJSONWebServiceActionConfigIndex(
097 servletContextPath, path, method, parameterNames);
098
099 if (jsonWebServiceActionConfigIndex == -1) {
100 throw new RuntimeException(
101 "No JSON web service action associated with path " + path +
102 " and method " + method + " for /" + servletContextPath);
103 }
104
105 JSONWebServiceActionConfig jsonWebServiceActionConfig =
106 _jsonWebServiceActionConfigs.get(jsonWebServiceActionConfigIndex);
107
108 return new JSONWebServiceActionImpl(
109 jsonWebServiceActionConfig, jsonWebServiceActionParameters);
110 }
111
112 public JSONWebServiceActionMapping getJSONWebServiceActionMapping(
113 String signature) {
114
115 for (JSONWebServiceActionConfig jsonWebServiceActionConfig :
116 _jsonWebServiceActionConfigs) {
117
118 if (signature.equals(jsonWebServiceActionConfig.getSignature())) {
119 return jsonWebServiceActionConfig;
120 }
121 }
122
123 return null;
124 }
125
126 public List<JSONWebServiceActionMapping> getJSONWebServiceActionMappings(
127 String servletContextPath) {
128
129 List<JSONWebServiceActionMapping> jsonWebServiceActionMappings =
130 new ArrayList<JSONWebServiceActionMapping>(
131 _jsonWebServiceActionConfigs.size());
132
133 for (JSONWebServiceActionConfig jsonWebServiceActionConfig :
134 _jsonWebServiceActionConfigs) {
135
136 String jsonWebServiceServletContextPath =
137 jsonWebServiceActionConfig.getServletContextPath();
138
139 if (servletContextPath.equals(jsonWebServiceServletContextPath)) {
140 jsonWebServiceActionMappings.add(jsonWebServiceActionConfig);
141 }
142 }
143
144 return jsonWebServiceActionMappings;
145 }
146
147 public void registerJSONWebServiceAction(
148 String servletContextPath, Class<?> actionClass, Method actionMethod,
149 String path, String method) {
150
151 JSONWebServiceActionConfig jsonWebServiceActionConfig =
152 new JSONWebServiceActionConfig(
153 servletContextPath, actionClass, actionMethod, path, method);
154
155 _jsonWebServiceActionConfigs.add(jsonWebServiceActionConfig);
156 }
157
158 public int unregisterJSONWebServiceActions(String servletContextPath) {
159 int count = 0;
160
161 Iterator<JSONWebServiceActionConfig> itr =
162 _jsonWebServiceActionConfigs.iterator();
163
164 while (itr.hasNext()) {
165 JSONWebServiceActionConfig jsonWebServiceActionConfig = itr.next();
166
167 if (servletContextPath.equals(
168 jsonWebServiceActionConfig.getServletContextPath())) {
169
170 itr.remove();
171
172 count++;
173 }
174 }
175
176 return count;
177 }
178
179 private int _countMatchedElements(
180 String[] parameterNames, MethodParameter[] methodParameters) {
181
182 int matched = 0;
183
184 for (MethodParameter methodParameter : methodParameters) {
185 String methodParameterName = methodParameter.getName();
186
187 methodParameterName = CamelCaseUtil.normalizeCamelCase(
188 methodParameterName);
189
190 for (String parameterName : parameterNames) {
191 if (parameterName.equals(methodParameterName)) {
192 matched++;
193
194 break;
195 }
196 }
197 }
198
199 return matched;
200 }
201
202 private int _getJSONWebServiceActionConfigIndex(
203 String servletContextPath, String path, String method,
204 String[] parameterNames) {
205
206 int hint = -1;
207
208 int dotIndex = path.indexOf(CharPool.PERIOD);
209
210 if (dotIndex != -1) {
211 hint = GetterUtil.getInteger(path.substring(dotIndex + 1));
212
213 path = path.substring(0, dotIndex);
214 }
215
216 path = servletContextPath + path;
217
218 int firstIndex = _pathBinarySearch.findFirst(path);
219
220 if (firstIndex < 0) {
221 return -1;
222 }
223
224 int lastIndex = _pathBinarySearch.findLast(path, firstIndex);
225
226 if (lastIndex < 0) {
227 lastIndex = firstIndex;
228 }
229
230 int index = -1;
231
232 int max = -1;
233
234 for (int i = firstIndex; i <= lastIndex; i++) {
235 JSONWebServiceActionConfig jsonWebServiceActionConfig
236 = _jsonWebServiceActionConfigs.get(i);
237
238 String jsonWebServiceActionConfigMethod =
239 jsonWebServiceActionConfig.getMethod();
240
241 if (PropsValues.JSONWS_WEB_SERVICE_STRICT_HTTP_METHOD &&
242 (method != null)) {
243
244 if ((jsonWebServiceActionConfigMethod != null) &&
245 !jsonWebServiceActionConfigMethod.equals(method)) {
246
247 continue;
248 }
249 }
250
251 MethodParameter[] jsonWebServiceActionConfigMethodParameters =
252 jsonWebServiceActionConfig.getMethodParameters();
253
254 int methodParametersCount =
255 jsonWebServiceActionConfigMethodParameters.length;
256
257 if ((hint != -1) && (methodParametersCount != hint)) {
258 continue;
259 }
260
261 int count = _countMatchedElements(
262 parameterNames, jsonWebServiceActionConfigMethodParameters);
263
264 if (count > max) {
265 if ((hint != -1) || (count >= methodParametersCount)) {
266 max = count;
267
268 index = i;
269 }
270 }
271 }
272
273 return index;
274 }
275
276 private int _getPathParametersIndex(String path) {
277 int index = path.indexOf(CharPool.SLASH, 1);
278
279 if (index != -1) {
280 index = path.indexOf(CharPool.SLASH, index + 1);
281 }
282
283 return index;
284 }
285
286 private SortedArrayList<JSONWebServiceActionConfig>
287 _jsonWebServiceActionConfigs =
288 new SortedArrayList<JSONWebServiceActionConfig>();
289 private BinarySearch<String> _pathBinarySearch = new PathBinarySearch();
290
291 private class PathBinarySearch extends BinarySearch<String> {
292
293 @Override
294 protected int compare(int index, String element) {
295 JSONWebServiceActionConfig jsonWebServiceActionConfig =
296 _jsonWebServiceActionConfigs.get(index);
297
298 String fullPath = jsonWebServiceActionConfig.getFullPath();
299
300 return fullPath.compareTo(element);
301 }
302
303 @Override
304 protected int getLastIndex() {
305 return _jsonWebServiceActionConfigs.size() - 1;
306 }
307
308 }
309
310 }