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