@@ -117,7 +117,7 @@ private BidRequest modifyRequest(BidRequest request, Imp imp, ExtImpYahooAds ext
117117 }
118118
119119 if (regs != null ) {
120- requestBuilder .regs (modifyRegs (regs ));
120+ requestBuilder .regs (promoteRegsExtToTopLevel (regs ));
121121 }
122122
123123 return requestBuilder
@@ -163,96 +163,97 @@ private static Banner modifyBanner(Banner banner) {
163163 }
164164
165165 // Promote legacy 2.5 regs.ext gpp/gpp_sid/coppa to their 2.6 top-level slots.
166- private static Regs modifyRegs (Regs regs ) {
167- final ExtRegs originalExt = regs .getExt ();
168- if (originalExt == null
169- || originalExt .getProperties () == null
170- || originalExt .getProperties ().isEmpty ()) {
166+ // A field is promoted only when it is absent at top-level and present and well-formed
167+ // in ext; each promoted key is then removed from ext. Anything not promoted (already
168+ // top-level, missing, or malformed) is left untouched, in ext.
169+ private static Regs promoteRegsExtToTopLevel (Regs regs ) {
170+ final ExtRegs ext = regs .getExt ();
171+ if (ext == null || ext .getProperties ().isEmpty ()) {
171172 return regs ;
172173 }
173174
174- final String resolvedGpp = resolveGpp (regs , originalExt );
175- final List <Integer > resolvedGppSid = resolveGppSid (regs , originalExt );
176- final Integer resolvedCoppa = resolveCoppa (regs , originalExt );
175+ final String promotedGpp = gppToPromote (regs , ext );
176+ final List <Integer > promotedGppSid = gppSidToPromote (regs , ext );
177+ final Integer promotedCoppa = coppaToPromote (regs , ext );
177178
178- final boolean changed = !Objects .equals (resolvedGpp , regs .getGpp ())
179- || !Objects .equals (resolvedGppSid , regs .getGppSid ())
180- || !Objects .equals (resolvedCoppa , regs .getCoppa ());
181-
182- if (!changed ) {
179+ if (promotedGpp == null && promotedGppSid == null && promotedCoppa == null ) {
183180 return regs ;
184181 }
185182
186- return regs .toBuilder ()
187- .gpp (resolvedGpp )
188- .gppSid (resolvedGppSid )
189- .coppa (resolvedCoppa )
190- .ext (stripPromotedFromExt (originalExt , resolvedGpp , resolvedGppSid , resolvedCoppa ))
183+ final Regs .RegsBuilder builder = regs .toBuilder ();
184+ if (promotedGpp != null ) {
185+ builder .gpp (promotedGpp );
186+ }
187+ if (promotedGppSid != null ) {
188+ builder .gppSid (promotedGppSid );
189+ }
190+ if (promotedCoppa != null ) {
191+ builder .coppa (promotedCoppa );
192+ }
193+ return builder
194+ .ext (removePromotedKeys (ext , promotedGpp != null , promotedGppSid != null , promotedCoppa != null ))
191195 .build ();
192196 }
193197
194- private static String resolveGpp (Regs regs , ExtRegs ext ) {
198+ // Value to lift from ext, or null when top-level already has it or ext lacks a valid value.
199+ private static String gppToPromote (Regs regs , ExtRegs ext ) {
195200 if (regs .getGpp () != null ) {
196- return regs . getGpp () ;
201+ return null ;
197202 }
198203 final JsonNode node = ext .getProperties ().get (GPP_PROPERTY );
199204 return node != null && node .isTextual () ? node .asText () : null ;
200205 }
201206
202- private static List <Integer > resolveGppSid (Regs regs , ExtRegs ext ) {
207+ private static List <Integer > gppSidToPromote (Regs regs , ExtRegs ext ) {
203208 if (!CollectionUtils .isEmpty (regs .getGppSid ())) {
204- return regs . getGppSid () ;
209+ return null ;
205210 }
206211 final JsonNode node = ext .getProperties ().get (GPP_SID_PROPERTY );
207- if (node == null || !node .isArray ()) {
208- return regs . getGppSid () ;
212+ if (node == null || !node .isArray () || node . isEmpty () ) {
213+ return null ;
209214 }
210215 final List <Integer > sids = new ArrayList <>(node .size ());
211216 for (final JsonNode elem : node ) {
212217 if (!elem .isIntegralNumber ()) {
213- return regs . getGppSid () ;
218+ return null ;
214219 }
215220 sids .add (elem .asInt ());
216221 }
217- return sids . isEmpty () ? regs . getGppSid () : sids ;
222+ return sids ;
218223 }
219224
220- private static Integer resolveCoppa (Regs regs , ExtRegs ext ) {
225+ private static Integer coppaToPromote (Regs regs , ExtRegs ext ) {
221226 if (regs .getCoppa () != null ) {
222- return regs . getCoppa () ;
227+ return null ;
223228 }
224229 final JsonNode node = ext .getProperties ().get (COPPA_PROPERTY );
225230 return node != null && node .isIntegralNumber () ? node .asInt () : null ;
226231 }
227232
228- // Drop a key from ext only if it was promoted; keep gpc/dsa, unknown, and non-promoted values.
229- private static ExtRegs stripPromotedFromExt (ExtRegs original ,
230- String resolvedGpp ,
231- List <Integer > resolvedGppSid ,
232- Integer resolvedCoppa ) {
233- final ExtRegs stripped = ExtRegs .of (
234- original .getGdpr (),
235- original .getUsPrivacy (),
236- original .getGpc (),
237- original .getDsa ());
238- original .getProperties ().forEach ((key , value ) -> {
239- final boolean promoted =
240- (GPP_PROPERTY .equals (key ) && resolvedGpp != null )
241- || (GPP_SID_PROPERTY .equals (key ) && !CollectionUtils .isEmpty (resolvedGppSid ))
242- || (COPPA_PROPERTY .equals (key ) && resolvedCoppa != null );
243- if (!promoted ) {
244- stripped .addProperty (key , value );
233+ // Rebuild regs.ext keeping the typed fields and every property except the promoted ones.
234+ private static ExtRegs removePromotedKeys (ExtRegs ext ,
235+ boolean gppPromoted ,
236+ boolean gppSidPromoted ,
237+ boolean coppaPromoted ) {
238+ final ExtRegs result = ExtRegs .of (
239+ ext .getGdpr (), ext .getUsPrivacy (), ext .getGpc (), ext .getDsa ());
240+ ext .getProperties ().forEach ((key , value ) -> {
241+ final boolean isPromotedKey = (gppPromoted && GPP_PROPERTY .equals (key ))
242+ || (gppSidPromoted && GPP_SID_PROPERTY .equals (key ))
243+ || (coppaPromoted && COPPA_PROPERTY .equals (key ));
244+ if (!isPromotedKey ) {
245+ result .addProperty (key , value );
245246 }
246247 });
247- return isExtEmpty (stripped ) ? null : stripped ;
248+ return isExtEmpty (result ) ? null : result ;
248249 }
249250
250251 private static boolean isExtEmpty (ExtRegs ext ) {
251252 return ext .getGdpr () == null
252253 && ext .getUsPrivacy () == null
253254 && ext .getGpc () == null
254255 && ext .getDsa () == null
255- && ( ext .getProperties () == null || ext . getProperties (). isEmpty () );
256+ && ext .getProperties (). isEmpty ();
256257 }
257258
258259 private HttpRequest <BidRequest > makeHttpRequest (BidRequest outgoingRequest ) {
0 commit comments