diff --git a/src/main/java/com/google/firebase/remoteconfig/Condition.java b/src/main/java/com/google/firebase/remoteconfig/Condition.java
new file mode 100644
index 000000000..c10498c36
--- /dev/null
+++ b/src/main/java/com/google/firebase/remoteconfig/Condition.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.firebase.remoteconfig;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Strings;
+import com.google.firebase.internal.NonNull;
+import com.google.firebase.internal.Nullable;
+import com.google.firebase.remoteconfig.internal.TemplateResponse.ConditionResponse;
+
+import java.util.Objects;
+
+/**
+ * Represents a Remote Config condition that can be included in a {@link Template}.
+ * A condition targets a specific group of users. A list of these conditions make up
+ * part of a Remote Config template.
+ */
+public final class Condition {
+
+ private String name;
+ private String expression;
+ private TagColor tagColor;
+
+ /**
+ * Creates a new {@link Condition}.
+ *
+ * @param name A non-null, non-empty, and unique name of this condition.
+ * @param expression A non-null and non-empty expression of this condition.
+ */
+ public Condition(@NonNull String name, @NonNull String expression) {
+ this(name, expression, null);
+ }
+
+ /**
+ * Creates a new {@link Condition}.
+ *
+ * @param name A non-null, non-empty, and unique name of this condition.
+ * @param expression A non-null and non-empty expression of this condition.
+ * @param tagColor A color associated with this condition for display purposes in the
+ * Firebase Console. Not specifying this value results in the console picking an
+ * arbitrary color to associate with the condition.
+ */
+ public Condition(@NonNull String name, @NonNull String expression, @Nullable TagColor tagColor) {
+ checkArgument(!Strings.isNullOrEmpty(name), "condition name must not be null or empty");
+ checkArgument(!Strings.isNullOrEmpty(expression),
+ "condition expression must not be null or empty");
+ this.name = name;
+ this.expression = expression;
+ this.tagColor = tagColor;
+ }
+
+ Condition(@NonNull ConditionResponse conditionResponse) {
+ checkNotNull(conditionResponse);
+ this.name = conditionResponse.getName();
+ this.expression = conditionResponse.getExpression();
+ if (conditionResponse.getTagColor() == null) {
+ this.tagColor = TagColor.UNSPECIFIED;
+ } else {
+ this.tagColor = TagColor.valueOf(conditionResponse.getTagColor());
+ }
+ }
+
+ /**
+ * Gets the name of the condition.
+ *
+ * @return The name of the condition.
+ */
+ @NonNull
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the expression of the condition.
+ *
+ * @return The expression of the condition.
+ */
+ @NonNull
+ public String getExpression() {
+ return expression;
+ }
+
+ /**
+ * Gets the tag color of the condition used for display purposes in the Firebase Console.
+ *
+ * @return The tag color of the condition.
+ */
+ @NonNull
+ public TagColor getTagColor() {
+ return tagColor;
+ }
+
+ /**
+ * Sets the name of the condition.
+ *
+ * @param name A non-empty and unique name of this condition.
+ * @return This {@link Condition}.
+ */
+ public Condition setName(@NonNull String name) {
+ checkArgument(!Strings.isNullOrEmpty(name), "condition name must not be null or empty");
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * Sets the expression of the condition.
+ *
+ *
See
+ * condition expressions for the expected syntax of this field.
+ *
+ * @param expression The logic of this condition.
+ * @return This {@link Condition}.
+ */
+ public Condition setExpression(@NonNull String expression) {
+ checkArgument(!Strings.isNullOrEmpty(expression),
+ "condition expression must not be null or empty");
+ this.expression = expression;
+ return this;
+ }
+
+ /**
+ * Sets the tag color of the condition.
+ *
+ *
The color associated with this condition for display purposes in the Firebase Console.
+ * Not specifying this value results in the console picking an arbitrary color to associate
+ * with the condition.
+ *
+ * @param tagColor The tag color of this condition.
+ * @return This {@link Condition}.
+ */
+ public Condition setTagColor(@Nullable TagColor tagColor) {
+ this.tagColor = tagColor;
+ return this;
+ }
+
+ ConditionResponse toConditionResponse() {
+ return new ConditionResponse()
+ .setName(this.name)
+ .setExpression(this.expression)
+ .setTagColor(this.tagColor == null ? null : this.tagColor.getColor());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Condition condition = (Condition) o;
+ return Objects.equals(name, condition.name)
+ && Objects.equals(expression, condition.expression) && tagColor == condition.tagColor;
+ }
+}
diff --git a/src/main/java/com/google/firebase/remoteconfig/TagColor.java b/src/main/java/com/google/firebase/remoteconfig/TagColor.java
new file mode 100644
index 000000000..ed7b8cdf4
--- /dev/null
+++ b/src/main/java/com/google/firebase/remoteconfig/TagColor.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.firebase.remoteconfig;
+
+/**
+ * Colors that are associated with conditions for display purposes in the Firebase Console.
+ */
+public enum TagColor {
+ BLUE("BLUE"),
+ BROWN("BROWN"),
+ CYAN("CYAN"),
+ DEEP_ORANGE("DEEP_ORANGE"),
+ GREEN("GREEN"),
+ INDIGO("INDIGO"),
+ LIME("LIME"),
+ ORANGE("ORANGE"),
+ PINK("PINK"),
+ PURPLE("PURPLE"),
+ TEAL("TEAL"),
+ UNSPECIFIED("CONDITION_DISPLAY_COLOR_UNSPECIFIED");
+
+ private final String color;
+
+ TagColor(String color) {
+ this.color = color;
+ }
+
+ public String getColor() {
+ return color;
+ }
+}
diff --git a/src/main/java/com/google/firebase/remoteconfig/Template.java b/src/main/java/com/google/firebase/remoteconfig/Template.java
index 53e5b6085..902273aa0 100644
--- a/src/main/java/com/google/firebase/remoteconfig/Template.java
+++ b/src/main/java/com/google/firebase/remoteconfig/Template.java
@@ -21,7 +21,9 @@
import com.google.firebase.internal.NonNull;
import com.google.firebase.remoteconfig.internal.TemplateResponse;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -31,23 +33,32 @@ public final class Template {
private String etag;
private Map parameters;
+ private List conditions;
/**
* Creates a new {@link Template}.
*/
public Template() {
parameters = new HashMap<>();
+ conditions = new ArrayList<>();
}
Template(@NonNull TemplateResponse templateResponse) {
checkNotNull(templateResponse);
this.parameters = new HashMap<>();
+ this.conditions = new ArrayList<>();
if (templateResponse.getParameters() != null) {
for (Map.Entry entry
: templateResponse.getParameters().entrySet()) {
this.parameters.put(entry.getKey(), new Parameter(entry.getValue()));
}
}
+ if (templateResponse.getConditions() != null) {
+ for (TemplateResponse.ConditionResponse conditionResponse
+ : templateResponse.getConditions()) {
+ this.conditions.add(new Condition(conditionResponse));
+ }
+ }
}
/**
@@ -70,6 +81,16 @@ public Map getParameters() {
return this.parameters;
}
+ /**
+ * Gets the list of conditions of the template.
+ *
+ * @return A non-null list of conditions
+ */
+ @NonNull
+ public List getConditions() {
+ return conditions;
+ }
+
/**
* Sets the map of parameters of the template.
*
@@ -84,6 +105,19 @@ public Template setParameters(
return this;
}
+ /**
+ * Sets the list of conditions of the template.
+ *
+ * @param conditions A non-null list of conditions in descending order by priority.
+ * @return This {@link Template} instance.
+ */
+ public Template setConditions(
+ @NonNull List conditions) {
+ checkNotNull(conditions, "conditions must not be null.");
+ this.conditions = conditions;
+ return this;
+ }
+
Template setETag(String etag) {
this.etag = etag;
return this;
@@ -91,9 +125,15 @@ Template setETag(String etag) {
TemplateResponse toTemplateResponse() {
Map parameterResponses = new HashMap<>();
- for (Map.Entry entry : parameters.entrySet()) {
+ for (Map.Entry entry : this.parameters.entrySet()) {
parameterResponses.put(entry.getKey(), entry.getValue().toParameterResponse());
}
- return new TemplateResponse().setParameters(parameterResponses);
+ List conditionResponses = new ArrayList<>();
+ for (Condition condition : this.conditions) {
+ conditionResponses.add(condition.toConditionResponse());
+ }
+ return new TemplateResponse()
+ .setParameters(parameterResponses)
+ .setConditions(conditionResponses);
}
}
diff --git a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java
index e36b4583e..cd1463e15 100644
--- a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java
+++ b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java
@@ -18,6 +18,7 @@
import com.google.api.client.util.Key;
+import java.util.List;
import java.util.Map;
/**
@@ -29,16 +30,29 @@ public final class TemplateResponse {
@Key("parameters")
private Map parameters;
+ @Key("conditions")
+ private List conditions;
+
public Map getParameters() {
return parameters;
}
+ public List getConditions() {
+ return conditions;
+ }
+
public TemplateResponse setParameters(
Map parameters) {
this.parameters = parameters;
return this;
}
+ public TemplateResponse setConditions(
+ List conditions) {
+ this.conditions = conditions;
+ return this;
+ }
+
/**
* The Data Transfer Object for parsing Remote Config parameter responses from the
* Remote Config service.
@@ -114,4 +128,47 @@ public ParameterValueResponse setUseInAppDefault(boolean useInAppDefault) {
return this;
}
}
+
+ /**
+ * The Data Transfer Object for parsing Remote Config condition responses from the
+ * Remote Config service.
+ **/
+ public static final class ConditionResponse {
+
+ @Key("name")
+ private String name;
+
+ @Key("expression")
+ private String expression;
+
+ @Key("tagColor")
+ private String tagColor;
+
+ public String getName() {
+ return name;
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public String getTagColor() {
+ return tagColor;
+ }
+
+ public ConditionResponse setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public ConditionResponse setExpression(String expression) {
+ this.expression = expression;
+ return this;
+ }
+
+ public ConditionResponse setTagColor(String tagColor) {
+ this.tagColor = tagColor;
+ return this;
+ }
+ }
}
diff --git a/src/test/java/com/google/firebase/remoteconfig/ConditionTest.java b/src/test/java/com/google/firebase/remoteconfig/ConditionTest.java
new file mode 100644
index 000000000..1c8b8cd57
--- /dev/null
+++ b/src/test/java/com/google/firebase/remoteconfig/ConditionTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.firebase.remoteconfig;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+
+public class ConditionTest {
+
+ @Test
+ public void testEquality() {
+ final Condition conditionOne = new Condition("ios", "device.os == 'ios'", TagColor.GREEN);
+ final Condition conditionTwo = new Condition("ios", "device.os == 'ios'", TagColor.GREEN);
+ final Condition conditionThree = new Condition("android", "device.os == 'android'");
+ final Condition conditionFour = new Condition("android", "device.os == 'android'");
+ final Condition conditionFive = new Condition("ios", "device.os == 'ios'", TagColor.BLUE);
+
+ assertEquals(conditionOne, conditionTwo);
+ assertEquals(conditionThree, conditionFour);
+ assertNotEquals(conditionOne, conditionThree);
+ assertNotEquals(conditionTwo, conditionFour);
+ assertNotEquals(conditionOne, conditionFive);
+ }
+}
diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java
index d733ed71a..aabc98a26 100644
--- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java
+++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java
@@ -86,6 +86,7 @@ public void testGetTemplate() throws Exception {
Template template = client.getTemplate();
+ // Check Parameters
assertEquals(TEST_ETAG, template.getETag());
Map parameters = template.getParameters();
assertEquals(2, parameters.size());
@@ -107,6 +108,20 @@ public void testGetTemplate() throws Exception {
assertTrue(
headerParameter.getDefaultValue() instanceof ParameterValue.InAppDefault);
checkGetRequestHeader(interceptor.getLastRequest());
+
+ // Check Conditions
+ List actualConditions = template.getConditions();
+ List expectedConditions = ImmutableList.of(
+ new Condition("ios_en", "device.os == 'ios' && device.country in ['us', 'uk']")
+ .setTagColor(TagColor.INDIGO),
+ new Condition("android_en",
+ "device.os == 'android' && device.country in ['us', 'uk']")
+ .setTagColor(TagColor.UNSPECIFIED)
+ );
+ assertEquals(expectedConditions.size(), actualConditions.size());
+ for (int i = 0; i < expectedConditions.size(); i++) {
+ assertEquals(expectedConditions.get(i), actualConditions.get(i));
+ }
}
@Test
diff --git a/src/test/resources/getRemoteConfig.json b/src/test/resources/getRemoteConfig.json
index 86322f267..df54117bb 100644
--- a/src/test/resources/getRemoteConfig.json
+++ b/src/test/resources/getRemoteConfig.json
@@ -7,8 +7,7 @@
},
{
"name": "android_en",
- "expression": "device.os == 'android' && device.country in ['us', 'uk']",
- "tagColor": "GREEN"
+ "expression": "device.os == 'android' && device.country in ['us', 'uk']"
}
],
"parameters": {