/*
* Copyright (c) 2007, 2011, 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.visualvm.jmx;
import com.sun.tools.visualvm.application.Application;
import com.sun.tools.visualvm.core.datasource.Storage;
import com.sun.tools.visualvm.core.datasupport.Utils;
import com.sun.tools.visualvm.jmx.impl.JmxApplicationProvider;
import java.io.File;
import javax.swing.SwingUtilities;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
/**
* Support for creating JMX applications in VisualVM.
*
* @since VisualVM 1.1
* @author Jiri Sedlacek
*/
public final class JmxApplicationsSupport {
private static final String STORAGE_DIRNAME = "jmxapplications"; // NOI18N
private static final Object storageDirectoryLock = new Object();
// @GuardedBy storageDirectoryLock
private static File storageDirectory;
private static final Object storageDirectoryStringLock = new Object();
// @GuardedBy storageDirectoryStringLock
private static String storageDirectoryString;
private static JmxApplicationsSupport instance;
private JmxApplicationProvider applicationProvider = new JmxApplicationProvider();
/**
* Returns singleton instance of JmxApplicationsSupport.
*
* @return singleton instance of JmxApplicationsSupport.
*/
public static synchronized JmxApplicationsSupport getInstance() {
if (instance == null) instance = new JmxApplicationsSupport();
return instance;
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. The application won't be restored on another VisualVM
* sessions. Throws a JmxApplicationException if the application cannot be created.
*
* Note that even though the created application won't be restored for another
* VisualVM sessions, the host created for this application will be restored.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param username username for the connection, may be null
* @param password password for the connection, may be null
* @return created JMX application
* @throws JmxApplicationException if creating the application failed
*/
public Application createJmxApplication(String connectionString, String displayName,
String username, String password) throws JmxApplicationException {
return createJmxApplication(connectionString, displayName, username,
password, false, false);
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. Throws a JmxApplicationException if the application
* cannot be created.
*
* Note that even if the created application isn't persistent for another
* VisualVM sessions, the host created for this application will be restored.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param username username for the connection, may be null
* @param password password for the connection, may be null
* @param saveCredentials if persistent, controls whether the username and password should be persisted for another VisualVM sessions
* @param persistent controls whether the application definition will be persisted for another VisualVM sessions
* @return created JMX application
* @throws JmxApplicationException if creating the application failed
*/
public Application createJmxApplication(String connectionString,
String displayName, String username,
String password, boolean saveCredentials,
boolean persistent) throws JmxApplicationException {
if (username == null) username = ""; // NOI18N
if (password == null) password = ""; // NOI18N
String suggestedName = JmxApplicationProvider.getSuggestedName(displayName,
connectionString, username);
EnvironmentProvider epr = new CredentialsProvider.Custom(username,
password.toCharArray(), saveCredentials);
return createJmxApplicationImpl(connectionString, displayName, suggestedName,
epr, persistent, false);
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. Throws a JmxApplicationException if the application
* cannot be created.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param provider JMX EnvironmentProvider for the Application
* @param persistent controls whether the application definition will be persisted for another VisualVM sessions
* @return created JMX application
* @throws JmxApplicationException if creating the application failed
*
* @since VisualVM 1.2
*/
public Application createJmxApplication(String connectionString,
String displayName,
EnvironmentProvider provider,
boolean persistent) throws JmxApplicationException {
String username = getUsername(provider);
String suggestedName = JmxApplicationProvider.getSuggestedName(displayName,
connectionString, username);
return createJmxApplicationImpl(connectionString, displayName, suggestedName,
provider, persistent, false);
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. The application won't be restored on another VisualVM
* sessions. Displays progress during application creation and opens an error
* dialog if creating the application failed. Throws a JmxApplicationException
* if the application cannot be created.
*
* Note that even though the created application won't be restored for another
* VisualVM sessions, the host created for this application will be restored.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param username username for the connection, may be null
* @param password password for the connection, may be null
* @return created JMX application or null if creating the application failed
* @throws JmxApplicationException if creating the application failed
*/
public Application createJmxApplicationInteractive(String connectionString, String displayName,
String username, String password) {
return createJmxApplicationInteractive(connectionString, displayName, username,
password, false, false);
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. Displays progress during application creation and
* opens an error dialog if creating the application failed.
*
* Note that even if the created application isn't persistent for another
* VisualVM sessions, the host created for this application will be restored.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param username username for the connection, may be null
* @param password password for the connection, may be null
* @param saveCredentials if persistent, controls whether the username and password should be persisted for another VisualVM sessions
* @param persistent controls whether the application definition will be persisted for another VisualVM sessions
* @return created JMX application or null if creating the application failed
*/
public Application createJmxApplicationInteractive(String connectionString,
String displayName, String username,
String password, boolean saveCredentials,
boolean persistent) {
if (username == null) username = ""; // NOI18N
if (password == null) password = ""; // NOI18N
final ProgressHandle[] pHandle = new ProgressHandle[1];
try {
final String suggestedName = JmxApplicationProvider.getSuggestedName(
displayName, connectionString, username);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
pHandle[0] = ProgressHandleFactory.createHandle(
NbBundle.getMessage(JmxApplicationsSupport.class,
"LBL_Adding", suggestedName)); // NOI18N
pHandle[0].setInitialDelay(0);
pHandle[0].start();
}
});
EnvironmentProvider epr = new CredentialsProvider.Custom(username,
password.toCharArray(), saveCredentials);
return createJmxApplicationImpl(connectionString, displayName,
suggestedName, epr, persistent, false);
} catch (JmxApplicationException e) {
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(e.
getMessage(), NotifyDescriptor.ERROR_MESSAGE));
} finally {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (pHandle[0] != null) {
pHandle[0].finish();
}
}
});
}
return null;
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. Displays progress during application creation and
* opens an error dialog if creating the application failed.
*
* Note that even if the created application isn't persistent for another
* VisualVM sessions, the host created for this application will be restored.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param provider JMX EnvironmentProvider for the Application
* @param persistent controls whether the application definition will be persisted for another VisualVM sessions
* @return created JMX application or null if creating the application failed
*
* @since VisualVM 1.2
*/
public Application createJmxApplicationInteractive(String connectionString,
String displayName,
EnvironmentProvider provider,
boolean persistent) {
return createJmxApplicationInteractive(connectionString, displayName,
provider, persistent, false);
}
/**
* Creates new Application defined by JMX connection and adds it to the
* Applications tree. Displays progress during application creation and
* opens an error dialog if creating the application failed.
*
* Note that even if the created application isn't persistent for another
* VisualVM sessions, the host created for this application will be restored.
*
* @param connectionString definition of the connection, for example hostname:port
* @param displayName display name for the application, may be null
* @param provider JMX EnvironmentProvider for the Application
* @param persistent controls whether the application definition will be persisted for another VisualVM sessions
* @param allowsInsecure true if SSL is not required for the connection, false otherwise
* @return created JMX application or null if creating the application failed
*
* @since VisualVM 1.3.7
*/
public Application createJmxApplicationInteractive(String connectionString,
String displayName,
EnvironmentProvider provider,
boolean persistent, boolean allowsInsecure) {
final ProgressHandle[] pHandle = new ProgressHandle[1];
try {
String username = getUsername(provider);
final String suggestedName = JmxApplicationProvider.getSuggestedName(
displayName, connectionString, username);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
pHandle[0] = ProgressHandleFactory.createHandle(
NbBundle.getMessage(JmxApplicationsSupport.class,
"LBL_Adding", suggestedName)); // NOI18N
pHandle[0].setInitialDelay(0);
pHandle[0].start();
}
});
return createJmxApplicationImpl(connectionString, displayName, suggestedName,
provider, persistent, allowsInsecure);
} catch (JmxApplicationException e) {
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(e.
getMessage(), NotifyDescriptor.ERROR_MESSAGE));
} finally {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (pHandle[0] != null) {
pHandle[0].finish();
}
}
});
}
return null;
}
private Application createJmxApplicationImpl(String connectionString,
String displayName, String suggestedName,
EnvironmentProvider provider,
boolean persistent, boolean allowsInsecure)
throws JmxApplicationException {
return applicationProvider.createJmxApplication(connectionString,
displayName, suggestedName, provider, persistent, allowsInsecure);
}
private static String getUsername(EnvironmentProvider provider) {
return provider instanceof CredentialsProvider ?
((CredentialsProvider)provider).getUsername(null) : null;
}
static String getStorageDirectoryString() {
synchronized(storageDirectoryStringLock) {
if (storageDirectoryString == null)
storageDirectoryString = Storage.getPersistentStorageDirectoryString() + File.separator + STORAGE_DIRNAME;
return storageDirectoryString;
}
}
/**
* Returns storage directory for defined JMX applications.
*
* @return storage directory for defined JMX applications.
*/
public static File getStorageDirectory() {
synchronized(storageDirectoryLock) {
if (storageDirectory == null) {
String storageString = getStorageDirectoryString();
storageDirectory = new File(storageString);
if (storageDirectory.exists() && storageDirectory.isFile())
throw new IllegalStateException("Cannot create hosts storage directory " + storageString + ", file in the way"); // NOI18N
if (storageDirectory.exists() && (!storageDirectory.canRead() || !storageDirectory.canWrite()))
throw new IllegalStateException("Cannot access hosts storage directory " + storageString + ", read&write permission required"); // NOI18N
if (!Utils.prepareDirectory(storageDirectory))
throw new IllegalStateException("Cannot create hosts storage directory " + storageString); // NOI18N
}
return storageDirectory;
}
}
/**
* Returns true if the storage directory for defined JMX applications already exists, false otherwise.
*
* @return true if the storage directory for defined JMX applications already exists, false otherwise.
*/
public static boolean storageDirectoryExists() {
return new File(getStorageDirectoryString()).isDirectory();
}
private JmxApplicationsSupport() {
applicationProvider.initialize();
}
}