001package jmri.util.prefs;
002
003import java.io.File;
004import java.util.HashMap;
005import javax.xml.parsers.DocumentBuilderFactory;
006import javax.xml.parsers.ParserConfigurationException;
007import jmri.profile.AuxiliaryConfiguration;
008import jmri.profile.Profile;
009
010/**
011 * Provides a general purpose XML element storage mechanism for the storage of
012 * user interface configuration.
013 * <p>
014 * There are two configuration files per {@link jmri.profile.Profile} and
015 * {@link jmri.util.node.NodeIdentity}, both stored in the directory
016 * <code>profile:profile</code>:
017 * <ul>
018 * <li><code>{@value jmri.profile.Profile#UI_CONFIG}</code> preferences that are
019 * shared across multiple nodes for a single profile. An example of such a
020 * preference would be the Railroad Name preference.</li>
021 * <li><code>&lt;node-identity&gt;/{@value jmri.profile.Profile#UI_CONFIG}</code>
022 * preferences that are specific to the profile running on a specific host
023 * (&lt;node-identity&gt; is the identity returned by
024 * {@link jmri.util.node.NodeIdentity#networkIdentity()}). An example of such a
025 * preference would be a file location.</li>
026 * </ul>
027 * <p>
028 * Non-profile specific configuration that applies to all profiles is stored in
029 * the file
030 * <code>settings:preferences/{@value jmri.profile.Profile#UI_CONFIG}</code>.
031 *
032 * @author Randall Wood 2015, 2016
033 */
034public final class JmriUserInterfaceConfigurationProvider extends AbstractConfigurationProvider {
035
036    private final Configuration configuration;
037
038    static {
039        try {
040            DocumentBuilderFactory.newInstance().newDocumentBuilder();
041        } catch (ParserConfigurationException e) {
042            throw new AssertionError(e);
043        }
044    }
045
046    private static final HashMap<Profile, JmriUserInterfaceConfigurationProvider> PROVIDERS = new HashMap<>();
047
048    /**
049     * Get the JmriPrefererncesProvider for the specified profile.
050     *
051     * @param project The profile. This is most often the profile returned by
052     *                the {@link jmri.profile.ProfileManager#getActiveProfile()}
053     *                method of the ProfileManager returned by
054     *                {@link jmri.profile.ProfileManager#getDefault()}
055     * @return The shared or private JmriPreferencesProvider for the project.
056     */
057    static synchronized JmriUserInterfaceConfigurationProvider findProvider(Profile project) {
058        if (PROVIDERS.get(project) == null) {
059            PROVIDERS.put(project, new JmriUserInterfaceConfigurationProvider(project));
060        }
061        return PROVIDERS.get(project);
062    }
063
064    /**
065     * Get the {@link java.util.prefs.Preferences} for the specified class in
066     * the specified profile.
067     *
068     * @param project The profile. This is most often the profile returned by
069     *                the {@link jmri.profile.ProfileManager#getActiveProfile()}
070     *                method of the ProfileManager returned by
071     *                {@link jmri.profile.ProfileManager#getDefault()}
072     * @return The shared or private AuxiliaryConfiguration for project.
073     */
074    public static AuxiliaryConfiguration getConfiguration(final Profile project) {
075        return findProvider(project).getConfiguration();
076    }
077
078    /**
079     * Get the {@link jmri.profile.AuxiliaryConfiguration}.
080     *
081     * @return The AuxiliaryConfiguration.
082     */
083    @Override
084    protected AuxiliaryConfiguration getConfiguration() {
085        return this.configuration;
086    }
087
088    @Override
089    protected File getConfigurationFile(boolean shared) {
090        if (this.project == null) {
091            return new File(this.getConfigurationDirectory(shared), Profile.UI_CONFIG); // NOI18N
092        } else {
093            return new File(this.getConfigurationDirectory(shared), Profile.UI_CONFIG); // NOI18N
094        }
095    }
096
097    JmriUserInterfaceConfigurationProvider(Profile project) {
098        super(project);
099        this.configuration = new Configuration();
100    }
101
102    private class Configuration extends JmriConfiguration {
103
104        private Configuration() {
105            super();
106        }
107
108        @Override
109        protected File getConfigurationFile(boolean shared) {
110            return JmriUserInterfaceConfigurationProvider.this.getConfigurationFile(shared);
111        }
112
113        @Override
114        protected boolean isSharedBackedUp() {
115            return JmriUserInterfaceConfigurationProvider.this.isSharedBackedUp();
116        }
117
118        @Override
119        protected void setSharedBackedUp(boolean backedUp) {
120            JmriUserInterfaceConfigurationProvider.this.setSharedBackedUp(backedUp);
121        }
122
123        @Override
124        protected boolean isPrivateBackedUp() {
125            return JmriUserInterfaceConfigurationProvider.this.isPrivateBackedUp();
126        }
127
128        @Override
129        protected void setPrivateBackedUp(boolean backedUp) {
130            JmriUserInterfaceConfigurationProvider.this.setPrivateBackedUp(backedUp);
131        }
132
133    }
134}