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