Extending it
The extension model
Your document types live in your model, keyed to your own enum values. The module finds them by name, and nothing of ours has to change.
Sooner or later a partner asks for a document nobody else uses, or a format that is theirs alone. The answer is not a support ticket. You extend two enums, write a handler class, and add the Electronic Reporting configurations that turn records into a file and back.
Nothing is forked, nothing of ours is edited, and an upgrade of the module does not touch what you wrote.
The three bases
The extension surface is three abstract classes. That is the contract; everything else is implementation and may change.
| Base | What it is for |
|---|---|
| LunoLakeEDIDocumentTypeHandler | A document type. What format it belongs to, which business process it sits at, and what to do with one that arrives |
| LunoLakeEDIOutboundDocumentTypeHandler | The same, for a type you also send. Adds the one method that builds the report contract |
| LunoLakeEDIAckTypeHandler | What an acknowledgement looks like in your format, per layer |
Extend the outbound base when the document is sent under an outbound agreement. Extend the plain base when it is only received, or when it is an acknowledgement, because an acknowledgement builds no contract.
How yours is found
By the name of your enum element. You extend LunoLakeEDIDocumentType with a value of your own, and you name that same value in an attribute on the handler.
[LunoLakeEDIDocumentTypeAttribute(enumLiteralStr(LunoLakeEDIDocumentType, SIMPLEDI_GRN))]
public final class LunoLakeEDIExampleGrnHandler extends LunoLakeEDIOutboundDocumentTypeHandler
{
}The element name is the key at both ends. The compiler produces the string in your attribute; the module produces the identical string at run time from the enum value it is holding. They meet on a name, not on a number, which is why nothing breaks when enum values are renumbered by a deployment.
Built-in types do not go through this
The shipped types are not decorated with attributes, and asking the registry for one returns nothing. That is by design: the lookup is only reached when a type is not one of ours. Your handler cannot accidentally take over EDIFACT INVOIC by registering for it.
Acknowledgements are the one exception, and deliberately so. An acknowledgement handler is consulted before the built-in mapping, so you can override what a receipt looks like in a format the module already knows, if a partner insists on a variant.
One handler per key
Two classes registering for the same document type is a mistake the platform reports loudly, and it will do so at the worst moment if the first time it happens is a live message. The module ships a diagnostic that finds duplicate registrations before that, and it is worth running after any model is added.
The example model
LunoLakeEDIExample is a complete worked example: an invented format called SIMPLEDI with a goods received note, two acknowledgement types, a compare engine, triggers and tests. It is a separate model which is deliberately not a friend of the module, so it compiles against the published surface only.
That is the point of it. If the example builds, the surface is enough, and anything you need that it cannot reach is a gap in the surface rather than a thing to work around.
Adding a document type walks through it from an empty model.