001
014
015 package com.liferay.portal.kernel.servlet;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.CharPool;
020 import com.liferay.portal.kernel.util.FileUtil;
021 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
022 import com.liferay.portal.kernel.util.ServerDetector;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025
026 import java.io.File;
027 import java.io.IOException;
028
029 import java.util.HashSet;
030 import java.util.Set;
031 import java.util.jar.JarEntry;
032 import java.util.jar.JarInputStream;
033
034 import javax.servlet.ServletContext;
035
036
039 public class ServletContextUtil {
040
041 public static final String LOG_INFO_LAST_MODIFIED =
042 ServletContextUtil.LOG_INFO_PREFIX + "retrieval of the most recent " +
043 "last modified date of a WAR for best performance";
044
045 public static final String LOG_INFO_PREFIX =
046 "Please configure Tomcat to unpack WARs to enable ";
047
048 public static final String LOG_INFO_SPRITES =
049 LOG_INFO_PREFIX + "enable sprites for best performance";
050
051 public static Set<String> getClassNames(ServletContext servletContext)
052 throws IOException {
053
054 Set<String> classNames = new HashSet<String>();
055
056 _getClassNames(servletContext, "/WEB-INF/classes", classNames);
057 _getClassNames(servletContext, "/WEB-INF/lib", classNames);
058
059 return classNames;
060 }
061
062 public static long getLastModified(ServletContext servletContext) {
063 return getLastModified(servletContext, StringPool.SLASH);
064 }
065
066 public static long getLastModified(
067 ServletContext servletContext, String resourcePath) {
068
069 return getLastModified(servletContext, resourcePath, false);
070 }
071
072 public static long getLastModified(
073 ServletContext servletContext, String resourcePath, boolean cache) {
074
075 if (cache) {
076 Long lastModified = (Long)servletContext.getAttribute(
077 ServletContextUtil.class.getName() + StringPool.PERIOD +
078 resourcePath);
079
080 if (lastModified != null) {
081 return lastModified.longValue();
082 }
083 }
084
085 long lastModified = 0;
086
087 Set<String> resourcePaths = servletContext.getResourcePaths(
088 resourcePath);
089
090 if (resourcePaths != null) {
091 for (String curResourcePath : resourcePaths) {
092 if (curResourcePath.endsWith(StringPool.SLASH)) {
093 long curLastModified = getLastModified(
094 servletContext, curResourcePath);
095
096 if (curLastModified > lastModified) {
097 lastModified = curLastModified;
098 }
099 }
100 else {
101 String realPath = getRealPath(
102 servletContext, curResourcePath);
103
104 if (realPath == null) {
105 if (ServerDetector.isTomcat()) {
106 if (_log.isInfoEnabled()) {
107 _log.info(LOG_INFO_LAST_MODIFIED);
108 }
109 }
110 else {
111 _log.error(
112 "Real path for " + curResourcePath +
113 " is null");
114 }
115
116 continue;
117 }
118
119 File file = new File(realPath);
120
121 if (file.lastModified() > lastModified) {
122 lastModified = file.lastModified();
123 }
124 }
125 }
126 }
127
128 if (cache) {
129 servletContext.setAttribute(
130 ServletContextUtil.class.getName() + StringPool.PERIOD +
131 resourcePath,
132 new Long(lastModified));
133 }
134
135 return lastModified;
136 }
137
138 public static String getRealPath(
139 ServletContext servletContext, String path) {
140
141 String realPath = servletContext.getRealPath(path);
142
143 if ((realPath == null) && ServerDetector.isWebLogic()) {
144 String rootDir = getRootDir(servletContext);
145
146 if (path.startsWith(StringPool.SLASH)) {
147 realPath = rootDir + path.substring(1);
148 }
149 else {
150 realPath = rootDir + path;
151 }
152
153 if (!FileUtil.exists(realPath)) {
154 realPath = null;
155 }
156 }
157
158 return realPath;
159 }
160
161 protected static String getRootDir(ServletContext servletContext) {
162 String key = ServletContextUtil.class.getName() + ".rootDir";
163
164 String rootDir = (String)servletContext.getAttribute(key);
165
166 if (rootDir == null) {
167 ClassLoader classLoader = (ClassLoader)servletContext.getAttribute(
168 PluginContextListener.PLUGIN_CLASS_LOADER);
169
170 if (classLoader == null) {
171 classLoader = PortalClassLoaderUtil.getClassLoader();
172 }
173
174 rootDir = WebDirDetector.getRootDir(classLoader);
175
176 servletContext.setAttribute(key, rootDir);
177 }
178
179 return rootDir;
180 }
181
182 private static String _getClassName(String path) {
183 return _getClassName(null, path);
184 }
185
186 private static String _getClassName(String rootResourcePath, String path) {
187 String className = path.substring(
188 0, path.length() - _EXT_CLASS.length());
189
190 if (rootResourcePath != null) {
191 className = className.substring(rootResourcePath.length() + 1);
192 }
193
194 className = StringUtil.replace(
195 className, CharPool.SLASH, CharPool.PERIOD);
196
197 return className;
198 }
199
200 private static void _getClassNames(
201 ServletContext servletContext, String rootResourcePath,
202 Set<String> classNames)
203 throws IOException {
204
205 _getClassNames(
206 servletContext, rootResourcePath,
207 servletContext.getResourcePaths(rootResourcePath), classNames);
208 }
209
210 private static void _getClassNames(
211 ServletContext servletContext, String rootResourcePath,
212 Set<String> resourcePaths, Set<String> classNames)
213 throws IOException {
214
215 if (resourcePaths == null) {
216 return;
217 }
218
219 for (String resourcePath : resourcePaths) {
220 if (resourcePath.endsWith(_EXT_CLASS)) {
221 String className = _getClassName(
222 rootResourcePath, resourcePath);
223
224 classNames.add(className);
225 }
226 else if (resourcePath.endsWith(_EXT_JAR)) {
227 JarInputStream jarFile = new JarInputStream(
228 servletContext.getResourceAsStream(resourcePath));
229
230 while (true) {
231 JarEntry jarEntry = jarFile.getNextJarEntry();
232
233 if (jarEntry == null) {
234 break;
235 }
236
237 String jarEntryName = jarEntry.getName();
238
239 if (jarEntryName.endsWith(_EXT_CLASS)) {
240 String className = _getClassName(jarEntryName);
241
242 classNames.add(className);
243 }
244 }
245
246 jarFile.close();
247
248 }
249 else if (resourcePath.endsWith(StringPool.SLASH)) {
250 _getClassNames(
251 servletContext, rootResourcePath,
252 servletContext.getResourcePaths(resourcePath), classNames);
253 }
254 }
255 }
256
257 private static final String _EXT_CLASS = ".class";
258
259 private static final String _EXT_JAR = ".jar";
260
261 private static Log _log = LogFactoryUtil.getLog(ServletContextUtil.class);
262
263 }