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.CharPool;
020 import com.liferay.portal.kernel.util.StringPool;
021 import com.liferay.portal.kernel.util.StringUtil;
022
023 import java.io.IOException;
024
025 import java.net.MalformedURLException;
026 import java.net.URI;
027 import java.net.URISyntaxException;
028 import java.net.URL;
029 import java.net.URLConnection;
030
031 import java.util.HashSet;
032 import java.util.Set;
033 import java.util.jar.JarEntry;
034 import java.util.jar.JarInputStream;
035
036 import javax.servlet.ServletContext;
037
038
042 public class ServletContextUtil {
043
044 public static final String PATH_WEB_XML = "/WEB-INF/web.xml";
045
046 public static final String URI_ATTRIBUTE =
047 ServletContextUtil.class.getName().concat(".rootURI");
048
049 public static Set<String> getClassNames(ServletContext servletContext)
050 throws IOException {
051
052 Set<String> classNames = new HashSet<String>();
053
054 _getClassNames(servletContext, "/WEB-INF/classes", classNames);
055 _getClassNames(servletContext, "/WEB-INF/lib", classNames);
056
057 return classNames;
058 }
059
060 public static long getLastModified(ServletContext servletContext) {
061 return getLastModified(servletContext, StringPool.SLASH);
062 }
063
064 public static long getLastModified(
065 ServletContext servletContext, String path) {
066
067 return getLastModified(servletContext, path, false);
068 }
069
070 public static long getLastModified(
071 ServletContext servletContext, String path, boolean cache) {
072
073 if (cache) {
074 Long lastModified = (Long)servletContext.getAttribute(
075 ServletContextUtil.class.getName() + StringPool.PERIOD +
076 path);
077
078 if (lastModified != null) {
079 return lastModified.longValue();
080 }
081 }
082
083 long lastModified = 0;
084
085 Set<String> paths = null;
086
087 if (path.endsWith(StringPool.SLASH)) {
088 paths = servletContext.getResourcePaths(path);
089 }
090 else {
091 paths = new HashSet<String>();
092
093 paths.add(path);
094 }
095
096 if ((paths == null) || paths.isEmpty()) {
097 if (cache) {
098 servletContext.setAttribute(
099 ServletContextUtil.class.getName() + StringPool.PERIOD +
100 path,
101 new Long(lastModified));
102 }
103
104 return lastModified;
105 }
106
107 for (String curPath : paths) {
108 if (curPath.endsWith(StringPool.SLASH)) {
109 long curLastModified = getLastModified(servletContext, curPath);
110
111 if (curLastModified > lastModified) {
112 lastModified = curLastModified;
113 }
114 }
115 else {
116 try {
117 URL url = servletContext.getResource(curPath);
118
119 if (url == null) {
120 _log.error("Resource URL for " + curPath + " is null");
121
122 continue;
123 }
124
125 URLConnection urlConnection = url.openConnection();
126
127 if (urlConnection.getLastModified() > lastModified) {
128 lastModified = urlConnection.getLastModified();
129 }
130 }
131 catch (IOException ioe) {
132 _log.error(ioe, ioe);
133 }
134 }
135 }
136
137 if (cache) {
138 servletContext.setAttribute(
139 ServletContextUtil.class.getName() + StringPool.PERIOD +
140 path,
141 new Long(lastModified));
142 }
143
144 return lastModified;
145 }
146
147 public static String getResourcePath(URL url) throws URISyntaxException {
148 URI uri = getResourceURI(url);
149
150 return uri.toString();
151 }
152
153 public static URI getResourceURI(URL url) throws URISyntaxException {
154 return _getResourceURI(url, url.getPath());
155 }
156
157 public static String getRootPath(ServletContext servletContext)
158 throws MalformedURLException {
159
160 URI rootURI = getRootURI(servletContext);
161
162 return rootURI.toString();
163 }
164
165 public static URI getRootURI(ServletContext servletContext)
166 throws MalformedURLException {
167
168 URI rootURI = (URI)servletContext.getAttribute(URI_ATTRIBUTE);
169
170 if (rootURI != null) {
171 return rootURI;
172 }
173
174 try {
175 URL rootURL = servletContext.getResource(PATH_WEB_XML);
176
177 String path = rootURL.getPath();
178
179 int index = path.indexOf(PATH_WEB_XML);
180
181 if (index < 0) {
182 throw new MalformedURLException("Invalid URL " + rootURL);
183 }
184
185 if (index == 0) {
186 path = StringPool.SLASH;
187 }
188 else {
189 path = path.substring(0, index);
190 }
191
192 rootURI = _getResourceURI(rootURL, path);
193
194 servletContext.setAttribute(URI_ATTRIBUTE, rootURI);
195 }
196 catch (URISyntaxException urise) {
197 throw new MalformedURLException(urise.getMessage());
198 }
199
200 return rootURI;
201 }
202
203 private static String _getClassName(String path) {
204 return _getClassName(null, path);
205 }
206
207 private static String _getClassName(String rootPath, String path) {
208 String className = path.substring(
209 0, path.length() - _EXT_CLASS.length());
210
211 if (rootPath != null) {
212 className = className.substring(rootPath.length() + 1);
213 }
214
215 className = StringUtil.replace(
216 className, CharPool.SLASH, CharPool.PERIOD);
217
218 return className;
219 }
220
221 private static void _getClassNames(
222 ServletContext servletContext, String rootPath,
223 Set<String> classNames)
224 throws IOException {
225
226 _getClassNames(
227 servletContext, rootPath, servletContext.getResourcePaths(rootPath),
228 classNames);
229 }
230
231 private static void _getClassNames(
232 ServletContext servletContext, String rootPath, Set<String> paths,
233 Set<String> classNames)
234 throws IOException {
235
236 if (paths == null) {
237 return;
238 }
239
240 for (String path : paths) {
241 if (path.endsWith(_EXT_CLASS)) {
242 String className = _getClassName(rootPath, path);
243
244 classNames.add(className);
245 }
246 else if (path.endsWith(_EXT_JAR)) {
247 JarInputStream jarFile = new JarInputStream(
248 servletContext.getResourceAsStream(path));
249
250 while (true) {
251 JarEntry jarEntry = jarFile.getNextJarEntry();
252
253 if (jarEntry == null) {
254 break;
255 }
256
257 String jarEntryName = jarEntry.getName();
258
259 if (jarEntryName.endsWith(_EXT_CLASS)) {
260 String className = _getClassName(jarEntryName);
261
262 classNames.add(className);
263 }
264 }
265
266 jarFile.close();
267
268 }
269 else if (path.endsWith(StringPool.SLASH)) {
270 _getClassNames(
271 servletContext, rootPath,
272 servletContext.getResourcePaths(path), classNames);
273 }
274 }
275 }
276
277 private static URI _getResourceURI(URL url, String path)
278 throws URISyntaxException {
279
280 return new URI(url.getProtocol(), path, null);
281 }
282
283 private static final String _EXT_CLASS = ".class";
284
285 private static final String _EXT_JAR = ".jar";
286
287 private static Log _log = LogFactoryUtil.getLog(ServletContextUtil.class);
288
289 }