diff --git a/source/org/jivesoftware/smackx/packet/VCard.java b/source/org/jivesoftware/smackx/packet/VCard.java
index 4f1248859..5898130d8 100644
--- a/source/org/jivesoftware/smackx/packet/VCard.java
+++ b/source/org/jivesoftware/smackx/packet/VCard.java
@@ -124,13 +124,35 @@ public class VCard extends IQ {
/**
* Set generic VCard field.
*
- * @param field value of field. Possible values: NICKNAME, PHOTO, BDAY, JABBERID, MAILER, TZ,
+ * @param field value of field. Possible values: FN, NICKNAME, PHOTO, BDAY, JABBERID, MAILER, TZ,
* GEO, TITLE, ROLE, LOGO, NOTE, PRODID, REV, SORT-STRING, SOUND, UID, URL, DESC.
*/
public String getField(String field) {
+ if ("FN".equals(field)) {
+ return buildFullName();
+ }
return (String) otherSimpleFields.get(field);
}
+ private String buildFullName() {
+ if (otherSimpleFields.containsKey("FN")) {
+ return otherSimpleFields.get("FN").toString().trim();
+ }
+ else {
+ StringBuffer sb = new StringBuffer();
+ if (firstName != null) {
+ sb.append(firstName).append(' ');
+ }
+ if (middleName != null) {
+ sb.append(middleName).append(' ');
+ }
+ if (lastName != null) {
+ sb.append(lastName);
+ }
+ return sb.toString().trim();
+ }
+ }
+
/**
* Set generic VCard field.
*
@@ -162,6 +184,13 @@ public class VCard extends IQ {
return middleName;
}
+ /**
+ * Returns the full name of the user, associated with this VCard.
+ */
+ public String getFullName() {
+ return getField("FN");
+ }
+
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
@@ -540,7 +569,7 @@ public class VCard extends IQ {
}
private boolean hasNameField() {
- return firstName != null || lastName != null || middleName != null;
+ return firstName != null || lastName != null || middleName != null || otherSimpleFields.containsKey("FN");
}
private boolean hasOrganizationFields() {
@@ -638,7 +667,7 @@ public class VCard extends IQ {
private void buildActualContent() {
if (hasNameField()) {
- appendFN();
+ appendTag("FN", getFullName());
appendN();
}
@@ -706,7 +735,9 @@ public class VCard extends IQ {
Iterator it = otherSimpleFields.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
- appendTag(entry.getKey().toString(), (String) entry.getValue());
+ String tag = entry.getKey().toString();
+ if ("FN".equals(tag)) continue;
+ appendTag(tag, (String) entry.getValue());
}
}
@@ -721,28 +752,6 @@ public class VCard extends IQ {
}
}
- 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() {
diff --git a/source/org/jivesoftware/smackx/provider/VCardProvider.java b/source/org/jivesoftware/smackx/provider/VCardProvider.java
index 3caf730db..1596edfd6 100644
--- a/source/org/jivesoftware/smackx/provider/VCardProvider.java
+++ b/source/org/jivesoftware/smackx/provider/VCardProvider.java
@@ -31,6 +31,8 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
/**
* Created by IntelliJ IDEA.
@@ -52,10 +54,10 @@ public class VCardProvider implements IQProvider {
sb.append(parser.getText());
break;
case XmlPullParser.START_TAG:
- sb.append('<' + parser.getName() + '>');
+ sb.append('<').append(parser.getName()).append('>');
break;
case XmlPullParser.END_TAG:
- sb.append("" + parser.getName() + '>');
+ sb.append("").append(parser.getName()).append('>');
break;
default:
}
@@ -71,6 +73,10 @@ public class VCardProvider implements IQProvider {
}
String xmlText = sb.toString();
+ return _createVCardFromXml(xmlText);
+ }
+
+ public static VCard _createVCardFromXml(String xmlText) {
VCard vCard = new VCard();
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
@@ -85,7 +91,7 @@ public class VCardProvider implements IQProvider {
return vCard;
}
- private class VCardReader {
+ private static class VCardReader {
private final VCard vCard;
private final Document document;
@@ -106,58 +112,88 @@ public class VCardProvider implements IQProvider {
vCard.setOrganizationUnit(getTagContents("ORGUNIT"));
setupSimpleFields();
- setupPhones("WORK", true);
- setupPhones("HOME", false);
- setupAddress("WORK", true);
- setupAddress("HOME", false);
+ setupPhones();
+ setupAddresses();
}
private void setupEmails() {
NodeList nodes = document.getElementsByTagName("USERID");
+ if (nodes == null) return;
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 {
+ if ("HOME".equals(element.getParentNode().getFirstChild().getNodeName())) {
vCard.setEmailHome(getTextContent(element));
+ } else {
+ vCard.setEmailWork(getTextContent(element));
}
}
}
- private void setupPhones(String type, boolean work) {
+ private void setupPhones() {
NodeList allPhones = document.getElementsByTagName("TEL");
+ if (allPhones == null) return;
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);
+ NodeList nodes = allPhones.item(i).getChildNodes();
+ String type = null;
+ String code = null;
+ String value = null;
+ for (int j = 0; j < nodes.getLength(); j++) {
+ Node node = nodes.item(j);
+ if (node.getNodeType() != Node.ELEMENT_NODE) continue;
+ String nodeName = node.getNodeName();
+ if ("NUMBER".equals(nodeName)) {
+ value = getTextContent(node);
+ }
+ else if (isWorkHome(nodeName)) {
+ type = nodeName;
}
else {
+ code = nodeName;
+ }
+ }
+ if (code == null || value == null) continue;
+ if ("HOME".equals(type)) {
vCard.setPhoneHome(code, value);
}
+ else { // By default, setup work phone
+ vCard.setPhoneWork(code, value);
}
}
}
- private void setupAddress(String type, boolean work) {
+ private boolean isWorkHome(String nodeName) {
+ return "HOME".equals(nodeName) || "WORK".equals(nodeName);
+ }
+
+ private void setupAddresses() {
NodeList allAddresses = document.getElementsByTagName("ADR");
+ if (allAddresses == null) return;
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));
+ Element addressNode = (Element) allAddresses.item(i);
+
+ String type = null;
+ List code = new ArrayList();
+ List value = new ArrayList();
+ NodeList childNodes = addressNode.getChildNodes();
+ for(int j = 0; j < childNodes.getLength(); j++) {
+ Node node = childNodes.item(j);
+ if (node.getNodeType() != Node.ELEMENT_NODE) continue;
+ String nodeName = node.getNodeName();
+ if (isWorkHome(nodeName)) {
+ type = nodeName;
}
else {
- vCard.setAddressFieldHome(item.getNodeName(), getTextContent(item));
+ code.add(nodeName);
+ value.add(getTextContent(node));
}
}
+ for (int j = 0; j < value.size(); j++) {
+ if ("HOME".equals(type)) {
+ vCard.setAddressFieldHome((String) code.get(j), (String) value.get(j));
+ }
+ else { // By default, setup work address
+ vCard.setAddressFieldWork((String) code.get(j), (String) value.get(j));
}
}
}
@@ -165,7 +201,7 @@ public class VCardProvider implements IQProvider {
private String getTagContents(String tag) {
NodeList nodes = document.getElementsByTagName(tag);
- if (nodes.getLength() == 1) {
+ if (nodes != null && nodes.getLength() == 1) {
return getTextContent(nodes.item(0));
}
return null;
@@ -177,13 +213,13 @@ public class VCardProvider implements IQProvider {
Node node = childNodes.item(i);
if (node instanceof Element) {
Element element = (Element) node;
- if ("FN".equals(element.getNodeName())) continue;
+ String field = element.getNodeName();
if (element.getChildNodes().getLength() == 0) {
- vCard.setField(element.getNodeName(), "");
+ vCard.setField(field, "");
} else if (element.getChildNodes().getLength() == 1 &&
element.getChildNodes().item(0) instanceof Text) {
- vCard.setField(element.getNodeName(), getTextContent(element));
+ vCard.setField(field, getTextContent(element));
}
}
}
diff --git a/test/org/jivesoftware/smackx/VCardTest.java b/test/org/jivesoftware/smackx/VCardTest.java
index 30a6e3a65..7bdffbc7f 100644
--- a/test/org/jivesoftware/smackx/VCardTest.java
+++ b/test/org/jivesoftware/smackx/VCardTest.java
@@ -1,8 +1,9 @@
package org.jivesoftware.smackx;
-import org.jivesoftware.smack.test.SmackTestCase;
import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.test.SmackTestCase;
import org.jivesoftware.smackx.packet.VCard;
+import org.jivesoftware.smackx.provider.VCardProvider;
/**
* Created by IntelliJ IDEA.
@@ -23,13 +24,18 @@ public class VCardTest extends SmackTestCase {
origVCard.setFirstName("kir");
origVCard.setLastName("max");
origVCard.setEmailHome("foo@fee.bar");
+ origVCard.setEmailWork("foo@fee.www.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.setAddressFieldWork("STREET", "Some street work");
+
origVCard.setPhoneWork("FAX", "3443233");
+ origVCard.setPhoneHome("VOICE", "3443233");
origVCard.save(getConnection(0));
@@ -41,7 +47,7 @@ public class VCardTest extends SmackTestCase {
fail(e.getMessage());
}
- assertEquals("Should load own VCard successfully", origVCard, loaded);
+ assertEquals("Should load own VCard successfully", origVCard.toString(), loaded.toString());
loaded = new VCard();
try {
@@ -51,7 +57,41 @@ public class VCardTest extends SmackTestCase {
fail(e.getMessage());
}
- assertEquals("Should load another user's VCard successfully", origVCard, loaded);
+ assertEquals("Should load another user's VCard successfully", origVCard.toString(), loaded.toString());
+ }
+
+ public void testNoWorkHomeSpecifier_EMAIL() throws Throwable {
+ VCard card = VCardProvider._createVCardFromXml("foo@fee.www.bar");
+ assertEquals("foo@fee.www.bar", card.getEmailWork());
+ }
+
+ public void testNoWorkHomeSpecifier_TEL() throws Throwable {
+ VCard card = VCardProvider._createVCardFromXml("3443233");
+ assertEquals("3443233", card.getPhoneWork("FAX"));
+ }
+
+ public void testNoWorkHomeSpecifier_ADDR() throws Throwable {
+ VCard card = VCardProvider._createVCardFromXml("Some streetddss");
+ assertEquals("Some street", card.getAddressFieldWork("STREET"));
+ assertEquals("ddss", card.getAddressFieldWork("FF"));
+ }
+
+ public void testFN() throws Throwable {
+ VCard card = VCardProvider._createVCardFromXml("kir max");
+ assertEquals("kir max", card.getField("FN"));
+ assertEquals("kir max", card.getFullName());
+ }
+
+ public void testFullName() throws Throwable {
+ VCard card = new VCard();
+ card.setFirstName("kir");
+ assertEquals("kir", card.getFullName());
+
+ card.setLastName("maximov");
+ assertEquals("kir maximov", card.getFullName());
+
+ card.setField("FN", "some name");
+ assertEquals("some name", card.getFullName());
}
protected int getMaxConnections() {