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