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