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