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