KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > examples > scandir > ScanDirAgent


1 /*
2  * ScanDirAgent.java
3  *
4  * Created on July 10, 2006, 2:11 PM
5  *
6  * @(#)ScanDirAgent.java 1.2 06/08/02
7  *
8  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * -Redistribution of source code must retain the above copyright notice, this
14  * list of conditions and the following disclaimer.
15  *
16  * -Redistribution in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  *
20  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
21  * be used to endorse or promote products derived from this software without
22  * specific prior written permission.
23  *
24  * This software is provided "AS IS," without a warranty of any kind. ALL
25  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
26  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
27  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
28  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
29  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
30  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
31  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
32  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
33  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
34  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
35  *
36  * You acknowledge that this software is not designed, licensed or intended
37  * for use in the design, construction, operation or maintenance of any
38  * nuclear facility.
39  */

40
41 package com.sun.jmx.examples.scandir;
42
43 import com.sun.jmx.examples.scandir.ScanManagerMXBean.ScanState;
44 import java.io.IOException JavaDoc;
45 import java.lang.management.ManagementFactory JavaDoc;
46 import java.util.concurrent.BlockingQueue JavaDoc;
47 import java.util.concurrent.LinkedBlockingQueue JavaDoc;
48 import java.util.concurrent.TimeUnit JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50 import javax.management.JMException JavaDoc;
51 import javax.management.Notification JavaDoc;
52 import javax.management.NotificationEmitter JavaDoc;
53 import javax.management.NotificationListener JavaDoc;
54
55 /**
56  * <p>
57  * The <code>ScanDirAgent</code> is the Agent class for the <i>scandir</i>
58  * application.
59  * This class contains the {@link #main} method to start a standalone
60  * <i>scandir</i> application.
61  * </p>
62  * <p>
63  * The {@link #main main()} method simply registers a {@link
64  * ScanManagerMXBean} in the platform MBeanServer - see {@link #init init},
65  * and then waits for someone to call {@link ScanManagerMXBean#close close}
66  * on that MBean.
67  * </p>
68  * <p>
69  * When the {@link ScanManagerMXBean} state is switched to {@link
70  * ScanManagerMXBean.ScanState#CLOSED CLOSED}, {@link #cleanup cleanup} is
71  * called, the {@link ScanManagerMXBean} is unregistered, and the application
72  * terminates (i.e. the main thread completes).
73  * </p>
74  * @author Sun Microsystems, 2006 - All rights reserved.
75  **/

76 public class ScanDirAgent {
77
78     /**
79      * A logger for this class.
80      **/

81     private static final Logger JavaDoc LOG =
82             Logger.getLogger(ScanDirAgent.class.getName());
83
84     // Proxy to the ScanManagerMXBean - created by init();
85
//
86
private volatile ScanManagerMXBean proxy = null;
87
88     // A queue to put received Notifications.
89
//
90
private final BlockingQueue JavaDoc<Notification JavaDoc> queue;
91
92     // A listener that will put notifications into the queue.
93
//
94
private final NotificationListener JavaDoc listener;
95
96     /**
97      * Creates a new instance of ScanDirAgent
98      * You will need to call {@link #init()} later on in order to initialize
99      * the application.
100      * @see #main
101      **/

102     public ScanDirAgent() {
103         // Initialize the notification queue
104
queue = new LinkedBlockingQueue JavaDoc<Notification JavaDoc>();
105
106         // Creates the listener.
107
listener = new NotificationListener JavaDoc() {
108             public void handleNotification(Notification JavaDoc notification,
109                                            Object JavaDoc handback) {
110                 try {
111                     // Just put the received notification in the queue.
112
// It will be consumed later on by 'waitForClose()'
113
//
114
LOG.finer("Queuing received notification "+notification);
115                     queue.put(notification);
116                 } catch (InterruptedException JavaDoc ex) {
117                     // OK
118
}
119             }
120         };
121     }
122
123     /**
124      * Initialize the application by registering a ScanManagerMXBean in
125      * the platform MBeanServer
126      * @throws java.io.IOException Registration failed for communication-related reasons.
127      * @throws javax.management.JMException Registration failed for JMX-related reasons.
128      */

129     public void init() throws IOException JavaDoc, JMException JavaDoc {
130
131         // Registers the ScanManagerMXBean singleton in the
132
// platform MBeanServer
133
//
134
proxy = ScanManager.register();
135
136         // Registers a NotificationListener with the ScanManagerMXBean in
137
// order to receive state changed notifications.
138
//
139
((NotificationEmitter JavaDoc)proxy).addNotificationListener(listener,null,null);
140     }
141
142     /**
143      * Cleanup after close: unregister the ScanManagerMXBean singleton.
144      * @throws java.io.IOException Cleanup failed for communication-related reasons.
145      * @throws javax.management.JMException Cleanup failed for JMX-related reasons.
146      */

147     public void cleanup() throws IOException JavaDoc, JMException JavaDoc {
148         try {
149             ((NotificationEmitter JavaDoc)proxy).
150                     removeNotificationListener(listener,null,null);
151         } finally {
152             ManagementFactory.getPlatformMBeanServer().
153                 unregisterMBean(ScanManager.SCAN_MANAGER_NAME);
154         }
155     }
156
157     /**
158      * Wait for someone to call 'close()' on the ScanManagerMXBean singleton.
159      * Every time its state changes, the ScanManagerMXBean emits a notification.
160      * We don't rely on the notification content (if we were using a remote
161      * connection, we could miss some notifications) - we simply use the
162      * state change notifications to react more quickly to state changes.
163      * We do so simply by polling the {@link BlockingQueue} in which our
164      * listener is pushing notifications, and checking the ScanManagerMXBean
165      * state every time that a notification is received.
166      * <p>
167      * We can do so because we know that once the ScanManagerMXBean state is
168      * switched to 'CLOSED', it will remain 'CLOSED' whatsoever. <br>
169      * Therefore we don't need to concern ourselves with the possibility of
170      * missing the window in which the ScanManagerMXBean state's will be
171      * CLOSED, because that particular window stays opened forever.
172      * <p>
173      * Had we wanted to wait for 'RUNNING', we would have needed to apply
174      * a different strategy - e.g. by taking into account the actual content
175      * of the state changed notifications we received.
176      * @throws java.io.IOException wait failed - a communication problem occurred.
177      * @throws javax.management.JMException wait failed - the MBeanServer threw an exception.
178      */

179     public void waitForClose() throws IOException JavaDoc, JMException JavaDoc {
180
181         // Wait until state is closed
182
while(proxy.getState() != ScanState.CLOSED ) {
183             try {
184                 // Wake up at least every 30 seconds - if we missed a
185
// notification - we will at least get a chance to
186
// call getState(). 30 seconds is obviously quite
187
// arbitrary - if this were a real daemon - id'be tempted
188
// to wait 30 minutes - knowing that any incoming
189
// notification will wake me up anyway.
190
// Note: we simply use the state change notifications to
191
// react more quickly to state changes: see javadoc above.
192
//
193
queue.poll(30,TimeUnit.SECONDS);
194             } catch (InterruptedException JavaDoc ex) {
195                 // OK
196
}
197         }
198     }
199
200     /**
201      * The agent's main: {@link #init registers} a {@link ScanManagerMXBean},
202      * {@link #waitForClose waits} until its state is {@link
203      * ScanManagerMXBean.ScanState#CLOSED CLOSED}, {@link #cleanup cleanup}
204      * and exits.
205      * @param args the command line arguments - ignored
206      * @throws java.io.IOException A communication problem occurred.
207      * @throws javax.management.JMException A JMX problem occurred.
208      */

209     public static void main(String JavaDoc[] args)
210         throws IOException JavaDoc, JMException JavaDoc {
211         System.out.println("Initializing ScanManager...");
212         final ScanDirAgent agent = new ScanDirAgent();
213         agent.init();
214         try {
215             System.out.println("Waiting for ScanManager to close...");
216             agent.waitForClose();
217         } finally {
218             System.out.println("Cleaning up...");
219             agent.cleanup();
220         }
221     }
222 }
223
Popular Tags