package com.netease.nim.uikit.cache;
import android.text.TextUtils;
import com.netease.nim.uikit.NimUIKit;
import com.netease.nim.uikit.UIKitLogTag;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.team.TeamService;
import com.netease.nimlib.sdk.team.TeamServiceObserver;
import com.netease.nimlib.sdk.team.constant.TeamTypeEnum;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.team.model.TeamMember;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 群信息/群成员数据监听&缓存
* <p/>
* Created by huangjun on 2015/3/1.
*/
public class TeamDataCache {
private static TeamDataCache instance;
public static synchronized TeamDataCache getInstance() {
if (instance == null) {
instance = new TeamDataCache();
}
return instance;
}
public void buildCache() {
final List<Team> teams = NIMClient.getService(TeamService.class).queryTeamListBlock();
LogUtil.i(UIKitLogTag.TEAM_CACHE, "start build TeamDataCache");
addOrUpdateTeam(teams);
LogUtil.i(UIKitLogTag.TEAM_CACHE, "build TeamDataCache completed, team count = " + teams.size());
}
public void clear() {
clearTeamCache();
clearTeamMemberCache();
}
/**
* *
* ******************************************** 观察者 ********************************************
*/
public interface TeamDataChangedObserver {
void onUpdateTeams(List<Team> teams);
void onRemoveTeam(Team team);
}
public interface TeamMemberDataChangedObserver {
void onUpdateTeamMember(List<TeamMember> members);
void onRemoveTeamMember(TeamMember member);
}
private List<TeamDataChangedObserver> teamObservers = new ArrayList<>();
private List<TeamMemberDataChangedObserver> memberObservers = new ArrayList<>();
public void registerObservers(boolean register) {
NIMClient.getService(TeamServiceObserver.class).observeTeamUpdate(teamUpdateObserver, register);
NIMClient.getService(TeamServiceObserver.class).observeTeamRemove(teamRemoveObserver, register);
NIMClient.getService(TeamServiceObserver.class).observeMemberUpdate(memberUpdateObserver, register);
NIMClient.getService(TeamServiceObserver.class).observeMemberRemove(memberRemoveObserver, register);
}
// 群资料变动观察者通知。新建群和群更新的通知都通过该接口传递
private Observer<List<Team>> teamUpdateObserver = new Observer<List<Team>>() {
@Override
public void onEvent(final List<Team> teams) {
if (teams != null) {
LogUtil.i(UIKitLogTag.TEAM_CACHE, "team update size:" + teams.size());
}
addOrUpdateTeam(teams);
notifyTeamDataUpdate(teams);
}
};
// 移除群的观察者通知。自己退群,群被解散,自己被踢出群时,会收到该通知
private Observer<Team> teamRemoveObserver = new Observer<Team>() {
@Override
public void onEvent(Team team) {
// team的flag被更新,isMyTeam为false
addOrUpdateTeam(team);
notifyTeamDataRemove(team);
}
};
// 群成员资料变化观察者通知。可通过此接口更新缓存。
private Observer<List<TeamMember>> memberUpdateObserver = new Observer<List<TeamMember>>() {
@Override
public void onEvent(List<TeamMember> members) {
addOrUpdateTeamMembers(members);
notifyTeamMemberDataUpdate(members);
}
};
// 移除群成员的观察者通知。
private Observer<TeamMember> memberRemoveObserver = new Observer<TeamMember>() {
@Override
public void onEvent(TeamMember member) {
// member的validFlag被更新,isInTeam为false
addOrUpdateTeamMember(member);
notifyTeamMemberRemove(member);
}
};
public void registerTeamDataChangedObserver(TeamDataChangedObserver o) {
if (teamObservers.contains(o)) {
return;
}
teamObservers.add(o);
}
public void unregisterTeamDataChangedObserver(TeamDataChangedObserver o) {
teamObservers.remove(o);
}
public void registerTeamMemberDataChangedObserver(TeamMemberDataChangedObserver o) {
if (memberObservers.contains(o)) {
return;
}
memberObservers.add(o);
}
public void unregisterTeamMemberDataChangedObserver(TeamMemberDataChangedObserver o) {
memberObservers.remove(o);
}
private void notifyTeamDataUpdate(List<Team> teams) {
for (TeamDataChangedObserver o : teamObservers) {
o.onUpdateTeams(teams);
}
}
private void notifyTeamDataRemove(Team team) {
for (TeamDataChangedObserver o : teamObservers) {
o.onRemoveTeam(team);
}
}
private void notifyTeamMemberDataUpdate(List<TeamMember> members) {
for (TeamMemberDataChangedObserver o : memberObservers) {
o.onUpdateTeamMember(members);
}
}
private void notifyTeamMemberRemove(TeamMember member) {
for (TeamMemberDataChangedObserver o : memberObservers) {
o.onRemoveTeamMember(member);
}
}
/**
* *
* ******************************************** 群资料缓存 ********************************************
*/
private Map<String, Team> id2TeamMap = new ConcurrentHashMap<>();
public void clearTeamCache() {
id2TeamMap.clear();
}
/**
* 异步获取Team(先从SDK DB中查询,如果不存在,则去服务器查询)
*/
public void fetchTeamById(final String teamId, final SimpleCallback<Team> callback) {
NIMClient.getService(TeamService.class).queryTeam(teamId).setCallback(new RequestCallbackWrapper<Team>() {
@Override
public void onResult(int code, Team t, Throwable exception) {
boolean success = true;
if (code == ResponseCode.RES_SUCCESS) {
addOrUpdateTeam(t);
} else {
success = false;
LogUtil.e(UIKitLogTag.TEAM_CACHE, "fetchTeamById failed, code=" + code);
}
if (exception != null) {
success = false;
LogUtil.e(UIKitLogTag.TEAM_CACHE, "fetchTeamById throw exception, e=" + exception.getMessage());
}
if (callback != null) {
callback.onResult(success, t);
}
}
});
}
/**
* 同步从本地获取Team(先从缓存中查询,如果不存在再从SDK DB中查询)
*/
public Team getTeamById(String teamId) {
Team team = id2TeamMap.get(teamId);
if (team == null) {
team = NIMClient.getService(TeamService.class).queryTeamBlock(teamId);
addOrUpdateTeam(team);
}
return team;
}
public String getTeamName(String teamId) {
Team team = getTeamById(teamId);
return team == null ? teamId : TextUtils.isEmpty(team.getName()) ? team.getId() : team
.getName();
}
public List<Team> getAllTeams() {
List<Team> teams = new ArrayList<>();
for (Team t : id2TeamMap.values()) {
if (t.isMyTeam()) {
teams.add(t);
}
}
return teams;
}
public List<Team> getAllAdvancedTeams() {
return getAllTeamsByType(TeamTypeEnum.Advanced);
}
public List<Team> getAllNormalTeams() {
return getAllTeamsByType(TeamTypeEnum.Normal);
}
private List<Team> getAllTeamsByType(TeamTypeEnum type) {
List<Team> teams = new ArrayList<>();
for (Team t : id2TeamMap.values()) {
if (t.isMyTeam() && t.getType() == type) {
teams.add(t);
}
}
return teams;
}
public void addOrUpdateTeam(Team team) {
if (team == null) {
return;
}
id2TeamMap.put(team.getId(), team);
}
private void addOrUpdateTeam(List<Team> teamList) {
if (teamList == null || teamList.isEmpty()) {
return;
}
for (Team t : teamList) {
if (t == null) {
continue;
}
id2TeamMap.put(t.getId(), t);
}
}
/**
* *
* ************************************** 群成员缓存(由App主动添加缓存) ****************************************
*/
private Map<String, Map<String, TeamMember>> teamMemberCache = new ConcurrentHashMap<>();
public void clearTeamMemberCache() {
teamMemberCache.clear();
}
/**
* (异步)查询群成员资料列表(先从SDK DB中查询,如果本地群成员资料已过期会去服务器获取最新的。)
*/
public void fetchTeamMemberList(final String teamId, final SimpleCallback<List<TeamMember>> callback) {
NIMClient.getService(TeamService.class).queryMemberList(teamId).setCallback(new RequestCallbackWrapper<List<TeamMember>>() {
@Override
public void onResult(int code, final List<TeamMember> members, Throwable exception) {
boolean success = true;
if (code == ResponseCode.RES_SUCCESS) {
replaceTeamMemberList(teamId, members);
} else {
success = false;
LogUtil.e(UIKitLogTag.TEAM_CACHE, "fetchTeamMemberList failed, code=" + code);
}
if (exception != null) {
success = false;
LogUtil.e(UIKitLogTag.TEAM_CACHE, "fetchTeamMemberList throw exception, e=" + exception.getMessage());
}
if (callback != null) {
callback.onResult(success, members);
}
}
});
}
/**
* 在缓存中查询群成员列表
*/
public List<TeamMember> getTeamMemberList(String teamId) {
List<TeamMember> members = new ArrayList<>();
Map<String, TeamMember> map = teamMemberCache.get(teamId);
if (map != null && !map.values().isEmpty()) {
for (TeamMember m : map.values()) {
if (m.isInTeam()) {
members.add(m);
}
}
}
return members;
}
/**
* (异步)查询群成员资料(先从SDK DB中查询,如果本地群成员资料已过期会去服务器获取最新的。)
*/
public void fetchTeamMember(final String teamId, final String account, final SimpleCallback<TeamMember> callback) {
NIMClient.getService(TeamService.class).queryTeamMember(teamId, account).setCallback(new RequestCallbackWrapper<TeamMember>() {
@Override
public void onResult(int code, TeamMember member, Throwable exception) {
boolean success = true;
if (code == ResponseCode.RES_SUCCESS) {
addOrUpdateTeamMember(member);
} else {
success = false;
LogUtil.e(UIKitLogTag.TEAM_CACHE, "fetchTeamMember failed, code=" + code);
}
if (exception != null) {
success = false;
LogUtil.e(UIKitLogTag.TEAM_CACHE, "fetchTeamMember throw exception, e=" + exception.getMessage());
}
if (callback != null) {
callback.onResult(success, member);
}
}
});
}
/**
* 查询群成员资料(先从缓存中查,如果没有则从SDK DB中查询)
*/
public TeamMember getTeamMember(String teamId, String account) {
Map<String, TeamMember> map = teamMemberCache.get(teamId);
if (map == null) {
map = new ConcurrentHashMap<>();
teamMemberCache.put(teamId, map);
}
if (!map.containsKey(account)) {
TeamMember member = NIMClient.getService(TeamService.class).queryTeamMemberBlock(teamId, account);
if (member != null) {
map.put(account, member);
}
}
return map.get(account);
}
/**
* 获取显示名称。用户本人显示“我”
*
* @param tid
* @param account
* @return
*/
public String getTeamMemberDisplayName(String tid, String account) {
if (account.equals(NimUIKit.getAccount())) {
return "我";
}
return getDisplayNameWithoutMe(tid, account);
}
/**
* 获取显示名称。用户本人显示“你”
*
* @param tid
* @param account
* @return
*/
public String getTeamMemberDisplayNameYou(String tid, String account) {
if (account.equals(NimUIKit.getAccount())) {
return "你";
}
return getDisplayNameWithoutMe(tid, account);
}
/**
* 获取显示名称。用户本人也显示昵称
* 高级群:首先返回群昵称。没有群昵称,则返回备注名。没有设置备注名,则返回用户昵称。
* 讨论组:首先返回备注名。没有设置备注名,则返回用户昵称。
*/
public String getDisplayNameWithoutMe(String tid, String account) {
String memberNick = getTeamNick(tid, account);
if (!TextUtils.isEmpty(memberNick)) {
return memberNick;
}
String alias = NimUserInfoCache.getInstance().getAlias(account);
if (!TextUtils.isEmpty(alias)) {
return alias;
}
return NimUserInfoCache.getInstance().getUserName(account);
}
public String getTeamNick(String tid, String account) {
Team team = getTeamById(tid);
if (team != null && team.getType() == TeamTypeEnum.Advanced) {
TeamMember member = getTeamMember(tid, account);
if (member != null && !TextUtils.isEmpty(member.getTeamNick())) {
return member.getTeamNick();
}
}
return null;
}
private void replaceTeamMemberList(String tid, List<TeamMember> members) {
if (members == null || members.isEmpty() || TextUtils.isEmpty(tid)) {
return;
}
Map<String, TeamMember> map = teamMemberCache.get(tid);
if (map == null) {
map = new ConcurrentHashMap<>();
teamMemberCache.put(tid, map);
} else {
map.clear();
}
for (TeamMember m : members) {
map.put(m.getAccount(), m);
}
}
private void addOrUpdateTeamMember(TeamMember member) {
if (member == null) {
return;
}
Map<String, TeamMember> map = teamMemberCache.get(member.getTid());
if (map == null) {
map = new ConcurrentHashMap<>();
teamMemberCache.put(member.getTid(), map);
}
map.put(member.getAccount(), member);
}
private void addOrUpdateTeamMembers(List<TeamMember> members) {
for (TeamMember m : members) {
addOrUpdateTeamMember(m);
}
}
}