alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ScanDirConfig.java)

This example Java source code file (ScanDirConfig.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

default, directoryscannerconfig, emitted, exception, file, ioexception, log, logging, management, mbeannotificationinfo, modified, notification_modified, notification_prefix, objectname, scandirconfig, scanmanagerconfig, string, util

The ScanDirConfig.java Java example source code

/*
 * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions 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 Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * This source code is provided to illustrate the usage of a given feature
 * or technique and has been deliberately simplified. Additional steps
 * required for a production-quality application, such as security checks,
 * input validation and proper error handling, might not be present in
 * this sample code.
 */


package com.sun.jmx.examples.scandir;

import static com.sun.jmx.examples.scandir.ScanManager.getNextSeqNumber;
import static com.sun.jmx.examples.scandir.ScanDirConfigMXBean.SaveState.*;
import com.sun.jmx.examples.scandir.config.XmlConfigUtils;
import com.sun.jmx.examples.scandir.config.DirectoryScannerConfig;
import com.sun.jmx.examples.scandir.config.FileMatch;
import com.sun.jmx.examples.scandir.config.ScanManagerConfig;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.*;
import javax.xml.bind.JAXBException;

/**
 * <p>The ScanDirConfig MBean is in charge of the
 * <i>scandir application configuration.
 * </p>
 * <p>The ScanDirConfig MBean is able to
 * load and save the <i>scandir application configuration to and from an
 * XML file.
 * </p>
 * <p>
 * It will let you also interactively modify that configuration, which you
 * can later save to the file, by calling {@link #save}, or discard, by
 * reloading the file without saving - see {@link #load}.
 * </p>
 * <p>
 * There can be as many <code>ScanDirConfigMXBean registered
 * in the MBeanServer as you like, but only one of them will be identified as
 * the current configuration of the {@link ScanManagerMXBean}.
 * You can switch to another configuration by calling {@link
 * ScanManagerMXBean#setConfigurationMBean
 * ScanManagerMXBean.setConfigurationMBean}.
 * </p>
 * <p>
 * Once the current configuration has been loaded (by calling {@link #load})
 * or modified (by calling one of {@link #addDirectoryScanner
 * addDirectoryScanner}, {@link #removeDirectoryScanner removeDirectoryScanner}
 * or {@link #setConfiguration setConfiguration}) it can be pushed
 * to the {@link ScanManagerMXBean} by calling {@link
 * ScanManagerMXBean#applyConfiguration
 * ScanManagerMXBean.applyConfiguration(true)} -
 * <code>true means that we apply the configuration from memory,
 * without first reloading the file.
 * </p>
 * <p>
 * The <code>ScanDirConfig uses the XML annotated Java Beans defined
 * in the {@link com.sun.jmx.examples.scandir.config} package.
 * </p>
 * <p>
 * <u>Note: The ScanDirConfig should probably use
 * {@code java.nio.channels.FileLock} and lock its configuration file so that
 * two <code>ScanDirConfig object do not share the same file, but it
 * doesn't. Feel free to improve the application in that way.
 * </p>
 * @author Sun Microsystems, 2006 - All rights reserved.
 */
public class ScanDirConfig extends NotificationBroadcasterSupport
        implements ScanDirConfigMXBean, MBeanRegistration {

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

    // We will emit a notification when the save state of this object
    // chenges. We use directly the base notification class, with a
    // notification type that indicates the new state at which the
    // object has arrived.
    //
    // All these notification types will have the same prefix, which is
    // 'com.sun.jmx.examples.scandir.config'.
    //
    private final static String NOTIFICATION_PREFIX =
            ScanManagerConfig.class.getPackage().getName();

    /**
     * The <i>com.sun.jmx.examples.scandir.config.saved notification
     * indicates that the configuration data was saved.
     **/
    public final static String NOTIFICATION_SAVED =
            NOTIFICATION_PREFIX+".saved";
    /**
     * The <i>com.sun.jmx.examples.scandir.config.loaded notification
     * indicates that the configuration data was loaded.
     **/
    public final static String NOTIFICATION_LOADED =
            NOTIFICATION_PREFIX+".loaded";

    /**
     * The <i>com.sun.jmx.examples.scandir.config.modified notification
     * indicates that the configuration data was modified.
     **/
    public final static String NOTIFICATION_MODIFIED =
            NOTIFICATION_PREFIX+".modified";

    // The array of MBeanNotificationInfo that will be exposed in the
    // ScanDirConfigMXBean MBeanInfo.
    // We will pass this array to the NotificationBroadcasterSupport
    // constructor.
    //
    private static MBeanNotificationInfo[] NOTIFICATION_INFO = {
        new MBeanNotificationInfo(
                new String[] {NOTIFICATION_SAVED},
                Notification.class.getName(),
                "Emitted when the configuration is saved"),
        new MBeanNotificationInfo(
                new String[] {NOTIFICATION_LOADED},
                Notification.class.getName(),
                "Emitted when the configuration is loaded"),
        new MBeanNotificationInfo(
                new String[] {NOTIFICATION_MODIFIED},
                Notification.class.getName(),
                "Emitted when the configuration is modified"),
    };

     // The ScanDirConfigMXBean configuration data.
    private volatile ScanManagerConfig config;

    // The name of the configuration file
    private String filename = null;

    // The name of this configuration. This is usually both equal to
    // config.getName() and objectName.getKeyProperty(name).
    private volatile String configname = null;

    // This object save state. CREATED is the initial state.
    //
    private volatile SaveState status = CREATED;

    /**
     * Creates a new {@link ScanDirConfigMXBean}.
     * <p>{@code ScanDirConfigMXBean} can be created by the {@link
     * ScanManagerMXBean}, or directly by a remote client, using
     * {@code createMBean} or {@code registerMBean}.
     * </p>
     * <p>{@code ScanDirConfigMXBean} created by the {@link
     * ScanManagerMXBean} will be unregistered by the
     * {@code ScanManagerMXBean}. {@code ScanDirConfigMXBean} created
     * directly by a remote client will not be unregistered by the
     * {@code ScanManagerMXBean} - this will remain to the responsibility of
     * the code/client that created them.
     * </p>
     * <p>This object is created empty, you should call load() if you want it
     *    to load its data from the configuration file.
     * </p>
     * @param  filename The configuration file used by this MBean.
     *         Can be null (in which case load() and save() will fail).
     *         Can point to a file that does not exists yet (in which case
     *         load() will fail if called before save(), and save() will
     *         attempt to create that file). Can point to an existing file,
     *         in which case load() will load that file and save() will save
     *         to that file.
     *
     **/
    public ScanDirConfig(String filename) {
        this(filename,null);
    }

    /**
     * Create a new ScanDirConfig MBean with an initial configuration.
     * @param filename The name of the configuration file.
     * @param initialConfig an initial configuration.
     **/
    public ScanDirConfig(String filename, ScanManagerConfig initialConfig) {
        super(NOTIFICATION_INFO);
        this.filename = filename;
        this.config = initialConfig;
    }


    // see ScanDirConfigMXBean
    public void load() throws IOException {
        if (filename == null)
            throw new UnsupportedOperationException("load");

        synchronized(this) {
            config = new XmlConfigUtils(filename).readFromFile();
            if (configname != null) config = config.copy(configname);
            else configname = config.getName();

            status=LOADED;
        }
        sendNotification(NOTIFICATION_LOADED);
    }

    // see ScanDirConfigMXBean
    public void save() throws IOException {
        if (filename == null)
            throw new UnsupportedOperationException("load");
        synchronized (this) {
            new XmlConfigUtils(filename).writeToFile(config);
            status = SAVED;
        }
        sendNotification(NOTIFICATION_SAVED);
    }

    // see ScanDirConfigMXBean
    public ScanManagerConfig getConfiguration() {
        synchronized (this) {
            return XmlConfigUtils.xmlClone(config);
        }
    }


    // sends a notification indicating the new save state.
    private void sendNotification(String type) {
        final Object source = (objectName==null)?this:objectName;
        final Notification n = new Notification(type,source,
                getNextSeqNumber(),
                "The configuration is "+
                type.substring(type.lastIndexOf('.')+1));
        sendNotification(n);
    }


    /**
     * Allows the MBean to perform any operations it needs before being
     * registered in the MBean server. If the name of the MBean is not
     * specified, the MBean can provide a name for its registration. If
     * any exception is raised, the MBean will not be registered in the
     * MBean server.
     * @param server The MBean server in which the MBean will be registered.
     * @param name The object name of the MBean. This name is null if the
     * name parameter to one of the createMBean or registerMBean methods in
     * the MBeanServer interface is null. In that case, this method will
     * try to guess its MBean name by examining its configuration data.
     * If its configuration data is null (nothing was provided in the
     * constructor) or doesn't contain a name, this method returns {@code null},
     * and registration will fail.
     * <p>
     * Otherwise, if {@code name} wasn't {@code null} or if a default name could
     * be constructed, the name of the configuration will be set to
     * the value of the ObjectName's {@code name=} key, and the configuration
     * data will always be renamed to reflect this change.
     * </p>
     *
     * @return The name under which the MBean is to be registered.
     * @throws Exception This exception will be caught by the MBean server and
     * re-thrown as an MBeanRegistrationException.
     */
    public ObjectName preRegister(MBeanServer server, ObjectName name)
        throws Exception {
        if (name == null) {
            if (config == null) return null;
            if (config.getName() == null) return null;
            name = ScanManager.
                    makeMBeanName(ScanDirConfigMXBean.class,config.getName());
        }
        objectName = name;
        mbeanServer = server;
        synchronized (this) {
            configname = name.getKeyProperty("name");
            if (config == null) config = new ScanManagerConfig(configname);
            else config = config.copy(configname);
        }
        return name;
    }

    /**
     * Allows the MBean to perform any operations needed after having
     * been registered in the MBean server or after the registration has
     * failed.
     * <p>This implementation does nothing

* @param registrationDone Indicates whether or not the MBean has been * successfully registered in the MBean server. The value false means * that the registration has failed. */ public void postRegister(Boolean registrationDone) { // Nothing to do here. } /** * Allows the MBean to perform any operations it needs before being * unregistered by the MBean server. * <p>This implementation does nothing

* @throws Exception This exception will be caught by the MBean server and * re-thrown as an MBeanRegistrationException. */ public void preDeregister() throws Exception { // Nothing to do here. } /** * Allows the MBean to perform any operations needed after having been * unregistered in the MBean server. * <p>This implementation does nothing

*/ public void postDeregister() { // Nothing to do here. } // see ScanDirConfigMXBean public String getConfigFilename() { return filename; } // see ScanDirConfigMXBean public void setConfiguration(ScanManagerConfig config) { synchronized (this) { if (config == null) { this.config = null; return; } if (configname == null) configname = config.getName(); this.config = config.copy(configname); status = MODIFIED; } sendNotification(NOTIFICATION_MODIFIED); } // see ScanDirConfigMXBean public DirectoryScannerConfig addDirectoryScanner(String name, String dir, String filePattern, long sizeExceedsMaxBytes, long sinceLastModified) { final DirectoryScannerConfig scanner = new DirectoryScannerConfig(name); scanner.setRootDirectory(dir); if (filePattern!=null||sizeExceedsMaxBytes>0||sinceLastModified>0) { final FileMatch filter = new FileMatch(); filter.setFilePattern(filePattern); filter.setSizeExceedsMaxBytes(sizeExceedsMaxBytes); if (sinceLastModified > 0) filter.setLastModifiedBefore(new Date(new Date().getTime() -sinceLastModified)); scanner.addIncludeFiles(filter); } synchronized (this) { config.putScan(scanner); status = MODIFIED; } LOG.fine("config: "+config); sendNotification(NOTIFICATION_MODIFIED); return scanner; } // see ScanDirConfigMXBean public DirectoryScannerConfig removeDirectoryScanner(String name) throws IOException, InstanceNotFoundException { final DirectoryScannerConfig scanner; synchronized (this) { scanner = config.removeScan(name); if (scanner == null) throw new IllegalArgumentException(name+": scanner not found"); status = MODIFIED; } sendNotification(NOTIFICATION_MODIFIED); return scanner; } // see ScanDirConfigMXBean public SaveState getSaveState() { return status; } // These methods are used by ScanManager to guess a configuration name from // a configuration filename. // static String DEFAULT = "DEFAULT"; private static String getBasename(String name) { final int dot = name.indexOf('.'); if (dot<0) return name; if (dot==0) return getBasename(name.substring(1)); return name.substring(0,dot); } static String guessConfigName(String configFileName,String defaultFile) { try { if (configFileName == null) return DEFAULT; final File f = new File(configFileName); if (f.canRead()) { final String confname = XmlConfigUtils.read(f).getName(); if (confname != null && confname.length()>0) return confname; } final File f2 = new File(defaultFile); if (f.equals(f2)) return DEFAULT; final String guess = getBasename(f.getName()); if (guess == null) return DEFAULT; if (guess.length()==0) return DEFAULT; return guess; } catch (Exception x) { return DEFAULT; } } // Set by preRegister() private volatile MBeanServer mbeanServer; private volatile ObjectName objectName; }

Other Java examples (source code examples)

Here is a short list of links related to this Java ScanDirConfig.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.