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         if (log.isDebugEnabled())
    114         {
    115             log.debug("Beginning request");
    116         }
    117         if (req instanceof HttpServletRequest)
    118         {
    119             httpServletRequestThreadLocal.set(req);
    120         }
    121         if (rsp instanceof HttpServletResponse)
    122         {
    123             httpServletResponseThreadLocal.set(rsp);
    124         }
    125
    126         FrameworkAdapter.setCurrentInstance(this);
    127     }
    128
    129     public void endRequest()
    130     {
    131         if (log.isDebugEnabled())
    132         {
    133             log.debug("Ending request");
    134         }
    135         FrameworkAdapter.setCurrentInstance(null);
    136         httpServletRequestThreadLocal.set(null);
    137         httpServletResponseThreadLocal.set(null);
    138     }
    139
    140     public String getInitParameter(String key)
    141     {
    142         return servletContext.getInitParameter(key);
    143     }
    144
    145     public Object getRequestParameterAttribute(String key)
    146     {
    147         HttpServletRequest request = getRequest();
    148         if (request != null)
    149         {
    150             return request.getParameter(key);
    151         }
    152
    153         throw new IllegalStateException(ISE_MESSAGE);
    154     }
    155
    156     public boolean containsRequestParameterAttribute(String key)
    157     {
    158         HttpServletRequest request = getRequest();
    159         if (request != null)
    160         {
    161             return request.getParameter(key) != null;
    162         }
    163
    164         throw new IllegalStateException(ISE_MESSAGE);
    165     }
    166
    167     public Object getRequestAttribute(String key)
    168     {
    169         HttpServletRequest request = getRequest();
    170         if (request != null)
    171         {
    172             return request.getAttribute(key);
    173         }
    174
    175         throw new IllegalStateException(ISE_MESSAGE);
    176     }
    177
    178     public void setRequestAttribute(String key, Object value)
    179     {
    180         HttpServletRequest request = getRequest();
    181         if (request != null)
    182         {
    183             request.setAttribute(key, value);
    184             return;
    185         }
    186
    187         throw new IllegalStateException(ISE_MESSAGE);
    188     }
    189
    190     public boolean containsRequestAttribute(String key)
    191     {
    192         HttpServletRequest request = getRequest();
    193         if (request != null)
    194         {
    195             return request.getAttribute(key) != null;
    196         }
    197
    198         throw new IllegalStateException(ISE_MESSAGE);
    199     }
    200
    201     public Object getSessionAttribute(String key)
    202     {
    203         HttpServletRequest request = getRequest();
    204         if (request != null && request.getSession(true) != null)
    205         {
    206             return request.getSession(true).getAttribute(key);
    207         }
    208
    209         throw new IllegalStateException(ISE_MESSAGE);
    210     }
    211
    212     public void setSessionAttribute(String key, Object value)
    213     {
    214         HttpServletRequest request = getRequest();
    215         if (request != null && request.getSession(true) != null)
    216         {
    217             request.getSession(true).setAttribute(key, value);
    218             return;
    219         }
    220
    221     }
    222
    223     public boolean containsSessionAttribute(String key)
    224     {
    225         HttpServletRequest request = getRequest();
    226         if (request != null && request.getSession(true) != null)
    227         {
    228             return request.getSession(true).getAttribute(key) != null;
    229         }
    230
    231         throw new IllegalStateException(ISE_MESSAGE);
    232     }
    233
    234     protected String getRequestContextPath()
    235     {
    236         HttpServletRequest request = getRequest();
    237         if (request != null)
    238         {
    239             return request.getContextPath();
    240         }
    241
    242         throw new IllegalStateException(ISE_MESSAGE);
    243     }
    244
    245     public void redirect(String url) throws IOException
    246     {
    247         StringBuffer redir = new StringBuffer();
    248         if (url.startsWith("/"))
    249         {
    250             redir.append(getRequestContextPath());
    251         }
    252         redir.append(url);
    253
    254         HttpServletResponse rsp = getResponse();
    255         String dstUrl = rsp.encodeRedirectURL(redir.toString());
    256         rsp.sendRedirect(dstUrl);
    257     }
    258
    259     /**
    260      * Look in the request and session scopes for an entry
    261      * with the specified name.
    262      * <p>
    263      * This basic adapter class does not support invoking the JSP expression
    264      * evaluator; no "variable resolver" will ever be used to look up the
    265      * specified name.
    266      * <p>
    267      * TODO: also look in the application scope.
    268      * <p>
    269      * TODO: investigate invoking the jsp.ExpressionFactory class to look up
    270      * the variable. Possibly that could be done in a different JspFrameworkAdapter
    271      * class.
    272      */
    273     public Object getBean(String name)
    274     {
    275         Object obj;
    276
    277         obj = getRequestAttribute(name);
    278         if (obj != null)
    279         {
    280             return obj;
    281         }
    282
    283         obj = getSessionAttribute(name);
    284         if (obj != null)
    285         {
    286             return obj;
    287         }
    288
    289         // TODO: look up application-scoped objects.
    290
    291         return null;
    292     }
    293
    294     /**
    295      * Perform a redirect to the specified url.
    296      * <p>
    297      * A redirect is done rather than a forward so that the remote browser has its
    298      * current url updated appropriately. Note that a redirect does cause any
    299      * request-scoped variables to be discarded.
    300      */
    301     public void invokeNavigation(String navigationName) throws IOException
    302     {
    303         redirect(navigationName);
    304     }
    305 }