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.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 = liferayPortletResponse.createRenderURL();
128    
129                    Enumeration<String> enu = liferayPortletRequest.getParameterNames();
130    
131                    while (enu.hasMoreElements()) {
132                            String param = enu.nextElement();
133                            String[] values = liferayPortletRequest.getParameterValues(param);
134    
135                            boolean addParam = true;
136    
137                            // Don't set paramter values that are over 32 kb. See LEP-1755.
138    
139                            for (int i = 0; i < values.length; i++) {
140                                    if (values[i].length() > _CURRENT_URL_PARAMETER_THRESHOLD) {
141                                            addParam = false;
142    
143                                            break;
144                                    }
145                            }
146    
147                            if (addParam) {
148                                    portletURL.setParameter(param, values);
149                            }
150                    }
151    
152                    return portletURL;
153            }
154    
155            public static PortletURL getCurrent(
156                    PortletRequest portletRequest, MimeResponse mimeResponse) {
157    
158                    return getCurrent(
159                            (LiferayPortletRequest)portletRequest,
160                            (LiferayPortletResponse)mimeResponse);
161            }
162    
163            public static String getRefreshURL(
164                    HttpServletRequest request, ThemeDisplay themeDisplay) {
165    
166                    StringBundler sb = new StringBundler(32);
167    
168                    sb.append(themeDisplay.getPathMain());
169                    sb.append("/portal/render_portlet?p_l_id=");
170    
171                    long plid = themeDisplay.getPlid();
172    
173                    sb.append(plid);
174    
175                    Portlet portlet = (Portlet)request.getAttribute(WebKeys.RENDER_PORTLET);
176    
177                    String portletId = portlet.getPortletId();
178    
179                    sb.append("&p_p_id=");
180                    sb.append(portletId);
181    
182                    sb.append("&p_p_lifecycle=0&p_t_lifecycle=");
183                    sb.append(themeDisplay.getLifecycle());
184    
185                    WindowState windowState = WindowState.NORMAL;
186    
187                    if (themeDisplay.isStatePopUp()) {
188                            windowState = LiferayWindowState.POP_UP;
189                    }
190                    else {
191                            LayoutTypePortlet layoutTypePortlet =
192                                    themeDisplay.getLayoutTypePortlet();
193    
194                            if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
195                                    windowState = WindowState.MAXIMIZED;
196                            }
197                            else if (layoutTypePortlet.hasStateMinPortletId(portletId)) {
198                                    windowState = WindowState.MINIMIZED;
199                            }
200                    }
201    
202                    sb.append("&p_p_state=");
203                    sb.append(windowState);
204    
205                    sb.append("&p_p_mode=view&p_p_col_id=");
206    
207                    String columnId = (String)request.getAttribute(
208                            WebKeys.RENDER_PORTLET_COLUMN_ID);
209    
210                    sb.append(columnId);
211    
212                    Integer columnPos = (Integer)request.getAttribute(
213                            WebKeys.RENDER_PORTLET_COLUMN_POS);
214    
215                    sb.append("&p_p_col_pos=");
216                    sb.append(columnPos);
217    
218                    Integer columnCount = (Integer)request.getAttribute(
219                            WebKeys.RENDER_PORTLET_COLUMN_COUNT);
220    
221                    sb.append("&p_p_col_count=");
222                    sb.append(columnCount);
223    
224                    if (portlet.isStatic()) {
225                            sb.append("&p_p_static=1");
226    
227                            if (portlet.isStaticStart()) {
228                                    sb.append("&p_p_static_start=1");
229                            }
230                    }
231    
232                    sb.append("&p_p_isolated=1");
233    
234                    long sourceGroupId = ParamUtil.getLong(request, "p_v_l_s_g_id");
235    
236                    if (sourceGroupId > 0) {
237                            sb.append("&p_v_l_s_g_id=");
238                            sb.append(sourceGroupId);
239                    }
240    
241                    String doAsUserId = themeDisplay.getDoAsUserId();
242    
243                    if (Validator.isNotNull(doAsUserId)) {
244                            sb.append("&doAsUserId=");
245                            sb.append(HttpUtil.encodeURL(doAsUserId));
246                    }
247    
248                    String currentURL = PortalUtil.getCurrentURL(request);
249    
250                    sb.append("&currentURL=");
251                    sb.append(HttpUtil.encodeURL(currentURL));
252    
253                    String ppid = ParamUtil.getString(request, "p_p_id");
254    
255                    if (!ppid.equals(portletId)) {
256                            return sb.toString();
257                    }
258    
259                    String namespace = PortalUtil.getPortletNamespace(portletId);
260    
261                    Map<String, String[]> parameters = request.getParameterMap();
262    
263                    for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
264                            String name = entry.getKey();
265    
266                            if (!PortalUtil.isReservedParameter(name) &&
267                                    !name.equals("currentURL") &&
268                                    !isRefreshURLReservedParameter(name, namespace)) {
269    
270                                    String[] values = entry.getValue();
271    
272                                    for (int i = 0; i < values.length; i++) {
273                                            sb.append(StringPool.AMPERSAND);
274                                            sb.append(name);
275                                            sb.append(StringPool.EQUAL);
276                                            sb.append(HttpUtil.encodeURL(values[i]));
277                                    }
278                            }
279                    }
280    
281                    return sb.toString();
282            }
283    
284            protected static boolean isRefreshURLReservedParameter(
285                    String parameter, String namespace) {
286    
287                    if (ArrayUtil.isEmpty(_PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS)) {
288                            return false;
289                    }
290    
291                    for (int i = 0; i < _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS.length;
292                                    i++) {
293    
294                            String reservedParameter = namespace.concat(
295                                    _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS[i]);
296    
297                            if (parameter.equals(reservedParameter)) {
298                                    return true;
299                            }
300                    }
301    
302                    return false;
303            }
304    
305            private static final int _CURRENT_URL_PARAMETER_THRESHOLD = 32768;
306    
307            private static final String[] _PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS =
308                    PropsUtil.getArray(
309                            PropsKeys.PORTLET_URL_REFRESH_URL_RESERVED_PARAMETERS);
310    
311    }