enum concept is great for data that is constant and never changes.
However, sometimes there is a need for data that rarely changes, but sometimes does.
There is also a need for constants that can be extended by end-users.
The “Extended Enum” concept covers these use cases.
Strata includes the following extended enums (and many others):
Each extended enum consists of:
- an interface, which is the primary type used in the application
- one or more implementation classes, which may be package-scoped
- a helper class of constants, typically named as the plural form of the interface’s name
Using an Extended Enum
An extended enum instance is a normal Java class, and using it in application code is simple.
// find using the unique name DayCount dayCount = DayCount.of("Act/365F"); // constants may be supplied for common names DayCount dayCount = DayCounts.ACT_365F; // a list of all names can also be obtained Map<String,DayCount> dayCounts = DayCount.extendedEnum().lookupAll();
Once obtained, any method on the extended enum interface can be used.
The key concept of an extended enum is that it has a unique name by which it is referred.
The instance of the extended enum may contain other state and methods but it can always be referred to by name.
As such, all extended enums implement the interface
The extended enum may be implemented using a Joda-Bean, however this is not required.
If it is, then the extended enum will implement the Joda-Convert annotations
@ToString to ensure that when written to XML/JSON/Binary, only the string name is used.
Each extended enum is managed by a single instance of
The instance is typically defined as a private static constant.
Most extended enums will make the constant available via a static
In addition to the unique name, each extended enum instance may have zero to many alternate names. This can be used for backwards compatibility, where the unique name is changed. It can also be used where there is more than one name commonly used for the concept.
of(String) lookup method matches alternate names.
Extended enums often refer to standard industry concepts. For example, the ISDA FpML specification includes long lists of standard codes for concepts such as day counts and indices. These external code lists can be tied to extended enums. When they are, the name used is called the external name.
For example, Strata includes external names that map the FpML names to the following extended enums:
There may be multiple groups of external names to handle different external providers of data. For example, the mapping used by FpML may differ from that used by Bloomberg.
External names are made available via the static
extendedEnum().externalNames(String group) method.
of(String) lookup method does not match external names.
Adding or replacing Extended Enums
The key feature of extended enums is that application code can add to the known set, or replace the existing ones. This means that the definition of a holiday calendar supplied by Strata can be replaced if necessary.
It is intended that extended enums are known at system startup. While it is possible to add or replace instances after the system has started, doing so would require use of concurrent data structures that could slow the application down.
Each extended enum is defined by one or more
The ini file must be located on the classpath in one of three specific locations.
- The “base” location is intended for use by Strata -
- The “library” location is intended for use by libraries that build on Strata -
- The “application” location is intended for use by end-user application code -
The list of known locations can be expanded by setting the system property
com.opengamma.strata.config.directories on the command line.
For example, if the extended enum interface is
then an application ini file must be named:
is responsible for loading and combining the ini files.
The ini file typically has the following format (described below):
[chain] chainNextFile = false [providers] com.opengamma.strata.basics.date.StandardDayCounts = constants com.opengamma.strata.basics.date.Business252DayCount = instance [alternates] Actual/Actual ISDA = Act/Act ISDA [externals.FpML] 30/360 = 30/360 ISDA
Ini file chain
The list of known locations provides a deterministic ordering to the loading of ini files. The “base” location is lower priority than the “library” location which is lower priority than the “application” location. There must only ever be one ini file in each location on the classpath.
[chain] section is used to control how the files link together.
chainNextFile property is a boolean, “true” or “false”.
When processing more than one ini file, processing will continue to the next file if the flag is true,
and ignore lower priority files if the flag is false.
The default value for
chainNextFile is true, thus the whole
[chain] section is normally omitted.
Ini file providers
The extended enum instances are made available via providers defined in the
Each entry in the section has a
key=value form, where the key is a full class name and the value is the provider type.
The three types of provider are:
constants- the class contains public static final constants of the extended enum type
lookup- the class implements
NamedLookupwith a no-args constructor
instance- the class has a static field named
INSTANCEthat is of type
When initializing, the providers are loaded and used to find the extended enum instances.
In the example above, two providers are specified. Both are non-public classes.
StandardDayCounts defines a set of public static final constants of type
Business252DayCount defines public static final constant
INSTANCE of type
Both will be used to lookup extended enums.
Ini file alternate names
[alternates] section defines alternate names for the extended enum.
Each entry in the section has a
key=value form, where the key is the alternate name and the value is the unique name.
In the example above, the name “Actual/Actual ISDA” in FpML has the same meaning as the name “Act/Act ISDA” in Strata.
Ini file external names
[externals.XXX] section defines external names for the extended enum, where
XXX is the name of the group.
Each entry in the section has a
key=value form, where the key is the external name and the value is the unique name.
In the example above, the name “30/360” in FpML has the same meaning as the name “30/360 ISDA” in Strata.