1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.wsrp;
24  
25  import com.liferay.portal.kernel.upload.UploadPortletRequest;
26  import com.liferay.portal.kernel.util.ContentTypes;
27  import com.liferay.portal.kernel.util.FileUtil;
28  import com.liferay.portal.model.Portlet;
29  import com.liferay.portal.service.PortletLocalServiceUtil;
30  import com.liferay.portal.util.PortalUtil;
31  import com.liferay.portal.wsrp.util.WSRPUtil;
32  
33  import java.io.File;
34  import java.io.IOException;
35  
36  import java.util.ArrayList;
37  import java.util.Collection;
38  import java.util.Enumeration;
39  import java.util.Iterator;
40  import java.util.List;
41  import java.util.Locale;
42  import java.util.Map;
43  import java.util.Set;
44  import java.util.concurrent.ConcurrentHashMap;
45  
46  import javax.portlet.ActionRequest;
47  import javax.portlet.PortletMode;
48  import javax.portlet.PortletRequest;
49  
50  import javax.servlet.http.HttpServletRequest;
51  
52  import oasis.names.tc.wsrp.v1.types.ClientData;
53  import oasis.names.tc.wsrp.v1.types.MarkupContext;
54  import oasis.names.tc.wsrp.v1.types.NamedString;
55  import oasis.names.tc.wsrp.v1.types.SessionContext;
56  import oasis.names.tc.wsrp.v1.types.UploadContext;
57  
58  import org.apache.wsrp4j.consumer.InteractionRequest;
59  import org.apache.wsrp4j.consumer.MarkupRequest;
60  import org.apache.wsrp4j.consumer.PortletWindowSession;
61  import org.apache.wsrp4j.consumer.driver.GenericWSRPBaseRequestImpl;
62  import org.apache.wsrp4j.log.LogManager;
63  import org.apache.wsrp4j.log.Logger;
64  import org.apache.wsrp4j.util.AuthenticationInfoHelper;
65  import org.apache.wsrp4j.util.Constants;
66  import org.apache.wsrp4j.util.LocaleHelper;
67  import org.apache.wsrp4j.util.Modes;
68  import org.apache.wsrp4j.util.WindowStates;
69  
70  /**
71   * <a href="WSRPRequestImpl.java.html"> <b><i>View Source</i></b></a>
72   *
73   * @author Michael Young
74   *
75   */
76  public class WSRPRequestImpl extends GenericWSRPBaseRequestImpl implements
77          InteractionRequest, MarkupRequest {
78  
79      public WSRPRequestImpl(PortletWindowSession windowSession,
80              PortletRequest portletRequest, boolean renderPhase) {
81  
82          this._windowSession = windowSession;
83          this._portletRequest = portletRequest;
84          this._userAuth = AuthenticationInfoHelper
85                  .getWsrpFromPortlet(portletRequest.getAuthType());
86  
87          _integrateParameters(renderPhase);
88      }
89  
90      public String getInteractionState() {
91          return _interactionState;
92      }
93  
94      public NamedString[] getFormParameters() {
95          return _formParameters;
96      }
97  
98      public UploadContext[] getUploadContexts() {
99          return _uploadContexts;
100     }
101 
102     public MarkupContext getCachedMarkup() {
103         if (_windowSession == null)
104             return null;
105 
106         return _windowSession.getCachedMarkup();
107     }
108 
109     public String getSessionID() {
110         if (this._windowSession != null) {
111             SessionContext sessionCtx = this._windowSession.getPortletSession()
112                     .getSessionContext();
113             if (sessionCtx != null) {
114                 return sessionCtx.getSessionID();
115 
116             }
117         }
118 
119         return null;
120     }
121 
122     public String getPortletInstanceKey() {
123         return _windowSession.getWindowID();
124     }
125 
126     public String getNavigationalState() {
127         return _naviState;
128     }
129 
130     public String getWindowState() {
131         if (_currentState == null) {
132             //map portlet window states to wsrp:window states
133             javax.portlet.WindowState portletWindowState = _portletRequest
134                     .getWindowState();
135             _currentState = WindowStates.getWsrpStateFromJsrPortletState(
136                     portletWindowState).toString();
137         }
138 
139         return _currentState;
140     }
141 
142     public String getMode() {
143         if (_currentMode == null) {
144             //map jsr-168 modes to wsrp:modes
145             PortletMode portletMode = _portletRequest.getPortletMode();
146             _currentMode = Modes.getWsrpModeFromJsrPortletMode(portletMode)
147                     .toString();
148         }
149 
150         return _currentMode;
151     }
152 
153     public ClientData getClientData() {
154         // TODO: need to find out the client data here
155         return null;
156     }
157 
158     public String[] getLocales() {
159         if (this._locales == null) {
160             Enumeration eLocales = _portletRequest.getLocales();
161             List wsrpLocales = new ArrayList();
162             while (eLocales.hasMoreElements()) {
163                 Locale locale = (Locale) eLocales.nextElement();
164                 wsrpLocales.add(LocaleHelper.getWsrpLocale(locale));
165             }
166 
167             _locales = (String[]) wsrpLocales.toArray(new String[0]);
168         }
169 
170         return _locales;
171     }
172 
173     public String[] getModes() {
174         final String MN = "getModes()";
175 
176         if (_logger.isLogging(Logger.TRACE_HIGH)) {
177             _logger.entry(Logger.TRACE_HIGH, MN);
178         }
179 
180         if (this._modes != null) {
181             if (_logger.isLogging(Logger.TRACE_HIGH)) {
182                 _logger.exit(Logger.TRACE_HIGH, MN);
183             }
184 
185             return this._modes;
186         }
187 
188         long companyId = PortalUtil.getCompanyId(_portletRequest);
189         try {
190             Portlet portlet = PortletLocalServiceUtil.getPortletById(companyId,
191                     _windowSession.getWindowID());
192             Map portletModesMap = portlet.getPortletModes();
193             Collection mimeTypes = portletModesMap.values();
194             Iterator it = mimeTypes.iterator();
195             Map portletModes = new ConcurrentHashMap();
196 
197             for (int i = 0; it.hasNext(); i++) {
198                 // Required
199                 Set portletModesSet = (Set) it.next();
200 
201                 Iterator it2 = portletModesSet.iterator();
202 
203                 for (int j = 0; it2.hasNext(); j++) {
204                     String mode = (String) it2.next();
205 
206                     if (portletModes.get(mode) == null) {
207                         portletModes.put(mode, mode);
208                     }
209                 }
210             }
211 
212             String[] wsrpModes = new String[portletModes.size()];
213             it = portletModes.values().iterator();
214             for (int i = 0; it.hasNext(); i++) {
215                 String mode = (String) it.next();
216                 wsrpModes[i] = WSRPUtil.toWsrpMode(mode);
217             }
218             this._modes = wsrpModes;
219         }
220         catch (Exception e) {
221             _logger.entry(Logger.ERROR, "Could not get portlet definition", e);
222         }
223 
224         if (_logger.isLogging(Logger.TRACE_HIGH)) {
225             _logger.exit(Logger.TRACE_HIGH, MN);
226         }
227 
228         return this._modes;
229     }
230 
231     public String[] getWindowStates() {
232         // TODO: for now we simply return what we know
233         //       we should return what our environment supports
234         return WindowStates.getWindowStatesAsStringArray();
235     }
236 
237     public String[] getMimeTypes() {
238         // TODO: return whatever our environment supports
239         return null;
240     }
241 
242     public String[] getCharacterEncodingSet() {
243         // TODO: return whatever our environment supports
244         return null;
245     }
246 
247     public boolean isModeSupported(String wsrpMode) {
248         if (wsrpMode == null)
249             throw new IllegalArgumentException("A mode must not be null");
250 
251         return _portletRequest.isPortletModeAllowed(Modes
252                 .getJsrPortletModeFromWsrpMode(Modes.fromString(wsrpMode)));
253     }
254 
255     public boolean isWindowStateSupported(String wsrpWindowState) {
256         if (wsrpWindowState == null)
257             throw new IllegalArgumentException(
258                     "A window state must not be null");
259 
260         return _portletRequest.isWindowStateAllowed(WindowStates
261                 .getJsrPortletStateFromWsrpState(WindowStates
262                         .fromString(wsrpWindowState)));
263     }
264 
265     public String getUserAuthentication() {
266         return this._userAuth;
267     }
268 
269     private void _integrateParameters(boolean renderPhase) {
270         final String MN = "integrateParameter()";
271 
272         if (_logger.isLogging(Logger.TRACE_HIGH)) {
273             _logger.entry(Logger.TRACE_HIGH, MN);
274         }
275 
276         // interaction state
277         this._interactionState = _portletRequest
278                 .getParameter(Constants.INTERACTION_STATE);
279 
280         // check for navistate
281         // if navistate is stored as url parameter take this
282         // otherwise look for render param
283         this._naviState = _portletRequest
284                 .getParameter(Constants.NAVIGATIONAL_STATE);
285         if (this._naviState == null) {
286             this._naviState = _portletRequest
287                     .getParameter(WSRPProxyPortlet.NAVIGATIONAL_STATE);
288         }
289 
290         ArrayList formParams = new ArrayList();
291         ArrayList uploadContexts = new ArrayList();
292 
293         HttpServletRequest httpReq =
294             PortalUtil.getHttpServletRequest(_portletRequest);
295 
296         String contentType = httpReq.getContentType();
297 
298         if (contentType != null &&
299                 contentType.startsWith(ContentTypes.MULTIPART_FORM_DATA) &&
300                 !renderPhase) {
301 
302             // process file uploads
303 
304             ActionRequest actionRequest = (ActionRequest)_portletRequest;
305 
306             UploadPortletRequest upr =
307                 PortalUtil.getUploadPortletRequest(actionRequest);
308 
309             Enumeration paramNames =
310                 upr.getParameterNames();
311 
312             while (paramNames.hasMoreElements()) {
313                 String name = (String)paramNames.nextElement();
314 
315                 if (_isReservedParameter(name)) {
316                     continue;
317                 }
318 
319                 if (upr.isFormField(name)) {
320                     _addFormField(formParams, name, upr.getParameterValues(name));
321                 }
322                 else {
323                     UploadContext uploadContext = new UploadContext();
324 
325                     String partContentType = upr.getContentType(name);
326 
327                     uploadContext.setMimeType(partContentType);
328 
329                     StringBuilder sm = new StringBuilder();
330 
331                     sm.append("form-data; ");
332                     sm.append("name=");
333                     sm.append(name);
334                     sm.append("; filename=");
335                     sm.append(upr.getFileName(name));
336 
337                     NamedString[] mimeAttributes = {new NamedString()};
338                     mimeAttributes[0].setName("Content-Disposition");
339                     mimeAttributes[0].setValue(sm.toString());
340 
341                     uploadContext.setMimeAttributes(mimeAttributes);
342 
343                     File file = upr.getFile(name);
344                     byte[] fileBytes = null;
345 
346                     try {
347                         fileBytes = FileUtil.getBytes(file);
348                     }
349                     catch (IOException e) {
350                         throw new IllegalStateException(
351                             "Error reading multi-part file");
352                     }
353 
354                     if (fileBytes == null) {
355                         continue;
356                     }
357 
358                     uploadContext.setUploadData(fileBytes);
359 
360                     uploadContexts.add(uploadContext);
361                 }
362             }
363         }
364         else {
365             _addFormFields(formParams);
366         }
367 
368         int formParamsSize = formParams.size();
369 
370         if (formParamsSize > 0) {
371             _formParameters = new NamedString[formParamsSize];
372             formParams.toArray(_formParameters);
373         }
374 
375         int uploadContextsSize = uploadContexts.size();
376 
377         if (uploadContextsSize > 0) {
378             _uploadContexts = new UploadContext[uploadContextsSize];
379             uploadContexts.toArray(_uploadContexts);
380         }
381 
382         if (_logger.isLogging(Logger.TRACE_HIGH)) {
383             _logger.exit(Logger.TRACE_HIGH, MN);
384         }
385     }
386 
387     private void _addFormFields(List formParams) {
388         Enumeration paramNames =
389             _portletRequest.getParameterNames();
390 
391         while (paramNames.hasMoreElements()) {
392             String name = (String) paramNames.nextElement();
393 
394             String[] values = _portletRequest.getParameterValues(name);
395 
396             if (values == null) {
397                 continue;
398             }
399 
400             _addFormField(formParams, name, values);
401         }
402     }
403 
404     private void _addFormField(List formParams, String name, String values[]) {
405         for (int i = 0; i < values.length; i++) {
406             NamedString paramPair = new NamedString();
407             paramPair.setName(name);
408             paramPair.setValue(values[i]);
409 
410             formParams.add(paramPair);
411         }
412 
413     }
414 
415     private boolean _isReservedParameter(String name) {
416         if (Constants.isWsrpURLParam(name)
417                 || name.equals(WSRPProxyPortlet.NAVIGATIONAL_STATE)
418                 || name.equals(WSRPProxyPortlet.REMOTE_INVOCATION)) {
419 
420             return true;
421         }
422         else {
423             return false;
424         }
425     }
426 
427     private final PortletRequest _portletRequest;
428 
429     private final PortletWindowSession _windowSession;
430 
431     private final String _userAuth;
432 
433     private NamedString[] _formParameters = null;
434 
435     private String _interactionState = null;
436 
437     private UploadContext[] _uploadContexts = null;
438 
439     private String _currentMode = null;
440 
441     private String _currentState = null;
442 
443     private String _naviState = null;
444 
445     //  just for performance reasons we cache this info
446     private String[] _modes = null;
447 
448     private String[] _locales = null;
449 
450     protected Logger _logger = LogManager.getLogManager().getLogger(
451             WSRPRequestImpl.class);
452 
453 }