Conversion Code
MusicXML to Java Beans
Handlers
When converting from MusicXML to Java beans, a series of handler classes are called.
The handlers iterate the XML document, calling a series of nested handlers reflecting the hierarchical nature of the document,
and creating the Java beans structure along the way.
The Score is first created by the ScoreHandler:
From within ScoreHandler, a series of PartHandler classes create the part and its measures:
Then a series of MusicDataHandler classes are called from within MeasureHandler:
and so on, until the entire score document is iterated.
When completed, the populated and annotated beans can then used to save to the database or to build LilyPond output.
Factories
Repetitive calls to create beans are handled by bean factories.
For example, a Display bean can occur in many places throughout the structure,
so these calls are handled by the DisplayFactory:
Java Beans to MusicXml and LilyPond Output
Java beans are converted to MusicXml or LilyPond text output by iterating the beans hierarchical structure.
MusicXML Builder Output
Iteration begins with a ScoreBuilder and continues through the score parts:
LilyPond Builder Output
Likewise, LilyPond iteration begins with a ScoreBuilder and continues through the score parts:
The LilyPond conversion code, however, only implements a fraction of MusicXML document conversion to LilyPond features,
due to the richness of the MusicXML and LilyPond definitions.
The user is expected to adjust the output once the conversion is complete
if features are noted as unimplemented, or if the conversion produces any anomalies.
LilyPond conversion fails at the measure level, so if, for example, a measure's duration count doesn't add up,
the conversion will output a measure-length spacer for that measure, and output the exception to the console.
Because there are so many possible output features and only some of them are implemented,
the Java code at the music-data level uses reflection to construct the expected builder class method call.
If the method is unimplemented, a message is sent to console output indicating the unimplemented method.
LilyPond output implementations can then be added individually as desired,
in the form of
buildXXX methods that correspond to bean class names.
For example, the DirectiontypeBuilder implements only those methods that have direction type output implemented for LilyPond: