1package eu.siacs.conversations.entities;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.concurrent.CopyOnWriteArrayList;
6
7import eu.siacs.conversations.crypto.PgpEngine;
8import eu.siacs.conversations.xml.Element;
9import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
10import android.annotation.SuppressLint;
11
12@SuppressLint("DefaultLocale")
13public class MucOptions {
14 public static final int ERROR_NO_ERROR = 0;
15 public static final int ERROR_NICK_IN_USE = 1;
16 public static final int ERROR_ROOM_NOT_FOUND = 2;
17
18 public interface OnRenameListener {
19 public void onRename(boolean success);
20 }
21
22 public class User {
23 public static final int ROLE_MODERATOR = 3;
24 public static final int ROLE_NONE = 0;
25 public static final int ROLE_PARTICIPANT = 2;
26 public static final int ROLE_VISITOR = 1;
27 public static final int AFFILIATION_ADMIN = 4;
28 public static final int AFFILIATION_OWNER = 3;
29 public static final int AFFILIATION_MEMBER = 2;
30 public static final int AFFILIATION_OUTCAST = 1;
31 public static final int AFFILIATION_NONE = 0;
32
33 private int role;
34 private int affiliation;
35 private String name;
36 private String jid;
37 private long pgpKeyId = 0;
38
39 public String getName() {
40 return name;
41 }
42
43 public void setName(String user) {
44 this.name = user;
45 }
46
47 public void setJid(String jid) {
48 this.jid = jid;
49 }
50
51 public String getJid() {
52 return this.jid;
53 }
54
55 public int getRole() {
56 return this.role;
57 }
58
59 public void setRole(String role) {
60 role = role.toLowerCase();
61 if (role.equals("moderator")) {
62 this.role = ROLE_MODERATOR;
63 } else if (role.equals("participant")) {
64 this.role = ROLE_PARTICIPANT;
65 } else if (role.equals("visitor")) {
66 this.role = ROLE_VISITOR;
67 } else {
68 this.role = ROLE_NONE;
69 }
70 }
71
72 public int getAffiliation() {
73 return this.affiliation;
74 }
75
76 public void setAffiliation(String affiliation) {
77 if (affiliation.equalsIgnoreCase("admin")) {
78 this.affiliation = AFFILIATION_ADMIN;
79 } else if (affiliation.equalsIgnoreCase("owner")) {
80 this.affiliation = AFFILIATION_OWNER;
81 } else if (affiliation.equalsIgnoreCase("member")) {
82 this.affiliation = AFFILIATION_MEMBER;
83 } else if (affiliation.equalsIgnoreCase("outcast")) {
84 this.affiliation = AFFILIATION_OUTCAST;
85 } else {
86 this.affiliation = AFFILIATION_NONE;
87 }
88 }
89
90 public void setPgpKeyId(long id) {
91 this.pgpKeyId = id;
92 }
93
94 public long getPgpKeyId() {
95 return this.pgpKeyId;
96 }
97 }
98
99 private Account account;
100 private List<User> users = new CopyOnWriteArrayList<User>();
101 private Conversation conversation;
102 private boolean isOnline = false;
103 private int error = ERROR_ROOM_NOT_FOUND;
104 private OnRenameListener renameListener = null;
105 private boolean aboutToRename = false;
106 private User self = new User();
107 private String subject = null;
108 private String joinnick;
109
110 public MucOptions(Account account) {
111 this.account = account;
112 }
113
114 public void deleteUser(String name) {
115 for (int i = 0; i < users.size(); ++i) {
116 if (users.get(i).getName().equals(name)) {
117 users.remove(i);
118 return;
119 }
120 }
121 }
122
123 public void addUser(User user) {
124 for (int i = 0; i < users.size(); ++i) {
125 if (users.get(i).getName().equals(user.getName())) {
126 users.set(i, user);
127 return;
128 }
129 }
130 users.add(user);
131 }
132
133 public void processPacket(PresencePacket packet, PgpEngine pgp) {
134 String[] fromParts = packet.getFrom().split("/");
135 if (fromParts.length >= 2) {
136 String name = fromParts[1];
137 String type = packet.getAttribute("type");
138 if (type == null) {
139 User user = new User();
140 Element item = packet.findChild("x",
141 "http://jabber.org/protocol/muc#user")
142 .findChild("item");
143 user.setName(name);
144 user.setAffiliation(item.getAttribute("affiliation"));
145 user.setRole(item.getAttribute("role"));
146 user.setJid(item.getAttribute("jid"));
147 user.setName(name);
148 if (name.equals(this.joinnick)) {
149 this.isOnline = true;
150 this.error = ERROR_NO_ERROR;
151 self = user;
152 if (aboutToRename) {
153 if (renameListener != null) {
154 renameListener.onRename(true);
155 }
156 aboutToRename = false;
157 }
158 } else {
159 addUser(user);
160 }
161 if (pgp != null) {
162 Element x = packet.findChild("x", "jabber:x:signed");
163 if (x != null) {
164 Element status = packet.findChild("status");
165 String msg;
166 if (status != null) {
167 msg = status.getContent();
168 } else {
169 msg = "";
170 }
171 user.setPgpKeyId(pgp.fetchKeyId(account, msg,
172 x.getContent()));
173 }
174 }
175 } else if (type.equals("unavailable")) {
176 deleteUser(packet.getAttribute("from").split("/")[1]);
177 } else if (type.equals("error")) {
178 Element error = packet.findChild("error");
179 if (error.hasChild("conflict")) {
180 if (aboutToRename) {
181 if (renameListener != null) {
182 renameListener.onRename(false);
183 }
184 aboutToRename = false;
185 this.setJoinNick(getActualNick());
186 } else {
187 this.error = ERROR_NICK_IN_USE;
188 }
189 }
190 }
191 }
192 }
193
194 public List<User> getUsers() {
195 return this.users;
196 }
197
198 public String getProposedNick() {
199 String[] mucParts = conversation.getContactJid().split("/");
200 if (conversation.getBookmark() != null
201 && conversation.getBookmark().getNick() != null) {
202 return conversation.getBookmark().getNick();
203 } else {
204 if (mucParts.length == 2) {
205 return mucParts[1];
206 } else {
207 return account.getUsername();
208 }
209 }
210 }
211
212 public String getActualNick() {
213 if (this.self.getName() != null) {
214 return this.self.getName();
215 } else {
216 return this.getProposedNick();
217 }
218 }
219
220 public void setJoinNick(String nick) {
221 this.joinnick = nick;
222 }
223
224 public void setConversation(Conversation conversation) {
225 this.conversation = conversation;
226 }
227
228 public boolean online() {
229 return this.isOnline;
230 }
231
232 public int getError() {
233 return this.error;
234 }
235
236 public void setOnRenameListener(OnRenameListener listener) {
237 this.renameListener = listener;
238 }
239
240 public OnRenameListener getOnRenameListener() {
241 return this.renameListener;
242 }
243
244 public void setOffline() {
245 this.users.clear();
246 this.error = 0;
247 this.isOnline = false;
248 }
249
250 public User getSelf() {
251 return self;
252 }
253
254 public void setSubject(String content) {
255 this.subject = content;
256 }
257
258 public String getSubject() {
259 return this.subject;
260 }
261
262 public void flagAboutToRename() {
263 this.aboutToRename = true;
264 }
265
266 public long[] getPgpKeyIds() {
267 List<Long> ids = new ArrayList<Long>();
268 for (User user : getUsers()) {
269 if (user.getPgpKeyId() != 0) {
270 ids.add(user.getPgpKeyId());
271 }
272 }
273 long[] primitivLongArray = new long[ids.size()];
274 for (int i = 0; i < ids.size(); ++i) {
275 primitivLongArray[i] = ids.get(i);
276 }
277 return primitivLongArray;
278 }
279
280 public boolean pgpKeysInUse() {
281 for (User user : getUsers()) {
282 if (user.getPgpKeyId() != 0) {
283 return true;
284 }
285 }
286 return false;
287 }
288
289 public boolean everybodyHasKeys() {
290 for (User user : getUsers()) {
291 if (user.getPgpKeyId() == 0) {
292 return false;
293 }
294 }
295 return true;
296 }
297
298 public String getJoinJid() {
299 return this.conversation.getContactJid().split("/")[0] + "/"
300 + this.joinnick;
301 }
302
303 public String getTrueCounterpart(String counterpart) {
304 for(User user : this.getUsers()) {
305 if (user.getName().equals(counterpart)) {
306 return user.getJid();
307 }
308 }
309 return null;
310 }
311}