1
22
23 package com.liferay.portal.kernel.servlet;
24
25 import com.liferay.portal.kernel.log.Log;
26 import com.liferay.portal.kernel.log.LogFactoryUtil;
27 import com.liferay.portal.kernel.util.FileUtil;
28 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
29 import com.liferay.portal.kernel.util.ServerDetector;
30 import com.liferay.portal.kernel.util.StringPool;
31 import com.liferay.portal.kernel.util.StringUtil;
32
33 import java.io.File;
34 import java.io.IOException;
35
36 import java.util.HashSet;
37 import java.util.Set;
38 import java.util.jar.JarEntry;
39 import java.util.jar.JarInputStream;
40
41 import javax.servlet.ServletContext;
42
43
48 public class ServletContextUtil {
49
50 public static final String LOG_INFO_PREFIX =
51 "Please configure Tomcat to unpack WARs to enable ";
52
53 public static final String LOG_INFO_LAST_MODIFIED =
54 LOG_INFO_PREFIX + "retrieval of the most recent last modified date " +
55 "of a WAR for best performance";
56
57 public static final String LOG_INFO_SPRITES =
58 LOG_INFO_PREFIX + "enable sprites for best performance";
59
60 public static Set<String> getClassNames(ServletContext servletContext)
61 throws IOException {
62
63 Set<String> classNames = new HashSet<String>();
64
65 _getClassNames(servletContext, "/WEB-INF/classes", classNames);
66 _getClassNames(servletContext, "/WEB-INF/lib", classNames);
67
68 return classNames;
69 }
70
71 public static long getLastModified(ServletContext servletContext) {
72 return getLastModified(servletContext, StringPool.SLASH);
73 }
74
75 public static long getLastModified(
76 ServletContext servletContext, String resourcePath) {
77
78 return getLastModified(servletContext, resourcePath, false);
79 }
80
81 public static long getLastModified(
82 ServletContext servletContext, String resourcePath, boolean cache) {
83
84 if (cache) {
85 Long lastModified = (Long)servletContext.getAttribute(
86 ServletContextUtil.class.getName() + StringPool.PERIOD +
87 resourcePath);
88
89 if (lastModified != null) {
90 return lastModified.longValue();
91 }
92 }
93
94 long lastModified = 0;
95
96 Set<String> resourcePaths = servletContext.getResourcePaths(
97 resourcePath);
98
99 if (resourcePaths != null) {
100 for (String curResourcePath : resourcePaths) {
101 if (curResourcePath.endsWith(StringPool.SLASH)) {
102 long curLastModified = getLastModified(
103 servletContext, curResourcePath);
104
105 if (curLastModified > lastModified) {
106 lastModified = curLastModified;
107 }
108 }
109 else {
110 String realPath = getRealPath(
111 servletContext, curResourcePath);
112
113 if (realPath == null) {
114 if (ServerDetector.isTomcat()) {
115 if (_log.isInfoEnabled()) {
116 _log.info(LOG_INFO_LAST_MODIFIED);
117 }
118 }
119 else {
120 _log.error(
121 "Real path for " + curResourcePath +
122 " is null");
123 }
124
125 continue;
126 }
127
128 File file = new File(realPath);
129
130 if (file.lastModified() > lastModified) {
131 lastModified = file.lastModified();
132 }
133 }
134 }
135 }
136
137 if (cache) {
138 servletContext.setAttribute(
139 ServletContextUtil.class.getName() + StringPool.PERIOD +
140 resourcePath,
141 new Long(lastModified));
142 }
143
144 return lastModified;
145 }
146
147 public static String getRealPath(
148 ServletContext servletContext, String path) {
149
150 String realPath = servletContext.getRealPath(path);
151
152 if ((realPath == null) && ServerDetector.isWebLogic()) {
153 String rootDir = getRootDir(servletContext);
154
155 if (path.startsWith(StringPool.SLASH)) {
156 realPath = rootDir + path.substring(1);
157 }
158 else {
159 realPath = rootDir + path;
160 }
161
162 if (!FileUtil.exists(realPath)) {
163 realPath = null;
164 }
165 }
166
167 return realPath;
168 }
169
170 protected static String getRootDir(ServletContext servletContext) {
171 String key = ServletContextUtil.class.getName() + ".rootDir";
172
173 String rootDir = (String)servletContext.getAttribute(key);
174
175 if (rootDir == null) {
176 ClassLoader classLoader = (ClassLoader)servletContext.getAttribute(
177 PortletServlet.PORTLET_CLASS_LOADER);
178
179 if (classLoader == null) {
180 classLoader = PortalClassLoaderUtil.getClassLoader();
181 }
182
183 rootDir = WebDirDetector.getRootDir(classLoader);
184
185 servletContext.setAttribute(key, rootDir);
186 }
187
188 return rootDir;
189 }
190
191 private static String _getClassName(String path) {
192 return _getClassName(null, path);
193 }
194
195 private static String _getClassName(String rootResourcePath, String path) {
196 String className = path.substring(
197 0, path.length() - _EXT_CLASS.length());
198
199 if (rootResourcePath != null) {
200 className = className.substring(rootResourcePath.length() + 1);
201 }
202
203 className = StringUtil.replace(
204 className, StringPool.SLASH, StringPool.PERIOD);
205
206 return className;
207 }
208
209 private static void _getClassNames(
210 ServletContext servletContext, String rootResourcePath,
211 Set<String> classNames)
212 throws IOException {
213
214 _getClassNames(
215 servletContext, rootResourcePath,
216 servletContext.getResourcePaths(rootResourcePath), classNames);
217 }
218
219 private static void _getClassNames(
220 ServletContext servletContext, String rootResourcePath,
221 Set<String> resourcePaths, Set<String> classNames)
222 throws IOException {
223
224 if (resourcePaths == null) {
225 return;
226 }
227
228 for (String resourcePath : resourcePaths) {
229 if (resourcePath.endsWith(_EXT_CLASS)) {
230 String className = _getClassName(
231 rootResourcePath, resourcePath);
232
233 classNames.add(className);
234 }
235 else if (resourcePath.endsWith(_EXT_JAR)) {
236 JarInputStream jarFile = new JarInputStream(
237 servletContext.getResourceAsStream(resourcePath));
238
239 while (true) {
240 JarEntry jarEntry = jarFile.getNextJarEntry();
241
242 if (jarEntry == null) {
243 break;
244 }
245
246 String jarEntryName = jarEntry.getName();
247
248 if (jarEntryName.endsWith(_EXT_CLASS)) {
249 String className = _getClassName(jarEntryName);
250
251 classNames.add(className);
252 }
253 }
254
255 }
256 else if (resourcePath.endsWith(StringPool.SLASH)) {
257 _getClassNames(
258 servletContext, rootResourcePath,
259 servletContext.getResourcePaths(resourcePath), classNames);
260 }
261 }
262 }
263
264 private static final String _EXT_CLASS = ".class";
265
266 private static final String _EXT_JAR = ".jar";
267
268 private static Log _log = LogFactoryUtil.getLog(ServletContextUtil.class);
269
270 }