Index: core/src/main/java/quickfix/DataDictionary.java =================================================================== --- core/src/main/java/quickfix/DataDictionary.java (rev1) +++ core/src/main/java/quickfix/DataDictionary.java @@ -71,6 +71,7 @@ private boolean checkFieldsOutOfOrder = true; private boolean checkFieldsHaveValues = true; private boolean checkUserDefinedFields = true; + private boolean checkDuplicateFields = true; private boolean allowUnknownMessageFields = false; private String beginString; private final Map> messageFields = new HashMap>(); @@ -486,12 +487,22 @@ checkUserDefinedFields = flag; } + public boolean isCheckDuplicateFields() { + return checkDuplicateFields; + } + + public void setCheckDuplicateFields(boolean checkDuplicateFields) { + this.checkDuplicateFields = checkDuplicateFields; + } + private void copyFrom(DataDictionary rhs) { hasVersion = rhs.hasVersion; beginString = rhs.beginString; checkFieldsOutOfOrder = rhs.checkFieldsOutOfOrder; checkFieldsHaveValues = rhs.checkFieldsHaveValues; checkUserDefinedFields = rhs.checkUserDefinedFields; + checkDuplicateFields = rhs.checkDuplicateFields; + allowUnknownMessageFields = rhs.allowUnknownMessageFields; copyMap(messageFields, rhs.messageFields); copyMap(requiredFields, rhs.requiredFields); Index: core/src/main/java/quickfix/Message.java =================================================================== --- core/src/main/java/quickfix/Message.java (original) +++ core/src/main/java/quickfix/Message.java @@ -541,24 +541,25 @@ if (isHeaderField(field.getField())) { // An acceptance test requires the sequence number to // be available even if the related field is out of order - setField(header, field); - throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, - field.getTag()); - } - - setField(this, field); - - // Group case - if (dd != null && dd.isGroup(getMsgType(), field.getField())) { - parseGroup(getMsgType(), field, dd, this); + setField(header, field, dd); + if(dd.isCheckFieldsOutOfOrder()) + throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, + field.getTag()); + } else { + setField(this, field, dd); + + // Group case + if (dd != null && dd.isGroup(getMsgType(), field.getField())) { + parseGroup(getMsgType(), field, dd, this); + } } field = extractField(dd, this); } } - private void setField(FieldMap fields, StringField field) { - if (fields.isSetField(field)) { + private void setField(FieldMap fields, StringField field, DataDictionary dd) { + if (dd.isCheckDuplicateFields() && fields.isSetField(field)) { throw new FieldException(SessionRejectReason.TAG_APPEARS_MORE_THAN_ONCE, field.getTag()); } fields.setField(field); Index: core/src/main/java/quickfix/Session.java =================================================================== --- core/src/main/java/quickfix/Session.java (rev1) +++ core/src/main/java/quickfix/Session.java @@ -206,6 +206,11 @@ public static final String SETTING_VALIDATE_USER_DEFINED_FIELDS = "ValidateUserDefinedFields"; /** + * Controls validation of duplicate fields. + */ + public static final String SETTING_VALIDATE_DUPLICATE_FIELDS = "ValidateDuplicateFields"; + + /** * Session setting that causes the session to reset sequence numbers when initiating * a logon (>= FIX 4.2). */ @@ -2063,4 +2068,4 @@ public ApplVerID getTargetDefaultApplicationVersionID() { return targetDefaultApplVerID.get(); } -} +} \ No newline at end of file