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