From 72bc56dbb32f2e311a9250ad561c9e3feef2e066 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Fri, 7 Jan 2011 19:01:32 +0000 Subject: [PATCH] Activates an initial implementation of the support for the Address Book of Mac OS X. Neither it, nor the support for the Address Book of Microsoft Outlook implement the SourceContact image property. --- lib/native/mac/libjmacosxaddrbook.jnilib | Bin 0 -> 60592 bytes src/native/addrbook/AddrBookContactQuery.c | 56 ++++++ src/native/addrbook/AddrBookContactQuery.h | 24 +++ src/native/addrbook/macosx/Makefile | 16 ++ ...drbook_macosx_MacOSXAddrBookContactQuery.m | 132 +++++++++++++- src/native/addrbook/msoutlook/Makefile | 7 +- ...soutlook_MsOutlookAddrBookContactQuery.cpp | 37 +--- .../plugin/addrbook/AddrBookActivator.java | 7 + .../macosx/MacOSXAddrBookContactQuery.java | 162 ++++++++++++++++-- 9 files changed, 388 insertions(+), 53 deletions(-) create mode 100755 lib/native/mac/libjmacosxaddrbook.jnilib create mode 100644 src/native/addrbook/AddrBookContactQuery.c create mode 100644 src/native/addrbook/AddrBookContactQuery.h create mode 100644 src/native/addrbook/macosx/Makefile diff --git a/lib/native/mac/libjmacosxaddrbook.jnilib b/lib/native/mac/libjmacosxaddrbook.jnilib new file mode 100755 index 0000000000000000000000000000000000000000..bf7b3548961a2d398269d9c16fc3215aeb11072a GIT binary patch literal 60592 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 F{|C@y=H&nY literal 0 HcmV?d00001 diff --git a/src/native/addrbook/AddrBookContactQuery.c b/src/native/addrbook/AddrBookContactQuery.c new file mode 100644 index 000000000..45cdcd274 --- /dev/null +++ b/src/native/addrbook/AddrBookContactQuery.c @@ -0,0 +1,56 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +#include "AddrBookContactQuery.h" + +static void Exception_throwNew + (JNIEnv *jniEnv, const char *className, const char *message); + +jmethodID +AddrBookContactQuery_getPtrCallbackMethodID(JNIEnv *jniEnv, jobject callback) +{ + jclass callbackClass; + jmethodID callbackMethodID = 0; + + /* + * Make sure that the specified arguments are valid. For example, check + * whether callback exists and has the necessary signature. + */ + if (callback) + { + callbackClass = (*jniEnv)->GetObjectClass(jniEnv, callback); + if (callbackClass) + { + callbackMethodID + = (*jniEnv)->GetMethodID( + jniEnv, + callbackClass, "callback", "(J)Z"); + if (!callbackMethodID) + { + Exception_throwNew( + jniEnv, "java/lang/IllegalArgumentException", "callback"); + } + } + } + else + { + Exception_throwNew( + jniEnv, "java/lang/NullPointerException", "callback"); + } + return callbackMethodID; +} + +static void +Exception_throwNew(JNIEnv *jniEnv, const char *className, const char *message) +{ + jclass clazz; + + clazz = (*jniEnv)->FindClass(jniEnv, className); + if (clazz) + (*jniEnv)->ThrowNew(jniEnv, clazz, message); +} + diff --git a/src/native/addrbook/AddrBookContactQuery.h b/src/native/addrbook/AddrBookContactQuery.h new file mode 100644 index 000000000..fbd62bca6 --- /dev/null +++ b/src/native/addrbook/AddrBookContactQuery.h @@ -0,0 +1,24 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +#ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_ADDRBOOKCONTACTQUERY_H_ +#define _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_ADDRBOOKCONTACTQUERY_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ + +jmethodID AddrBookContactQuery_getPtrCallbackMethodID + (JNIEnv *jniEnv, jobject callback); + +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ + +#endif /* #ifndef _NET_JAVA_SIP_COMMUNICATOR_PLUGIN_ADDRBOOK_ADDRBOOKCONTACTQUERY_H_ */ diff --git a/src/native/addrbook/macosx/Makefile b/src/native/addrbook/macosx/Makefile new file mode 100644 index 000000000..6b71ff522 --- /dev/null +++ b/src/native/addrbook/macosx/Makefile @@ -0,0 +1,16 @@ +CC = cc -O2 +TARGET_BASENAME = jmacosxaddrbook + +JAVA_HOME = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.5 + +CC := $(CC) -arch i386 -arch ppc -arch x86_64 -mmacosx-version-min=10.4 +CPPFLAGS = -Wall -Wreturn-type -DJNI_IMPLEMENTATION -I$(JAVA_HOME)/Headers -I.. +LDFLAGS = -dynamiclib +LIBS = -framework AddressBook -framework Foundation +TARGET = ../../../../lib/native/mac/lib$(TARGET_BASENAME).jnilib + +$(TARGET): \ + ../AddrBookContactQuery.c \ + net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.m + $(CC) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ $(LIBS) + -strip $(TARGET) 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 358e7a897..23a2e501f 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 @@ -7,21 +7,98 @@ #include "net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.h" +#include "AddrBookContactQuery.h" + #import +#import +#import + +static void MacOSXAddrBookContactQuery_idToJObject + (JNIEnv *jniEnv, id o, jobjectArray jos, jint i, jclass objectClass); JNIEXPORT jobjectArray JNICALL Java_net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery_ABRecord_1valuesForProperties (JNIEnv *jniEnv, jclass clazz, jlong record, jlongArray properties) { - /* TODO Auto-generated method stub */ - return NULL; + jsize propertyCount; + jobjectArray values = NULL; + + propertyCount = (*jniEnv)->GetArrayLength(jniEnv, properties); + if (propertyCount) + { + jclass objectClass; + + objectClass = (*jniEnv)->FindClass(jniEnv, "java/lang/Object"); + if (objectClass) + { + values + = (*jniEnv)->NewObjectArray( + jniEnv, + propertyCount, objectClass, NULL); + if (values) + { + jint i; + ABRecord *r = (ABRecord *) record; + + for (i = 0; i < propertyCount; i++) + { + jlong property; + + (*jniEnv)->GetLongArrayRegion( + jniEnv, + properties, i, 1, &property); + MacOSXAddrBookContactQuery_idToJObject( + jniEnv, + [r valueForProperty:(NSString *)property], + values, i, + objectClass); + if (JNI_TRUE == (*jniEnv)->ExceptionCheck(jniEnv)) + break; + } + } + } + } + return values; } JNIEXPORT void JNICALL Java_net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery_foreachPerson (JNIEnv *jniEnv, jclass clazz, jstring query, jobject callback) { - /* TODO Auto-generated method stub */ + jmethodID callbackMethodID; + NSAutoreleasePool *autoreleasePool; + ABAddressBook *addressBook; + NSArray *people; + NSUInteger peopleCount; + NSUInteger i; + + callbackMethodID + = AddrBookContactQuery_getPtrCallbackMethodID(jniEnv, callback); + if (!callbackMethodID || (JNI_TRUE == (*jniEnv)->ExceptionCheck(jniEnv))) + return; + + autoreleasePool = [[NSAutoreleasePool alloc] init]; + + addressBook = [ABAddressBook addressBook]; + people = [addressBook people]; + peopleCount = [people count]; + for (i = 0; i < peopleCount; i++) + { + jboolean proceed; + ABPerson *person = [people objectAtIndex:i]; + + proceed + = (*jniEnv)->CallBooleanMethod( + jniEnv, + callback, callbackMethodID, + person); + if ((JNI_FALSE == proceed) + || (JNI_TRUE == (*jniEnv)->ExceptionCheck(jniEnv))) + break; + } + [addressBook release]; + + [autoreleasePool release]; } #define DEFINE_ABPERSON_PROPERTY_GETTER(property) \ @@ -46,3 +123,52 @@ DEFINE_ABPERSON_PROPERTY_GETTER(kABMSNInstantProperty) DEFINE_ABPERSON_PROPERTY_GETTER(kABNicknameProperty) DEFINE_ABPERSON_PROPERTY_GETTER(kABPhoneProperty) DEFINE_ABPERSON_PROPERTY_GETTER(kABYahooInstantProperty) + +static void +MacOSXAddrBookContactQuery_idToJObject + (JNIEnv *jniEnv, + id o, + jobjectArray jos, jint i, + jclass objectClass) +{ + if (o) + { + jobject jo; + + if ([o isKindOfClass:[NSString class]]) + { + jo = (*jniEnv)->NewStringUTF(jniEnv, [((NSString *) o) UTF8String]); + } + else if ([o isKindOfClass:[ABMultiValue class]]) + { + ABMultiValue *mv = (ABMultiValue *) o; + NSUInteger mvCount = [mv count]; + jobjectArray joArray + = (*jniEnv)->NewObjectArray(jniEnv, mvCount, objectClass, NULL); + + jo = joArray; + if (joArray) + { + NSUInteger j; + + for (j = 0; j < mvCount; j++) + { + MacOSXAddrBookContactQuery_idToJObject( + jniEnv, + [mv valueAtIndex:j], + joArray, j, + objectClass); + if (JNI_TRUE == (*jniEnv)->ExceptionCheck(jniEnv)) + { + jo = NULL; + break; + } + } + } + } + else + jo = NULL; + if (jo) + (*jniEnv)->SetObjectArrayElement(jniEnv, jos, i, jo); + } +} diff --git a/src/native/addrbook/msoutlook/Makefile b/src/native/addrbook/msoutlook/Makefile index 32d05f734..53e108ca1 100644 --- a/src/native/addrbook/msoutlook/Makefile +++ b/src/native/addrbook/msoutlook/Makefile @@ -1,6 +1,6 @@ CXX = c++ -O2 OUTLOOK_MAPI_HEADERS ?= /c/Users/lyubomir/Downloads/Outlook2010MAPIHeaders -TARGET_BASENAME = jmsoutlook.dll +TARGET_BASENAME = jmsoutlookaddrbook ARCH = $(shell $(CXX) -dumpmachine | sed -e s/x86_64-.*/-64/ -e s/i.86-.*//) ifeq "$(ARCH)" "-64" @@ -9,12 +9,13 @@ else JAVA_HOME ?= C:/PROGRA~2/jdk endif -CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/win32 -I$(OUTLOOK_MAPI_HEADERS) +CPPFLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/win32 -I$(OUTLOOK_MAPI_HEADERS) -I.. LDFLAGS = -shared -Wl,--kill-at LIBS = -lmapi32 -TARGET = ../../../../lib/native/windows$(ARCH)/jmsoutlookaddrbook.dll +TARGET = ../../../../lib/native/windows$(ARCH)/$(TARGET_BASENAME).dll $(TARGET): \ + ../AddrBookContactQuery.c MsOutlookMAPIHResultException.cpp \ net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.cpp \ net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactSourceService.c diff --git a/src/native/addrbook/msoutlook/net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.cpp b/src/native/addrbook/msoutlook/net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.cpp index 033d29712..f238e1966 100644 --- a/src/native/addrbook/msoutlook/net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.cpp +++ b/src/native/addrbook/msoutlook/net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.cpp @@ -7,6 +7,7 @@ #include "net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery.h" +#include "AddrBookContactQuery.h" #include "MsOutlookMAPI.h" #include "MsOutlookMAPIHResultException.h" @@ -15,9 +16,6 @@ #define WIND32_MEAN_AND_LEAK #include -static void Exception_throwNew - (JNIEnv *jniEnv, const char *className, const char *message); - static jboolean MsOutlookAddrBookContactQuery_foreachMailUser (ULONG objType, LPUNKNOWN iUnknown, JNIEnv *jniEnv, @@ -32,46 +30,19 @@ static void MsOutlookAddrBookContactQuery_freeSRowSet(LPSRowSet rows); static jboolean MsOutlookAddrBookContactQuery_mailUserMatches (LPMAPIPROP mailUser, JNIEnv *jniEnv, jstring query); -static void -Exception_throwNew(JNIEnv *jniEnv, const char *className, const char *message) -{ - jclass clazz; - - clazz = jniEnv->FindClass(className); - if (clazz) - jniEnv->ThrowNew(clazz, message); -} - JNIEXPORT void JNICALL Java_net_java_sip_communicator_plugin_addrbook_msoutlook_MsOutlookAddrBookContactQuery_foreachMailUser (JNIEnv *jniEnv, jclass clazz, jstring query, jobject callback) { - jclass callbackClass; jmethodID callbackMethodID; HRESULT hResult; LPMAPISESSION mapiSession; - /* - * Make sure that the specified arguments are valid. For example, check - * whether callback exists and has the necessary signature. - */ - if (!callback) - { - Exception_throwNew( - jniEnv, "java/lang/NullPointerException", "callback"); - return; - } - callbackClass = jniEnv->GetObjectClass(callback); - if (!callbackClass) + callbackMethodID + = AddrBookContactQuery_getPtrCallbackMethodID(jniEnv, callback); + if (!callbackMethodID || (JNI_TRUE == jniEnv->ExceptionCheck())) return; - callbackMethodID = jniEnv->GetMethodID(callbackClass, "callback", "(J)Z"); - if (!callbackMethodID) - { - Exception_throwNew( - jniEnv, "java/lang/IllegalArgumentException", "callback"); - return; - } hResult = MAPILogonEx( diff --git a/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java b/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java index 854972d16..ceeeb1cdf 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java +++ b/src/net/java/sip/communicator/plugin/addrbook/AddrBookActivator.java @@ -20,6 +20,13 @@ public class AddrBookActivator implements BundleActivator { + /** + * The Logger used by the AddrBookActivator class and its + * instances for logging output. + */ + private static final Logger logger + = Logger.getLogger(AddrBookActivator.class); + /** * The ContactSourceService implementation for the OS-specific * Address Book. 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 037d9a6bd..525ebd965 100644 --- a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java +++ b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactQuery.java @@ -127,6 +127,24 @@ public class MacOSXAddrBookContactQuery */ private static final int kABYahooInstantProperty = 13; + /** + * The indexes in {@link #ABPERSON_PROPERTIES} of the properties which are + * to be represented in SourceContact as ContactDetails. + */ + private static final int[] CONTACT_DETAIL_PROPERTY_INDEXES + = new int[] + { + kABEmailProperty, + + kABPhoneProperty, + + kABAIMInstantProperty, + kABICQInstantProperty, + kABJabberInstantProperty, + kABMSNInstantProperty, + kABYahooInstantProperty + }; + static { System.loadLibrary("jmacosxaddrbook"); @@ -179,8 +197,37 @@ private static native void foreachPerson( */ private List getContactDetails(Object[] values) { - // TODO Auto-generated method stub - return null; + List contactDetails = new LinkedList(); + + for (int i = 0; i < CONTACT_DETAIL_PROPERTY_INDEXES.length; i++) + { + Object value = values[CONTACT_DETAIL_PROPERTY_INDEXES[i]]; + + if (value instanceof String) + { + String stringValue = (String) value; + + if (stringValue.length() != 0) + contactDetails.add(new ContactDetail(stringValue)); + } + else if (value instanceof Object[]) + { + for (Object subValue : (Object[]) value) + { + if (subValue instanceof String) + { + String stringSubValue = (String) subValue; + + if (stringSubValue.length() != 0) + { + contactDetails.add( + new ContactDetail(stringSubValue)); + } + } + } + } + } + return contactDetails; } /** @@ -195,8 +242,84 @@ private List getContactDetails(Object[] values) */ private String getDisplayName(Object[] values) { - // TODO Auto-generated method stub - return null; + String displayName + = (values[kABNicknameProperty] instanceof String) + ? (String) values[kABNicknameProperty] + : ""; + + if (displayName.length() != 0) + return displayName; + + String firstName + = (values[kABFirstNameProperty] instanceof String) + ? (String) values[kABFirstNameProperty] + : ""; + + if ((firstName.length() == 0) + && (values[kABFirstNamePhoneticProperty] instanceof String)) + { + firstName = (String) values[kABFirstNamePhoneticProperty]; + } + + String lastName + = (values[kABLastNameProperty] instanceof String) + ? (String) values[kABLastNameProperty] + : ""; + + if ((lastName.length() == 0) + && (values[kABLastNamePhoneticProperty] instanceof String)) + lastName = (String) values[kABLastNamePhoneticProperty]; + if ((lastName.length() == 0) + && (values[kABMiddleNameProperty] instanceof String)) + lastName = (String) values[kABMiddleNameProperty]; + if ((lastName.length() == 0) + && (values[kABMiddleNamePhoneticProperty] instanceof String)) + lastName = (String) values[kABMiddleNamePhoneticProperty]; + + if (firstName.length() == 0) + displayName = lastName; + else + { + displayName + = (lastName.length() == 0) + ? firstName + : (firstName + " " + lastName); + } + if (displayName.length() != 0) + return displayName; + + for (int i = 0; i < CONTACT_DETAIL_PROPERTY_INDEXES.length; i++) + { + Object value = values[CONTACT_DETAIL_PROPERTY_INDEXES[i]]; + + if (value instanceof String) + { + String stringValue = (String) value; + + if (stringValue.length() != 0) + { + displayName = stringValue; + break; + } + } + else if (value instanceof Object[]) + { + for (Object subValue : (Object[]) value) + { + if (subValue instanceof String) + { + String stringSubValue = (String) subValue; + + if (stringSubValue.length() != 0) + { + displayName = stringSubValue; + break; + } + } + } + } + } + return displayName; } /** @@ -314,15 +437,16 @@ private boolean matches(Object[] values) { if (value instanceof String) { - if (((String) value).toLowerCase().equals(query)) + if (((String) value).toLowerCase().contains(query)) return true; } - else if (value instanceof String[]) + else if (value instanceof Object[]) { - for (Object subValue : (String[]) value) + for (Object subValue : (Object[]) value) { if ((subValue instanceof String) - && ((String) subValue).toLowerCase().equals(query)) + && ((String) subValue) + .toLowerCase().contains(query)) return true; } } @@ -345,13 +469,23 @@ private boolean onPerson(long person) if (matches(values)) { - SourceContact sourceContact - = new AddrBookSourceContact( - getContactSource(), - getDisplayName(values), - getContactDetails(values)); + String displayName = getDisplayName(values); - addQueryResult(sourceContact); + if (displayName.length() != 0) + { + List contactDetails = getContactDetails(values); + + if (!contactDetails.isEmpty()) + { + SourceContact sourceContact + = new AddrBookSourceContact( + getContactSource(), + displayName, + contactDetails); + + addQueryResult(sourceContact); + } + } } return (getStatus() == QUERY_IN_PROGRESS); }