Closed CrazyKidJack closed 8 months ago
Note, this PR now contains a small change to the Preferences
class. Namely,
reregister()
functionunregister()
only delete the data from persistence... not from memoryThanks for the PR, great suggestion and implementation. Mind if I use your description from this for the readme?
Thanks for the PR, great suggestion and implementation. Mind if I use your description from this for the readme?
Yes feel free!
Overview
This would add 6 convenience classes to the library which would allow users to easily create auto-persisting objects / containers.
Note that modifications made to the contents of the containers via direct references to those contents (for example a reference to an element of a PersistedList) cannot be automatically persisted because the container has no way to know what you are doing with that reference. Therefore, modifications made in this manner require either explicit calls to the
PersistedContainer::save()
method or custom implementations of the element types that either do the saving or notify the PersistedContainer of the changes.Related PR: I believe this PR would no longer be necessary if THIS PR gets approved.
PersistedContainer
This is the abstract parent of all auto-persisting things. It encapsulates the creation of the
Preferences
as well as provides a publicsave()
function to persist the current state of the container.Persisted Collections and PersistedMap
These classes are designed to have an api that is as compliant with the Java Collections Framework as possible. These classes allow users to create collections that work like any other collection, but that automatically persist themselves using the
Preferences
class.These classes allow user's to have auto-persisting things, without have to do any custom implementation of any kind (though of course they could if they wanted to). These classes implement standard Java Collections Framework interfaces but are really only proxies for pre-existing implementations. This means that these classes must be given an instance of some other implementation as the proxy target and any methods provided only by that particular implementation will not be available for auto-persistence without creating custom extensions of these classes (which should not actually be too difficult if one wanted).
Some notable departures from the Java Collections Framework API is that these classes:
Preferences
to persist those modifications.PersistedObject
Abstract base class that allows users to easily create custom objects that are auto-persisted. Extending this class is the preferred method to auto-persist data. But it also requires the most effort (which is why the other classes exist).
As the purpose of this class is to allow easy auto-persistence of CUSTOM classes, some (a very small part) of the implementation is left to the user. For example:
Preferences:register()
method.PersistedCollection
andPersistedMap
classes.clone()
instance method that creates a copy of the initial (default) state of the object (conceptually I think I actually like this best... but if your auto-persisted custom object contains other objects, then the user would have to handle the cloning all the way down the tree and thatclone
method would have to change any time any part of the tree changed unless reflection is used. This could be partially mitigated by constituents implementing their ownclone()
method... but it will never be perfect)_prefs
reset()
methods.PersistedObject
provides areset()
proxy method that resets thePreferences
instance... butPersistedObject
cannot (without reflection) know what fields then need to be retrieved from the reset_prefs
.register()
. This allows them to set custom default values by passing them in as arguments... However, that was actually an artifact of an earlier version in which I was trying to use the object's default state itself as the default value (which doesn't work becausePreferences
stores a reference to the default object, not a copy) and now I'm not sure it is actually useful any more (because I'm requiring the no-arg constructor to be defined and using it to get the default value). Therefore, it may be better to actually remove this requirement with a slight modification of thePersistedObject
class.Example Usage
A sample Burp Extension that uses these features can be found here.
Please note that it also uses some other features for which I have submitted PRs / issues but that may not yet have been pulled into this repo. A working version of a fork of this repo with all of features used by the sample extension can be found here (tag 1.1.0-beta.0.1.0).
If you trust them, I have created releases with jars that you can load and run to save you the trouble of building: