View Javadoc
1   /**
2    * This file Copyright (c) 2003-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.context;
35  
36  import info.magnolia.cms.beans.runtime.MultipartForm;
37  import info.magnolia.cms.core.AggregationState;
38  import info.magnolia.objectfactory.Components;
39  
40  import java.io.IOException;
41  import java.io.Writer;
42  import java.util.Enumeration;
43  import java.util.HashMap;
44  import java.util.Map;
45  import java.util.Stack;
46  
47  import javax.servlet.ServletContext;
48  import javax.servlet.ServletException;
49  import javax.servlet.ServletRequest;
50  import javax.servlet.http.HttpServletRequest;
51  import javax.servlet.http.HttpServletResponse;
52  import javax.servlet.http.HttpSession;
53  
54  
55  /**
56   * Context implementation keeping track of the current request, response, servletContext and pageContext.
57   */
58  public abstract class WebContextImpl extends UserContextImpl implements WebContext {
59      private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WebContextImpl.class);
60  
61      private HttpServletRequest request;
62  
63      private HttpServletResponse response;
64  
65      private ServletContext servletContext;
66  
67      protected AggregationState aggregationState;
68  
69      private Stack<HttpServletResponse> responseStack = new Stack<HttpServletResponse>();
70  
71      private Stack<HttpServletRequest> requestStack = new Stack<HttpServletRequest>();
72  
73      /**
74       * Use init to initialize the object.
75       */
76      public WebContextImpl() {
77          log.debug("new WebContextImpl() {}", this);
78      }
79  
80      @Override
81      public void init(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
82          this.request = request;
83          this.response = response;
84          this.servletContext = servletContext;
85          //reset();
86          //setUser(getAnonymousUser());
87          setAttributeStrategy(new RequestAttributeStrategy(this));
88          setRepositoryStrategy(createRepositoryStrategy());
89      }
90  
91      private DefaultRepositoryStrategy createRepositoryStrategy() {
92          return Components.newInstance(DefaultRepositoryStrategy.class, this);
93      }
94  
95      @Override
96      public AggregationState getAggregationState() {
97          if (aggregationState == null) {
98              aggregationState = newAggregationState();
99          }
100         return aggregationState;
101     }
102 
103     /**
104      * @see info.magnolia.context.WebContextFactoryImpl#newAggregationState()
105      */
106     protected abstract AggregationState newAggregationState();
107 
108     /**
109      * This will only reset the original URI/URL by calling {@link AggregationState#resetURIs()}.
110      */
111     @Override
112     public void resetAggregationState() {
113         getAggregationState().resetURIs();
114     }
115 
116     /**
117      * Get form object assembled by <code>MultipartRequestFilter</code>.
118      *
119      * @return multipart form object
120      */
121     @Override
122     public MultipartForm getPostedForm() {
123         return (MultipartForm) getAttribute(MultipartForm.REQUEST_ATTRIBUTE_NAME, LOCAL_SCOPE);
124     }
125 
126     /**
127      * Get parameter value as string.
128      *
129      * @return parameter value
130      */
131     @Override
132     public String getParameter(String name) {
133         return this.request.getParameter(name);
134     }
135 
136     /**
137      * Get parameter values as string[].
138      *
139      * @return parameter values
140      */
141     @Override
142     public String[] getParameterValues(String name) {
143         return this.request.getParameterValues(name);
144     }
145 
146     /**
147      * Get parameter values as a Map<String, String> (unlike HttpServletRequest.getParameterMap() which returns a Map<String,
148      * String[]>, so don't expect to retrieve multiple-valued form parameters here).
149      *
150      * @return parameter values
151      */
152     @Override
153     public Map<String, String> getParameters() {
154         Map<String, String> map = new HashMap<String, String>();
155         Enumeration<String> paramEnum = this.request.getParameterNames();
156         while (paramEnum.hasMoreElements()) {
157             final String name = paramEnum.nextElement();
158             map.put(name, this.request.getParameter(name));
159         }
160         return map;
161     }
162 
163     /**
164      * Avoid the call to this method where ever possible.
165      *
166      * @return Returns the request.
167      */
168     @Override
169     public HttpServletRequest getRequest() {
170         return this.request;
171     }
172 
173     @Override
174     public HttpServletResponse getResponse() {
175         return response;
176     }
177 
178     @Override
179     public String getContextPath() {
180         return this.request.getContextPath();
181     }
182 
183     /**
184      * Does an include using the request that was set when setting up this context, or using the
185      * request wrapped by the pageContext if existing.
186      */
187     @Override
188     public void include(final String path, final Writer out) throws ServletException, IOException {
189         try {
190             final ServletRequest requestToUse = /*pageContext != null ? pageContext.getRequest() :*/ this.getRequest();
191             final HttpServletResponse responseToUse = /*(pageContext != null && pageContext.getResponse() instanceof HttpServletResponse) ? (HttpServletResponse) pageContext.getResponse() :*/ response;
192             final WriterResponseWrapper wrappedResponse = new WriterResponseWrapper(responseToUse, out);
193 
194             requestToUse.getRequestDispatcher(path).include(requestToUse, wrappedResponse);
195         } catch (ServletException e) {
196             throw new RuntimeException(e);
197         } catch (IOException e) {
198             throw new RuntimeException(e);
199         }
200     }
201 
202     /**
203      * {@inheritDoc}
204      */
205     @Override
206     public ServletContext getServletContext() {
207         return servletContext;
208     }
209 
210     public void login() {
211         setRepositoryStrategy(createRepositoryStrategy());
212     }
213 
214     /**
215      * Closes opened JCR sessions and invalidates the current HttpSession.
216      *
217      * @see #release()
218      */
219     @Override
220     public void logout() {
221         releaseJCRSessions();
222         super.logout();
223 
224         HttpSession session = this.request.getSession(false);
225         if (session != null) {
226             session.invalidate();
227         }
228     }
229 
230     /**
231      * Closes opened JCR sessions.
232      */
233     @Override
234     public void release() {
235         releaseJCRSessions();
236         this.request = null;
237         this.response = null;
238     }
239 
240     protected void releaseJCRSessions() {
241         getRepositoryStrategy().release();
242     }
243 
244     /* (non-Javadoc)
245      * @see info.magnolia.context.WebContext#pop()
246      */
247     @Override
248     public void pop() {
249         request = requestStack.pop();
250         response = responseStack.pop();
251     }
252 
253     /* (non-Javadoc)
254      * @see info.magnolia.context.WebContext#push(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
255      */
256     @Override
257     public void push(HttpServletRequest request, HttpServletResponse response) {
258         requestStack.push(this.request);
259         this.request = request;
260         responseStack.push(this.response);
261         this.response = response;
262     }
263 }