001/*- 002 * #%L 003 * Smile CDR - CDR 004 * %% 005 * Copyright (C) 2016 - 2024 Smile CDR, Inc. 006 * %% 007 * All rights reserved. 008 * #L% 009 */ 010package ca.cdr.api.model.json; 011 012import ca.cdr.api.log.Logs; 013import ca.cdr.api.util.ValueUtils; 014import io.swagger.v3.oas.annotations.Operation; 015import io.swagger.v3.oas.annotations.Parameter; 016import jakarta.annotation.Nullable; 017 018import java.util.Map; 019 020public interface IHasUserData { 021 022 @Operation(summary = "getUserData", description = "Get a user supplied data value.") 023 default Object getUserData( 024 @Parameter(name = "theName", description = "The user data attribute name") String theName) { 025 if (getClientPopulatedUserData(false) == null) { 026 return null; 027 } 028 return getClientPopulatedUserData(true).get(theName); 029 } 030 031 @Operation(summary = "setUserData", description = "Sets a user supplied data value in the session.") 032 default void setUserData( 033 @Parameter(name = "theName", description = "The user data attribute name") String theName, 034 @Parameter(name = "theValue", description = "The attribute value") Object theValue) { 035 setUserDataInternal(true, theName, theValue); 036 } 037 038 default void setUserDataInternal(boolean theDoValidationCheck, String theName, Object theValue) { 039 if (theDoValidationCheck && !ValueUtils.isPrimitiveOrString(theValue)) { 040 Logs.getSecurityTroubleshootingLog() 041 .warn(String.format( 042 "Attempt to save complex object in UserData at %s. Suggest using JSON.stringify(obj) to save.", 043 theName)); 044 } 045 getClientPopulatedUserData(true).put(theName, theValue); 046 } 047 048 @Operation(summary = "clearUserData", description = "Clear all user data.") 049 default void clearUserData( 050 @Parameter(name = "theName", description = "The user data attribute name") String theName) { 051 getClientPopulatedUserData(true).remove(theName); 052 } 053 054 @Operation( 055 summary = "setUserDataINN", 056 description = "Sets a user supplied data value in the session if `value` is not null.") 057 default void setUserDataINN( 058 @Parameter(name = "theName", description = "The user data attribute name") String theName, 059 @Parameter(name = "theValue", description = "The attribute value") Object theValue) { 060 if (theValue == null) { 061 return; 062 } 063 064 getClientPopulatedUserData(true).put(theName, theValue); 065 } 066 067 @Operation(summary = "hasUserData", description = "Has user data for `name` been set?") 068 default boolean hasUserData( 069 @Parameter(name = "theName", description = "The user data attribute name") String theName) { 070 if (getClientPopulatedUserData(false) == null) { 071 return false; 072 } else { 073 return getClientPopulatedUserData(true).containsKey(theName); 074 } 075 } 076 077 @Operation( 078 summary = "getUserString", 079 description = "Get a user supplied data value as a string (converting if needed) or null if unset.") 080 default String getUserString( 081 @Parameter(name = "theName", description = "The user data attribute name") String theName) { 082 Object ud = getUserData(theName); 083 if (ud == null) { 084 return null; 085 } 086 if (ud instanceof String) { 087 return (String) ud; 088 } 089 return ud.toString(); 090 } 091 092 @Operation( 093 summary = "getUserInt", 094 description = "Get a user supplied data value as a integer, converting null/unset to 0.") 095 default int getUserInt(@Parameter(name = "theName", description = "The user data attribute name") String theName) { 096 if (!hasUserData(theName)) { 097 return 0; 098 } 099 return (Integer) getUserData(theName); 100 } 101 102 @Operation(summary = "addUserData", description = "Add all entries to the user data. A null value will be ignored.") 103 default void addUserData( 104 @Nullable @Parameter(name = "theExtraData", description = "The data to add") 105 Map<String, Object> theExtraData) { 106 if (theExtraData != null && theExtraData.size() > 0) { 107 final Map<String, Object> map = getClientPopulatedUserData(true); 108 theExtraData.forEach(map::put); 109 } 110 } 111 112 /** 113 * Model objects wishing to implement user data can implement this interface, 114 * and only need to actually implement this method 115 */ 116 Map<String, Object> getClientPopulatedUserData(boolean theCreateIfNull); 117}