All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.launchdarkly.sdk.LDUser Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
package com.launchdarkly.sdk;

import com.google.gson.annotations.JsonAdapter;
import com.launchdarkly.sdk.json.JsonSerializable;
import com.launchdarkly.sdk.json.JsonSerialization;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static java.util.Collections.unmodifiableMap;
import static java.util.Collections.unmodifiableSet;

/**
 * A collection of attributes that can affect flag evaluation, usually corresponding to a user of your application.
 * 

* The only mandatory property is the {@code key}, which must uniquely identify each user; this could be a username * or email address for authenticated users, or a session ID for anonymous users. All other built-in properties are * optional. You may also define custom properties with arbitrary names and values. *

* For a fuller description of user attributes and how they can be referenced in feature flag rules, see the reference * guides on Setting user attributes * and Targeting users. *

* LaunchDarkly defines a standard JSON encoding for user objects, used by the JavaScript SDK and also in analytics * events. {@link LDUser} can be converted to and from JSON in any of these ways: *

    *
  1. With {@link JsonSerialization}. *
  2. With Gson, if and only if you configure your {@code Gson} instance with * {@link com.launchdarkly.sdk.json.LDGson}. *
  3. With Jackson, if and only if you configure your {@code ObjectMapper} instance with * {@link com.launchdarkly.sdk.json.LDJackson}. *
*/ @JsonAdapter(LDUserTypeAdapter.class) public class LDUser implements JsonSerializable { // Note that these fields are all stored internally as LDValue rather than String so that // we don't waste time repeatedly converting them to LDValue in the rule evaluation logic. final LDValue key; final LDValue secondary; final LDValue ip; final LDValue email; final LDValue name; final LDValue avatar; final LDValue firstName; final LDValue lastName; final LDValue anonymous; final LDValue country; final Map custom; Set privateAttributeNames; protected LDUser(Builder builder) { this.key = LDValue.of(builder.key); this.ip = LDValue.of(builder.ip); this.country = LDValue.of(builder.country); this.secondary = LDValue.of(builder.secondary); this.firstName = LDValue.of(builder.firstName); this.lastName = LDValue.of(builder.lastName); this.email = LDValue.of(builder.email); this.name = LDValue.of(builder.name); this.avatar = LDValue.of(builder.avatar); this.anonymous = builder.anonymous == null ? LDValue.ofNull() : LDValue.of(builder.anonymous); this.custom = builder.custom == null ? null : unmodifiableMap(builder.custom); this.privateAttributeNames = builder.privateAttributes == null ? null : unmodifiableSet(builder.privateAttributes); } /** * Create a user with the given key * * @param key a {@code String} that uniquely identifies a user */ public LDUser(String key) { this.key = LDValue.of(key); this.secondary = this.ip = this.email = this.name = this.avatar = this.firstName = this.lastName = this.anonymous = this.country = LDValue.ofNull(); this.custom = null; this.privateAttributeNames = null; } /** * Returns the user's unique key. * * @return the user key as a string */ public String getKey() { return key.stringValue(); } /** * Returns the value of the secondary key property for the user, if set. * * @return a string or null */ public String getSecondary() { return secondary.stringValue(); } /** * Returns the value of the IP property for the user, if set. * * @return a string or null */ public String getIp() { return ip.stringValue(); } /** * Returns the value of the country property for the user, if set. * * @return a string or null */ public String getCountry() { return country.stringValue(); } /** * Returns the value of the full name property for the user, if set. * * @return a string or null */ public String getName() { return name.stringValue(); } /** * Returns the value of the first name property for the user, if set. * * @return a string or null */ public String getFirstName() { return firstName.stringValue(); } /** * Returns the value of the last name property for the user, if set. * * @return a string or null */ public String getLastName() { return lastName.stringValue(); } /** * Returns the value of the email property for the user, if set. * * @return a string or null */ public String getEmail() { return email.stringValue(); } /** * Returns the value of the avatar property for the user, if set. * * @return a string or null */ public String getAvatar() { return avatar.stringValue(); } /** * Returns true if this user was marked anonymous. * * @return true for an anonymous user */ public boolean isAnonymous() { return anonymous.booleanValue(); } /** * Gets the value of a user attribute, if present. *

* This can be either a built-in attribute or a custom one. It returns the value using the {@link LDValue} * type, which can have any type that is supported in JSON. If the attribute does not exist, it returns * {@link LDValue#ofNull()}. * * @param attribute the attribute to get * @return the attribute value or {@link LDValue#ofNull()}; will never be an actual null reference */ public LDValue getAttribute(UserAttribute attribute) { if (attribute.isBuiltIn()) { return attribute.builtInGetter.apply(this); } else { return custom == null ? LDValue.ofNull() : LDValue.normalize(custom.get(attribute)); } } /** * Returns an enumeration of all custom attribute names that were set for this user. * * @return the custom attribute names */ public Iterable getCustomAttributes() { return custom == null ? Collections.emptyList() : custom.keySet(); } /** * Returns an enumeration of all attributes that were marked private for this user. *

* This does not include any attributes that were globally marked private in your SDK configuration. * * @return the names of private attributes for this user */ public Iterable getPrivateAttributes() { return privateAttributeNames == null ? Collections.emptyList() : privateAttributeNames; } /** * Tests whether an attribute has been marked private for this user. * * @param attribute a built-in or custom attribute * @return true if the attribute was marked private on a per-user level */ public boolean isAttributePrivate(UserAttribute attribute) { return privateAttributeNames != null && privateAttributeNames.contains(attribute); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o instanceof LDUser) { LDUser ldUser = (LDUser) o; return Objects.equals(key, ldUser.key) && Objects.equals(secondary, ldUser.secondary) && Objects.equals(ip, ldUser.ip) && Objects.equals(email, ldUser.email) && Objects.equals(name, ldUser.name) && Objects.equals(avatar, ldUser.avatar) && Objects.equals(firstName, ldUser.firstName) && Objects.equals(lastName, ldUser.lastName) && Objects.equals(anonymous, ldUser.anonymous) && Objects.equals(country, ldUser.country) && Objects.equals(custom, ldUser.custom) && Objects.equals(privateAttributeNames, ldUser.privateAttributeNames); } return false; } @Override public int hashCode() { return Objects.hash(key, secondary, ip, email, name, avatar, firstName, lastName, anonymous, country, custom, privateAttributeNames); } @Override public String toString() { return "LDUser(" + JsonSerialization.serialize(this) + ")"; } /** * A builder that helps construct {@link LDUser} objects. Builder * calls can be chained, enabling the following pattern: *

   * LDUser user = new LDUser.Builder("key")
   *      .country("US")
   *      .ip("192.168.0.1")
   *      .build()
   * 
*/ public static class Builder { private String key; private String secondary; private String ip; private String firstName; private String lastName; private String email; private String name; private String avatar; private Boolean anonymous; private String country; private Map custom; private Set privateAttributes; /** * Creates a builder with the specified key. * * @param key the unique key for this user */ public Builder(String key) { this.key = key; } /** * Creates a builder based on an existing user. * * @param user an existing {@code LDUser} */ public Builder(LDUser user) { this.key = user.key.stringValue(); this.secondary = user.secondary.stringValue(); this.ip = user.ip.stringValue(); this.firstName = user.firstName.stringValue(); this.lastName = user.lastName.stringValue(); this.email = user.email.stringValue(); this.name = user.name.stringValue(); this.avatar = user.avatar.stringValue(); this.anonymous = user.anonymous.isNull() ? null : user.anonymous.booleanValue(); this.country = user.country.stringValue(); this.custom = user.custom == null ? null : new HashMap<>(user.custom); this.privateAttributes = user.privateAttributeNames == null ? null : new HashSet<>(user.privateAttributeNames); } /** * Changes the user's key. * * @param s the user key * @return the builder */ public Builder key(String s) { this.key = s; return this; } /** * Sets the IP for a user. * * @param s the IP address for the user * @return the builder */ public Builder ip(String s) { this.ip = s; return this; } /** * Sets the IP for a user, and ensures that the IP attribute is not sent back to LaunchDarkly. * * @param s the IP address for the user * @return the builder */ public Builder privateIp(String s) { addPrivate(UserAttribute.IP); return ip(s); } /** * Sets the secondary key for a user. This affects * feature flag targeting * as follows: if you have chosen to bucket users by a specific attribute, the secondary key (if set) * is used to further distinguish between users who are otherwise identical according to that attribute. * @param s the secondary key for the user * @return the builder */ public Builder secondary(String s) { this.secondary = s; return this; } /** * Sets the secondary key for a user, and ensures that the secondary key attribute is not sent back to * LaunchDarkly. * @param s the secondary key for the user * @return the builder */ public Builder privateSecondary(String s) { addPrivate(UserAttribute.SECONDARY_KEY); return secondary(s); } /** * Set the country for a user. Before version 5.0.0, this field was validated and normalized by the SDK * as an ISO-3166-1 country code before assignment. This behavior has been removed so that the SDK can * treat this field as a normal string, leaving the meaning of this field up to the application. * * @param s the country for the user * @return the builder */ public Builder country(String s) { this.country = s; return this; } /** * Set the country for a user, and ensures that the country attribute will not be sent back to LaunchDarkly. * Before version 5.0.0, this field was validated and normalized by the SDK as an ISO-3166-1 country code * before assignment. This behavior has been removed so that the SDK can treat this field as a normal string, * leaving the meaning of this field up to the application. * * @param s the country for the user * @return the builder */ public Builder privateCountry(String s) { addPrivate(UserAttribute.COUNTRY); return country(s); } /** * Sets the user's first name * * @param firstName the user's first name * @return the builder */ public Builder firstName(String firstName) { this.firstName = firstName; return this; } /** * Sets the user's first name, and ensures that the first name attribute will not be sent back to LaunchDarkly. * * @param firstName the user's first name * @return the builder */ public Builder privateFirstName(String firstName) { addPrivate(UserAttribute.FIRST_NAME); return firstName(firstName); } /** * Sets whether this user is anonymous. * * @param anonymous whether the user is anonymous * @return the builder */ public Builder anonymous(boolean anonymous) { this.anonymous = anonymous; return this; } /** * Sets the user's last name. * * @param lastName the user's last name * @return the builder */ public Builder lastName(String lastName) { this.lastName = lastName; return this; } /** * Sets the user's last name, and ensures that the last name attribute will not be sent back to LaunchDarkly. * * @param lastName the user's last name * @return the builder */ public Builder privateLastName(String lastName) { addPrivate(UserAttribute.LAST_NAME); return lastName(lastName); } /** * Sets the user's full name. * * @param name the user's full name * @return the builder */ public Builder name(String name) { this.name = name; return this; } /** * Sets the user's full name, and ensures that the name attribute will not be sent back to LaunchDarkly. * * @param name the user's full name * @return the builder */ public Builder privateName(String name) { addPrivate(UserAttribute.NAME); return name(name); } /** * Sets the user's avatar. * * @param avatar the user's avatar * @return the builder */ public Builder avatar(String avatar) { this.avatar = avatar; return this; } /** * Sets the user's avatar, and ensures that the avatar attribute will not be sent back to LaunchDarkly. * * @param avatar the user's avatar * @return the builder */ public Builder privateAvatar(String avatar) { addPrivate(UserAttribute.AVATAR); return avatar(avatar); } /** * Sets the user's e-mail address. * * @param email the e-mail address * @return the builder */ public Builder email(String email) { this.email = email; return this; } /** * Sets the user's e-mail address, and ensures that the e-mail address attribute will not be sent back to LaunchDarkly. * * @param email the e-mail address * @return the builder */ public Builder privateEmail(String email) { addPrivate(UserAttribute.EMAIL); return email(email); } /** * Adds a {@link java.lang.String}-valued custom attribute. When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param v the value for the custom attribute * @return the builder */ public Builder custom(String k, String v) { return custom(k, LDValue.of(v)); } /** * Adds an integer-valued custom attribute. When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param n the value for the custom attribute * @return the builder */ public Builder custom(String k, int n) { return custom(k, LDValue.of(n)); } /** * Adds a double-precision numeric custom attribute. When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param n the value for the custom attribute * @return the builder */ public Builder custom(String k, double n) { return custom(k, LDValue.of(n)); } /** * Add a boolean-valued custom attribute. When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param b the value for the custom attribute * @return the builder */ public Builder custom(String k, boolean b) { return custom(k, LDValue.of(b)); } /** * Add a custom attribute whose value can be any JSON type, using {@link LDValue}. When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param v the value for the custom attribute * @return the builder */ public Builder custom(String k, LDValue v) { if (k != null) { return customInternal(UserAttribute.forName(k), v); } return this; } private Builder customInternal(UserAttribute a, LDValue v) { if (custom == null) { custom = new HashMap<>(); } custom.put(a, LDValue.normalize(v)); return this; } /** * Add a {@link java.lang.String}-valued custom attribute that will not be sent back to LaunchDarkly. * When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param v the value for the custom attribute * @return the builder */ public Builder privateCustom(String k, String v) { return privateCustom(k, LDValue.of(v)); } /** * Add an int-valued custom attribute that will not be sent back to LaunchDarkly. * When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param n the value for the custom attribute * @return the builder */ public Builder privateCustom(String k, int n) { return privateCustom(k, LDValue.of(n)); } /** * Add a double-precision numeric custom attribute that will not be sent back to LaunchDarkly. * When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param n the value for the custom attribute * @return the builder */ public Builder privateCustom(String k, double n) { return privateCustom(k, LDValue.of(n)); } /** * Add a boolean-valued custom attribute that will not be sent back to LaunchDarkly. * When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param b the value for the custom attribute * @return the builder */ public Builder privateCustom(String k, boolean b) { return privateCustom(k, LDValue.of(b)); } /** * Add a custom attribute of any JSON type, that will not be sent back to LaunchDarkly. * When set to one of the * built-in * user attribute keys, this custom attribute will be ignored. * * @param k the key for the custom attribute * @param v the value for the custom attribute * @return the builder */ public Builder privateCustom(String k, LDValue v) { if (k != null) { UserAttribute a = UserAttribute.forName(k); addPrivate(a); return customInternal(a, v); } return this; } void addPrivate(UserAttribute attribute) { if (privateAttributes == null) { privateAttributes = new LinkedHashSet<>(); // LinkedHashSet preserves insertion order, for test determinacy } privateAttributes.add(attribute); } /** * Builds the configured {@link LDUser} object. * * @return the {@link LDUser} configured by this builder */ public LDUser build() { return new LDUser(this); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy