It is very common for programs developed for the Unix platform to have its own configuration file. These configuration files are often called .XXXrc (e.g., .cambarc) and stored in the user's home directory. Furthermore, as more and more programs are ported from Unix to Windows, we are seeing an increase use of these configuration files on Windows platform. For ease of reference, in this article, these configuration files are referred to as RCFile. Any self-respecting User Interface program, like GenericFX, cannot afford to ignore these files and will try to integrate them into the User Interface. This article outline the strategy used in GenericFX to integrate these files. We used CamBAfx as an example, but the same principle applies to all programs. It is also important to note that alternative strategies can be developed and coexists side-by-side with this strategy.
Background
With CamBA, the authors define a .cambarc file to be placed in the user's home directory. This file contains user preferences for parameters used by CamBA programs. It is desirable to read the value in .cambarc and integrate it into the pipeline interface.
Strategy For Integration
It is decided that when users hit File->New... menu, the .cambarc file will be read and its value integrated into the Input Data Spreadsheet and pipeline. From that point on, the Input Data Spreadsheet and the pipeline itself will not be affected by changes in the .cambarc file. The last statement is important. It is there to ensure that the user always know what values is assigned to the pipeline when it is run. The scenario we are guarding against is the possibility that these values changes halfway through a batch processing job because the user changes the .cambarc file.
What this actually means...
- [Programmer] Everything inside .cambarc file must be settable from the command line. For example, .cambarc define the value FWHM (Full Width Half Maximum) value which defines the width of the smoothing kernel for program spatsmooth. The program spatsmooth, however, has a option switch -g which will is used to set the the kernel size explicitly. This requirement is necessary to allow CamBAfx to overwirte the value of FWHM in .cambarc.
- When the Input Data Spreadsheet is created, CamBAfx must reach out and interpret and adopt its values. At all other time, the .cambarc file will not be read.
- When writing the script files to execute the batch processing, CamBAfx will use the command line options, e.g. the -g switch above, to set the values explicitly. This ensures that the exact batch processing is repeated everytime the user relaunch the batch processing and create an accountability trail where the user can always find out what values are used in the batch processing.
In addition, CamBAfx will provide a way to modify the .cambarc file.
How CambaFX (GenericFX) Actually Understands The RCFiles
The solution is delivered in two parts:
- How to represent the instructions to read from RCFile in the pipeline file, i.e., the .epl file, and,
- How CambaFX interpret the instructions in the pipeline file.
Representing the instructions in the pipeline file
The pipeline file is written in XML. This article is not going to explain the detail of the file format. Suffice to say that the natural location to put the instruction is inside the
GFXData element, since this element identify the type of data. Moreover, because this strategy calls for the RCFile to be used as a way to initialize the data value, it is logical to put it as part of the subsection describing the default value (
defaultValue).
<! -- from plugin/uk.ac.cam.psychiatry.camba.linux/resources/tsafx.pml,
i.e., the Time Series Analysis Pipeline -->
<gfx:gfxData
name="eppi" hierarchy="fMRI" datatype="Number"
xmlns:gfx='http://genericfx.org/namespace'
class='org.genericfx.data.datatypes.GFXIntegerNumber' version="1.0.0">
<gfx:defaultValue value="10"
pref='genericfx://keyvalueparser/CambaRCKeyValueParser?
getValue#source=file:/$user.home$/.cambarc,
platform:/plugin/uk.ac.cam.psychiatry.camba.$osgi.os$/software/camba/bin/.cambarc
&keyword=EPPI&dtype=integer'/>
</gfx:gfxData>
In the XML sniplet above, a data with the name eppi of type integer number (GFXIntegerNumber). The default value can be found by following the instruction in bold. The instruction (it will be explained later) effectively asked CambaFX to read the keyword EPPI from the file ~userid/.cambarc and convert it to an integer value. If it cannot find EPPI in ~userid/.cambarc, it should try the alterantive location (a default file (software/camba/bin/.cambarc) stored in CamBAFX plugin directory, i.e., uk.ac.cam.psychiatry.camba.linux directory for linux). Faling that, use the hard-coded default value of 10 instead.
As it is obvious, the instruction is placed in the pref attribute of the element defaultValue. The instruction is in the form of URI (Uniform Resource Identifiers). The form of the instruction is
scheme://Authority/path?query#fragment
where
scheme = genericfx
Authority = keyvalueparser
Path = CambaRCKeyValueParser
Query = getValue
fragment = source=....
The way to interpret this instruction is
- Scheme section (genericfx) specify that genericFX (and by association, CamBAfx) knows how to handle it.
- Authority section (keyvalueparser) tells genericFX that a text parser that resolve values for keywords is needed.
- Path section (CambaRCKeyValueParser) give the ID for the parser (a piece of program that can intepret a file) that is capable of handling the Query/fragment section. This is the part that link the RCFile to the parser (subprogram) that can interpret it.
- Query/fragment section is a parser specific way of retreiving the data. In this case, CambaRCKeyValueParser can intepret the Query/fragment section to retrieve the appropriate value from the RCFile.
An important feature to note is that the instruction string is very generic and thus, different instruction scheme can be implemented.
How the instruction is interpreted by CamBAfx
The key is the substring "genericfx://keyvalueparser/CambaRCFileKeyValueParser" in the instruction. This provide sufficient information to tell CamBAfx that it can handle the instruction, and how it should handle it. The rest of the instruction (query/fragement) string is simply instruction to the parser that can understand the RCFile.
The ID CambaRCFileKeyValueParser allows CamBAfx to lookup the correct parser that can generate the value required. After it found the parser, it then pass in the (query/fragment) section to instruct the parser how to retrieve the value. The value retrieved is then used as the default value.
Yes, its that simple!
More about choosing the correct parser
To get CamBAfx to understand the parser, the parser is a child class of org.genericfx.data.files.parsers.IKeyValueFileParser. The extension point org.genericfx.data.keyvalueparser is then used to associate the parser with the ID for the pipeline file. A sniplet from the plugin.xml file for uk.ac.cam.psychiatry.camba will illustrate this point:
<extension point="org.genericfx.data.keyvalueparsers">
<keyvalueparser
class="org.genericfx.data.files.parsers.CascadingRCFileKeyValueParser"
id="CambaRCKeyValueParser"/>
</extension>
This syntax associate the parser org.genericfx.data.files.parsers.CascadingRCFileKeyValueParser with the ID CambaRCKeyValueParser.
The System Is Generic
The best thing is, this system is generic. If you have a different layout for your configuration file, simply
- Design the syntax for your instruction, i.e. the Query/Fragment part.
- Create a new child class of org.genericfx.data.files.parsers.IKeyValueFileParser.
- Associate this child class with an ID using org.genericfx.data.keyvalueparser extension point.
- Write the instructions in your pipeline file
Anything else I should know?
Yes. You bet. Since we are able to read RCFiles, why not modifying it in the UI as well? Currently, .cambarc is modifiable via the Preference Page ( Windows->Preferences...->Camba->.cambarc).
The following sniplet from uk.ac.cam.psychiatry.camba.ui shows how it is done for .cambarc above.
<extension
point="org.eclipse.ui.preferencePages">
<page
class="uk.ac.cam.psychiatry.camba.ui.preferences.CambaPreferencePage"
id="CambaPreferencePages"
name="CamBA"/>
<page
name=".cambarc"
class="uk.ac.cam.psychiatry.camba.ui.preferences.CambaRCFilePreferencePage"
id="CambaDotCambaRC"
category="/CambaPreferencePages" />
</extension>
The preference page used (uk.ac.cam.psychiatry.camba.ui.preferences.CambaRCFilePreferenePage) is derived from org.genericfx.ui.preferences.pages.TextFilePreferencePage, a generic page that loads RCFile as text for editing. CambaRCFilePreferencePage simply add location of the .cambarc file to TextFilePreferencePage. It is loaded into GenericFX using the standard Eclipse extension point org.eclipse.ui.preferencePages.
Conclusion
Getting genericFX to understand and interprets RCFiles is not an easy task, but hopefully, with the strategy and implementation above, most of the difficulty are taken out from the equation. Any comments and suggestions on how to improve on this will be greatly appreciated.
Time Series Analysis Pipeline is the pipeline you get when you use File->New menu on the latest development build of CamBAfx. It combines the old fbamm and gbamm to perform a full group analysis. This article describes its development to date. Bac
Tracked: Mar 28, 17:04