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.jakarta.servlet;
018
019import java.util.Map;
020
021import org.apache.commons.chain.web.jakarta.WebContext;
022
023import jakarta.servlet.ServletContext;
024import jakarta.servlet.http.Cookie;
025import jakarta.servlet.http.HttpServletRequest;
026import jakarta.servlet.http.HttpServletResponse;
027
028/**
029 * Concrete implementation of {@link WebContext} suitable for use in
030 * Servlets and JSP pages. The abstract methods are mapped to the appropriate
031 * collections of the underlying servlet context, request, and response
032 * instances that are passed to the constructor (or the initialize method).
033 *
034 * @author Craig R. McClanahan
035 */
036public class ServletWebContext extends WebContext {
037    private static final long serialVersionUID = 5302874006663111922L;
038
039    // ------------------------------------------------------ Instance Variables
040
041    /**
042     * The lazily instantiated {@code Map} of application scope
043     * attributes.
044     */
045    private transient Map<String, Object> applicationScope = null;
046
047    /**
048     * The {@code ServletContext} for this web application.
049     */
050    private transient ServletContext context = null;
051
052    /**
053     * The lazily instantiated {@code Map} of header name-value
054     * combinations (immutable).
055     */
056    private transient Map<String, String> header = null;
057
058    /**
059     * The lazily instantiated {@code Map} of header name-values
060     * combinations (immutable).
061     */
062    private transient Map<String, String[]> headerValues = null;
063
064    /**
065     * The lazily instantiated {@code Map} of context initialization
066     * parameters.
067     */
068    private transient Map<String, String> initParam = null;
069
070    /**
071     * The lazily instantiated {@code Map} of cookies.
072     */
073    private transient Map<String, Cookie> cookieValues = null;
074
075    /**
076     * The lazily instantiated {@code Map} of request
077     * parameter name-value.
078     */
079    private transient Map<String, String> param = null;
080
081    /**
082     * The lazily instantiated {@code Map} of request
083     * parameter name-values.
084     */
085    private transient Map<String, String[]> paramValues = null;
086
087    /**
088     * The {@code HttpServletRequest} for this request.
089     */
090    private transient HttpServletRequest request = null;
091
092    /**
093     * The lazily instantiated {@code Map} of request scope
094     * attributes.
095     */
096    private transient Map<String, Object> requestScope = null;
097
098    /**
099     * The {@code HttpServletResponse} for this request.
100     */
101    private transient HttpServletResponse response = null;
102
103    /**
104     * The lazily instantiated {@code Map} of session scope
105     * attributes.
106     */
107    private transient Map<String, Object> sessionScope = null;
108
109    // ------------------------------------------------------------ Constructors
110
111    /**
112     * Construct an uninitialized {@link ServletWebContext} instance.
113     */
114    public ServletWebContext() {
115    }
116
117    /**
118     * Construct a {@link ServletWebContext} instance that is initialized
119     * with the specified Servlet API objects.
120     *
121     * @param context The {@code ServletContext} for this web application
122     * @param request The {@code HttpServletRequest} for this request
123     * @param response The {@code HttpServletResponse} for this request
124     */
125    public ServletWebContext(ServletContext context,
126                             HttpServletRequest request,
127                             HttpServletResponse response) {
128
129        initialize(context, request, response);
130    }
131
132    // ---------------------------------------------------------- Public Methods
133
134    /**
135     * Return the {@link ServletContext} for this context.
136     *
137     * @return The {@code ServletContext} for this context.
138     */
139    public ServletContext getContext() {
140        return this.context;
141    }
142
143    /**
144     * Return the {@link HttpServletRequest} for this context.
145     *
146     * @return The {@code HttpServletRequest} for this context.
147     */
148    public HttpServletRequest getRequest() {
149        return this.request;
150    }
151
152    /**
153     * Return the {@link HttpServletResponse} for this context.
154     *
155     * @return The {@code HttpServletResponse} for this context.
156     */
157    public HttpServletResponse getResponse() {
158        return this.response;
159    }
160
161    /**
162     * Initialize (or reinitialize) this {@link ServletWebContext} instance
163     * for the specified Servlet API objects.
164     *
165     * @param context The {@code ServletContext} for this web application
166     * @param request The {@code HttpServletRequest} for this request
167     * @param response The {@code HttpServletResponse} for this request
168     */
169    public void initialize(ServletContext context,
170                           HttpServletRequest request,
171                           HttpServletResponse response) {
172
173        // Save the specified Servlet API object references
174        this.context = context;
175        this.request = request;
176        this.response = response;
177
178        // Perform other setup as needed
179    }
180
181    /**
182     * Release references to allocated resources acquired in
183     * {@code initialize()} of via subsequent processing. After this
184     * method is called, subsequent calls to any other method than
185     * {@code initialize()} will return undefined results.
186     */
187    public void release() {
188        // Release references to allocated collections
189        applicationScope = null;
190        header = null;
191        headerValues = null;
192        initParam = null;
193        param = null;
194        paramValues = null;
195        cookieValues = null;
196        requestScope = null;
197        sessionScope = null;
198
199        // Release references to Servlet API objects
200        context = null;
201        request = null;
202        response = null;
203    }
204
205    // ------------------------------------------------------ WebContext Methods
206
207    /**
208     * See the {@link WebContext}'s Javadoc.
209     *
210     * @return Application scope Map.
211     */
212    @Override
213    public Map<String, Object> getApplicationScope() {
214        if (applicationScope == null && context != null) {
215            applicationScope = new ServletApplicationScopeMap(context);
216        }
217        return applicationScope;
218    }
219
220    /**
221     * See the {@link WebContext}'s Javadoc.
222     *
223     * @return Header values Map.
224     */
225    @Override
226    public Map<String, String> getHeader() {
227        if (header == null && request != null) {
228            header = new ServletHeaderMap(request);
229        }
230        return header;
231    }
232
233    /**
234     * See the {@link WebContext}'s Javadoc.
235     *
236     * @return Header values Map.
237     */
238    @Override
239    public Map<String, String[]> getHeaderValues() {
240        if (headerValues == null && request != null) {
241            headerValues = new ServletHeaderValuesMap(request);
242        }
243        return headerValues;
244    }
245
246    /**
247     * See the {@link WebContext}'s Javadoc.
248     *
249     * @return Initialization parameter Map.
250     */
251    @Override
252    public Map<String, String> getInitParam() {
253        if (initParam == null && context != null) {
254            initParam = new ServletInitParamMap(context);
255        }
256        return initParam;
257    }
258
259    /**
260     * See the {@link WebContext}'s Javadoc.
261     *
262     * @return Request parameter Map.
263     */
264    @Override
265    public Map<String, String> getParam() {
266        if (param == null && request != null) {
267            param = new ServletParamMap(request);
268        }
269        return param;
270    }
271
272    /**
273     * See the {@link WebContext}'s Javadoc.
274     *
275     * @return Request parameter Map.
276     */
277    @Override
278    public Map<String, String[]> getParamValues() {
279        if (paramValues == null && request != null) {
280            paramValues = new ServletParamValuesMap(request);
281        }
282        return paramValues;
283    }
284
285    /**
286     * See the {@link WebContext}'s Javadoc.
287     *
288     * @return Map of Cookies.
289     * @since Chain 1.1
290     */
291    @Override
292    public Map<String, Cookie> getCookies() {
293        if (cookieValues == null && request != null) {
294            cookieValues = new ServletCookieMap(request);
295        }
296        return cookieValues;
297    }
298
299    /**
300     * See the {@link WebContext}'s Javadoc.
301     *
302     * @return Request scope Map.
303     */
304    @Override
305    public Map<String, Object> getRequestScope() {
306        if (requestScope == null && request != null) {
307            requestScope = new ServletRequestScopeMap(request);
308        }
309        return requestScope;
310    }
311
312    /**
313     * See the {@link WebContext}'s Javadoc.
314     *
315     * @return Session scope Map.
316     */
317    @Override
318    public Map<String, Object> getSessionScope() {
319        if (sessionScope == null && request != null) {
320            sessionScope = new ServletSessionScopeMap(request);
321        }
322        return sessionScope;
323    }
324}