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.portlet;
016    
017    import com.liferay.portal.kernel.portlet.LiferayPortletRequest;
018    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
019    import com.liferay.portal.kernel.portlet.LiferayPortletURL;
020    import com.liferay.portal.kernel.portlet.LiferayWindowState;
021    import com.liferay.portal.kernel.util.HttpUtil;
022    import com.liferay.portal.kernel.util.ParamUtil;
023    import com.liferay.portal.kernel.util.PropsKeys;
024    import com.liferay.portal.kernel.util.PropsUtil;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.util.WebKeys;
029    import com.liferay.portal.model.LayoutTypePortlet;
030    import com.liferay.portal.model.Portlet;
031    import com.liferay.portal.theme.ThemeDisplay;
032    import com.liferay.portal.util.PortalUtil;
033    
034    import java.util.Enumeration;
035    import java.util.Map;
036    
037    import javax.portlet.MimeResponse;
038    import javax.portlet.PortletException;
039    import javax.portlet.PortletMode;
040    import javax.portlet.PortletRequest;
041    import javax.portlet.PortletURL;
042    import javax.portlet.WindowState;
043    
044    import javax.servlet.http.HttpServletRequest;
045    
046    /**
047     * @author Brian Wing Shun Chan
048     * @author Miguel Pastor
049     */
050    public class PortletURLUtil {
051    
052            public static PortletURL clone(
053                            LiferayPortletURL liferayPortletURL, String lifecycle,
054                            LiferayPortletResponse liferayPortletResponse)
055                    throws PortletException {
056    
057                    LiferayPortletURL newLiferayPortletURL =
058                            liferayPortletResponse.createLiferayPortletURL(lifecycle);
059    
060                    newLiferayPortletURL.setPortletId(liferayPortletURL.getPortletId());
061    
062                    WindowState windowState = liferayPortletURL.getWindowState();
063    
064                    if (windowState != null) {
065                            newLiferayPortletURL.setWindowState(windowState);
066                    }
067    
068                    PortletMode portletMode = liferayPortletURL.getPortletMode();
069    
070                    if (portletMode != null) {
071                            newLiferayPortletURL.setPortletMode(portletMode);
072                    }
073    
074                    newLiferayPortletURL.setParameters(liferayPortletURL.getParameterMap());
075    
076                    return newLiferayPortletURL;
077            }
078    
079            public static PortletURL clone(
080                            PortletURL portletURL,
081                            LiferayPortletResponse liferayPortletResponse)
082                    throws PortletException {
083    
084                    LiferayPortletURL liferayPortletURL = (LiferayPortletURL)portletURL;
085    
086                    return clone(
087                            liferayPortletURL, liferayPortletURL.getLifecycle(),
088                            liferayPortletResponse);
089            }
090    
091            public static PortletURL clone(
092                            PortletURL portletURL, MimeResponse mimeResponse)
093                    throws PortletException {
094    
095                    LiferayPortletURL liferayPortletURL = (LiferayPortletURL)portletURL;
096    
097                    return clone(
098                            liferayPortletURL, liferayPortletURL.getLifecycle(),
099                            (LiferayPortletResponse)mimeResponse);
100            }
101    
102            public static PortletURL clone(
103                            PortletURL portletURL, String lifecycle,
104                            LiferayPortletResponse liferayPortletResponse)
105                    throws PortletException {
106    
107                    LiferayPortletURL liferayPortletURL = (LiferayPortletURL)portletURL;
108    
109                    return clone(liferayPortletURL, lifecycle, liferayPortletResponse);
110            }
111    
112            public static PortletURL clone(
113                            PortletURL portletURL, String lifecycle, MimeResponse mimeResponse)
114                    throws PortletException {
115    
116                    LiferayPortletURL liferayPortletURL = (LiferayPortletURL)portletURL;
117    
118                    return clone(
119                            liferayPortletURL, lifecycle, (LiferayPortletResponse)mimeResponse);
120            }
121    
122            public static PortletURL getCurrent(
123                    LiferayPortletRequest liferayPortletRequest,
124                    LiferayPortletResponse liferayPortletResponse) {
125    
126                    PortletURL portletURL = liferayPortletResponse.createRenderURL();
127    
128                    Enumeration<String> enu = liferayPortletRequest.getParameterNames();
129    
130                    while (enu.hasMoreElements()) {
131                            String param = enu.nextElement();
132                            String[] values = liferayPortletRequest.getParameterValues(param);
133    
134                            boolean addParam = true;
135    
136                            // Don't set paramter values that are over 32 kb. See LEP-1755.
137    
138                            for (int i = 0; i < values.length; i++) {
139                                    if (values[i].length() > _CURRENT_URL_PARAMETER_THRESHOLD) {
140                                            addParam = false;
141    
142                                            break;
143                                    }
144                            }
145    
146                            if (addParam) {
147                                    portletURL.setParameter(param, values);
148                            }
149                    }
150    
151                    return portletURL;
152            }
153    
154            public static PortletURL getCurrent(
155                    PortletRequest portletRequest, MimeResponse mimeResponse) {
156    
157                    return getCurrent(
158                            (LiferayPortletRequest)portletRequest,
159                            (LiferayPortletResponse)mimeResponse);
160            }
161    
162            public static String getRefreshURL(
163                    HttpServletRequest request, ThemeDisplay themeDisplay) {
164    
165                    StringBundler sb = new StringBundler(32);
166    
167                    sb.append(themeDisplay.getPathMain());
168                    sb.append("/portal/render_portlet?p_l_id=");
169    
170                    long plid = themeDisplay.getPlid();
171    
172                    sb.append(plid);
173    
174                    Portlet portlet = (Portlet)request.getAttribute(WebKeys.RENDER_PORTLET);
175    
176                    String portletId = portlet.getPortletId();
177    
178                    sb.append("&p_p_id=");
179                    sb.append(portletId);
180    
181                    sb.append("&p_p_lifecycle=0&p_t_lifecycle=");
182                    sb.append(themeDisplay.getLifecycle());
183    
184                    WindowState windowState = WindowState.NORMAL;
185    
186                    if (themeDisplay.isStatePopUp()) {
187                            windowState = LiferayWindowState.POP_UP;
188                    }
189                    else {
190                            LayoutTypePortlet layoutTypePortlet =
191                                    themeDisplay.getLayoutTypePortlet();
192    
193                            if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
194                                    windowState = WindowState.MAXIMIZED;
195                            }
196                            else if (layoutTypePortlet.hasStateMinPortletId(portletId)) {
197                                    windowState = WindowState.MINIMIZED;
198                            }
199                    }
200    
201                    sb.append("&p_p_state=");
202                    sb.append(windowState);
203    
204                    sb.append("&p_p_mode=view&p_p_col_id=");
205    
206                    String columnId = (String)request.getAttribute(
207                            WebKeys.RENDER_PORTLET_COLUMN_ID);
208    
209                    sb.append(columnId);
210    
211                    Integer columnPos = (Integer)request.getAttribute(
212                            WebKeys.RENDER_PORTLET_COLUMN_POS);
213    
214                    sb.append("&p_p_col_pos=");
215                    sb.append(columnPos);
216    
217                    Integer columnCount = (Integer)request.getAttribute(
218                            WebKeys.RENDER_PORTLET_COLUMN_COUNT);
219    
220                    sb.append("&p_p_col_count=");
221                    sb.append(columnCount);
222    
223                    if (portlet.isStatic()) {
224                            sb.append("&p_p_static=1");
225    
226                            if (portlet.isStaticStart()) {
227                                    sb.append("&p_p_static_start=1");
228                            }
229                    }
230    
231                    sb.append("&p_p_isolated=1&p_v_l_s_g_id=");
232                    sb.append(themeDisplay.getSiteGroupId());
233    
234                    String doAsUserId = themeDisplay.getDoAsUserId();
235    
236                    if (Validator.isNotNull(doAsUserId)) {
237                            sb.append("&doAsUserId=");
238                            sb.append(HttpUtil.encodeURL(doAsUserId));
239                    }
240    
241                    String currentURL = PortalUtil.getCurrentURL(request);
242    
243                    sb.append("&currentURL=");
244                    sb.append(HttpUtil.encodeURL(currentURL));
245    
246                    String ppid = ParamUtil.getString(request, "p_p_id");
247    
248                    if (ppid.equals(portletId)) {
249                            String namespace = PortalUtil.getPortletNamespace(portletId);
250    
251                            Map<String, String[]> parameters = request.getParameterMap();
252    
253                            for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
254                                    String name = entry.getKey();
255    
256                                    if (!PortalUtil.isReservedParameter(name) &&
257                                            !name.equals("currentURL") &&
258                                            !isRefreshURLReservedParameter(name, namespace)) {
259    
260                                            String[] values = entry.getValue();
261    
262                                            for (int i = 0; i < values.length; i++) {
263                                                    sb.append(StringPool.AMPERSAND);
264                                                    sb.append(name);
265                                                    sb.append(StringPool.EQUAL);
266                                                    sb.append(HttpUtil.encodeURL(values[i]));
267                                            }
268                                    }
269                            }
270                    }
271    
272                    return sb.toString();
273            }
274    
275            protected static boolean isRefreshURLReservedParameter(
276                    String parameter, String namespace) {
277    
278                    if ((_PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS == null) ||
279                            (_PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS.length == 0)) {
280    
281                            return false;
282                    }
283    
284                    for (int i = 0; i < _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS.length;
285                                    i++) {
286    
287                            String reservedParameter = namespace.concat(
288                                    _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS[i]);
289    
290                            if (parameter.equals(reservedParameter)) {
291                                    return true;
292                            }
293                    }
294    
295                    return false;
296            }
297    
298            private static final int _CURRENT_URL_PARAMETER_THRESHOLD = 32768;
299    
300            private static final String[] _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS =
301                    PropsUtil.getArray(
302                            PropsKeys.PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS);
303    
304    }