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 boolean anyIdentity(final String category, final String type) {
153        synchronized (this.presences) {
154            if (this.presences.size() == 0) {
155                // https://github.com/iNPUTmice/Conversations/issues/4230
156                return false;
157            }
158            for (Presence presence : this.presences.values()) {
159                ServiceDiscoveryResult disco = presence.getServiceDiscoveryResult();
160                if (disco != null && disco.hasIdentity(category, type)) {
161                    return true;
162                }
163            }
164        }
165        return false;
166    }
167
168    public Pair<Map<String, String>, Map<String, String>> toTypeAndNameMap() {
169        Map<String, String> typeMap = new HashMap<>();
170        Map<String, String> nameMap = new HashMap<>();
171        synchronized (this.presences) {
172            for (Map.Entry<String, Presence> presenceEntry : this.presences.entrySet()) {
173                String resource = presenceEntry.getKey();
174                Presence presence = presenceEntry.getValue();
175                ServiceDiscoveryResult serviceDiscoveryResult = presence == null ? null : presence.getServiceDiscoveryResult();
176                if (serviceDiscoveryResult != null && serviceDiscoveryResult.getIdentities().size() > 0) {
177                    ServiceDiscoveryResult.Identity identity = serviceDiscoveryResult.getIdentities().get(0);
178                    String type = identity.getType();
179                    String name = identity.getName();
180                    if (type != null) {
181                        typeMap.put(resource, type);
182                    }
183                    if (name != null) {
184                        nameMap.put(resource, nameWithoutVersion(name));
185                    }
186                }
187            }
188        }
189        return new Pair<>(typeMap, nameMap);
190    }
191}