1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.jencks.interceptor;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.geronimo.transaction.DefaultInstanceContext;
22 import org.apache.geronimo.transaction.InstanceContext;
23 import org.apache.geronimo.transaction.TrackedConnectionAssociator;
24
25 import javax.resource.ResourceException;
26 import javax.servlet.Filter;
27 import javax.servlet.FilterChain;
28 import javax.servlet.FilterConfig;
29 import javax.servlet.ServletException;
30 import javax.servlet.ServletRequest;
31 import javax.servlet.ServletResponse;
32 import java.io.IOException;
33 import java.util.HashSet;
34 import java.util.Set;
35
36 /***
37 * This servlet filter is used to enter in a transactional context
38 * automtically at every servlet call and exit of it when the response
39 * is sent back to the client.
40 * <p/>
41 * This class must be used with a mechanism (for example, Acegi) to
42 * use injection on filters.
43 * <p/>
44 * The following is an example of use:
45 * <p/>
46 * <web-app id="WebApp">
47 * ...
48 * <filter>
49 * <filter-name>Geronimo Transaction Context Filter</filter-name>
50 * <filter-class>
51 * org.springframework.web.filter.DelegatingFilterProxy</filter-class>
52 * <init-param>
53 * <param-name>targetBeanName</param-name>
54 * <param-value>
55 * org.springframework.jca.interceptor.TransactionContexFilter
56 * </param-value>
57 * </init-param>
58 * </filter>
59 * <p/>
60 * <filter-mapping>
61 * <filter-name>Geronimo Transaction Context Filter</filter-name>
62 * <url-pattern>/*</url-pattern>
63 * </filter-mapping>
64 * ...
65 * </web-app>
66 *
67 * @author Thierry Templier
68 * @see TrackedConnectionAssociator#enter(InstanceContext)
69 * @see TrackedConnectionAssociator#exit(InstanceContext)
70 * @see InstanceContext
71 * @see DefaultInstanceContext
72 */
73 public class TransactionContexFilter implements Filter {
74
75 private TrackedConnectionAssociator associator;
76
77 protected transient Log logger = LogFactory.getLog(getClass());
78
79 public void init(FilterConfig config) throws ServletException {
80 }
81
82 /***
83 * This is the central method of the filter which allows the
84 * request to enter in a transactionnal context and exit when
85 * the request is sent back to the client.
86 *
87 * @see #enterContext(Set, Set)
88 * @see #exitContext(InstanceContext)
89 */
90 public void doFilter(ServletRequest request, ServletResponse response,
91 FilterChain chain) throws IOException, ServletException {
92
93 Set unshareableResources = new HashSet();
94 Set applicationManagedSecurityResources = new HashSet();
95 InstanceContext oldContext =
96 enterContext(unshareableResources, applicationManagedSecurityResources);
97
98
99 chain.doFilter(request, response);
100
101
102 exitContext(oldContext);
103 }
104
105 /***
106 * This method enters in a new context and returns it
107 * in order to exit of it when the request is sent back to
108 * the client.
109 */
110 private InstanceContext enterContext(Set unshareableResources,
111 Set applicationManagedSecurityResources) {
112 try {
113 InstanceContext oldContext =
114 associator.enter(new DefaultInstanceContext(
115 unshareableResources, applicationManagedSecurityResources));
116 if (logger.isDebugEnabled()) {
117 logger.info("Geronimo transaction context set.");
118 }
119 return oldContext;
120 }
121 catch (ResourceException ex) {
122 }
123 return null;
124 }
125
126 /***
127 * This method exits of the specified context. This context is
128 * created when entering a new one.
129 *
130 * @see #enterContext(Set, Set)
131 */
132 private void exitContext(InstanceContext oldContext) {
133 try {
134 associator.exit(oldContext);
135 if (logger.isDebugEnabled()) {
136 logger.info("Geronimo transaction context unset.");
137 }
138 }
139 catch (ResourceException ex) {
140 }
141 }
142
143 public void destroy() {
144 }
145
146 /***
147 * Set the TrackedConnectionAssociator instance to allow the bean
148 * to enter and exit a transactional context.
149 */
150 public void setAssociator(TrackedConnectionAssociator associator) {
151 this.associator = associator;
152 }
153
154 }