mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
Initial version. SMACK-58
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@2508 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
0f43eb7a48
commit
680e57dcbf
3 changed files with 917 additions and 0 deletions
648
source/org/jivesoftware/smackx/packet/VCard.java
Normal file
648
source/org/jivesoftware/smackx/packet/VCard.java
Normal file
|
@ -0,0 +1,648 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2004 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.packet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.PacketCollector;
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.packet.XMPPError;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A VCard class for use with the
|
||||||
|
* <a href="http://www.jivesoftware.com/xmpp/smack/" target="_blank">SMACK jabber library</a>.<p>
|
||||||
|
*
|
||||||
|
* You should refer to the
|
||||||
|
* <a href="http://www.jabber.org/jeps/jep-0054.html" target="_blank">JEP-54 documentation</a>.<p>
|
||||||
|
*
|
||||||
|
* Please note that this class is incomplete but it does provide the most commonly found
|
||||||
|
* information in vCards. Also remember that VCard transfer is not a standard, and the protocol
|
||||||
|
* may change or be replaced.<p>
|
||||||
|
*
|
||||||
|
* <b>Usage:</b>
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* // To save VCard:
|
||||||
|
*
|
||||||
|
* VCard vCard = new VCard();
|
||||||
|
* vCard.setFirstName("kir");
|
||||||
|
* vCard.setLastName("max");
|
||||||
|
* vCard.setEmailHome("foo@fee.bar");
|
||||||
|
* vCard.setJabberId("jabber@id.org");
|
||||||
|
* vCard.setOrganization("Jetbrains, s.r.o");
|
||||||
|
* vCard.setNickName("KIR");
|
||||||
|
*
|
||||||
|
* vCard.setField("TITLE", "Mr");
|
||||||
|
* vCard.setAddressFieldHome("STREET", "Some street");
|
||||||
|
* vCard.setAddressFieldWork("CTRY", "US");
|
||||||
|
* vCard.setPhoneWork("FAX", "3443233");
|
||||||
|
*
|
||||||
|
* vCard.save(connection);
|
||||||
|
*
|
||||||
|
* // To load VCard:
|
||||||
|
*
|
||||||
|
* VCard vCard = new VCard();
|
||||||
|
* vCard.load(conn); // load own VCard
|
||||||
|
* vCard.load(conn, "joe@foo.bar"); // load someone's VCard
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Kirill Maximov (kir@maxkir.com)
|
||||||
|
*/
|
||||||
|
public class VCard extends IQ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Phone types:
|
||||||
|
* VOICE?, FAX?, PAGER?, MSG?, CELL?, VIDEO?, BBS?, MODEM?, ISDN?, PCS?, PREF?
|
||||||
|
*/
|
||||||
|
private Map homePhones = new HashMap();
|
||||||
|
private Map workPhones = new HashMap();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address types:
|
||||||
|
* POSTAL?, PARCEL?, (DOM | INTL)?, PREF?, POBOX?, EXTADR?, STREET?, LOCALITY?,
|
||||||
|
* REGION?, PCODE?, CTRY?
|
||||||
|
*/
|
||||||
|
private Map homeAddr = new HashMap();
|
||||||
|
private Map workAddr = new HashMap();
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private String middleName;
|
||||||
|
|
||||||
|
private String emailHome;
|
||||||
|
private String emailWork;
|
||||||
|
|
||||||
|
private String organization;
|
||||||
|
private String organizationUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Such as DESC ROLE GEO etc.. see JEP-0054
|
||||||
|
*/
|
||||||
|
private Map otherSimpleFields = new HashMap();
|
||||||
|
|
||||||
|
public VCard() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set generic VCard field.
|
||||||
|
*
|
||||||
|
* @param field value of field
|
||||||
|
* @param field NICKNAME, PHOTO, BDAY, JABBERID, MAILER, TZ, GEO, TITLE, ROLE, LOGO,
|
||||||
|
* NOTE, PRODID, REV,
|
||||||
|
* SORT-STRING, SOUND, UID, URL, DESC
|
||||||
|
*/
|
||||||
|
public String getField(String field) {
|
||||||
|
return (String) otherSimpleFields.get(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set generic VCard field.
|
||||||
|
*
|
||||||
|
* @param value value of field
|
||||||
|
* @param field field to set. See {@link #getField(String)}
|
||||||
|
* @see #getField(String)
|
||||||
|
*/
|
||||||
|
public void setField(String field, String value) {
|
||||||
|
otherSimpleFields.put(field, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMiddleName() {
|
||||||
|
return middleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiddleName(String middleName) {
|
||||||
|
this.middleName = middleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickName() {
|
||||||
|
return (String) otherSimpleFields.get("NICKNAME");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickName(String nickName) {
|
||||||
|
otherSimpleFields.put("NICKNAME", nickName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmailHome() {
|
||||||
|
return emailHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailHome(String email) {
|
||||||
|
this.emailHome = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmailWork() {
|
||||||
|
return emailWork;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailWork(String emailWork) {
|
||||||
|
this.emailWork = emailWork;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJabberId() {
|
||||||
|
return (String) otherSimpleFields.get("JABBERID");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJabberId(String jabberId) {
|
||||||
|
otherSimpleFields.put("JABBERID", jabberId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrganization() {
|
||||||
|
return organization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrganization(String organization) {
|
||||||
|
this.organization = organization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrganizationUnit() {
|
||||||
|
return organizationUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrganizationUnit(String organizationUnit) {
|
||||||
|
this.organizationUnit = organizationUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get home address field
|
||||||
|
*
|
||||||
|
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||||
|
* LOCALITY, REGION, PCODE, CTRY
|
||||||
|
*/
|
||||||
|
public String getAddressFieldHome(String addrField) {
|
||||||
|
return (String) homeAddr.get(addrField);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set home address field
|
||||||
|
*
|
||||||
|
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||||
|
* LOCALITY, REGION, PCODE, CTRY
|
||||||
|
*/
|
||||||
|
public void setAddressFieldHome(String addrField, String value) {
|
||||||
|
homeAddr.put(addrField, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get work address field
|
||||||
|
*
|
||||||
|
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||||
|
* LOCALITY, REGION, PCODE, CTRY
|
||||||
|
*/
|
||||||
|
public String getAddressFieldWork(String addrField) {
|
||||||
|
return (String) workAddr.get(addrField);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set work address field
|
||||||
|
*
|
||||||
|
* @param addrField one of POSTAL, PARCEL, (DOM | INTL), PREF, POBOX, EXTADR, STREET,
|
||||||
|
* LOCALITY, REGION, PCODE, CTRY
|
||||||
|
*/
|
||||||
|
public void setAddressFieldWork(String addrField, String value) {
|
||||||
|
workAddr.put(addrField, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set home phone number
|
||||||
|
*
|
||||||
|
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||||
|
* @param phoneNum phone number
|
||||||
|
*/
|
||||||
|
public void setPhoneHome(String phoneType, String phoneNum) {
|
||||||
|
homePhones.put(phoneType, phoneNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get home phone number
|
||||||
|
*
|
||||||
|
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||||
|
*/
|
||||||
|
public String getPhoneHome(String phoneType) {
|
||||||
|
return (String) homePhones.get(phoneType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set work phone number
|
||||||
|
*
|
||||||
|
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||||
|
* @param phoneNum phone number
|
||||||
|
*/
|
||||||
|
public void setPhoneWork(String phoneType, String phoneNum) {
|
||||||
|
workPhones.put(phoneType, phoneNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get work phone number
|
||||||
|
*
|
||||||
|
* @param phoneType one of VOICE, FAX, PAGER, MSG, CELL, VIDEO, BBS, MODEM, ISDN, PCS, PREF
|
||||||
|
*/
|
||||||
|
public String getPhoneWork(String phoneType) {
|
||||||
|
return (String) workPhones.get(phoneType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save this vCard for the user connected by 'connection'. Connection should be authenticated
|
||||||
|
* and not anonymous.<p>
|
||||||
|
* <p/>
|
||||||
|
* NOTE: the method is asynchronous and does not wait for the returned value.
|
||||||
|
*/
|
||||||
|
public void save(XMPPConnection connection) {
|
||||||
|
checkAuthenticated(connection);
|
||||||
|
|
||||||
|
setType(IQ.Type.SET);
|
||||||
|
setFrom(connection.getUser());
|
||||||
|
connection.sendPacket(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load VCard information for a connected user. Connection should be authenticated
|
||||||
|
* and not anonymous.
|
||||||
|
*/
|
||||||
|
public void load(XMPPConnection connection) throws XMPPException {
|
||||||
|
checkAuthenticated(connection);
|
||||||
|
|
||||||
|
setFrom(connection.getUser());
|
||||||
|
doLoad(connection, connection.getUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load VCard information for a given user. Connection should be authenticated and not anonymous.
|
||||||
|
*/
|
||||||
|
public void load(XMPPConnection connection, String user) throws XMPPException {
|
||||||
|
checkAuthenticated(connection);
|
||||||
|
|
||||||
|
setTo(user);
|
||||||
|
doLoad(connection, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doLoad(XMPPConnection connection, String user) throws XMPPException {
|
||||||
|
setType(Type.GET);
|
||||||
|
PacketCollector collector = connection.createPacketCollector(
|
||||||
|
new PacketIDFilter(getPacketID()));
|
||||||
|
connection.sendPacket(this);
|
||||||
|
|
||||||
|
VCard result = null;
|
||||||
|
try {
|
||||||
|
result = (VCard) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
throw new XMPPException(new XMPPError(408, "Timeout getting VCard information"));
|
||||||
|
}
|
||||||
|
if (result.getError() != null) {
|
||||||
|
throw new XMPPException(result.getError());
|
||||||
|
}
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
System.out.println("No VCard for " + user);
|
||||||
|
}
|
||||||
|
|
||||||
|
copyFieldsFrom(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getChildElementXML() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
new VCardWriter(sb).write();
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyFieldsFrom(VCard result) {
|
||||||
|
if (result == null) result = new VCard();
|
||||||
|
|
||||||
|
Field[] fields = VCard.class.getDeclaredFields();
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
Field field = fields[i];
|
||||||
|
if (field.getDeclaringClass() == VCard.class &&
|
||||||
|
!Modifier.isFinal(field.getModifiers())) {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(this, field.get(result));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("This cannot happen:" + field, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAuthenticated(XMPPConnection connection) {
|
||||||
|
if (connection == null) {
|
||||||
|
new IllegalArgumentException("No connection was provided");
|
||||||
|
}
|
||||||
|
if (!connection.isAuthenticated()) {
|
||||||
|
new IllegalArgumentException("Connection is not authenticated");
|
||||||
|
}
|
||||||
|
if (connection.isAnonymous()) {
|
||||||
|
new IllegalArgumentException("Connection cannot be anonymous");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasContent() {
|
||||||
|
//noinspection OverlyComplexBooleanExpression
|
||||||
|
return hasNameField()
|
||||||
|
|| hasOrganizationFields()
|
||||||
|
|| emailHome != null
|
||||||
|
|| emailWork != null
|
||||||
|
|| otherSimpleFields.size() > 0
|
||||||
|
|| homeAddr.size() > 0
|
||||||
|
|| homePhones.size() > 0
|
||||||
|
|| workAddr.size() > 0
|
||||||
|
|| workPhones.size() > 0
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasNameField() {
|
||||||
|
return firstName != null || lastName != null || middleName != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasOrganizationFields() {
|
||||||
|
return organization != null || organizationUnit != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used in tests:
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
final VCard vCard = (VCard) o;
|
||||||
|
|
||||||
|
if (emailHome != null ? !emailHome.equals(vCard.emailHome) : vCard.emailHome != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (emailWork != null ? !emailWork.equals(vCard.emailWork) : vCard.emailWork != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (firstName != null ? !firstName.equals(vCard.firstName) : vCard.firstName != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!homeAddr.equals(vCard.homeAddr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!homePhones.equals(vCard.homePhones)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (lastName != null ? !lastName.equals(vCard.lastName) : vCard.lastName != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (middleName != null ? !middleName.equals(vCard.middleName) : vCard.middleName != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (organization != null ?
|
||||||
|
!organization.equals(vCard.organization) : vCard.organization != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (organizationUnit != null ?
|
||||||
|
!organizationUnit.equals(vCard.organizationUnit) : vCard.organizationUnit != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!otherSimpleFields.equals(vCard.otherSimpleFields)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!workAddr.equals(vCard.workAddr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!workPhones.equals(vCard.workPhones)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int result;
|
||||||
|
result = homePhones.hashCode();
|
||||||
|
result = 29 * result + workPhones.hashCode();
|
||||||
|
result = 29 * result + homeAddr.hashCode();
|
||||||
|
result = 29 * result + workAddr.hashCode();
|
||||||
|
result = 29 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||||
|
result = 29 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||||
|
result = 29 * result + (middleName != null ? middleName.hashCode() : 0);
|
||||||
|
result = 29 * result + (emailHome != null ? emailHome.hashCode() : 0);
|
||||||
|
result = 29 * result + (emailWork != null ? emailWork.hashCode() : 0);
|
||||||
|
result = 29 * result + (organization != null ? organization.hashCode() : 0);
|
||||||
|
result = 29 * result + (organizationUnit != null ? organizationUnit.hashCode() : 0);
|
||||||
|
result = 29 * result + otherSimpleFields.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getChildElementXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
|
||||||
|
private class VCardWriter {
|
||||||
|
private final StringBuffer sb;
|
||||||
|
|
||||||
|
VCardWriter(StringBuffer sb) {
|
||||||
|
this.sb = sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write() {
|
||||||
|
appendTag("vCard", "xmlns", "vcard-temp", hasContent(), new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
buildActualContent();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildActualContent() {
|
||||||
|
if (hasNameField()) {
|
||||||
|
appendFN();
|
||||||
|
appendN();
|
||||||
|
}
|
||||||
|
|
||||||
|
appendOrganization();
|
||||||
|
appendGenericFields();
|
||||||
|
|
||||||
|
appendEmail(emailWork, "WORK");
|
||||||
|
appendEmail(emailHome, "HOME");
|
||||||
|
|
||||||
|
appendPhones(workPhones, "WORK");
|
||||||
|
appendPhones(homePhones, "HOME");
|
||||||
|
|
||||||
|
appendAddress(workAddr, "WORK");
|
||||||
|
appendAddress(homeAddr, "HOME");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendEmail(final String email, final String type) {
|
||||||
|
if (email != null) {
|
||||||
|
appendTag("EMAIL", true, new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
appendEmptyTag(type);
|
||||||
|
appendEmptyTag("INTERNET");
|
||||||
|
appendEmptyTag("PREF");
|
||||||
|
appendTag("USERID", email);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendPhones(Map phones, final String code) {
|
||||||
|
Iterator it = phones.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
final Map.Entry entry = (Map.Entry) it.next();
|
||||||
|
appendTag("TEL", true, new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
appendEmptyTag(entry.getKey());
|
||||||
|
appendEmptyTag(code);
|
||||||
|
appendTag("NUMBER", (String) entry.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendAddress(final Map addr, final String code) {
|
||||||
|
if (addr.size() > 0) {
|
||||||
|
appendTag("ADR", true, new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
appendEmptyTag(code);
|
||||||
|
|
||||||
|
Iterator it = addr.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
final Map.Entry entry = (Map.Entry) it.next();
|
||||||
|
appendTag((String) entry.getKey(), (String) entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendEmptyTag(Object tag) {
|
||||||
|
sb.append('<').append(tag).append("/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendGenericFields() {
|
||||||
|
Iterator it = otherSimpleFields.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Map.Entry entry = (Map.Entry) it.next();
|
||||||
|
appendTag(entry.getKey().toString(), (String) entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendOrganization() {
|
||||||
|
if (hasOrganizationFields()) {
|
||||||
|
appendTag("ORG", true, new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
appendTag("ORGNAME", organization);
|
||||||
|
appendTag("ORGUNIT", organizationUnit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendField(String tag) {
|
||||||
|
String value = (String) otherSimpleFields.get(tag);
|
||||||
|
appendTag(tag, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendFN() {
|
||||||
|
final ContentBuilder contentBuilder = new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
if (firstName != null) {
|
||||||
|
sb.append(firstName + ' ');
|
||||||
|
}
|
||||||
|
if (middleName != null) {
|
||||||
|
sb.append(middleName + ' ');
|
||||||
|
}
|
||||||
|
if (lastName != null) {
|
||||||
|
sb.append(lastName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
appendTag("FN", true, contentBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendN() {
|
||||||
|
appendTag("N", true, new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
appendTag("FAMILY", lastName);
|
||||||
|
appendTag("GIVEN", firstName);
|
||||||
|
appendTag("MIDDLE", middleName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendTag(String tag, String attr, String attrValue, boolean hasContent,
|
||||||
|
ContentBuilder builder) {
|
||||||
|
sb.append('<').append(tag);
|
||||||
|
if (attr != null) {
|
||||||
|
sb.append(' ').append(attr).append('=').append('\'').append(attrValue).append('\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasContent) {
|
||||||
|
sb.append('>');
|
||||||
|
builder.addTagContent();
|
||||||
|
sb.append("</").append(tag).append(">\n");
|
||||||
|
} else {
|
||||||
|
sb.append("/>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendTag(String tag, boolean hasContent, ContentBuilder builder) {
|
||||||
|
appendTag(tag, null, null, hasContent, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendTag(String tag, final String tagText) {
|
||||||
|
if (tagText == null) return;
|
||||||
|
final ContentBuilder contentBuilder = new ContentBuilder() {
|
||||||
|
public void addTagContent() {
|
||||||
|
sb.append(tagText.trim());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
appendTag(tag, true, contentBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
|
||||||
|
private interface ContentBuilder {
|
||||||
|
void addTagContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
}
|
||||||
|
|
209
source/org/jivesoftware/smackx/provider/VCardProvider.java
Normal file
209
source/org/jivesoftware/smackx/provider/VCardProvider.java
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2004 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smackx.packet.VCard;
|
||||||
|
import org.w3c.dom.*;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: Gaston
|
||||||
|
* Date: Jun 18, 2005
|
||||||
|
* Time: 1:00:57 AM
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public class VCardProvider implements IQProvider {
|
||||||
|
|
||||||
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
try {
|
||||||
|
int event = parser.getEventType();
|
||||||
|
// get the content
|
||||||
|
while (true) {
|
||||||
|
switch (event) {
|
||||||
|
case XmlPullParser.TEXT:
|
||||||
|
sb.append(parser.getText());
|
||||||
|
break;
|
||||||
|
case XmlPullParser.START_TAG:
|
||||||
|
sb.append('<' + parser.getName() + '>');
|
||||||
|
break;
|
||||||
|
case XmlPullParser.END_TAG:
|
||||||
|
sb.append("</" + parser.getName() + '>');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == XmlPullParser.END_TAG && "vCard".equals(parser.getName())) break;
|
||||||
|
|
||||||
|
event = parser.next();
|
||||||
|
}
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
String xmlText = sb.toString();
|
||||||
|
VCard vCard = new VCard();
|
||||||
|
try {
|
||||||
|
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||||
|
Document document = documentBuilder.parse(new ByteArrayInputStream(xmlText.getBytes()));
|
||||||
|
|
||||||
|
new VCardReader(vCard, document).initializeFields();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
return vCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class VCardReader {
|
||||||
|
private final VCard vCard;
|
||||||
|
private final Document document;
|
||||||
|
|
||||||
|
VCardReader(VCard vCard, Document document) {
|
||||||
|
this.vCard = vCard;
|
||||||
|
this.document = document;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initializeFields() {
|
||||||
|
vCard.setFirstName(getTagContents("GIVEN"));
|
||||||
|
vCard.setLastName(getTagContents("FAMILY"));
|
||||||
|
vCard.setMiddleName(getTagContents("MIDDLE"));
|
||||||
|
|
||||||
|
setupEmails();
|
||||||
|
|
||||||
|
vCard.setOrganization(getTagContents("ORGNAME"));
|
||||||
|
vCard.setOrganizationUnit(getTagContents("ORGUNIT"));
|
||||||
|
|
||||||
|
setupSimpleFields();
|
||||||
|
setupPhones("WORK", true);
|
||||||
|
setupPhones("HOME", false);
|
||||||
|
|
||||||
|
setupAddress("WORK", true);
|
||||||
|
setupAddress("HOME", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupEmails() {
|
||||||
|
NodeList nodes = document.getElementsByTagName("USERID");
|
||||||
|
for (int i = 0; i < nodes.getLength(); i++) {
|
||||||
|
Element element = (Element) nodes.item(i);
|
||||||
|
if ("WORK".equals(element.getParentNode().getFirstChild().getNodeName())) {
|
||||||
|
vCard.setEmailWork(getTextContent(element));
|
||||||
|
} else {
|
||||||
|
vCard.setEmailHome(getTextContent(element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupPhones(String type, boolean work) {
|
||||||
|
NodeList allPhones = document.getElementsByTagName("TEL");
|
||||||
|
for (int i = 0; i < allPhones.getLength(); i++) {
|
||||||
|
Element node = (Element) allPhones.item(i);
|
||||||
|
if (type.equals(node.getChildNodes().item(1).getNodeName())) {
|
||||||
|
String code = node.getFirstChild().getNodeName();
|
||||||
|
String value = getTextContent(node.getChildNodes().item(2));
|
||||||
|
if (work) {
|
||||||
|
vCard.setPhoneWork(code, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vCard.setPhoneHome(code, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAddress(String type, boolean work) {
|
||||||
|
NodeList allAddresses = document.getElementsByTagName("ADR");
|
||||||
|
for (int i = 0; i < allAddresses.getLength(); i++) {
|
||||||
|
Element node = (Element) allAddresses.item(i);
|
||||||
|
NodeList childNodes = node.getChildNodes();
|
||||||
|
if (type.equals(childNodes.item(0).getNodeName())) {
|
||||||
|
for (int j = 1; j < childNodes.getLength(); j++) {
|
||||||
|
Node item = childNodes.item(j);
|
||||||
|
if (item instanceof Element) {
|
||||||
|
if (work) {
|
||||||
|
vCard.setAddressFieldWork(item.getNodeName(), getTextContent(item));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vCard.setAddressFieldHome(item.getNodeName(), getTextContent(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTagContents(String tag) {
|
||||||
|
NodeList nodes = document.getElementsByTagName(tag);
|
||||||
|
if (nodes.getLength() == 1) {
|
||||||
|
return getTextContent(nodes.item(0));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSimpleFields() {
|
||||||
|
NodeList childNodes = document.getDocumentElement().getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node node = childNodes.item(i);
|
||||||
|
if (node instanceof Element) {
|
||||||
|
Element element = (Element) node;
|
||||||
|
if ("FN".equals(element.getNodeName())) continue;
|
||||||
|
|
||||||
|
if (element.getChildNodes().getLength() == 0) {
|
||||||
|
vCard.setField(element.getNodeName(), "");
|
||||||
|
} else if (element.getChildNodes().getLength() == 1 &&
|
||||||
|
element.getChildNodes().item(0) instanceof Text) {
|
||||||
|
vCard.setField(element.getNodeName(), getTextContent(element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTextContent(Node node) {
|
||||||
|
StringBuffer result = new StringBuffer();
|
||||||
|
appendText(result, node);
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendText(StringBuffer result, Node node) {
|
||||||
|
NodeList childNodes = node.getChildNodes();
|
||||||
|
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||||
|
Node nd = childNodes.item(i);
|
||||||
|
String nodeValue = nd.getNodeValue();
|
||||||
|
if (nodeValue != null) {
|
||||||
|
result.append(nodeValue);
|
||||||
|
}
|
||||||
|
appendText(result, nd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
test/org/jivesoftware/smackx/VCardTest.java
Normal file
60
test/org/jivesoftware/smackx/VCardTest.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package org.jivesoftware.smackx;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.test.SmackTestCase;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smackx.packet.VCard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: Gaston
|
||||||
|
* Date: Jun 18, 2005
|
||||||
|
* Time: 1:29:30 AM
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public class VCardTest extends SmackTestCase {
|
||||||
|
|
||||||
|
public VCardTest(String arg0) {
|
||||||
|
super(arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBigFunctional() {
|
||||||
|
VCard origVCard = new VCard();
|
||||||
|
|
||||||
|
origVCard.setFirstName("kir");
|
||||||
|
origVCard.setLastName("max");
|
||||||
|
origVCard.setEmailHome("foo@fee.bar");
|
||||||
|
origVCard.setJabberId("jabber@id.org");
|
||||||
|
origVCard.setOrganization("Jetbrains, s.r.o");
|
||||||
|
origVCard.setNickName("KIR");
|
||||||
|
|
||||||
|
origVCard.setField("TITLE", "Mr");
|
||||||
|
origVCard.setAddressFieldHome("STREET", "Some street");
|
||||||
|
origVCard.setPhoneWork("FAX", "3443233");
|
||||||
|
|
||||||
|
origVCard.save(getConnection(0));
|
||||||
|
|
||||||
|
VCard loaded = new VCard();
|
||||||
|
try {
|
||||||
|
loaded.load(getConnection(0));
|
||||||
|
} catch (XMPPException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Should load own VCard successfully", origVCard, loaded);
|
||||||
|
|
||||||
|
loaded = new VCard();
|
||||||
|
try {
|
||||||
|
loaded.load(getConnection(1), getBareJID(0));
|
||||||
|
} catch (XMPPException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Should load another user's VCard successfully", origVCard, loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getMaxConnections() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue