Skip to content

Extract validation logic from DataDictionary into DataDictionaryValidator - #1306

Open
konradbloor wants to merge 4 commits into
quickfix-j:masterfrom
konradbloor:feature/extract-datadictionary-validator
Open

Extract validation logic from DataDictionary into DataDictionaryValidator#1306
konradbloor wants to merge 4 commits into
quickfix-j:masterfrom
konradbloor:feature/extract-datadictionary-validator

Conversation

@konradbloor

Copy link
Copy Markdown
Contributor

This is a follow-up to #1303 — there I said I would make the validation methods consistent. The review feedback on that PR was to pass a single flag rather than the whole ValidationSettings when a method only reads one attribute. This PR actually pulls the validation out into its own class which also holds the settings.

Looking at DataDictionary, it does three things: loading the XML dictionary, providing a queryable message metadata model, and validation. Ideally a change to how we validate shouldn't mean modifying DataDictionary, so this PR moves the validation logic (~240 lines: validate, iterate and the check* methods) into a new DataDictionaryValidator class. The existing public API is unaffected — the DataDictionary.validate(...) overloads are kept and delegate to the new class.

A couple of notes:

  • If this is a step too far, please say and I'll change the PR to be just the scope requested before (making the validation methods consistent).
  • Happy to make DataDictionaryValidator package-private if we should keep it internal, what do you think?

@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.18182% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.92%. Comparing base (369182d) to head (539bdf0).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...rc/main/java/quickfix/DataDictionaryValidator.java 93.65% 1 Missing and 7 partials ⚠️
...xj-base/src/main/java/quickfix/DataDictionary.java 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1306      +/-   ##
============================================
+ Coverage     70.42%   70.92%   +0.49%     
- Complexity     2249     2281      +32     
============================================
  Files           159      160       +1     
  Lines          9065     9076      +11     
  Branches       1192     1193       +1     
============================================
+ Hits           6384     6437      +53     
+ Misses         2218     2190      -28     
+ Partials        463      449      -14     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@konradbloor
konradbloor force-pushed the feature/extract-datadictionary-validator branch from a22b45b to 24dc7ae Compare August 19, 2026 14:07
…lidator`

`DataDictionaryValidator` holds the `ValidationSettings` as instance state,
so the validation methods no longer need to pass settings (or individual
flags) as parameters. The public `DataDictionary.validate()` overloads are
kept and delegate to the new class, so no API change for callers.
Method bodies are moved verbatim apart from referencing the dictionary and
settings through `dd.` and `settings.`.
@konradbloor
konradbloor force-pushed the feature/extract-datadictionary-validator branch from 24dc7ae to d770386 Compare August 19, 2026 14:11
…lidation tests

JaCoCo attributes a call site as missed when the called method throws, so
the `throwNewFieldException` helper made `checkGroupCount` appear
uncovered even though tests exercised it. Inline the throws and add tests
for the matching, mismatched, non-integer, and undefined-group cases.
public void validate(Message message, ValidationSettings settings) throws IncorrectTagValue, FieldNotFound,
IncorrectDataFormat {
validate(message, false, settings);
new DataDictionaryValidator(settings).validate(this, message);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently OOO so cannot browse all changes in full, but this looks like we create a new object on every call to validate()?

@konradbloor konradbloor Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! This is a good point. Have fixed this in 539bdf0. The new instance allocation for each call is gone, and nothing new has been added to the public API.

Are you comfortable with the change? My aim has been to move the validation out so we have one fewer reason to change DataDictionary, but it does come with tradeoffs. Your experience with the project will give you a much better intuitive sense of whether those tradeoffs are worth it!

If you would prefer actually we wind back and simply make the validation methods consistent as per 1303 I would totally understand and would close this and just follow up with that.

…lidate()` call

Move the validation implementation into a package-private static
`validateInternal()` that `DataDictionary`'s convenience overloads call
directly, so no validator object is created per call. The public
instance API is unchanged and keeps its delegation chain; `Session`
continues to reuse its single cached validator.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants