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