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