mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-23 06:42:05 +01:00
1 - Small fix in Roster to return unavailable presence with from.
2 - Throw exception if parsing of vCard fails. git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7217 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
0bd96e5156
commit
1f8cb4452b
3 changed files with 115 additions and 97 deletions
|
@ -36,16 +36,16 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
/**
|
/**
|
||||||
* Represents a user's roster, which is the collection of users a person receives
|
* Represents a user's roster, which is the collection of users a person receives
|
||||||
* presence updates for. Roster items are categorized into groups for easier management.<p>
|
* presence updates for. Roster items are categorized into groups for easier management.<p>
|
||||||
*
|
* <p/>
|
||||||
* Others users may attempt to subscribe to this user using a subscription request. Three
|
* Others users may attempt to subscribe to this user using a subscription request. Three
|
||||||
* modes are supported for handling these requests: <ul>
|
* modes are supported for handling these requests: <ul>
|
||||||
* <li>{@link SubscriptionMode#accept_all accept_all} -- accept all subscription requests.</li>
|
* <li>{@link SubscriptionMode#accept_all accept_all} -- accept all subscription requests.</li>
|
||||||
* <li>{@link SubscriptionMode#reject_all reject_all} -- reject all subscription requests.</li>
|
* <li>{@link SubscriptionMode#reject_all reject_all} -- reject all subscription requests.</li>
|
||||||
* <li>{@link SubscriptionMode#manual manual} -- manually process all subscription requests.</li>
|
* <li>{@link SubscriptionMode#manual manual} -- manually process all subscription requests.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see XMPPConnection#getRoster()
|
|
||||||
* @author Matt Tucker
|
* @author Matt Tucker
|
||||||
|
* @see XMPPConnection#getRoster()
|
||||||
*/
|
*/
|
||||||
public class Roster {
|
public class Roster {
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public class Roster {
|
||||||
*/
|
*/
|
||||||
Roster(final XMPPConnection connection) {
|
Roster(final XMPPConnection connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
groups = new ConcurrentHashMap<String,RosterGroup>();
|
groups = new ConcurrentHashMap<String, RosterGroup>();
|
||||||
unfiledEntries = new CopyOnWriteArrayList<RosterEntry>();
|
unfiledEntries = new CopyOnWriteArrayList<RosterEntry>();
|
||||||
entries = new CopyOnWriteArrayList<RosterEntry>();
|
entries = new CopyOnWriteArrayList<RosterEntry>();
|
||||||
rosterListeners = new CopyOnWriteArrayList<RosterListener>();
|
rosterListeners = new CopyOnWriteArrayList<RosterListener>();
|
||||||
|
@ -141,7 +141,7 @@ public class Roster {
|
||||||
* Returns the subscription processing mode, which dictates what action
|
* Returns the subscription processing mode, which dictates what action
|
||||||
* Smack will take when subscription requests from other users are made.
|
* Smack will take when subscription requests from other users are made.
|
||||||
* The default subscription mode is {@link SubscriptionMode#accept_all}.<p>
|
* The default subscription mode is {@link SubscriptionMode#accept_all}.<p>
|
||||||
*
|
* <p/>
|
||||||
* If using the manual mode, a PacketListener should be registered that
|
* If using the manual mode, a PacketListener should be registered that
|
||||||
* listens for Presence packets that have a type of
|
* listens for Presence packets that have a type of
|
||||||
* {@link org.jivesoftware.smack.packet.Presence.Type#subscribe}.
|
* {@link org.jivesoftware.smack.packet.Presence.Type#subscribe}.
|
||||||
|
@ -156,7 +156,7 @@ public class Roster {
|
||||||
* Sets the subscription processing mode, which dictates what action
|
* Sets the subscription processing mode, which dictates what action
|
||||||
* Smack will take when subscription requests from other users are made.
|
* Smack will take when subscription requests from other users are made.
|
||||||
* The default subscription mode is {@link SubscriptionMode#accept_all}.<p>
|
* The default subscription mode is {@link SubscriptionMode#accept_all}.<p>
|
||||||
*
|
* <p/>
|
||||||
* If using the manual mode, a PacketListener should be registered that
|
* If using the manual mode, a PacketListener should be registered that
|
||||||
* listens for Presence packets that have a type of
|
* listens for Presence packets that have a type of
|
||||||
* {@link org.jivesoftware.smack.packet.Presence.Type#subscribe}.
|
* {@link org.jivesoftware.smack.packet.Presence.Type#subscribe}.
|
||||||
|
@ -184,7 +184,7 @@ public class Roster {
|
||||||
*/
|
*/
|
||||||
public void addRosterListener(RosterListener rosterListener) {
|
public void addRosterListener(RosterListener rosterListener) {
|
||||||
if (!rosterListeners.contains(rosterListener)) {
|
if (!rosterListeners.contains(rosterListener)) {
|
||||||
rosterListeners.add(rosterListener);
|
rosterListeners.add(rosterListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ public class Roster {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new group.<p>
|
* Creates a new group.<p>
|
||||||
*
|
* <p/>
|
||||||
* Note: you must add at least one entry to the group for the group to be kept
|
* Note: you must add at least one entry to the group for the group to be kept
|
||||||
* after a logout/login. This is due to the way that XMPP stores group information.
|
* after a logout/login. This is due to the way that XMPP stores group information.
|
||||||
*
|
*
|
||||||
|
@ -220,13 +220,13 @@ public class Roster {
|
||||||
* Creates a new roster entry and presence subscription. The server will asynchronously
|
* Creates a new roster entry and presence subscription. The server will asynchronously
|
||||||
* update the roster with the subscription status.
|
* update the roster with the subscription status.
|
||||||
*
|
*
|
||||||
* @param user the user. (e.g. johndoe@jabber.org)
|
* @param user the user. (e.g. johndoe@jabber.org)
|
||||||
* @param name the nickname of the user.
|
* @param name the nickname of the user.
|
||||||
* @param groups the list of group names the entry will belong to, or <tt>null</tt> if the
|
* @param groups the list of group names the entry will belong to, or <tt>null</tt> if the
|
||||||
* the roster entry won't belong to a group.
|
* the roster entry won't belong to a group.
|
||||||
* @throws XMPPException if an XMPP exception occurs.
|
* @throws XMPPException if an XMPP exception occurs.
|
||||||
*/
|
*/
|
||||||
public void createEntry(String user, String name, String [] groups) throws XMPPException {
|
public void createEntry(String user, String name, String[] groups) throws XMPPException {
|
||||||
// Create and send roster entry creation packet.
|
// Create and send roster entry creation packet.
|
||||||
RosterPacket rosterPacket = new RosterPacket();
|
RosterPacket rosterPacket = new RosterPacket();
|
||||||
rosterPacket.setType(IQ.Type.SET);
|
rosterPacket.setType(IQ.Type.SET);
|
||||||
|
@ -243,7 +243,7 @@ public class Roster {
|
||||||
PacketCollector collector = connection.createPacketCollector(
|
PacketCollector collector = connection.createPacketCollector(
|
||||||
new PacketIDFilter(rosterPacket.getPacketID()));
|
new PacketIDFilter(rosterPacket.getPacketID()));
|
||||||
connection.sendPacket(rosterPacket);
|
connection.sendPacket(rosterPacket);
|
||||||
IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
collector.cancel();
|
collector.cancel();
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
throw new XMPPException("No response from the server.");
|
throw new XMPPException("No response from the server.");
|
||||||
|
@ -281,9 +281,9 @@ public class Roster {
|
||||||
item.setItemType(RosterPacket.ItemType.remove);
|
item.setItemType(RosterPacket.ItemType.remove);
|
||||||
packet.addRosterItem(item);
|
packet.addRosterItem(item);
|
||||||
PacketCollector collector = connection.createPacketCollector(
|
PacketCollector collector = connection.createPacketCollector(
|
||||||
new PacketIDFilter(packet.getPacketID()));
|
new PacketIDFilter(packet.getPacketID()));
|
||||||
connection.sendPacket(packet);
|
connection.sendPacket(packet);
|
||||||
IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||||
collector.cancel();
|
collector.cancel();
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
throw new XMPPException("No response from the server.");
|
throw new XMPPException("No response from the server.");
|
||||||
|
@ -349,7 +349,7 @@ public class Roster {
|
||||||
* <tt>null</tt> if the user is not an entry in the roster.
|
* <tt>null</tt> if the user is not an entry in the roster.
|
||||||
*
|
*
|
||||||
* @param user the XMPP address of the user (eg "jsmith@example.com"). The address could be
|
* @param user the XMPP address of the user (eg "jsmith@example.com"). The address could be
|
||||||
* in any valid format (e.g. "domain/resource", "user@domain" or "user@domain/resource").
|
* in any valid format (e.g. "domain/resource", "user@domain" or "user@domain/resource").
|
||||||
* @return the roster entry or <tt>null</tt> if it does not exist.
|
* @return the roster entry or <tt>null</tt> if it does not exist.
|
||||||
*/
|
*/
|
||||||
public RosterEntry getEntry(String user) {
|
public RosterEntry getEntry(String user) {
|
||||||
|
@ -369,8 +369,8 @@ public class Roster {
|
||||||
* Returns true if the specified XMPP address is an entry in the roster.
|
* Returns true if the specified XMPP address is an entry in the roster.
|
||||||
*
|
*
|
||||||
* @param user the XMPP address of the user (eg "jsmith@example.com"). The
|
* @param user the XMPP address of the user (eg "jsmith@example.com"). The
|
||||||
* address could be in any valid format (e.g. "domain/resource",
|
* address could be in any valid format (e.g. "domain/resource",
|
||||||
* "user@domain" or "user@domain/resource").
|
* "user@domain" or "user@domain/resource").
|
||||||
* @return true if the XMPP address is an entry in the roster.
|
* @return true if the XMPP address is an entry in the roster.
|
||||||
*/
|
*/
|
||||||
public boolean contains(String user) {
|
public boolean contains(String user) {
|
||||||
|
@ -385,7 +385,7 @@ public class Roster {
|
||||||
* @return the roster group with the specified name.
|
* @return the roster group with the specified name.
|
||||||
*/
|
*/
|
||||||
public RosterGroup getGroup(String name) {
|
public RosterGroup getGroup(String name) {
|
||||||
return groups.get(name);
|
return groups.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -410,14 +410,14 @@ public class Roster {
|
||||||
* Returns the presence info for a particular user. If the user is offline, or
|
* Returns the presence info for a particular user. If the user is offline, or
|
||||||
* if no presence data is available (such as when you are not subscribed to the
|
* if no presence data is available (such as when you are not subscribed to the
|
||||||
* user's presence updates), unavailable presence will be returned.<p>
|
* user's presence updates), unavailable presence will be returned.<p>
|
||||||
*
|
* <p/>
|
||||||
* If the user has several presences (one for each resource), then the presence with
|
* If the user has several presences (one for each resource), then the presence with
|
||||||
* highest priority will be returned. If multiple presences have the same priority,
|
* highest priority will be returned. If multiple presences have the same priority,
|
||||||
* the one with the "most available" presence mode will be returned. In order,
|
* the one with the "most available" presence mode will be returned. In order,
|
||||||
* that's {@link Presence.Mode#chat free to chat}, {@link Presence.Mode#available available},
|
* that's {@link Presence.Mode#chat free to chat}, {@link Presence.Mode#available available},
|
||||||
* {@link Presence.Mode#away away}, {@link Presence.Mode#xa extended away}, and
|
* {@link Presence.Mode#away away}, {@link Presence.Mode#xa extended away}, and
|
||||||
* {@link Presence.Mode#dnd do not disturb}.<p>
|
* {@link Presence.Mode#dnd do not disturb}.<p>
|
||||||
*
|
* <p/>
|
||||||
* Note that presence information is received asynchronously. So, just after logging
|
* Note that presence information is received asynchronously. So, just after logging
|
||||||
* in to the server, presence values for users in the roster may be unavailable
|
* in to the server, presence values for users in the roster may be unavailable
|
||||||
* even if they are actually online. In other words, the value returned by this
|
* even if they are actually online. In other words, the value returned by this
|
||||||
|
@ -427,16 +427,18 @@ public class Roster {
|
||||||
* {@link RosterListener}.
|
* {@link RosterListener}.
|
||||||
*
|
*
|
||||||
* @param user an XMPP ID. The address could be in any valid format (e.g.
|
* @param user an XMPP ID. The address could be in any valid format (e.g.
|
||||||
* "domain/resource", "user@domain" or "user@domain/resource"). Any resource
|
* "domain/resource", "user@domain" or "user@domain/resource"). Any resource
|
||||||
* information that's part of the ID will be discarded.
|
* information that's part of the ID will be discarded.
|
||||||
* @return the user's current presence, or unavailable presence if the user is offline
|
* @return the user's current presence, or unavailable presence if the user is offline
|
||||||
* or if no presence information is available..
|
* or if no presence information is available..
|
||||||
*/
|
*/
|
||||||
public Presence getPresence(String user) {
|
public Presence getPresence(String user) {
|
||||||
String key = getPresenceMapKey(StringUtils.parseBareAddress(user));
|
String key = getPresenceMapKey(StringUtils.parseBareAddress(user));
|
||||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||||
if (userPresences == null) {
|
if (userPresences == null) {
|
||||||
return new Presence(Presence.Type.unavailable);
|
Presence presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(user);
|
||||||
|
return presence;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Find the resource with the highest priority
|
// Find the resource with the highest priority
|
||||||
|
@ -467,7 +469,9 @@ public class Roster {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (presence == null) {
|
if (presence == null) {
|
||||||
return new Presence(Presence.Type.unavailable);
|
presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(user);
|
||||||
|
return presence;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return presence;
|
return presence;
|
||||||
|
@ -482,19 +486,23 @@ public class Roster {
|
||||||
*
|
*
|
||||||
* @param userWithResource a fully qualified XMPP ID including a resource (user@domain/resource).
|
* @param userWithResource a fully qualified XMPP ID including a resource (user@domain/resource).
|
||||||
* @return the user's current presence, or unavailable presence if the user is offline
|
* @return the user's current presence, or unavailable presence if the user is offline
|
||||||
* or if no presence information is available.
|
* or if no presence information is available.
|
||||||
*/
|
*/
|
||||||
public Presence getPresenceResource(String userWithResource) {
|
public Presence getPresenceResource(String userWithResource) {
|
||||||
String key = getPresenceMapKey(userWithResource);
|
String key = getPresenceMapKey(userWithResource);
|
||||||
String resource = StringUtils.parseResource(userWithResource);
|
String resource = StringUtils.parseResource(userWithResource);
|
||||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||||
if (userPresences == null) {
|
if (userPresences == null) {
|
||||||
return new Presence(Presence.Type.unavailable);
|
Presence presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(userWithResource);
|
||||||
|
return presence;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Presence presence = userPresences.get(resource);
|
Presence presence = userPresences.get(resource);
|
||||||
if (presence == null) {
|
if (presence == null) {
|
||||||
return new Presence(Presence.Type.unavailable);
|
presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(userWithResource);
|
||||||
|
return presence;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return presence;
|
return presence;
|
||||||
|
@ -510,14 +518,16 @@ public class Roster {
|
||||||
*
|
*
|
||||||
* @param user a XMPP ID, e.g. jdoe@example.com.
|
* @param user a XMPP ID, e.g. jdoe@example.com.
|
||||||
* @return an iterator (of Presence objects) for all the user's current presences,
|
* @return an iterator (of Presence objects) for all the user's current presences,
|
||||||
* or an unavailable presence if the user is offline or if no presence information
|
* or an unavailable presence if the user is offline or if no presence information
|
||||||
* is available.
|
* is available.
|
||||||
*/
|
*/
|
||||||
public Iterator<Presence> getPresences(String user) {
|
public Iterator<Presence> getPresences(String user) {
|
||||||
String key = getPresenceMapKey(user);
|
String key = getPresenceMapKey(user);
|
||||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||||
if (userPresences == null) {
|
if (userPresences == null) {
|
||||||
return Arrays.asList(new Presence(Presence.Type.unavailable)).iterator();
|
Presence presence = new Presence(Presence.Type.unavailable);
|
||||||
|
presence.setFrom(user);
|
||||||
|
return Arrays.asList(presence).iterator();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return userPresences.values().iterator();
|
return userPresences.values().iterator();
|
||||||
|
@ -541,7 +551,7 @@ public class Roster {
|
||||||
* since it will always contain one entry for the user.
|
* since it will always contain one entry for the user.
|
||||||
*
|
*
|
||||||
* @param user the bare or fully qualified XMPP ID, e.g. jdoe@example.com or
|
* @param user the bare or fully qualified XMPP ID, e.g. jdoe@example.com or
|
||||||
* jdoe@example.com/Work.
|
* jdoe@example.com/Work.
|
||||||
* @return the key to use in the presenceMap for the fully qualified XMPP ID.
|
* @return the key to use in the presenceMap for the fully qualified XMPP ID.
|
||||||
*/
|
*/
|
||||||
private String getPresenceMapKey(String user) {
|
private String getPresenceMapKey(String user) {
|
||||||
|
@ -579,13 +589,12 @@ public class Roster {
|
||||||
* specified collections of contacts have been added, updated or deleted
|
* specified collections of contacts have been added, updated or deleted
|
||||||
* from the roster.
|
* from the roster.
|
||||||
*
|
*
|
||||||
* @param addedEntries the collection of address of the added contacts.
|
* @param addedEntries the collection of address of the added contacts.
|
||||||
* @param updatedEntries the collection of address of the updated contacts.
|
* @param updatedEntries the collection of address of the updated contacts.
|
||||||
* @param deletedEntries the collection of address of the deleted contacts.
|
* @param deletedEntries the collection of address of the deleted contacts.
|
||||||
*/
|
*/
|
||||||
private void fireRosterChangedEvent(Collection<String> addedEntries, Collection<String> updatedEntries,
|
private void fireRosterChangedEvent(Collection<String> addedEntries, Collection<String> updatedEntries,
|
||||||
Collection<String> deletedEntries)
|
Collection<String> deletedEntries) {
|
||||||
{
|
|
||||||
for (RosterListener listener : rosterListeners) {
|
for (RosterListener listener : rosterListeners) {
|
||||||
if (!addedEntries.isEmpty()) {
|
if (!addedEntries.isEmpty()) {
|
||||||
listener.entriesAdded(addedEntries);
|
listener.entriesAdded(addedEntries);
|
||||||
|
@ -619,7 +628,7 @@ public class Roster {
|
||||||
* Automatically accept all subscription and unsubscription requests. This is
|
* Automatically accept all subscription and unsubscription requests. This is
|
||||||
* the default mode and is suitable for simple client. More complex client will
|
* the default mode and is suitable for simple client. More complex client will
|
||||||
* likely wish to handle subscription requests manually.
|
* likely wish to handle subscription requests manually.
|
||||||
*/
|
*/
|
||||||
accept_all,
|
accept_all,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -640,8 +649,9 @@ public class Roster {
|
||||||
* Listens for all presence packets and processes them.
|
* Listens for all presence packets and processes them.
|
||||||
*/
|
*/
|
||||||
private class PresencePacketListener implements PacketListener {
|
private class PresencePacketListener implements PacketListener {
|
||||||
|
|
||||||
public void processPacket(Packet packet) {
|
public void processPacket(Packet packet) {
|
||||||
Presence presence = (Presence)packet;
|
Presence presence = (Presence) packet;
|
||||||
String from = presence.getFrom();
|
String from = presence.getFrom();
|
||||||
String key = getPresenceMapKey(from);
|
String key = getPresenceMapKey(from);
|
||||||
|
|
||||||
|
|
|
@ -39,62 +39,69 @@ import java.util.List;
|
||||||
* vCard provider.
|
* vCard provider.
|
||||||
*
|
*
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
|
* @author Derek DeMoro
|
||||||
*/
|
*/
|
||||||
public class VCardProvider implements IQProvider {
|
public class VCardProvider implements IQProvider {
|
||||||
|
|
||||||
private final static String PREFERRED_ENCODING = "UTF-8";
|
private static final String PREFERRED_ENCODING = "UTF-8";
|
||||||
|
|
||||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
int event = parser.getEventType();
|
int event = parser.getEventType();
|
||||||
// get the content
|
// get the content
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case XmlPullParser.TEXT:
|
case XmlPullParser.TEXT:
|
||||||
// We must re-escape the xml so that the DOM won't throw an exception
|
// We must re-escape the xml so that the DOM won't throw an exception
|
||||||
sb.append(StringUtils.escapeForXML(parser.getText()));
|
sb.append(StringUtils.escapeForXML(parser.getText()));
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.START_TAG:
|
case XmlPullParser.START_TAG:
|
||||||
sb.append('<').append(parser.getName()).append('>');
|
sb.append('<').append(parser.getName()).append('>');
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.END_TAG:
|
case XmlPullParser.END_TAG:
|
||||||
sb.append("</").append(parser.getName()).append('>');
|
sb.append("</").append(parser.getName()).append('>');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == XmlPullParser.END_TAG && "vCard".equals(parser.getName())) break;
|
if (event == XmlPullParser.END_TAG && "vCard".equals(parser.getName())) break;
|
||||||
|
|
||||||
event = parser.next();
|
event = parser.next();
|
||||||
}
|
}
|
||||||
} catch (XmlPullParserException e) {
|
}
|
||||||
e.printStackTrace();
|
catch (XmlPullParserException e) {
|
||||||
} catch (IOException e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
String xmlText = sb.toString();
|
String xmlText = sb.toString();
|
||||||
return _createVCardFromXml(xmlText);
|
return createVCardFromXML(xmlText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VCard _createVCardFromXml(String xmlText) {
|
/**
|
||||||
VCard vCard = new VCard();
|
* Builds a users vCard from xml file.
|
||||||
try {
|
*
|
||||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
* @param xml the xml representing a users vCard.
|
||||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
* @return the VCard.
|
||||||
Document document = documentBuilder.parse(
|
* @throws
|
||||||
new ByteArrayInputStream(xmlText.getBytes(PREFERRED_ENCODING)));
|
*/
|
||||||
|
public static VCard createVCardFromXML(String xml) throws Exception {
|
||||||
|
VCard vCard = new VCard();
|
||||||
|
|
||||||
new VCardReader(vCard, document).initializeFields();
|
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||||
|
Document document = documentBuilder.parse(
|
||||||
|
new ByteArrayInputStream(xml.getBytes(PREFERRED_ENCODING)));
|
||||||
|
|
||||||
} catch (Exception e) {
|
new VCardReader(vCard, document).initializeFields();
|
||||||
e.printStackTrace(System.err);
|
return vCard;
|
||||||
}
|
}
|
||||||
return vCard;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class VCardReader {
|
private static class VCardReader {
|
||||||
|
|
||||||
private final VCard vCard;
|
private final VCard vCard;
|
||||||
private final Document document;
|
private final Document document;
|
||||||
|
|
||||||
|
@ -158,8 +165,8 @@ public class VCardProvider implements IQProvider {
|
||||||
}
|
}
|
||||||
if (code == null || value == null) continue;
|
if (code == null || value == null) continue;
|
||||||
if ("HOME".equals(type)) {
|
if ("HOME".equals(type)) {
|
||||||
vCard.setPhoneHome(code, value);
|
vCard.setPhoneHome(code, value);
|
||||||
}
|
}
|
||||||
else { // By default, setup work phone
|
else { // By default, setup work phone
|
||||||
vCard.setPhoneWork(code, value);
|
vCard.setPhoneWork(code, value);
|
||||||
}
|
}
|
||||||
|
@ -180,18 +187,18 @@ public class VCardProvider implements IQProvider {
|
||||||
List code = new ArrayList();
|
List code = new ArrayList();
|
||||||
List value = new ArrayList();
|
List value = new ArrayList();
|
||||||
NodeList childNodes = addressNode.getChildNodes();
|
NodeList childNodes = addressNode.getChildNodes();
|
||||||
for(int j = 0; j < childNodes.getLength(); j++) {
|
for (int j = 0; j < childNodes.getLength(); j++) {
|
||||||
Node node = childNodes.item(j);
|
Node node = childNodes.item(j);
|
||||||
if (node.getNodeType() != Node.ELEMENT_NODE) continue;
|
if (node.getNodeType() != Node.ELEMENT_NODE) continue;
|
||||||
String nodeName = node.getNodeName();
|
String nodeName = node.getNodeName();
|
||||||
if (isWorkHome(nodeName)) {
|
if (isWorkHome(nodeName)) {
|
||||||
type = nodeName;
|
type = nodeName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
code.add(nodeName);
|
code.add(nodeName);
|
||||||
value.add(getTextContent(node));
|
value.add(getTextContent(node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int j = 0; j < value.size(); j++) {
|
for (int j = 0; j < value.size(); j++) {
|
||||||
if ("HOME".equals(type)) {
|
if ("HOME".equals(type)) {
|
||||||
vCard.setAddressFieldHome((String) code.get(j), (String) value.get(j));
|
vCard.setAddressFieldHome((String) code.get(j), (String) value.get(j));
|
||||||
|
@ -221,7 +228,8 @@ public class VCardProvider implements IQProvider {
|
||||||
String field = element.getNodeName();
|
String field = element.getNodeName();
|
||||||
if (element.getChildNodes().getLength() == 0) {
|
if (element.getChildNodes().getLength() == 0) {
|
||||||
vCard.setField(field, "");
|
vCard.setField(field, "");
|
||||||
} else if (element.getChildNodes().getLength() == 1 &&
|
}
|
||||||
|
else if (element.getChildNodes().getLength() == 1 &&
|
||||||
element.getChildNodes().item(0) instanceof Text) {
|
element.getChildNodes().item(0) instanceof Text) {
|
||||||
vCard.setField(field, getTextContent(element));
|
vCard.setField(field, getTextContent(element));
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,23 +62,23 @@ public class VCardTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoWorkHomeSpecifier_EMAIL() throws Throwable {
|
public void testNoWorkHomeSpecifier_EMAIL() throws Throwable {
|
||||||
VCard card = VCardProvider._createVCardFromXml("<vcard><EMAIL><USERID>foo@fee.www.bar</USERID></EMAIL></vcard>");
|
VCard card = VCardProvider.createVCardFromXML("<vcard><EMAIL><USERID>foo@fee.www.bar</USERID></EMAIL></vcard>");
|
||||||
assertEquals("foo@fee.www.bar", card.getEmailHome());
|
assertEquals("foo@fee.www.bar", card.getEmailHome());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoWorkHomeSpecifier_TEL() throws Throwable {
|
public void testNoWorkHomeSpecifier_TEL() throws Throwable {
|
||||||
VCard card = VCardProvider._createVCardFromXml("<vcard><TEL><FAX/><NUMBER>3443233</NUMBER></TEL></vcard>");
|
VCard card = VCardProvider.createVCardFromXML("<vcard><TEL><FAX/><NUMBER>3443233</NUMBER></TEL></vcard>");
|
||||||
assertEquals("3443233", card.getPhoneWork("FAX"));
|
assertEquals("3443233", card.getPhoneWork("FAX"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoWorkHomeSpecifier_ADDR() throws Throwable {
|
public void testNoWorkHomeSpecifier_ADDR() throws Throwable {
|
||||||
VCard card = VCardProvider._createVCardFromXml("<vcard><ADR><STREET>Some street</STREET><FF>ddss</FF></ADR></vcard>");
|
VCard card = VCardProvider.createVCardFromXML("<vcard><ADR><STREET>Some street</STREET><FF>ddss</FF></ADR></vcard>");
|
||||||
assertEquals("Some street", card.getAddressFieldWork("STREET"));
|
assertEquals("Some street", card.getAddressFieldWork("STREET"));
|
||||||
assertEquals("ddss", card.getAddressFieldWork("FF"));
|
assertEquals("ddss", card.getAddressFieldWork("FF"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFN() throws Throwable {
|
public void testFN() throws Throwable {
|
||||||
VCard card = VCardProvider._createVCardFromXml("<vcard><FN>kir max</FN></vcard>");
|
VCard card = VCardProvider.createVCardFromXML("<vcard><FN>kir max</FN></vcard>");
|
||||||
assertEquals("kir max", card.getField("FN"));
|
assertEquals("kir max", card.getField("FN"));
|
||||||
// assertEquals("kir max", card.getFullName());
|
// assertEquals("kir max", card.getFullName());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue