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.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.ArrayUtil;
020    import com.liferay.portal.model.Layout;
021    import com.liferay.portal.model.Portlet;
022    import com.liferay.portal.model.PublicRenderParameter;
023    import com.liferay.portal.model.User;
024    import com.liferay.portal.util.PortalUtil;
025    
026    import java.io.Serializable;
027    
028    import java.util.ArrayList;
029    import java.util.LinkedHashMap;
030    import java.util.List;
031    import java.util.Map;
032    
033    import javax.portlet.Event;
034    import javax.portlet.PortletMode;
035    import javax.portlet.PortletModeException;
036    import javax.portlet.StateAwareResponse;
037    import javax.portlet.WindowState;
038    import javax.portlet.WindowStateException;
039    
040    import javax.servlet.http.HttpServletResponse;
041    
042    import javax.xml.XMLConstants;
043    import javax.xml.namespace.QName;
044    
045    /**
046     * @author Brian Wing Shun Chan
047     */
048    public abstract class StateAwareResponseImpl
049            extends PortletResponseImpl implements StateAwareResponse {
050    
051            public String getDefaultNamespace() {
052                    Portlet portlet = getPortlet();
053    
054                    if (portlet != null) {
055                            return portlet.getPortletApp().getDefaultNamespace();
056                    }
057                    else {
058                            return XMLConstants.NULL_NS_URI;
059                    }
060            }
061    
062            public List<Event> getEvents() {
063                    return _events;
064            }
065    
066            public Layout getLayout() {
067                    return _layout;
068            }
069    
070            @Override
071            public PortletMode getPortletMode() {
072                    return _portletMode;
073            }
074    
075            public String getRedirectLocation() {
076                    return _redirectLocation;
077            }
078    
079            @Override
080            public Map<String, String[]> getRenderParameterMap() {
081                    return _params;
082            }
083    
084            public User getUser() {
085                    return _user;
086            }
087    
088            @Override
089            public WindowState getWindowState() {
090                    return _windowState;
091            }
092    
093            public boolean isCalledSetRenderParameter() {
094                    return _calledSetRenderParameter;
095            }
096    
097            @Override
098            public void removePublicRenderParameter(String name) {
099                    if (name == null) {
100                            throw new IllegalArgumentException();
101                    }
102    
103                    PublicRenderParameter publicRenderParameter =
104                            getPortlet().getPublicRenderParameter(name);
105    
106                    if (publicRenderParameter == null) {
107                            if (_log.isWarnEnabled()) {
108                                    _log.warn("Public parameter " + name + "does not exist");
109                            }
110    
111                            return;
112                    }
113    
114                    com.liferay.portal.kernel.xml.QName qName =
115                            publicRenderParameter.getQName();
116    
117                    String key = PortletQNameUtil.getPublicRenderParameterName(qName);
118    
119                    _publicRenderParameters.remove(key);
120            }
121    
122            @Override
123            public void setEvent(QName name, Serializable value) {
124                    if (name == null) {
125                            throw new IllegalArgumentException();
126                    }
127    
128                    _events.add(new EventImpl(name.getLocalPart(), name, value));
129            }
130    
131            @Override
132            public void setEvent(String name, Serializable value) {
133                    if (name == null) {
134                            throw new IllegalArgumentException();
135                    }
136    
137                    setEvent(new QName(getDefaultNamespace(), name), value);
138            }
139    
140            @Override
141            public void setPortletMode(PortletMode portletMode)
142                    throws PortletModeException {
143    
144                    if (_redirectLocation != null) {
145                            throw new IllegalStateException();
146                    }
147    
148                    if (!_portletRequestImpl.isPortletModeAllowed(portletMode)) {
149                            throw new PortletModeException(portletMode.toString(), portletMode);
150                    }
151    
152                    try {
153                            _portletMode = PortalUtil.updatePortletMode(
154                                    _portletName, _user, _layout, portletMode,
155                                    _portletRequestImpl.getHttpServletRequest());
156    
157                            _portletRequestImpl.setPortletMode(_portletMode);
158                    }
159                    catch (Exception e) {
160                            throw new PortletModeException(e, portletMode);
161                    }
162    
163                    _calledSetRenderParameter = true;
164            }
165    
166            public void setRedirectLocation(String redirectLocation) {
167                    _redirectLocation = redirectLocation;
168            }
169    
170            @Override
171            public void setRenderParameter(String name, String value) {
172                    if (_redirectLocation != null) {
173                            throw new IllegalStateException();
174                    }
175    
176                    if ((name == null) || (value == null)) {
177                            throw new IllegalArgumentException();
178                    }
179    
180                    setRenderParameter(name, new String[] {value});
181            }
182    
183            @Override
184            public void setRenderParameter(String name, String[] values) {
185                    if (_redirectLocation != null) {
186                            throw new IllegalStateException();
187                    }
188    
189                    if ((name == null) || (values == null)) {
190                            throw new IllegalArgumentException();
191                    }
192    
193                    for (int i = 0; i < values.length; i++) {
194                            if (values[i] == null) {
195                                    throw new IllegalArgumentException();
196                            }
197                    }
198    
199                    if (!setPublicRenderParameter(name, values)) {
200                            _params.put(name, values);
201                    }
202    
203                    _calledSetRenderParameter = true;
204            }
205    
206            @Override
207            public void setRenderParameters(Map<String, String[]> params) {
208                    if (_redirectLocation != null) {
209                            throw new IllegalStateException();
210                    }
211    
212                    if (params == null) {
213                            throw new IllegalArgumentException();
214                    }
215                    else {
216                            Map<String, String[]> newParams =
217                                    new LinkedHashMap<String, String[]>();
218    
219                            for (Map.Entry<String, String[]> entry : params.entrySet()) {
220                                    String key = entry.getKey();
221                                    String[] value = entry.getValue();
222    
223                                    if (key == null) {
224                                            throw new IllegalArgumentException();
225                                    }
226                                    else if (value == null) {
227                                            throw new IllegalArgumentException();
228                                    }
229    
230                                    if (setPublicRenderParameter(key, value)) {
231                                            continue;
232                                    }
233    
234                                    newParams.put(key, value);
235                            }
236    
237                            _params = newParams;
238                    }
239    
240                    _calledSetRenderParameter = true;
241            }
242    
243            @Override
244            public void setWindowState(WindowState windowState)
245                    throws WindowStateException {
246    
247                    if (_redirectLocation != null) {
248                            throw new IllegalStateException();
249                    }
250    
251                    if (!_portletRequestImpl.isWindowStateAllowed(windowState)) {
252                            throw new WindowStateException(windowState.toString(), windowState);
253                    }
254    
255                    try {
256                            _windowState = PortalUtil.updateWindowState(
257                                    _portletName, _user, _layout, windowState,
258                                    _portletRequestImpl.getHttpServletRequest());
259    
260                            _portletRequestImpl.setWindowState(_windowState);
261                    }
262                    catch (Exception e) {
263                            throw new WindowStateException(e, windowState);
264                    }
265    
266                    _calledSetRenderParameter = true;
267            }
268    
269            protected void init(
270                            PortletRequestImpl portletRequestImpl, HttpServletResponse response,
271                            String portletName, User user, Layout layout,
272                            WindowState windowState, PortletMode portletMode)
273                    throws PortletModeException, WindowStateException {
274    
275                    super.init(
276                            portletRequestImpl, response, portletName, layout.getCompanyId(),
277                            layout.getPlid());
278    
279                    _portletRequestImpl = portletRequestImpl;
280                    _portletName = portletName;
281                    _user = user;
282                    _layout = layout;
283                    _publicRenderParameters = PublicRenderParametersPool.get(
284                            getHttpServletRequest(), layout.getPlid());
285    
286                    if (windowState != null) {
287                            setWindowState(windowState);
288                    }
289    
290                    if (portletMode != null) {
291                            setPortletMode(portletMode);
292                    }
293    
294                    // Set _calledSetRenderParameter to false because setWindowState and
295                    // setPortletMode sets it to true
296    
297                    _calledSetRenderParameter = false;
298            }
299    
300            protected boolean setPublicRenderParameter(String name, String[] values) {
301                    Portlet portlet = getPortlet();
302    
303                    PublicRenderParameter publicRenderParameter =
304                            portlet.getPublicRenderParameter(name);
305    
306                    if (publicRenderParameter == null) {
307                            return false;
308                    }
309    
310                    com.liferay.portal.kernel.xml.QName qName =
311                            publicRenderParameter.getQName();
312    
313                    String[] oldValues = _publicRenderParameters.get(name);
314    
315                    if (oldValues != null) {
316                            values = ArrayUtil.append(oldValues, values);
317                    }
318    
319                    _publicRenderParameters.put(
320                            PortletQNameUtil.getPublicRenderParameterName(qName), values);
321    
322                    return true;
323            }
324    
325            private static Log _log = LogFactoryUtil.getLog(
326                    StateAwareResponseImpl.class);
327    
328            private boolean _calledSetRenderParameter;
329            private List<Event> _events = new ArrayList<Event>();
330            private Layout _layout;
331            private Map<String, String[]> _params =
332                    new LinkedHashMap<String, String[]>();
333            private PortletMode _portletMode;
334            private String _portletName;
335            private PortletRequestImpl _portletRequestImpl;
336            private Map<String, String[]> _publicRenderParameters;
337            private String _redirectLocation;
338            private User _user;
339            private WindowState _windowState;
340    
341    }