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