Presences.java

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