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.GetterUtil;
020 import com.liferay.portal.kernel.util.PropsKeys;
021 import com.liferay.portal.kernel.util.PropsUtil;
022 import com.liferay.portal.kernel.util.ReflectionUtil;
023 import com.liferay.portal.kernel.util.StringPool;
024
025 import java.io.File;
026
027 import java.lang.reflect.Method;
028
029 import java.util.Collection;
030 import java.util.List;
031 import java.util.Map;
032 import java.util.concurrent.ConcurrentHashMap;
033
034 import javax.servlet.Servlet;
035 import javax.servlet.ServletConfig;
036 import javax.servlet.ServletContext;
037
038
041 public class DirectServletRegistry {
042
043 public static void clearServlets() {
044 _instance._clearServlets();
045 }
046
047 public static Servlet getServlet(String path) {
048 return _instance._getServlet(path);
049 }
050
051 public static void putServlet(String path, Servlet servlet) {
052 _instance._putServlet(path, servlet);
053 }
054
055 private DirectServletRegistry() {
056 }
057
058 private void _clearServlets() {
059 _servletInfos.clear();
060 }
061
062 private long _getFileLastModified(String path, Servlet servlet) {
063 ServletConfig servletConfig = servlet.getServletConfig();
064
065 ServletContext servletContext = servletConfig.getServletContext();
066
067 String rootPath = servletContext.getRealPath(StringPool.BLANK);
068
069 File file = new File(rootPath, path);
070
071 return file.lastModified();
072 }
073
074 private Servlet _getServlet(String path) {
075 ServletInfo servletInfo = _servletInfos.get(path);
076
077 if (servletInfo == null) {
078 return null;
079 }
080
081 Servlet servlet = servletInfo.getServlet();
082
083 if (_DIRECT_SERVLET_CONTEXT_RELOAD) {
084 long lastModified = _getFileLastModified(path, servlet);
085
086 if ((lastModified == 0) ||
087 (lastModified != servletInfo.getLastModified())) {
088
089 _servletInfos.remove(path);
090
091 servlet = null;
092
093 if (_log.isDebugEnabled()) {
094 _log.debug("Reload " + path);
095 }
096 }
097 else {
098 servlet = _reloadDependents(path, servlet, servletInfo);
099 }
100 }
101
102 return servlet;
103 }
104
105 private void _putServlet(String path, Servlet servlet) {
106 if (_servletInfos.containsKey(path)) {
107 return;
108 }
109
110 long lastModified = 1;
111
112 if (_DIRECT_SERVLET_CONTEXT_RELOAD) {
113 lastModified = _getFileLastModified(path, servlet);
114 }
115
116 if (lastModified > 0) {
117 ServletInfo servletInfo = new ServletInfo();
118
119 servletInfo.setLastModified(lastModified);
120 servletInfo.setServlet(servlet);
121
122 _servletInfos.put(path, servletInfo);
123 }
124 }
125
126 private Servlet _reloadDependents(
127 String path, Servlet servlet, ServletInfo servletInfo) {
128
129 try {
130 if (!_reloadDependents) {
131 return servlet;
132 }
133
134 Method method = ReflectionUtil.getDeclaredMethod(
135 servlet.getClass(), "getDependants");
136
137 Collection<String> dependants = null;
138
139 String jasperVersion = JasperVersionDetector.getJasperVersion();
140
141 if (jasperVersion.contains("7.0")) {
142 Map<String, ?> dependantsMap = (Map<String, ?>)method.invoke(
143 servlet);
144
145 if (dependantsMap != null) {
146 dependants = dependantsMap.keySet();
147 }
148 }
149 else {
150 dependants = (List<String>)method.invoke(servlet);
151 }
152
153 if (dependants == null) {
154 return servlet;
155 }
156
157 boolean reloadServlet = false;
158
159 for (String dependant : dependants) {
160 long lastModified = _getFileLastModified(dependant, servlet);
161
162 Long previousLastModified = _dependantTimestamps.get(dependant);
163
164 if (previousLastModified == null) {
165 previousLastModified = lastModified;
166 }
167
168 if ((lastModified == 0) ||
169 (lastModified != previousLastModified.longValue())) {
170
171 reloadServlet = true;
172
173 _dependantTimestamps.put(dependant, lastModified);
174
175 if (_log.isDebugEnabled()) {
176 _log.debug("Reload dependent " + dependant);
177 }
178 }
179 }
180
181 if (reloadServlet) {
182 _servletInfos.remove(path);
183
184 servlet = null;
185 }
186 }
187 catch (NoSuchMethodException nsme) {
188 if (_log.isWarnEnabled()) {
189 _log.warn(
190 "Reloading of dependant JSP is disabled because your " +
191 "Servlet container is not a variant of Jasper");
192 }
193
194 _reloadDependents = false;
195 }
196 catch (Exception e) {
197 _log.error(e, e);
198 }
199
200 return servlet;
201 }
202
203 private static final boolean _DIRECT_SERVLET_CONTEXT_RELOAD =
204 GetterUtil.getBoolean(
205 PropsUtil.get(PropsKeys.DIRECT_SERVLET_CONTEXT_RELOAD));
206
207 private static Log _log = LogFactoryUtil.getLog(
208 DirectServletRegistry.class);
209
210 private static DirectServletRegistry _instance =
211 new DirectServletRegistry();
212
213 private static boolean _reloadDependents = true;
214
215 private Map<String, Long> _dependantTimestamps =
216 new ConcurrentHashMap<String, Long>();
217 private Map<String, ServletInfo> _servletInfos =
218 new ConcurrentHashMap<String, ServletInfo>();
219
220 private class ServletInfo {
221
222 public long getLastModified() {
223 return _lastModified;
224 }
225
226 public Servlet getServlet() {
227 return _servlet;
228 }
229
230 public void setLastModified(long lastModified) {
231 _lastModified = lastModified;
232 }
233
234 public void setServlet(Servlet servlet) {
235 _servlet = servlet;
236 }
237
238 private long _lastModified;
239 private Servlet _servlet;
240
241 }
242
243 }