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