/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.management.relation;

import static com.sun.jmx.mbeanserver.Util.cast;
import static com.sun.jmx.defaults.JmxProperties.RELATION_LOGGER;
import com.sun.jmx.mbeanserver.GetPropertyAction;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.security.AccessController;

import java.util.List;
import java.util.Vector;

import javax.management.MBeanServerNotification;

import javax.management.Notification;
import javax.management.NotificationFilterSupport;
import javax.management.ObjectName;

import java.util.List;
import java.util.logging.Level;
import java.util.Vector;

/**
 * Filter for {@link MBeanServerNotification}.
 * This filter filters MBeanServerNotification notifications by
 * selecting the ObjectNames of interest and the operations (registration,
 * unregistration, both) of interest (corresponding to notification
 * types).
 *
 * <p>The <b>serialVersionUID</b> of this class is <code>2605900539589789736L</code>.
 *
 * @since 1.5
 */
@SuppressWarnings("serial")  // serialVersionUID must be constant
public class MBeanServerNotificationFilter extends NotificationFilterSupport {

    // Serialization compatibility stuff:
    // Two serial forms are supported in this class. The selected form depends
    // on system property "jmx.serial.form":
    //  - "1.0" for JMX 1.0
    //  - any other value for JMX 1.1 and higher
    //
    // Serial version for old serial form
    private static final long oldSerialVersionUID = 6001782699077323605L;
    //
    // Serial version for new serial form
    private static final long newSerialVersionUID = 2605900539589789736L;
    //
    // Serializable fields in old serial form
    private static final ObjectStreamField[] oldSerialPersistentFields =
    {
      new ObjectStreamField("mySelectObjNameList", Vector.class),
      new ObjectStreamField("myDeselectObjNameList", Vector.class)
    };
    //
    // Serializable fields in new serial form
    private static final ObjectStreamField[] newSerialPersistentFields =
    {
      new ObjectStreamField("selectedNames", List.class),
      new ObjectStreamField("deselectedNames", List.class)
    };
    //
    // Actual serial version and serial form
    private static final long serialVersionUID;
    /**
     * @serialField selectedNames List List of {@link ObjectName}s of interest
     *         <ul>
     *         <li><code>null</code> means that all {@link ObjectName}s are implicitly selected
     *         (check for explicit deselections)</li>
     *         <li>Empty vector means that no {@link ObjectName} is explicitly selected</li>
     *         </ul>
     * @serialField deselectedNames List List of {@link ObjectName}s with no interest
     *         <ul>
     *         <li><code>null</code> means that all {@link ObjectName}s are implicitly deselected
     *         (check for explicit selections))</li>
     *         <li>Empty vector means that no {@link ObjectName} is explicitly deselected</li>
     *         </ul>
     */
    private static final ObjectStreamField[] serialPersistentFields;
    private static boolean compat = false;
    static {
        try {
            GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
            String form = AccessController.doPrivileged(act);
            compat = (form != null && form.equals("1.0"));
        } catch (Exception e) {
            // OK : Too bad, no compat with 1.0
        }
        if (compat) {
            serialPersistentFields = oldSerialPersistentFields;
            serialVersionUID = oldSerialVersionUID;
        } else {
            serialPersistentFields = newSerialPersistentFields;
            serialVersionUID = newSerialVersionUID;
        }
    }
    //
    // END Serialization compatibility stuff

    //
    // Private members
    //

    /**
     * @serial List of {@link ObjectName}s of interest
     *         <ul>
     *         <li><code>null</code> means that all {@link ObjectName}s are implicitly selected
     *         (check for explicit deselections)</li>
     *         <li>Empty vector means that no {@link ObjectName} is explicitly selected</li>
     *         </ul>
     */
    private List<ObjectName> selectedNames = new Vector<ObjectName>();

    /**
     * @serial List of {@link ObjectName}s with no interest
     *         <ul>
     *         <li><code>null</code> means that all {@link ObjectName}s are implicitly deselected
     *         (check for explicit selections))</li>
     *         <li>Empty vector means that no {@link ObjectName} is explicitly deselected</li>
     *         </ul>
     */
    private List<ObjectName> deselectedNames = null;

    //
    // Constructor
    //

    /**
     * Creates a filter selecting all MBeanServerNotification notifications for
     * all ObjectNames.
     */
    public MBeanServerNotificationFilter() {

        super();
        RELATION_LOGGER.entering(MBeanServerNotificationFilter.class.getName(),
                "MBeanServerNotificationFilter");

        enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION);
        enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);

        RELATION_LOGGER.exiting(MBeanServerNotificationFilter.class.getName(),
                "MBeanServerNotificationFilter");
        return;
    }

    //
    // Accessors
    //

    /**
     * Disables any MBeanServerNotification (all ObjectNames are
     * deselected).
     */
    public synchronized void disableAllObjectNames() {

        RELATION_LOGGER.entering(MBeanServerNotificationFilter.class.getName(),
                "disableAllObjectNames");

        selectedNames = new Vector<ObjectName>();
        deselectedNames = null;

        RELATION_LOGGER.exiting(MBeanServerNotificationFilter.class.getName(),
                "disableAllObjectNames");
        return;
    }

    /**
     * Disables MBeanServerNotifications concerning given ObjectName.
     *
     * @param objectName  ObjectName no longer of interest
     *
     * @exception IllegalArgumentException  if the given ObjectName is null
     */
    public synchronized void disableObjectName(ObjectName objectName)
        throws IllegalArgumentException {

        if (objectName == null) {
            String excMsg = "Invalid parameter.";
            throw new IllegalArgumentException(excMsg);
        }

        RELATION_LOGGER.entering(MBeanServerNotificationFilter.class.getName(),
                "disableObjectName", objectName);

        // Removes from selected ObjectNames, if present
        if (selectedNames != null) {
            if (selectedNames.size() != 0) {
                selectedNames.remove(objectName);
            }
        }

        // Adds it in deselected ObjectNames
        if (deselectedNames != null) {
            // If all are deselected, no need to do anything :)
            if (!(deselectedNames.contains(objectName))) {
                // ObjectName was not already deselected
                deselectedNames.add(objectName);
            }
        }

        RELATION_LOGGER.exiting(MBeanServerNotificationFilter.class.getName(),
                "disableObjectName");
        return;
    }

    /**
     * Enables all MBeanServerNotifications (all ObjectNames are selected).
     */
    public synchronized void enableAllObjectNames() {

        RELATION_LOGGER.entering(MBeanServerNotificationFilter.class.getName(),
                "enableAllObjectNames");

        selectedNames = null;
        deselectedNames = new Vector<ObjectName>();

        RELATION_LOGGER.exiting(MBeanServerNotificationFilter.class.getName(),
                "enableAllObjectNames");
        return;
    }

    /**
     * Enables MBeanServerNotifications concerning given ObjectName.
     *
     * @param objectName  ObjectName of interest
     *
     * @exception IllegalArgumentException  if the given ObjectName is null
     */
    public synchronized void enableObjectName(ObjectName objectName)
        throws IllegalArgumentException {

        if (objectName == null) {
            String excMsg = "Invalid parameter.";
            throw new IllegalArgumentException(excMsg);
        }

        RELATION_LOGGER.entering(MBeanServerNotificationFilter.class.getName(),
                "enableObjectName", objectName);

        // Removes from deselected ObjectNames, if present
        if (deselectedNames != null) {
            if (deselectedNames.size() != 0) {
                deselectedNames.remove(objectName);
            }
        }

        // Adds it in selected ObjectNames
        if (selectedNames != null) {
            // If all are selected, no need to do anything :)
            if (!(selectedNames.contains(objectName))) {
                // ObjectName was not already selected
                selectedNames.add(objectName);
            }
        }

        RELATION_LOGGER.exiting(MBeanServerNotificationFilter.class.getName(),
                "enableObjectName");
        return;
    }

    /**
     * Gets all the ObjectNames enabled.
     *
     * @return Vector of ObjectNames:
     * <P>- null means all ObjectNames are implicitly selected, except the
     * ObjectNames explicitly deselected
     * <P>- empty means all ObjectNames are deselected, i.e. no ObjectName
     * selected.
     */
    public synchronized Vector<ObjectName> getEnabledObjectNames() {
        if (selectedNames != null) {
            return new Vector<ObjectName>(selectedNames);
        } else {
            return null;
        }
    }

    /**
     * Gets all the ObjectNames disabled.
     *
     * @return Vector of ObjectNames:
     * <P>- null means all ObjectNames are implicitly deselected, except the
     * ObjectNames explicitly selected
     * <P>- empty means all ObjectNames are selected, i.e. no ObjectName
     * deselected.
     */
    public synchronized Vector<ObjectName> getDisabledObjectNames() {
        if (deselectedNames != null) {
            return new Vector<ObjectName>(deselectedNames);
        } else {
            return null;
        }
    }

    //
    // NotificationFilter interface
    //

    /**
     * Invoked before sending the specified notification to the listener.
     * <P>If:
     * <P>- the ObjectName of the concerned MBean is selected (explicitly OR
     * (implicitly and not explicitly deselected))
     * <P>AND
     * <P>- the type of the operation (registration or unregistration) is
     * selected
     * <P>then the notification is sent to the listener.
     *
     * @param notif  The notification to be sent.
     *
     * @return true if the notification has to be sent to the listener, false
     * otherwise.
     *
     * @exception IllegalArgumentException  if null parameter
     */
    public synchronized boolean isNotificationEnabled(Notification notif)
        throws IllegalArgumentException {

        if (notif == null) {
            String excMsg = "Invalid parameter.";
            throw new IllegalArgumentException(excMsg);
        }

        RELATION_LOGGER.entering(MBeanServerNotificationFilter.class.getName(),
                "isNotificationEnabled", notif);

        // Checks the type first
        String ntfType = notif.getType();
        Vector enabledTypes = getEnabledTypes();
        if (!(enabledTypes.contains(ntfType))) {
            RELATION_LOGGER.logp(Level.FINER,
                    MBeanServerNotificationFilter.class.getName(),
                    "isNotificationEnabled",
                    "Type not selected, exiting");
            return false;
        }

        // We have a MBeanServerNotification: downcasts it
        MBeanServerNotification mbsNtf = (MBeanServerNotification)notif;

        // Checks the ObjectName
        ObjectName objName = mbsNtf.getMBeanName();
        // Is it selected?
        boolean isSelectedFlg = false;
        if (selectedNames != null) {
            // Not all are implicitly selected:
            // checks for explicit selection
            if (selectedNames.size() == 0) {
                // All are explicitly not selected
                RELATION_LOGGER.logp(Level.FINER,
                        MBeanServerNotificationFilter.class.getName(),
                        "isNotificationEnabled",
                        "No ObjectNames selected, exiting");
                return false;
            }

            isSelectedFlg = selectedNames.contains(objName);
            if (!isSelectedFlg) {
                // Not in the explicit selected list
                RELATION_LOGGER.logp(Level.FINER,
                        MBeanServerNotificationFilter.class.getName(),
                        "isNotificationEnabled",
                        "ObjectName not in selected list, exiting");
                return false;
            }
        }

        if (!isSelectedFlg) {
            // Not explicitly selected: is it deselected?

            if (deselectedNames == null) {
                // All are implicitly deselected and it is not explicitly
                // selected
                RELATION_LOGGER.logp(Level.FINER,
                        MBeanServerNotificationFilter.class.getName(),
                        "isNotificationEnabled",
                        "ObjectName not selected, and all " +
                        "names deselected, exiting");
                return false;

            } else if (deselectedNames.contains(objName)) {
                // Explicitly deselected
                RELATION_LOGGER.logp(Level.FINER,
                        MBeanServerNotificationFilter.class.getName(),
                        "isNotificationEnabled",
                        "ObjectName explicitly not selected, exiting");
                return false;
            }
        }

        RELATION_LOGGER.logp(Level.FINER,
                MBeanServerNotificationFilter.class.getName(),
                "isNotificationEnabled",
                "ObjectName selected, exiting");
        return true;
    }


    /**
     * Deserializes an {@link MBeanServerNotificationFilter} from an {@link ObjectInputStream}.
     */
    private void readObject(ObjectInputStream in)
            throws IOException, ClassNotFoundException {
      if (compat)
      {
        // Read an object serialized in the old serial form
        //
        ObjectInputStream.GetField fields = in.readFields();
        selectedNames = cast(fields.get("mySelectObjNameList", null));
        if (fields.defaulted("mySelectObjNameList"))
        {
          throw new NullPointerException("mySelectObjNameList");
        }
        deselectedNames = cast(fields.get("myDeselectObjNameList", null));
        if (fields.defaulted("myDeselectObjNameList"))
        {
          throw new NullPointerException("myDeselectObjNameList");
        }
      }
      else
      {
        // Read an object serialized in the new serial form
        //
        in.defaultReadObject();
      }
    }


    /**
     * Serializes an {@link MBeanServerNotificationFilter} to an {@link ObjectOutputStream}.
     */
    private void writeObject(ObjectOutputStream out)
            throws IOException {
      if (compat)
      {
        // Serializes this instance in the old serial form
        //
        ObjectOutputStream.PutField fields = out.putFields();
        fields.put("mySelectObjNameList", (Vector)selectedNames);
        fields.put("myDeselectObjNameList", (Vector)deselectedNames);
        out.writeFields();
      }
      else
      {
        // Serializes this instance in the new serial form
        //
        out.defaultWriteObject();
      }
    }
}
