001    /**
002     * Copyright (c) 2000-2013 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");
232    
233                    long sourceGroupId = ParamUtil.getLong(request, "p_v_l_s_g_id");
234    
235                    if (sourceGroupId > 0) {
236                            sb.append("&p_v_l_s_g_id=");
237                            sb.append(sourceGroupId);
238                    }
239    
240                    String doAsUserId = themeDisplay.getDoAsUserId();
241    
242                    if (Validator.isNotNull(doAsUserId)) {
243                            sb.append("&doAsUserId=");
244                            sb.append(HttpUtil.encodeURL(doAsUserId));
245                    }
246    
247                    String currentURL = PortalUtil.getCurrentURL(request);
248    
249                    sb.append("&currentURL=");
250                    sb.append(HttpUtil.encodeURL(currentURL));
251    
252                    String ppid = ParamUtil.getString(request, "p_p_id");
253    
254                    if (ppid.equals(portletId)) {
255                            String namespace = PortalUtil.getPortletNamespace(portletId);
256    
257                            Map<String, String[]> parameters = request.getParameterMap();
258    
259                            for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
260                                    String name = entry.getKey();
261    
262                                    if (!PortalUtil.isReservedParameter(name) &&
263                                            !name.equals("currentURL") &&
264                                            !isRefreshURLReservedParameter(name, namespace)) {
265    
266                                            String[] values = entry.getValue();
267    
268                                            for (int i = 0; i < values.length; i++) {
269                                                    sb.append(StringPool.AMPERSAND);
270                                                    sb.append(name);
271                                                    sb.append(StringPool.EQUAL);
272                                                    sb.append(HttpUtil.encodeURL(values[i]));
273                                            }
274                                    }
275                            }
276                    }
277    
278                    return sb.toString();
279            }
280    
281            protected static boolean isRefreshURLReservedParameter(
282                    String parameter, String namespace) {
283    
284                    if ((_PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS == null) ||
285                            (_PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS.length == 0)) {
286    
287                            return false;
288                    }
289    
290                    for (int i = 0; i < _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS.length;
291                                    i++) {
292    
293                            String reservedParameter = namespace.concat(
294                                    _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS[i]);
295    
296                            if (parameter.equals(reservedParameter)) {
297                                    return true;
298                            }
299                    }
300    
301                    return false;
302            }
303    
304            private static final int _CURRENT_URL_PARAMETER_THRESHOLD = 32768;
305    
306            private static final String[] _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS =
307                    PropsUtil.getArray(
308                            PropsKeys.PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS);
309    
310    }