diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java index 22da774..17dc9d3 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java @@ -16,6 +16,9 @@ import com.iab.gpp.encoder.section.UsDe; import com.iab.gpp.encoder.section.UsFl; import com.iab.gpp.encoder.section.UsIa; +import com.iab.gpp.encoder.section.UsIn; +import com.iab.gpp.encoder.section.UsKy; +import com.iab.gpp.encoder.section.UsMd; import com.iab.gpp.encoder.section.UsMn; import com.iab.gpp.encoder.section.UsMt; import com.iab.gpp.encoder.section.UsNat; @@ -23,6 +26,7 @@ import com.iab.gpp.encoder.section.UsNh; import com.iab.gpp.encoder.section.UsNj; import com.iab.gpp.encoder.section.UsOr; +import com.iab.gpp.encoder.section.UsRi; import com.iab.gpp.encoder.section.UsTn; import com.iab.gpp.encoder.section.UsTx; import com.iab.gpp.encoder.section.UsUt; @@ -66,6 +70,10 @@ public class GppModel extends AbstractEncodable { constructors.add(UsNj::new); constructors.add(UsTn::new); constructors.add(UsMn::new); + constructors.add(UsMd::new); + constructors.add(UsIn::new); + constructors.add(UsKy::new); + constructors.add(UsRi::new); for (Supplier> constructor : constructors) { EncodableSection prototype = constructor.get(); @@ -265,6 +273,22 @@ public UsMn getUsMnSection() { return (UsMn) getSection(UsMn.ID); } + public UsMd getUsMdSection() { + return (UsMd) getSection(UsMd.ID); + } + + public UsIn getUsInSection() { + return (UsIn) getSection(UsIn.ID); + } + + public UsKy getUsKySection() { + return (UsKy) getSection(UsKy.ID); + } + + public UsRi getUsRiSection() { + return (UsRi) getSection(UsRi.ID); + } + public IntegerSet getSectionIds() { ensureDecode(); return header.getSectionsIds(); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java new file mode 100644 index 0000000..24218e2 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java @@ -0,0 +1,58 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.datatype.UnencodableBoolean; +import com.iab.gpp.encoder.section.UsIn; + +public enum UsInField implements FieldKey { + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, UsIn.VERSION)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + KNOWN_CHILD_SENSITIVE_DATA_CONSENTS( + new EncodableFixedInteger<>("KnownChildSensitiveDataConsents", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + SENSITIVE_DATA_PROCESSING( + new EncodableFixedIntegerList<>("SensitiveDataProcessing", 2, 8, VALIDATOR_LIST_012)), + SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED( + new UnencodableBoolean<>("SensitiveDataConsentSegmentIncluded", true)); + + private final DataType type; + + UsInField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USIN_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsInField.MSPA_VERSION, + UsInField.MSPA_COVERED_TRANSACTION, + UsInField.MSPA_MODE, + UsInField.PROCESSING_NOTICE, + UsInField.SALE_OPT_OUT_NOTICE, + UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsInField.SALE_OPT_OUT, + UsInField.TARGETED_ADVERTISING_OPT_OUT, + UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USIN_SENSITIVE_DATA_CONSENT_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsInField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED, UsInField.SENSITIVE_DATA_PROCESSING); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java new file mode 100644 index 0000000..985d60c --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java @@ -0,0 +1,58 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.datatype.UnencodableBoolean; +import com.iab.gpp.encoder.section.UsKy; + +public enum UsKyField implements FieldKey { + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, UsKy.VERSION)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + KNOWN_CHILD_SENSITIVE_DATA_CONSENTS( + new EncodableFixedInteger<>("KnownChildSensitiveDataConsents", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + SENSITIVE_DATA_PROCESSING( + new EncodableFixedIntegerList<>("SensitiveDataProcessing", 2, 8, VALIDATOR_LIST_012)), + SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED( + new UnencodableBoolean<>("SensitiveDataConsentSegmentIncluded", true)); + + private final DataType type; + + UsKyField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USKY_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsKyField.MSPA_VERSION, + UsKyField.MSPA_COVERED_TRANSACTION, + UsKyField.MSPA_MODE, + UsKyField.PROCESSING_NOTICE, + UsKyField.SALE_OPT_OUT_NOTICE, + UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsKyField.SALE_OPT_OUT, + UsKyField.TARGETED_ADVERTISING_OPT_OUT, + UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USKY_SENSITIVE_DATA_CONSENT_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsKyField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED, UsKyField.SENSITIVE_DATA_PROCESSING); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java new file mode 100644 index 0000000..d15edd8 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java @@ -0,0 +1,53 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.UnencodableBoolean; +import com.iab.gpp.encoder.section.UsMd; + +public enum UsMdField implements FieldKey { + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, UsMd.VERSION)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + GPC_SEGMENT_TYPE(new EncodableFixedInteger<>("GpcSegmentType", 2, 1)), + GPC_SEGMENT_INCLUDED(new UnencodableBoolean<>("GpcSegmentIncluded", true)), + GPC(new EncodableBoolean<>("Gpc", false)); + + private final DataType type; + + UsMdField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USMD_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsMdField.MSPA_VERSION, + UsMdField.MSPA_COVERED_TRANSACTION, + UsMdField.MSPA_MODE, + UsMdField.PROCESSING_NOTICE, + UsMdField.SALE_OPT_OUT_NOTICE, + UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsMdField.SALE_OPT_OUT, + UsMdField.TARGETED_ADVERTISING_OPT_OUT, + UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USMD_GPC_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsMdField.GPC_SEGMENT_TYPE, UsMdField.GPC_SEGMENT_INCLUDED, UsMdField.GPC); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java new file mode 100644 index 0000000..96d83ff --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java @@ -0,0 +1,58 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.datatype.UnencodableBoolean; +import com.iab.gpp.encoder.section.UsRi; + +public enum UsRiField implements FieldKey { + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, UsRi.VERSION)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + KNOWN_CHILD_SENSITIVE_DATA_CONSENTS( + new EncodableFixedInteger<>("KnownChildSensitiveDataConsents", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + SENSITIVE_DATA_PROCESSING( + new EncodableFixedIntegerList<>("SensitiveDataProcessing", 2, 8, VALIDATOR_LIST_012)), + SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED( + new UnencodableBoolean<>("SensitiveDataConsentSegmentIncluded", true)); + + private final DataType type; + + UsRiField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USRI_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsRiField.MSPA_VERSION, + UsRiField.MSPA_COVERED_TRANSACTION, + UsRiField.MSPA_MODE, + UsRiField.PROCESSING_NOTICE, + UsRiField.SALE_OPT_OUT_NOTICE, + UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsRiField.SALE_OPT_OUT, + UsRiField.TARGETED_ADVERTISING_OPT_OUT, + UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USRI_SENSITIVE_DATA_CONSENT_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsRiField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED, UsRiField.SENSITIVE_DATA_PROCESSING); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithSensitiveDataConsent.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithSensitiveDataConsent.java new file mode 100644 index 0000000..45bab5e --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithSensitiveDataConsent.java @@ -0,0 +1,58 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.field.FieldKey; +import com.iab.gpp.encoder.segment.EncodableSegment; +import java.util.ArrayList; +import java.util.List; + +/** + * Base class for US sections whose core segment is optionally followed by a "Sensitive Data + * Consents" segment (e.g. Indiana, Kentucky, Rhode Island). Mirrors {@link + * AbstractUsSectionWithGpc}, but the optional second segment carries sensitive data consents rather + * than GPC. + */ +public abstract class AbstractUsSectionWithSensitiveDataConsent & FieldKey> + extends AbstractUsSection { + + protected AbstractUsSectionWithSensitiveDataConsent( + EncodableSegment coreSegment, EncodableSegment sensitiveDataConsentSegment) { + super(coreSegment, sensitiveDataConsentSegment); + } + + protected abstract E getSensitiveDataConsentSegmentIncludedKey(); + + @Override + protected final void doDecode(CharSequence encodedString) { + List encodedSegments = SlicedCharSequence.split(encodedString, '.'); + int numEncodedSegments = encodedSegments.size(); + + if (numEncodedSegments > 0) { + getSegment(0).decode(encodedSegments.get(0)); + } + + E sensitiveDataConsentSegmentIncludedKey = getSensitiveDataConsentSegmentIncludedKey(); + if (numEncodedSegments > 1) { + getSegment(1).setFieldValue(sensitiveDataConsentSegmentIncludedKey, Boolean.TRUE); + getSegment(1).decode(encodedSegments.get(1)); + } else { + getSegment(1).setFieldValue(sensitiveDataConsentSegmentIncludedKey, Boolean.FALSE); + } + } + + @Override + protected final CharSequence doEncode() { + int size = size(); + List encodedSegments = new ArrayList<>(size); + + encodedSegments.add(getSegment(0).encodeCharSequence()); + if (size >= 2 && getSensitiveDataConsentSegmentIncluded()) { + encodedSegments.add(getSegment(1).encodeCharSequence()); + } + + return SlicedCharSequence.join('.', encodedSegments); + } + + public Boolean getSensitiveDataConsentSegmentIncluded() { + return (Boolean) getSegment(1).getFieldValue(getSensitiveDataConsentSegmentIncludedKey()); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java new file mode 100644 index 0000000..b65555d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java @@ -0,0 +1,83 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.FixedIntegerList; +import com.iab.gpp.encoder.field.UsInField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsIn extends AbstractUsSectionWithSensitiveDataConsent { + + public static final int ID = 25; + public static final int VERSION = 1; + public static final String NAME = "usin"; + + public UsIn() { + super( + new Base64Segment<>(UsInField.USIN_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsInField.USIN_SENSITIVE_DATA_CONSENT_SEGMENT_FIELD_NAMES)); + } + + public UsIn(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsIn.ID; + } + + @Override + public String getName() { + return UsIn.NAME; + } + + @Override + public int getVersion() { + return (Integer) this.getFieldValue(UsInField.MSPA_VERSION); + } + + @Override + protected final UsInField getSensitiveDataConsentSegmentIncludedKey() { + return UsInField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED; + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsInField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsInField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsInField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsInField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsInField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsInField.SENSITIVE_DATA_PROCESSING); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java new file mode 100644 index 0000000..b1f326d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java @@ -0,0 +1,83 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.FixedIntegerList; +import com.iab.gpp.encoder.field.UsKyField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsKy extends AbstractUsSectionWithSensitiveDataConsent { + + public static final int ID = 26; + public static final int VERSION = 1; + public static final String NAME = "usky"; + + public UsKy() { + super( + new Base64Segment<>(UsKyField.USKY_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsKyField.USKY_SENSITIVE_DATA_CONSENT_SEGMENT_FIELD_NAMES)); + } + + public UsKy(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsKy.ID; + } + + @Override + public String getName() { + return UsKy.NAME; + } + + @Override + public int getVersion() { + return (Integer) this.getFieldValue(UsKyField.MSPA_VERSION); + } + + @Override + protected final UsKyField getSensitiveDataConsentSegmentIncludedKey() { + return UsKyField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED; + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsKyField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsKyField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsKyField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsKyField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsKyField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsKyField.SENSITIVE_DATA_PROCESSING); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java new file mode 100644 index 0000000..bcb1e00 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java @@ -0,0 +1,79 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.field.UsMdField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsMd extends AbstractUsSectionWithGpc { + + public static final int ID = 24; + public static final int VERSION = 1; + public static final String NAME = "usmd"; + + public UsMd() { + super( + new Base64Segment<>(UsMdField.USMD_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsMdField.USMD_GPC_SEGMENT_FIELD_NAMES)); + } + + public UsMd(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsMd.ID; + } + + @Override + public String getName() { + return UsMd.NAME; + } + + @Override + public int getVersion() { + return (Integer) this.getFieldValue(UsMdField.MSPA_VERSION); + } + + @Override + protected final UsMdField getGpcSegmentIncludedKey() { + return UsMdField.GPC_SEGMENT_INCLUDED; + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsMdField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsMdField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsMdField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsMdField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsMdField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + @Override + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsMdField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java new file mode 100644 index 0000000..809cdc8 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java @@ -0,0 +1,83 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.FixedIntegerList; +import com.iab.gpp.encoder.field.UsRiField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsRi extends AbstractUsSectionWithSensitiveDataConsent { + + public static final int ID = 27; + public static final int VERSION = 1; + public static final String NAME = "usri"; + + public UsRi() { + super( + new Base64Segment<>(UsRiField.USRI_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsRiField.USRI_SENSITIVE_DATA_CONSENT_SEGMENT_FIELD_NAMES)); + } + + public UsRi(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsRi.ID; + } + + @Override + public String getName() { + return UsRi.NAME; + } + + @Override + public int getVersion() { + return (Integer) this.getFieldValue(UsRiField.MSPA_VERSION); + } + + @Override + protected final UsRiField getSensitiveDataConsentSegmentIncludedKey() { + return UsRiField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED; + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsRiField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsRiField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsRiField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsRiField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsRiField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsRiField.SENSITIVE_DATA_PROCESSING); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java new file mode 100644 index 0000000..5f13cb9 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java @@ -0,0 +1,102 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsInField; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsInTest { + + @Test + public void testEncode1() { + UsIn usIn = new UsIn(); + Assertions.assertEquals("BQAA.AAA", usIn.encode()); + } + + @Test + public void testEncode2() { + UsIn usIn = new UsIn(); + + usIn.setFieldValue(UsInField.MSPA_COVERED_TRANSACTION, 1); + usIn.setFieldValue(UsInField.MSPA_MODE, 1); + usIn.setFieldValue(UsInField.PROCESSING_NOTICE, 1); + usIn.setFieldValue(UsInField.SALE_OPT_OUT_NOTICE, 1); + usIn.setFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usIn.setFieldValue(UsInField.SALE_OPT_OUT, 1); + usIn.setFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT, 1); + usIn.setFieldValue(UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usIn.setFieldValue(UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usIn.setFieldValue(UsInField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + + Assertions.assertEquals("BVVV.kkk", usIn.encode()); + } + + @Test + public void testSetInvalidValues() { + UsIn usIn = new UsIn(); + + try { + usIn.setFieldValue(UsInField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.MSPA_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue( + UsInField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithSensitiveDataConsentSegmentExcluded() { + UsIn usIn = new UsIn(); + usIn.setFieldValue(UsInField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BQAA", usIn.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsIn usIn = new UsIn("BVVV.kkk"); + + Assertions.assertEquals(1, usIn.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usIn.getMspaMode()); + Assertions.assertEquals(1, usIn.getProcessingNotice()); + Assertions.assertEquals(1, usIn.getSaleOptOutNotice()); + Assertions.assertEquals(1, usIn.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usIn.getSaleOptOut()); + Assertions.assertEquals(1, usIn.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(1, usIn.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usIn.getAdditionalDataProcessingConsent()); + Assertions.assertEquals( + Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usIn.getSensitiveDataProcessing()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsIn("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java new file mode 100644 index 0000000..e0bcf58 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java @@ -0,0 +1,102 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsKyField; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsKyTest { + + @Test + public void testEncode1() { + UsKy usKy = new UsKy(); + Assertions.assertEquals("BQAA.AAA", usKy.encode()); + } + + @Test + public void testEncode2() { + UsKy usKy = new UsKy(); + + usKy.setFieldValue(UsKyField.MSPA_COVERED_TRANSACTION, 1); + usKy.setFieldValue(UsKyField.MSPA_MODE, 1); + usKy.setFieldValue(UsKyField.PROCESSING_NOTICE, 1); + usKy.setFieldValue(UsKyField.SALE_OPT_OUT_NOTICE, 1); + usKy.setFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usKy.setFieldValue(UsKyField.SALE_OPT_OUT, 1); + usKy.setFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT, 1); + usKy.setFieldValue(UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usKy.setFieldValue(UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usKy.setFieldValue(UsKyField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + + Assertions.assertEquals("BVVV.kkk", usKy.encode()); + } + + @Test + public void testSetInvalidValues() { + UsKy usKy = new UsKy(); + + try { + usKy.setFieldValue(UsKyField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.MSPA_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue( + UsKyField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithSensitiveDataConsentSegmentExcluded() { + UsKy usKy = new UsKy(); + usKy.setFieldValue(UsKyField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BQAA", usKy.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsKy usKy = new UsKy("BVVV.kkk"); + + Assertions.assertEquals(1, usKy.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usKy.getMspaMode()); + Assertions.assertEquals(1, usKy.getProcessingNotice()); + Assertions.assertEquals(1, usKy.getSaleOptOutNotice()); + Assertions.assertEquals(1, usKy.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usKy.getSaleOptOut()); + Assertions.assertEquals(1, usKy.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(1, usKy.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usKy.getAdditionalDataProcessingConsent()); + Assertions.assertEquals( + Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usKy.getSensitiveDataProcessing()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsKy("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java new file mode 100644 index 0000000..8b646c6 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java @@ -0,0 +1,97 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsMdField; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsMdTest { + + @Test + public void testEncode1() { + UsMd usMd = new UsMd(); + Assertions.assertEquals("BQAA.QA", usMd.encode()); + } + + @Test + public void testEncode2() { + UsMd usMd = new UsMd(); + + usMd.setFieldValue(UsMdField.MSPA_COVERED_TRANSACTION, 1); + usMd.setFieldValue(UsMdField.MSPA_MODE, 1); + usMd.setFieldValue(UsMdField.PROCESSING_NOTICE, 1); + usMd.setFieldValue(UsMdField.SALE_OPT_OUT_NOTICE, 1); + usMd.setFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usMd.setFieldValue(UsMdField.SALE_OPT_OUT, 1); + usMd.setFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT, 1); + usMd.setFieldValue(UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usMd.setFieldValue(UsMdField.GPC, true); + + Assertions.assertEquals("BVVU.YA", usMd.encode()); + } + + @Test + public void testSetInvalidValues() { + UsMd usMd = new UsMd(); + + try { + usMd.setFieldValue(UsMdField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.MSPA_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsMd usMd = new UsMd(); + usMd.setFieldValue(UsMdField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BQAA", usMd.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsMd usMd = new UsMd("BVVU.YA"); + + Assertions.assertEquals(1, usMd.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usMd.getMspaMode()); + Assertions.assertEquals(1, usMd.getProcessingNotice()); + Assertions.assertEquals(1, usMd.getSaleOptOutNotice()); + Assertions.assertEquals(1, usMd.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usMd.getSaleOptOut()); + Assertions.assertEquals(1, usMd.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(1, usMd.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(true, usMd.getGpc()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsMd("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java new file mode 100644 index 0000000..714e8e9 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java @@ -0,0 +1,102 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsRiField; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsRiTest { + + @Test + public void testEncode1() { + UsRi usRi = new UsRi(); + Assertions.assertEquals("BQAA.AAA", usRi.encode()); + } + + @Test + public void testEncode2() { + UsRi usRi = new UsRi(); + + usRi.setFieldValue(UsRiField.MSPA_COVERED_TRANSACTION, 1); + usRi.setFieldValue(UsRiField.MSPA_MODE, 1); + usRi.setFieldValue(UsRiField.PROCESSING_NOTICE, 1); + usRi.setFieldValue(UsRiField.SALE_OPT_OUT_NOTICE, 1); + usRi.setFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usRi.setFieldValue(UsRiField.SALE_OPT_OUT, 1); + usRi.setFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT, 1); + usRi.setFieldValue(UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usRi.setFieldValue(UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usRi.setFieldValue(UsRiField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + + Assertions.assertEquals("BVVV.kkk", usRi.encode()); + } + + @Test + public void testSetInvalidValues() { + UsRi usRi = new UsRi(); + + try { + usRi.setFieldValue(UsRiField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.MSPA_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue( + UsRiField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithSensitiveDataConsentSegmentExcluded() { + UsRi usRi = new UsRi(); + usRi.setFieldValue(UsRiField.SENSITIVE_DATA_CONSENT_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BQAA", usRi.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsRi usRi = new UsRi("BVVV.kkk"); + + Assertions.assertEquals(1, usRi.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usRi.getMspaMode()); + Assertions.assertEquals(1, usRi.getProcessingNotice()); + Assertions.assertEquals(1, usRi.getSaleOptOutNotice()); + Assertions.assertEquals(1, usRi.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usRi.getSaleOptOut()); + Assertions.assertEquals(1, usRi.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(1, usRi.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usRi.getAdditionalDataProcessingConsent()); + Assertions.assertEquals( + Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usRi.getSensitiveDataProcessing()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsRi("z").getProcessingNotice(); + }); + } +}