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.util;
20  
21  import javax.faces.context.ExternalContext;
22  import javax.servlet.ServletContext;
23  
24  import org.apache.myfaces.shared.util.ExternalContextUtils;
25  
26  /**
27   * Utilities for determining the current container and for the unified
28   * expression language.
29   * 
30   */
31  public class ContainerUtils
32  {
33      /**
34       * Used for determining whether Myfaces is running on Google App Engine.
35       */
36      private static final String GAE_SERVER_INFO_BEGINNING = "Google App Engine";
37  
38      /**
39       * Determines whether we're running in a Servlet 2.5/JSP 2.1 environment.
40       * 
41       * @return <code>true</code> if we're running in a JSP 2.1 environment,
42       *         <code>false</code> otherwise
43       */
44      public static boolean isJsp21(ServletContext context)
45      {
46          //if running on GAE, treat like it is JSP 2.0
47          if(isRunningOnGoogleAppEngine(context))
48          {
49              return false;
50          }
51          
52          try 
53          {
54              // simply check if the class JspApplicationContext is available
55              Class.forName("javax.servlet.jsp.JspApplicationContext");
56              return true;
57          } 
58          catch (ClassNotFoundException ex) 
59          {
60              // expected exception in a JSP 2.0 (or less) environment
61          }
62          
63          return false;
64      }
65      
66      /**
67       * Return true if the specified string contains an EL expression.
68       * 
69       * <p>
70       * <strong>NOTICE</strong> This method is just a copy of
71       * {@link javax.faces.webapp.UIComponentTag#isValueReference(String)}, but it's required
72       * because the class UIComponentTag depends on a JSP 2.1 container 
73       * (for example, it indirectly implements the interface JspIdConsumer)
74       * and therefore internal classes shouldn't access this class. That's
75       * also the reason why this method is inside the class ContainerUtils,
76       * because it allows MyFaces to be independent of a JSP 2.1 container.
77       * </p>
78       */
79      public static boolean isValueReference(String value) 
80      {
81          if (value == null)
82          {
83              throw new NullPointerException("value");
84          }
85  
86          int start = value.indexOf("#{");
87          if (start < 0)
88          {
89              return false;
90          }
91  
92          int end = value.lastIndexOf('}');
93          return (end >=0 && start < end);
94      }
95      
96  private static Boolean runningOnGoogleAppEngine = null;
97      
98      /**Returns true if running on Google App Engine (both production and development environment).
99       * <p>If this method returns true, then
100      * <ul>
101      * <li>MyFaces is initialized as in JSP 2.0 or less environment.</li>
102      * <li>Last modification check of faces config is not done during update.</li>
103      * </ul>
104      */
105     public static boolean isRunningOnGoogleAppEngine(
106             ServletContext servletContext)
107     {
108         if (runningOnGoogleAppEngine != null)
109         {
110             return runningOnGoogleAppEngine.booleanValue();
111         }
112         else
113         {
114             return isServerGoogleAppEngine(servletContext.getServerInfo());
115         }
116     }
117 
118     /**
119      * @see ContainerUtils#isRunningOnGoogleAppEngine(ServletContext)
120      */
121     public static boolean isRunningOnGoogleAppEngine(
122             ExternalContext externalContext)
123     {
124 
125         if (runningOnGoogleAppEngine != null)
126         {
127             return runningOnGoogleAppEngine.booleanValue();
128         }
129         else
130         {
131             String serverInfo = ExternalContextUtils.getServerInfo(externalContext);
132             
133             return isServerGoogleAppEngine(serverInfo);
134         }
135     }
136 
137     private static boolean isServerGoogleAppEngine(String serverInfo)
138     {
139         //for GAE, server info can be "Google App Engine/x.x.x" or "Google App Engine Development/x.x.x" 
140         if (serverInfo != null && serverInfo.startsWith(GAE_SERVER_INFO_BEGINNING))
141         {
142             runningOnGoogleAppEngine = Boolean.TRUE;
143         }
144         else
145         {
146             runningOnGoogleAppEngine = Boolean.FALSE;
147         }
148 
149         return runningOnGoogleAppEngine;
150     }
151 }