From e4f32ced6d4a69038f68520097273ed5067dce45 Mon Sep 17 00:00:00 2001 From: Philip Whitehouse Date: Tue, 26 Nov 2019 15:50:24 +0000 Subject: [PATCH 01/19] QFJ-982 Rework Data Dictionary handling to separate DataDictionarySettings from DataDictionary --- .../main/java/quickfix/DataDictionary.java | 135 ++--------- .../java/quickfix/DataDictionarySettings.java | 81 +++++++ .../java/quickfix/DefaultSessionFactory.java | 21 +- .../src/main/java/quickfix/Message.java | 65 +++--- .../src/main/java/quickfix/MessageUtils.java | 11 +- .../src/main/java/quickfix/Session.java | 16 +- .../quickfix/DataDictionarySettingsTest.java | 26 +++ .../java/quickfix/DataDictionaryTest.java | 216 +++++++++--------- .../src/test/java/quickfix/FieldTest.java | 2 +- .../src/test/java/quickfix/FileLogTest.java | 2 +- .../src/test/java/quickfix/JdbcLogTest.java | 2 +- .../src/test/java/quickfix/LogUtilTest.java | 2 +- .../src/test/java/quickfix/MessageTest.java | 157 +++++++------ .../test/java/quickfix/MessageUtilsTest.java | 2 +- .../java/quickfix/RepeatingGroupTest.java | 52 +++-- .../test/java/quickfix/SerializationTest.java | 2 +- .../quickfix/SessionFactoryTestSupport.java | 8 +- .../src/test/java/quickfix/SessionTest.java | 18 +- .../mina/message/FIXMessageDecoderTest.java | 3 +- 19 files changed, 430 insertions(+), 391 deletions(-) create mode 100644 quickfixj-core/src/main/java/quickfix/DataDictionarySettings.java create mode 100644 quickfixj-core/src/test/java/quickfix/DataDictionarySettingsTest.java diff --git a/quickfixj-core/src/main/java/quickfix/DataDictionary.java b/quickfixj-core/src/main/java/quickfix/DataDictionary.java index a8732dec06..79416d3f9d 100644 --- a/quickfixj-core/src/main/java/quickfix/DataDictionary.java +++ b/quickfixj-core/src/main/java/quickfix/DataDictionary.java @@ -68,11 +68,6 @@ public class DataDictionary { private static final int USER_DEFINED_TAG_MIN = 5000; private static final String NO = "N"; private boolean hasVersion = false; - private boolean checkFieldsOutOfOrder = true; - private boolean checkFieldsHaveValues = true; - private boolean checkUserDefinedFields = true; - private boolean checkUnorderedGroupFields = true; - private boolean allowUnknownMessageFields = false; private String beginString; private final Map> messageFields = new HashMap<>(); private final Map> requiredFields = new HashMap<>(); @@ -428,86 +423,6 @@ private boolean isMultipleValueStringField(int field) { return fieldType == FieldType.MULTIPLEVALUESTRING || fieldType == FieldType.MULTIPLESTRINGVALUE; } - /** - * Controls whether out of order fields are checked. - * - * @param flag true = checked, false = not checked - */ - public void setCheckFieldsOutOfOrder(boolean flag) { - checkFieldsOutOfOrder = flag; - } - - public boolean isCheckFieldsOutOfOrder() { - return checkFieldsOutOfOrder; - } - - public boolean isCheckUnorderedGroupFields() { - return checkUnorderedGroupFields; - } - - public boolean isCheckFieldsHaveValues() { - return checkFieldsHaveValues; - } - - public boolean isCheckUserDefinedFields() { - return checkUserDefinedFields; - } - - public boolean isAllowUnknownMessageFields() { - return allowUnknownMessageFields; - } - - /** - * Controls whether group fields are in the same order - * - * @param flag true = checked, false = not checked - */ - public void setCheckUnorderedGroupFields(boolean flag) { - checkUnorderedGroupFields = flag; - for (Map gm : groups.values()) { - for (GroupInfo gi : gm.values()) { - gi.getDataDictionary().setCheckUnorderedGroupFields(flag); - } - } - } - - /** - * Controls whether empty field values are checked. - * - * @param flag true = checked, false = not checked - */ - public void setCheckFieldsHaveValues(boolean flag) { - checkFieldsHaveValues = flag; - for (Map gm : groups.values()) { - for (GroupInfo gi : gm.values()) { - gi.getDataDictionary().setCheckFieldsHaveValues(flag); - } - } - } - - /** - * Controls whether user defined fields are checked. - * - * @param flag true = checked, false = not checked - */ - public void setCheckUserDefinedFields(boolean flag) { - checkUserDefinedFields = flag; - for (Map gm : groups.values()) { - for (GroupInfo gi : gm.values()) { - gi.getDataDictionary().setCheckUserDefinedFields(flag); - } - } - } - - public void setAllowUnknownMessageFields(boolean allowUnknownFields) { - allowUnknownMessageFields = allowUnknownFields; - for (Map gm : groups.values()) { - for (GroupInfo gi : gm.values()) { - gi.getDataDictionary().setAllowUnknownMessageFields(allowUnknownFields); - } - } - } - private void copyFrom(DataDictionary rhs) { hasVersion = rhs.hasVersion; beginString = rhs.beginString; @@ -523,12 +438,6 @@ private void copyFrom(DataDictionary rhs) { copyMap(valueNames, rhs.valueNames); copyGroups(groups, rhs.groups); copyMap(components, rhs.components); - - setCheckFieldsOutOfOrder(rhs.checkFieldsOutOfOrder); - setCheckFieldsHaveValues(rhs.checkFieldsHaveValues); - setCheckUserDefinedFields(rhs.checkUserDefinedFields); - setCheckUnorderedGroupFields(rhs.checkUnorderedGroupFields); - setAllowUnknownMessageFields(rhs.allowUnknownMessageFields); } @SuppressWarnings("unchecked") @@ -581,9 +490,9 @@ private static void copyCollection(Collection lhs, Collection rhs) { * @throws FieldNotFound if a field cannot be found * @throws IncorrectDataFormat if a field value has a wrong data type */ - public void validate(Message message) throws IncorrectTagValue, FieldNotFound, + public void validate(Message message, DataDictionarySettings settings) throws IncorrectTagValue, FieldNotFound, IncorrectDataFormat { - validate(message, false); + validate(message, false, settings); } /** @@ -595,13 +504,13 @@ public void validate(Message message) throws IncorrectTagValue, FieldNotFound, * @throws FieldNotFound if a field cannot be found * @throws IncorrectDataFormat if a field value has a wrong data type */ - public void validate(Message message, boolean bodyOnly) throws IncorrectTagValue, + public void validate(Message message, boolean bodyOnly, DataDictionarySettings settings) throws IncorrectTagValue, FieldNotFound, IncorrectDataFormat { - validate(message, bodyOnly ? null : this, this); + validate(message, bodyOnly ? null : this, this, settings); } static void validate(Message message, DataDictionary sessionDataDictionary, - DataDictionary applicationDataDictionary) throws IncorrectTagValue, FieldNotFound, + DataDictionary applicationDataDictionary, DataDictionarySettings settings) throws IncorrectTagValue, FieldNotFound, IncorrectDataFormat { final boolean bodyOnly = sessionDataDictionary == null; @@ -626,39 +535,39 @@ static void validate(Message message, DataDictionary sessionDataDictionary, } if (!bodyOnly) { - sessionDataDictionary.iterate(message.getHeader(), HEADER_ID, sessionDataDictionary); - sessionDataDictionary.iterate(message.getTrailer(), TRAILER_ID, sessionDataDictionary); + sessionDataDictionary.iterate(settings, message.getHeader(), HEADER_ID, sessionDataDictionary); + sessionDataDictionary.iterate(settings, message.getTrailer(), TRAILER_ID, sessionDataDictionary); } - applicationDataDictionary.iterate(message, msgType, applicationDataDictionary); + applicationDataDictionary.iterate(settings, message, msgType, applicationDataDictionary); } private static boolean isVersionSpecified(DataDictionary dd) { return dd != null && dd.hasVersion; } - private void iterate(FieldMap map, String msgType, DataDictionary dd) throws IncorrectTagValue, + private void iterate(DataDictionarySettings settings, FieldMap map, String msgType, DataDictionary dd) throws IncorrectTagValue, IncorrectDataFormat { final Iterator> iterator = map.iterator(); while (iterator.hasNext()) { final StringField field = (StringField) iterator.next(); - checkHasValue(field); + checkHasValue(settings, field); if (hasVersion) { - checkValidFormat(field); + checkValidFormat(settings, field); checkValue(field); } if (beginString != null) { - dd.checkField(field, msgType, map instanceof Message); + dd.checkField(settings, field, msgType, map instanceof Message); dd.checkGroupCount(field, map, msgType); } } for (final List groups : map.getGroups().values()) { for (final Group group : groups) { - iterate(group, msgType, dd.getGroup(msgType, group.getFieldTag()) + iterate(settings, group, msgType, dd.getGroup(msgType, group.getFieldTag()) .getDataDictionary()); } } @@ -679,10 +588,10 @@ void checkValidTagNumber(Field field) { } /** Check if field tag is defined for message or group **/ - void checkField(Field field, String msgType, boolean message) { + void checkField(DataDictionarySettings settings, Field field, String msgType, boolean message) { // use different validation for groups and messages boolean messageField = message ? isMsgField(msgType, field.getField()) : fields.contains(field.getField()); - boolean fail = checkFieldFailure(field.getField(), messageField); + boolean fail = checkFieldFailure(settings, field.getField(), messageField); if (fail) { if (fields.contains(field.getField())) { @@ -693,22 +602,22 @@ void checkField(Field field, String msgType, boolean message) { } } - boolean checkFieldFailure(int field, boolean messageField) { + boolean checkFieldFailure(DataDictionarySettings settings, int field, boolean messageField) { boolean fail; if (field < USER_DEFINED_TAG_MIN) { - fail = !messageField && !allowUnknownMessageFields; + fail = !messageField && !settings.allowUnknownMessageFields; } else { - fail = !messageField && checkUserDefinedFields; + fail = !messageField && settings.checkUserDefinedFields; } return fail; } - private void checkValidFormat(StringField field) throws IncorrectDataFormat { + private void checkValidFormat(DataDictionarySettings settings, StringField field) throws IncorrectDataFormat { FieldType fieldType = getFieldType(field.getTag()); if (fieldType == null) { return; } - if (!checkFieldsHaveValues && field.getValue().length() == 0) { + if (!settings.checkFieldsHaveValues && field.getValue().length() == 0) { return; } try { @@ -770,8 +679,8 @@ private void checkValue(StringField field) throws IncorrectTagValue { } /** Check if a field has a value. **/ - private void checkHasValue(StringField field) { - if (checkFieldsHaveValues && field.getValue().length() == 0) { + private void checkHasValue(DataDictionarySettings settings, StringField field) { + if (settings.checkFieldsHaveValues && field.getValue().length() == 0) { throw new FieldException(SessionRejectReason.TAG_SPECIFIED_WITHOUT_A_VALUE, field.getField()); } diff --git a/quickfixj-core/src/main/java/quickfix/DataDictionarySettings.java b/quickfixj-core/src/main/java/quickfix/DataDictionarySettings.java new file mode 100644 index 0000000000..fce73a4848 --- /dev/null +++ b/quickfixj-core/src/main/java/quickfix/DataDictionarySettings.java @@ -0,0 +1,81 @@ +package quickfix; + +import java.util.Map; + +public class DataDictionarySettings { + boolean checkFieldsOutOfOrder = true; + boolean checkFieldsHaveValues = true; + boolean checkUserDefinedFields = true; + boolean checkUnorderedGroupFields = true; + boolean allowUnknownMessageFields = false; + + public DataDictionarySettings() {} + + public DataDictionarySettings(DataDictionarySettings dataDictionarySettings) { + this.checkFieldsOutOfOrder = dataDictionarySettings.checkFieldsOutOfOrder; + this.checkFieldsHaveValues = dataDictionarySettings.checkFieldsHaveValues; + this.checkUserDefinedFields = dataDictionarySettings.checkUserDefinedFields; + this.checkUnorderedGroupFields = dataDictionarySettings.checkUnorderedGroupFields; + this.allowUnknownMessageFields = dataDictionarySettings.allowUnknownMessageFields; + } + + /** + * Controls whether out of order fields are checked. + * + * @param flag true = checked, false = not checked + */ + public void setCheckFieldsOutOfOrder(boolean flag) { + checkFieldsOutOfOrder = flag; + } + + public boolean isCheckFieldsOutOfOrder() { + return checkFieldsOutOfOrder; + } + + public boolean isCheckUnorderedGroupFields() { + return checkUnorderedGroupFields; + } + + public boolean isCheckFieldsHaveValues() { + return checkFieldsHaveValues; + } + + public boolean isCheckUserDefinedFields() { + return checkUserDefinedFields; + } + + public boolean isAllowUnknownMessageFields() { + return allowUnknownMessageFields; + } + + /** + * Controls whether group fields are in the same order + * + * @param flag true = checked, false = not checked + */ + public void setCheckUnorderedGroupFields(boolean flag) { + checkUnorderedGroupFields = flag; + } + + /** + * Controls whether empty field values are checked. + * + * @param flag true = checked, false = not checked + */ + public void setCheckFieldsHaveValues(boolean flag) { + checkFieldsHaveValues = flag; + } + + /** + * Controls whether user defined fields are checked. + * + * @param flag true = checked, false = not checked + */ + public void setCheckUserDefinedFields(boolean flag) { + checkUserDefinedFields = flag; + } + + public void setAllowUnknownMessageFields(boolean allowUnknownFields) { + allowUnknownMessageFields = allowUnknownFields; + } +} diff --git a/quickfixj-core/src/main/java/quickfix/DefaultSessionFactory.java b/quickfixj-core/src/main/java/quickfix/DefaultSessionFactory.java index 66e3c67c8b..2c61d1e8e7 100644 --- a/quickfixj-core/src/main/java/quickfix/DefaultSessionFactory.java +++ b/quickfixj-core/src/main/java/quickfix/DefaultSessionFactory.java @@ -152,6 +152,7 @@ public Session create(SessionID sessionID, SessionSettings settings) throws Conf processPreFixtDataDictionary(sessionID, settings, dataDictionaryProvider); } } + DataDictionarySettings dataDictionarySettings = createDataDictionarySettings(sessionID, settings); int heartbeatInterval = 0; if (connectionType.equals(SessionFactory.INITIATOR_CONNECTION_TYPE)) { @@ -215,7 +216,7 @@ public Session create(SessionID sessionID, SessionSettings settings) throws Conf final SessionSchedule sessionSchedule = sessionScheduleFactory.create(sessionID, settings); final Session session = new Session(application, messageStoreFactory, sessionID, - dataDictionaryProvider, sessionSchedule, logFactory, + dataDictionaryProvider, dataDictionarySettings, sessionSchedule, logFactory, messageFactory, heartbeatInterval, checkLatency, maxLatency, timestampPrecision, resetOnLogon, resetOnLogout, resetOnDisconnect, refreshAtLogon, checkCompID, redundantResentRequestAllowed, persistMessages, useClosedIntervalForResend, @@ -259,34 +260,38 @@ private void processPreFixtDataDictionary(SessionID sessionID, SessionSettings s private DataDictionary createDataDictionary(SessionID sessionID, SessionSettings settings, String settingsKey, String beginString) throws ConfigError, FieldConvertError { final String path = getDictionaryPath(sessionID, settings, settingsKey, beginString); - final DataDictionary dataDictionary = getDataDictionary(path); + return getDataDictionary(path); + } + + private DataDictionarySettings createDataDictionarySettings(SessionID sessionID, SessionSettings settings) throws FieldConvertError, ConfigError { + DataDictionarySettings dataDictionarySettings = new DataDictionarySettings(); if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_FIELDS_OUT_OF_ORDER)) { - dataDictionary.setCheckFieldsOutOfOrder(settings.getBool(sessionID, + dataDictionarySettings.setCheckFieldsOutOfOrder(settings.getBool(sessionID, Session.SETTING_VALIDATE_FIELDS_OUT_OF_ORDER)); } if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_FIELDS_HAVE_VALUES)) { - dataDictionary.setCheckFieldsHaveValues(settings.getBool(sessionID, + dataDictionarySettings.setCheckFieldsHaveValues(settings.getBool(sessionID, Session.SETTING_VALIDATE_FIELDS_HAVE_VALUES)); } if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_UNORDERED_GROUP_FIELDS)) { - dataDictionary.setCheckUnorderedGroupFields(settings.getBool(sessionID, + dataDictionarySettings.setCheckUnorderedGroupFields(settings.getBool(sessionID, Session.SETTING_VALIDATE_UNORDERED_GROUP_FIELDS)); } if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_USER_DEFINED_FIELDS)) { - dataDictionary.setCheckUserDefinedFields(settings.getBool(sessionID, + dataDictionarySettings.setCheckUserDefinedFields(settings.getBool(sessionID, Session.SETTING_VALIDATE_USER_DEFINED_FIELDS)); } if (settings.isSetting(sessionID, Session.SETTING_ALLOW_UNKNOWN_MSG_FIELDS)) { - dataDictionary.setAllowUnknownMessageFields(settings.getBool(sessionID, + dataDictionarySettings.setAllowUnknownMessageFields(settings.getBool(sessionID, Session.SETTING_ALLOW_UNKNOWN_MSG_FIELDS)); } - return dataDictionary; + return dataDictionarySettings; } private void processFixtDataDictionaries(SessionID sessionID, SessionSettings settings, diff --git a/quickfixj-core/src/main/java/quickfix/Message.java b/quickfixj-core/src/main/java/quickfix/Message.java index 301ff802c8..4ce459f4b8 100644 --- a/quickfixj-core/src/main/java/quickfix/Message.java +++ b/quickfixj-core/src/main/java/quickfix/Message.java @@ -92,27 +92,26 @@ protected Message(int[] fieldOrder) { public Message(String string) throws InvalidMessage { initializeHeader(); - fromString(string, null, true, true); + fromString(string, null, null, true, true); } public Message(String string, boolean validate) throws InvalidMessage { initializeHeader(); - fromString(string, null, validate, true); + fromString(string, null, null, validate, true); } - public Message(String string, DataDictionary dd) throws InvalidMessage { + public Message(String string, DataDictionary dd, DataDictionarySettings dds) throws InvalidMessage { initializeHeader(); - fromString(string, dd, true, true); + fromString(string, dd, dds, true, true); } - public Message(String string, DataDictionary dd, boolean validate) throws InvalidMessage { + public Message(String string, DataDictionary dd, DataDictionarySettings dds, boolean validate) throws InvalidMessage { initializeHeader(); - fromString(string, dd, validate, true); + fromString(string, dd, dds, validate, true); } - - public Message(String string, DataDictionary sessionDictionary, DataDictionary applicationDictionary, boolean validate) throws InvalidMessage { + public Message(String string, DataDictionary sessionDictionary, DataDictionary applicationDictionary, DataDictionarySettings dataDictionarySettings, boolean validate) throws InvalidMessage { initializeHeader(); - fromString(string, sessionDictionary, applicationDictionary, validate, true); + fromString(string, sessionDictionary, applicationDictionary, dataDictionarySettings, validate, true); } private void initializeHeader() { @@ -541,38 +540,38 @@ private void optionallySetID(Header header, int field, String value) { } } - public void fromString(String messageData, DataDictionary dd, boolean doValidation) + public void fromString(String messageData, DataDictionary dd, DataDictionarySettings dataDictionarySettings, boolean doValidation) throws InvalidMessage { - parse(messageData, dd, dd, doValidation, true); + parse(messageData, dd, dd, dataDictionarySettings, doValidation, true); } - public void fromString(String messageData, DataDictionary dd, boolean doValidation, + public void fromString(String messageData, DataDictionary dd, DataDictionarySettings dds, boolean doValidation, boolean validateChecksum) throws InvalidMessage { - parse(messageData, dd, dd, doValidation, validateChecksum); + parse(messageData, dd, dd, dds, doValidation, validateChecksum); } public void fromString(String messageData, DataDictionary sessionDictionary, - DataDictionary applicationDictionary, boolean doValidation) throws InvalidMessage { - fromString(messageData, sessionDictionary, applicationDictionary, doValidation, true); + DataDictionary applicationDictionary, DataDictionarySettings dataDictionarySettings, boolean doValidation) throws InvalidMessage { + fromString(messageData, sessionDictionary, applicationDictionary, dataDictionarySettings, doValidation, true); } public void fromString(String messageData, DataDictionary sessionDictionary, - DataDictionary applicationDictionary, boolean doValidation, boolean validateChecksum) + DataDictionary applicationDictionary, DataDictionarySettings dataDictionarySettings, boolean doValidation, boolean validateChecksum) throws InvalidMessage { if (sessionDictionary.isAdminMessage(MessageUtils.getMessageType(messageData))) { applicationDictionary = sessionDictionary; } - parse(messageData, sessionDictionary, applicationDictionary, doValidation, validateChecksum); + parse(messageData, sessionDictionary, applicationDictionary, dataDictionarySettings, doValidation, validateChecksum); } void parse(String messageData, DataDictionary sessionDataDictionary, - DataDictionary applicationDataDictionary, boolean doValidation, + DataDictionary applicationDataDictionary, DataDictionarySettings dataDictionarySettings, boolean doValidation, boolean validateChecksum) throws InvalidMessage { this.messageData = messageData; try { - parseHeader(sessionDataDictionary, doValidation); - parseBody(applicationDataDictionary, doValidation); + parseHeader(sessionDataDictionary, dataDictionarySettings, doValidation); + parseBody(applicationDataDictionary, dataDictionarySettings, doValidation); parseTrailer(sessionDataDictionary); if (doValidation && validateChecksum) { validateCheckSum(messageData); @@ -596,7 +595,7 @@ private void validateCheckSum(String messageData) throws InvalidMessage { } } - private void parseHeader(DataDictionary dd, boolean doValidation) throws InvalidMessage { + private void parseHeader(DataDictionary dd, DataDictionarySettings dds, boolean doValidation) throws InvalidMessage { if (doValidation) { final boolean validHeaderFieldOrder = isNextField(dd, header, BeginString.FIELD) && isNextField(dd, header, BodyLength.FIELD) @@ -613,7 +612,7 @@ && isNextField(dd, header, BodyLength.FIELD) header.setField(field); if (dd != null && dd.isGroup(DataDictionary.HEADER_ID, field.getField())) { - parseGroup(DataDictionary.HEADER_ID, field, dd, dd, header, doValidation); + parseGroup(DataDictionary.HEADER_ID, field, dd, dd, dds, header, doValidation); } field = extractField(dd, header); @@ -638,7 +637,7 @@ private String getMsgType() throws InvalidMessage { } } - private void parseBody(DataDictionary dd, boolean doValidation) throws InvalidMessage { + private void parseBody(DataDictionary dd, DataDictionarySettings dds, boolean doValidation) throws InvalidMessage { StringField field = extractField(dd, this); while (field != null) { if (isTrailerField(field.getField())) { @@ -652,16 +651,16 @@ private void parseBody(DataDictionary dd, boolean doValidation) throws InvalidMe setField(header, field); // Group case if (dd != null && dd.isGroup(DataDictionary.HEADER_ID, field.getField())) { - parseGroup(DataDictionary.HEADER_ID, field, dd, dd, header, doValidation); + parseGroup(DataDictionary.HEADER_ID, field, dd, dd, dds, header, doValidation); } - if (doValidation && dd != null && dd.isCheckFieldsOutOfOrder()) + if (doValidation && dd != null && dds.isCheckFieldsOutOfOrder()) throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, field.getTag()); } else { setField(this, field); // Group case if (dd != null && dd.isGroup(getMsgType(), field.getField())) { - parseGroup(getMsgType(), field, dd, dd, this, doValidation); + parseGroup(getMsgType(), field, dd, dd, dds, this, doValidation); } } @@ -676,7 +675,7 @@ private void setField(FieldMap fields, StringField field) { fields.setField(field); } - private void parseGroup(String msgType, StringField field, DataDictionary dd, DataDictionary parentDD, FieldMap parent, boolean doValidation) + private void parseGroup(String msgType, StringField field, DataDictionary dd, DataDictionary parentDD, DataDictionarySettings dds, FieldMap parent, boolean doValidation) throws InvalidMessage { final DataDictionary.GroupInfo rg = dd.getGroup(msgType, field.getField()); final DataDictionary groupDataDictionary = rg.getDataDictionary(); @@ -710,15 +709,15 @@ private void parseGroup(String msgType, StringField field, DataDictionary dd, Da previousOffset = -1; // QFJ-742 if (groupDataDictionary.isGroup(msgType, tag)) { - parseGroup(msgType, field, groupDataDictionary, parentDD, group, doValidation); + parseGroup(msgType, field, groupDataDictionary, parentDD, dds, group, doValidation); } } else if (groupDataDictionary.isGroup(msgType, tag)) { // QFJ-934: message should be rejected and not ignored when first field not found checkFirstFieldFound(firstFieldFound, groupCountTag, firstField, tag); - parseGroup(msgType, field, groupDataDictionary, parentDD, group, doValidation); + parseGroup(msgType, field, groupDataDictionary, parentDD, dds, group, doValidation); } else if (groupDataDictionary.isField(tag)) { checkFirstFieldFound(firstFieldFound, groupCountTag, firstField, tag); - if (fieldOrder != null && dd.isCheckUnorderedGroupFields()) { + if (fieldOrder != null && dds.isCheckUnorderedGroupFields()) { final int offset = indexOf(tag, fieldOrder); if (offset > -1) { if (offset <= previousOffset) { @@ -735,7 +734,7 @@ private void parseGroup(String msgType, StringField field, DataDictionary dd, Da } else { // QFJ-169/QFJ-791: handle unknown repeating group fields in the body if (!isTrailerField(tag) && !(DataDictionary.HEADER_ID.equals(msgType))) { - if (checkFieldValidation(parent, parentDD, field, msgType, doValidation, group)) { + if (checkFieldValidation(parent, parentDD, dds, field, msgType, doValidation, group)) { continue; } } @@ -763,11 +762,11 @@ private void checkFirstFieldFound(boolean firstFieldFound, final int groupCountT } } - private boolean checkFieldValidation(FieldMap parent, DataDictionary parentDD, StringField field, String msgType, boolean doValidation, Group group) throws FieldException { + private boolean checkFieldValidation(FieldMap parent, DataDictionary parentDD, DataDictionarySettings dds, StringField field, String msgType, boolean doValidation, Group group) throws FieldException { boolean isField = (parent instanceof Group) ? parentDD.isField(field.getTag()) : parentDD.isMsgField(msgType, field.getTag()); if (!isField) { if (doValidation) { - boolean fail = parentDD.checkFieldFailure(field.getTag(), false); + boolean fail = parentDD.checkFieldFailure(dds, field.getTag(), false); if (fail) { throw new FieldException(SessionRejectReason.TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE, field.getTag()); } diff --git a/quickfixj-core/src/main/java/quickfix/MessageUtils.java b/quickfixj-core/src/main/java/quickfix/MessageUtils.java index 60f7c8bdbc..0cc25ef7a9 100644 --- a/quickfixj-core/src/main/java/quickfix/MessageUtils.java +++ b/quickfixj-core/src/main/java/quickfix/MessageUtils.java @@ -90,9 +90,9 @@ private static String getFieldOrDefault(FieldMap fields, int tag, String default } } - public static Message parse(MessageFactory messageFactory, DataDictionary dataDictionary, + public static Message parse(MessageFactory messageFactory, DataDictionary dataDictionary, DataDictionarySettings dataDictionarySettings, String messageString) throws InvalidMessage { - return parse(messageFactory, dataDictionary, messageString, true); + return parse(messageFactory, dataDictionary, dataDictionarySettings, messageString, true); } /** @@ -105,7 +105,7 @@ public static Message parse(MessageFactory messageFactory, DataDictionary dataDi * @return the parsed message * @throws InvalidMessage */ - public static Message parse(MessageFactory messageFactory, DataDictionary dataDictionary, + public static Message parse(MessageFactory messageFactory, DataDictionary dataDictionary, DataDictionarySettings dataDictionarySettings, String messageString, boolean validateChecksum) throws InvalidMessage { final int index = messageString.indexOf(FIELD_SEPARATOR); if (index < 0) { @@ -114,7 +114,7 @@ public static Message parse(MessageFactory messageFactory, DataDictionary dataDi final String beginString = messageString.substring(2, index); final String messageType = getMessageType(messageString); final quickfix.Message message = messageFactory.create(beginString, messageType); - message.fromString(messageString, dataDictionary, dataDictionary != null, validateChecksum); + message.fromString(messageString, dataDictionary, dataDictionarySettings, dataDictionary != null, validateChecksum); return message; } @@ -141,6 +141,7 @@ public static Message parse(Session session, String messageString) throws Invali final MessageFactory messageFactory = session.getMessageFactory(); final DataDictionaryProvider ddProvider = session.getDataDictionaryProvider(); + final DataDictionarySettings dataDictionarySettings = session.getDataDictionarySettings(); final DataDictionary sessionDataDictionary = ddProvider == null ? null : ddProvider .getSessionDataDictionary(beginString); final DataDictionary applicationDataDictionary = ddProvider == null ? null : ddProvider @@ -154,7 +155,7 @@ public static Message parse(Session session, String messageString) throws Invali final boolean doValidation = payloadDictionary != null; final boolean validateChecksum = session.isValidateChecksum(); - message.parse(messageString, sessionDataDictionary, payloadDictionary, doValidation, + message.parse(messageString, sessionDataDictionary, payloadDictionary, dataDictionarySettings, doValidation, validateChecksum); return message; diff --git a/quickfixj-core/src/main/java/quickfix/Session.java b/quickfixj-core/src/main/java/quickfix/Session.java index ad8f9d91e7..ab1a4e773a 100644 --- a/quickfixj-core/src/main/java/quickfix/Session.java +++ b/quickfixj-core/src/main/java/quickfix/Session.java @@ -385,6 +385,7 @@ public class Session implements Closeable { private long lastSessionLogon = 0; private final DataDictionaryProvider dataDictionaryProvider; + private final DataDictionarySettings dataDictionarySettings; private final boolean checkLatency; private final int maxLatency; private int resendRequestChunkSize = 0; @@ -441,9 +442,10 @@ public class Session implements Closeable { Session(Application application, MessageStoreFactory messageStoreFactory, SessionID sessionID, - DataDictionaryProvider dataDictionaryProvider, SessionSchedule sessionSchedule, + DataDictionaryProvider dataDictionaryProvider, DataDictionarySettings dataDictionarySettings, + SessionSchedule sessionSchedule, LogFactory logFactory, MessageFactory messageFactory, int heartbeatInterval) { - this(application, messageStoreFactory, sessionID, dataDictionaryProvider, sessionSchedule, + this(application, messageStoreFactory, sessionID, dataDictionaryProvider, dataDictionarySettings, sessionSchedule, logFactory, messageFactory, heartbeatInterval, true, DEFAULT_MAX_LATENCY, UtcTimestampPrecision.MILLIS, false, false, false, false, true, false, true, false, DEFAULT_TEST_REQUEST_DELAY_MULTIPLIER, null, true, new int[] { 5 }, false, false, @@ -451,7 +453,8 @@ public class Session implements Closeable { } Session(Application application, MessageStoreFactory messageStoreFactory, SessionID sessionID, - DataDictionaryProvider dataDictionaryProvider, SessionSchedule sessionSchedule, + DataDictionaryProvider dataDictionaryProvider, DataDictionarySettings dataDictionarySettings, + SessionSchedule sessionSchedule, LogFactory logFactory, MessageFactory messageFactory, int heartbeatInterval, boolean checkLatency, int maxLatency, UtcTimestampPrecision timestampPrecision, boolean resetOnLogon, boolean resetOnLogout, boolean resetOnDisconnect, @@ -477,6 +480,7 @@ public class Session implements Closeable { this.timestampPrecision = timestampPrecision; this.refreshMessageStoreAtLogon = refreshMessageStoreAtLogon; this.dataDictionaryProvider = dataDictionaryProvider; + this.dataDictionarySettings = dataDictionarySettings; this.messageFactory = messageFactory; this.checkCompID = checkCompID; this.redundantResentRequestsAllowed = redundantResentRequestsAllowed; @@ -992,7 +996,7 @@ private void next(Message message, boolean isProcessingQueuedMessages) throws Fi // related to QFJ-367 : just warn invalid incoming field/tags try { DataDictionary.validate(message, sessionDataDictionary, - applicationDataDictionary); + applicationDataDictionary, dataDictionarySettings); } catch (final IncorrectTagValue e) { if (rejectInvalidMessage) { throw e; @@ -2704,6 +2708,10 @@ public DataDictionaryProvider getDataDictionaryProvider() { return dataDictionaryProvider; } + public DataDictionarySettings getDataDictionarySettings() { + return dataDictionarySettings; + } + public SessionID getSessionID() { return sessionID; } diff --git a/quickfixj-core/src/test/java/quickfix/DataDictionarySettingsTest.java b/quickfixj-core/src/test/java/quickfix/DataDictionarySettingsTest.java new file mode 100644 index 0000000000..e109f0540d --- /dev/null +++ b/quickfixj-core/src/test/java/quickfix/DataDictionarySettingsTest.java @@ -0,0 +1,26 @@ +package quickfix; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class DataDictionarySettingsTest { + @Test + public void copy() { + final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings(); + + dataDictionarySettings.setAllowUnknownMessageFields(true); + dataDictionarySettings.setCheckFieldsHaveValues(false); + dataDictionarySettings.setCheckFieldsOutOfOrder(false); + dataDictionarySettings.setCheckUnorderedGroupFields(false); + dataDictionarySettings.setCheckUserDefinedFields(false); + + DataDictionarySettings dataDictionarySettingsCopy = new DataDictionarySettings(dataDictionarySettings); + + assertEquals(dataDictionarySettingsCopy.isAllowUnknownMessageFields(),dataDictionarySettings.isAllowUnknownMessageFields()); + assertEquals(dataDictionarySettingsCopy.isCheckFieldsHaveValues(),dataDictionarySettings.isCheckFieldsHaveValues()); + assertEquals(dataDictionarySettingsCopy.isCheckFieldsOutOfOrder(),dataDictionarySettings.isCheckFieldsOutOfOrder()); + assertEquals(dataDictionarySettingsCopy.isCheckUnorderedGroupFields(),dataDictionarySettings.isCheckUnorderedGroupFields()); + assertEquals(dataDictionarySettingsCopy.isCheckUserDefinedFields(),dataDictionarySettings.isCheckUserDefinedFields()); + } +} diff --git a/quickfixj-core/src/test/java/quickfix/DataDictionaryTest.java b/quickfixj-core/src/test/java/quickfix/DataDictionaryTest.java index 117d908116..99afee442c 100644 --- a/quickfixj-core/src/test/java/quickfix/DataDictionaryTest.java +++ b/quickfixj-core/src/test/java/quickfix/DataDictionaryTest.java @@ -746,11 +746,11 @@ public void testMessageValidateBodyOnly() throws Exception { new ExpectedTestFailure(FieldException.class, "field=") { @Override protected void execute() throws Throwable { - dd.validate(newSingle); + dd.validate(newSingle, new DataDictionarySettings()); } }.run(); - dd.validate(newSingle, true); + dd.validate(newSingle, true, new DataDictionarySettings()); } @Test @@ -769,13 +769,13 @@ public void testMessageDataDictionaryMismatch() throws Exception { "Message version 'FIX.4.3' does not match the data dictionary version 'FIX.4.4'") { @Override protected void execute() throws Throwable { - dd.validate(newSingle); + dd.validate(newSingle, new DataDictionarySettings()); } }.run(); // TODO: This is unexpected for pre-FIX 5.0 messages: // If bodyOnly is true, the correct data dictionary is not checked. - dd.validate(newSingle, true); + dd.validate(newSingle, true, new DataDictionarySettings()); } // QF C++ treats the string argument as a filename although it's @@ -844,36 +844,38 @@ public void testAllowUnknownFields() throws Exception { newSingle.setField(new LastMkt("FOO")); final DataDictionary dictionary = new DataDictionary(getDictionary()); + final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings(); new ExpectedTestFailure(FieldException.class, "field=") { @Override protected void execute() throws Throwable { - dictionary.validate(newSingle); + dictionary.validate(newSingle, dataDictionarySettings); } }.run(); - dictionary.setAllowUnknownMessageFields(true); - dictionary.validate(newSingle); + dataDictionarySettings.setAllowUnknownMessageFields(true); + dictionary.validate(newSingle, dataDictionarySettings); } // QFJ-535 @Test public void testValidateFieldsOutOfOrderForGroups() throws Exception { final DataDictionary dictionary = new DataDictionary(getDictionary()); - dictionary.setCheckUnorderedGroupFields(false); + final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings(); + dataDictionarySettings.setCheckUnorderedGroupFields(false); Message messageWithGroupLevel1 = new Message( "8=FIX.4.4\0019=185\00135=D\00134=25\00149=SENDER\00156=TARGET\00152=20110412-13:43:00\001" + "60=20110412-13:43:00\0011=testAccount\00111=123\00121=3\00138=42\00140=2\00144=42.37\001" + "54=1\00155=QFJ\00159=0\00178=1\00179=allocAccount\001736=currency\001661=1\00110=130\001", - dictionary); - dictionary.validate(messageWithGroupLevel1); + dictionary, dataDictionarySettings); + dictionary.validate(messageWithGroupLevel1, dataDictionarySettings); Message messageWithGroupLevel2 = new Message( "8=FIX.4.4\0019=185\00135=D\00134=25\00149=SENDER\00156=TARGET\00152=20110412-13:43:00\001" + "60=20110412-13:43:00\0011=testAccount\00111=123\00121=3\00138=42\00140=2\00144=42.37\001" + "54=1\00155=QFJ\00159=0\00178=1\00179=allocAccount\001539=1\001524=1\001538=1\001525=a\00110=145\001", - dictionary); - dictionary.validate(messageWithGroupLevel2); + dictionary, dataDictionarySettings); + dictionary.validate(messageWithGroupLevel2, dataDictionarySettings); } // QFJ-535 @@ -881,7 +883,8 @@ public void testValidateFieldsOutOfOrderForGroups() throws Exception { public void testNewOrderSingleWithCorrectTag50() throws Exception { final DataDictionary dataDictionary = new DataDictionary(getDictionary()); - dataDictionary.setCheckFieldsOutOfOrder(true); + final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings(); + dataDictionarySettings.setCheckFieldsOutOfOrder(true); String correctFixMessage = "8=FIX.4.4\0019=218\00135=D\00149=cust\00150=trader\001" + "56=FixGateway\00134=449\00152=20110420-09:17:40\00111=clordid\00154=1\00138=50\001" + @@ -891,28 +894,28 @@ public void testNewOrderSingleWithCorrectTag50() throws Exception { // in any case, it must be validated as the message is correct //doValidation and checkFieldsOutOfOrder final NewOrderSingle nos1 = new NewOrderSingle(); - nos1.fromString(correctFixMessage, dataDictionary, true); - dataDictionary.validate(nos1); + nos1.fromString(correctFixMessage, dataDictionary, dataDictionarySettings, true); + dataDictionary.validate(nos1, dataDictionarySettings); assertTrue(nos1.getHeader().isSetField(new SenderSubID())); //doNotValidation and checkFieldsOutOfOrder final NewOrderSingle nos2 = new NewOrderSingle(); - nos2.fromString(correctFixMessage, dataDictionary, false); - dataDictionary.validate(nos2); + nos2.fromString(correctFixMessage, dataDictionary, dataDictionarySettings, false); + dataDictionary.validate(nos2, dataDictionarySettings); assertTrue(nos2.getHeader().isSetField(new SenderSubID())); - dataDictionary.setCheckFieldsOutOfOrder(false); + dataDictionarySettings.setCheckFieldsOutOfOrder(false); //doValidation and no checkFieldsOutOfOrder final NewOrderSingle nos3 = new NewOrderSingle(); - nos3.fromString(correctFixMessage, dataDictionary, true); - dataDictionary.validate(nos3); + nos3.fromString(correctFixMessage, dataDictionary, dataDictionarySettings, true); + dataDictionary.validate(nos3, dataDictionarySettings); assertTrue(nos3.getHeader().isSetField(new SenderSubID())); //doNotValidation and no checkFieldsOutOfOrder final NewOrderSingle nos4 = new NewOrderSingle(); - nos4.fromString(correctFixMessage, dataDictionary, false); - dataDictionary.validate(nos4); + nos4.fromString(correctFixMessage, dataDictionary, dataDictionarySettings, false); + dataDictionary.validate(nos4, dataDictionarySettings); assertTrue(nos4.getHeader().isSetField(new SenderSubID())); } @@ -920,7 +923,8 @@ public void testNewOrderSingleWithCorrectTag50() throws Exception { public void testNewOrderSingleWithMisplacedTag50() throws Exception { final DataDictionary dataDictionary = new DataDictionary(getDictionary()); - dataDictionary.setCheckFieldsOutOfOrder(true); + final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings(); + dataDictionarySettings.setCheckFieldsOutOfOrder(true); String incorrectFixMessage = "8=FIX.4.4\0019=218\00135=D\00149=cust\00156=FixGateway\001" + "34=449\00152=20110420-09:17:40\00111=clordid\00154=1\00138=50\00159=6\00140=2\001" + @@ -930,62 +934,32 @@ public void testNewOrderSingleWithMisplacedTag50() throws Exception { //doValidation and checkFieldsOutOfOrder -> should fail final NewOrderSingle nos1 = new NewOrderSingle(); try { - nos1.fromString(incorrectFixMessage, dataDictionary, true); + nos1.fromString(incorrectFixMessage, dataDictionary, dataDictionarySettings, true); } catch (FieldException fe) { // expected exception } //doNotValidation and checkFieldsOutOfOrder -> should NOT fail final NewOrderSingle nos2 = new NewOrderSingle(); - nos2.fromString(incorrectFixMessage, dataDictionary, false); - dataDictionary.validate(nos2); + nos2.fromString(incorrectFixMessage, dataDictionary, dataDictionarySettings, false); + dataDictionary.validate(nos2, dataDictionarySettings); assertTrue(nos2.getHeader().isSetField(new SenderSubID())); - dataDictionary.setCheckFieldsOutOfOrder(false); + dataDictionarySettings.setCheckFieldsOutOfOrder(false); //doValidation and no checkFieldsOutOfOrder -> should NOT fail final NewOrderSingle nos3 = new NewOrderSingle(); - nos3.fromString(incorrectFixMessage, dataDictionary, true); - dataDictionary.validate(nos3); + nos3.fromString(incorrectFixMessage, dataDictionary, dataDictionarySettings, true); + dataDictionary.validate(nos3, dataDictionarySettings); assertTrue(nos3.getHeader().isSetField(new SenderSubID())); //doNotValidation and no checkFieldsOutOfOrder -> should NOT fail final NewOrderSingle nos4 = new NewOrderSingle(); - nos4.fromString(incorrectFixMessage, dataDictionary, false); - dataDictionary.validate(nos4); + nos4.fromString(incorrectFixMessage, dataDictionary, dataDictionarySettings, false); + dataDictionary.validate(nos4, dataDictionarySettings); assertTrue(nos4.getHeader().isSetField(new SenderSubID())); } - @Test - public void testCopy() throws Exception { - final DataDictionary dataDictionary = new DataDictionary(getDictionary()); - - dataDictionary.setAllowUnknownMessageFields(true); - dataDictionary.setCheckFieldsHaveValues(false); - dataDictionary.setCheckFieldsOutOfOrder(false); - dataDictionary.setCheckUnorderedGroupFields(false); - dataDictionary.setCheckUserDefinedFields(false); - - DataDictionary ddCopy = new DataDictionary(dataDictionary); - - assertEquals(ddCopy.isAllowUnknownMessageFields(),dataDictionary.isAllowUnknownMessageFields()); - assertEquals(ddCopy.isCheckFieldsHaveValues(),dataDictionary.isCheckFieldsHaveValues()); - assertEquals(ddCopy.isCheckFieldsOutOfOrder(),dataDictionary.isCheckFieldsOutOfOrder()); - assertEquals(ddCopy.isCheckUnorderedGroupFields(),dataDictionary.isCheckUnorderedGroupFields()); - assertEquals(ddCopy.isCheckUserDefinedFields(),dataDictionary.isCheckUserDefinedFields()); - - DataDictionary.GroupInfo groupFromDDCopy = ddCopy.getGroup(NewOrderSingle.MSGTYPE, NoPartyIDs.FIELD); - assertTrue(groupFromDDCopy.getDataDictionary().isAllowUnknownMessageFields()); - // set to false on ORIGINAL DD - dataDictionary.setAllowUnknownMessageFields(false); - assertFalse(dataDictionary.isAllowUnknownMessageFields()); - assertFalse(dataDictionary.getGroup(NewOrderSingle.MSGTYPE, NoPartyIDs.FIELD).getDataDictionary().isAllowUnknownMessageFields()); - // should be still true on COPIED DD and its group - assertTrue(ddCopy.isAllowUnknownMessageFields()); - groupFromDDCopy = ddCopy.getGroup(NewOrderSingle.MSGTYPE, NoPartyIDs.FIELD); - assertTrue(groupFromDDCopy.getDataDictionary().isAllowUnknownMessageFields()); - } - /** *
      * +---------------------------+------------------------+-------+------------+
@@ -1004,12 +978,13 @@ public void testNonUDFDefinedInFieldsSectionDontAllowUMFDontCheckUDF() throws Ex
         quoteRequest.setDecimal(AvgPx.FIELD, new BigDecimal(1.2345));
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Tag not defined for this message type, field=6");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1018,12 +993,13 @@ public void testNonUDFDefinedInFieldsSectionDontAllowUMFCheckUDF() throws Except
         quoteRequest.setDecimal(AvgPx.FIELD, new BigDecimal(1.2345));
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Tag not defined for this message type, field=6");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1032,10 +1008,11 @@ public void testNonUDFDefinedInFieldsSectionAllowUMFDontCheckUDF() throws Except
         quoteRequest.setDecimal(AvgPx.FIELD, new BigDecimal(1.2345));
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1044,10 +1021,11 @@ public void testNonUDFDefinedInFieldsSectionAllowUMFCheckUDF() throws Exception
         quoteRequest.setDecimal(AvgPx.FIELD, new BigDecimal(1.2345));
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     /**
@@ -1068,10 +1046,11 @@ public void testUDFDefinedInFieldsSectionDontAllowUMFDontCheckUDF() throws Excep
         quoteRequest.setInt(5000, 555);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1080,12 +1059,13 @@ public void testUDFDefinedInFieldsSectionDontAllowUMFCheckUDF() throws Exception
         quoteRequest.setInt(5000, 555);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Tag not defined for this message type, field=5000");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1094,10 +1074,11 @@ public void testUDFDefinedInFieldsSectionAllowUMFDontCheckUDF() throws Exception
         quoteRequest.setInt(5000, 555);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1106,12 +1087,13 @@ public void testUDFDefinedInFieldsSectionAllowUMFCheckUDF() throws Exception {
         quoteRequest.setInt(5000, 555);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Tag not defined for this message type, field=5000");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     /**
@@ -1132,12 +1114,13 @@ public void testNonUDFNotDefinedInFieldsSectionDontAllowUMFDontCheckUDF() throws
         quoteRequest.setInt(1000, 111);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Invalid tag number, field=1000");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1146,12 +1129,13 @@ public void testNonUDFNotDefinedInFieldsSectionDontAllowUMFCheckUDF() throws Exc
         quoteRequest.setInt(1000, 111);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Invalid tag number, field=1000");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1160,10 +1144,11 @@ public void testNonUDFNotDefinedInFieldsSectionAllowUMFDontCheckUDF() throws Exc
         quoteRequest.setInt(1000, 111);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1172,10 +1157,11 @@ public void testNonUDFNotDefinedInFieldsSectionAllowUMFCheckUDF() throws Excepti
         quoteRequest.setInt(1000, 111);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     /**
@@ -1196,10 +1182,11 @@ public void testUDFNotDefinedInFieldsSectionDontAllowUMFDontCheckUDF() throws Ex
         quoteRequest.setInt(6000, 666);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1208,12 +1195,13 @@ public void testUDFNotDefinedInFieldsSectionDontAllowUMFCheckUDF() throws Except
         quoteRequest.setInt(6000, 666);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(false);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Invalid tag number, field=6000");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1222,10 +1210,11 @@ public void testUDFNotDefinedInFieldsSectionAllowUMFDontCheckUDF() throws Except
         quoteRequest.setInt(6000, 666);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     @Test
@@ -1234,12 +1223,13 @@ public void testUDFNotDefinedInFieldsSectionAllowUMFCheckUDF() throws Exception
         quoteRequest.setInt(6000, 666);
 
         DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setAllowUnknownMessageFields(true);
-        dataDictionary.setCheckUserDefinedFields(true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(true);
+        dataDictionarySettings.setCheckUserDefinedFields(true);
 
         expectedException.expect(FieldException.class);
         expectedException.expectMessage("Invalid tag number, field=6000");
-        dataDictionary.validate(quoteRequest, true);
+        dataDictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     private Message createQuoteRequest() {
@@ -1268,12 +1258,13 @@ public void testGroupWithReqdComponentWithReqdFieldValidation() throws Exception
         final Message quoteRequest = createQuoteRequest();
         quoteRequest.getGroup(1, NoRelatedSym.FIELD).removeField(Symbol.FIELD);
         final DataDictionary dictionary = getDictionary();
+        final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
 
         expectedException.expect(FieldException.class);
         expectedException.expect(hasProperty("sessionRejectReason", is(SessionRejectReason.REQUIRED_TAG_MISSING)));
         expectedException.expect(hasProperty("field", is(Symbol.FIELD)));
 
-        dictionary.validate(quoteRequest, true);
+        dictionary.validate(quoteRequest, true, dataDictionarySettings);
     }
 
     /**
@@ -1284,7 +1275,8 @@ public void testGroupWithReqdComponentWithReqdFieldValidation() throws Exception
     @Test
     public void testAllowingBlankValuesDisablesFieldValidation() throws Exception {
         final DataDictionary dictionary = getDictionary();
-        dictionary.setCheckFieldsHaveValues(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setCheckFieldsHaveValues(false);
         final quickfix.fix44.NewOrderSingle newSingle = new quickfix.fix44.NewOrderSingle(
                 new ClOrdID("123"), new Side(Side.BUY), new TransactTime(), new OrdType(OrdType.LIMIT)
         );
@@ -1296,7 +1288,7 @@ public void testAllowingBlankValuesDisablesFieldValidation() throws Exception {
         newSingle.setField(new TimeInForce(TimeInForce.DAY));
         newSingle.setField(new Account("testAccount"));
         newSingle.setField(new StringField(EffectiveTime.FIELD));
-        dictionary.validate(newSingle, true);
+        dictionary.validate(newSingle, true, dataDictionarySettings);
     }
 
     //
diff --git a/quickfixj-core/src/test/java/quickfix/FieldTest.java b/quickfixj-core/src/test/java/quickfix/FieldTest.java
index 3bc5202361..dc46ab8df4 100644
--- a/quickfixj-core/src/test/java/quickfix/FieldTest.java
+++ b/quickfixj-core/src/test/java/quickfix/FieldTest.java
@@ -272,7 +272,7 @@ public void testMultipleStringValue() throws Exception {
         md.addGroup(value);
 
         DataDictionary dd = new DataDictionary("FIX50.xml");
-        dd.validate(md);
+        dd.validate(md, new DataDictionarySettings());
     }
 
     private void assertEqualsAndHash(Field field1, Field field2) {
diff --git a/quickfixj-core/src/test/java/quickfix/FileLogTest.java b/quickfixj-core/src/test/java/quickfix/FileLogTest.java
index 15dd38d6c5..a4f7bb3661 100644
--- a/quickfixj-core/src/test/java/quickfix/FileLogTest.java
+++ b/quickfixj-core/src/test/java/quickfix/FileLogTest.java
@@ -209,7 +209,7 @@ public void testLogErrorWhenFilesystemRemoved() throws IOException {
         FileLogFactory factory = new FileLogFactory(settings);
 
         try (Session session = new Session(new UnitTestApplication(), new MemoryStoreFactory(),
-                sessionID, new DefaultDataDictionaryProvider(), null, factory,
+                sessionID, new DefaultDataDictionaryProvider(), new DataDictionarySettings(), null, factory,
                 new DefaultMessageFactory(), 0)) {
             Session.registerSession(session);
             
diff --git a/quickfixj-core/src/test/java/quickfix/JdbcLogTest.java b/quickfixj-core/src/test/java/quickfix/JdbcLogTest.java
index 9c1d5147b2..f0fc7252e2 100644
--- a/quickfixj-core/src/test/java/quickfix/JdbcLogTest.java
+++ b/quickfixj-core/src/test/java/quickfix/JdbcLogTest.java
@@ -101,7 +101,7 @@ public void testHandlesRecursivelyFailingException() throws Exception {
 
         // need to register the session since we are going to log errors through LogUtil
         Session.registerSession(new Session(new UnitTestApplication(), new MemoryStoreFactory(),
-                sessionID, new DefaultDataDictionaryProvider(), null, logFactory,
+                sessionID, new DefaultDataDictionaryProvider(), new DataDictionarySettings(), null, logFactory,
                 new DefaultMessageFactory(), 0));
 
         // remove the messages and events tables
diff --git a/quickfixj-core/src/test/java/quickfix/LogUtilTest.java b/quickfixj-core/src/test/java/quickfix/LogUtilTest.java
index f533c7c042..7bc0ea0995 100644
--- a/quickfixj-core/src/test/java/quickfix/LogUtilTest.java
+++ b/quickfixj-core/src/test/java/quickfix/LogUtilTest.java
@@ -68,7 +68,7 @@ public Date getCreationTime() throws IOException {
                 // ignore
                 return null;
             }
-        }, sessionID, null, schedule, mockLogFactory, null, 0);
+        }, sessionID, null, null, schedule, mockLogFactory, null, 0);
         try {
             session.close();
         } catch (IOException e) {
diff --git a/quickfixj-core/src/test/java/quickfix/MessageTest.java b/quickfixj-core/src/test/java/quickfix/MessageTest.java
index a9e5c60c44..c7a217be8d 100644
--- a/quickfixj-core/src/test/java/quickfix/MessageTest.java
+++ b/quickfixj-core/src/test/java/quickfix/MessageTest.java
@@ -192,15 +192,14 @@ public MyMessage() {
     
     @Test
     public void testHeaderFieldWithCustomTransportDictionaryConstructorReadsHeaderField() throws Exception {
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setAllowUnknownMessageFields(false);
 
         final DataDictionary customSessionDictionary = new DataDictionary("FIXT11_Custom_Test.xml");
-        customSessionDictionary.setAllowUnknownMessageFields(false);
 
         final DataDictionary standardSessionDictionary = new DataDictionary("FIXT11.xml");
-        standardSessionDictionary.setAllowUnknownMessageFields(false);
 
         final DataDictionary applicationDictionary = new DataDictionary("FIX50.xml");
-        applicationDictionary.setAllowUnknownMessageFields(false);
 
         final String sep = "\001";
         final StringBuilder sb = new StringBuilder();
@@ -234,7 +233,7 @@ public void testHeaderFieldWithCustomTransportDictionaryConstructorReadsHeaderFi
         sb.append(sep);
         final String messageData = sb.toString();
 
-        final Message standardMessage = new Message(messageData, standardSessionDictionary, applicationDictionary, true);
+        final Message standardMessage = new Message(messageData, standardSessionDictionary, applicationDictionary, dataDictionarySettings, true);
 
         // Test that field is in body not the header
         assertTrue(standardMessage.toString().contains("12312=foo"));
@@ -243,7 +242,7 @@ public void testHeaderFieldWithCustomTransportDictionaryConstructorReadsHeaderFi
         assertEquals("foo", standardMessage.getString(12312));
 
         // Test that field is correctly classified in header with customSessionDictionary
-        final Message customMessage = new Message(messageData, customSessionDictionary, applicationDictionary, true);
+        final Message customMessage = new Message(messageData, customSessionDictionary, applicationDictionary, dataDictionarySettings, true);
         assertTrue(customMessage.toString().contains("12312=foo"));
         assertTrue(customMessage.getHeader().isSetField(12312));
         assertEquals("foo", customMessage.getHeader().getString(12312));
@@ -275,7 +274,7 @@ public void testHeaderGroupParsing() throws Exception {
         final Message message = new Message("8=FIX.4.2\0019=40\00135=A\001"
                 + "627=2\001628=FOO\001628=BAR\001"
                 + "98=0\001384=2\001372=D\001385=R\001372=8\001385=S\00110=228\001",
-                DataDictionaryTest.getDictionary());
+                DataDictionaryTest.getDictionary(), new DataDictionarySettings());
 
         final quickfix.fix44.Message.Header.NoHops hops = new quickfix.fix44.Message.Header.NoHops();
         message.getHeader().getGroup(1, hops);
@@ -296,7 +295,7 @@ public void testEmbeddedMessage() throws Exception {
         report.set(new EncodedTextLen(text.length()));
         report.set(new EncodedText(text));
 
-        final Message msg = new Message(report.toString(), DataDictionaryTest.getDictionary());
+        final Message msg = new Message(report.toString(), DataDictionaryTest.getDictionary(), new DataDictionarySettings());
         assertEquals("embedded order", text, msg.getString(EncodedText.FIELD));
     }
 
@@ -306,7 +305,7 @@ private void doTestMessageWithEncodedField(String charset, String text) throws E
             NewOrderSingle order = createNewOrderSingle();
             order.set(new EncodedTextLen(MessageUtils.length(CharsetSupport.getCharsetInstance(), text)));
             order.set(new EncodedText(text));
-            final Message msg = new Message(order.toString(), DataDictionaryTest.getDictionary());
+            final Message msg = new Message(order.toString(), DataDictionaryTest.getDictionary(), new DataDictionarySettings());
             assertEquals(charset + " encoded field", text, msg.getString(EncodedText.FIELD));
         } finally {
             CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());
@@ -330,7 +329,7 @@ public void testParsing() throws Exception {
         // checksum is not verified in these tests
         final Message message = new Message("8=FIX.4.2\0019=40\00135=A\001"
                 + "98=0\001384=2\001372=D\001385=R\001372=8\001385=S\00110=96\001",
-                DataDictionaryTest.getDictionary());
+                DataDictionaryTest.getDictionary(), new DataDictionarySettings());
 
         assertHeaderField(message, "FIX.4.2", BeginString.FIELD);
         assertHeaderField(message, "40", BodyLength.FIELD);
@@ -362,7 +361,7 @@ public void testParsing2() throws Exception {
         data += "311=IBM\001";
         data += "318=CAD\001";
         data += "10=037\001";
-        final Message message = new Message(data, DataDictionaryTest.getDictionary());
+        final Message message = new Message(data, DataDictionaryTest.getDictionary(), new DataDictionarySettings());
 
         assertHeaderField(message, "FIX.4.2", BeginString.FIELD);
         assertHeaderField(message, "76", BodyLength.FIELD);
@@ -384,7 +383,7 @@ public void testParseEmptyString() throws Exception {
 
         // with validation
         try {
-            new Message(data, DataDictionaryTest.getDictionary());
+            new Message(data, DataDictionaryTest.getDictionary(), new DataDictionarySettings());
         } catch (final InvalidMessage im) {
         } catch (final Throwable e) {
             e.printStackTrace();
@@ -393,7 +392,7 @@ public void testParseEmptyString() throws Exception {
 
         // without validation
         try {
-            new Message(data, DataDictionaryTest.getDictionary(), false);
+            new Message(data, DataDictionaryTest.getDictionary(), new DataDictionarySettings(), false);
         } catch (final InvalidMessage im) {
         } catch (final Throwable e) {
             e.printStackTrace();
@@ -412,8 +411,8 @@ public void testValidation() throws Exception {
         final ExecutionReport executionReport = new ExecutionReport();
         final DataDictionary dictionary = DataDictionaryTest.getDictionary();
         assertNotNull(dictionary);
-        executionReport.fromString(data, dictionary, true);
-        dictionary.validate(executionReport);
+        executionReport.fromString(data, dictionary, new DataDictionarySettings(), true);
+        dictionary.validate(executionReport, new DataDictionarySettings());
     }
 
     @Test
@@ -436,12 +435,12 @@ public void testParseTwice() throws Exception {
         final ExecutionReport executionReport = new ExecutionReport();
 
         assertNotNull(dictionary);
-        executionReport.fromString(data1, dictionary, true);
-        dictionary.validate(executionReport);
+        executionReport.fromString(data1, dictionary, new DataDictionarySettings(), true);
+        dictionary.validate(executionReport, new DataDictionarySettings());
 
         executionReport.clear();
-        executionReport.fromString(data2, dictionary, true);
-        dictionary.validate(executionReport);
+        executionReport.fromString(data2, dictionary, new DataDictionarySettings(), true);
+        dictionary.validate(executionReport, new DataDictionarySettings());
     }
 
     @Test
@@ -456,12 +455,12 @@ public void testValidationWithHops() throws Exception {
         final DataDictionary dictionary = DataDictionaryTest.getDictionary();
         assertNotNull(dictionary);
 
-        executionReport.fromString(data, dictionary, true);
+        executionReport.fromString(data, dictionary, new DataDictionarySettings(), true);
         final Header.NoHops hops = new Header.NoHops();
         hops.set(new HopCompID("FOO"));
         executionReport.header.addGroup(hops);
 
-        dictionary.validate(executionReport);
+        dictionary.validate(executionReport, new DataDictionarySettings());
     }
 
     @Test
@@ -474,8 +473,8 @@ public void testAppMessageValidation() throws Exception {
         final DataDictionary appDictionary = DataDictionaryTest.getDictionary("FIX50.xml");
         assertNotNull(sessDictionary);
         assertNotNull(appDictionary);
-        mdsfr.fromString(data, sessDictionary, appDictionary, true);
-        DataDictionary.validate(mdsfr, sessDictionary, appDictionary);
+        mdsfr.fromString(data, sessDictionary, appDictionary, new DataDictionarySettings(), true);
+        DataDictionary.validate(mdsfr, sessDictionary, appDictionary, new DataDictionarySettings());
     }
 
     @Test
@@ -487,8 +486,8 @@ public void testAdminMessageValidation() throws Exception {
         final DataDictionary appDictionary = DataDictionaryTest.getDictionary("FIX50.xml");
         assertNotNull(sessionDictionary);
         assertNotNull(appDictionary);
-        logon.fromString(data, sessionDictionary, appDictionary, true);
-        DataDictionary.validate(logon, sessionDictionary, sessionDictionary);
+        logon.fromString(data, sessionDictionary, appDictionary, new DataDictionarySettings(), true);
+        DataDictionary.validate(logon, sessionDictionary, sessionDictionary, new DataDictionarySettings());
     }
 
     @Test
@@ -538,7 +537,7 @@ public void testComponentGroupInsertion() throws Exception {
     public void testHeaderDataField() throws Exception {
         final Message m = new Message("8=FIX.4.2\0019=53\00135=A\00190=4\00191=ABCD\001"
                 + "98=0\001384=2\001372=D\001385=R\001372=8\001385=S\00110=241\001",
-                DataDictionaryTest.getDictionary());
+                DataDictionaryTest.getDictionary(), new DataDictionarySettings());
         assertEquals("ABCD", m.getHeader().getString(SecureData.FIELD));
     }
 
@@ -553,7 +552,7 @@ public void testInvalidFirstFieldInGroup() throws Exception {
         news.addGroup(relatedSym);
 
         try {
-            new Message(news.toString(), DataDictionaryTest.getDictionary());
+            new Message(news.toString(), DataDictionaryTest.getDictionary(), new DataDictionarySettings());
         } catch (final InvalidMessage e) {
             // expected
         } catch (final NullPointerException e) {
@@ -567,7 +566,7 @@ public void testRequiredGroupValidation() throws Exception {
         news.set(new Headline("Test"));
         final DataDictionary dictionary = DataDictionaryTest.getDictionary();
         try {
-            dictionary.validate(news);
+            dictionary.validate(news, new DataDictionarySettings());
             fail("no field exception for missing lines group");
         } catch (final FieldException e) {
             // expected
@@ -599,9 +598,9 @@ public void testDataFieldParsing() throws Exception {
             final DataDictionary dictionary = DataDictionaryTest.getDictionary();
             final Message m = new Message(("8=FIX.4.4\0019=1144\00135=A\001"
                     + "98=0\001384=2\001372=D\001385=R\001372=8\001385=S\00195=1092\001" + "96="
-                    + data + "\00110=5\001"), dictionary);
+                    + data + "\00110=5\001"), dictionary, new DataDictionarySettings());
             assertEquals(1144, m.bodyLength());
-            final Message m2 = new Message(m.toString(), dictionary);
+            final Message m2 = new Message(m.toString(), dictionary, new DataDictionarySettings());
             assertEquals(1144, m2.bodyLength());
         } catch (final InvalidMessage e) {
             fail(e.getMessage());
@@ -638,7 +637,7 @@ public void testDataFieldWithManualFieldInsertion() throws Exception {
             m.setInt(RawDataLength.FIELD, data.length());
             m.setString(RawData.FIELD, data);
             assertEquals(1108 + msgType.getValue().length(), m.bodyLength());
-            final Message m2 = new Message(m.toString(), dictionary);
+            final Message m2 = new Message(m.toString(), dictionary, new DataDictionarySettings());
             assertEquals(m.bodyLength(), m2.bodyLength());
         } catch (final InvalidMessage e) {
             fail(e.getMessage());
@@ -728,7 +727,7 @@ public void testFieldOrdering() throws Exception {
         final DataDictionary dataDictionary = new DataDictionary("FIX44.xml");
         final Message message = new DefaultMessageFactory()
                 .create(dataDictionary.getVersion(), "D");
-        message.fromString(expectedMessageString, dataDictionary, false);
+        message.fromString(expectedMessageString, dataDictionary, new DataDictionarySettings(), false);
         final String actualMessageString = message.toString();
         assertTrue(
                 "wrong field ordering",
@@ -748,7 +747,7 @@ public void testHeaderFieldsMissing() throws Exception {
     public void testHeaderFieldInBody() throws Exception {
         final Message message = new Message("8=FIX.4.2\0019=40\00135=A\001"
                 + "98=0\001212=4\001384=2\001372=D\001385=R\001372=8\001385=S\00110=103\001",
-                DataDictionaryTest.getDictionary());
+                DataDictionaryTest.getDictionary(), new DataDictionarySettings());
 
         assertFalse(message.hasValidStructure());
 
@@ -763,7 +762,7 @@ public void testHeaderFieldInBody() throws Exception {
     public void testTrailerFieldInBody() throws Exception {
         final Message message = new Message("8=FIX.4.2\0019=40\00135=A\001"
                 + "98=0\00193=5\001384=2\001372=D\001385=R\001372=8\001385=S\00110=63\001",
-                DataDictionaryTest.getDictionary());
+                DataDictionaryTest.getDictionary(), new DataDictionarySettings());
 
         assertFalse(message.hasValidStructure());
 
@@ -809,9 +808,9 @@ public void testMessageGroupCountValidation() throws Exception {
             "79=AllocACC2\00180=2020.2\001453=2\001448=8\001447=D\001452=4\001448=AAA35354\001447=D\001452=3\00110=079\001";
         final Message message = new Message();
         final DataDictionary dd = DataDictionaryTest.getDictionary();
-        message.fromString(data, dd, true);
+        message.fromString(data, dd, new DataDictionarySettings(), true);
         try {
-            dd.validate(message);
+            dd.validate(message, new DataDictionarySettings());
             fail("No exception thrown");
         } catch (final FieldException e) {
             final String emsg = e.getMessage();
@@ -834,7 +833,7 @@ public void testMessageWithMissingChecksumField() throws Exception {
 
         Message msg = new Message();
         try {
-            msg.fromString(badMessage, DataDictionaryTest.getDictionary(), true);
+            msg.fromString(badMessage, DataDictionaryTest.getDictionary(), new DataDictionarySettings(), true);
             fail();
         } catch (final InvalidMessage e) {
             final String emsg = e.getMessage();
@@ -1294,7 +1293,7 @@ public void testFalseMessageStructureException() {
             final DataDictionary dd = DataDictionaryTest.getDictionary();
             // duplicated tag 98
             // QFJ-65
-            new Message("8=FIX.4.4\0019=22\00135=A\00198=0\00198=0\001108=30\00110=223\001", dd,
+            new Message("8=FIX.4.4\0019=22\00135=A\00198=0\00198=0\001108=30\00110=223\001", dd, new DataDictionarySettings(),
                     true);
             // For now, this will not cause an exception if the length and checksum are correct
         } catch (final Exception e) {
@@ -1339,7 +1338,7 @@ public void testComponentInGroup() {
                 "525=D\001538=51\001524=FCM\001525=D\001538=60 524=U\001525=D\001538=54\001600=217927\001" +
                 "602=BRN FMG0010!\00163=8 608-FXXXXX\001624=1\001637=80.09\001687=1.0\001654=41296073\001" +
                 "9019=1\0019023=1\0019020=20100201\001021=20100228\001",
-                dd, true);
+                dd, new DataDictionarySettings(), true);
             // For now, this will not cause an exception if the length and checksum are correct
         } catch (final Exception e) {
             final String text = e.getMessage();
@@ -1353,7 +1352,7 @@ public void testFalseMessageStructureException2() {
             final DataDictionary dd = DataDictionaryTest.getDictionary();
             // duplicated raw data length
             // QFJ-121
-            new Message("8=FIX.4.4\0019=22\00135=A\00196=X\001108=30\00110=223\001", dd, true);
+            new Message("8=FIX.4.4\0019=22\00135=A\00196=X\001108=30\00110=223\001", dd, new DataDictionarySettings(), true);
         } catch (final Exception e) {
             final String text = e.getMessage();
             assertTrue("Wrong exception message: " + text,
@@ -1372,7 +1371,7 @@ public void testFieldWithEqualsCharacter() {
                 "269=0\001270=1.38854\001271=2000000\001269=1\001270=1.38855\001271=6000000\001" +
                 "269=1\001270=1.38856\001271=7000000\001269=1\001270=1.38857\001271=3000000\001" +
                 "269=1\001270=1.38858\001271=9000000\001269=1\001270=1.38859\001271=100000000\00110=51\001",
-                dd, true);
+                dd, new DataDictionarySettings(), true);
             assertEquals(m.getString(461), "RCSXX=0");
             final MarketDataSnapshotFullRefresh.NoMDEntries group = new MarketDataSnapshotFullRefresh.NoMDEntries();
             m.getGroup(1, group);
@@ -1397,7 +1396,7 @@ public void testMiscFeeType() {
                 "269=0\001270=1.38854\001271=2000000\001269=1\001270=1.38855\001271=6000000\001" +
                 "269=1\001270=1.38856\001271=7000000\001269=1\001270=1.38857\001271=3000000\001" +
                 "269=1\001270=1.38858\001271=9000000\001269=1\001270=1.38859\001271=100000000\00110=51\001",
-                dd, true);
+                dd, new DataDictionarySettings(), true);
             assertEquals(m.getString(461), "RCSXX=0");
             final MarketDataSnapshotFullRefresh.NoMDEntries group = new MarketDataSnapshotFullRefresh.NoMDEntries();
             m.getGroup(1, group);
@@ -1478,7 +1477,7 @@ public void testRepeatingGroupCount() throws Exception {
             m1.addGroup(leg2);
 
             String s1 = m1.toString();
-            Message parsed1 = new Message(s1, DataDictionaryTest.getDictionary());
+            Message parsed1 = new Message(s1, DataDictionaryTest.getDictionary(), new DataDictionarySettings());
 
             assertEquals(s1, parsed1.toString());
             assertEquals(2, parsed1.getGroupCount(555));
@@ -1501,8 +1500,8 @@ public void testRepeatingGroupCount() throws Exception {
             String s2 = m2.toString();
             // do not use validation to parse full message
             // regardless of errors in message structure
-            Message parsed2 = new Message(s2, DataDictionaryTest.getDictionary(), false);
-            
+            Message parsed2 = new Message(s2, DataDictionaryTest.getDictionary(), new DataDictionarySettings(), false);
+
             assertEquals(s2, parsed2.toString());
             assertEquals(2, parsed2.getGroupCount(555));
 
@@ -1552,22 +1551,23 @@ public void testUnknownFieldsInRepeatingGroupsAndValidation() throws Exception {
             m1.addGroup(sides);
 
             String s1 = m1.toString();
+            DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
             DataDictionary dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
             // parsing without validation should succeed
-            Message parsed1 = new Message(s1, dictionary, false);
+            Message parsed1 = new Message(s1, dictionary, dataDictionarySettings,false);
 
             // validation should fail
             int failingTag = 0;
             try {
-                dictionary.validate(parsed1);
+                dictionary.validate(parsed1, dataDictionarySettings);
             } catch (FieldException e) {
                 failingTag = e.getField();
             }
             assertEquals(10000, failingTag);
 
             // but without checking user-defined fields, validation should succeed
-            dictionary.setCheckUserDefinedFields(false);
-            dictionary.validate(parsed1);
+            dataDictionarySettings.setCheckUserDefinedFields(false);
+            dictionary.validate(parsed1, dataDictionarySettings);
 
             assertEquals(s1, parsed1.toString());
             assertEquals(2, parsed1.getGroupCount(555));
@@ -1589,20 +1589,21 @@ public void testUnknownFieldsInRepeatingGroupsAndValidation() throws Exception {
             String s2 = m2.toString();
             DataDictionary dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
             // parsing without validation should succeed
-            Message parsed2 = new Message(s2, dictionary, false);
+            Message parsed2 = new Message(s2, dictionary, new DataDictionarySettings(), false);
 
             // validation should fail
             int failingTag = 0;
             try {
-                dictionary.validate(parsed2);
+                dictionary.validate(parsed2, new DataDictionarySettings());
             } catch (FieldException e) {
                 failingTag = e.getField();
             }
             assertEquals(Text.FIELD, failingTag);
             
             // but without checking for unknown message fields, validation should succeed
-            dictionary.setAllowUnknownMessageFields(true);
-            dictionary.validate(parsed2);
+            DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+            dataDictionarySettings.setAllowUnknownMessageFields(true);
+            dictionary.validate(parsed2, dataDictionarySettings);
 
             assertEquals(s2, parsed2.toString());
             assertEquals(2, parsed2.getGroupCount(555));
@@ -1640,10 +1641,11 @@ public void testInvalidFieldInGroup() throws Exception {
         responseMessage.setField(resultCode);
 
         DataDictionary dd = new DataDictionary(DataDictionaryTest.getDictionary());
-        
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+
         int tagNo = 0;
         try {
-            dd.validate(responseMessage, true);
+            dd.validate(responseMessage, true, dataDictionarySettings);
         } catch (FieldException e) {
             tagNo = e.getField();
         }
@@ -1651,9 +1653,9 @@ public void testInvalidFieldInGroup() throws Exception {
         // (which is the first field after the invalid 297 field)
         assertEquals(QuoteAckStatus.FIELD, tagNo);
 
-        Message msg2 = new Message(responseMessage.toString(), dd);
+        Message msg2 = new Message(responseMessage.toString(), dd, dataDictionarySettings);
         try {
-            dd.validate(msg2, true);
+            dd.validate(msg2, true, dataDictionarySettings);
         } catch (FieldException e) {
             tagNo = e.getField();
         }
@@ -1662,7 +1664,7 @@ public void testInvalidFieldInGroup() throws Exception {
         assertEquals(QuoteAckStatus.FIELD, tagNo);
 
         // parse message again without validation
-        msg2 = new Message(responseMessage.toString(), dd, false);
+        msg2 = new Message(responseMessage.toString(), dd, dataDictionarySettings, false);
         assertEquals(responseMessage.toString(), msg2.toString());
         Group noRelatedSymGroup = new quickfix.fix44.DerivativeSecurityList.NoRelatedSym();
         Group group = responseMessage.getGroup(1, noRelatedSymGroup);
@@ -1686,10 +1688,11 @@ public void testNestedRepeatingGroup()
         quickfix.fix44.NewOrderSingle nos = new quickfix.fix44.NewOrderSingle();
         // using custom dictionary with user-defined tag 22000
         final DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setCheckUserDefinedFields(false);
-        nos.fromString(newOrdersSingleString.replaceAll("\\|", "\001"), dataDictionary, true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setCheckUserDefinedFields(false);
+        nos.fromString(newOrdersSingleString.replaceAll("\\|", "\001"), dataDictionary, dataDictionarySettings, true);
         assertNull(nos.getException());
-        dataDictionary.validate(nos);
+        dataDictionary.validate(nos, dataDictionarySettings);
 
         // defined tag should be set on the message
         assertTrue(nos.isSetField(22000));
@@ -1714,10 +1717,11 @@ public void testUnknownTagBeforeFirstFieldInRepeatingGroup()
 
         quickfix.fix44.NewOrderSingle nos = new quickfix.fix44.NewOrderSingle();
         final DataDictionary dataDictionary = new DataDictionary(DataDictionaryTest.getDictionary());
-        dataDictionary.setCheckUserDefinedFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setCheckUserDefinedFields(false);
 
         // When
-        nos.fromString(newOrdersSingleString.replaceAll("\\|", "\001"), dataDictionary, true);
+        nos.fromString(newOrdersSingleString.replaceAll("\\|", "\001"), dataDictionary, dataDictionarySettings, true);
 
         // Then
         FieldException e = nos.getException();
@@ -1740,10 +1744,11 @@ public void testNestedRepeatingSubGroup()
         quickfix.fix44.NewOrderSingle nos = new quickfix.fix44.NewOrderSingle();
         // using custom dictionary with user-defined tag 22000
         final DataDictionary dataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
-        dataDictionary.setCheckUserDefinedFields(false);
-        nos.fromString(newOrdersSingleString.replaceAll("\\|", "\001"), dataDictionary, true);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setCheckUserDefinedFields(false);
+        nos.fromString(newOrdersSingleString.replaceAll("\\|", "\001"), dataDictionary, dataDictionarySettings, true);
         assertNull(nos.getException());
-        dataDictionary.validate(nos);
+        dataDictionary.validate(nos, dataDictionarySettings);
 
         // defined tag should be set on the message
         assertTrue(nos.isSetField(22000));
@@ -1790,9 +1795,10 @@ private void testRepeatingGroupCountForFieldOrder(int fieldOrder[]) throws Excep
          */
         String s = tcr.toString();
         DataDictionary dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
-        dictionary.setCheckUnorderedGroupFields(false);
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
+        dataDictionarySettings.setCheckUnorderedGroupFields(false);
         // without checking order of repeating group it should work
-        Message parsed = new Message(s, dictionary);
+        Message parsed = new Message(s, dictionary, dataDictionarySettings);
         FieldException exception = parsed.getException();
         assertNull(exception);
 
@@ -1800,7 +1806,7 @@ private void testRepeatingGroupCountForFieldOrder(int fieldOrder[]) throws Excep
 
         dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
         // when checking order of repeating group, an error should be reported
-        parsed = new Message(s, dictionary);
+        parsed = new Message(s, dictionary, new DataDictionarySettings());
         exception = parsed.getException();
         assertEquals(654, exception.getField());
         // but we still should have the repeating group set and not ignore it
@@ -1811,11 +1817,12 @@ private void testRepeatingGroupCountForFieldOrder(int fieldOrder[]) throws Excep
     @Test
     public void testRepeatingGroupCountWithNonIntegerValues() throws Exception {
         DataDictionary dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
         Message ioi = new quickfix.fix50.IOI();
         ioi.setString(quickfix.field.NoPartyIDs.FIELD, "abc");
         final String invalidCountMessage = ioi.toString();
         try {
-            Message message =  new Message(invalidCountMessage, dictionary);
+            Message message =  new Message(invalidCountMessage, dictionary, dataDictionarySettings);
         } catch (final InvalidMessage im) {
             assertNotNull("InvalidMessage correctly thrown", im);
         } catch (final Throwable e) {
@@ -1835,8 +1842,9 @@ public void testRepeatingGroupCountWithUnknownFields() throws Exception {
                 + "9083=0|9084=0|9061=579|9062=text|9063=text|9032=10.0|9002=F|9004=780415|9005=780503|10=223|";
         
         DataDictionary dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
+        DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
         Message message = new Message();
-        message.fromString(test.replaceAll("\\|", "\001"), dictionary, true);
+        message.fromString(test.replaceAll("\\|", "\001"), dictionary, dataDictionarySettings, true);
         Group group = message.getGroup(1, 711);
         String underlyingSymbol = group.getString(311);
         assertEquals("780508", underlyingSymbol);
@@ -1854,7 +1862,7 @@ public void testRawString() throws Exception {
         
         DataDictionary dictionary = new DataDictionary(DataDictionaryTest.getDictionary());
         Message message = new Message();
-        message.fromString(test.replaceAll("\\|", "\001"), dictionary, true);
+        message.fromString(test.replaceAll("\\|", "\001"), dictionary, new DataDictionarySettings(), true);
         assertEquals(test, message.toRawString().replaceAll("\001", "\\|"));
     }
 
@@ -1879,6 +1887,7 @@ public void testIfMessageHeaderIsOverwritten() {
     public void testIfMessageHeaderIsCreatedWithEveryConstructor() throws Exception {
         final String rawMessage = "8=FIX.4.2\0019=12\00135=A\001108=30\00110=026\001";
         final DataDictionary dataDictionary = new DataDictionary(DataDictionaryTest.getDictionary());
+        final DataDictionarySettings dataDictionarySettings = new DataDictionarySettings();
 
         final Message emptyConstructor = new Message();
         assertNotNull(emptyConstructor.getHeader());
@@ -1892,13 +1901,13 @@ public void testIfMessageHeaderIsCreatedWithEveryConstructor() throws Exception
         final Message fourthConstructor = new Message(rawMessage, false);
         assertNotNull(fourthConstructor.getHeader());
 
-        final Message fifthConstructor = new Message(rawMessage, dataDictionary);
+        final Message fifthConstructor = new Message(rawMessage, dataDictionary, dataDictionarySettings);
         assertNotNull(fifthConstructor.getHeader());
 
-        final Message sixthConstructor = new Message(rawMessage, dataDictionary, false);
+        final Message sixthConstructor = new Message(rawMessage, dataDictionary, dataDictionarySettings,false);
         assertNotNull(sixthConstructor.getHeader());
 
-        final Message seventhConstructor = new Message(rawMessage, dataDictionary, dataDictionary, false);
+        final Message seventhConstructor = new Message(rawMessage, dataDictionary, dataDictionary, dataDictionarySettings, false);
         assertNotNull(seventhConstructor.getHeader());
     }
 
diff --git a/quickfixj-core/src/test/java/quickfix/MessageUtilsTest.java b/quickfixj-core/src/test/java/quickfix/MessageUtilsTest.java
index 8e4e6fb88f..8903e9b65b 100644
--- a/quickfixj-core/src/test/java/quickfix/MessageUtilsTest.java
+++ b/quickfixj-core/src/test/java/quickfix/MessageUtilsTest.java
@@ -160,7 +160,7 @@ public void testLegacyParse() throws Exception {
             "44=15\00159=1\0016=0\001453=3\001448=AAA35791\001447=D\001452=3\001448=8\001" +
             "447=D\001452=4\001448=FIX11\001447=D\001452=36\00160=20060320-03:34:29\00110=169\001";
 
-        Message message = MessageUtils.parse(new quickfix.fix40.MessageFactory(), DataDictionaryTest.getDictionary(), data);
+        Message message = MessageUtils.parse(new quickfix.fix40.MessageFactory(), DataDictionaryTest.getDictionary(), new DataDictionarySettings(), data);
         assertThat(message, is(notNullValue()));
     }
 
diff --git a/quickfixj-core/src/test/java/quickfix/RepeatingGroupTest.java b/quickfixj-core/src/test/java/quickfix/RepeatingGroupTest.java
index 1132a307f2..fe391c862a 100644
--- a/quickfixj-core/src/test/java/quickfix/RepeatingGroupTest.java
+++ b/quickfixj-core/src/test/java/quickfix/RepeatingGroupTest.java
@@ -281,26 +281,28 @@ public void testSettingGettingGroupByReusingGroup() throws FieldNotFound {
 
     // Testing Message validation
     private static DataDictionary defaultDataDictionary = null;
-    private static DataDictionary defaultDataDictionaryWithIgnoreOutOfOrder = null;
+    private static DataDictionarySettings defaultDDSettings = null;
+    private static DataDictionarySettings ignoreOutOfOrderSettings = null;
     private static DataDictionary customDataDictionary = null;
     private final DefaultMessageFactory messageFactory = new DefaultMessageFactory();
 
     static {
         try {
             defaultDataDictionary = new DataDictionary("FIX44.xml");
-            defaultDataDictionaryWithIgnoreOutOfOrder = new DataDictionary("FIX44.xml");
-            defaultDataDictionaryWithIgnoreOutOfOrder.setCheckUnorderedGroupFields(false);
+            defaultDDSettings = new DataDictionarySettings();
+            ignoreOutOfOrderSettings = new DataDictionarySettings();
+            ignoreOutOfOrderSettings.setCheckUnorderedGroupFields(false);
             customDataDictionary = new DataDictionary("FIX44_Custom_Test.xml");
         } catch (final ConfigError e) {
             e.printStackTrace();
         }
     }
 
-    private Message buildValidatedMessage(String sourceFIXString, DataDictionary dd)
+    private Message buildValidatedMessage(String sourceFIXString, DataDictionary dd, DataDictionarySettings dataDictionarySettings)
             throws InvalidMessage {
         final Message message = messageFactory.create(MessageUtils.getStringField(sourceFIXString,
                 BeginString.FIELD), MessageUtils.getMessageType(sourceFIXString));
-        message.fromString(sourceFIXString, dd, true);
+        message.fromString(sourceFIXString, dd, dataDictionarySettings, true);
         return message;
     }
 
@@ -321,7 +323,7 @@ public void testValidationWithNestedGroupAndStandardFields() throws InvalidMessa
         final String sourceFIXString = quoteRequest.toString();
 
         final quickfix.fix44.QuoteRequest validatedMessage = (quickfix.fix44.QuoteRequest) buildValidatedMessage(
-                sourceFIXString, defaultDataDictionary);
+                sourceFIXString, defaultDataDictionary, defaultDDSettings);
         String validateFIXString = null;
         if (validatedMessage != null) {
             validateFIXString = validatedMessage.toString();
@@ -348,7 +350,7 @@ public void testValidationWithNestedGroupAndStandardFieldsFIX50SP2() throws Inva
         final String sourceFIXString = quoteRequest.toString();
         final DataDictionary fix50sp2DataDictionary = new DataDictionary("FIX50SP2.xml");
         final quickfix.fix50sp2.QuoteRequest validatedMessage = (quickfix.fix50sp2.QuoteRequest) messageFactory.create(FixVersions.FIX50SP2, QuoteRequest.MSGTYPE);
-        validatedMessage.fromString(sourceFIXString, fix50sp2DataDictionary, true);
+        validatedMessage.fromString(sourceFIXString, fix50sp2DataDictionary, new DataDictionarySettings(), true);
 
         String validateFIXString = validatedMessage.toString();
 
@@ -371,7 +373,7 @@ public void testValidationWithNestedGroupAndStandardFieldsWithoutDelimiter() thr
 
         final String sourceFIXString = quoteRequest.toString();
 
-        Message buildValidatedMessage = buildValidatedMessage(sourceFIXString, defaultDataDictionary);
+        Message buildValidatedMessage = buildValidatedMessage(sourceFIXString, defaultDataDictionary, defaultDDSettings);
         assertEquals("The group 146 must set the delimiter field 55", buildValidatedMessage.getException().getMessage());
     }
 
@@ -406,7 +408,7 @@ public void testGroupFieldsOrderWithCustomDataDictionary() throws InvalidMessage
 
         final String sourceFIXString = quoteRequest.toString();
         final quickfix.fix44.QuoteRequest validatedMessage = (quickfix.fix44.QuoteRequest) buildValidatedMessage(
-                sourceFIXString, customDataDictionary);
+                sourceFIXString, customDataDictionary, new DataDictionarySettings());
 
         assertNull("Invalid message", validatedMessage.getException());
 
@@ -421,9 +423,9 @@ public void testOutOfOrderGroupMembersDelimiterField() throws Exception {
             "8=FIX.4.4\0019=0\00135=D\00134=2\00149=TW\00152=