Package com.sun.jmx.examples.scandir

Source Code of com.sun.jmx.examples.scandir.ScanDirAgent

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

package com.sun.jmx.examples.scandir;

import com.sun.jmx.examples.scandir.ScanManagerMXBean.ScanState;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import javax.management.JMException;
import javax.management.Notification;
import javax.management.NotificationEmitter;
import javax.management.NotificationListener;

/**
* <p>
* The <code>ScanDirAgent</code> is the Agent class for the <i>scandir</i>
* application.
* This class contains the {@link #main} method to start a standalone
* <i>scandir</i> application.
* </p>
* <p>
* The {@link #main main()} method simply registers a {@link
* ScanManagerMXBean} in the platform MBeanServer - see {@link #init init},
* and then waits for someone to call {@link ScanManagerMXBean#close close}
* on that MBean.
* </p>
* <p>
* When the {@link ScanManagerMXBean} state is switched to {@link
* ScanManagerMXBean.ScanState#CLOSED CLOSED}, {@link #cleanup cleanup} is
* called, the {@link ScanManagerMXBean} is unregistered, and the application
* terminates (i.e. the main thread completes).
* </p>
* @author Sun Microsystems, 2006 - All rights reserved.
**/
public class ScanDirAgent {

    /**
     * A logger for this class.
     **/
    private static final Logger LOG =
            Logger.getLogger(ScanDirAgent.class.getName());

    // Proxy to the ScanManagerMXBean - created by init();
    //
    private volatile ScanManagerMXBean proxy = null;

    // A queue to put received Notifications.
    //
    private final BlockingQueue<Notification> queue;

    // A listener that will put notifications into the queue.
    //
    private final NotificationListener listener;

    /**
     * Creates a new instance of ScanDirAgent
     * You will need to call {@link #init()} later on in order to initialize
     * the application.
     * @see #main
     **/
    public ScanDirAgent() {
        // Initialize the notification queue
        queue = new LinkedBlockingQueue<Notification>();

        // Creates the listener.
        listener = new NotificationListener() {
            public void handleNotification(Notification notification,
                                           Object handback) {
                try {
                    // Just put the received notification in the queue.
                    // It will be consumed later on by 'waitForClose()'
                    //
                    LOG.finer("Queuing received notification "+notification);
                    queue.put(notification);
                } catch (InterruptedException ex) {
                    // OK
                }
            }
        };
    }

    /**
     * Initialize the application by registering a ScanManagerMXBean in
     * the platform MBeanServer
     * @throws java.io.IOException Registration failed for communication-related reasons.
     * @throws javax.management.JMException Registration failed for JMX-related reasons.
     */
    public void init() throws IOException, JMException {

        // Registers the ScanManagerMXBean singleton in the
        // platform MBeanServer
        //
        proxy = ScanManager.register();

        // Registers a NotificationListener with the ScanManagerMXBean in
        // order to receive state changed notifications.
        //
        ((NotificationEmitter)proxy).addNotificationListener(listener,null,null);
    }

    /**
     * Cleanup after close: unregister the ScanManagerMXBean singleton.
     * @throws java.io.IOException Cleanup failed for communication-related reasons.
     * @throws javax.management.JMException Cleanup failed for JMX-related reasons.
     */
    public void cleanup() throws IOException, JMException {
        try {
            ((NotificationEmitter)proxy).
                    removeNotificationListener(listener,null,null);
        } finally {
            ManagementFactory.getPlatformMBeanServer().
                unregisterMBean(ScanManager.SCAN_MANAGER_NAME);
        }
    }

    /**
     * Wait for someone to call 'close()' on the ScanManagerMXBean singleton.
     * Every time its state changes, the ScanManagerMXBean emits a notification.
     * We don't rely on the notification content (if we were using a remote
     * connection, we could miss some notifications) - we simply use the
     * state change notifications to react more quickly to state changes.
     * We do so simply by polling the {@link BlockingQueue} in which our
     * listener is pushing notifications, and checking the ScanManagerMXBean
     * state every time that a notification is received.
     * <p>
     * We can do so because we know that once the ScanManagerMXBean state is
     * switched to 'CLOSED', it will remain 'CLOSED' whatsoever. <br>
     * Therefore we don't need to concern ourselves with the possibility of
     * missing the window in which the ScanManagerMXBean state's will be
     * CLOSED, because that particular window stays opened forever.
     * <p>
     * Had we wanted to wait for 'RUNNING', we would have needed to apply
     * a different strategy - e.g. by taking into account the actual content
     * of the state changed notifications we received.
     * @throws java.io.IOException wait failed - a communication problem occurred.
     * @throws javax.management.JMException wait failed - the MBeanServer threw an exception.
     */
    public void waitForClose() throws IOException, JMException {

        // Wait until state is closed
        while(proxy.getState() != ScanState.CLOSED ) {
            try {
                // Wake up at least every 30 seconds - if we missed a
                // notification - we will at least get a chance to
                // call getState(). 30 seconds is obviously quite
                // arbitrary - if this were a real daemon - id'be tempted
                // to wait 30 minutes - knowing that any incoming
                // notification will wake me up anyway.
                // Note: we simply use the state change notifications to
                // react more quickly to state changes: see javadoc above.
                //
                queue.poll(30,TimeUnit.SECONDS);
            } catch (InterruptedException ex) {
                // OK
            }
        }
    }

    /**
     * The agent's main: {@link #init registers} a {@link ScanManagerMXBean},
     * {@link #waitForClose waits} until its state is {@link
     * ScanManagerMXBean.ScanState#CLOSED CLOSED}, {@link #cleanup cleanup}
     * and exits.
     * @param args the command line arguments - ignored
     * @throws java.io.IOException A communication problem occurred.
     * @throws javax.management.JMException A JMX problem occurred.
     */
    public static void main(String[] args)
        throws IOException, JMException {
        System.out.println("Initializing ScanManager...");
        final ScanDirAgent agent = new ScanDirAgent();
        agent.init();
        try {
            System.out.println("Waiting for ScanManager to close...");
            agent.waitForClose();
        } finally {
            System.out.println("Cleaning up...");
            agent.cleanup();
        }
    }
}
TOP

Related Classes of com.sun.jmx.examples.scandir.ScanDirAgent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.