001/*
002 * Copyright 2002-2013 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.mock.web.portlet;
018
019import java.security.Principal;
020import java.util.Collections;
021import java.util.Enumeration;
022import java.util.HashSet;
023import java.util.LinkedHashMap;
024import java.util.LinkedHashSet;
025import java.util.LinkedList;
026import java.util.List;
027import java.util.Locale;
028import java.util.Map;
029import java.util.Set;
030import javax.portlet.PortalContext;
031import javax.portlet.PortletContext;
032import javax.portlet.PortletMode;
033import javax.portlet.PortletPreferences;
034import javax.portlet.PortletRequest;
035import javax.portlet.PortletSession;
036import javax.portlet.WindowState;
037import javax.servlet.http.Cookie;
038
039import org.springframework.util.Assert;
040import org.springframework.util.CollectionUtils;
041
042/**
043 * Mock implementation of the {@link javax.portlet.PortletRequest} interface.
044 *
045 * @author John A. Lewis
046 * @author Juergen Hoeller
047 * @since 2.0
048 */
049public class MockPortletRequest implements PortletRequest {
050
051        private boolean active = true;
052
053        private final PortalContext portalContext;
054
055        private final PortletContext portletContext;
056
057        private PortletSession session;
058
059        private WindowState windowState = WindowState.NORMAL;
060
061        private PortletMode portletMode = PortletMode.VIEW;
062
063        private PortletPreferences portletPreferences = new MockPortletPreferences();
064
065        private final Map<String, List<String>> properties = new LinkedHashMap<String, List<String>>();
066
067        private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
068
069        private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>();
070
071        private String authType = null;
072
073        private String contextPath = "";
074
075        private String remoteUser = null;
076
077        private Principal userPrincipal = null;
078
079        private final Set<String> userRoles = new HashSet<String>();
080
081        private boolean secure = false;
082
083        private boolean requestedSessionIdValid = true;
084
085        private final List<String> responseContentTypes = new LinkedList<String>();
086
087        private final List<Locale> locales = new LinkedList<Locale>();
088
089        private String scheme = "http";
090
091        private String serverName = "localhost";
092
093        private int serverPort = 80;
094
095        private String windowID;
096
097        private Cookie[] cookies;
098
099        private final Set<String> publicParameterNames = new HashSet<String>();
100
101
102        /**
103         * Create a new MockPortletRequest with a default {@link MockPortalContext}
104         * and a default {@link MockPortletContext}.
105         *
106         * @see MockPortalContext
107         * @see MockPortletContext
108         */
109        public MockPortletRequest() {
110                this(null, null);
111        }
112
113        /**
114         * Create a new MockPortletRequest with a default {@link MockPortalContext}.
115         *
116         * @param portletContext the PortletContext that the request runs in
117         * @see MockPortalContext
118         */
119        public MockPortletRequest(PortletContext portletContext) {
120                this(null, portletContext);
121        }
122
123        /**
124         * Create a new MockPortletRequest.
125         *
126         * @param portalContext the PortalContext that the request runs in
127         * @param portletContext the PortletContext that the request runs in
128         */
129        public MockPortletRequest(PortalContext portalContext, PortletContext portletContext) {
130                this.portalContext = (portalContext != null ? portalContext : new MockPortalContext());
131                this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
132                this.responseContentTypes.add("text/html");
133                this.locales.add(Locale.ENGLISH);
134                this.attributes.put(LIFECYCLE_PHASE, getLifecyclePhase());
135        }
136
137        // ---------------------------------------------------------------------
138        // Lifecycle methods
139        // ---------------------------------------------------------------------
140
141        /**
142         * Return the Portlet 2.0 lifecycle id for the current phase.
143         */
144        protected String getLifecyclePhase() {
145                return null;
146        }
147
148        /**
149         * Return whether this request is still active (that is, not completed yet).
150         */
151        public boolean isActive() {
152                return this.active;
153        }
154
155        /**
156         * Mark this request as completed.
157         */
158        public void close() {
159                this.active = false;
160        }
161
162        /**
163         * Check whether this request is still active (that is, not completed yet),
164         * throwing an IllegalStateException if not active anymore.
165         */
166        protected void checkActive() throws IllegalStateException {
167                if (!this.active) {
168                        throw new IllegalStateException("Request is not active anymore");
169                }
170        }
171
172        // ---------------------------------------------------------------------
173        // PortletRequest methods
174        // ---------------------------------------------------------------------
175
176        @Override
177        public boolean isWindowStateAllowed(WindowState windowState) {
178                return CollectionUtils.contains(this.portalContext.getSupportedWindowStates(), windowState);
179        }
180
181        @Override
182        public boolean isPortletModeAllowed(PortletMode portletMode) {
183                return CollectionUtils.contains(this.portalContext.getSupportedPortletModes(), portletMode);
184        }
185
186        public void setPortletMode(PortletMode portletMode) {
187                Assert.notNull(portletMode, "PortletMode must not be null");
188                this.portletMode = portletMode;
189        }
190
191        @Override
192        public PortletMode getPortletMode() {
193                return this.portletMode;
194        }
195
196        public void setWindowState(WindowState windowState) {
197                Assert.notNull(windowState, "WindowState must not be null");
198                this.windowState = windowState;
199        }
200
201        @Override
202        public WindowState getWindowState() {
203                return this.windowState;
204        }
205
206        public void setPreferences(PortletPreferences preferences) {
207                Assert.notNull(preferences, "PortletPreferences must not be null");
208                this.portletPreferences = preferences;
209        }
210
211        @Override
212        public PortletPreferences getPreferences() {
213                return this.portletPreferences;
214        }
215
216        public void setSession(PortletSession session) {
217                this.session = session;
218                if (session instanceof MockPortletSession) {
219                        MockPortletSession mockSession = ((MockPortletSession) session);
220                        mockSession.access();
221                }
222        }
223
224        @Override
225        public PortletSession getPortletSession() {
226                return getPortletSession(true);
227        }
228
229        @Override
230        public PortletSession getPortletSession(boolean create) {
231                checkActive();
232                // Reset session if invalidated.
233                if (this.session instanceof MockPortletSession && ((MockPortletSession) this.session).isInvalid()) {
234                        this.session = null;
235                }
236                // Create new session if necessary.
237                if (this.session == null && create) {
238                        this.session = new MockPortletSession(this.portletContext);
239                }
240                return this.session;
241        }
242
243        /**
244         * Set a single value for the specified property.
245         * <p>
246         * If there are already one or more values registered for the given property
247         * key, they will be replaced.
248         */
249        public void setProperty(String key, String value) {
250                Assert.notNull(key, "Property key must not be null");
251                List<String> list = new LinkedList<String>();
252                list.add(value);
253                this.properties.put(key, list);
254        }
255
256        /**
257         * Add a single value for the specified property.
258         * <p>
259         * If there are already one or more values registered for the given property
260         * key, the given value will be added to the end of the list.
261         */
262        public void addProperty(String key, String value) {
263                Assert.notNull(key, "Property key must not be null");
264                List<String> oldList = this.properties.get(key);
265                if (oldList != null) {
266                        oldList.add(value);
267                }
268                else {
269                        List<String> list = new LinkedList<String>();
270                        list.add(value);
271                        this.properties.put(key, list);
272                }
273        }
274
275        @Override
276        public String getProperty(String key) {
277                Assert.notNull(key, "Property key must not be null");
278                List<String> list = this.properties.get(key);
279                return (list != null && list.size() > 0 ? list.get(0) : null);
280        }
281
282        @Override
283        public Enumeration<String> getProperties(String key) {
284                Assert.notNull(key, "property key must not be null");
285                return Collections.enumeration(this.properties.get(key));
286        }
287
288        @Override
289        public Enumeration<String> getPropertyNames() {
290                return Collections.enumeration(this.properties.keySet());
291        }
292
293        @Override
294        public PortalContext getPortalContext() {
295                return this.portalContext;
296        }
297
298        public void setAuthType(String authType) {
299                this.authType = authType;
300        }
301
302        @Override
303        public String getAuthType() {
304                return this.authType;
305        }
306
307        public void setContextPath(String contextPath) {
308                this.contextPath = contextPath;
309        }
310
311        @Override
312        public String getContextPath() {
313                return this.contextPath;
314        }
315
316        public void setRemoteUser(String remoteUser) {
317                this.remoteUser = remoteUser;
318        }
319
320        @Override
321        public String getRemoteUser() {
322                return this.remoteUser;
323        }
324
325        public void setUserPrincipal(Principal userPrincipal) {
326                this.userPrincipal = userPrincipal;
327        }
328
329        @Override
330        public Principal getUserPrincipal() {
331                return this.userPrincipal;
332        }
333
334        public void addUserRole(String role) {
335                this.userRoles.add(role);
336        }
337
338        @Override
339        public boolean isUserInRole(String role) {
340                return this.userRoles.contains(role);
341        }
342
343        @Override
344        public Object getAttribute(String name) {
345                checkActive();
346                return this.attributes.get(name);
347        }
348
349        @Override
350        public Enumeration<String> getAttributeNames() {
351                checkActive();
352                return Collections.enumeration(new LinkedHashSet<String>(this.attributes.keySet()));
353        }
354
355        public void setParameters(Map<String, String[]> parameters) {
356                Assert.notNull(parameters, "Parameters Map must not be null");
357                this.parameters.clear();
358                this.parameters.putAll(parameters);
359        }
360
361        public void setParameter(String key, String value) {
362                Assert.notNull(key, "Parameter key must be null");
363                Assert.notNull(value, "Parameter value must not be null");
364                this.parameters.put(key, new String[] { value });
365        }
366
367        public void setParameter(String key, String[] values) {
368                Assert.notNull(key, "Parameter key must be null");
369                Assert.notNull(values, "Parameter values must not be null");
370                this.parameters.put(key, values);
371        }
372
373        public void addParameter(String name, String value) {
374                addParameter(name, new String[] { value });
375        }
376
377        public void addParameter(String name, String[] values) {
378                String[] oldArr = this.parameters.get(name);
379                if (oldArr != null) {
380                        String[] newArr = new String[oldArr.length + values.length];
381                        System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
382                        System.arraycopy(values, 0, newArr, oldArr.length, values.length);
383                        this.parameters.put(name, newArr);
384                }
385                else {
386                        this.parameters.put(name, values);
387                }
388        }
389
390        @Override
391        public String getParameter(String name) {
392                String[] arr = this.parameters.get(name);
393                return (arr != null && arr.length > 0 ? arr[0] : null);
394        }
395
396        @Override
397        public Enumeration<String> getParameterNames() {
398                return Collections.enumeration(this.parameters.keySet());
399        }
400
401        @Override
402        public String[] getParameterValues(String name) {
403                return this.parameters.get(name);
404        }
405
406        @Override
407        public Map<String, String[]> getParameterMap() {
408                return Collections.unmodifiableMap(this.parameters);
409        }
410
411        public void setSecure(boolean secure) {
412                this.secure = secure;
413        }
414
415        @Override
416        public boolean isSecure() {
417                return this.secure;
418        }
419
420        @Override
421        public void setAttribute(String name, Object value) {
422                checkActive();
423                if (value != null) {
424                        this.attributes.put(name, value);
425                }
426                else {
427                        this.attributes.remove(name);
428                }
429        }
430
431        @Override
432        public void removeAttribute(String name) {
433                checkActive();
434                this.attributes.remove(name);
435        }
436
437        @Override
438        public String getRequestedSessionId() {
439                PortletSession session = this.getPortletSession();
440                return (session != null ? session.getId() : null);
441        }
442
443        public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
444                this.requestedSessionIdValid = requestedSessionIdValid;
445        }
446
447        @Override
448        public boolean isRequestedSessionIdValid() {
449                return this.requestedSessionIdValid;
450        }
451
452        public void addResponseContentType(String responseContentType) {
453                this.responseContentTypes.add(responseContentType);
454        }
455
456        public void addPreferredResponseContentType(String responseContentType) {
457                this.responseContentTypes.add(0, responseContentType);
458        }
459
460        @Override
461        public String getResponseContentType() {
462                return this.responseContentTypes.get(0);
463        }
464
465        @Override
466        public Enumeration<String> getResponseContentTypes() {
467                return Collections.enumeration(this.responseContentTypes);
468        }
469
470        public void addLocale(Locale locale) {
471                this.locales.add(locale);
472        }
473
474        public void addPreferredLocale(Locale locale) {
475                this.locales.add(0, locale);
476        }
477
478        @Override
479        public Locale getLocale() {
480                return this.locales.get(0);
481        }
482
483        @Override
484        public Enumeration<Locale> getLocales() {
485                return Collections.enumeration(this.locales);
486        }
487
488        public void setScheme(String scheme) {
489                this.scheme = scheme;
490        }
491
492        @Override
493        public String getScheme() {
494                return this.scheme;
495        }
496
497        public void setServerName(String serverName) {
498                this.serverName = serverName;
499        }
500
501        @Override
502        public String getServerName() {
503                return this.serverName;
504        }
505
506        public void setServerPort(int serverPort) {
507                this.serverPort = serverPort;
508        }
509
510        @Override
511        public int getServerPort() {
512                return this.serverPort;
513        }
514
515        public void setWindowID(String windowID) {
516                this.windowID = windowID;
517        }
518
519        @Override
520        public String getWindowID() {
521                return this.windowID;
522        }
523
524        public void setCookies(Cookie... cookies) {
525                this.cookies = cookies;
526        }
527
528        @Override
529        public Cookie[] getCookies() {
530                return this.cookies;
531        }
532
533        @Override
534        public Map<String, String[]> getPrivateParameterMap() {
535                if (!this.publicParameterNames.isEmpty()) {
536                        Map<String, String[]> filtered = new LinkedHashMap<String, String[]>();
537                        for (String key : this.parameters.keySet()) {
538                                if (!this.publicParameterNames.contains(key)) {
539                                        filtered.put(key, this.parameters.get(key));
540                                }
541                        }
542                        return filtered;
543                }
544                else {
545                        return Collections.unmodifiableMap(this.parameters);
546                }
547        }
548
549        @Override
550        public Map<String, String[]> getPublicParameterMap() {
551                if (!this.publicParameterNames.isEmpty()) {
552                        Map<String, String[]> filtered = new LinkedHashMap<String, String[]>();
553                        for (String key : this.parameters.keySet()) {
554                                if (this.publicParameterNames.contains(key)) {
555                                        filtered.put(key, this.parameters.get(key));
556                                }
557                        }
558                        return filtered;
559                }
560                else {
561                        return Collections.emptyMap();
562                }
563        }
564
565        public void registerPublicParameter(String name) {
566                this.publicParameterNames.add(name);
567        }
568
569}