1
2
3
4
5 package net.sf.wfnm.web;
6
7 import net.sf.wfnm.AttributeContainer;
8 import net.sf.wfnm.Config;
9 import net.sf.wfnm.NavigationManager;
10 import net.sf.wfnm.NavigationManagerFactory;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14
15 import java.io.IOException;
16
17 import javax.servlet.Filter;
18 import javax.servlet.FilterChain;
19 import javax.servlet.FilterConfig;
20 import javax.servlet.ServletException;
21 import javax.servlet.ServletRequest;
22 import javax.servlet.ServletResponse;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26
27 /***
28 * This filter allows to avoid multiple form submits.
29 *
30 * @author <a href="mailto:malbari@users.sourceforge.net">Maurizio Albari </a>
31 * @version 1.0.6
32 */
33 public class NoMultipleSubmitFilter implements Filter {
34 /***
35 * The log
36 */
37 private static Log log = LogFactory.getLog(NoMultipleSubmitFilter.class);
38
39 /***
40 * The URL rewriter
41 */
42 private UrlRewriter urlRewriter;
43
44 /***
45 * Creates a new PageNotifierFilter object.
46 */
47 public NoMultipleSubmitFilter() {
48 super();
49 }
50
51 /***
52 * Destroy the filter.
53 */
54 public void destroy() {
55 }
56
57 /***
58 * Filter the request in order to notify that a page has been reached.
59 *
60 * @param servletRequest the servlet request
61 * @param servletResponse the servlet response
62 * @param filterChain the filter chain
63 *
64 * @throws IOException if an input/output exception ocours
65 * @throws ServletException if a servlet exception ocours
66 */
67 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
68 throws IOException, ServletException {
69 HttpServletRequest req = (HttpServletRequest) servletRequest;
70 AttributeContainer sessionWrapper = (AttributeContainer) HttpSessionWrapper.wrapItIfNecessary(req.getSession());
71
72 if (!Config.getInstance().isEnabled() || !NavigationManagerFactory.existsInstance(sessionWrapper)) {
73 filterChain.doFilter(servletRequest, servletResponse);
74 } else {
75 NavigationManager navigationManager = NavigationManagerFactory.getInstance(sessionWrapper);
76
77 Object lock = navigationManager.getLock();
78 boolean isFirst = (lock == null);
79
80 try {
81 if (isFirst) {
82 synchronized (req.getSession()) {
83 lock = navigationManager.getLock();
84 isFirst = (lock == null);
85
86 if (isFirst) {
87 lock = new Object();
88 navigationManager.setLock(lock);
89 filterChain.doFilter(servletRequest, servletResponse);
90 }
91 }
92 }
93 } finally {
94 if (isFirst) {
95 synchronized (req.getSession()) {
96 synchronized (lock) {
97 navigationManager.setLock(null);
98 lock.notifyAll();
99 }
100 }
101 } else {
102 synchronized (lock) {
103 Object currentLock = navigationManager.getLock();
104
105 if (currentLock == lock) {
106 try {
107 lock.wait();
108 } catch (InterruptedException ie) {
109 log.warn("Interrupted exception");
110 }
111 }
112 }
113
114 synchronized (req.getSession()) {
115 String url = navigationManager.getCurrentPage();
116 String rewrittenUrl = ((urlRewriter != null) ? urlRewriter.rewriteUrl(url) : url);
117 String fullUrl = req.getContextPath() + rewrittenUrl;
118 HttpServletResponse res = (HttpServletResponse) servletResponse;
119 res.sendRedirect(fullUrl);
120 }
121 }
122 }
123 }
124 }
125
126 /***
127 * Initialize the filter.
128 *
129 * @param filterConfig the filter configuration
130 *
131 * @throws ServletException if a servlet exception ocours
132 */
133 public void init(FilterConfig filterConfig) throws ServletException {
134 Class urlRewriterClass = Config.getInstance().getUrlRewriter();
135
136 if (urlRewriterClass != null) {
137 try {
138 this.urlRewriter = (UrlRewriter) urlRewriterClass.newInstance();
139 } catch (Exception e) {
140 throw new ServletException("Unable to instantiate the class '" + urlRewriterClass.getName() + "'", e);
141 }
142 }
143 }
144 }