/*
 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.jconsole;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

/**
 * A JConsole plugin class.  JConsole uses the
 * <a href="{@docRoot}/../../../../api/java/util/ServiceLoader.html">
 * service provider</a> mechanism to search the JConsole plugins.
 * Users can provide their JConsole plugins in a jar file
 * containing a file named
 *
 * <blockquote><pre>
 * META-INF/services/com.sun.tools.jconsole.JConsolePlugin</pre></blockquote>
 *
 * <p> This file contains one line for each plugin, for example,
 *
 * <blockquote><pre>
 * com.sun.example.JTop</pre></blockquote>
 * <p> which is the fully qualified class name of the class implementing
 * {@code JConsolePlugin}.
 *
 * <p> To load the JConsole plugins in JConsole, run:
 *
 * <blockquote><pre>
 * jconsole -pluginpath &lt;plugin-path&gt; </pre></blockquote>
 *
 * <p> where {@code <plugin-path>} specifies the paths of JConsole
 * plugins to look up which can be a directory or a jar file. Multiple
 * paths are separated by the path separator character of the platform.
 *
 * <p> When a new JConsole window is created for a connection,
 * an instance of each {@code JConsolePlugin} will be created.
 * The {@code JConsoleContext} object is not available at its
 * construction time.
 * JConsole will set the {@link JConsoleContext} object for
 * a plugin after the plugin object is created.  It will then
 * call its {@link #getTabs getTabs} method and add the returned
 * tabs to the JConsole window.
 *
 * @see <a href="{@docRoot}/../../../../api/java/util/ServiceLoader.html">
 * java.util.ServiceLoader</a>
 *
 * @since 1.6
 */
public abstract class JConsolePlugin {
    private volatile JConsoleContext context = null;
    private List<PropertyChangeListener> listeners = null;

    /**
     * Constructor.
     */
    protected JConsolePlugin() {
    }

    /**
     * Sets the {@link JConsoleContext JConsoleContext} object representing
     * the connection to an application.  This method will be called
     * only once after the plugin is created and before the {@link #getTabs}
     * is called. The given {@code context} can be in any
     * {@link JConsoleContext#getConnectionState connection state} when
     * this method is called.
     *
     * @param context a {@code JConsoleContext} object
     */
    public final synchronized void setContext(JConsoleContext context) {
        this.context = context;
        if (listeners != null) {
            for (PropertyChangeListener l : listeners) {
                context.addPropertyChangeListener(l);
            }
            // throw away the listener list
            listeners = null;
        }
    }

    /**
     * Returns the {@link JConsoleContext JConsoleContext} object representing
     * the connection to an application.  This method may return {@code null}
     * if it is called before the {@link #setContext context} is initialized.
     *
     * @return the {@link JConsoleContext JConsoleContext} object representing
     *         the connection to an application.
     */
    public final JConsoleContext getContext() {
        return context;
    }

    /**
     * Returns the tabs to be added in JConsole window.
     * <p>
     * The returned map contains one entry for each tab
     * to be added in the tabbed pane in a JConsole window with
     * the tab name as the key
     * and the {@link JPanel} object as the value.
     * This method returns an empty map if no tab is added by this plugin.
     * This method will be called from the <i>Event Dispatch Thread</i>
     * once at the new connection time.
     *
     * @return a map of a tab name and a {@link JPanel} object
     *         representing the tabs to be added in the JConsole window;
     *         or an empty map.
     */
    public abstract java.util.Map<String, JPanel> getTabs();

    /**
     * Returns a {@link SwingWorker} to perform
     * the GUI update for this plugin at the same interval
     * as JConsole updates the GUI.
     * <p>
     * JConsole schedules the GUI update at an interval specified
     * for a connection.  This method will be called at every
     * update to obtain a {@code SwingWorker} for each plugin.
     * <p>
     * JConsole will invoke the {@link SwingWorker#execute execute()}
     * method to schedule the returned {@code SwingWorker} for execution
     * if:
     * <ul>
     *   <li> the {@code SwingWorker} object has not been executed
     *        (i.e. the {@link SwingWorker#getState} method
     *        returns {@link javax.swing.SwingWorker.StateValue#PENDING PENDING}
     *        state); and</li>
     *   <li> the {@code SwingWorker} object returned in the previous
     *        update has completed the task if it was not {@code null}
     *        (i.e. the {@link SwingWorker#isDone SwingWorker.isDone} method
     *        returns {@code true}).</li>
     * </ul>
     * <br>
     * Otherwise, {@code SwingWorker} object will not be scheduled to work.
     *
     * <p>
     * A plugin can schedule its own GUI update and this method
     * will return {@code null}.
     *
     * @return a {@code SwingWorker} to perform the GUI update; or
     *         {@code null}.
     */
    public abstract SwingWorker<?,?> newSwingWorker();

    /**
     * Dispose this plugin. This method is called by JConsole to inform
     * that this plugin will be discarded and that it should free
     * any resources that it has allocated.
     * The {@link #getContext JConsoleContext} can be in any
     * {@link JConsoleContext#getConnectionState connection state} when
     * this method is called.
     */
    public void dispose() {
        // Default nop implementation
    }

    /**
     * Adds a {@link PropertyChangeListener PropertyChangeListener}
     * to the {@link #getContext JConsoleContext} object for this plugin.
     * This method is a convenient method for this plugin to register
     * a listener when the {@code JConsoleContext} object may or
     * may not be available.
     *
     * <p>For example, a plugin constructor can
     * call this method to register a listener to listen to the
     * {@link JConsoleContext.ConnectionState connectionState}
     * property changes and the listener will be added to the
     * {@link JConsoleContext#addPropertyChangeListener JConsoleContext}
     * object when it is available.
     *
     * @param listener  The {@code PropertyChangeListener} to be added
     *
     * @throws NullPointerException if {@code listener} is {@code null}.
     */
    public final void addContextPropertyChangeListener(PropertyChangeListener listener) {
        if (listener == null) {
            throw new NullPointerException("listener is null");
        }

        if (context == null) {
            // defer registration of the listener until setContext() is called
            synchronized (this) {
                // check again if context is not set
                if (context == null) {
                    // maintain a listener list to be added later
                    if (listeners == null) {
                        listeners = new ArrayList<PropertyChangeListener>();
                    }
                    listeners.add(listener);
                    return;
                }
            }
        }
        context.addPropertyChangeListener(listener);
    }

    /**
     * Removes a {@link PropertyChangeListener PropertyChangeListener}
     * from the listener list of the {@link #getContext JConsoleContext}
     * object for this plugin.
     * If {@code listener} was never added, no exception is
     * thrown and no action is taken.
     *
     * @param listener the {@code PropertyChangeListener} to be removed
     *
     * @throws NullPointerException if {@code listener} is {@code null}.
     */
    public final void removeContextPropertyChangeListener(PropertyChangeListener listener) {
        if (listener == null) {
            throw new NullPointerException("listener is null");
        }

        if (context == null) {
            // defer registration of the listener until setContext() is called
            synchronized (this) {
                // check again if context is not set
                if (context == null) {
                    if (listeners != null) {
                        listeners.remove(listener);
                    }
                    return;
                }
            }
        }
        context.removePropertyChangeListener(listener);
    }
}
