Skip to content

Commit 130032b

Browse files
authored
feat: support map type variables in user event and item event (#41)
1 parent ff5f9f1 commit 130032b

File tree

10 files changed

+313
-80
lines changed

10 files changed

+313
-80
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@
7575
<scope>test</scope>
7676
</dependency>
7777

78+
<dependency>
79+
<groupId>com.google.code.gson</groupId>
80+
<artifactId>gson</artifactId>
81+
<version>2.8.9</version>
82+
<scope>test</scope>
83+
</dependency>
84+
7885
</dependencies>
7986

8087
<distributionManagement>

src/main/java/io/growing/sdk/java/com/googlecode/protobuf/format/JsonFormat.java

Lines changed: 2 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3838
import java.io.OutputStreamWriter;
3939
import java.math.BigInteger;
4040
import java.nio.charset.Charset;
41-
import java.text.CharacterIterator;
42-
import java.text.StringCharacterIterator;
4341
import java.util.*;
4442
import java.util.regex.Matcher;
4543
import java.util.regex.Pattern;
@@ -54,6 +52,7 @@ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5452
import com.google.protobuf.Descriptors.EnumValueDescriptor;
5553
import com.google.protobuf.Descriptors.FieldDescriptor;
5654

55+
import static io.growing.sdk.java.com.googlecode.protobuf.format.util.JsonUtils.*;
5756
import static io.growing.sdk.java.com.googlecode.protobuf.format.util.TextUtils.*;
5857

5958
/**
@@ -1297,76 +1296,7 @@ public InvalidEscapeSequence(String description) {
12971296
}
12981297

12991298
/**
1300-
* Implements JSON string escaping as specified <a href="http://www.ietf.org/rfc/rfc4627.txt">here</a>.
1301-
* <ul>
1302-
* <li>The following characters are escaped by prefixing them with a '\' : \b,\f,\n,\r,\t,\,"</li>
1303-
* <li>Other control characters in the range 0x0000-0x001F are escaped using the \\uXXXX notation</li>
1304-
* <li>UTF-16 surrogate pairs are encoded using the \\uXXXX\\uXXXX notation</li>
1305-
* <li>any other character is printed as-is</li>
1306-
* </ul>
1307-
*/
1308-
static String escapeText(String input) {
1309-
StringBuilder builder = new StringBuilder(input.length());
1310-
CharacterIterator iter = new StringCharacterIterator(input);
1311-
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
1312-
switch (c) {
1313-
case '\b':
1314-
builder.append("\\b");
1315-
break;
1316-
case '\f':
1317-
builder.append("\\f");
1318-
break;
1319-
case '\n':
1320-
builder.append("\\n");
1321-
break;
1322-
case '\r':
1323-
builder.append("\\r");
1324-
break;
1325-
case '\t':
1326-
builder.append("\\t");
1327-
break;
1328-
case '\\':
1329-
builder.append("\\\\");
1330-
break;
1331-
case '"':
1332-
builder.append("\\\"");
1333-
break;
1334-
default:
1335-
// Check for other control characters
1336-
if (c >= 0x0000 && c <= 0x001F) {
1337-
appendEscapedUnicode(builder, c);
1338-
} else if (Character.isHighSurrogate(c)) {
1339-
// Encode the surrogate pair using 2 six-character sequence (\\uXXXX\\uXXXX)
1340-
appendEscapedUnicode(builder, c);
1341-
c = iter.next();
1342-
if (c == CharacterIterator.DONE) {
1343-
throw new IllegalArgumentException("invalid unicode string: unexpected high surrogate pair value without corresponding low value.");
1344-
}
1345-
appendEscapedUnicode(builder, c);
1346-
} else {
1347-
// Anything else can be printed as-is
1348-
builder.append(c);
1349-
}
1350-
break;
1351-
}
1352-
}
1353-
return builder.toString();
1354-
}
1355-
1356-
static void appendEscapedUnicode(StringBuilder builder, char ch) {
1357-
String prefix = "\\u";
1358-
if (ch < 0x10) {
1359-
prefix = "\\u000";
1360-
} else if (ch < 0x100) {
1361-
prefix = "\\u00";
1362-
} else if (ch < 0x1000) {
1363-
prefix = "\\u0";
1364-
}
1365-
builder.append(prefix).append(Integer.toHexString(ch));
1366-
}
1367-
1368-
/**
1369-
* Un-escape a text string as escaped using {@link #escapeText(String)}.
1299+
* Un-escape a text string as escaped using {@link io.growing.sdk.java.com.googlecode.protobuf.format.util.JsonUtils#escapeText(String)}.
13701300
*/
13711301
static String unescapeText(String input) throws JsonFormat.InvalidEscapeSequence {
13721302
StringBuilder builder = new StringBuilder();
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
Copyright (c) 2009, Orbitz World Wide
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without modification,
6+
are permitted provided that the following conditions are met:
7+
8+
* Redistributions of source code must retain the above copyright notice,
9+
this list of conditions and the following disclaimer.
10+
* Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
* Neither the name of the Orbitz World Wide nor the names of its contributors
14+
may be used to endorse or promote products derived from this software
15+
without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
29+
The JsonUtils implementation is referenced from protobuf-java-format
30+
https://code.google.com/archive/p/protobuf-java-format/
31+
*/
32+
33+
package io.growing.sdk.java.com.googlecode.protobuf.format.util;
34+
35+
import java.text.CharacterIterator;
36+
import java.text.StringCharacterIterator;
37+
38+
public class JsonUtils {
39+
// =================================================================
40+
// Utility functions
41+
//
42+
// Some of these methods are package-private because Descriptors.java uses
43+
// them.
44+
45+
/**
46+
* Implements JSON string escaping as specified <a href="http://www.ietf.org/rfc/rfc4627.txt">here</a>.
47+
* <ul>
48+
* <li>The following characters are escaped by prefixing them with a '\' : \b,\f,\n,\r,\t,\,"</li>
49+
* <li>Other control characters in the range 0x0000-0x001F are escaped using the \\uXXXX notation</li>
50+
* <li>UTF-16 surrogate pairs are encoded using the \\uXXXX\\uXXXX notation</li>
51+
* <li>any other character is printed as-is</li>
52+
* </ul>
53+
*/
54+
public static String escapeText(String input) {
55+
StringBuilder builder = new StringBuilder(input.length());
56+
CharacterIterator iter = new StringCharacterIterator(input);
57+
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
58+
switch (c) {
59+
case '\b':
60+
builder.append("\\b");
61+
break;
62+
case '\f':
63+
builder.append("\\f");
64+
break;
65+
case '\n':
66+
builder.append("\\n");
67+
break;
68+
case '\r':
69+
builder.append("\\r");
70+
break;
71+
case '\t':
72+
builder.append("\\t");
73+
break;
74+
case '\\':
75+
builder.append("\\\\");
76+
break;
77+
case '"':
78+
builder.append("\\\"");
79+
break;
80+
default:
81+
// Check for other control characters
82+
if (c >= 0x0000 && c <= 0x001F) {
83+
appendEscapedUnicode(builder, c);
84+
} else if (Character.isHighSurrogate(c)) {
85+
// Encode the surrogate pair using 2 six-character sequence (\\uXXXX\\uXXXX)
86+
appendEscapedUnicode(builder, c);
87+
c = iter.next();
88+
if (c == CharacterIterator.DONE) {
89+
throw new IllegalArgumentException("invalid unicode string: unexpected high surrogate pair value without corresponding low value.");
90+
}
91+
appendEscapedUnicode(builder, c);
92+
} else {
93+
// Anything else can be printed as-is
94+
builder.append(c);
95+
}
96+
break;
97+
}
98+
}
99+
return builder.toString();
100+
}
101+
102+
static void appendEscapedUnicode(StringBuilder builder, char ch) {
103+
String prefix = "\\u";
104+
if (ch < 0x10) {
105+
prefix = "\\u000";
106+
} else if (ch < 0x100) {
107+
prefix = "\\u00";
108+
} else if (ch < 0x1000) {
109+
prefix = "\\u0";
110+
}
111+
builder.append(prefix).append(Integer.toHexString(ch));
112+
}
113+
}

src/main/java/io/growing/sdk/java/dto/GioCdpItemMessage.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import java.io.Serializable;
88
import java.util.List;
9+
import java.util.Map;
910

1011
/**
1112
* @author : tong.wang
@@ -76,6 +77,14 @@ public <T> Builder addItemVariable(String key, List<T> value) {
7677
return this;
7778
}
7879

80+
public <T> Builder addItemVariable(String key, Map<String, String> value) {
81+
if (key != null && value != null && !value.isEmpty()) {
82+
builder.putAttributes(key, StringUtils.map2Str(value));
83+
}
84+
85+
return this;
86+
}
87+
7988
public Builder addItemVariable(String key, String value) {
8089
if (key != null && value != null) {
8190
builder.putAttributes(key, value);

src/main/java/io/growing/sdk/java/dto/GioCdpUserMessage.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ public <T> Builder addUserVariable(String key, List<T> value) {
114114
return this;
115115
}
116116

117+
public <T> Builder addUserVariable(String key, Map<String, String> value) {
118+
if (key != null && value != null && !value.isEmpty()) {
119+
builder.putAttributes(key, StringUtils.map2Str(value));
120+
}
121+
122+
return this;
123+
}
124+
117125
private Builder addVariableObject(String key, Object value) {
118126
if (key != null && value != null) {
119127
key = key.trim();

src/main/java/io/growing/sdk/java/utils/StringUtils.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package io.growing.sdk.java.utils;
22

3+
import io.growing.sdk.java.com.googlecode.protobuf.format.util.JsonUtils;
4+
35
import java.util.Iterator;
46
import java.util.List;
7+
import java.util.Map;
58

69
/**
710
* @author : tong.wang
@@ -18,6 +21,41 @@ public static boolean isBlank(String value) {
1821
return value == null || value.isEmpty();
1922
}
2023

24+
public static String map2Str(Map<String, String> map) {
25+
try {
26+
if (map != null && !map.isEmpty()) {
27+
boolean printedComma = false;
28+
StringBuilder builder = new StringBuilder("{");
29+
for (Map.Entry<String, String> entry : map.entrySet()) {
30+
String key = entry.getKey();
31+
String value = entry.getValue();
32+
33+
if (key != null && value != null) {
34+
if (printedComma) {
35+
builder.append(",");
36+
} else {
37+
printedComma = true;
38+
}
39+
printField(builder, key);
40+
builder.append(":");
41+
printField(builder, toString(value));
42+
}
43+
}
44+
builder.append("}");
45+
return builder.toString();
46+
}
47+
} catch (Exception ignored) {
48+
}
49+
50+
return "{}";
51+
}
52+
53+
private static void printField(StringBuilder builder, String value) {
54+
builder.append("\"");
55+
builder.append(JsonUtils.escapeText(value));
56+
builder.append("\"");
57+
}
58+
2159
public static <T> String list2Str(List<T> value) {
2260
if (value != null && !value.isEmpty()) {
2361
final String listSplit = "||";

src/main/java/io/growing/sdk/java/utils/VersionInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
public class VersionInfo {
99
private static String version = null;
1010

11-
private static final String defaultVersion = "1.0.13-cdp";
11+
private static final String defaultVersion = "1.0.15-cdp";
1212

1313
public static String getVersion() {
1414
if (version == null) {

src/test/java/io/growing/sdk/java/test/Case0PropertiesTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ public void checkProperties() {
4848
sender = new GrowingAPI.Builder().setDataSourceId(DATASOURCE_ID).setProjectKey(PROJECT_KEY).build();
4949

5050
// check properties
51-
Assert.assertEquals(ConfigUtils.getStringValue("api.host", ""), "http://localhost:8080");
52-
Assert.assertEquals(ConfigUtils.getStringValue("project.id", ""), "123456654321");
53-
Assert.assertEquals(StoreStrategyClient.CURRENT_STRATEGY.name(), "ABORT_POLICY");
51+
Assert.assertEquals("https://www.growingio.com", ConfigUtils.getStringValue("api.host", ""));
52+
Assert.assertEquals("123456654321", ConfigUtils.getStringValue("project.id", ""));
53+
Assert.assertEquals("ABORT_POLICY", StoreStrategyClient.CURRENT_STRATEGY.name());
5454
Assert.assertTrue(RunMode.isProductionMode());
55-
Assert.assertEquals(getStaticField(GioLogger.class, "loggerLevel"), "error");
55+
Assert.assertEquals("error", getStaticField(GioLogger.class, "loggerLevel"));
5656

57-
Assert.assertEquals(getStaticField(AbortPolicyStoreStrategy.class, "THREADS"), Integer.parseInt(magicNumber));
58-
Assert.assertEquals(getStaticField(AbortPolicyStoreStrategy.class, "SEND_INTERVAL"), Integer.parseInt(magicNumber + 1));
59-
Assert.assertEquals(getStaticField(AbortPolicyStoreStrategy.class, "LIMIT"), Integer.parseInt(magicNumber + 2));
57+
Assert.assertEquals(Integer.parseInt(magicNumber), getStaticField(AbortPolicyStoreStrategy.class, "THREADS"));
58+
Assert.assertEquals(Integer.parseInt(magicNumber + 1), getStaticField(AbortPolicyStoreStrategy.class, "SEND_INTERVAL"));
59+
Assert.assertEquals(Integer.parseInt(magicNumber + 2), getStaticField(AbortPolicyStoreStrategy.class, "LIMIT"));
6060
}
6161

6262
private static void setStaticField(Class clazz, String fieldName, Object value) {

0 commit comments

Comments
 (0)