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 }