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 for (String dependant : dependants) {
158 long lastModified = _getFileLastModified(dependant, servlet);
159
160 if ((lastModified == 0) ||
161 (lastModified > servletInfo.getLastModified())) {
162
163 _servletInfos.remove(path);
164
165 _updateFileLastModified(path, servlet);
166
167 servlet = null;
168
169 if (_log.isDebugEnabled()) {
170 _log.debug("Reload dependent " + dependant);
171 }
172
173 break;
174 }
175 }
176 }
177 catch (NoSuchMethodException nsme) {
178 if (_log.isWarnEnabled()) {
179 _log.warn(
180 "Reloading of dependant JSP is disabled because your " +
181 "Servlet container is not a variant of Jasper");
182 }
183
184 _reloadDependents = false;
185 }
186 catch (Exception e) {
187 _log.error(e, e);
188 }
189
190 return servlet;
191 }
192
193 private void _updateFileLastModified(String path, Servlet servlet) {
194 ServletConfig servletConfig = servlet.getServletConfig();
195
196 ServletContext servletContext = servletConfig.getServletContext();
197
198 String rootPath = servletContext.getRealPath(StringPool.BLANK);
199
200 File file = new File(rootPath, path);
201
202 file.setLastModified(System.currentTimeMillis());
203 }
204
205 private static final boolean _DIRECT_SERVLET_CONTEXT_RELOAD =
206 GetterUtil.getBoolean(
207 PropsUtil.get(PropsKeys.DIRECT_SERVLET_CONTEXT_RELOAD));
208
209 private static Log _log = LogFactoryUtil.getLog(
210 DirectServletRegistry.class);
211
212 private static DirectServletRegistry _instance =
213 new DirectServletRegistry();
214
215 private static boolean _reloadDependents = true;
216
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 }