KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > jmx > remote > server > notification > NotificationConnection


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.admin.jmx.remote.server.notification;
25
26 import java.io.*;
27 import java.nio.channels.ClosedChannelException JavaDoc;
28 import java.net.SocketException JavaDoc;
29 import java.rmi.ConnectException JavaDoc;
30 import java.rmi.ConnectIOException JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32
33 import javax.management.*;
34
35 import com.sun.enterprise.admin.jmx.remote.DefaultConfiguration;
36 import com.sun.enterprise.admin.jmx.remote.notification.SimpleQueue;
37 import com.sun.enterprise.admin.jmx.remote.notification.NotificationWrapper;
38
39 /**
40  * A Connection class that represents a single client connection.
41  * This class maintains a notification buffer that is used to buffer notifications
42  * that needs to be sent to the client that is being represented by an object of this class.
43  * A dispatch thread is started, to dispatch the buffered notifications to the client.
44  */

45 public class NotificationConnection implements Runnable JavaDoc {
46     private SimpleQueue que = new SimpleQueue();
47     private int bufsiz = 0;
48     private Thread JavaDoc dispatchThr = null;
49     private long lastNotifTime = 0;
50
51     private OutputStream out = null;
52
53     private boolean exiting = false;
54     private boolean dispatching = false;
55     private boolean isIOException = false;
56
57     private static final Logger JavaDoc logger = Logger.getLogger(
58         DefaultConfiguration.JMXCONNECTOR_LOGGER);/*,
59         DefaultConfiguration.LOGGER_RESOURCE_BUNDLE_NAME );*/

60
61     public NotificationConnection(OutputStream out, int bufsiz) {
62         this.out = out;
63         if (bufsiz <= DefaultConfiguration.NOTIF_MIN_BUFSIZ)
64             this.bufsiz = DefaultConfiguration.NOTIF_MAX_BUFSIZ;
65         else
66             this.bufsiz = bufsiz;
67         dispatchThr = new Thread JavaDoc(this);
68         dispatchThr.start();
69     }
70
71     /**
72      * Reinitialized this connection and restarts the dispatch thread.
73      * This method is called everytime the client reconnects to the server
74      * because the connection had dropped.
75      */

76     public void reinit(OutputStream out) {
77         this.out = out;
78         isIOException = false;
79         dispatchThr = new Thread JavaDoc(this);
80         dispatchThr.start();
81     }
82
83     /**
84      * Returns true if an IOException had occurred while dispatching a notification
85      * to the client.
86      * If true, then the connection to the client may have dropped.
87      * If true, the ServerNotificationManager suspends this connection, waiting for
88      * the client to reconnect.
89      */

90     public boolean hasIOExceptionOccurred() {
91         return isIOException;
92     }
93
94     private boolean isIdle() {
95         boolean ret = ((System.currentTimeMillis() - lastNotifTime) >= DefaultConfiguration.NOTIF_WAIT_INTERVAL);
96         return ret;
97     }
98     
99     /**
100      * Sends an empty notification to the client.
101      * An empty notification is sent every 10 seconds.
102      */

103     public void fireWaitNotif() {
104         if (!hasIOExceptionOccurred() && (que.size() < bufsiz) && !dispatching && isIdle()) {
105             synchronized (que) {
106                 que.add(new NotificationWrapper(NotificationWrapper.WAIT, null, null));
107                 que.notify();
108             }
109         }
110     }
111
112     /**
113      * Called by the ServerNotificationManager whenever a notification needs to be
114      * sent to the client.
115      */

116     public void fireNotification(NotificationWrapper wrapr) {
117         if (que.size() < bufsiz) {
118             synchronized (que) {
119                 que.add(wrapr);
120                 que.notify();
121             }
122         }
123     }
124
125     /**
126      * When the server-side connector webapp is shutdown by the servlet container,
127      * the ServerNotificationManager calls this method.
128      * All pending notifications are dropped.
129      */

130     public void close() {
131         exiting = true;
132         synchronized (que) {
133             que.notify();
134         }
135         try {
136             dispatchThr.join();
137         } catch (InterruptedException JavaDoc intre) {
138         }
139         try {
140             out.close();
141         } catch (IOException JavaDoc ioe) {
142             // XXX: Log it
143
}
144     }
145
146     public boolean isExiting() {
147         return exiting;
148     }
149
150     /**
151      * The notifications dispatch thread.
152      * The dispatch thread sends all pending notifications in the buffer to the client.
153      * The dispatch thread exits, whenever an IOException occurs during actual dispatch
154      * or whenever this connection is being closed (after a call to close())
155      */

156     public void run() {
157         /* XXX: Even when we are exiting should we send the remaining notifications?
158          * OR just drop the remaining notifications ?
159          *
160          * Currently we drop all the remaining notifications!!
161          */

162         while (!isExiting() && !hasIOExceptionOccurred()) {
163             synchronized (que) {
164                 while (que.isEmpty() && !isExiting() && !hasIOExceptionOccurred()) {
165                     try {
166                         que.wait();
167                     } catch (InterruptedException JavaDoc intre) {
168                     }
169                 }
170             }
171             if (isExiting() || hasIOExceptionOccurred())
172                 break;
173             dispatching = true;
174             while (!que.isEmpty() && !isExiting() && !hasIOExceptionOccurred()) {
175                 NotificationWrapper wrapr = (NotificationWrapper) que.remove();
176                 try {
177                     sendNotificationMsg(wrapr);
178                 } catch (IOException JavaDoc ioe) {
179                     if (isExiting())
180                         break;
181                     // XXX: Log it; drop the notification
182
if (!isDisconnected(ioe))
183                         break;
184                     isIOException = true;
185                     synchronized (this) {
186                         this.notify();
187                     }
188                     break;
189                 }
190             }
191             lastNotifTime = System.currentTimeMillis();
192             dispatching = false;
193         }
194     }
195
196     private boolean isDisconnected(IOException JavaDoc ioe) {
197         if (ioe instanceof ClosedChannelException JavaDoc ||
198             ioe instanceof SocketException JavaDoc ||
199             ioe instanceof ConnectException JavaDoc ||
200             ioe instanceof ConnectIOException JavaDoc)
201             return true;
202         return false;
203     }
204
205     private void sendNotificationMsg(NotificationWrapper wrapr) throws IOException JavaDoc {
206         ObjectOutputStream objout = new ObjectOutputStream(out);
207         objout.writeObject(wrapr);
208         objout.flush();
209     }
210 }
211
212
Popular Tags