![JAR search and dependency download from the Maven repository](/logo.png)
com.whaleal.icefrog.extra.emoji.factory.EmojiFactory Maven / Gradle / Ivy
package com.whaleal.icefrog.extra.emoji.factory;
import com.whaleal.icefrog.extra.emoji.exception.EmojiException;
import com.whaleal.icefrog.extra.emoji.loader.EmojiDataLoader;
import com.whaleal.icefrog.extra.emoji.loader.EmojiTrie;
import com.whaleal.icefrog.extra.emoji.loader.impl.LocalEmojiDataLoader;
import com.whaleal.icefrog.extra.emoji.model.AliasCandidate;
import com.whaleal.icefrog.extra.emoji.model.Emoji;
import com.whaleal.icefrog.extra.emoji.model.UnicodeCandidate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* emoji factory
*
* @author xuxueli 2018-07-06 20:15:22
*/
public class EmojiFactory {
private static List ALL_EMOJIS = null; // all emoji
private static EmojiTrie EMOJI_TRIE = null; // tree trie
private static Map EMOJIS_BY_ALIAS = null; // alias-emoji, N:1
private static Map> EMOJIS_BY_TAG = null; // tag-emoji, N:1
private static EmojiDataLoader emojiLoader = new LocalEmojiDataLoader();
public static void setEmojiLoader(EmojiDataLoader emojiLoader) {
EmojiFactory.emojiLoader = emojiLoader;
}
public static void loadEmoji(){
List emojis = emojiLoader.loadEmojiData();
if (emojis==null || emojis.size()==0) {
throw new EmojiException("emoji loader fail");
}
ALL_EMOJIS = emojis;
EMOJI_TRIE = new EmojiTrie(ALL_EMOJIS);
EMOJIS_BY_ALIAS = new HashMap();
EMOJIS_BY_TAG = new HashMap>();
for (Emoji emoji : ALL_EMOJIS) {
for (String alias : emoji.getAliases()) {
EMOJIS_BY_ALIAS.put(alias, emoji);
}
for (String tag : emoji.getTags()) {
if (EMOJIS_BY_TAG.get(tag) == null) {
EMOJIS_BY_TAG.put(tag, new HashSet());
}
EMOJIS_BY_TAG.get(tag).add(emoji);
}
}
}
static {
loadEmoji();
}
// ---------------------- get unicode/alias emoji util ----------------------
public static Emoji getForAlias(String alias) {
if (alias == null) {
return null;
}
return EMOJIS_BY_ALIAS.get(trimAlias(alias));
}
private static String trimAlias(String alias) {
String result = alias;
if (result.startsWith(":")) {
result = result.substring(1, result.length());
}
if (result.endsWith(":")) {
result = result.substring(0, result.length() - 1);
}
return result;
}
public static Set getForTag(String tag) {
if (tag == null) {
return null;
}
return EMOJIS_BY_TAG.get(tag);
}
public static Set getAllTags() {
return EMOJIS_BY_TAG.keySet();
}
public static Emoji getByUnicode(String unicode) {
if (unicode == null) {
return null;
}
return EMOJI_TRIE.getEmoji(unicode);
}
public static List getAll() {
return ALL_EMOJIS;
}
// ------------------------ find unicode/alias emoji util ------------------------
private static final Pattern ALIAS_CANDIDATE_PATTERN = Pattern.compile("(?<=:)\\+?(\\w|\\||\\-)+(?=:)");
/**
* find AliasCandidate (alias) for each emoji alias
*
* @param input input
* @return return
*/
public static List getAliasCandidates(String input) {
List candidates = new ArrayList();
Matcher matcher = ALIAS_CANDIDATE_PATTERN.matcher(input);
matcher = matcher.useTransparentBounds(true);
while (matcher.find()) {
String match = matcher.group();
if (!match.contains("|")) {
candidates.add(new AliasCandidate(match, match, null));
} else {
String[] splitted = match.split("\\|");
if (splitted.length == 2 || splitted.length > 2) {
candidates.add(new AliasCandidate(match, splitted[0], splitted[1]));
} else {
candidates.add(new AliasCandidate(match, match, null));
}
}
}
return candidates;
}
/**
* find UnicodeCandidate (unicode) for each unicode emoji, include Fitzpatrick modifier if follwing emoji.
*
* Finally, it contains start and end index of unicode emoji itself (WITHOUT Fitzpatrick modifier whether it is there or not!).
*
* @param input input
* @return return
*/
public static List getUnicodeCandidates(String input) {
char[] inputCharArray = input.toCharArray();
List candidates = new ArrayList();
UnicodeCandidate next;
for (int i = 0; (next = getNextUnicodeCandidate(inputCharArray, i)) != null; i = next.getFitzpatrickEndIndex()) {
candidates.add(next);
}
return candidates;
}
/**
* find next UnicodeCandidate after given starting index
*
* @param chars chars
* @param start start
* @return return
*/
protected static UnicodeCandidate getNextUnicodeCandidate(char[] chars, int start) {
for (int i = start; i < chars.length; i++) {
int emojiEnd = getFirstEmojiEndPos(chars, i);
if (emojiEnd != -1) {
Emoji emoji = EmojiFactory.getByUnicode(new String(chars, i, emojiEnd - i));
String fitzpatrickString = (emojiEnd + 2 <= chars.length) ? new String(chars, emojiEnd, 2) : null;
return new UnicodeCandidate(emoji, fitzpatrickString, i);
}
}
return null;
}
/**
* find end index of first unicode emoji, starting at index startPos, -1 if not found
*
* match the longest matching emoji, when emoji contain others
*
* @param text start
* @param startPos startPos
* @return return
*/
protected static int getFirstEmojiEndPos(char[] text, int startPos) {
int best = -1;
for (int j = startPos + 1; j <= text.length; j++) {
EmojiTrie.Matches status = EMOJI_TRIE.isEmoji(Arrays.copyOfRange(text, startPos, j));
if (status.exactMatch()) {
best = j;
} else if (status.impossibleMatch()) {
return best;
}
}
return best;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy