View Javadoc

1   /*
2    * WebFlow Navigation Manager: webflow definiton, server side navigation history and automatic session cleaning.
3    * Distributed under LGPL license at web site http://wfnm.sourceforge.net .
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 }