Package jmri.configurexml

Provides an XML-based mechanism for storing and restoring configurations.

This is intended to satisfy a number of requirements:

  • No XML-specific code in the objects being loaded/stored.
  • Separation at the package level between load/store code and the configured objects
  • Customizable storage of complex objects
  • Control over the order in which complex objects are recreated during load.

To do this:

  1. The application registers relevant objects with the ConfigXmlManager class. These objects are usually the higher-level managers; since code has to be written for the actual class of these objects, you should design to have a minimal number of them. For example, a LayoutManager object of the specific LocoNetLayoutManager class might be registered.
  2. The ConfigXmlManager checks that an adapter class for that object exists. The adapter class for an object of package and class "p.c" is located at runtime by searching for a class called "p.configurexml.cXml", and must implement jmri.configurexml.Adapter.
  3. When a store operation is required, the ConfigXmlManager object iterates over the set of registered objects. For each, it creates an adapter object and requests a store operation, which returns a JDOM Element which is added to the output XML.
  4. When a load operation is required, the input XML file is iterated through. For each top-level Element, an adapter object of the described type is created and passed the Element. Note that the adapter should register the objects it creates!

We choose to put the adapters in a separate package to encourage the reduction of coupling, and make it clear that they are separate (you can get a source tree without them easily, for example). But this means that package-level member variables are not automatically visible. For one class, you can get around this by subclassing. We'll have to see whether this is a real problem or not.

On read, the right class has to be found to handle any given top-level XML element. We do this in an ugly fashion by putting the class name in the "class" attribute. This prevents the XML output from being portable from program to program, an unfortunate loss, but for the time being it seems a reasonable compromise.

The various types do still have descriptive element names (e.g. "turnouts") to help the reader and so that we can have an understandable schema.

The order of loading is the order in the XML file, as written. This constrains the write order: It has to make sure that the reading process works, in that objects are created before others need to reference them.

There are four levels of information, a coarse measure to ensure that prerequisites are present during a load:

  • Pref - program-level preferences
  • Config - NamedBeanManagers
  • Tool - not used
  • User - panels
The level is specified via the call used when registering with the ConfigureManager.

Additionally, the Manager class has a Manager.getXMLOrder() method that is used to order operations within a level.

Schema management

Validation is via XML Schema. (Use of DTDs ended in the 2.9 development series.)

Schemas for these files are found in the xml/schema directory.

A rudimentary version control system is provided by schema file naming, i.e.

  • layout.xsd - the original, not to be changed any more.
  • layout-2-9-6.xsd - manually created when the first non-backward-compatible XML content change was made after the release of JMRI 2.9.5, this accumulates changes until some later non-backward-compatible change is made.
  • layout-4-19-2.xsd - a significant update in structure and content.
When a non-backward compatible change is made to XML persistance, the following steps are needed:
  • Copy the existing schema to one with the next version name (e.g. while building the 3.1.2 release, copy layout-2-9-6.xsd to layout-config-3-1-2.xsd) and commit to Git.
  • Update the comment on the previous file.
  • Update the schemaVersion value in the ConfigXmlManager code.
For more information, see the schema management page.

Related Documentation

For overviews, tutorials, examples, guides, and tool documentation, please see: