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.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 = new LinkedHashMap<>();
217    
218                            for (Map.Entry<String, String[]> entry : params.entrySet()) {
219                                    String key = entry.getKey();
220                                    String[] value = entry.getValue();
221    
222                                    if (key == null) {
223                                            throw new IllegalArgumentException();
224                                    }
225                                    else if (value == null) {
226                                            throw new IllegalArgumentException();
227                                    }
228    
229                                    if (setPublicRenderParameter(key, value)) {
230                                            continue;
231                                    }
232    
233                                    newParams.put(key, value);
234                            }
235    
236                            _params = newParams;
237                    }
238    
239                    _calledSetRenderParameter = true;
240            }
241    
242            @Override
243            public void setWindowState(WindowState windowState)
244                    throws WindowStateException {
245    
246                    if (_redirectLocation != null) {
247                            throw new IllegalStateException();
248                    }
249    
250                    if (!_portletRequestImpl.isWindowStateAllowed(windowState)) {
251                            throw new WindowStateException(windowState.toString(), windowState);
252                    }
253    
254                    try {
255                            _windowState = PortalUtil.updateWindowState(
256                                    _portletName, _user, _layout, windowState,
257                                    _portletRequestImpl.getHttpServletRequest());
258    
259                            _portletRequestImpl.setWindowState(_windowState);
260                    }
261                    catch (Exception e) {
262                            throw new WindowStateException(e, windowState);
263                    }
264    
265                    _calledSetRenderParameter = true;
266            }
267    
268            protected void init(
269                            PortletRequestImpl portletRequestImpl, HttpServletResponse response,
270                            String portletName, User user, Layout layout,
271                            WindowState windowState, PortletMode portletMode)
272                    throws PortletModeException, WindowStateException {
273    
274                    super.init(
275                            portletRequestImpl, response, portletName, layout.getCompanyId(),
276                            layout.getPlid());
277    
278                    _portletRequestImpl = portletRequestImpl;
279                    _portletName = portletName;
280                    _user = user;
281                    _layout = layout;
282                    _publicRenderParameters = PublicRenderParametersPool.get(
283                            getHttpServletRequest(), layout.getPlid());
284    
285                    if (windowState != null) {
286                            setWindowState(windowState);
287                    }
288    
289                    if (portletMode != null) {
290                            setPortletMode(portletMode);
291                    }
292    
293                    // Set _calledSetRenderParameter to false because setWindowState and
294                    // setPortletMode sets it to true
295    
296                    _calledSetRenderParameter = false;
297            }
298    
299            protected void reset() {
300                    _calledSetRenderParameter = false;
301                    _events.clear();
302                    _params.clear();
303                    _portletMode = null;
304                    _redirectLocation = null;
305                    _windowState = null;
306            }
307    
308            protected boolean setPublicRenderParameter(String name, String[] values) {
309                    Portlet portlet = getPortlet();
310    
311                    PublicRenderParameter publicRenderParameter =
312                            portlet.getPublicRenderParameter(name);
313    
314                    if (publicRenderParameter == null) {
315                            return false;
316                    }
317    
318                    com.liferay.portal.kernel.xml.QName qName =
319                            publicRenderParameter.getQName();
320    
321                    String[] oldValues = _publicRenderParameters.get(name);
322    
323                    if (oldValues != null) {
324                            values = ArrayUtil.append(oldValues, values);
325                    }
326    
327                    _publicRenderParameters.put(
328                            PortletQNameUtil.getPublicRenderParameterName(qName), values);
329    
330                    return true;
331            }
332    
333            private static final Log _log = LogFactoryUtil.getLog(
334                    StateAwareResponseImpl.class);
335    
336            private boolean _calledSetRenderParameter;
337            private final List<Event> _events = new ArrayList<>();
338            private Layout _layout;
339            private Map<String, String[]> _params = new LinkedHashMap<>();
340            private PortletMode _portletMode;
341            private String _portletName;
342            private PortletRequestImpl _portletRequestImpl;
343            private Map<String, String[]> _publicRenderParameters;
344            private String _redirectLocation;
345            private User _user;
346            private WindowState _windowState;
347    
348    }