-
Notifications
You must be signed in to change notification settings - Fork 69
Internal Workings of the Anathema Repository
Written by @curttasker for anathema/anathema#192
I spent some quality time trying to understand our preferences system, mainly how we go about handling the default repository preference.
Since this sort of thing helps me understand code like this, I'm just going to do a brain dump of what I've found, and hopefully this is all mostly correct, and can help someone dealing with the preference system it in the future.
AnathemaPreferences
- Singleton, constructed in
Anathema
, storesPreferences.userRoot().node(SYSTEM_PREFERENCES_NODE))
locally as itsjava.util.prefs.Preferences
data store. -
getRepositoryLocationPreferences(defaultLocation)
callsPreferences.get( REPOSITORY_PREFERENCE, DEFAULT_REPOSITORY_LOCATION)
This will return the Preferences value for the key REPOSITORY_REFERENCE, but if this value does not exist, returns the literal value of DEFAULT_REPOSITORY_LOCATION
RepositoryLocationResolver
- Constructed with an
IAnathemaPreferences
object, stores it privately. -
resolve()
looks forSystem.getProperty("repository")
, and returns its value. This is the linux shell script override for changing your repository at the command line. - If the above property is not found, it calls
AnathemaPreferences.getRepositoryLocationPreferences()
with the argument ofSystem.getProperty("defaultrepository") )
.AnathemaPreferences.getRepositoryLocationPreferences()
then returns either the user's custom chosen repository, or the value ofSystem.getProperty("defaultrepository")
. If the user has no custom repository folder, and the "defaultrepository" property is not set, then it defaults to./repository/
. -
resolve()
looks like it attempts to strip out the user's home folder from the path of the repository.LeadingPropertyResolver
is being created to parse"%USER_HOME%", "user.home"
. I'm very confused as to what this achieves. -
resolve()
is used byRepositoryFolderCreator
andDefaultAnathemaReflections
only. update Figured this one out. It only happens when I build a full mac application and run, not during testing. Java prepends some garbage onto the path that needs to be stripped off.
RepositoryPreferencesElement
- Displays the preferences elements from the window shown above.
- Uses
SYSTEM_PREFERENCES.get(REPOSITORY_PREFERENCE, DEFAULT_REPOSITORY_LOCATION))
to load the repository directory. This will return the Preferences value for the key REPOSITORY_PREFERENCE, but if this value does not exist, returns the literal value of DEFAULT_REPOSITORY_LOCATION. -
savePreferences()
Saves the repository's location to Preferences, using the key REPOSITORY_PREFERENCE. If the user's selected repository location equals the system default location, then remove the key REPOSITORY_PREFERENCE from Preferences. - Thus, in absence of any user selected repository locaiton, this class always assumes the default repository location of DEFAULT_REPOSITORY_LOCATION, which is "./repository".
There are many more PreferencesElements that all use SYSTEM_PREFERENCES.get(KEY_HERE)
method to get (and set) their preferences.
RepositoryFolderCreator
- Called by
AnathemaModelInitializer
&RepositoryPreferencesElement.isValid()
- Uses
RepositoryLocationResolver
to find the repository folder - Creates, the repository folder, if it does not exist, and returns a
File
reference to the current repository folder.
AnathemaModelInitializer
- Uses
RepositoryFolderCreator
to get aFile
reference to the repository folder. - Passes this repository reference into AnathemaModel, and from there its used downstream by most of the application (
GsonEquipmentDatabse
, for example), to find the location of the Repository.
DefaultAnathemaReflections
- Uses
RepositoryLocationResolver
to find the location of the repository, and adds the repository location to the classpath list it uses.
RepositoryPreferenceUpdater
- Rips the key/value pair for OLD_REPOSITORY_PREFERENCE out Properties, and re-stores the value under the key REPOSITORY_PREFERENCE.
- It looks like this deletes the Preferences key for the old repository entirely. So I'm not sure how this "allows users to run current versions of Anathema in parallel with 3.1.x versions" as is stated in the class's comment. It looks like once you run 4.0.0, your preferences are moved to the new format for life.
AnathemaPreferencesAction
-
execute()
Called when someone changes a preference in the preferences menu. It goes through every preference in the menu, checks to see if it has been changed (isDirty()
), and if so, calls that preference class'savePreferences()
method. In this case, it will callRepositoryPreferencesElement.savePreferences()
-
execute()
brings up the "Please restart Anathema" dialog when you change a preference.
Constants Referenced
IAnathemaPreferencesConstants.REPOSITORY_PREFERENCE = "RepositoryForAnathema4orHigher"; IAnathemaPreferencesConstants.DIRECTORY_CHOOSER_NODE = "DirectoryChooser"; IAnathemaPreferencesConstants.DEFAULT_REPOSITORY_LOCATION = "./repository/"; IAnathemaPreferencesConstants.SYSTEM_PREFERENCES_NODE = "anathema/system"; IPreferencesElement.SYSTEM_PREFERENCES = Preferences.userRoot().node(SYSTEM_PREFERENCES_NODE); RepositoryPreferencesElement.REPOSITORY_PREFERENCE_DIRECTORY_CHOOSER_VALUE = "RepositoryPreference"; RepositoryPreferenceUpdater.OLD_REPOSITORY_PREFERENCE = "Repository";
-
The Mac client uses the
System.getProperty("defaultrepository")
property to set the default repository location. -
The Linux shell script launcher uses the
System.getProperty("repository")
property to set the default repository location. -
The Windows Installer (for both all users and just you) uses a hardcoded
./repository
folder off of the installed root of the application. -
Rulling the application as a jar file on any OS uses a hardcoded
./repository
folder off of the anathema.jar file location. -
Java Preferences - The implementation of the actual storage for Preferences depends on the platform, and OS version.
-
Mac OS X 10.7.3 stores them in a file called
~/Library/Preferences/com.apple.java.util.prefs.plist
. -
Windows 7 stores the preferences in the registry under
HKEY_CURRENT_USER\Software\JavaSoft\Prefs\
-
Mac OS X 10.7.3 stores them in a file called
So the system is largely based around hardcoded ./repository
folders rooted at the location of the Anathema executable. The system can be overridden using System properties, with defaultrepository
and repository
both working, though in different ways. The value of the key defaultrepository
is only used as the repository location if the user has not selected a custom repository location (which would be now stored in the Preferences bundle). The repository
key is a master override, and setting a value for this key will force anathema to ignore any custom repository location in favor of the value of the key.
There doesn't seem to be any single point of entry for systems wishing to know where the repository is located, at the moment. We have RepositoryPreferencesElement
(among others) checking directly against the Preferences bundle, and we have the AnathemaModelInitializer
using RepositoryLocationResolver
to grab the location from the System Properties, rather than the Preferences.
Intent:
It looks like the intention was to use the two System Properties keys, "repository" and "defaultrepository" to allow overriding the user selected repository, and setting the default repository location, respectively. Unfortunately, these properties are only used in the linux shell script and mac app file, respectively. Everywhere else the system just assumes a ./repository
folder. When referenced in code, the constant DEFAULT_REPOSITORY_LOCATION (shown above) is used. The ./repository
value is hardcoded into the windows installer in anathema.nsi
The actual Preferences bundle works well, though there is a little confusion over how to access the repository folder. We have RepositoryPreferencesElement
duplicating some of the RepositoryLocationResolver
code, and directly accessing the Properties bundle to retrieve the repository location.
Basics
Contributors' Quickstart
Developing Anathema with Eclipse
Some notes on translations
How to release a new version
Technical Stuff
How to compile NSIS for POSIX systems
Internal Workings of the Repository
How to update the JRE
How to start a new update train
Specifics
How to add new Character Sheets