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 }