From 2ec8f1b300b23af5f48255b88f421a257d75fa61 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Wed, 16 Feb 2011 10:12:58 +0000 Subject: [PATCH] Reports contact specifiers such as Home, Work, Mobile for the SourceContact ContactDetails returned by the Mac OS X Address Book ContactSourceService. --- lib/native/mac/libjmacosxaddrbook.jnilib | Bin 65232 -> 65248 bytes ...drbook_macosx_MacOSXAddrBookContactQuery.m | 26 +++++- .../macosx/MacOSXAddrBookContactQuery.java | 88 +++++++++++++++++- .../service/contactsource/ContactDetail.java | 12 +-- 4 files changed, 113 insertions(+), 13 deletions(-) diff --git a/lib/native/mac/libjmacosxaddrbook.jnilib b/lib/native/mac/libjmacosxaddrbook.jnilib index 2a8bc416239d7e92ef08d15ff633a620e57beea1..64a5ce4e95d3440f6037b4ca1e3b1f4295a87faa 100755 GIT binary patch delta 5124 zcmZ`-4OEm>8ouAi|KAMA#3(95j0h+KC5nRUj4{U{F;OA$_&2Un*ioBRtg!`WazOd~ zK#6NfKWkL#QL|lab~oE-8^sVyON9&*g{;;wZPQ94OJ|?^eHT+a`?@7NWug{0+A0O#DnY)J^PGfG{Nawlmru!PAfFo z!8yYSDTQ5*`+(*HLCB@gMokLIO(!H8HFDGGv6V6O%cz9lVyHAw71J35V` zLC};!;}eiZFVhztJi2bej6BOP^#SevPpDKV)YL@+2|3e`Lh)7myx4oqAw&Q z1$hv7B=XxIY7KH{Xnks0H#}VbNeCfgz9CGiZdFjwoZ^

b%UnSaQBe-ygm))Q%pB zxrVS>R|TD!m>yUGUQ72#nsO?M?G2)pRf#5kczPOWm9E2pF6G+IuBSgQIdi5^QF zraGi#uO!jsNpbY(h)Jq+MKemtI!7=wp@;5G%9yq@MsD9va-Czy&)|J)1R;|9bwwW} zmKpq{q7E_I;N60PN>7QE75RD3C> z{<1H1M`_5L2zzs<6muAXVbPMzVXVGn?i4%#eqxTnSKov#h~};;kGj(4 z^Z8K7;0gz3DC7F2IqJAdR+V4?L6Yl*yIa_R7Nnvu5#6kPRKVb*X}`iMIVH?tyvI$|a=5v80Q$a; zNv_{x{~sPH?{IkSirjZFxL}ACVI7_ZX zhA_3K3`1U(A$<#1p;u0~$Y~ALRS$jWHDAZ%SBZc5%L!}h1QO)%s&;OP z_tllJjkTBmbELievj^?vH?r-fb*k+-3$Z~QgiM@7i0gG-mUFSr<`Q*dsJ(i$N|#P| zRVPIDS}}fRMh>@=K^qZyFJT;<-aD@?r8bZ zKHCtK<5UHVDGyd6_K4FjzPvnkjcJ{5H0?z~OxuKJ)(6&pb|d=TDy zi`}u~lAX21+Hq8UWp@nRdC6YB1dU8-mm8YuyY&{ei*d>G)_(ooJ?2?wiO|owgjo-b z&VHY$94~r}roZ?~Erk4b$2je@Sxiv{`cbbqIv_AQt2J;49kMY|r8Cgnji%5;Zu{CD zZ`%KbXw$llg9fhu%0AWSJDL?wY)(X7);Dj=7Q$)o#s|$-=VEOc>phE_vr;>+50^h3 zYiEr@R}33@gxsd^w#_rKh_beT+N2mEpH@pQ!9v4o&a0vcy;3t>*g=i88?@V*d3gm3 zE^#U@qOk00Ckd~(hip;{_Z+OJ+_yISYZl>&6^BzN4og379Aq+N24pq_QxmrWQU>`m zWCH|?KCT|J9kK_q57G?z1kwfh2J!>uj~}YT>fP4HZEC7&+80@ft!Tv7weoxkZEhOu zUdnq6a>p;K3erBVNs3G&l(0NF^!-IH!r~GRIcDm*;Yv4t$VfIQ2{6*aQ5$g74E4 z;y-}vuK+LQ`X=BL96JdKFmYUv1G1Zw9)wM;;1~_?8jg*?UvO;0@i&p}#WoTBhSX+Sl@A{LZwl;?nuo4d>J6T2}0SX8}KBNp(6QX|OG& zrbCmoNn@0o)&3wMxScTfI9q9k_ON^2hkoJIdD1^>>vuk%X_jyJ=5Smfal|)#6Wx09 z<)Dvn=~!yDZFE9=vVNOPGMUbsikF@_FyH0jPxbb_{WtW}6;06`2ZWSzMQs^2Fcr#A_C@$Rkc`o+ci)R9(l@5&^eJ zL%)|BnP_1>tIa$C=F@)6bmBqISr6Os6QDRx@-tYZhAb>=6t%)g?)>|*b!)zO!Pm}e zRh?8pzwFl+-QiF|Eb{$HZYno@8Z(3klc*NxU3f)-BoJbQtVp(nG zRAfG_S$532!8q@Ry7C<63%Z~2^Ga_2zW^4|+@^GIb(=-Fp5Zu>FWz81seAI4!62R`~n{Dh<3;*RmH6>z9Mg>N|4BTH!-H&AlwS*UM@bme<`OX{kd* z=CIn*#DgrW&CEvT(`L#ZSwtA`o0x<0$ZInr@W^7_D@f0y#?J$U-E_+5hTJlj5}1Y_ zC2sM&rdB6AJ0J(@I_hP3it;^k|~OyBX)k@-rh<-s|+GGh@;H6KAFi1vI{EoX|<!j}|PZ_^njEEAufHB4Lhl^e2?B@~t$|3BE>fz?1ZzkBrtsfEM$Y$eZsmLsrjj`*;M~c%jdL&OPR?gxuyO}D zKfrk%=Ob{KsRg{tj&sFkS%E*!IQMbh#QEd6iI~G4&W~|^h4XRPJFJ}W2sLo7;rv(5 y^_-Vr!wPQg4|9e1U8sh;J7Pa_OjtxCay-}~JjjP2Z=%orxIw6MNB;Cd$o~MBcY!zn delta 4870 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 Mzt;LQuC_${A0Sy0!~g&Q 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); - } } } }