Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/tools/jconsole/JConsolePlugin.java
38920 views
/*1* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.jconsole;2627import java.beans.PropertyChangeEvent;28import java.beans.PropertyChangeListener;29import java.util.ArrayList;30import java.util.List;31import javax.swing.JPanel;32import javax.swing.SwingWorker;3334/**35* A JConsole plugin class. JConsole uses the36* <a href="{@docRoot}/../../../../api/java/util/ServiceLoader.html">37* service provider</a> mechanism to search the JConsole plugins.38* Users can provide their JConsole plugins in a jar file39* containing a file named40*41* <blockquote><pre>42* META-INF/services/com.sun.tools.jconsole.JConsolePlugin</pre></blockquote>43*44* <p> This file contains one line for each plugin, for example,45*46* <blockquote><pre>47* com.sun.example.JTop</pre></blockquote>48* <p> which is the fully qualified class name of the class implementing49* {@code JConsolePlugin}.50*51* <p> To load the JConsole plugins in JConsole, run:52*53* <blockquote><pre>54* jconsole -pluginpath <plugin-path> </pre></blockquote>55*56* <p> where <tt><plugin-path></tt> specifies the paths of JConsole57* plugins to look up which can be a directory or a jar file. Multiple58* paths are separated by the path separator character of the platform.59*60* <p> When a new JConsole window is created for a connection,61* an instance of each {@code JConsolePlugin} will be created.62* The {@code JConsoleContext} object is not available at its63* construction time.64* JConsole will set the {@link JConsoleContext} object for65* a plugin after the plugin object is created. It will then66* call its {@link #getTabs getTabs} method and add the returned67* tabs to the JConsole window.68*69* @see <a href="{@docRoot}/../../../../api/java/util/ServiceLoader.html">70* java.util.ServiceLoader</a>71*72* @since 1.673*/74@jdk.Exported75public abstract class JConsolePlugin {76private volatile JConsoleContext context = null;77private List<PropertyChangeListener> listeners = null;7879/**80* Constructor.81*/82protected JConsolePlugin() {83}8485/**86* Sets the {@link JConsoleContext JConsoleContext} object representing87* the connection to an application. This method will be called88* only once after the plugin is created and before the {@link #getTabs}89* is called. The given {@code context} can be in any90* {@link JConsoleContext#getConnectionState connection state} when91* this method is called.92*93* @param context a {@code JConsoleContext} object94*/95public final synchronized void setContext(JConsoleContext context) {96this.context = context;97if (listeners != null) {98for (PropertyChangeListener l : listeners) {99context.addPropertyChangeListener(l);100}101// throw away the listener list102listeners = null;103}104}105106/**107* Returns the {@link JConsoleContext JConsoleContext} object representing108* the connection to an application. This method may return <tt>null</tt>109* if it is called before the {@link #setContext context} is initialized.110*111* @return the {@link JConsoleContext JConsoleContext} object representing112* the connection to an application.113*/114public final JConsoleContext getContext() {115return context;116}117118/**119* Returns the tabs to be added in JConsole window.120* <p>121* The returned map contains one entry for each tab122* to be added in the tabbed pane in a JConsole window with123* the tab name as the key124* and the {@link JPanel} object as the value.125* This method returns an empty map if no tab is added by this plugin.126* This method will be called from the <i>Event Dispatch Thread</i>127* once at the new connection time.128*129* @return a map of a tab name and a {@link JPanel} object130* representing the tabs to be added in the JConsole window;131* or an empty map.132*/133public abstract java.util.Map<String, JPanel> getTabs();134135/**136* Returns a {@link SwingWorker} to perform137* the GUI update for this plugin at the same interval138* as JConsole updates the GUI.139* <p>140* JConsole schedules the GUI update at an interval specified141* for a connection. This method will be called at every142* update to obtain a {@code SwingWorker} for each plugin.143* <p>144* JConsole will invoke the {@link SwingWorker#execute execute()}145* method to schedule the returned {@code SwingWorker} for execution146* if:147* <ul>148* <li> the <tt>SwingWorker</tt> object has not been executed149* (i.e. the {@link SwingWorker#getState} method150* returns {@link javax.swing.SwingWorker.StateValue#PENDING PENDING}151* state); and</li>152* <li> the <tt>SwingWorker</tt> object returned in the previous153* update has completed the task if it was not <tt>null</tt>154* (i.e. the {@link SwingWorker#isDone SwingWorker.isDone} method155* returns <tt>true</tt>).</li>156* </ul>157* <br>158* Otherwise, <tt>SwingWorker</tt> object will not be scheduled to work.159*160* <p>161* A plugin can schedule its own GUI update and this method162* will return <tt>null</tt>.163*164* @return a <tt>SwingWorker</tt> to perform the GUI update; or165* <tt>null</tt>.166*/167public abstract SwingWorker<?,?> newSwingWorker();168169/**170* Dispose this plugin. This method is called by JConsole to inform171* that this plugin will be discarded and that it should free172* any resources that it has allocated.173* The {@link #getContext JConsoleContext} can be in any174* {@link JConsoleContext#getConnectionState connection state} when175* this method is called.176*/177public void dispose() {178// Default nop implementation179}180181/**182* Adds a {@link PropertyChangeListener PropertyChangeListener}183* to the {@link #getContext JConsoleContext} object for this plugin.184* This method is a convenient method for this plugin to register185* a listener when the {@code JConsoleContext} object may or186* may not be available.187*188* <p>For example, a plugin constructor can189* call this method to register a listener to listen to the190* {@link JConsoleContext.ConnectionState connectionState}191* property changes and the listener will be added to the192* {@link JConsoleContext#addPropertyChangeListener JConsoleContext}193* object when it is available.194*195* @param listener The {@code PropertyChangeListener} to be added196*197* @throws NullPointerException if {@code listener} is {@code null}.198*/199public final void addContextPropertyChangeListener(PropertyChangeListener listener) {200if (listener == null) {201throw new NullPointerException("listener is null");202}203204if (context == null) {205// defer registration of the listener until setContext() is called206synchronized (this) {207// check again if context is not set208if (context == null) {209// maintain a listener list to be added later210if (listeners == null) {211listeners = new ArrayList<PropertyChangeListener>();212}213listeners.add(listener);214return;215}216}217}218context.addPropertyChangeListener(listener);219}220221/**222* Removes a {@link PropertyChangeListener PropertyChangeListener}223* from the listener list of the {@link #getContext JConsoleContext}224* object for this plugin.225* If {@code listener} was never added, no exception is226* thrown and no action is taken.227*228* @param listener the {@code PropertyChangeListener} to be removed229*230* @throws NullPointerException if {@code listener} is {@code null}.231*/232public final void removeContextPropertyChangeListener(PropertyChangeListener listener) {233if (listener == null) {234throw new NullPointerException("listener is null");235}236237if (context == null) {238// defer registration of the listener until setContext() is called239synchronized (this) {240// check again if context is not set241if (context == null) {242if (listeners != null) {243listeners.remove(listener);244}245return;246}247}248}249context.removePropertyChangeListener(listener);250}251}252253254