KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > user > User


1 /**
2  * $RCSfile: User.java,v $
3  * $Revision: 1.14 $
4  * $Date: 2005/05/05 18:31:03 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.user;
13
14 import org.jivesoftware.messenger.roster.Roster;
15 import org.jivesoftware.messenger.XMPPServer;
16 import org.jivesoftware.messenger.event.UserEventDispatcher;
17 import org.jivesoftware.util.Log;
18 import org.jivesoftware.util.Cacheable;
19 import org.jivesoftware.util.CacheSizes;
20 import org.jivesoftware.database.DbConnectionManager;
21
22 import java.util.*;
23 import java.util.concurrent.ConcurrentHashMap JavaDoc;
24 import java.sql.Connection JavaDoc;
25 import java.sql.PreparedStatement JavaDoc;
26 import java.sql.ResultSet JavaDoc;
27 import java.sql.SQLException JavaDoc;
28
29 /**
30  * Encapsulates information about a user. New users are created using
31  * {@link UserManager#createUser(String, String, String, String)}. All user
32  * properties are loaded on demand and are read from the <tt>jiveUserProp</tt>
33  * database table. The currently-installed {@link UserProvider} is used for
34  * setting all other user data and some operations may not be supported
35  * depending on the capabilities of the {@link UserProvider}.
36  *
37  * @author Matt Tucker
38  */

39 public class User implements Cacheable {
40
41     private static final String JavaDoc LOAD_PROPERTIES =
42         "SELECT name, propValue FROM jiveUserProp WHERE username=?";
43     private static final String JavaDoc DELETE_PROPERTY =
44         "DELETE FROM jiveUserProp WHERE username=? AND name=?";
45     private static final String JavaDoc UPDATE_PROPERTY =
46         "UPDATE jiveUserProp SET propValue=? WHERE name=? AND username=?";
47     private static final String JavaDoc INSERT_PROPERTY =
48         "INSERT INTO jiveUserProp (username, name, propValue) VALUES (?, ?, ?)";
49
50     private String JavaDoc username;
51     private String JavaDoc name;
52     private String JavaDoc email;
53     private Date creationDate;
54     private Date modificationDate;
55
56     private Map JavaDoc<String JavaDoc,String JavaDoc> properties = null;
57
58     /**
59      * Constructs a new user. All arguments can be <tt>null</tt> except the username.
60      * Typically, User objects should not be constructed by end-users of the API.
61      * Instead, user objects should be retrieved using {@link UserManager#getUser(String)}.
62      *
63      * @param username the username.
64      * @param name the name.
65      * @param email the email address.
66      * @param creationDate the date the user was created.
67      * @param modificationDate the date the user was last modified.
68      */

69     public User(String JavaDoc username, String JavaDoc name, String JavaDoc email, Date creationDate,
70             Date modificationDate)
71     {
72         if (username == null) {
73             throw new NullPointerException JavaDoc("Username cannot be null");
74         }
75         this.username = username;
76         this.name = name;
77         this.email = email;
78         this.creationDate = creationDate;
79         this.modificationDate = modificationDate;
80     }
81
82     /**
83      * Returns this user's username.
84      *
85      * @return the username..
86      */

87     public String JavaDoc getUsername() {
88         return username;
89     }
90
91     /**
92      * Sets a new password for this user.
93      *
94      * @param password the new password for the user.
95      */

96     public void setPassword(String JavaDoc password) {
97         if (UserManager.getUserProvider().isReadOnly()) {
98             throw new UnsupportedOperationException JavaDoc("User provider is read-only.");
99         }
100
101         try {
102             UserManager.getUserProvider().setPassword(username, password);
103
104             // Fire event.
105
Map JavaDoc params = new HashMap JavaDoc();
106             params.put("type", "passwordModified");
107             UserEventDispatcher.dispatchEvent(this, UserEventDispatcher.EventType.user_modified,
108                     params);
109         }
110         catch (UserNotFoundException unfe) {
111             Log.error(unfe);
112         }
113     }
114
115     public String JavaDoc getName() {
116         return name == null ? "" : name;
117     }
118
119     public void setName(String JavaDoc name) {
120         if (UserManager.getUserProvider().isReadOnly()) {
121             throw new UnsupportedOperationException JavaDoc("User provider is read-only.");
122         }
123
124         try {
125             String JavaDoc originalName = this.name;
126             UserManager.getUserProvider().setName(username, name);
127             this.name = name;
128
129             // Fire event.
130
Map JavaDoc params = new HashMap JavaDoc();
131             params.put("type", "nameModified");
132             params.put("originalValue", originalName);
133             UserEventDispatcher.dispatchEvent(this, UserEventDispatcher.EventType.user_modified,
134                     params);
135         }
136         catch (UserNotFoundException unfe) {
137             Log.error(unfe);
138         }
139     }
140
141     public String JavaDoc getEmail() {
142         return email;
143     }
144
145     public void setEmail(String JavaDoc email) {
146         if (UserManager.getUserProvider().isReadOnly()) {
147             throw new UnsupportedOperationException JavaDoc("User provider is read-only.");
148         }
149
150         try {
151             String JavaDoc originalEmail= this.email;
152             UserManager.getUserProvider().setEmail(username, email);
153             this.email = email;
154             // Fire event.
155
Map JavaDoc params = new HashMap JavaDoc();
156             params.put("type", "emailModified");
157             params.put("originalValue", originalEmail);
158             UserEventDispatcher.dispatchEvent(this, UserEventDispatcher.EventType.user_modified,
159                     params);
160         }
161         catch (UserNotFoundException unfe) {
162             Log.error(unfe);
163         }
164     }
165
166     public Date getCreationDate() {
167         return creationDate;
168     }
169
170     public void setCreationDate(Date creationDate) {
171         if (UserManager.getUserProvider().isReadOnly()) {
172             throw new UnsupportedOperationException JavaDoc("User provider is read-only.");
173         }
174
175         try {
176             Date originalCreationDate = this.creationDate;
177             UserManager.getUserProvider().setCreationDate(username, creationDate);
178             this.creationDate = creationDate;
179
180             // Fire event.
181
Map JavaDoc params = new HashMap JavaDoc();
182             params.put("type", "creationDateModified");
183             params.put("originalValue", originalCreationDate);
184             UserEventDispatcher.dispatchEvent(this, UserEventDispatcher.EventType.user_modified,
185                     params);
186         }
187         catch (UserNotFoundException unfe) {
188             Log.error(unfe);
189         }
190     }
191
192     public Date getModificationDate() {
193         return modificationDate;
194     }
195
196     public void setModificationDate(Date modificationDate) {
197         if (UserManager.getUserProvider().isReadOnly()) {
198             throw new UnsupportedOperationException JavaDoc("User provider is read-only.");
199         }
200
201         try {
202             Date originalModificationDate = this.modificationDate;
203             UserManager.getUserProvider().setCreationDate(username, modificationDate);
204             this.modificationDate = modificationDate;
205
206             // Fire event.
207
Map JavaDoc params = new HashMap JavaDoc();
208             params.put("type", "nameModified");
209             params.put("originalValue", originalModificationDate);
210             UserEventDispatcher.dispatchEvent(this, UserEventDispatcher.EventType.user_modified,
211                     params);
212         }
213         catch (UserNotFoundException unfe) {
214             Log.error(unfe);
215         }
216     }
217
218     /**
219      * Returns all extended properties of the group. Groups
220      * have an arbitrary number of extended properties.
221      *
222      * @return the extended properties.
223      */

224     public Map JavaDoc<String JavaDoc,String JavaDoc> getProperties() {
225         synchronized (this) {
226             if (properties == null) {
227                 properties = new ConcurrentHashMap JavaDoc<String JavaDoc, String JavaDoc>();
228                 loadProperties();
229             }
230         }
231         // Return a wrapper that will intercept add and remove commands.
232
return new PropertiesMap();
233     }
234
235     /**
236      * Returns the user's roster. A roster is a list of users that the user wishes to know
237      * if they are online. Rosters are similar to buddy groups in popular IM clients.
238      *
239      * @return the user's roster.
240      */

241     public Roster getRoster() {
242         try {
243             return XMPPServer.getInstance().getRosterManager().getRoster(username);
244         }
245         catch (UserNotFoundException unfe) {
246             Log.error(unfe);
247             return null;
248         }
249     }
250
251     public int getCachedSize() {
252         // Approximate the size of the object in bytes by calculating the size
253
// of each field.
254
int size = 0;
255         size += CacheSizes.sizeOfObject(); // overhead of object
256
size += CacheSizes.sizeOfLong(); // id
257
size += CacheSizes.sizeOfString(username); // username
258
size += CacheSizes.sizeOfString(name); // name
259
size += CacheSizes.sizeOfString(email); // email
260
size += CacheSizes.sizeOfDate() * 2; // creationDate and modificationDate
261
size += CacheSizes.sizeOfMap(properties); // properties
262
return size;
263     }
264
265     public String JavaDoc toString() {
266         return username;
267     }
268
269     public int hashCode() {
270         return username.hashCode();
271     }
272
273     public boolean equals(Object JavaDoc object) {
274         if (this == object) {
275             return true;
276         }
277         if (object != null && object instanceof User) {
278             return username.equals(((User)object).getUsername());
279         }
280         else {
281             return false;
282         }
283     }
284
285     /**
286      * Map implementation that updates the database when properties are modified.
287      */

288     private class PropertiesMap extends AbstractMap {
289
290         public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
291             Map JavaDoc eventParams = new HashMap JavaDoc();
292             Object JavaDoc answer;
293             String JavaDoc keyString = (String JavaDoc) key;
294             synchronized (keyString.intern()) {
295                 if (properties.containsKey(key)) {
296                     String JavaDoc originalValue = properties.get(key);
297                     answer = properties.put(keyString, (String JavaDoc)value);
298                     updateProperty(keyString, (String JavaDoc)value);
299                     // Configure event.
300
eventParams.put("type", "propertyModified");
301                     eventParams.put("propertyKey", key);
302                     eventParams.put("originalValue", originalValue);
303                 }
304                 else {
305                     answer = properties.put(keyString, (String JavaDoc)value);
306                     insertProperty(keyString, (String JavaDoc)value);
307                     // Configure event.
308
eventParams.put("type", "propertyAdded");
309                     eventParams.put("propertyKey", key);
310                 }
311             }
312             // Fire event.
313
UserEventDispatcher.dispatchEvent(User.this,
314                     UserEventDispatcher.EventType.user_modified, eventParams);
315             return answer;
316         }
317
318         public Set JavaDoc<Entry> entrySet() {
319             return new PropertiesEntrySet();
320         }
321     }
322
323     /**
324      * Set implementation that updates the database when properties are deleted.
325      */

326     private class PropertiesEntrySet extends AbstractSet {
327
328         public int size() {
329             return properties.entrySet().size();
330         }
331
332         public Iterator iterator() {
333             return new Iterator() {
334
335                 Iterator iter = properties.entrySet().iterator();
336                 Map.Entry JavaDoc current = null;
337
338                 public boolean hasNext() {
339                     return iter.hasNext();
340                 }
341
342                 public Object JavaDoc next() {
343                     current = (Map.Entry JavaDoc)iter.next();
344                     return current;
345                 }
346
347                 public void remove() {
348                     if (current == null) {
349                         throw new IllegalStateException JavaDoc();
350                     }
351                     String JavaDoc key = (String JavaDoc)current.getKey();
352                     deleteProperty(key);
353                     iter.remove();
354                     // Fire event.
355
Map JavaDoc params = new HashMap JavaDoc();
356                     params.put("type", "propertyDeleted");
357                     params.put("propertyKey", key);
358                     UserEventDispatcher.dispatchEvent(User.this,
359                         UserEventDispatcher.EventType.user_modified, params);
360                 }
361             };
362         }
363     }
364
365     private void loadProperties() {
366         Connection JavaDoc con = null;
367         PreparedStatement JavaDoc pstmt = null;
368         try {
369             con = DbConnectionManager.getConnection();
370             pstmt = con.prepareStatement(LOAD_PROPERTIES);
371             pstmt.setString(1, username);
372             ResultSet JavaDoc rs = pstmt.executeQuery();
373             while (rs.next()) {
374                 properties.put(rs.getString(1), rs.getString(2));
375             }
376             rs.close();
377         }
378         catch (SQLException JavaDoc sqle) {
379             Log.error(sqle);
380         }
381         finally {
382             try { if (pstmt != null) pstmt.close(); }
383             catch (Exception JavaDoc e) { Log.error(e); }
384             try { if (con != null) con.close(); }
385             catch (Exception JavaDoc e) { Log.error(e); }
386         }
387     }
388
389     private void insertProperty(String JavaDoc propName, String JavaDoc propValue) {
390         Connection JavaDoc con = null;
391         PreparedStatement JavaDoc pstmt = null;
392         try {
393             con = DbConnectionManager.getConnection();
394             pstmt = con.prepareStatement(INSERT_PROPERTY);
395             pstmt.setString(1, username);
396             pstmt.setString(2, propName);
397             pstmt.setString(3, propValue);
398             pstmt.executeUpdate();
399         }
400         catch (SQLException JavaDoc e) {
401             Log.error(e);
402         }
403         finally {
404             try { if (pstmt != null) pstmt.close(); }
405             catch (Exception JavaDoc e) { Log.error(e); }
406             try { if (con != null) con.close(); }
407             catch (Exception JavaDoc e) { Log.error(e); }
408         }
409     }
410
411     private void updateProperty(String JavaDoc propName, String JavaDoc propValue) {
412         Connection JavaDoc con = null;
413         PreparedStatement JavaDoc pstmt = null;
414         try {
415             con = DbConnectionManager.getConnection();
416             pstmt = con.prepareStatement(UPDATE_PROPERTY);
417             pstmt.setString(1, propValue);
418             pstmt.setString(2, propName);
419             pstmt.setString(3, username);
420             pstmt.executeUpdate();
421         }
422         catch (SQLException JavaDoc e) {
423             Log.error(e);
424         }
425         finally {
426             try { if (pstmt != null) pstmt.close(); }
427             catch (Exception JavaDoc e) { Log.error(e); }
428             try { if (con != null) con.close(); }
429             catch (Exception JavaDoc e) { Log.error(e); }
430         }
431     }
432
433     private void deleteProperty(String JavaDoc propName) {
434         Connection JavaDoc con = null;
435         PreparedStatement JavaDoc pstmt = null;
436         try {
437             con = DbConnectionManager.getConnection();
438             pstmt = con.prepareStatement(DELETE_PROPERTY);
439             pstmt.setString(1, username);
440             pstmt.setString(2, propName);
441             pstmt.executeUpdate();
442         }
443         catch (SQLException JavaDoc e) {
444             Log.error(e);
445         }
446         finally {
447             try { if (pstmt != null) pstmt.close(); }
448             catch (Exception JavaDoc e) { Log.error(e); }
449             try { if (con != null) con.close(); }
450             catch (Exception JavaDoc e) { Log.error(e); }
451         }
452     }
453 }
Popular Tags