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.

cusax-fix
Lyubomir Marinov 15 years ago
parent 8b919ddfb1
commit 72bc56dbb3

@ -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);
}

@ -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 <jni.h>
#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_ */

@ -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)

@ -7,21 +7,98 @@
#include "net_java_sip_communicator_plugin_addrbook_macosx_MacOSXAddrBookContactQuery.h"
#include "AddrBookContactQuery.h"
#import <AddressBook/AddressBook.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
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);
}
}

@ -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

@ -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 <windows.h>
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(

@ -20,6 +20,13 @@
public class AddrBookActivator
implements BundleActivator
{
/**
* The <tt>Logger</tt> used by the <tt>AddrBookActivator</tt> class and its
* instances for logging output.
*/
private static final Logger logger
= Logger.getLogger(AddrBookActivator.class);
/**
* The <tt>ContactSourceService</tt> implementation for the OS-specific
* Address Book.

@ -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 <tt>SourceContact</tt> as <tt>ContactDetail</tt>s.
*/
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<ContactDetail> getContactDetails(Object[] values)
{
// TODO Auto-generated method stub
return null;
List<ContactDetail> contactDetails = new LinkedList<ContactDetail>();
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<ContactDetail> 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<ContactDetail> contactDetails = getContactDetails(values);
if (!contactDetails.isEmpty())
{
SourceContact sourceContact
= new AddrBookSourceContact(
getContactSource(),
displayName,
contactDetails);
addQueryResult(sourceContact);
}
}
}
return (getStatus() == QUERY_IN_PROGRESS);
}

Loading…
Cancel
Save