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, Long.valueOf(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 new URI(url.getProtocol(), url.getPath(), null);
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 = new URI(rootURL.getProtocol(), path, null);
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 rootPath, String path) {
179 String className = path.substring(
180 0, path.length() - _EXT_CLASS.length());
181
182 if (rootPath != null) {
183 className = className.substring(rootPath.length() + 1);
184 }
185
186 className = StringUtil.replace(
187 className, CharPool.SLASH, CharPool.PERIOD);
188
189 return className;
190 }
191
192 private static void _getClassNames(
193 ServletContext servletContext, String rootPath,
194 Set<String> classNames)
195 throws IOException {
196
197 _getClassNames(
198 servletContext, rootPath, servletContext.getResourcePaths(rootPath),
199 classNames);
200 }
201
202 private static void _getClassNames(
203 ServletContext servletContext, String rootPath, Set<String> paths,
204 Set<String> classNames)
205 throws IOException {
206
207 if (paths == null) {
208 return;
209 }
210
211 for (String path : paths) {
212 if (path.endsWith(_EXT_CLASS)) {
213 String className = _getClassName(rootPath, path);
214
215 classNames.add(className);
216 }
217 else if (path.endsWith(_EXT_JAR)) {
218 try (JarInputStream jarFile = new JarInputStream(
219 servletContext.getResourceAsStream(path))) {
220
221 while (true) {
222 JarEntry jarEntry = jarFile.getNextJarEntry();
223
224 if (jarEntry == null) {
225 break;
226 }
227
228 String jarEntryName = jarEntry.getName();
229
230 if (jarEntryName.endsWith(_EXT_CLASS)) {
231 String className = _getClassName(
232 null, jarEntryName);
233
234 classNames.add(className);
235 }
236 }
237 }
238 }
239 else if (path.endsWith(StringPool.SLASH)) {
240 _getClassNames(
241 servletContext, rootPath,
242 servletContext.getResourcePaths(path), classNames);
243 }
244 }
245 }
246
247 private static final String _EXT_CLASS = ".class";
248
249 private static final String _EXT_JAR = ".jar";
250
251 }