001    /**
002     * Copyright (c) 2000-2012 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.KeyValue;
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<KeyValue<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            private void _addDefaultParameters() {
103                    _parameters.put("serviceContext", Void.TYPE);
104            }
105    
106            private void _collectDefaultsFromRequestAttributes(
107                    HttpServletRequest request) {
108    
109                    Enumeration<String> enu = request.getAttributeNames();
110    
111                    while (enu.hasMoreElements()) {
112                            String attributeName = enu.nextElement();
113    
114                            Object value = request.getAttribute(attributeName);
115    
116                            _parameters.put(attributeName, value);
117                    }
118            }
119    
120            private void _collectFromJSONRPCRequest(JSONRPCRequest jsonRPCRequest) {
121                    if (jsonRPCRequest == null) {
122                            return;
123                    }
124    
125                    Set<String> parameterNames = jsonRPCRequest.getParameterNames();
126    
127                    for (String parameterName : parameterNames) {
128                            String value = jsonRPCRequest.getParameter(parameterName);
129    
130                            parameterName = CamelCaseUtil.normalizeCamelCase(parameterName);
131    
132                            _parameters.put(parameterName, value);
133                    }
134            }
135    
136            private void _collectFromMap(Map<String, Object> parameterMap) {
137                    if (parameterMap == null) {
138                            return;
139                    }
140    
141                    for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
142                            String parameterName = entry.getKey();
143    
144                            Object value = entry.getValue();
145    
146                            _parameters.put(parameterName, value);
147                    }
148            }
149    
150            private void _collectFromPath(String parameterPath) {
151                    if (parameterPath == null) {
152                            return;
153                    }
154    
155                    if (parameterPath.startsWith(StringPool.SLASH)) {
156                            parameterPath = parameterPath.substring(1);
157                    }
158    
159                    String[] parameterPathParts = StringUtil.split(
160                            parameterPath, CharPool.SLASH);
161    
162                    int i = 0;
163    
164                    while (i < parameterPathParts.length) {
165                            String name = parameterPathParts[i];
166    
167                            if (name.length() == 0) {
168                                    i++;
169    
170                                    continue;
171                            }
172    
173                            String value = null;
174    
175                            if (name.startsWith(StringPool.DASH)) {
176                                    name = name.substring(1);
177                            }
178                            else if (!name.startsWith(StringPool.PLUS)) {
179                                    i++;
180    
181                                    if (i >= parameterPathParts.length) {
182                                            throw new IllegalArgumentException(
183                                                    "Missing value for parameter " + name);
184                                    }
185    
186                                    value = parameterPathParts[i];
187                            }
188    
189                            name = CamelCaseUtil.toCamelCase(name);
190    
191                            _parameters.put(name, value);
192    
193                            i++;
194                    }
195            }
196    
197            private void _collectFromRequestParameters(HttpServletRequest request) {
198                    UploadServletRequest uploadServletRequest = null;
199    
200                    if (request instanceof UploadServletRequest) {
201                            uploadServletRequest = (UploadServletRequest)request;
202                    }
203    
204                    Enumeration<String> enu = request.getParameterNames();
205    
206                    while (enu.hasMoreElements()) {
207                            String name = enu.nextElement();
208    
209                            Object value = null;
210    
211                            if ((uploadServletRequest != null) &&
212                                    (uploadServletRequest.getFileName(name) != null)) {
213    
214                                    value = uploadServletRequest.getFile(name, true);
215                            }
216                            else {
217                                    String[] parameterValues = request.getParameterValues(name);
218    
219                                    if (parameterValues.length == 1) {
220                                            value = parameterValues[0];
221                                    }
222                                    else {
223                                            value = parameterValues;
224                                    }
225                            }
226    
227                            name = CamelCaseUtil.normalizeCamelCase(name);
228    
229                            _parameters.put(name, value);
230                    }
231            }
232    
233            private ServiceContext _mergeServiceContext(ServiceContext serviceContext) {
234                    _serviceContext.setAddGroupPermissions(
235                            serviceContext.isAddGroupPermissions());
236                    _serviceContext.setAddGuestPermissions(
237                            serviceContext.isAddGuestPermissions());
238    
239                    if (serviceContext.getAssetCategoryIds() != null) {
240                            _serviceContext.setAssetCategoryIds(
241                                    serviceContext.getAssetCategoryIds());
242                    }
243    
244                    if (serviceContext.getAssetLinkEntryIds() != null) {
245                            _serviceContext.setAssetLinkEntryIds(
246                                    serviceContext.getAssetLinkEntryIds());
247                    }
248    
249                    if (serviceContext.getAssetTagNames() != null) {
250                            _serviceContext.setAssetTagNames(serviceContext.getAssetTagNames());
251                    }
252    
253                    if (serviceContext.getAttributes() != null) {
254                            _serviceContext.setAttributes(serviceContext.getAttributes());
255                    }
256    
257                    if (Validator.isNotNull(serviceContext.getCommand())) {
258                            _serviceContext.setCommand(serviceContext.getCommand());
259                    }
260    
261                    if (serviceContext.getCompanyId() > 0) {
262                            _serviceContext.setCompanyId(serviceContext.getCompanyId());
263                    }
264    
265                    if (serviceContext.getCreateDate() != null) {
266                            _serviceContext.setCreateDate(serviceContext.getCreateDate());
267                    }
268    
269                    if (Validator.isNotNull(serviceContext.getCurrentURL())) {
270                            _serviceContext.setCurrentURL(serviceContext.getCurrentURL());
271                    }
272    
273                    if (serviceContext.getExpandoBridgeAttributes() != null) {
274                            _serviceContext.setExpandoBridgeAttributes(
275                                    serviceContext.getExpandoBridgeAttributes());
276                    }
277    
278                    if (serviceContext.getGroupPermissions() != null) {
279                            _serviceContext.setGroupPermissions(
280                                    serviceContext.getGroupPermissions());
281                    }
282    
283                    if (serviceContext.getGuestPermissions() != null) {
284                            _serviceContext.setGuestPermissions(
285                                    serviceContext.getGuestPermissions());
286                    }
287    
288                    if (serviceContext.getHeaders() != null) {
289                            _serviceContext.setHeaders(serviceContext.getHeaders());
290                    }
291    
292                    if (Validator.isNotNull(serviceContext.getLanguageId())) {
293                            _serviceContext.setLanguageId(serviceContext.getLanguageId());
294                    }
295    
296                    if (Validator.isNotNull(serviceContext.getLayoutFullURL())) {
297                            _serviceContext.setLayoutFullURL(serviceContext.getLayoutFullURL());
298                    }
299    
300                    if (Validator.isNotNull(serviceContext.getLayoutURL())) {
301                            _serviceContext.setLayoutURL(serviceContext.getLayoutURL());
302                    }
303    
304                    if (serviceContext.getModifiedDate() != null) {
305                            _serviceContext.setModifiedDate(serviceContext.getModifiedDate());
306                    }
307    
308                    if (Validator.isNotNull(serviceContext.getPathMain())) {
309                            _serviceContext.setPathMain(serviceContext.getPathMain());
310                    }
311    
312                    if (serviceContext.getPlid() > 0) {
313                            _serviceContext.setPlid(serviceContext.getPlid());
314                    }
315    
316                    if (Validator.isNotNull(serviceContext.getPortalURL())) {
317                            _serviceContext.setPortalURL(serviceContext.getPortalURL());
318                    }
319    
320                    if (serviceContext.getPortletPreferencesIds() != null) {
321                            _serviceContext.setPortletPreferencesIds(
322                                    serviceContext.getPortletPreferencesIds());
323                    }
324    
325                    if (Validator.isNotNull(serviceContext.getRemoteAddr())) {
326                            _serviceContext.setRemoteAddr(serviceContext.getRemoteAddr());
327                    }
328    
329                    if (Validator.isNotNull(serviceContext.getRemoteHost())) {
330                            _serviceContext.setRemoteHost(serviceContext.getRemoteHost());
331                    }
332    
333                    if (serviceContext.getScopeGroupId() > 0) {
334                            _serviceContext.setScopeGroupId(serviceContext.getScopeGroupId());
335                    }
336    
337                    _serviceContext.setSignedIn(serviceContext.isSignedIn());
338    
339                    if (Validator.isNotNull(serviceContext.getUserDisplayURL())) {
340                            _serviceContext.setUserDisplayURL(
341                                    serviceContext.getUserDisplayURL());
342                    }
343    
344                    if (serviceContext.getUserId() > 0) {
345                            _serviceContext.setUserId(serviceContext.getUserId());
346                    }
347    
348                    if (Validator.isNotNull(serviceContext.getUuid())) {
349                            _serviceContext.setUuid(serviceContext.getUuid());
350                    }
351    
352                    if (serviceContext.getWorkflowAction() > 0) {
353                            _serviceContext.setWorkflowAction(
354                                    serviceContext.getWorkflowAction());
355                    }
356    
357                    return serviceContext;
358            }
359    
360            private Map<String, List<KeyValue<String, Object>>> _innerParameters;
361            private JSONRPCRequest _jsonRPCRequest;
362            private Map<String, Object> _parameters = new HashMap<String, Object>() {
363    
364                    @Override
365                    public Object put(String key, Object value) {
366                            if (key.startsWith(StringPool.DASH)) {
367                                    key = key.substring(1);
368    
369                                    value = null;
370                            }
371                            else if (key.startsWith(StringPool.PLUS)) {
372                                    key = key.substring(1);
373    
374                                    int pos = key.indexOf(CharPool.COLON);
375    
376                                    if (pos != -1) {
377                                            value = key.substring(pos + 1);
378    
379                                            key = key.substring(0, pos);
380                                    }
381    
382                                    if (Validator.isNotNull(value)) {
383                                            if (_parameterTypes == null) {
384                                                    _parameterTypes = new HashMap<String, String>();
385                                            }
386    
387                                            _parameterTypes.put(key, value.toString());
388                                    }
389    
390                                    value = Void.TYPE;
391                            }
392    
393                            int pos = key.indexOf(CharPool.PERIOD);
394    
395                            if (pos != -1) {
396                                    String baseName = key.substring(0, pos);
397    
398                                    String innerName = key.substring(pos + 1);
399    
400                                    if (_innerParameters == null) {
401                                            _innerParameters =
402                                                    new HashMap<String, List<KeyValue<String, Object>>>();
403                                    }
404    
405                                    List<KeyValue<String, Object>> values = _innerParameters.get(
406                                            baseName);
407    
408                                    if (values == null) {
409                                            values = new ArrayList<KeyValue<String, Object>>();
410    
411                                            _innerParameters.put(baseName, values);
412                                    }
413    
414                                    values.add(new KeyValue<String, Object>(innerName, value));
415    
416                                    return value;
417                            }
418    
419                            if ((_serviceContext != null) && key.equals("serviceContext")) {
420                                    if ((value != null) &&
421                                            ServiceContext.class.isAssignableFrom(value.getClass())) {
422    
423                                            value = _mergeServiceContext((ServiceContext)value);
424                                    }
425                                    else {
426                                            value = _serviceContext;
427                                    }
428                            }
429    
430                            return super.put(key, value);
431                    }
432    
433            };
434    
435            private Map<String, String> _parameterTypes;
436            private ServiceContext _serviceContext;
437    
438    }