KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > smackx > packet > VCard


1 /**
2  * $RCSfile$
3  * $Revision: 2635 $
4  * $Date: 2005-08-12 16:25:48 -0300 (Fri, 12 Aug 2005) $
5  *
6  * Copyright 2003-2004 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */

20
21 package org.jivesoftware.smackx.packet;
22
23 import org.jivesoftware.smack.PacketCollector;
24 import org.jivesoftware.smack.SmackConfiguration;
25 import org.jivesoftware.smack.XMPPConnection;
26 import org.jivesoftware.smack.XMPPException;
27 import org.jivesoftware.smack.filter.PacketIDFilter;
28 import org.jivesoftware.smack.packet.IQ;
29 import org.jivesoftware.smack.packet.XMPPError;
30
31 import java.lang.reflect.Field JavaDoc;
32 import java.lang.reflect.Modifier JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Map JavaDoc;
36
37 /**
38  * A VCard class for use with the
39  * <a HREF="http://www.jivesoftware.org/smack/" target="_blank">SMACK jabber library</a>.<p>
40  *
41  * You should refer to the
42  * <a HREF="http://www.jabber.org/jeps/jep-0054.html" target="_blank">JEP-54 documentation</a>.<p>
43  *
44  * Please note that this class is incomplete but it does provide the most commonly found
45  * information in vCards. Also remember that VCard transfer is not a standard, and the protocol
46  * may change or be replaced.<p>
47  *
48  * <b>Usage:</b>
49  * <pre>
50  *
51  * // To save VCard:
52  *
53  * VCard vCard = new VCard();
54  * vCard.setFirstName("kir");
55  * vCard.setLastName("max");
56  * vCard.setEmailHome("foo@fee.bar");
57  * vCard.setJabberId("jabber@id.org");
58  * vCard.setOrganization("Jetbrains, s.r.o");
59  * vCard.setNickName("KIR");
60  *
61  * vCard.setField("TITLE", "Mr");
62  * vCard.setAddressFieldHome("STREET", "Some street");
63  * vCard.setAddressFieldWork("CTRY", "US");
64  * vCard.setPhoneWork("FAX", "3443233");
65  *
66  * vCard.save(connection);
67  *
68  * // To load VCard:
69  *
70  * VCard vCard = new VCard();
71  * vCard.load(conn); // load own VCard
72  * vCard.load(conn, "joe@foo.bar"); // load someone's VCard
73  * </pre>
74  *
75  * @author Kirill Maximov (kir@maxkir.com)
76  */

77 public class VCard extends IQ {
78
79     /**
80      * Phone types:
81      * VOICE?, FAX?, PAGER?, MSG?, CELL?, VIDEO?, BBS?, MODEM?, ISDN?, PCS?, PREF?
82      */

83     private Map JavaDoc homePhones = new HashMap JavaDoc();
84     private Map JavaDoc workPhones = new HashMap JavaDoc();
85
86
87     /**
88      * Address types:
89      * POSTAL?, PARCEL?, (DOM | INTL)?, PREF?, POBOX?, EXTADR?, STREET?, LOCALITY?,
90      * REGION?, PCODE?, CTRY?
91      */

92     private Map JavaDoc homeAddr = new HashMap JavaDoc();
93     private Map JavaDoc workAddr = new HashMap JavaDoc();
94
95     private String JavaDoc firstName;
96     private String JavaDoc lastName;
97     private String JavaDoc middleName;
98
99     private String JavaDoc emailHome;
100     private String JavaDoc emailWork;
101
102     private String JavaDoc organization;
103     private String JavaDoc organizationUnit;
104
105     /**
106      * Such as DESC ROLE GEO etc.. see JEP-0054
107      */

108     private Map JavaDoc otherSimpleFields = new HashMap JavaDoc();
109
110     public VCard() {
111     }
112
113     /**
114      * Set generic VCard field.
115      *
116      * @param field value of field. Possible values: NICKNAME, PHOTO, BDAY, JABBERID, MAILER, TZ,
117      * GEO, TITLE, ROLE, LOGO, NOTE, PRODID, REV, SORT-STRING, SOUND, UID, URL, DESC.
118      */

119     public String JavaDoc getField(String JavaDoc field) {
120         return (String JavaDoc) otherSimpleFields.get(field);
121     }
122
123     /**
124      * Set generic VCard field.
125      *
126      * @param value value of field
127      * @param field field to set. See {@link #getField(String)}
128      * @see #getField(String)
129      */

130     public void setField(String JavaDoc field, String JavaDoc value) {
131         otherSimpleFields.put(field, value);
132     }
133
134     public String JavaDoc getFirstName() {
135         return firstName;
136     }
137
138     public void setFirstName(String JavaDoc firstName) {
139         this.firstName = firstName;
140     }
141
142     public String JavaDoc getLastName() {
143         return lastName;
144     }
145
146     public void setLastName(String JavaDoc lastName) {
147         this.lastName = lastName;
148     }
149
150     public String JavaDoc getMiddleName() {
151         return middleName;
152     }
153
154     public void setMiddleName(String JavaDoc middleName) {
155         this.middleName = middleName;
156     }
157
158     public String JavaDoc getNickName() {
159         return (String JavaDoc) otherSimpleFields.get("NICKNAME");
160     }
161
162     public void setNickName(String JavaDoc nickName) {
163         otherSimpleFields.put("NICKNAME", nickName);
164     }
165
166     public String JavaDoc getEmailHome() {
167         return emailHome;
168     }
169
170     public void setEmailHome(String JavaDoc email) {
171         this.emailHome = email;
172     }
173
174     public String JavaDoc getEmailWork() {
175         return emailWork;
176     }
177
178     public void setEmailWork(String JavaDoc emailWork) {
179         this.emailWork = emailWork;
180     }
181
182     public String JavaDoc getJabberId() {
183         return (String JavaDoc) otherSimpleFields.get("JABBERID");
184     }
185
186     public void setJabberId(String JavaDoc jabberId) {
187         otherSimpleFields.put("JABBERID", jabberId);
188     }
189
190     public String JavaDoc getOrganization() {
191         return organization;
192     }
193
194     public void setOrganization(String JavaDoc organization) {
195         this.organization = organization;
196     }
197
198     public String JavaDoc getOrganizationUnit() {
199         return organizationUnit;
200     }
201
202     public void setOrganizationUnit(String JavaDoc organizationUnit) {
203         this.organizationUnit = organizationUnit;
204     }
205
206     /**
207      * Get home address field
208      *
209      * @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
210      * LOCALITY, REGION, PCODE, CTRY
211      */

212     public String JavaDoc getAddressFieldHome(String JavaDoc addrField) {
213         return (String JavaDoc) homeAddr.get(addrField);
214     }
215
216     /**
217      * Set home address field
218      *
219      * @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
220      * LOCALITY, REGION, PCODE, CTRY
221      */

222     public void setAddressFieldHome(String JavaDoc addrField, String JavaDoc value) {
223         homeAddr.put(addrField, value);
224     }
225
226     /**
227      * Get work address field
228      *
229      * @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
230      * LOCALITY, REGION, PCODE, CTRY
231      */

232     public String JavaDoc getAddressFieldWork(String JavaDoc addrField) {
233         return (String JavaDoc) workAddr.get(addrField);
234     }
235
236     /**
237      * Set work address field
238      *
239      * @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
240      * LOCALITY, REGION, PCODE, CTRY
241      */

242     public void setAddressFieldWork(String JavaDoc addrField, String JavaDoc value) {
243         workAddr.put(addrField, value);
244     }
245
246
247     /**
248      * Set home phone number
249      *
250      * @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
251      * @param phoneNum phone number
252      */

253     public void setPhoneHome(String JavaDoc phoneType, String JavaDoc phoneNum) {
254         homePhones.put(phoneType, phoneNum);
255     }
256
257     /**
258      * Get home phone number
259      *
260      * @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
261      */

262     public String JavaDoc getPhoneHome(String JavaDoc phoneType) {
263         return (String JavaDoc) homePhones.get(phoneType);
264     }
265
266     /**
267      * Set work phone number
268      *
269      * @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
270      * @param phoneNum phone number
271      */

272     public void setPhoneWork(String JavaDoc phoneType, String JavaDoc phoneNum) {
273         workPhones.put(phoneType, phoneNum);
274     }
275
276     /**
277      * Get work phone number
278      *
279      * @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
280      */

281     public String JavaDoc getPhoneWork(String JavaDoc phoneType) {
282         return (String JavaDoc) workPhones.get(phoneType);
283     }
284
285     /**
286      * Save this vCard for the user connected by 'connection'. Connection should be authenticated
287      * and not anonymous.<p>
288      * <p/>
289      * NOTE: the method is asynchronous and does not wait for the returned value.
290      */

291     public void save(XMPPConnection connection) {
292         checkAuthenticated(connection);
293
294         setType(IQ.Type.SET);
295         setFrom(connection.getUser());
296         connection.sendPacket(this);
297     }
298
299     /**
300      * Load VCard information for a connected user. Connection should be authenticated
301      * and not anonymous.
302      */

303     public void load(XMPPConnection connection) throws XMPPException {
304         checkAuthenticated(connection);
305
306         setFrom(connection.getUser());
307         doLoad(connection, connection.getUser());
308     }
309
310     /**
311      * Load VCard information for a given user. Connection should be authenticated and not anonymous.
312      */

313     public void load(XMPPConnection connection, String JavaDoc user) throws XMPPException {
314         checkAuthenticated(connection);
315
316         setTo(user);
317         doLoad(connection, user);
318     }
319
320     private void doLoad(XMPPConnection connection, String JavaDoc user) throws XMPPException {
321         setType(Type.GET);
322         PacketCollector collector = connection.createPacketCollector(
323                 new PacketIDFilter(getPacketID()));
324         connection.sendPacket(this);
325
326         VCard result = null;
327         try {
328             result = (VCard) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
329
330             if (result == null) {
331                 throw new XMPPException(new XMPPError(408, "Timeout getting VCard information"));
332             }
333             if (result.getError() != null) {
334                 throw new XMPPException(result.getError());
335             }
336         } catch (ClassCastException JavaDoc e) {
337             System.out.println("No VCard for " + user);
338         }
339
340         copyFieldsFrom(result);
341     }
342
343     public String JavaDoc getChildElementXML() {
344         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
345         new VCardWriter(sb).write();
346         return sb.toString();
347     }
348
349     private void copyFieldsFrom(VCard result) {
350         if (result == null) result = new VCard();
351
352         Field JavaDoc[] fields = VCard.class.getDeclaredFields();
353         for (int i = 0; i < fields.length; i++) {
354             Field JavaDoc field = fields[i];
355             if (field.getDeclaringClass() == VCard.class &&
356                     !Modifier.isFinal(field.getModifiers())) {
357                 try {
358                     field.setAccessible(true);
359                     field.set(this, field.get(result));
360                 } catch (IllegalAccessException JavaDoc e) {
361                     throw new RuntimeException JavaDoc("This cannot happen:" + field, e);
362                 }
363             }
364         }
365     }
366
367     private void checkAuthenticated(XMPPConnection connection) {
368         if (connection == null) {
369             new IllegalArgumentException JavaDoc("No connection was provided");
370         }
371         if (!connection.isAuthenticated()) {
372             new IllegalArgumentException JavaDoc("Connection is not authenticated");
373         }
374         if (connection.isAnonymous()) {
375             new IllegalArgumentException JavaDoc("Connection cannot be anonymous");
376         }
377     }
378
379     private boolean hasContent() {
380         //noinspection OverlyComplexBooleanExpression
381
return hasNameField()
382                 || hasOrganizationFields()
383                 || emailHome != null
384                 || emailWork != null
385                 || otherSimpleFields.size() > 0
386                 || homeAddr.size() > 0
387                 || homePhones.size() > 0
388                 || workAddr.size() > 0
389                 || workPhones.size() > 0
390                 ;
391     }
392
393     private boolean hasNameField() {
394         return firstName != null || lastName != null || middleName != null;
395     }
396
397     private boolean hasOrganizationFields() {
398         return organization != null || organizationUnit != null;
399     }
400
401     // Used in tests:
402

403     public boolean equals(Object JavaDoc o) {
404         if (this == o) return true;
405         if (o == null || getClass() != o.getClass()) return false;
406
407         final VCard vCard = (VCard) o;
408
409         if (emailHome != null ? !emailHome.equals(vCard.emailHome) : vCard.emailHome != null) {
410             return false;
411         }
412         if (emailWork != null ? !emailWork.equals(vCard.emailWork) : vCard.emailWork != null) {
413             return false;
414         }
415         if (firstName != null ? !firstName.equals(vCard.firstName) : vCard.firstName != null) {
416             return false;
417         }
418         if (!homeAddr.equals(vCard.homeAddr)) {
419             return false;
420         }
421         if (!homePhones.equals(vCard.homePhones)) {
422             return false;
423         }
424         if (lastName != null ? !lastName.equals(vCard.lastName) : vCard.lastName != null) {
425             return false;
426         }
427         if (middleName != null ? !middleName.equals(vCard.middleName) : vCard.middleName != null) {
428             return false;
429         }
430         if (organization != null ?
431                 !organization.equals(vCard.organization) : vCard.organization != null) {
432             return false;
433         }
434         if (organizationUnit != null ?
435                 !organizationUnit.equals(vCard.organizationUnit) : vCard.organizationUnit != null) {
436             return false;
437         }
438         if (!otherSimpleFields.equals(vCard.otherSimpleFields)) {
439             return false;
440         }
441         if (!workAddr.equals(vCard.workAddr)) {
442             return false;
443         }
444         if (!workPhones.equals(vCard.workPhones)) {
445             return false;
446         }
447
448         return true;
449     }
450
451     public int hashCode() {
452         int result;
453         result = homePhones.hashCode();
454         result = 29 * result + workPhones.hashCode();
455         result = 29 * result + homeAddr.hashCode();
456         result = 29 * result + workAddr.hashCode();
457         result = 29 * result + (firstName != null ? firstName.hashCode() : 0);
458         result = 29 * result + (lastName != null ? lastName.hashCode() : 0);
459         result = 29 * result + (middleName != null ? middleName.hashCode() : 0);
460         result = 29 * result + (emailHome != null ? emailHome.hashCode() : 0);
461         result = 29 * result + (emailWork != null ? emailWork.hashCode() : 0);
462         result = 29 * result + (organization != null ? organization.hashCode() : 0);
463         result = 29 * result + (organizationUnit != null ? organizationUnit.hashCode() : 0);
464         result = 29 * result + otherSimpleFields.hashCode();
465         return result;
466     }
467
468     public String JavaDoc toString() {
469         return getChildElementXML();
470     }
471
472     //==============================================================
473

474     private class VCardWriter {
475         private final StringBuffer JavaDoc sb;
476
477         VCardWriter(StringBuffer JavaDoc sb) {
478             this.sb = sb;
479         }
480
481         public void write() {
482             appendTag("vCard", "xmlns", "vcard-temp", hasContent(), new ContentBuilder() {
483                 public void addTagContent() {
484                     buildActualContent();
485                 }
486             });
487         }
488
489         private void buildActualContent() {
490             if (hasNameField()) {
491                 appendFN();
492                 appendN();
493             }
494
495             appendOrganization();
496             appendGenericFields();
497
498             appendEmail(emailWork, "WORK");
499             appendEmail(emailHome, "HOME");
500
501             appendPhones(workPhones, "WORK");
502             appendPhones(homePhones, "HOME");
503
504             appendAddress(workAddr, "WORK");
505             appendAddress(homeAddr, "HOME");
506         }
507
508         private void appendEmail(final String JavaDoc email, final String JavaDoc type) {
509             if (email != null) {
510                 appendTag("EMAIL", true, new ContentBuilder() {
511                     public void addTagContent() {
512                         appendEmptyTag(type);
513                         appendEmptyTag("INTERNET");
514                         appendEmptyTag("PREF");
515                         appendTag("USERID", email);
516                     }
517                 });
518             }
519         }
520
521         private void appendPhones(Map JavaDoc phones, final String JavaDoc code) {
522             Iterator JavaDoc it = phones.entrySet().iterator();
523             while (it.hasNext()) {
524                 final Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
525                 appendTag("TEL", true, new ContentBuilder() {
526                     public void addTagContent() {
527                         appendEmptyTag(entry.getKey());
528                         appendEmptyTag(code);
529                         appendTag("NUMBER", (String JavaDoc) entry.getValue());
530                     }
531                 });
532             }
533         }
534
535         private void appendAddress(final Map JavaDoc addr, final String JavaDoc code) {
536             if (addr.size() > 0) {
537                 appendTag("ADR", true, new ContentBuilder() {
538                     public void addTagContent() {
539                         appendEmptyTag(code);
540
541                         Iterator JavaDoc it = addr.entrySet().iterator();
542                         while (it.hasNext()) {
543                             final Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
544                             appendTag((String JavaDoc) entry.getKey(), (String JavaDoc) entry.getValue());
545                         }
546                     }
547                 });
548             }
549         }
550
551         private void appendEmptyTag(Object JavaDoc tag) {
552             sb.append('<').append(tag).append("/>");
553         }
554
555         private void appendGenericFields() {
556             Iterator JavaDoc it = otherSimpleFields.entrySet().iterator();
557             while (it.hasNext()) {
558                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
559                 appendTag(entry.getKey().toString(), (String JavaDoc) entry.getValue());
560             }
561         }
562
563         private void appendOrganization() {
564             if (hasOrganizationFields()) {
565                 appendTag("ORG", true, new ContentBuilder() {
566                     public void addTagContent() {
567                         appendTag("ORGNAME", organization);
568                         appendTag("ORGUNIT", organizationUnit);
569                     }
570                 });
571             }
572         }
573
574         private void appendField(String JavaDoc tag) {
575             String JavaDoc value = (String JavaDoc) otherSimpleFields.get(tag);
576             appendTag(tag, value);
577         }
578
579         private void appendFN() {
580             final ContentBuilder contentBuilder = new ContentBuilder() {
581                 public void addTagContent() {
582                     if (firstName != null) {
583                         sb.append(firstName + ' ');
584                     }
585                     if (middleName != null) {
586                         sb.append(middleName + ' ');
587                     }
588                     if (lastName != null) {
589                         sb.append(lastName);
590                     }
591                 }
592             };
593             appendTag("FN", true, contentBuilder);
594         }
595
596         private void appendN() {
597             appendTag("N", true, new ContentBuilder() {
598                 public void addTagContent() {
599                     appendTag("FAMILY", lastName);
600                     appendTag("GIVEN", firstName);
601                     appendTag("MIDDLE", middleName);
602                 }
603             });
604         }
605
606         private void appendTag(String JavaDoc tag, String JavaDoc attr, String JavaDoc attrValue, boolean hasContent,
607                                ContentBuilder builder) {
608             sb.append('<').append(tag);
609             if (attr != null) {
610                 sb.append(' ').append(attr).append('=').append('\'').append(attrValue).append('\'');
611             }
612
613             if (hasContent) {
614                 sb.append('>');
615                 builder.addTagContent();
616                 sb.append("</").append(tag).append(">\n");
617             } else {
618                 sb.append("/>\n");
619             }
620         }
621
622         private void appendTag(String JavaDoc tag, boolean hasContent, ContentBuilder builder) {
623             appendTag(tag, null, null, hasContent, builder);
624         }
625
626         private void appendTag(String JavaDoc tag, final String JavaDoc tagText) {
627             if (tagText == null) return;
628             final ContentBuilder contentBuilder = new ContentBuilder() {
629                 public void addTagContent() {
630                     sb.append(tagText.trim());
631                 }
632             };
633             appendTag(tag, true, contentBuilder);
634         }
635
636     }
637
638     //==============================================================
639

640     private interface ContentBuilder {
641         void addTagContent();
642     }
643
644     //==============================================================
645
}
646
647
Popular Tags