001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.chain.web.javax.portlet;
018
019import java.util.Collections;
020import java.util.Map;
021
022import javax.portlet.PortletContext;
023import javax.portlet.PortletRequest;
024import javax.portlet.PortletResponse;
025import javax.servlet.http.Cookie;
026
027import org.apache.commons.chain.web.javax.WebContext;
028
029/**
030 * Concrete implementation of {@link WebContext} suitable for use in
031 * portlets. The abstract methods are mapped to the appropriate
032 * collections of the underlying portlet context, request, and response
033 * instances that are passed to the constructor (or the initialize method).
034 *
035 * @author Craig R. McClanahan
036 */
037public class PortletWebContext extends WebContext {
038    private static final long serialVersionUID = 7590757017994210786L;
039
040    // ------------------------------------------------------ Instance Variables
041
042    /**
043     * The lazily instantiated {@code Map} of application scope
044     * attributes.
045     */
046    private transient Map<String, Object> applicationScope = null;
047
048    /**
049     * The {@code PortletContext} for this web application.
050     */
051    private transient PortletContext context = null;
052
053    /**
054     * The lazily instantiated {@code Map} of header name-value
055     * combinations (immutable).
056     */
057    private transient Map<String, String> header = null;
058
059    /**
060     * The lazily instantiated {@code Map} of header name-values
061     * combinations (immutable).
062     */
063    private transient Map<String, String[]> headerValues = null;
064
065    /**
066     * The lazily instantiated {@code Map} of context initialization
067     * parameters.
068     */
069    private transient Map<String, String> initParam = null;
070
071    /**
072     * The lazily instantiated {@code Map} of cookies.
073     */
074    private transient Map<String, Cookie> cookieValues = null;
075
076    /**
077     * The lazily instantiated {@code Map} of request
078     * parameter name-value.
079     */
080    private transient Map<String, String> param = null;
081
082    /**
083     * The lazily instantiated {@code Map} of request
084     * parameter name-values.
085     */
086    private transient Map<String, String[]> paramValues = null;
087
088    /**
089     * The {@code PortletRequest} for this request.
090     */
091    private transient PortletRequest request = null;
092
093    /**
094     * The lazily instantiated {@code Map} of request scope
095     * attributes.
096     */
097    private transient Map<String, Object> requestScope = null;
098
099    /**
100     * The {@code PortletResponse} for this request.
101     */
102    private transient PortletResponse response = null;
103
104    /**
105     * The lazily instantiated {@code Map} of session scope
106     * attributes.
107     */
108    private transient Map<String, Object> sessionScope = null;
109
110    // ------------------------------------------------------------ Constructors
111
112    /**
113     * Construct an uninitialized {@link PortletWebContext} instance.
114     */
115    public PortletWebContext() {
116    }
117
118    /**
119     * Construct a {@link PortletWebContext} instance that is initialized
120     * with the specified Portlet API objects.
121     *
122     * @param context The {@code PortletContext} for this web application
123     * @param request The {@code PortletRequest} for this request
124     * @param response The {@code PortletResponse} for this request
125     */
126    public PortletWebContext(PortletContext context,
127                             PortletRequest request,
128                             PortletResponse response) {
129
130        initialize(context, request, response);
131    }
132
133    // ---------------------------------------------------------- Public Methods
134
135    /**
136     * Return the {@link PortletContext} for this context.
137     *
138     * @return The {@code PortletContext} for this request
139     */
140    public PortletContext getContext() {
141        return this.context;
142    }
143
144    /**
145     * Return the {@link PortletRequest} for this context.
146     *
147     * @return The {@code PortletRequest} for this context.
148     */
149    public PortletRequest getRequest() {
150        return this.request;
151    }
152
153    /**
154     * Return the {@link PortletResponse} for this context.
155     *
156     * @return The {@code PortletResponse} for this context.
157     */
158    public PortletResponse getResponse() {
159        return this.response;
160    }
161
162    /**
163     * Initialize (or reinitialize) this {@link PortletWebContext} instance
164     * for the specified Portlet API objects.
165     *
166     * @param context The {@code PortletContext} for this web application
167     * @param request The {@code PortletRequest} for this request
168     * @param response The {@code PortletResponse} for this request
169     */
170    public void initialize(PortletContext context,
171                           PortletRequest request,
172                           PortletResponse response) {
173
174        // Save the specified Portlet API object references
175        this.context = context;
176        this.request = request;
177        this.response = response;
178
179        // Perform other setup as needed
180    }
181
182    /**
183     * Release references to allocated resources acquired in
184     * {@code initialize()} of via subsequent processing. After this
185     * method is called, subsequent calls to any other method than
186     * {@code initialize()} will return undefined results.
187     */
188    public void release() {
189        // Release references to allocated collections
190        applicationScope = null;
191        header = null;
192        headerValues = null;
193        initParam = null;
194        param = null;
195        paramValues = null;
196        cookieValues = null;
197        requestScope = null;
198        sessionScope = null;
199
200        // Release references to Portlet API objects
201        context = null;
202        request = null;
203        response = null;
204    }
205
206    // ------------------------------------------------------ WebContext Methods
207
208    /**
209     * See the {@link WebContext}'s Javadoc.
210     *
211     * @return Application scope Map.
212     */
213    @Override
214    public Map<String, Object> getApplicationScope() {
215        if (applicationScope == null && context != null) {
216            applicationScope = new PortletApplicationScopeMap(context);
217        }
218        return applicationScope;
219    }
220
221    /**
222     * See the {@link WebContext}'s Javadoc.
223     *
224     * @return Header values Map.
225     */
226    @Override
227    public Map<String, String> getHeader() {
228        if (header == null && request != null) {
229            // header = new PortletHeaderMap(request);
230            header = Collections.emptyMap();
231        }
232        return header;
233    }
234
235    /**
236     * See the {@link WebContext}'s Javadoc.
237     *
238     * @return Header values Map.
239     */
240    @Override
241    public Map<String, String[]> getHeaderValues() {
242        if (headerValues == null && request != null) {
243            // headerValues = new PortletHeaderValuesMap(request);
244            headerValues = Collections.emptyMap();
245        }
246        return headerValues;
247    }
248
249    /**
250     * See the {@link WebContext}'s Javadoc.
251     *
252     * @return Initialization parameter Map.
253     */
254    @Override
255    public Map<String, String> getInitParam() {
256        if (initParam == null && context != null) {
257            initParam = new PortletInitParamMap(context);
258        }
259        return initParam;
260    }
261
262    /**
263     * See the {@link WebContext}'s Javadoc.
264     *
265     * @return Request parameter Map.
266     */
267    @Override
268    public Map<String, String> getParam() {
269        if (param == null && request != null) {
270            param = new PortletParamMap(request);
271        }
272        return param;
273    }
274
275    /**
276     * See the {@link WebContext}'s Javadoc.
277     *
278     * @return Request parameter Map.
279     */
280    @Override
281    public Map<String, String[]> getParamValues() {
282        if (paramValues == null && request != null) {
283            paramValues = new PortletParamValuesMap(request);
284        }
285        return paramValues;
286    }
287
288    /**
289     * See the {@link WebContext}'s Javadoc.
290     *
291     * @return Map of Cookies.
292     * @since Chain 1.1
293     */
294    @Override
295    public Map<String, Cookie> getCookies() {
296        if (cookieValues == null && request != null) {
297            cookieValues = new PortletCookieMap(request);
298        }
299        return cookieValues;
300    }
301
302    /**
303     * See the {@link WebContext}'s Javadoc.
304     *
305     * @return Request scope Map.
306     */
307    @Override
308    public Map<String, Object> getRequestScope() {
309        if (requestScope == null && request != null) {
310            requestScope = new PortletRequestScopeMap(request);
311        }
312        return requestScope;
313    }
314
315    /**
316     * See the {@link WebContext}'s Javadoc.
317     *
318     * @return Session scope Map.
319     */
320    @Override
321    public Map<String, Object> getSessionScope() {
322        if (sessionScope == null && request != null) {
323            sessionScope = new PortletSessionScopeMap(request);
324        }
325        return sessionScope;
326    }
327}