View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.orchestra.frameworkAdapter.basic;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.myfaces.orchestra.conversation.ConversationMessager;
24  import org.apache.myfaces.orchestra.conversation.basic.LogConversationMessager;
25  import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;
26  import org.apache.myfaces.orchestra.lib._ClassUtils;
27  
28  import javax.servlet.ServletContext;
29  import javax.servlet.ServletRequest;
30  import javax.servlet.ServletResponse;
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  import java.io.IOException;
34  
35  /**
36   * An implementation of the FrameworkAdapter for plain servlet environments.
37   * <p>
38   * This class requires the BasicFrameworkAdapterFilter to be configured to run
39   * for every request.
40   * 
41   * <h2>Configuring the ConversationMessager</h2>
42   * 
43   * This class allows the concrete ConversationMessager instance returned
44   * by the getConversationMessager method to be configured
45   * in a number of ways:
46   * <ul>
47   * <li>By calling an explicit setter, passing an instance.</li>
48   * <li>By specifying a conversationMessagerName parameter to the constructor
49   * of this method which matches a bean name defined in the dependency injection
50   * framework.</li>
51   * <li>By specifying a conversationMessagerName that is the fully-qualified
52   * name of a ConversationMessager class to be instantiated</li>
53   * <li>Otherwise, method createDefaultConversationMessager is called which
54   * returns a LogConversationMessager instance (unless overridden in a subclass).</li>
55   * </ul>
56   * 
57   * See also the BasicFrameworkAdapterFilter class.
58   */
59  public class BasicFrameworkAdapter extends FrameworkAdapter
60  {
61      private final static String ISE_MESSAGE="No request/response data available"; // NON-NLS
62  
63      private final static ThreadLocal httpServletRequestThreadLocal = new ThreadLocal();
64      private final static ThreadLocal httpServletResponseThreadLocal = new ThreadLocal();
65  
66      private final Log log = LogFactory.getLog(BasicFrameworkAdapter.class);
67  
68      private final ServletContext servletContext;
69      private final String conversationMessagerClass;
70  
71      public BasicFrameworkAdapter(ServletContext context, String conversationMessagerClass)
72      {
73          servletContext = context;
74          this.conversationMessagerClass = conversationMessagerClass;
75      }
76  
77      protected ConversationMessager createConversationMessager()
78      {
79          if (conversationMessagerClass == null)
80          {
81              return createDefaultConversationMessager();
82          }
83  
84          // First try to find a bean of that name in the dependency-injection
85          // framework.
86          Object instance = getBean(conversationMessagerClass);
87          if (instance instanceof ConversationMessager)
88          {
89              return (ConversationMessager) instance;
90          }
91  
92          // Now resort to trying the value as a classname.
93          return (ConversationMessager) _ClassUtils.newInstance(conversationMessagerClass);
94      }
95  
96      protected ConversationMessager createDefaultConversationMessager()
97      {
98          return new LogConversationMessager();
99      }
100 
101     private HttpServletRequest getRequest()
102     {
103         return (HttpServletRequest) httpServletRequestThreadLocal.get();
104     }
105 
106     private HttpServletResponse getResponse()
107     {
108         return (HttpServletResponse) httpServletResponseThreadLocal.get();
109     }
110 
111     public void beginRequest(ServletRequest req, ServletResponse rsp)
112     {
113         log.debug("Beginning request");
114         if (req instanceof HttpServletRequest)
115         {
116             httpServletRequestThreadLocal.set(req);
117         }
118         if (rsp instanceof HttpServletResponse)
119         {
120             httpServletResponseThreadLocal.set(rsp);
121         }
122 
123         FrameworkAdapter.setCurrentInstance(this);
124     }
125 
126     public void endRequest()
127     {
128         log.debug("Ending request");
129         FrameworkAdapter.setCurrentInstance(null);
130         httpServletRequestThreadLocal.set(null);
131         httpServletResponseThreadLocal.set(null);
132     }
133 
134     public String getInitParameter(String key)
135     {
136         return servletContext.getInitParameter(key);
137     }
138 
139     public Object getRequestParameterAttribute(String key)
140     {
141         HttpServletRequest request = getRequest();
142         if (request != null)
143         {
144             return request.getParameter(key);
145         }
146 
147         throw new IllegalStateException(ISE_MESSAGE);
148     }
149 
150     public boolean containsRequestParameterAttribute(String key)
151     {
152         HttpServletRequest request = getRequest();
153         if (request != null)
154         {
155             return request.getParameter(key) != null;
156         }
157 
158         throw new IllegalStateException(ISE_MESSAGE);
159     }
160 
161     public Object getRequestAttribute(String key)
162     {
163         HttpServletRequest request = getRequest();
164         if (request != null)
165         {
166             return request.getAttribute(key);
167         }
168 
169         throw new IllegalStateException(ISE_MESSAGE);
170     }
171 
172     public void setRequestAttribute(String key, Object value)
173     {
174         HttpServletRequest request = getRequest();
175         if (request != null)
176         {
177             request.setAttribute(key, value);
178             return;
179         }
180 
181         throw new IllegalStateException(ISE_MESSAGE);
182     }
183 
184     public boolean containsRequestAttribute(String key)
185     {
186         HttpServletRequest request = getRequest();
187         if (request != null)
188         {
189             return request.getAttribute(key) != null;
190         }
191 
192         throw new IllegalStateException(ISE_MESSAGE);
193     }
194 
195     public Object getSessionAttribute(String key)
196     {
197         HttpServletRequest request = getRequest();
198         if (request != null && request.getSession(true) != null)
199         {
200             return request.getSession(true).getAttribute(key);
201         }
202 
203         throw new IllegalStateException(ISE_MESSAGE);
204     }
205 
206     public void setSessionAttribute(String key, Object value)
207     {
208         HttpServletRequest request = getRequest();
209         if (request != null && request.getSession(true) != null)
210         {
211             request.getSession(true).setAttribute(key, value);
212             return;
213         }
214 
215     }
216 
217     public boolean containsSessionAttribute(String key)
218     {
219         HttpServletRequest request = getRequest();
220         if (request != null && request.getSession(true) != null)
221         {
222             return request.getSession(true).getAttribute(key) != null;
223         }
224 
225         throw new IllegalStateException(ISE_MESSAGE);
226     }
227 
228     protected String getRequestContextPath()
229     {
230         HttpServletRequest request = getRequest();
231         if (request != null)
232         {
233             return request.getContextPath();
234         }
235 
236         throw new IllegalStateException(ISE_MESSAGE);
237     }
238 
239     public void redirect(String url) throws IOException
240     {
241         StringBuffer redir = new StringBuffer();
242         if (url.startsWith("/"))
243         {
244             redir.append(getRequestContextPath());
245         }
246         redir.append(url);
247 
248         HttpServletResponse rsp = getResponse();
249         String dstUrl = rsp.encodeRedirectURL(redir.toString());
250         rsp.sendRedirect(dstUrl);
251     }
252 
253     /**
254      * Look in the request and session scopes for an entry
255      * with the specified name.
256      * <p>
257      * This basic adapter class does not support invoking the JSP expression
258      * evaluator; no "variable resolver" will ever be used to look up the
259      * specified name.
260      * <p>
261      * TODO: also look in the application scope.
262      * <p>
263      * TODO: investigate invoking the jsp.ExpressionFactory class to look up
264      * the variable. Possibly that could be done in a different JspFrameworkAdapter
265      * class.
266      */
267     public Object getBean(String name)
268     {
269         Object obj;
270 
271         obj = getRequestAttribute(name);
272         if (obj != null)
273         {
274             return obj;
275         }
276 
277         obj = getSessionAttribute(name);
278         if (obj != null)
279         {
280             return obj;
281         }
282 
283         // TODO: look up application-scoped objects.
284 
285         return null;
286     }
287 
288     /**
289      * Perform a redirect to the specified url.
290      * <p>
291      * A redirect is done rather than a forward so that the remote browser has its
292      * current url updated appropriately. Note that a redirect does cause any
293      * request-scoped variables to be discarded.
294      */
295     public void invokeNavigation(String navigationName) throws IOException
296     {
297         redirect(navigationName);
298     }
299 }