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