/* * 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.core.properties; import com.sun.tools.visualvm.core.datasource.DataSource; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * Entrypoint for customization of DataSource properties. PropertiesProvider * instances should be registered/unregistered using the registerPropertiesProvider * and unregisterPropertiesProvider methods. * * DataSource providers displaying a dialog supporting user-customizable properties * should use getCustomizer(Class) method to get the properties UI. * * @since VisualVM 1.2 * @author Jiri Sedlacek */ public final class PropertiesSupport { private static PropertiesSupport INSTANCE; private final Map<PropertiesProvider, Class<? extends DataSource>> providers = Collections.synchronizedMap(new HashMap()); /** * Returns singleton instance of PropertiesSupport. * * @return singleton instance of PropertiesSupport */ public static synchronized PropertiesSupport sharedInstance() { if (INSTANCE == null) INSTANCE = new PropertiesSupport(); return INSTANCE; } /** * Registers a PropertiesProvider for a concrete DataSource type. * * @param <X> any DataSource type * @param provider PropertiesProvider to be registered * @param scope type of DataSource supported by the PropertiesProvider */ public <X extends DataSource> void registerPropertiesProvider( PropertiesProvider<X> provider, Class<X> scope) { providers.put(provider, scope); } /** * Unregisters the PropertiesProvider. * * @param <X> any DataSource type * @param provider PropertiesProvider to unregister */ public <X extends DataSource> void unregisterPropertiesProvider( PropertiesProvider<X> provider) { providers.remove(provider); } /** * Returns true if there's at least one PropertiesProvider providing properties * for the DataSource type, false otherwise. * * @param <X> any DataSource type * @param type type of the DataSource to be checked * @return true if there's at least one PropertiesProvider providing properties for the DataSource type, false otherwise */ public <X extends DataSource> boolean hasProperties(Class<X> type) { return hasProperties(null, type); } /** * Returns true if there's at least one PropertiesProvider providing properties * for the DataSource, false otherwise. * * @param <X> any DataSource type * @param dataSource DataSource to be checked * @return true if there's at least one PropertiesProvider providing properties for the DataSource, false otherwise */ public <X extends DataSource> boolean hasProperties(X dataSource) { if (dataSource == null) throw new IllegalArgumentException("DataSource cannot be null"); // NOI18N return hasProperties(dataSource, (Class<X>)dataSource.getClass()); } /** * Returns an UI component to display user-customizable properties for the * provided DataSource type. Use hasProperties(Class) method to check if there * are any customizable properties for the given DataSource type. For no * properties available the created PropertiesCustomizer is empty. * * @param <X> any DataSource type * @param type type of the DataSource to customize * @return UI component to display user-customizable properties for the provided DataSource type */ public <X extends DataSource> PropertiesCustomizer<X> getCustomizer(Class<X> type) { return getCustomizer(null, type); } /** * Opens Properites window of the DataSource. The first category is selected. * * @param dataSource DataSource for which to open the Properties window */ public void openProperties(DataSource dataSource) { openProperties(dataSource, PropertiesProvider.CATEGORY_GENERAL); } /** * Opens Properites window of the DataSource and selects the provided category * if available. * * @param dataSource DataSource for which to open the Properties window */ public void openProperties(DataSource dataSource, int propertiesCategory) { if (dataSource == null) throw new IllegalArgumentException("DataSource cannot be null"); // NOI18N PropertiesConfigurator.editProperties(dataSource, propertiesCategory); } <X extends DataSource> PropertiesCustomizer<X> getCustomizer(X dataSource, Class<X> type) { return new PropertiesCustomizer(dataSource, type); } <X extends DataSource> List<PropertiesProvider<X>> getProviders(X dataSource, Class<X> type) { Map<PropertiesProvider, Class<? extends DataSource>> providersCopy = new HashMap(); synchronized(providers) { providersCopy.putAll(providers); } if (dataSource != null) type = (Class<X>)dataSource.getClass(); List<PropertiesProvider<X>> compatibleProviders = new ArrayList(); Set<Map.Entry<PropertiesProvider,Class<? extends DataSource>>> providersSet = providersCopy.entrySet(); for (Map.Entry<PropertiesProvider,Class<? extends DataSource>> entry : providersSet) { PropertiesProvider provider = entry.getKey(); if (entry.getValue().isAssignableFrom(type) && provider.supportsDataSource(dataSource)) compatibleProviders.add(provider); } return compatibleProviders; } private <X extends DataSource> boolean hasProperties(X dataSource, Class<X> type) { return !getProviders(dataSource, type).isEmpty(); } private PropertiesSupport() {} }