1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.orchestra.conversation.spring;
21
22 import org.aopalliance.intercept.MethodInterceptor;
23 import org.aopalliance.intercept.MethodInvocation;
24 import org.apache.myfaces.orchestra.conversation.Conversation;
25
26 /***
27 * Maintain the appropriate persistence state for the current call-stack.
28 * <p>
29 * This class is a MethodInterceptor (an AOP Advice) which should be configured to intercept
30 * calls to all conversation-scoped beans. It ensures that the appropriate PersistenceContext
31 * object for this conversation is placed into the default location, by invoking the
32 * <i>bind</i> method on the persistence context object. Typically the bind method stores
33 * the persistence context into a thread-local variable, but that is implementation-specific.
34 * <p>
35 * When Spring code retrieves the persistence context in order to inject it into a bean,
36 * it then finds the correct context for the conversation that is associated with the
37 * nearest conversation-scoped bean in the callstack.
38 * <p>
39 * If no PersistenceContext yet exists for the conversation associated with the bean
40 * that is being invoked then one is created using {@link PersistenceContextFactory}.
41 * <p>
42 * A reference to the {@link PersistenceContext} is put into the conversation attribute
43 * map wrapped in an {@link PersistenceContextCloser} so that when the conversation
44 * ends a callback occurs on it which closes the underlying object.
45 */
46 public class PersistenceContextConversationInterceptor implements MethodInterceptor
47 {
48 private final static String PERSISTENCE_CONTEXT_CONV_ATTRIBUTE = PersistenceContextConversationInterceptor.class.getName() + ".PERSISTENCE_CONTEXT";
49 public final static String REQUEST_ATTRIBUTE = PersistenceContextConversationInterceptor.class.getName() + ".USED_PERSISTENCE_CONTEXTS";
50
51 private PersistenceContextFactory persistenceContextFactory;
52
53 public PersistenceContextConversationInterceptor()
54 {
55 }
56
57 public void setPersistenceContextFactory(PersistenceContextFactory persistenceContextFactory)
58 {
59 this.persistenceContextFactory = persistenceContextFactory;
60 }
61
62 public Object invoke(MethodInvocation methodInvocation) throws Throwable
63 {
64 PersistenceContext persistenceContext = null;
65
66 Conversation conversation = Conversation.getCurrentInstance();
67 if (conversation != null)
68 {
69 PersistenceContextCloser persistenceContextCloser = (PersistenceContextCloser) conversation.getAttribute(PERSISTENCE_CONTEXT_CONV_ATTRIBUTE);
70 if (persistenceContextCloser != null)
71 {
72 persistenceContext = persistenceContextCloser.getPersistenceContext();
73 }
74
75 if (persistenceContext == null)
76 {
77 persistenceContext = persistenceContextFactory.create();
78
79 conversation.setAttribute(PERSISTENCE_CONTEXT_CONV_ATTRIBUTE, new PersistenceContextCloser(persistenceContext));
80 }
81 }
82
83 if (persistenceContext != null)
84 {
85
86
87 persistenceContext.bind();
88 }
89
90 try
91 {
92 return methodInvocation.proceed();
93 }
94 finally
95 {
96 if (persistenceContext != null)
97 {
98 persistenceContext.unbind();
99 }
100 }
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 }