1package eu.siacs.conversations.entities;
2
3import android.util.Pair;
4
5import java.util.ArrayList;
6import java.util.HashMap;
7import java.util.Hashtable;
8import java.util.List;
9import java.util.Map;
10
11public class Presences {
12 private final Hashtable<String, Presence> presences = new Hashtable<>();
13
14 public Hashtable<String, Presence> getPresences() {
15 return this.presences;
16 }
17
18 public void updatePresence(String resource, Presence presence) {
19 synchronized (this.presences) {
20 this.presences.put(resource, presence);
21 }
22 }
23
24 public void removePresence(String resource) {
25 synchronized (this.presences) {
26 this.presences.remove(resource);
27 }
28 }
29
30 public void clearPresences() {
31 synchronized (this.presences) {
32 this.presences.clear();
33 }
34 }
35
36 public Presence.Status getShownStatus() {
37 Presence.Status status = Presence.Status.OFFLINE;
38 synchronized (this.presences) {
39 for(Presence p : presences.values()) {
40 if (p.getStatus() == Presence.Status.DND) {
41 return p.getStatus();
42 } else if (p.getStatus().compareTo(status) < 0){
43 status = p.getStatus();
44 }
45 }
46 }
47 return status;
48 }
49
50 public int size() {
51 synchronized (this.presences) {
52 return presences.size();
53 }
54 }
55
56 public String[] toResourceArray() {
57 synchronized (this.presences) {
58 final String[] presencesArray = new String[presences.size()];
59 presences.keySet().toArray(presencesArray);
60 return presencesArray;
61 }
62 }
63
64 public List<PresenceTemplate> asTemplates() {
65 synchronized (this.presences) {
66 ArrayList<PresenceTemplate> templates = new ArrayList<>(presences.size());
67 for(Presence p : presences.values()) {
68 if (p.getMessage() != null && !p.getMessage().trim().isEmpty()) {
69 templates.add(new PresenceTemplate(p.getStatus(), p.getMessage()));
70 }
71 }
72 return templates;
73 }
74 }
75
76 public boolean has(String presence) {
77 synchronized (this.presences) {
78 return presences.containsKey(presence);
79 }
80 }
81
82 public List<String> getStatusMessages() {
83 ArrayList<String> messages = new ArrayList<>();
84 synchronized (this.presences) {
85 for(Presence presence : this.presences.values()) {
86 String message = presence.getMessage() == null ? null : presence.getMessage().trim();
87 if (message != null && !message.isEmpty() && !messages.contains(message)) {
88 messages.add(message);
89 }
90 }
91 }
92 return messages;
93 }
94
95 public boolean allOrNonSupport(String namespace) {
96 synchronized (this.presences) {
97 for(Presence presence : this.presences.values()) {
98 ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
99 if (disco == null || !disco.getFeatures().contains(namespace)) {
100 return false;
101 }
102 }
103 }
104 return true;
105 }
106
107 public Pair<Map<String, String>,Map<String,String>> toTypeAndNameMap() {
108 Map<String,String> typeMap = new HashMap<>();
109 Map<String,String> nameMap = new HashMap<>();
110 synchronized (this.presences) {
111 for(Map.Entry<String,Presence> presenceEntry : this.presences.entrySet()) {
112 String resource = presenceEntry.getKey();
113 Presence presence = presenceEntry.getValue();
114 ServiceDiscoveryResult serviceDiscoveryResult = presence == null ? null : presence.getServiceDiscoveryResult();
115 if (serviceDiscoveryResult != null && serviceDiscoveryResult.getIdentities().size() > 0) {
116 ServiceDiscoveryResult.Identity identity = serviceDiscoveryResult.getIdentities().get(0);
117 String type = identity.getType();
118 String name = identity.getName();
119 if (type != null) {
120 typeMap.put(resource,type);
121 }
122 if (name != null) {
123 nameMap.put(resource, nameWithoutVersion(name));
124 }
125 }
126 }
127 }
128 return new Pair<>(typeMap,nameMap);
129 }
130
131 private static String nameWithoutVersion(String name) {
132 String[] parts = name.split(" ");
133 if (parts.length > 1 && Character.isDigit(parts[parts.length -1].charAt(0))) {
134 StringBuilder output = new StringBuilder();
135 for(int i = 0; i < parts.length -1; ++i) {
136 if (output.length() != 0) {
137 output.append(' ');
138 }
139 output.append(parts[i]);
140 }
141 return output.toString();
142 } else {
143 return name;
144 }
145 }
146}