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