JMRI: Adding A New Data Type
Author: Bob Jacobsen
Keywords: JMRI technical type add

# JMRI Code: Adding a New Data Type

This page describes the steps to add a new data-type, e.g. Turnouts, to the JMRI code.

It uses as an example the addition of the Reporter type in July, 2004. Reporter was added as a new type of NamedBean and is being used to bring complex information back from the layout.

Note that we don't do this very often, and the specifics are more important than the generalities here. You should should make sure you understand the intended system connection structure which is documented documented on another page.

This mostly talks about a type that connected to one or more system connections, e.g. represents hardware-specific items. It's also possible to have non-layout-specific types, which are somewhat different (and should also be documented). For example, `Routes`.

We list the files that are modified and created in the order they were done in this case; other orders may also work, and you might not need to do all these.

In this particular case, our first implementation is for only one hardware system (LocoNet). This effects how we ordered this, and reduced the need to have unit tests in place at the beginning. By working through the LocoNet implementation first, we could get a better idea of whether the proposed Reporter interface did what's needed. If you are creating a new type that several system will need at first, you should also create unit tests early in the process to encode what you think is the common behavior.

In general, the new classes and interfaces defined below can most easily be made by copying an existing one. In this case, we copy the "*Turnout*" file to make a corresponding "*Reporter*" file.

### Define the new type and its manager

Reporter

  This interface defines the properties needed. It should inherit from NamedBean, though you can add new accessors as desired.

ReporterManager

  This interface provides methods for getting a Reporter object, either just from the system name (preferred) or with additional parameters

  At this point, make sure you can compile.

doc/Technical/Names.shtml

  Update the discussion of naming to include the type-letter for your new type. While you're at it, update the system-specific naming pages as needed.

### Provide the base for implementations

AbstractReporter

  This is a basic implementation.

AbstractReporterManager

  Basic implementation; stuff that's useful to all the system-specific implementations

  At this point, make sure you can compile.

managers.ProxyReporterManager

  This handles having more than one system providing Reporter objects. It takes zero or more ReporterManager implementations, and routes requests for Reporter access to the right one.

InstanceManager

  There are several historical ways to install things in the InstanceManager. The current way is to use the `getDefault(..)` and `getOptionalDefault(..)` calls for a default and the `getList(..)` call to get access to all.

  At this point, make sure you can compile.

### Provide the first system-specific implementation

jmrix.loconet.LnReporterManager

  This class listens for activity indicating a new LocoNet-specific Reporter, and calls for one to be created if needed. Other than that, and providing the right system-specific letter (e.g. 'L'), this is just a direct copy.

jmrix.loconet/LnReporter

  Converts specific messages into reporter actions and report. All of the rest of the stuff is just to get this in place.

  At this point, make sure you can compile. Nothing will happen when you run until the next step.

jmrix.loconet.LnPortController

  Here (or perhaps somewhere else in another system) you create an instance of the correct ReporterManager class at system startup and install it in the InstanceManager. See the system structure page for more details.

### Add to the scripting support

jython/jmri_defaults.py

  Add a new variable to give easy access to the new manager.

doc/Technical/Jython.shtml

  Update this to refer to the new Jython variable (There may be other web pages too!)

  At this point, you should be able to compile and run, testing the new code from the jython command line.

### Add a new table tool for access (optional)

jmrit.beantable.ReporterTableAction

  Create a new "Table" for watching these in action.

  In this particular case, the code had to be modified a little (instead of just copied) because a Reporter doesn't really have a way to support "click to change"

jmrit/beantable/BeanTableBundle.properties

  Add strings for the new properties you defined in the previous step. You might also want to translate these in the other properties files when possible.

jmrit.ToolsMenu

  Add the new ReporterTableAction class to the menu.

jmrit/JmritToolsBundle.properties

  Add strings for the new property you defined in the previous step. You might also want to translate these in the other properties files when possible.

  At this point, you should be able to compile and run to test the new table.

### Provide for persistance of the manager and type objects

configxml.AbstractReporterManagerConfigXML

  Loads and stores the configuration date for the ReporterManager implementations

jmrix.loconet.configurexml.LnReporterManagerXml

  Load and store the system-specific LocoNet Reporter Manager info

xml/DTD/layout-config.dtd

  Add any new XML elements and attributes to the DTD

### Provide a suitable display icon class (optional)

jmrit.display.ReporterIcon

  discussion

jmrit.display.configxml.ReporterIconXml

  discussion

xml/DTD/layout-config.dtd

  discussion

### Complete the documentation

ant javadoc

  Create the Javadocs, and fix any new (or old) problems.