Preference Settings Framework
The Preference Settings Framework provides support for easy processing of preference settings from the .ini file. The framework identifies the valid values for each preference setting and supplies a default value if the preference setting is not included in the .ini file. Preference settings are associated with applications and the most common way to code settings in the .ini file is to put them in a stanza named the same as the application they apply to. However, settings in arbitrarily named stanzas and in multiple stanzas are also supported.
When the image is started, the settings for all currently loaded applications are read from the .ini file, collected together, and stored in an EmSystemConfiguration instance variable. As new applications are loaded (or already loaded application reloaded), their settings are read and added to the collection. When an application is unloaded, its settings are removed from the collection. You can access the current collection of settings using System settings.
Settings Framework API
The API for the Preference Settings Framework consists of extension methods on the Application class, a new EmRange class, and extensions on a few other classes to facilitate creation of EmRange instances.
Some of the Application class methods are delegated to subclasses, which mean that you must implement them to make use of the settings framework; some are modifiable, which means you may implement them in your application class to change the default behavior; and some are provided for the application to use in processing the settings. Tto use the settings framework for an application, only the 3 modifiable and delegated methods need to be implemented.
Application Public Class Methods (modifiable)
validSettings
Answer a keyed collection of settings information identifying stanzas, and keywords within those stanzas, that are valid for the receiver. This method must be overridden by applications that want to use settings from the settings file; otherwise no settings will be read from the file for that application.
The keys of the answered collection are the names of stanzas containing settings for the application and the values are themselves keyed collections with keys being the setting keywords and the values being element types describing the type and/or range of the value that can appear in the file for the specified key. The element type can be:
• an Atom (obtained by calling one of the xxxType methods on self)
• an EmRange
• a single-element Array containing either an Atom or an EmRange describing an unbounded array of values that are all of the same element type
• a multiple-element Array containing Atoms and/or EmRanges describing a bounded (by the number of element types specified) array of values that correspond positionally with the specified element types
The default behavior is to answer an empty keyed collection, which means that no preference settings will be read from the file for the application.
Application Public Class Methods (delegated)
currentSettings
Answer a keyed collection of settings information for the application.
The keys of the answered collection are the names of stanzas containing settings for the application and the values are themselves keyed collections with keys being the setting keywords and the values being two element arrays of current values and default values for the settings. The value for the default setting should be of the same type as specified in the corresponding validSettings method.
setCurrentSettings
Set the setting values used by this application.
This method retrieves setting values that were specified in the .ini file and sets those values into their expected locations (generally class variables of the receiver or another class controlled by the receiver).
Applications should specify
System imageStarted ifTrue: [ self setCurrentSettings ].
in their #loaded method and
self setCurrentSettings
in their #startUp method so that the settings are initialized after an application has been loaded into a running image from the code repository and at image startup time.
Application Public Class Methods
booleanType
Answer an Atom identifying the valid setting value as a Boolean
decimalType
Answer an Atom identifying the valid setting value as a ScaledDecimal
directoryType
Answer an Atom identifying the valid setting value as a String representing a directory path name (with a trailing path separator character)
fileType
Answer an Atom identifying the valid setting value as a String representing an absolute or relative filename
fractionType
Answer an Atom identifying the valid setting value as a Fraction
integerType
Answer an Atom identifying the valid setting value as an Integer
multiLineStringType
Answer an Atom identifying the valid setting value as a String which may contain line-end characters (\)
numberType
Answer an Atom identifying the valid setting value as a Fraction, Integer, or ScaledDecimal
pointType
Answer an Atom identifying the valid setting value as a Point
positiveInteger
Answer an Atom identifying the valid setting value as a positive Integer
stringType
Answer an Atom identifying the valid setting value as a String
settingFor: aKey
Answer the value associated with @aKey in the default stanza for the receiver in the .ini file.
If no value was provided, answer the default value.
settingFor: aKey in: aStanza
Answer the value associated with @aKey from the stanza named @aStanzaName in the .ini file.
If the stanza was not provided, answer nil. If no value was provided, answer the default value."
Number, subclass of Number, and Point Public Class Methods
exclusiveInclusiveTo: @last elementType: @anAtom
Answer a new instance of EmRange that goes from self to @last and includes @last in the range but does not include self. Set the element type to @anAtom which specifies the legal types of values within the range. @anAtom can be one of ##decimalType, ##integerType, ##fractionType, ##pointType, or ##numberType (indicating that any of a decimal, fraction, or integer are valid setting elements).
exclusiveTo:elementType:
Answer a new instance of EmRange that goes from self to @last and excludes both self and @last from the range. Set the element type to @anAtom which specifies the legal types of values within the range. @anAtom can be one of ##decimalType, ##integerType, ##fractionType, ##pointType, or ##numberType (indicating that any of a decimal, fraction, or integer are valid setting elements).
inclusiveExclusiveTo:elementType:
Answer a new instance of EmRange that goes from self to @last and includes self in the range but does not include @last. Set the element type to @anAtom which specifies the legal types of values within the range. @anAtom can be one of ##decimalType, ##integerType, ##fractionType, ##pointType, or ##numberType (indicating that any of a decimal, fraction, or integer are valid setting elements).
inclusiveTo:elementType:
Answer a new instance of EmRange that goes from self to @last and includes both self and @last in the range. Set the element type to @anAtom which specifies the legal types of values within the range. @anAtom can be one of ##decimalType, ##integerType, ##fractionType, ##pointType, or ##numberType (indicating that any of a decimal, fraction, or integer are valid setting elements).
Examples
Here are some examples of using these API methods to specify the processing of settings from the .INI file:
A validSettings method specifying the value types for settings from 2 stanzas (showing the use of a simple specification and an EmRange specification)
validSettings
^ LookupTable new
at: self symbol asString
put: (LookupTable with: 'fplevel' ->(0 inclusiveTo: 9 elementType: self integerType));
at: 'VAST 5.0 Compatibility'
put: (LookupTable with: 'installPath' -> self directoryType);
yourself
A validSettings method specifying the valueType for settings from one stanza showing the use of an Array specification with a single elementType. This specifies that bitmapPath will accept any number of directoryType values.
validSettings
^ LookupTable new
at: self symbol asString
put: (LookupTable with: 'bitmapPath' -> (Array with: self directoryType));
yourself
A validSettings method specifying the valueType for settings from one stanza showing the use of an Array specification with multiple elementTypes. This specifies that fooBar will accept exactly 3 values: 2 numberTypes and a stringType.
validSettings
^ LookupTable new
at: self symbol asString
put: (LookupTable with: 'fooBar' -> (Array with: self numberType with: self numberType with: self stringType));
yourself
A currentSettings method specifying information about settings from 2 stanzas
currentSettings
^ LookupTable new
at: self symbol asString
put: (LookupTable with: 'fplevel' -> (Array with: AbtFeatureLoader fixpackLevel with: 0));
at: 'VAST 5.0 Compatibility' put: (LookupTable with: 'installPath' -> (Array with: AbtFeatureLoader featureDirectory with: ('..%1feature%1' bindWith: CfsDirectoryDescriptor pathSeparatorString)));
yourself
A setCurrentSettings method showing how setting values are processed
setCurrentSettings
| addr |
addr := self settingFor: 'ServerAddress'.
addr isEmpty ifTrue: [ addr := nil ].
EmLibrary
defaultName: (self settingFor: 'DefaultName');
serverAddress: addr;
openReadOnly: (self settingFor: 'OpenReadOnly')
You can find additional examples to study by browsing for implementors of these 3 methods.