KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > jms > client > container > ClosedInterceptor


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.jms.client.container;
8
9 import java.util.HashSet JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.Set JavaDoc;
12
13 import org.jboss.aop.advice.Interceptor;
14 import org.jboss.aop.joinpoint.Invocation;
15 import org.jboss.aop.joinpoint.MethodInvocation;
16 import org.jboss.jms.client.Lifecycle;
17 import org.jboss.jms.container.Container;
18
19 /**
20  * An interceptor for checking closed state. It waits for
21  * other invocations to complete allowing the close.
22  *
23  * @author <a HREF="mailto:adrian@jboss.org>Adrian Brock</a>
24  * @version $Revision: 1.4 $
25  */

26 public class ClosedInterceptor
27    implements Interceptor
28 {
29    // Constants -----------------------------------------------------
30

31    /** Not closed */
32    private static final int NOT_CLOSED = 0;
33    
34    /** Closing */
35    private static final int IN_CLOSING = 1;
36    
37    /** Closing */
38    private static final int CLOSING = 2;
39    
40    /** Performing the close */
41    private static final int IN_CLOSE = 3;
42    
43    /** Closed */
44    private static final int CLOSED = -1;
45
46    // Attributes ----------------------------------------------------
47

48    /** The state of the object */
49    private int state = NOT_CLOSED;
50    
51    /** The inuse count */
52    private int inuseCount = 0;
53
54    // Static --------------------------------------------------------
55

56    // Constructors --------------------------------------------------
57

58    // Public --------------------------------------------------------
59

60    // Interceptor implementation -----------------------------------
61

62    public String JavaDoc getName()
63    {
64       return "ClosedInterceptor";
65    }
66
67    public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
68    {
69       String JavaDoc methodName = ((MethodInvocation) invocation).getMethod().getName();
70       boolean isClosing = methodName.equals("closing");
71       boolean isClose = methodName.equals("close");
72
73       if (isClosing)
74       {
75          if (checkClosingAlreadyDone())
76             return null;
77       }
78       else if (isClose)
79       {
80          if(checkCloseAlreadyDone())
81             return null;
82       }
83       else
84          inuse();
85
86       if (isClosing)
87          maintainRelatives(invocation);
88
89       try
90       {
91          return invocation.invokeNext();
92       }
93       finally
94       {
95          if (isClosing)
96             closing();
97          else if (isClose)
98             closed();
99          else
100             done();
101       }
102    }
103
104    // Protected ------------------------------------------------------
105

106    /**
107     * Check the closing notification has not already been done
108     *
109     * @return true when already closing or closed
110     */

111    protected synchronized boolean checkClosingAlreadyDone()
112       throws Throwable JavaDoc
113    {
114       if (state != NOT_CLOSED)
115          return true;
116       state = IN_CLOSING;
117       return false;
118    }
119
120    /**
121     * Closing the object
122     */

123    protected synchronized void closing()
124       throws Throwable JavaDoc
125    {
126       state = CLOSING;
127    }
128
129    /**
130     * Check the close has not already been done and
131     * wait for all invocations to complete
132     *
133     * @return true when already closed
134     */

135    protected synchronized boolean checkCloseAlreadyDone()
136       throws Throwable JavaDoc
137    {
138       if (state != CLOSING)
139          return true;
140       while (inuseCount > 0)
141          wait();
142       state = IN_CLOSE;
143       return false;
144    }
145
146    /**
147     * Closed the object
148     */

149    protected synchronized void closed()
150       throws Throwable JavaDoc
151    {
152       state = CLOSED;
153    }
154    
155    /**
156     * Mark the object as inuse
157     */

158    protected synchronized void inuse()
159       throws Throwable JavaDoc
160    {
161       if (state != NOT_CLOSED)
162          throw new IllegalStateException JavaDoc("Already closed");
163       ++inuseCount;
164    }
165    
166    /**
167     * Mark the object as no longer inuse
168     */

169    protected synchronized void done()
170       throws Throwable JavaDoc
171    {
172       if (--inuseCount == 0)
173          notifyAll();
174    }
175
176    /**
177     * Close children and remove from parent
178     *
179     * @param invocation the invocation
180     */

181    protected void maintainRelatives(Invocation invocation)
182    {
183       // We use a clone to avoid a deadlock where requests
184
// are made to close parent and child concurrently
185
Container container = Container.getContainer(invocation);
186       Set JavaDoc clone = null;
187       Set JavaDoc children = container.getChildren();
188       synchronized (children)
189       {
190          clone = new HashSet JavaDoc(children);
191       }
192       
193       // Cycle through the children this will do a depth
194
// first close
195
for (Iterator JavaDoc i = clone.iterator(); i.hasNext();)
196       {
197          Container childContainer = (Container) i.next();
198          Lifecycle child = (Lifecycle) childContainer.getProxy();
199          try
200          {
201             child.closing();
202             child.close();
203          }
204          catch (Throwable JavaDoc ignored)
205          {
206             // Add a log interceptor to the child if you want the error
207
}
208       }
209       
210       // Remove from the parent
211
Container parent = container.getParent();
212       if (parent != null)
213          parent.removeChild(container);
214    }
215
216    // Package Private ------------------------------------------------
217

218    // Private --------------------------------------------------------
219

220    // Inner Classes --------------------------------------------------
221

222 }
223
Popular Tags