├── .github
└── FUNDING.yml
├── .gitignore
├── .travis.yml
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── github
│ │ └── binarywang
│ │ └── java
│ │ └── emoji
│ │ ├── EmojiConverter.java
│ │ ├── EmojiReader.java
│ │ ├── model
│ │ └── Emoji4Unicode.java
│ │ └── util
│ │ └── EmojiUtils.java
└── resources
│ └── emoji4unicode.xml
└── test
└── java
└── com
└── github
└── binarywang
└── java
└── emoji
├── EmojiConverterTest.java
└── EmojiReaderTest.java
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [binarywang]
4 | custom: https://github.com/Wechat-Group/WxJava/blob/master/images/qrcodes/wepay.jpg?raw=true
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .classpath
3 | .project
4 | .settings/
5 | /build/
6 | *.pmd
7 | /.idea/
8 | *.iml
9 | *.versionsBackup
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - openjdk8
4 |
5 | script: "mvn cobertura:cobertura"
6 |
7 | branches:
8 | only:
9 | - main
10 |
11 | notifications:
12 | email:
13 | - binarywang@vip.qq.com
14 |
15 | after_success:
16 | - bash <(curl -s https://codecov.io/bash)
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://gitee.com/binary/java-emoji-converter)
2 | [](https://github.com/binarywang/java-emoji-converter)
3 | [](https://travis-ci.org/binarywang/java-emoji-converter)
4 | [](https://codecov.io/gh/binarywang/java-emoji-converter)
5 | 
6 |
7 | # Java Emoji Converter(Emoji 表情转换工具)
8 |
9 | Emoji转换工具,便于各种规格客户端生成的Emoji字符串转换成另外一种格式。
10 |
11 | A tool to convert emoji string among each type, like softbank emoji, unicode emoji, alias emoji, html emoji.
12 |
13 | When converting softbank emoji to unicode, we utilize this file:
14 | https://raw.githubusercontent.com/googlei18n/emoji4unicode/master/data/emoji4unicode.xml
15 |
16 | ## Quick Start 快速入门
17 |
18 | Add this in your maven pom file(将以下内容加入你的maven的pom文件中):
19 | ```xml
20 |
21 | com.github.binarywang
22 | java-emoji-converter
23 | 1.0.2
24 |
25 | ```
26 |
27 | ## Usage (from junit test):用法(摘自单元测试代码)
28 |
29 | private EmojiConverter emojiConverter = EmojiConverter.getInstance();
30 |
31 | @Test
32 | public void testToAlias() {
33 | String str = " An 😃😀awesome 😃😃string with a few 😃😉emojis!";
34 | String alias = this.emojiConverter.toAlias(str);
35 | System.out.println(str);
36 | System.out.println("EmojiConverterTest.testToAlias()=====>");
37 | System.out.println(alias);
38 | Assert.assertEquals(
39 | ":no_good: :ok_woman: :couple_with_heart:An :smiley::grinning:awesome :smiley::smiley:string with a few :smiley::wink:emojis!",
40 | alias);
41 | }
42 |
43 | @Test
44 | public void testToHtml() {
45 | String str = " An 😀😃awesome 😃😃string with a few 😉😃emojis!";
46 | String result = this.emojiConverter.toHtml(str);
47 | System.out.println(str);
48 | System.out.println("EmojiConverterTest.testToHtml()=====>");
49 | System.out.println(result);
50 | Assert.assertEquals(
51 | "🙅 🙆 💑An 😀😃awesome 😃😃string with a few 😉😃emojis!",
52 | result);
53 | }
54 |
55 | @Test
56 | public void testToUnicode() {
57 | String str = " :smiley: :grinning: :wink:";
58 | String result = this.emojiConverter.toUnicode(str);
59 | System.err.println(str);
60 | System.err.println("EmojiConverterTest.testToUnicode()=====>");
61 | System.err.println(result);
62 | Assert.assertEquals("🙅 🙆 💑 😃 😀 😉", result);
63 | }
64 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.github.binarywang
5 | java-emoji-converter
6 | 1.0.2
7 | jar
8 | Java Emoji Converter
9 | Java Emoji Converter
10 | https://github.com/binarywang/java-emoji-converter
11 |
12 | scm:git:https://github.com/binarywang/java-emoji-converter.git
13 | scm:git:https://github.com/binarywang/java-emoji-converter.git
14 | https://github.com/binarywang/java-emoji-converter
15 | v1.0.0
16 |
17 |
18 | 1.8
19 | 1.8
20 |
21 |
22 | UTF-8
23 | UTF-8
24 |
25 | UTF-8
26 |
27 |
28 |
29 | ossrh
30 | https://oss.sonatype.org/content/repositories/snapshots
31 |
32 |
33 | ossrh
34 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
35 |
36 |
37 |
38 |
39 |
40 | binarywang
41 | binarywang@qq.com
42 |
43 |
44 |
45 |
46 | The Apache License, Version 2.0
47 | http://www.apache.org/licenses/LICENSE-2.0.txt
48 |
49 |
50 |
51 |
52 |
53 | com.vdurmont
54 | emoji-java
55 | 5.1.1
56 |
57 |
58 | com.thoughtworks.xstream
59 | xstream
60 | 1.4.20
61 |
62 |
63 | org.slf4j
64 | slf4j-api
65 | 1.7.36
66 |
67 |
68 | org.jodd
69 | jodd-http
70 | 6.2.1
71 |
72 |
73 | org.apache.commons
74 | commons-lang3
75 | 3.12.0
76 |
77 |
78 | com.google.guava
79 | guava
80 | 32.0.0-jre
81 |
82 |
83 | joda-time
84 | joda-time
85 | 2.10.14
86 |
87 |
88 |
89 | org.slf4j
90 | slf4j-log4j12
91 | 1.7.36
92 | test
93 |
94 |
95 |
96 | org.testng
97 | testng
98 | 7.7.0
99 | test
100 |
101 |
102 |
103 |
104 |
105 | doclint-java8-disable
106 |
107 | [1.8,)
108 |
109 |
110 | -Xdoclint:none
111 |
112 |
113 |
114 |
115 | release
116 |
117 |
118 |
119 | org.codehaus.mojo
120 | cobertura-maven-plugin
121 | 2.7
122 |
123 |
124 | html
125 | xml
126 |
127 |
128 |
129 |
130 |
131 | org.apache.maven.plugins
132 | maven-source-plugin
133 | 2.2.1
134 |
135 |
136 | attach-sources
137 |
138 | jar-no-fork
139 |
140 |
141 |
142 |
143 |
144 | org.apache.maven.plugins
145 | maven-javadoc-plugin
146 | 2.9.1
147 |
148 |
149 | attach-javadocs
150 |
151 | jar
152 |
153 |
154 |
155 |
156 | ${javadoc.opts}
157 | UTF-8
158 | zh_CN
159 |
160 |
161 |
162 | org.apache.maven.plugins
163 | maven-gpg-plugin
164 | 1.5
165 |
166 |
167 | sign-artifacts
168 | verify
169 |
170 | sign
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | org.apache.maven.plugins
185 | maven-surefire-plugin
186 | 2.17
187 |
188 | true
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | org.codehaus.mojo
197 | cobertura-maven-plugin
198 | 2.7
199 |
200 |
201 | html
202 | xml
203 |
204 |
205 |
206 |
207 |
208 | org.sonatype.plugins
209 | nexus-staging-maven-plugin
210 | 1.6.3
211 | true
212 |
213 | ossrh
214 | https://oss.sonatype.org/
215 | true
216 |
217 |
218 |
219 | org.apache.maven.plugins
220 | maven-release-plugin
221 | 2.5.1
222 |
223 | true
224 | false
225 | release
226 | deploy
227 |
228 |
229 |
230 | org.apache.maven.plugins
231 | maven-compiler-plugin
232 | 3.6.0
233 |
234 | UTF-8
235 |
236 |
237 |
238 |
239 | maven-surefire-plugin
240 |
241 | once
242 | -Dfile.encoding=UTF-8
243 |
244 |
245 |
246 |
247 |
248 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/java/emoji/EmojiConverter.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.java.emoji;
2 |
3 | import com.github.binarywang.java.emoji.util.EmojiUtils;
4 | import com.vdurmont.emoji.EmojiParser;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | * @author Binary Wang
12 | */
13 | public class EmojiConverter {
14 | private EmojiReader emojiReader = null;
15 | private final static EmojiConverter INSTANCE = new EmojiConverter();
16 |
17 | private EmojiConverter() {
18 | }
19 |
20 | public static EmojiConverter getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 | /**
25 | * convert emoji string with unicode/softbank to strings with aliases
26 | *
27 | * @param input 输入的字符串内容
28 | * @return result string
29 | */
30 | public String toAlias(String input) {
31 | if (EmojiUtils.containsSbEmoji(input)) {
32 | input = this.sb2Unicode(input);
33 | }
34 |
35 | String result = EmojiParser.parseToAliases(input);
36 | if (result.equals(EmojiParser.parseToAliases(result))) {
37 | return result;
38 | } else {
39 | return EmojiParser.parseToAliases(result);
40 | }
41 |
42 | }
43 |
44 | private String sb2Unicode(String input) {
45 | if (this.emojiReader == null) {
46 | this.emojiReader = new EmojiReader();
47 | }
48 |
49 | final Map, String> sb2UnicodeMap = this.emojiReader.getSb2UnicodeMap();
50 |
51 | StringBuilder result = new StringBuilder();
52 | int[] codePoints = toCodePointArray(input);
53 | for (int i = 0; i < codePoints.length; i++) {
54 | List key2;
55 | if (i + 1 < codePoints.length) {
56 | key2 = new ArrayList<>();
57 | key2.add(codePoints[i]);
58 | key2.add(codePoints[i + 1]);
59 |
60 | if (sb2UnicodeMap.containsKey(key2)) {
61 | String value = sb2UnicodeMap.get(key2);
62 | if (value != null) {
63 | result.append(value);
64 | }
65 |
66 | i++;
67 | continue;
68 | }
69 | }
70 |
71 | List key1 = new ArrayList<>();
72 | key1.add(codePoints[i]);
73 | if (sb2UnicodeMap.containsKey(key1)) {
74 | String value = sb2UnicodeMap.get(key1);
75 | if (value != null) {
76 | result.append(value);
77 | }
78 | continue;
79 | }
80 |
81 | result.append(Character.toChars(codePoints[i]));
82 |
83 | }
84 |
85 | return result.toString();
86 | }
87 |
88 | private static int[] toCodePointArray(String str) {
89 | char[] ach = str.toCharArray();
90 | int len = ach.length;
91 | int[] acp = new int[Character.codePointCount(ach, 0, len)];
92 | int j = 0;
93 |
94 | for (int i = 0, cp; i < len; i += Character.charCount(cp)) {
95 | cp = Character.codePointAt(ach, i);
96 | acp[j++] = cp;
97 | }
98 |
99 | return acp;
100 | }
101 |
102 | /**
103 | * convert emoji string with unicode/softbank to strings with html code
104 | *
105 | * @param input 输入的字符串内容
106 | * @return result string
107 | */
108 | public String toHtml(String input) {
109 | if (EmojiUtils.containsSbEmoji(input)) {
110 | input = sb2Unicode(input);
111 | }
112 |
113 | String result = EmojiParser.parseToHtmlDecimal(input);
114 | if (result.equals(EmojiParser.parseToHtmlDecimal(result))) {
115 | return result;
116 | } else {
117 | return EmojiParser.parseToHtmlDecimal(result);
118 | }
119 | }
120 |
121 | /**
122 | * convert string with softbank/alias emoji to strings with unicode
123 | *
124 | * @param input 输入的字符串内容
125 | * @return result string
126 | */
127 | public String toUnicode(String input) {
128 | if (EmojiUtils.containsSbEmoji(input)) {
129 | input = sb2Unicode(input);
130 | }
131 |
132 | String result = EmojiParser.parseToUnicode(input);
133 | if (result.equals(EmojiParser.parseToUnicode(result))) {
134 | return result;
135 | } else {
136 | return EmojiParser.parseToUnicode(result);
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/java/emoji/EmojiReader.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.java.emoji;
2 |
3 | import com.github.binarywang.java.emoji.model.Emoji4Unicode;
4 | import com.github.binarywang.java.emoji.model.Emoji4Unicode.Category;
5 | import com.github.binarywang.java.emoji.model.Emoji4Unicode.Element;
6 | import com.github.binarywang.java.emoji.model.Emoji4Unicode.SubCategory;
7 | import com.google.common.collect.Maps;
8 | import com.thoughtworks.xstream.XStream;
9 | import com.thoughtworks.xstream.io.xml.DomDriver;
10 | import com.thoughtworks.xstream.security.NoTypePermission;
11 | import com.thoughtworks.xstream.security.WildcardTypePermission;
12 | import org.joda.time.Interval;
13 | import org.slf4j.Logger;
14 | import org.slf4j.LoggerFactory;
15 |
16 | import java.net.URL;
17 | import java.util.ArrayList;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | /**
22 | * @author Binary Wang
23 | */
24 | public class EmojiReader {
25 | private static final Logger logger = LoggerFactory.getLogger(EmojiReader.class);
26 | private static final String URL = "https://raw.githubusercontent.com/googlei18n/emoji4unicode/master/data/emoji4unicode.xml";
27 |
28 | private static final String TRIM_PATTERN = "[^0-9A-F]*";
29 | private Emoji4Unicode emoji = null;
30 | private Map, String> sb2UnicodeMap = null;
31 |
32 | /**
33 | * 从相关文件读取并解析得到Emoji4Unicode对象
34 | *
35 | * @param onlyFromLocal 是否只从本地读取
36 | * @return Emoji4Unicode对象
37 | */
38 | Emoji4Unicode read(boolean onlyFromLocal) {
39 | if (emoji != null) {
40 | return emoji;
41 | }
42 |
43 | long beginTime = System.currentTimeMillis();
44 |
45 | XStream xstream = new XStream(new DomDriver());
46 | xstream.processAnnotations(Emoji4Unicode.class);
47 | xstream.addPermission(NoTypePermission.NONE);
48 | xstream.addPermission(new WildcardTypePermission(new String[]{"com.github.binarywang.**"}));
49 |
50 | if (onlyFromLocal) {
51 | logger.info("==============from local file==============");
52 | emoji = (Emoji4Unicode) xstream.fromXML(EmojiReader.class.getResourceAsStream("/emoji4unicode.xml"));
53 | return emoji;
54 | }
55 |
56 | try {
57 | emoji = (Emoji4Unicode) xstream.fromXML(new URL(URL));
58 | logger.info("==============from url==============");
59 | } catch (Exception e) {
60 | e.printStackTrace();
61 | }
62 |
63 | if (emoji != null) {
64 | String interval = new Interval(beginTime, System.currentTimeMillis())
65 | .toPeriod().toString().replace("PT", "").replace("M", "分")
66 | .replace("S", "秒");
67 | logger.info("从网络读取总耗时: " + interval);
68 | return emoji;
69 | }
70 |
71 | logger.info("==============from local file==============");
72 | emoji = (Emoji4Unicode) xstream.fromXML(
73 | EmojiReader.class.getResourceAsStream("/emoji4unicode.xml"));
74 | return emoji;
75 |
76 | }
77 |
78 | public Map, String> getSb2UnicodeMap() {
79 | if (sb2UnicodeMap != null) {
80 | return sb2UnicodeMap;
81 | }
82 |
83 | sb2UnicodeMap = Maps.newHashMap();
84 |
85 | Emoji4Unicode emoji4Unicode = read(false);
86 | for (Category category : emoji4Unicode.getCategories()) {
87 | List subCategories = category.getSubCategories();
88 | if (subCategories == null) {
89 | continue;
90 | }
91 |
92 | for (SubCategory subCategory : subCategories) {
93 | List elements = subCategory.getElements();
94 | if (elements == null) {
95 | continue;
96 | }
97 |
98 | for (Element element : elements) {
99 | List fromCodePoints = new ArrayList<>();
100 | String fromValue = element.getSoftbank();
101 | if (fromValue == null) {
102 | continue;
103 | }
104 |
105 | if (fromValue.length() > 6) {
106 | String[] froms = fromValue.split("\\+");
107 | for (String part : froms) {
108 | fromCodePoints.add(Integer.parseInt(
109 | part.replaceAll(TRIM_PATTERN, ""), 16));
110 | }
111 | } else {
112 | fromCodePoints.add(Integer.parseInt(
113 | fromValue.replaceAll(TRIM_PATTERN, ""), 16));
114 | }
115 |
116 | String toValue = element.getUnicode();
117 | if (toValue == null) {
118 | sb2UnicodeMap.put(fromCodePoints, null);
119 | continue;
120 | }
121 |
122 | StringBuilder toBuilder = new StringBuilder();
123 | if (toValue.length() > 6) {
124 | String[] tos = toValue.split("\\+");
125 | for (String part : tos) {
126 | toBuilder.append(Character.toChars(Integer.parseInt(
127 | part.replaceAll(TRIM_PATTERN, ""), 16)));
128 | }
129 | } else {
130 | toBuilder.append(Character.toChars(Integer.parseInt(
131 | toValue.replaceAll(TRIM_PATTERN, ""), 16)));
132 | }
133 |
134 | sb2UnicodeMap.put(fromCodePoints, toBuilder.toString());
135 | }
136 | }
137 |
138 | }
139 |
140 | return sb2UnicodeMap;
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/java/emoji/model/Emoji4Unicode.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.java.emoji.model;
2 |
3 |
4 | import java.util.List;
5 |
6 | import org.apache.commons.lang3.builder.ToStringBuilder;
7 | import org.apache.commons.lang3.builder.ToStringStyle;
8 |
9 | import com.thoughtworks.xstream.annotations.XStreamAlias;
10 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
11 | import com.thoughtworks.xstream.annotations.XStreamImplicit;
12 |
13 | @XStreamAlias("emoji4unicode")
14 | public class Emoji4Unicode {
15 | @XStreamImplicit(itemFieldName = "category")
16 | private List categories;
17 |
18 | @XStreamAlias("category")
19 | public static class Category {
20 | @XStreamImplicit(itemFieldName = "subcategory")
21 | private List subCategories;
22 |
23 | @XStreamAsAttribute
24 | private String name;
25 |
26 | @Override
27 | public String toString() {
28 | return toSimpleString(this);
29 | }
30 |
31 | public List getSubCategories() {
32 | return this.subCategories;
33 | }
34 |
35 | public void setSubCategories(List subCategories) {
36 | this.subCategories = subCategories;
37 | }
38 |
39 | public String getName() {
40 | return this.name;
41 | }
42 |
43 | public void setName(String name) {
44 | this.name = name;
45 | }
46 | }
47 |
48 | public static class SubCategory {
49 | @Override
50 | public String toString() {
51 | return toSimpleString(this);
52 | }
53 |
54 | @XStreamImplicit(itemFieldName = "e")
55 | private List elements;
56 |
57 | @XStreamAsAttribute
58 | private String name;
59 |
60 | public List getElements() {
61 | return this.elements;
62 | }
63 |
64 | public void setElements(List elements) {
65 | this.elements = elements;
66 | }
67 |
68 | }
69 |
70 | public static class Element {
71 | @Override
72 | public String toString() {
73 | return toSimpleString(this);
74 | }
75 |
76 | @XStreamAsAttribute
77 | private String name;
78 |
79 | @XStreamAsAttribute
80 | private String docomo;
81 |
82 | @XStreamAsAttribute
83 | private String google;
84 |
85 | @XStreamAsAttribute
86 | private String id;
87 |
88 | @XStreamAsAttribute
89 | private String kddi;
90 |
91 | @XStreamAsAttribute
92 | private String softbank;
93 |
94 | @XStreamAsAttribute
95 | private String unicode;
96 |
97 | @XStreamAsAttribute
98 | private String text_fallback;
99 |
100 | @XStreamAsAttribute
101 | private String text_repr;
102 |
103 | @XStreamAsAttribute
104 | private String img_from;
105 |
106 | @XStreamAsAttribute
107 | private String in_proposal;
108 |
109 | @XStreamAsAttribute
110 | private String glyphRefID;
111 |
112 | @XStreamAsAttribute
113 | private String oldname;
114 |
115 | @XStreamAsAttribute
116 | private String design;
117 |
118 | @XStreamImplicit(itemFieldName = "ann")
119 | private List ann;
120 |
121 | @XStreamImplicit(itemFieldName = "desc")
122 | private List desc;
123 |
124 | public String getName() {
125 | return this.name;
126 | }
127 |
128 | public void setName(String name) {
129 | this.name = name;
130 | }
131 |
132 | public String getDocomo() {
133 | return this.docomo;
134 | }
135 |
136 | public void setDocomo(String docomo) {
137 | this.docomo = docomo;
138 | }
139 |
140 | public String getGoogle() {
141 | return this.google;
142 | }
143 |
144 | public void setGoogle(String google) {
145 | this.google = google;
146 | }
147 |
148 | public String getId() {
149 | return this.id;
150 | }
151 |
152 | public void setId(String id) {
153 | this.id = id;
154 | }
155 |
156 | public String getKddi() {
157 | return this.kddi;
158 | }
159 |
160 | public void setKddi(String kddi) {
161 | this.kddi = kddi;
162 | }
163 |
164 | public String getSoftbank() {
165 | return this.softbank;
166 | }
167 |
168 | public void setSoftbank(String softbank) {
169 | this.softbank = softbank;
170 | }
171 |
172 | public String getUnicode() {
173 | return this.unicode;
174 | }
175 |
176 | public void setUnicode(String unicode) {
177 | this.unicode = unicode;
178 | }
179 |
180 | public String getText_fallback() {
181 | return this.text_fallback;
182 | }
183 |
184 | public void setText_fallback(String text_fallback) {
185 | this.text_fallback = text_fallback;
186 | }
187 |
188 | public String getText_repr() {
189 | return this.text_repr;
190 | }
191 |
192 | public void setText_repr(String text_repr) {
193 | this.text_repr = text_repr;
194 | }
195 |
196 | public String getImg_from() {
197 | return this.img_from;
198 | }
199 |
200 | public void setImg_from(String img_from) {
201 | this.img_from = img_from;
202 | }
203 |
204 | public String getIn_proposal() {
205 | return this.in_proposal;
206 | }
207 |
208 | public void setIn_proposal(String in_proposal) {
209 | this.in_proposal = in_proposal;
210 | }
211 |
212 | public String getGlyphRefID() {
213 | return this.glyphRefID;
214 | }
215 |
216 | public void setGlyphRefID(String glyphRefID) {
217 | this.glyphRefID = glyphRefID;
218 | }
219 |
220 | public String getOldname() {
221 | return this.oldname;
222 | }
223 |
224 | public void setOldname(String oldname) {
225 | this.oldname = oldname;
226 | }
227 |
228 | public List getAnn() {
229 | return this.ann;
230 | }
231 |
232 | public void setAnn(List ann) {
233 | this.ann = ann;
234 | }
235 |
236 | public List getDesc() {
237 | return this.desc;
238 | }
239 |
240 | public void setDesc(List desc) {
241 | this.desc = desc;
242 | }
243 |
244 | }
245 |
246 | public List getCategories() {
247 | return this.categories;
248 | }
249 |
250 | public void setCategories(List categories) {
251 | this.categories = categories;
252 | }
253 |
254 | private static final String LINE_SEPARATOR = "\n";
255 |
256 | public static String toSimpleString(Object obj) {
257 | String toStringResult = ToStringBuilder.reflectionToString(obj,
258 | new SimpleToStringStyle());
259 | String[] split = toStringResult.split(LINE_SEPARATOR);
260 | StringBuilder result = new StringBuilder();
261 | for (String string : split) {
262 | if (string.endsWith("")) {
263 | continue;
264 | }
265 | result.append(string + LINE_SEPARATOR);
266 | }
267 |
268 | if (result.length() == 0) {
269 | return "";
270 | }
271 |
272 | return result.deleteCharAt(result.length() - 1).toString();
273 | }
274 |
275 | static class SimpleToStringStyle extends ToStringStyle {
276 | private static final long serialVersionUID = 7718004986394868800L;
277 |
278 | public SimpleToStringStyle() {
279 | this.setContentStart("[");
280 | this.setFieldSeparator(LINE_SEPARATOR + " ");
281 | this.setFieldSeparatorAtStart(true);
282 | this.setContentEnd(LINE_SEPARATOR + "]");
283 | this.setUseShortClassName(true);
284 | this.setUseIdentityHashCode(false);
285 | }
286 | }
287 | }
288 |
289 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/java/emoji/util/EmojiUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.java.emoji.util;
2 |
3 | import java.util.Set;
4 |
5 | import com.google.common.base.Joiner;
6 | import com.google.common.collect.Sets;
7 |
8 | public class EmojiUtils {
9 |
10 | private static final char[] EMOJI_SOFTBANK_TABLE = { 0x21d4, 0x25b2, 0x25bc,
11 | 0x25cb, 0x25cf, 0x3013, 0xe001, 0xe002, 0xe003, 0xe004, 0xe005, 0xe006,
12 | 0xe007, 0xe008, 0xe009, 0xe00a, 0xe00b, 0xe00c, 0xe00d, 0xe00e, 0xe00f,
13 | 0xe010, 0xe011, 0xe012, 0xe013, 0xe014, 0xe015, 0xe016, 0xe017, 0xe018,
14 | 0xe019, 0xe01a, 0xe01b, 0xe01c, 0xe01d, 0xe01e, 0xe01f, 0xe020, 0xe021,
15 | 0xe022, 0xe023, 0xe024, 0xe025, 0xe026, 0xe027, 0xe028, 0xe029, 0xe02a,
16 | 0xe02b, 0xe02c, 0xe02d, 0xe02e, 0xe02f, 0xe030, 0xe031, 0xe032, 0xe033,
17 | 0xe034, 0xe035, 0xe036, 0xe037, 0xe038, 0xe039, 0xe03a, 0xe03b, 0xe03c,
18 | 0xe03d, 0xe03e, 0xe03f, 0xe040, 0xe041, 0xe042, 0xe043, 0xe044, 0xe045,
19 | 0xe046, 0xe047, 0xe048, 0xe049, 0xe04a, 0xe04b, 0xe04c, 0xe04d, 0xe04e,
20 | 0xe04f, 0xe050, 0xe051, 0xe052, 0xe053, 0xe054, 0xe055, 0xe056, 0xe057,
21 | 0xe058, 0xe059, 0xe05a, 0xe101, 0xe102, 0xe103, 0xe104, 0xe105, 0xe106,
22 | 0xe107, 0xe108, 0xe109, 0xe10a, 0xe10b, 0xe10c, 0xe10d, 0xe10e, 0xe10f,
23 | 0xe110, 0xe111, 0xe112, 0xe113, 0xe114, 0xe115, 0xe116, 0xe117, 0xe118,
24 | 0xe119, 0xe11a, 0xe11b, 0xe11c, 0xe11d, 0xe11e, 0xe11f, 0xe120, 0xe121,
25 | 0xe122, 0xe123, 0xe124, 0xe125, 0xe126, 0xe127, 0xe128, 0xe129, 0xe12a,
26 | 0xe12b, 0xe12c, 0xe12d, 0xe12e, 0xe12f, 0xe130, 0xe131, 0xe132, 0xe133,
27 | 0xe134, 0xe135, 0xe136, 0xe137, 0xe138, 0xe139, 0xe13a, 0xe13b, 0xe13c,
28 | 0xe13d, 0xe13e, 0xe13f, 0xe140, 0xe141, 0xe142, 0xe143, 0xe144, 0xe145,
29 | 0xe146, 0xe147, 0xe148, 0xe149, 0xe14a, 0xe14b, 0xe14c, 0xe14d, 0xe14e,
30 | 0xe14f, 0xe150, 0xe151, 0xe152, 0xe153, 0xe154, 0xe155, 0xe156, 0xe157,
31 | 0xe158, 0xe159, 0xe15a, 0xe201, 0xe202, 0xe203, 0xe204, 0xe205, 0xe206,
32 | 0xe207, 0xe208, 0xe209, 0xe20a, 0xe20b, 0xe20c, 0xe20d, 0xe20e, 0xe20f,
33 | 0xe210, 0xe211, 0xe212, 0xe213, 0xe214, 0xe215, 0xe216, 0xe217, 0xe218,
34 | 0xe219, 0xe21a, 0xe21b, 0xe21c, 0xe21d, 0xe21e, 0xe21f, 0xe220, 0xe221,
35 | 0xe222, 0xe223, 0xe224, 0xe225, 0xe226, 0xe227, 0xe228, 0xe229, 0xe22a,
36 | 0xe22b, 0xe22c, 0xe22d, 0xe22e, 0xe22f, 0xe230, 0xe231, 0xe232, 0xe233,
37 | 0xe234, 0xe235, 0xe236, 0xe237, 0xe238, 0xe239, 0xe23a, 0xe23b, 0xe23c,
38 | 0xe23d, 0xe23e, 0xe23f, 0xe240, 0xe241, 0xe242, 0xe243, 0xe244, 0xe245,
39 | 0xe246, 0xe247, 0xe248, 0xe249, 0xe24a, 0xe24b, 0xe24c, 0xe24d, 0xe24e,
40 | 0xe24f, 0xe250, 0xe251, 0xe252, 0xe253, 0xe301, 0xe302, 0xe303, 0xe304,
41 | 0xe305, 0xe306, 0xe307, 0xe308, 0xe309, 0xe30a, 0xe30b, 0xe30c, 0xe30d,
42 | 0xe30e, 0xe30f, 0xe310, 0xe311, 0xe312, 0xe313, 0xe314, 0xe315, 0xe316,
43 | 0xe317, 0xe318, 0xe319, 0xe31a, 0xe31b, 0xe31c, 0xe31d, 0xe31e, 0xe31f,
44 | 0xe320, 0xe321, 0xe322, 0xe323, 0xe324, 0xe325, 0xe326, 0xe327, 0xe328,
45 | 0xe329, 0xe32a, 0xe32b, 0xe32c, 0xe32d, 0xe32e, 0xe32f, 0xe330, 0xe331,
46 | 0xe332, 0xe333, 0xe334, 0xe335, 0xe336, 0xe337, 0xe338, 0xe339, 0xe33a,
47 | 0xe33b, 0xe33c, 0xe33d, 0xe33e, 0xe33f, 0xe340, 0xe341, 0xe342, 0xe343,
48 | 0xe344, 0xe345, 0xe346, 0xe347, 0xe348, 0xe349, 0xe34a, 0xe34b, 0xe34c,
49 | 0xe34d, 0xe401, 0xe402, 0xe403, 0xe404, 0xe405, 0xe406, 0xe407, 0xe408,
50 | 0xe409, 0xe40a, 0xe40b, 0xe40c, 0xe40d, 0xe40e, 0xe40f, 0xe410, 0xe411,
51 | 0xe412, 0xe413, 0xe414, 0xe415, 0xe416, 0xe417, 0xe418, 0xe419, 0xe41a,
52 | 0xe41b, 0xe41c, 0xe41d, 0xe41e, 0xe41f, 0xe420, 0xe421, 0xe422, 0xe423,
53 | 0xe424, 0xe425, 0xe426, 0xe427, 0xe428, 0xe429, 0xe42a, 0xe42b, 0xe42c,
54 | 0xe42d, 0xe42e, 0xe42f, 0xe430, 0xe431, 0xe432, 0xe433, 0xe434, 0xe435,
55 | 0xe436, 0xe437, 0xe438, 0xe439, 0xe43a, 0xe43b, 0xe43c, 0xe43d, 0xe43e,
56 | 0xe43f, 0xe440, 0xe441, 0xe442, 0xe443, 0xe444, 0xe445, 0xe446, 0xe447,
57 | 0xe448, 0xe449, 0xe44a, 0xe44b, 0xe44c, 0xe501, 0xe502, 0xe503, 0xe504,
58 | 0xe505, 0xe506, 0xe507, 0xe508, 0xe509, 0xe50b, 0xe50c, 0xe50d, 0xe50e,
59 | 0xe50f, 0xe510, 0xe511, 0xe512, 0xe513, 0xe514, 0xe515, 0xe516, 0xe517,
60 | 0xe518, 0xe519, 0xe51a, 0xe51b, 0xe51c, 0xe51d, 0xe51e, 0xe51f, 0xe520,
61 | 0xe521, 0xe522, 0xe523, 0xe524, 0xe525, 0xe526, 0xe527, 0xe528, 0xe529,
62 | 0xe52a, 0xe52b, 0xe52c, 0xe52d, 0xe52e, 0xe52f, 0xe530, 0xe531, 0xe532,
63 | 0xe533, 0xe534, 0xe535, 0xe536, 0xe537, 0xff5e, 0xffe5 };
64 |
65 | private static final Set EMOJI_SET = Sets
66 | .newLinkedHashSetWithExpectedSize(EMOJI_SOFTBANK_TABLE.length);
67 |
68 | static {
69 | for (int i = 0; i < EMOJI_SOFTBANK_TABLE.length; i++) {
70 | EMOJI_SET.add(EMOJI_SOFTBANK_TABLE[i]);
71 | }
72 | }
73 |
74 | public static String allSbEmojis() {
75 | return Joiner.on(" ").join(EMOJI_SET);
76 | }
77 |
78 | public static boolean isSbEmoji(char c) {
79 | return EMOJI_SET.contains(c);
80 | }
81 |
82 | public static boolean containsSbEmoji(String s) {
83 | for (int i = 0; i < s.length(); i++) {
84 | if (isSbEmoji(s.charAt(i))) {
85 | return true;
86 | }
87 | }
88 |
89 | return false;
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/src/test/java/com/github/binarywang/java/emoji/EmojiConverterTest.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.java.emoji;
2 |
3 | import org.apache.log4j.BasicConfigurator;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.testng.annotations.*;
7 |
8 | import static org.testng.Assert.*;
9 |
10 | public class EmojiConverterTest {
11 | private final Logger logger = LoggerFactory.getLogger(this.getClass());
12 |
13 | private final EmojiConverter emojiConverter = EmojiConverter.getInstance();
14 |
15 | @BeforeTest
16 | public void init(){
17 | BasicConfigurator.configure();
18 | }
19 |
20 | @Test
21 | public void testToAlias() {
22 | String str = " An 😃😀awesome 😃😃string with a few 😃😉emojis!";
23 | String alias = this.emojiConverter.toAlias(str);
24 | this.logger.info(str);
25 | this.logger.info("EmojiConverterTest.testToAlias()=====>");
26 | this.logger.info(alias);
27 | assertEquals(
28 | ":no_good: :ok_woman: :couple_with_heart:An :smiley::grinning:awesome :smiley::smiley:string with a few :smiley::wink:emojis!",
29 | alias);
30 | }
31 |
32 | @Test
33 | public void testToHtml() {
34 | String str = " An 😀😃awesome 😃😃string with a few 😉😃emojis!";
35 | String result = this.emojiConverter.toHtml(str);
36 | this.logger.info(str);
37 | this.logger.info("EmojiConverterTest.testToHtml()=====>");
38 | this.logger.info(result);
39 | assertEquals(
40 | "🙅 🙆 💑An 😀😃awesome 😃😃string with a few 😉😃emojis!",
41 | result);
42 | }
43 |
44 | @Test
45 | public void testToUnicode() {
46 | String str = " :smiley: :grinning: :wink:";
47 | String result = this.emojiConverter.toUnicode(str);
48 | this.logger.info(str);
49 | this.logger.info("EmojiConverterTest.testToUnicode()=====>");
50 | this.logger.info(result);
51 | assertEquals("🙅 🙆 💑 😃 😀 😉", result);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/com/github/binarywang/java/emoji/EmojiReaderTest.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.java.emoji;
2 |
3 | import com.github.binarywang.java.emoji.model.Emoji4Unicode;
4 | import org.apache.commons.lang3.builder.ToStringBuilder;
5 | import org.apache.log4j.BasicConfigurator;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.testng.annotations.*;
9 |
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | import static org.testng.AssertJUnit.*;
14 |
15 | public class EmojiReaderTest {
16 | private final Logger logger = LoggerFactory.getLogger(this.getClass());
17 | private EmojiReader emojiReader = new EmojiReader();
18 |
19 | @BeforeTest
20 | public void init(){
21 | BasicConfigurator.configure();
22 | }
23 |
24 | @Test
25 | public void testRead() {
26 | Emoji4Unicode a = this.emojiReader.read(false);
27 | this.logger.info(ToStringBuilder.reflectionToString(a));
28 | assertNotNull(a);
29 | }
30 |
31 | @Test
32 | public void testGetSb2UnicodeMap() {
33 | Map, String> sb2UnicodeMap = this.emojiReader.getSb2UnicodeMap();
34 |
35 | this.logger.info(sb2UnicodeMap.toString());
36 | assertNotNull(sb2UnicodeMap);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------