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