001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.jsonwebservice;
016    
017    import com.liferay.portal.kernel.upload.FileItem;
018    import com.liferay.portal.kernel.upload.UploadServletRequest;
019    import com.liferay.portal.kernel.util.CamelCaseUtil;
020    import com.liferay.portal.kernel.util.CharPool;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.service.ServiceContext;
026    import com.liferay.portal.service.ServiceContextFactory;
027    
028    import java.util.ArrayList;
029    import java.util.Collections;
030    import java.util.Enumeration;
031    import java.util.HashMap;
032    import java.util.List;
033    import java.util.Map;
034    import java.util.Set;
035    
036    import javax.servlet.http.HttpServletRequest;
037    
038    import jodd.util.NameValue;
039    
040    /**
041     * @author Igor Spasic
042     */
043    public class JSONWebServiceActionParameters {
044    
045            public void collectAll(
046                    HttpServletRequest request, String parameterPath,
047                    JSONRPCRequest jsonRPCRequest, Map<String, Object> parameterMap) {
048    
049                    _jsonRPCRequest = jsonRPCRequest;
050    
051                    try {
052                            _serviceContext = ServiceContextFactory.getInstance(request);
053                    }
054                    catch (Exception e) {
055                    }
056    
057                    _addDefaultParameters();
058    
059                    _collectDefaultsFromRequestAttributes(request);
060    
061                    _collectFromPath(parameterPath);
062                    _collectFromRequestParameters(request);
063                    _collectFromJSONRPCRequest(jsonRPCRequest);
064                    _collectFromMap(parameterMap);
065            }
066    
067            public List<NameValue<String, Object>> getInnerParameters(String baseName) {
068                    if (_innerParameters == null) {
069                            return null;
070                    }
071    
072                    return _innerParameters.get(baseName);
073            }
074    
075            public JSONRPCRequest getJSONRPCRequest() {
076                    return _jsonRPCRequest;
077            }
078    
079            public Object getParameter(String name) {
080                    return _parameters.get(name);
081            }
082    
083            public String[] getParameterNames() {
084                    String[] names = new String[_parameters.size()];
085    
086                    int i = 0;
087    
088                    for (String key : _parameters.keySet()) {
089                            names[i] = key;
090    
091                            i++;
092                    }
093    
094                    return names;
095            }
096    
097            public String getParameterTypeName(String name) {
098                    if (_parameterTypes == null) {
099                            return null;
100                    }
101    
102                    return _parameterTypes.get(name);
103            }
104    
105            public ServiceContext getServiceContext() {
106                    return _serviceContext;
107            }
108    
109            private void _addDefaultParameters() {
110                    _parameters.put("serviceContext", Void.TYPE);
111            }
112    
113            private void _collectDefaultsFromRequestAttributes(
114                    HttpServletRequest request) {
115    
116                    Enumeration<String> enu = request.getAttributeNames();
117    
118                    while (enu.hasMoreElements()) {
119                            String attributeName = enu.nextElement();
120    
121                            Object value = request.getAttribute(attributeName);
122    
123                            _parameters.put(attributeName, value);
124                    }
125            }
126    
127            private void _collectFromJSONRPCRequest(JSONRPCRequest jsonRPCRequest) {
128                    if (jsonRPCRequest == null) {
129                            return;
130                    }
131    
132                    Set<String> parameterNames = jsonRPCRequest.getParameterNames();
133    
134                    for (String parameterName : parameterNames) {
135                            String value = jsonRPCRequest.getParameter(parameterName);
136    
137                            parameterName = CamelCaseUtil.normalizeCamelCase(parameterName);
138    
139                            _parameters.put(parameterName, value);
140                    }
141            }
142    
143            private void _collectFromMap(Map<String, Object> parameterMap) {
144                    if (parameterMap == null) {
145                            return;
146                    }
147    
148                    for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
149                            String parameterName = entry.getKey();
150    
151                            Object value = entry.getValue();
152    
153                            _parameters.put(parameterName, value);
154                    }
155            }
156    
157            private void _collectFromPath(String parameterPath) {
158                    if (parameterPath == null) {
159                            return;
160                    }
161    
162                    if (parameterPath.startsWith(StringPool.SLASH)) {
163                            parameterPath = parameterPath.substring(1);
164                    }
165    
166                    String[] parameterPathParts = StringUtil.split(
167                            parameterPath, CharPool.SLASH);
168    
169                    int i = 0;
170    
171                    while (i < parameterPathParts.length) {
172                            String name = parameterPathParts[i];
173    
174                            if (name.length() == 0) {
175                                    i++;
176    
177                                    continue;
178                            }
179    
180                            String value = null;
181    
182                            if (name.startsWith(StringPool.DASH)) {
183                                    name = name.substring(1);
184                            }
185                            else if (!name.startsWith(StringPool.PLUS)) {
186                                    i++;
187    
188                                    if (i >= parameterPathParts.length) {
189                                            throw new IllegalArgumentException(
190                                                    "Missing value for parameter " + name);
191                                    }
192    
193                                    value = parameterPathParts[i];
194                            }
195    
196                            name = CamelCaseUtil.toCamelCase(name);
197    
198                            _parameters.put(name, value);
199    
200                            i++;
201                    }
202            }
203    
204            private void _collectFromRequestParameters(HttpServletRequest request) {
205                    UploadServletRequest uploadServletRequest = null;
206    
207                    if (request instanceof UploadServletRequest) {
208                            uploadServletRequest = (UploadServletRequest)request;
209                    }
210    
211                    List<String> parameterNames = Collections.list(
212                            request.getParameterNames());
213    
214                    if (uploadServletRequest != null) {
215                            Map<String, FileItem[]> multipartParameterMap =
216                                    uploadServletRequest.getMultipartParameterMap();
217    
218                            parameterNames.addAll(multipartParameterMap.keySet());
219                    }
220    
221                    for (String parameterName : parameterNames) {
222                            Object value = null;
223    
224                            if ((uploadServletRequest != null) &&
225                                    (uploadServletRequest.getFileName(parameterName) != null)) {
226    
227                                    value = uploadServletRequest.getFile(parameterName, true);
228                            }
229                            else {
230                                    String[] parameterValues = request.getParameterValues(
231                                            parameterName);
232    
233                                    if (parameterValues.length == 1) {
234                                            value = parameterValues[0];
235                                    }
236                                    else {
237                                            value = parameterValues;
238                                    }
239                            }
240    
241                            parameterName = CamelCaseUtil.normalizeCamelCase(parameterName);
242    
243                            _parameters.put(parameterName, value);
244                    }
245            }
246    
247            private Map<String, List<NameValue<String, Object>>> _innerParameters;
248            private JSONRPCRequest _jsonRPCRequest;
249    
250            private Map<String, Object> _parameters = new HashMap<String, Object>() {
251    
252                    @Override
253                    public Object put(String key, Object value) {
254                            int pos = key.indexOf(CharPool.COLON);
255    
256                            if (key.startsWith(StringPool.DASH)) {
257                                    key = key.substring(1);
258    
259                                    value = null;
260                            }
261                            else if (key.startsWith(StringPool.PLUS)) {
262                                    key = key.substring(1);
263    
264                                    String typeName = null;
265    
266                                    if (pos != -1) {
267                                            typeName = key.substring(pos);
268    
269                                            key = key.substring(0, pos - 1);
270                                    }
271                                    else {
272                                            if (value != null) {
273                                                    typeName = value.toString();
274    
275                                                    value = Void.TYPE;
276                                            }
277                                    }
278    
279                                    if (typeName != null) {
280                                            if (_parameterTypes == null) {
281                                                    _parameterTypes = new HashMap<String, String>();
282                                            }
283    
284                                            _parameterTypes.put(key, typeName);
285                                    }
286    
287                                    if (Validator.isNull(GetterUtil.getString(value))) {
288                                            value = Void.TYPE;
289                                    }
290                            }
291                            else if (pos != -1) {
292                                    String typeName = key.substring(pos + 1);
293    
294                                    key = key.substring(0, pos);
295    
296                                    if (_parameterTypes == null) {
297                                            _parameterTypes = new HashMap<String, String>();
298                                    }
299    
300                                    _parameterTypes.put(key, typeName);
301    
302                                    if (Validator.isNull(GetterUtil.getString(value))) {
303                                            value = Void.TYPE;
304                                    }
305                            }
306    
307                            pos = key.indexOf(CharPool.PERIOD);
308    
309                            if (pos != -1) {
310                                    String baseName = key.substring(0, pos);
311    
312                                    String innerName = key.substring(pos + 1);
313    
314                                    if (_innerParameters == null) {
315                                            _innerParameters =
316                                                    new HashMap<String, List<NameValue<String, Object>>>();
317                                    }
318    
319                                    List<NameValue<String, Object>> values = _innerParameters.get(
320                                            baseName);
321    
322                                    if (values == null) {
323                                            values = new ArrayList<NameValue<String, Object>>();
324    
325                                            _innerParameters.put(baseName, values);
326                                    }
327    
328                                    values.add(new NameValue<String, Object>(innerName, value));
329    
330                                    return value;
331                            }
332    
333                            return super.put(key, value);
334                    }
335    
336            };
337    
338            private Map<String, String> _parameterTypes;
339            private ServiceContext _serviceContext;
340    
341    }