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