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