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