/* * 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 java.util.HashMap; import java.util.Map; import javax.management.remote.JMXConnector; /** * EnvironmentProvider adding the JMXConnector.CREDENTIALS property to the JMX * environment map. * * There are two subclasses of EnvironmentProvider available, typically you want * to use the EnvironmentProvider.Custom class to provide a custom credentials * for a JMX connection. The EnvironmentProvider.Persistent class is used for * handling credentials for persisted connections. * * Note that if the credentials provided by this provider are incorrect a dialog * requesting new credentials will be displayed by the framework. If the * user-provided credentials are correct they will override the credentials * defined by this provider. The user-provided credentials are never persisted. * * @since VisualVM 1.2 * @author Jiri Sedlacek */ public abstract class CredentialsProvider extends EnvironmentProvider { private static final String PROPERTY_USERNAME = "prop_credentials_username"; // NOI18N private static final String PROPERTY_PASSWORD = "prop_credentials_password"; // NOI18N private static Persistent PERSISTENT_PROVIDER; static synchronized Persistent persistent() { if (PERSISTENT_PROVIDER == null) PERSISTENT_PROVIDER = new Persistent(); return PERSISTENT_PROVIDER; } /** * Returns an unique String identifying the CredentialsProvider. Must be * overridden to return a different identificator when subclassing the * CredentialsProvider. * * @return unique String identifying the CredentialsProvider */ public String getId() { return CredentialsProvider.class.getName(); } abstract String getUsername(Storage storage); abstract boolean hasPassword(Storage storage); abstract boolean isPersistent(Storage storage); /** * CredentialsProvider to provide custom settings. * * @since VisualVM 1.2 * @author Jiri Sedlacek */ public static class Custom extends CredentialsProvider { private final String username; private final char[] password; private final boolean persistent; /** * Creates new instance of CredentialsProvider.Custom. * * @param username username * @param password password * @param persistent true if the credentials should be persisted for another VisualVM sessions, false otherwise */ public Custom(String username, char[] password, boolean persistent) { this.username = username; this.password = encodePassword(password); this.persistent = persistent; } public Map<String, ?> getEnvironment(Application application, Storage storage) { return createMap(username, password != null ? new String(password) : null); } public String getEnvironmentId(Storage storage) { if (username != null) return username; return super.getEnvironmentId(storage); } public void saveEnvironment(Storage storage) { if (!persistent) return; storage.setCustomProperty(PROPERTY_USERNAME, username); storage.setCustomProperty(PROPERTY_PASSWORD, new String(password)); } String getUsername(Storage storage) { return username; } boolean hasPassword(Storage storage) { return password != null && password.length > 0; } boolean isPersistent(Storage storage) { return persistent; } } /** * CredentialsProvider to provide custom settings. * * @since VisualVM 1.2 * @author Jiri Sedlacek */ public static class Persistent extends CredentialsProvider { public Map<String, ?> getEnvironment(Application application, Storage storage) { String username = storage.getCustomProperty(PROPERTY_USERNAME); String password = storage.getCustomProperty(PROPERTY_PASSWORD); return createMap(username, password); } public String getEnvironmentId(Storage storage) { if (storage != null) { String username = storage.getCustomProperty(PROPERTY_USERNAME); if (username != null) return username; } return super.getEnvironmentId(storage); } String getUsername(Storage storage) { return storage.getCustomProperty( PROPERTY_USERNAME); } boolean hasPassword(Storage storage) { String password = storage.getCustomProperty(PROPERTY_PASSWORD); return password != null && password.length() > 0; } boolean isPersistent(Storage storage) { return getUsername(storage) != null || hasPassword(storage); } } // --- Private implementation ---------------------------------------------- private static Map<String, ?> createMap(String username, String password) { Map map = new HashMap(); if (username != null && !username.isEmpty()) map.put(JMXConnector.CREDENTIALS, new String[] { username, decodePassword(password) }); return map; } private static char[] encodePassword(char[] password) { if (password == null) return null; return Utils.encodePassword(new String(password)).toCharArray(); } private static String decodePassword(String password) { if (password == null) return null; return Utils.decodePassword(password); } }