diff --git a/lib/native/mac/libjmacosxaddrbook.jnilib b/lib/native/mac/libjmacosxaddrbook.jnilib
index 2a8bc4162..64a5ce4e9 100755
Binary files a/lib/native/mac/libjmacosxaddrbook.jnilib and b/lib/native/mac/libjmacosxaddrbook.jnilib differ
diff --git a/src/native/addrbook/macosx/net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.m b/src/native/addrbook/macosx/net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.m
index 2572adf72..be3ddd397 100644
--- a/src/native/addrbook/macosx/net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.m
+++ b/src/native/addrbook/macosx/net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.m
@@ -173,15 +173,24 @@ MacOSXAddrBookContactQuery_idToJObject
}
else if ([o isKindOfClass:[ABMultiValue class]])
{
+ /*
+ * We changed our minds after the initial implementation and decided
+ * that we want to display not only the values but the labels as
+ * well. In order to minimize the scope of the modifications, we'll
+ * be returning each label in the same array right after its
+ * corresponding value.
+ */
ABMultiValue *mv = (ABMultiValue *) o;
NSUInteger mvCount = [mv count];
jobjectArray joArray
- = (*jniEnv)->NewObjectArray(jniEnv, mvCount, objectClass, NULL);
+ = (*jniEnv)->NewObjectArray(
+ jniEnv,
+ mvCount * 2 /* value, label */, objectClass, NULL);
jo = joArray;
if (joArray)
{
- NSUInteger j;
+ NSUInteger j, j1;
for (j = 0; j < mvCount; j++)
{
@@ -195,6 +204,19 @@ MacOSXAddrBookContactQuery_idToJObject
jo = NULL;
break;
}
+ /* Because the compiler says ++j may be undefined for j. */
+ j1 = j + 1;
+ MacOSXAddrBookContactQuery_idToJObject(
+ jniEnv,
+ [mv labelAtIndex:j],
+ joArray, j1,
+ objectClass);
+ if (JNI_TRUE == (*jniEnv)->ExceptionCheck(jniEnv))
+ {
+ jo = NULL;
+ break;
+ }
+ j = j1;
}
}
}
diff --git a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java
index 2b9467b68..22e33a9de 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java
@@ -173,6 +173,15 @@ public class MacOSXAddrBookContactQuery
kABYahooInstantProperty
};
+ /**
+ * The regex which matches the superfluous parts of an ABMultiValue
+ * label.
+ */
+ private static final Pattern LABEL_PATTERN
+ = Pattern.compile(
+ "kAB|Email|Phone|Label|(\\p{Punct}*)",
+ Pattern.CASE_INSENSITIVE);
+
static
{
System.loadLibrary("jmacosxaddrbook");
@@ -201,6 +210,52 @@ private static native Object[] ABRecord_valuesForProperties(
long record,
long[] properties);
+ /**
+ * Initializes a new ContactDetail instance which is to reperesent
+ * a specific contact address that is the value of a specific
+ * ABPerson property and, optionally, has a specific label.
+ *
+ * @param property the index in {@link #ABPERSON_PROPERTIES} of the
+ * ABPerson property to be represented by ContactDetail
+ * @param contactAddress the contact address to be represented by the new
+ * ContactDetail instance
+ * @param label an optional label to be added to the set of labels, if any,
+ * determined by property
+ * @return a new ContactDetail instance which represents the
+ * specified contactAddress
+ */
+ private ContactDetail createContactDetail(
+ int property,
+ String contactAddress,
+ Object label)
+ {
+ String p, l;
+
+ switch (property)
+ {
+ case kABEmailProperty:
+ p = ContactDetail.LABEL_EMAIL;
+ break;
+ case kABPhoneProperty:
+ p = ContactDetail.LABEL_PHONE;
+ break;
+ default:
+ p = null;
+ break;
+ }
+
+ if (label == null)
+ l = null;
+ else
+ {
+ l = LABEL_PATTERN.matcher((String) label).replaceAll("").trim();
+ if (l.length() < 1)
+ l = null;
+ }
+
+ return new ContactDetail(contactAddress, new String[] { p, l });
+ }
+
/**
* Calls back to a specific PtrCallback for each ABPerson
* found in the Address Book of Mac OS X which matches a specific
@@ -245,14 +300,23 @@ private List getContactDetails(Object[] values)
contactDetails.add(
setCapabilities(
- new ContactDetail(stringValue),
+ createContactDetail(
+ property,
+ stringValue,
+ null),
property));
}
}
else if (value instanceof Object[])
{
- for (Object subValue : (Object[]) value)
+ Object[] multiValue = (Object[]) value;
+
+ for (int multiValueIndex = 0;
+ multiValueIndex < multiValue.length;
+ multiValueIndex += 2)
{
+ Object subValue = multiValue[multiValueIndex];
+
if (subValue instanceof String)
{
String stringSubValue = (String) subValue;
@@ -267,7 +331,10 @@ else if (value instanceof Object[])
contactDetails.add(
setCapabilities(
- new ContactDetail(stringSubValue),
+ createContactDetail(
+ property,
+ stringSubValue,
+ multiValue[multiValueIndex + 1]),
property));
}
}
@@ -366,8 +433,14 @@ private String getDisplayName(Object[] values)
}
else if (value instanceof Object[])
{
- for (Object subValue : (Object[]) value)
+ Object[] multiValue = (Object[]) value;
+
+ for (int multiValueIndex = 0;
+ multiValueIndex < multiValue.length;
+ multiValueIndex += 2)
{
+ Object subValue = multiValue[multiValueIndex];
+
if (subValue instanceof String)
{
String stringSubValue = (String) subValue;
@@ -538,8 +611,13 @@ private boolean matches(Object[] values)
}
else if (value instanceof Object[])
{
- for (Object subValue : (Object[]) value)
+ Object[] multiValue = (Object[]) value;
+
+ for (int multiValueIndex = 0;
+ multiValueIndex < multiValue.length;
+ multiValueIndex += 2)
{
+ Object subValue = multiValue[multiValueIndex];
if ((subValue instanceof String)
&& matches(property, (String) subValue))
return true;
diff --git a/src/net/java/sip/communicator/service/contactsource/ContactDetail.java b/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
index 1dcaa3865..92b47a72f 100644
--- a/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
+++ b/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
@@ -117,7 +117,11 @@ public ContactDetail(String contactAddress)
* @param labels the set of labels with which the new ContactDetail
* instance is to be labeled. The labels may be arbitrary and may include
* any of the standard/well-known labels defined by the LABEL_XXX
- * constants of the ContactDetail class.
+ * constants of the ContactDetail class. For the sake of
+ * convenience, null and duplicate values in the specified
+ * String[] labels will be ignored i.e. will not appear in
+ * the set of labels reported by the new ContactDetail instance
+ * later on.
*/
public ContactDetail(String contactAddress, String[] labels)
{
@@ -126,14 +130,10 @@ public ContactDetail(String contactAddress, String[] labels)
// labels
if (labels != null)
{
- System.err.println(this.contactAddress);
for (String label : labels)
{
- if (!this.labels.contains(label))
- {
+ if ((label != null) && !this.labels.contains(label))
this.labels.add(label);
- System.err.println("\t" + label);
- }
}
}
}