001package jmri.spi; 002 003import java.util.Collection; 004import java.util.List; 005import javax.annotation.Nonnull; 006import jmri.profile.Profile; 007import jmri.util.prefs.InitializationException; 008 009/** 010 * An API for Java Service Providers that manage preferences within JMRI. It is 011 * strongly recommended that PreferencesManagers use 012 * {@link jmri.util.prefs.JmriConfigurationProvider} or 013 * {@link jmri.util.prefs.JmriPreferencesProvider} to store preferences. 014 * <p> 015 * PreferencesManagers must provide a default public constructor, but must also 016 * not perform any initialization until 017 * {@link #initialize(jmri.profile.Profile)} is called as the PreferencesManager 018 * may be constructed before the {@link jmri.profile.Profile} is known. 019 * <p> 020 * {@link jmri.util.prefs.AbstractPreferencesManager} provides an abstract 021 * implementation that is ready to extend. 022 * 023 * @see jmri.util.prefs.AbstractPreferencesManager 024 * @author Randall Wood 2015, 2019 025 */ 026public interface PreferencesManager extends JmriServiceProviderInterface { 027 028 /** 029 * Initialize the PreferencesManager with preferences associated with the 030 * provided Profile. 031 * <p> 032 * Implementing classes should throw an InitializationException with a user 033 * readable localized message, since it most likely be displayed to the 034 * user. Implementing classes will still want to ensure that 035 * {@link #isInitialized(jmri.profile.Profile)} or 036 * {@link #isInitializedWithExceptions(jmri.profile.Profile)} return true if 037 * throwing an InitializationException to ensure that the provider is not 038 * repeatedly initialized. 039 * 040 * @param profile the configuration profile used for this initialization; 041 * may be null to initialize for this user regardless of 042 * profile 043 * @throws InitializationException if the user needs to be notified of an 044 * issue that prevents regular use of the 045 * application 046 */ 047 void initialize(Profile profile) throws InitializationException; 048 049 /** 050 * Test if the PreferencesManager is initialized without errors for the 051 * provided Profile. Note that although both this method and 052 * {@link #isInitializedWithExceptions(jmri.profile.Profile)} can be false, 053 * if isInitializedWithExceptions(Profile) returns true, this method must 054 * return false. 055 * 056 * @param profile the configuration profile to test against; may be null to 057 * test for exceptions thrown when initializing for this user 058 * regardless of profile 059 * @return true if the provider is initialized without exceptions 060 */ 061 boolean isInitialized(Profile profile); 062 063 /** 064 * Test if the PreferencesManager is initialized, but threw an 065 * {@link InitializationException} during initialization, for the provided 066 * Profile. Note that although both this method and 067 * {@link #isInitialized(jmri.profile.Profile)} can be false, if 068 * isInitialized(Profile) returns true, this method must return false. 069 * 070 * @param profile the configuration profile to test against; may be null to 071 * test for exceptions thrown when initializing for this user 072 * regardless of profile 073 * @return true if the provide is initialized with exceptions 074 */ 075 boolean isInitializedWithExceptions(Profile profile); 076 077 /** 078 * Get the set of exceptions thrown during initialization for the provided 079 * Profile. 080 * 081 * @param profile the configuration profile to test against; may be null to 082 * test for exceptions thrown when initializing for this user 083 * regardless of profile 084 * @return A list of exceptions. If there are no exceptions, return an empty 085 * set instead of null. 086 */ 087 @Nonnull 088 List<Exception> getInitializationExceptions(Profile profile); 089 090 /** 091 * Get the set of PreferencesManagers that must be initialized prior to 092 * initializing this PreferencesManager. It is generally preferable to 093 * require an Interface or an abstract Class instead of a concrete Class, 094 * since that allows all (or any) concrete implementations of the required 095 * class to be initialized to provide required services for the requiring 096 * PreferencesManager instance. 097 * <p> 098 * Note that for any set of PreferencesManagers with the same requirements, 099 * or with a circular dependency between each other, the order in which the 100 * PreferencesManagers in that set are initialized should be considered 101 * non-deterministic. 102 * 103 * @return A set or list of classes. If there are no dependencies, return an 104 * empty set instead of null. 105 */ 106 @Nonnull 107 Collection<Class<? extends PreferencesManager>> getRequires(); 108 109 /** 110 * Get the set of Classes that this PreferencesManager can be registered as 111 * a provider of in the {@link jmri.InstanceManager}. 112 * 113 * @return A set or list of classes. If this PreferencesManager provides an 114 * instance of no other Interfaces or abstract Classes than 115 * PreferencesManager, return an empty set instead of null. 116 */ 117 @Nonnull 118 Iterable<Class<?>> getProvides(); 119 120 /** 121 * Save the preferences that this provider manages for the provided Profile. 122 * 123 * @param profile the profile associated with the preferences to save; may 124 * be null to save preferences that apply to the current user 125 * regardless of profile 126 */ 127 void savePreferences(Profile profile); 128 129}