001    /*
002     Copyright (C) 2003 Adam Olsen
003    
004     This program is free software; you can redistribute it and/or modify
005     it under the terms of the GNU General Public License as published by
006     the Free Software Foundation; either version 1, or (at your option)
007     any later version.
008    
009     This program is distributed in the hope that it will be useful,
010     but WITHOUT ANY WARRANTY; without even the implied warranty of
011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012     GNU General Public License for more details.
013    
014     You should have received a copy of the GNU General Public License
015     along with this program; if not, write to the Free Software
016     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
017     */
018    
019    package com.valhalla.jbother.jabber;
020    
021    import java.util.Hashtable;
022    import java.util.Iterator;
023    import java.util.Locale;
024    import java.util.Properties;
025    import java.util.ResourceBundle;
026    import java.util.Set;
027    
028    import org.jivesoftware.smack.*;
029    import org.jivesoftware.smack.packet.Presence;
030    
031    import com.valhalla.jbother.BuddyList;
032    import com.valhalla.jbother.ConversationPanel;
033    import com.valhalla.jbother.ConnectorThread;
034    import com.valhalla.settings.Settings;
035    
036    import javax.swing.*;
037    
038    /**
039     * Tracks a users different presences and resources
040     *
041     * @author Adam Olsen
042     * @author Andrey Zakirov
043     * @version 1.1
044     */
045    public class BuddyStatus extends Hashtable {
046        protected ResourceBundle sources = ResourceBundle.getBundle(
047                "JBotherBundle", Locale.getDefault());
048    
049        protected String userId = "";
050    
051        protected ConversationPanel conversation = null;
052    
053        protected String name = null;
054    
055        protected boolean removed = false;
056    
057        protected boolean hasSignedOn = false;
058    
059        protected String resources = "";
060    
061        protected Hashtable presences = null;
062    
063        protected Properties statusMessages = null;
064    
065        protected String tempGroup = null;
066    
067        protected String versionInfo = null;
068    
069        protected String composingId = "";
070    
071        protected boolean encrypting = false;
072    
073        protected boolean askForDelivered = false;
074    
075        protected boolean askForDisplayed = false;
076    
077        protected boolean askForOffline = false;
078    
079        protected Hashtable notDisplayedMessages = new Hashtable();
080    
081        protected String pubKeyId = null;
082        protected RosterEntry entry = null;
083    
084        /**
085         * Sets up the buddy container
086         *
087         * @param buddyId
088         *            the buddy/user to track
089         */
090        public BuddyStatus(String buddyId) {
091            this.userId = buddyId;
092        }
093    
094        public void setComposingID(String id) {
095            this.composingId = id;
096        }
097    
098        public String getComposingID() {
099            return composingId;
100        }
101    
102        public void addNotDisplayedID(String packetID, String from) {
103            notDisplayedMessages.put ( packetID, from);
104        }
105    
106    
107        public void sendNotDisplayedID() {
108                    String packetID = null;
109                    String from = null;
110                    while (notDisplayedMessages.keys ().hasMoreElements ())
111                    {
112                        from = (String) notDisplayedMessages.keys ().nextElement ();
113                        packetID = (String) notDisplayedMessages.get ( from );
114                        ConnectorThread.getInstance().getMessageEventManager().sendDisplayedNotification ( packetID, from);
115                        if (from !=null)
116                        {
117                            notDisplayedMessages.remove ( from);
118                        }
119                    }
120        }
121    
122        /**
123         * Gets the resource with the higest priority
124         *
125         * @return the resource with the highest priority, or null if the user is
126         *         offline
127         */
128        public String getHighestResource() {
129            String resource = null;
130    
131            Set keys = keySet();
132            Iterator iterator = keys.iterator();
133    
134            int highest = -2;
135    
136            while (iterator.hasNext()) {
137                Object key = iterator.next();
138                Integer value = (Integer) get(key);
139    
140                if (value.intValue() > highest) {
141                    resource = (String) key;
142                    highest = value.intValue();
143                }
144            }
145    
146            return resource;
147        }
148    
149        public String getAddress()
150        {
151            String to = getUser();
152            if(size() > 0 && !getHighestResource().equals("N/A")) to += "/" + getHighestResource();
153            return to;
154        }
155    
156        /**
157         * Resets the buddy so that it appears as though they never signed on
158         */
159        public void resetBuddy() {
160            clear();
161            presences = null;
162            statusMessages = null;
163        }
164    
165        /**
166         * Adds a resource to the tracker
167         *
168         * @param resource
169         *            the resource name
170         * @param priority
171         *            the priority level of this resource
172         * @param mode
173         *            the current presence mode
174         * @param statusMessage
175         *            the status message if there is one
176         */
177        public void addResource(String resource, int priority, Presence.Mode mode,
178                String statusMessage) {
179            if (presences == null)
180                presences = new Hashtable();
181            if (statusMessages == null)
182                statusMessages = new Properties();
183            presences.put(resource, mode);
184    
185            if (statusMessage == null)
186                statusMessage = "";
187            statusMessages.setProperty(resource, statusMessage);
188            put(resource, new Integer(priority));
189        }
190    
191        /**
192         * Gets the status message of the highest resource
193         *
194         * @return the status message of the highest resource, or an empty string if
195         *         there is no status message
196         */
197        public String getStatusMessage(String resource) {
198            if (resource == null)
199                return "";
200            if (statusMessages == null)
201                statusMessages = new Properties();
202            String message = statusMessages.getProperty(resource);
203            if (message == null)
204                message = "";
205            return message;
206        }
207    
208        /**
209         * Stops tracking a resource
210         *
211         * @param resource
212         *            the resource to remove
213         */
214        public void removeResource(String resource) {
215            if (presences != null)
216                presences.remove(resource);
217            if (statusMessages != null)
218                statusMessages.remove(resource);
219            remove(resource);
220        }
221    
222        /**
223         * Gets the presence mode of the highest priority
224         *
225         * @return the presence mode of the highest priority or null if the user is
226         *         offline
227         */
228        public Presence.Mode getPresence(String resource) {
229            if (presences == null)
230                presences = new Hashtable();
231            if (resource == null)
232                return null;
233            return (Presence.Mode) presences.get(resource);
234        }
235    
236        /**
237         * Sets a temporary group name (if the user is displayed before the group
238         * actually changes on the server)
239         *
240         * @param group
241         *            the temporary group to use
242         */
243        public void setTempGroup(String group) {
244            this.tempGroup = group;
245        }
246    
247        /**
248         * Returns the temporary group
249         *
250         * @return the temp group
251         */
252        public String getTempGroup() {
253            String temp = tempGroup;
254            tempGroup = null;
255    
256            return temp;
257        }
258    
259        /**
260         * Gets the group the user is in in the Roster
261         *
262         * @return the group the user is in
263         */
264        public String getGroup() {
265            RosterEntry entry = getRosterEntry();
266    
267            if (entry == null)
268                return sources.getString("notInRoster");
269            Iterator groups = entry.getGroups();
270    
271            String group = sources.getString("contactsGroup");
272            if (groups.hasNext())
273                group = ((RosterGroup) groups.next()).getName();
274            if (userId.indexOf("@") < 0)
275                group = sources.getString("transportsGroup");
276            return group;
277        }
278    
279        /**
280         * Gets the roster entry for this user
281         *
282         * @return the RosterEntry for this user
283         */
284        public RosterEntry getRosterEntry() {
285            if (!BuddyList.getInstance().checkConnection())
286                return null;
287    
288            if( entry != null ) return entry;
289            Roster roster = ConnectorThread.getInstance().getRoster();
290            if( roster == null ) return entry;
291            entry = roster.getEntry( userId );
292            return entry;
293        }
294    
295        /**
296         * Sets the users jabber:iq:version information
297         *
298         * @param info
299         *            the users jabber:iq:version information
300         */
301        public void setVersionInfo(String info) {
302            this.versionInfo = info;
303        }
304    
305        /**
306         * @return the users jabber:iq:version information
307         */
308        public String getVersionInfo() {
309            return versionInfo;
310        }
311    
312        /**
313         * Whether or not the user has signed on
314         *
315         * @param on
316         *            set to true if the user has signed on
317         */
318        public void setHasSignedOn(boolean on) {
319            this.hasSignedOn = on;
320        }
321    
322        /**
323         * @return true if the user has signed on
324         */
325        public boolean getHasSignedOn() {
326            return this.hasSignedOn;
327        }
328    
329        /**
330         * @param removed
331         *            set to true if this user has been removed from the roster
332         */
333        public void setRemoved(boolean removed) {
334            this.removed = removed;
335        }
336    
337        /**
338         * @return true if the user has been removed from the roster
339         */
340        public boolean getRemoved() {
341            return this.removed;
342        }
343    
344        /**
345         * @return the users alias
346         */
347        public String getName() {
348            if (name != null)
349                return name;
350            RosterEntry entry = getRosterEntry();
351            if (entry != null && entry.getName()!=null)
352                return entry.getName();
353            else if (userId == null)
354                return "unknown";
355            else
356                return userId;
357        }
358    
359        /**
360         * @param name
361         *            the buddy's alias
362         */
363        public void setName(String name) {
364            this.name = name;
365        }
366    
367        /**
368         * @param buddyId
369         *            the userId
370         */
371        public void setUser(String buddyId) {
372            this.userId = buddyId.toLowerCase();
373        }
374    
375        /**
376         * @return the JID for this Buddy
377         */
378        public String getUser() {
379            return this.userId;
380        }
381    
382        /**
383         * Sets the ConversationPanel for this buddy
384         *
385         * @param window
386         *            the conversation for this buddy
387         */
388        public void setConversation(ConversationPanel window) {
389            this.conversation = window;
390        }
391    
392        /**
393         * Gets the conversation window for this buddy
394         *
395         * @return the conversation for this buddy
396         */
397        public ConversationPanel getConversation() {
398            return this.conversation;
399        }
400    
401        /**
402         * Gets the encryption status
403         *
404         * @return encryption status
405         */
406        public boolean isEncrypting() {
407            return encrypting;
408        }
409    
410        /**
411         * Sets the encryption status
412         *
413         * @param variant
414         *            encryption status
415         */
416    
417        public void isEncrypting(boolean variant) {
418            this.encrypting = variant;
419        }
420    
421    
422        public boolean isAskForDelivered() {
423             return askForDelivered;
424         }
425    
426         public void isAskForDelivered(boolean variant) {
427             this.askForDelivered = variant;
428         }
429    
430         public boolean isAskForDisplayed() {
431             return askForDisplayed;
432         }
433    
434         public void isAskForDisplayed(boolean variant) {
435             this.askForDisplayed = variant;
436         }
437    
438         public boolean isAskForOffline () {
439             return askForOffline;
440         }
441    
442         public void isAskForOffline(boolean variant) {
443             this.askForOffline = variant;
444         }
445    
446    
447        /**
448         * Gets Public Key ID
449         *
450         * @return public key ID
451         */
452        public String getPubKey() {
453            return this.pubKeyId;
454        }
455    
456        /**
457         * Sets Public Key ID
458         *
459         * @param ID
460         *            public key ID
461         */
462        public void setPubKey(String Id) {
463            if (Id == null) {
464                Settings.getInstance()
465                        .remove("gnupg." + this.userId + ".PublicKey");
466            } else {
467                Settings.getInstance().setProperty(
468                        "gnupg." + this.userId + ".PublicKey", Id);
469            }
470            this.pubKeyId = Id;
471        }
472    
473        /**
474         * Creates Public Key ID
475         *
476         */
477    
478        public void newPubKey() {
479    
480            String pubKey = Settings.getInstance().getProperty(
481                    "gnupg." + this.userId + ".PublicKey");
482            if (pubKey != null) {
483                this.pubKeyId = pubKey;
484            }
485    
486        }
487    }