Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Update Javadoc when setting custom attributes for users. #53

Merged
merged 4 commits into from
May 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 98 additions & 39 deletions src/main/java/com/launchdarkly/client/LDUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
* A {@code LDUser} object contains specific attributes of a user browsing your site. The only mandatory property property is the {@code key},
* which must uniquely identify each user. For authenticated users, this may be a username or e-mail address. For anonymous users,
* this could be an IP address or session ID.
*
* <p>
* Besides the mandatory {@code key}, {@code LDUser} supports two kinds of optional attributes: interpreted attributes (e.g. {@code ip} and {@code country})
* and custom attributes. LaunchDarkly can parse interpreted attributes and attach meaning to them. For example, from an {@code ip} address, LaunchDarkly can
* do a geo IP lookup and determine the user's country.
*
* <p>
* Custom attributes are not parsed by LaunchDarkly. They can be used in custom rules-- for example, a custom attribute such as "customer_ranking" can be used to
* launch a feature to the top 10% of users on a site.
*/
Expand All @@ -33,7 +33,6 @@ public class LDUser {
private JsonPrimitive firstName;
private JsonPrimitive lastName;
private JsonPrimitive anonymous;

private JsonPrimitive country;
private Map<String, JsonElement> custom;
private static final Logger logger = LoggerFactory.getLogger(LDUser.class);
Expand All @@ -44,21 +43,22 @@ public class LDUser {
}

protected LDUser(Builder builder) {
this.key = builder.key == null? null : new JsonPrimitive(builder.key);
this.ip = builder.ip == null? null : new JsonPrimitive(builder.ip);
this.country = builder.country == null? null : new JsonPrimitive(builder.country.getAlpha2());
this.key = builder.key == null ? null : new JsonPrimitive(builder.key);
this.ip = builder.ip == null ? null : new JsonPrimitive(builder.ip);
this.country = builder.country == null ? null : new JsonPrimitive(builder.country.getAlpha2());
this.secondary = builder.secondary == null ? null : new JsonPrimitive(builder.secondary);
this.firstName = builder.firstName == null ? null : new JsonPrimitive(builder.firstName);
this.lastName = builder.lastName == null ? null : new JsonPrimitive(builder.lastName);
this.email = builder.email == null ? null : new JsonPrimitive(builder.email);
this.name = builder.name == null ? null : new JsonPrimitive(builder.name);
this.avatar = builder.avatar == null ? null : new JsonPrimitive(builder.avatar);
this.anonymous = builder.anonymous == null ? null : new JsonPrimitive(builder.anonymous);
this.anonymous = builder.anonymous == null ? null : new JsonPrimitive(builder.anonymous);
this.custom = new HashMap<>(builder.custom);
}

/**
* Create a user with the given key
*
* @param key a {@code String} that uniquely identifies a user
*/
public LDUser(String key) {
Expand All @@ -70,23 +70,41 @@ JsonPrimitive getKey() {
return key;
}

JsonPrimitive getIp() { return ip; }
JsonPrimitive getIp() {
return ip;
}

JsonPrimitive getCountry() { return country; }
JsonPrimitive getCountry() {
return country;
}

JsonPrimitive getSecondary() { return secondary; }
JsonPrimitive getSecondary() {
return secondary;
}

JsonPrimitive getName() { return name; }
JsonPrimitive getName() {
return name;
}

JsonPrimitive getFirstName() { return firstName; }
JsonPrimitive getFirstName() {
return firstName;
}

JsonPrimitive getLastName() { return lastName; }
JsonPrimitive getLastName() {
return lastName;
}

JsonPrimitive getEmail() { return email; }
JsonPrimitive getEmail() {
return email;
}

JsonPrimitive getAvatar() { return avatar; }
JsonPrimitive getAvatar() {
return avatar;
}

JsonPrimitive getAnonymous() { return anonymous; }
JsonPrimitive getAnonymous() {
return anonymous;
}

JsonElement getCustom(String key) {
return custom.get(key);
Expand All @@ -95,14 +113,13 @@ JsonElement getCustom(String key) {
/**
* A <a href="http://en.wikipedia.org/wiki/Builder_pattern">builder</a> that helps construct {@link com.launchdarkly.client.LDUser} objects. Builder
* calls can be chained, enabling the following pattern:
*
* <p>
* <pre>
* LDUser user = new LDUser.Builder("key")
* .country("US")
* .ip("192.168.0.1")
* .build()
* </pre>
*
*/
public static class Builder {
private String key;
Expand All @@ -119,6 +136,7 @@ public static class Builder {

/**
* Create a builder with the specified key
*
* @param key the unique key for this user
*/
public Builder(String key) {
Expand All @@ -128,6 +146,7 @@ public Builder(String key) {

/**
* Set the IP for a user
*
* @param s the IP address for the user
* @return the builder
*/
Expand All @@ -145,6 +164,7 @@ public Builder secondary(String s) {
* Set the country for a user. The country should be a valid <a href="http://en.wikipedia.org/wiki/ISO_3166-1">ISO 3166-1</a>
* alpha-2 or alpha-3 code. If it is not a valid ISO-3166-1 code, an attempt will be made to look up the country by its name.
* If that fails, a warning will be logged, and the country will not be set.
*
* @param s the country for the user
* @return the builder
*/
Expand All @@ -156,8 +176,7 @@ public Builder country(String s) {

if (codes.isEmpty()) {
logger.warn("Invalid country. Expected valid ISO-3166-1 code: " + s);
}
else if (codes.size() > 1) {
} else if (codes.size() > 1) {
// See if any of the codes is an exact match
for (LDCountryCode c : codes) {
if (c.getName().equals(s)) {
Expand All @@ -167,8 +186,7 @@ else if (codes.size() > 1) {
}
logger.warn("Ambiguous country. Provided code matches multiple countries: " + s);
country = codes.get(0);
}
else {
} else {
country = codes.get(0);
}

Expand All @@ -189,6 +207,7 @@ public Builder country(LDCountryCode country) {

/**
* Sets the user's first name
*
* @param firstName the user's first name
* @return the builder
*/
Expand All @@ -199,6 +218,7 @@ public Builder firstName(String firstName) {

/**
* Sets whether this user is anonymous
*
* @param anonymous whether the user is anonymous
* @return the builder
*/
Expand All @@ -209,6 +229,7 @@ public Builder anonymous(boolean anonymous) {

/**
* Sets the user's last name
*
* @param lastName the user's last name
* @return the builder
*/
Expand All @@ -219,6 +240,7 @@ public Builder lastName(String lastName) {

/**
* Sets the user's full name
*
* @param name the user's full name
* @return the builder
*/
Expand All @@ -229,6 +251,7 @@ public Builder name(String name) {

/**
* Sets the user's avatar
*
* @param avatar the user's avatar
* @return the builder
*/
Expand All @@ -239,6 +262,7 @@ public Builder avatar(String avatar) {

/**
* Sets the user's e-mail address
*
* @param email the e-mail address
* @return the builder
*/
Expand All @@ -248,62 +272,83 @@ public Builder email(String email) {
}

/**
* Add a {@link java.lang.String}-valued custom attribute
* @param k the key for the custom attribute
* Add a {@link java.lang.String}-valued custom attribute. When set to one of the
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
* built-in user attribute keys</a>, 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
* @see
*/
public Builder custom(String k, String v) {
if (key != null && v != null) {
checkCustomAttribute(k);
if (k != null && v != null) {
custom.put(k, new JsonPrimitive(v));
}
return this;
}

/**
* Add a {@link java.lang.Number}-valued custom attribute
* @param k the key for the custom attribute
* Add a {@link java.lang.Number}-valued custom attribute. When set to one of the
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
* built-in user attribute keys</a>, this custom attribute will be ignored.
*
* @param k the key for the custom attribute. When set to one of the built-in user attribute keys, this custom attribute will be ignored.
* @param n the value for the custom attribute
* @return the builder
*/
public Builder custom(String k, Number n) {
if (key != null && n != null) {
checkCustomAttribute(k);
if (k != null && n != null) {
custom.put(k, new JsonPrimitive(n));
}
return this;
}

/**
* Add a {@link java.lang.Boolean}-valued custom attribute
* @param k the key for the custom attribute
* Add a {@link java.lang.Boolean}-valued custom attribute. When set to one of the
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
* built-in user attribute keys</a>, this custom attribute will be ignored.
*
* @param k the key for the custom attribute. When set to one of the built-in user attribute keys, this custom attribute will be ignored.
* @param b the value for the custom attribute
* @return the builder
*/
public Builder custom(String k, Boolean b) {
if (key != null && b != null) {
checkCustomAttribute(k);
if (k != null && b != null) {
custom.put(k, new JsonPrimitive(b));
}
return this;
}

/**
* Add a list of {@link java.lang.String}-valued custom attributes
* @param k the key for the list
* Add a list of {@link java.lang.String}-valued custom attributes. When set to one of the
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
* built-in user attribute keys</a>, this custom attribute will be ignored.
*
* @param k the key for the list. When set to one of the built-in user attribute keys, this custom attribute will be ignored.
* @param vs the values for the attribute
* @return the builder
* @deprecated As of version 0.16.0, renamed to {@link #customString(String, List) customString}
*/
public Builder custom(String k, List<String> vs) {
checkCustomAttribute(k);
return this.customString(k, vs);
}

/**
* Add a list of {@link java.lang.String}-valued custom attributes
* @param k the key for the list
* Add a list of {@link java.lang.String}-valued custom attributes. When set to one of the
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
* built-in user attribute keys</a>, this custom attribute will be ignored.
*
* @param k the key for the list. When set to one of the built-in user attribute keys, this custom attribute will be ignored.
* @param vs the values for the attribute
* @return the builder
*/
public Builder customString(String k, List<String> vs) {
checkCustomAttribute(k);
JsonArray array = new JsonArray();
for (String v : vs) {
if (v != null) {
Expand All @@ -313,14 +358,18 @@ public Builder customString(String k, List<String> vs) {
custom.put(k, array);
return this;
}

/**
* Add a list of {@link java.lang.Integer}-valued custom attributes
* @param k the key for the list
* Add a list of {@link java.lang.Integer}-valued custom attributes. When set to one of the
* <a href="http://docs.launchdarkly.com/docs/targeting-users#targeting-based-on-user-attributes">
* built-in user attribute keys</a>, this custom attribute will be ignored.
*
* @param k the key for the list. When set to one of the built-in user attribute keys, this custom attribute will be ignored.
* @param vs the values for the attribute
* @return the builder
*/
public Builder customNumber(String k, List<Number> vs) {
checkCustomAttribute(k);
JsonArray array = new JsonArray();
for (Number v : vs) {
if (v != null) {
Expand All @@ -331,8 +380,18 @@ public Builder customNumber(String k, List<Number> vs) {
return this;
}

private void checkCustomAttribute(String key) {
for (UserAttribute a : UserAttribute.values()) {
if (a.name().equals(key)) {
logger.warn("Built-in attribute key: " + key + " added as custom attribute! This custom attribute will be ignored during Feature Flag evaluation");
return;
}
}
}

/**
* Build the configured {@link com.launchdarkly.client.LDUser} object
*
* @return the {@link com.launchdarkly.client.LDUser} configured by this builder
*/
public LDUser build() {
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/launchdarkly/client/UserAttribute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.launchdarkly.client;

enum UserAttribute {
key,
secondary,
ip,
email,
name,
avatar,
firstName,
lastName,
anonymous,
country
}