001
014
015 package com.liferay.portal.kernel.servlet;
016
017 import com.liferay.portal.kernel.util.CharPool;
018 import com.liferay.portal.kernel.util.StringPool;
019 import com.liferay.portal.kernel.util.StringUtil;
020
021 import java.io.IOException;
022
023 import java.net.MalformedURLException;
024 import java.net.URI;
025 import java.net.URISyntaxException;
026 import java.net.URL;
027
028 import java.util.HashSet;
029 import java.util.LinkedList;
030 import java.util.Queue;
031 import java.util.Set;
032 import java.util.jar.JarEntry;
033 import java.util.jar.JarInputStream;
034
035 import javax.servlet.ServletContext;
036
037
042 public class ServletContextUtil {
043
044 public static final String PATH_WEB_INF = "/WEB-INF";
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<>();
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 String lastModifiedCacheKey = null;
074
075 if (cache) {
076 lastModifiedCacheKey = ServletContextUtil.class.getName();
077 lastModifiedCacheKey = lastModifiedCacheKey.concat(
078 StringPool.PERIOD).concat(path);
079
080 Long lastModified = (Long)servletContext.getAttribute(
081 lastModifiedCacheKey);
082
083 if (lastModified != null) {
084 return lastModified.longValue();
085 }
086 }
087
088 String curPath = null;
089
090 long lastModified = 0;
091
092 Queue<String> pathQueue = new LinkedList<>();
093
094 pathQueue.offer(path);
095
096 while ((curPath = pathQueue.poll()) != null) {
097 if (curPath.charAt(curPath.length() - 1) == CharPool.SLASH) {
098 Set<String> pathSet = servletContext.getResourcePaths(curPath);
099
100 if (pathSet != null) {
101 pathQueue.addAll(pathSet);
102 }
103 }
104 else {
105 long curLastModified = FileTimestampUtil.getTimestamp(
106 servletContext, curPath);
107
108 if (curLastModified > lastModified) {
109 lastModified = curLastModified;
110 }
111 }
112 }
113
114 if (cache) {
115 servletContext.setAttribute(
116 lastModifiedCacheKey, new Long(lastModified));
117 }
118
119 return lastModified;
120 }
121
122 public static String getResourcePath(URL url) throws URISyntaxException {
123 URI uri = getResourceURI(url);
124
125 return uri.toString();
126 }
127
128 public static URI getResourceURI(URL url) throws URISyntaxException {
129 return _getResourceURI(url, url.getPath());
130 }
131
132 public static String getRootPath(ServletContext servletContext)
133 throws MalformedURLException {
134
135 URI rootURI = getRootURI(servletContext);
136
137 return rootURI.toString();
138 }
139
140 public static URI getRootURI(ServletContext servletContext)
141 throws MalformedURLException {
142
143 URI rootURI = (URI)servletContext.getAttribute(URI_ATTRIBUTE);
144
145 if (rootURI != null) {
146 return rootURI;
147 }
148
149 try {
150 URL rootURL = servletContext.getResource(PATH_WEB_INF);
151
152 String path = rootURL.getPath();
153
154 int index = path.indexOf(PATH_WEB_INF);
155
156 if (index < 0) {
157 throw new MalformedURLException("Invalid URL " + rootURL);
158 }
159
160 if (index == 0) {
161 path = StringPool.SLASH;
162 }
163 else {
164 path = path.substring(0, index);
165 }
166
167 rootURI = _getResourceURI(rootURL, path);
168
169 servletContext.setAttribute(URI_ATTRIBUTE, rootURI);
170 }
171 catch (URISyntaxException urise) {
172 throw new MalformedURLException(urise.getMessage());
173 }
174
175 return rootURI;
176 }
177
178 private static String _getClassName(String path) {
179 return _getClassName(null, path);
180 }
181
182 private static String _getClassName(String rootPath, String path) {
183 String className = path.substring(
184 0, path.length() - _EXT_CLASS.length());
185
186 if (rootPath != null) {
187 className = className.substring(rootPath.length() + 1);
188 }
189
190 className = StringUtil.replace(
191 className, CharPool.SLASH, CharPool.PERIOD);
192
193 return className;
194 }
195
196 private static void _getClassNames(
197 ServletContext servletContext, String rootPath,
198 Set<String> classNames)
199 throws IOException {
200
201 _getClassNames(
202 servletContext, rootPath, servletContext.getResourcePaths(rootPath),
203 classNames);
204 }
205
206 private static void _getClassNames(
207 ServletContext servletContext, String rootPath, Set<String> paths,
208 Set<String> classNames)
209 throws IOException {
210
211 if (paths == null) {
212 return;
213 }
214
215 for (String path : paths) {
216 if (path.endsWith(_EXT_CLASS)) {
217 String className = _getClassName(rootPath, path);
218
219 classNames.add(className);
220 }
221 else if (path.endsWith(_EXT_JAR)) {
222 try (JarInputStream jarFile = new JarInputStream(
223 servletContext.getResourceAsStream(path))) {
224
225 while (true) {
226 JarEntry jarEntry = jarFile.getNextJarEntry();
227
228 if (jarEntry == null) {
229 break;
230 }
231
232 String jarEntryName = jarEntry.getName();
233
234 if (jarEntryName.endsWith(_EXT_CLASS)) {
235 String className = _getClassName(jarEntryName);
236
237 classNames.add(className);
238 }
239 }
240 }
241 }
242 else if (path.endsWith(StringPool.SLASH)) {
243 _getClassNames(
244 servletContext, rootPath,
245 servletContext.getResourcePaths(path), classNames);
246 }
247 }
248 }
249
250 private static URI _getResourceURI(URL url, String path)
251 throws URISyntaxException {
252
253 return new URI(url.getProtocol(), path, null);
254 }
255
256 private static final String _EXT_CLASS = ".class";
257
258 private static final String _EXT_JAR = ".jar";
259
260 }