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