Hans Muller wrote:
* Requirements
A - A preferences implementation that works correctly in the
applet and web start secure sandboxes.
Desktop applications that run without privileges are desirable. The
preferences backing store for a Web Started application can be
provided by the JNLP persistence service. Applets would require
server-side support, or an applet version of the JNLP persistence
service (Applet support for the JNLP persistence service is planned
for Dolphin, see http://jplan.sfbay/feature/411).
Presently one can't get a Preferences object from the sandbox.
Methods like userNode() check for the "preferences" runtime
permission which is not granted - probably because the Windows
implementation of Preferences use the registry for backing store.
System.setSecurityManager(new sun.applet.AppletSecurity());
java.security.Permission p = new RuntimePermission("preferences");
System.getSecurityManager().checkPermission(p); // FAILS
B - Support for initializing an Application's preferences before any
subcomponent has access.
Presently, all access to preferences is via four static methods,
userNode() and rootNode(), and their fooNodeForPackage() variants. An
application can't initialize preferences for the classes that it
depends on, because those classes can read preferences in their own
static blocks, at class-load time.
C - Support for reading/writing large objects to files
The preferences API doesn't provide a way to save large objects,
MAX_VALUE_LENGTH is 8Kbytes. Eliminating this limit wouldn't
be backward compatible and would interact badly with the existing
backing store implementations. An alternative would be to
provide a pair of Preferences methods like this:
InputStream openResourceInput(String key) throws IOException;
OutputStream openResourceOuptut(String key) throws IOException;
D - Simple support for application defaults
An application should be able to get preferences without specifying a
default value. Providing a default value for each preferences lookup
is tedious, error prone, and (most importantly) it makes revising the
defaults for an entire application painful or impossible.
Similarly: applications should be able to specify default values
for preferences.
Presently the spec says that if null is specified as the default
value then:
If the implementation supports stored defaults and such a default
exists, is accessible, and could be converted to a <type> with
<Type>.parse<Type>, this <type> is returned in preference to the
specified default.
This is close to useless. Applications can't depend on something
that might be part of an implementation and they need a way
to explicitly initialize defaults.
* Proposal
[This is incomplete, but just to get the ball rolling]
Dolphin will include an Application class, see
http://jplan.sfbay/feature/205. This class could provide
access to preferences, e.g. like this:
Application.getInstance().getPreferences()
Desktop apps would define a subclass of Application, and
boilerplate for an app's main method might look like this:
public static void main(String[] args) {
Application.launch(MyApplication.class);
}
The Application class could create a Preferences object
by specifying a PreferencesFactory, e.g. like this:
new Preferences(applicationPreferencesFactory);
Application subclasses could override this, but they probably
wouldn't bother.
To initialize defaults, application subclasses could override
getPreferences(), or we could provide an explicit initialization call
to do so.
Finally - add the methods for file storage per item C.
* Problems with the proposal
- static blocks in classes that MyApplication.class depend on
could load preferences, before the app had had a chance to
intitialize defaults. Could disallow this: throw an exception
if defaults are accessed too early.
- Only supports defining fine-grained defaults. Would like
to be able to write:
appPreferences.put("backgroundColor", Color.white);
and then find it via:
appPreferences.get("/foo/bar/backgroundColor");
Assuming that no other backgroundColor preference had been
defined. But beware: lookup scheme complexity seems
to inevitably grow out of proportion to its value.
- How would the Preferences object returned by Application.getInstance().getPreferences() relate to the
one returned by the existing static entry points?
* Requirements
A - A preferences implementation that works correctly in the
applet and web start secure sandboxes.
Desktop applications that run without privileges are desirable. The
preferences backing store for a Web Started application can be
provided by the JNLP persistence service. Applets would require
server-side support, or an applet version of the JNLP persistence
service (Applet support for the JNLP persistence service is planned
for Dolphin, see http://jplan.sfbay/feature/411).
Presently one can't get a Preferences object from the sandbox.
Methods like userNode() check for the "preferences" runtime
permission which is not granted - probably because the Windows
implementation of Preferences use the registry for backing store.
System.setSecurityManager(new sun.applet.AppletSecurity());
java.security.Permission p = new RuntimePermission("preferences");
System.getSecurityManager().checkPermission(p); // FAILS
B - Support for initializing an Application's preferences before any
subcomponent has access.
Presently, all access to preferences is via four static methods,
userNode() and rootNode(), and their fooNodeForPackage() variants. An
application can't initialize preferences for the classes that it
depends on, because those classes can read preferences in their own
static blocks, at class-load time.
C - Support for reading/writing large objects to files
The preferences API doesn't provide a way to save large objects,
MAX_VALUE_LENGTH is 8Kbytes. Eliminating this limit wouldn't
be backward compatible and would interact badly with the existing
backing store implementations. An alternative would be to
provide a pair of Preferences methods like this:
InputStream openResourceInput(String key) throws IOException;
OutputStream openResourceOuptut(String key) throws IOException;
D - Simple support for application defaults
An application should be able to get preferences without specifying a
default value. Providing a default value for each preferences lookup
is tedious, error prone, and (most importantly) it makes revising the
defaults for an entire application painful or impossible.
Similarly: applications should be able to specify default values
for preferences.
Presently the spec says that if null is specified as the default
value then:
If the implementation supports stored defaults and such a default
exists, is accessible, and could be converted to a <type> with
<Type>.parse<Type>, this <type> is returned in preference to the
specified default.
This is close to useless. Applications can't depend on something
that might be part of an implementation and they need a way
to explicitly initialize defaults.
* Proposal
[This is incomplete, but just to get the ball rolling]
Dolphin will include an Application class, see
http://jplan.sfbay/feature/205. This class could provide
access to preferences, e.g. like this:
Application.getInstance().getPreferences()
Desktop apps would define a subclass of Application, and
boilerplate for an app's main method might look like this:
public static void main(String[] args) {
Application.launch(MyApplication.class);
}
The Application class could create a Preferences object
by specifying a PreferencesFactory, e.g. like this:
new Preferences(applicationPreferencesFactory);
Application subclasses could override this, but they probably
wouldn't bother.
To initialize defaults, application subclasses could override
getPreferences(), or we could provide an explicit initialization call
to do so.
Finally - add the methods for file storage per item C.
* Problems with the proposal
- static blocks in classes that MyApplication.class depend on
could load preferences, before the app had had a chance to
intitialize defaults. Could disallow this: throw an exception
if defaults are accessed too early.
- Only supports defining fine-grained defaults. Would like
to be able to write:
appPreferences.put("backgroundColor", Color.white);
and then find it via:
appPreferences.get("/foo/bar/backgroundColor");
Assuming that no other backgroundColor preference had been
defined. But beware: lookup scheme complexity seems
to inevitably grow out of proportion to its value.
- How would the Preferences object returned by Application.getInstance().getPreferences() relate to the
one returned by the existing static entry points?