/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.addrbook.macosx;
import java.util.*;
import net.java.sip.communicator.plugin.addrbook.*;
import net.java.sip.communicator.service.contactsource.*;
/**
* Implements ContactQuery for the Address Book of Mac OS X.
*
* @author Lyubomir Marinov
*/
public class MacOSXAddrBookContactQuery
extends AsyncContactQuery
{
/**
* The properties of ABPerson which are to be queried by the
* MacOSXAddrBookContactQuery instances.
*/
private static final long[] ABPERSON_PROPERTIES
= new long[]
{
kABAIMInstantProperty(),
kABEmailProperty(),
kABFirstNameProperty(),
kABFirstNamePhoneticProperty(),
kABICQInstantProperty(),
kABJabberInstantProperty(),
kABLastNameProperty(),
kABLastNamePhoneticProperty(),
kABMiddleNameProperty(),
kABMiddleNamePhoneticProperty(),
kABMSNInstantProperty(),
kABNicknameProperty(),
kABPhoneProperty(),
kABYahooInstantProperty()
};
/**
* The index of the kABAIMInstantProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABAIMInstantProperty = 0;
/**
* The index of the kABEmailProperty ABPerson property in
* {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABEmailProperty = 1;
/**
* The index of the kABFirstNameProperty ABPerson property
* in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABFirstNameProperty = 2;
/**
* The index of the kABFirstNamePhoneticProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABFirstNamePhoneticProperty = 3;
/**
* The index of the kABICQInstantProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABICQInstantProperty = 4;
/**
* The index of the kABJabberInstantProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABJabberInstantProperty = 5;
/**
* The index of the kABLastNameProperty ABPerson property
* in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABLastNameProperty = 6;
/**
* The index of the kABLastNamePhoneticProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABLastNamePhoneticProperty = 7;
/**
* The index of the kABMiddleNameProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABMiddleNameProperty = 8;
/**
* The index of the kABMiddleNamePhoneticProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABMiddleNamePhoneticProperty = 9;
/**
* The index of the kABMSNInstantProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABMSNInstantProperty = 10;
/**
* The index of the kABNicknameProperty ABPerson property
* in {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABNicknameProperty = 11;
/**
* The index of the kABPhoneProperty ABPerson property in
* {@link #ABPERSON_PROPERTIES}.
*/
private static final int kABPhoneProperty = 12;
/**
* The index of the kABYahooInstantProperty ABPerson
* property in {@link #ABPERSON_PROPERTIES}.
*/
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");
}
/**
* Initializes a new MacOSXAddrBookContactQuery which is to perform
* a specific query in the Address Book of Mac OS X on behalf of a
* specific MacOSXAddrBookContactSourceService.
*
* @param contactSource the MacOSXAddrBookContactSourceService
* which is to perform the new ContactQuery instance
* @param query the String for which contactSource i.e.
* the Address Book of Mac OS X is being queried
*/
public MacOSXAddrBookContactQuery(
MacOSXAddrBookContactSourceService contactSource,
String query)
{
super(contactSource, query);
}
private static native Object[] ABRecord_valuesForProperties(
long record,
long[] properties);
/**
* Calls back to a specific PtrCallback for each ABPerson
* found in the Address Book of Mac OS X which matches a specific
* String query.
*
* @param query the String for which the Address Book of Mac OS X
* is to be queried. Warning: Ignored at the time of this writing.
* @param callback the PtrCallback to be notified about the
* matching ABPersons
*/
private static native void foreachPerson(
String query,
PtrCallback callback);
/**
* Gets the contactDetails to be set on a SourceContact
* which is to represent an ABPerson specified by the values of its
* {@link #ABPERSON_PROPERTIES}.
*
* @param values the values of the ABPERSON_PROPERTIES which
* represent the ABPerson to get the contactDetails of
* @return the contactDetails to be set on a SourceContact
* which is to represent the ABPerson specified by values
*/
private List getContactDetails(Object[] values)
{
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;
}
/**
* Gets the displayName to be set on a SourceContact
* which is to represent an ABPerson specified by the values of its
* {@link #ABPERSON_PROPERTIES}.
*
* @param values the values of the ABPERSON_PROPERTIES which
* represent the ABPerson to get the displayName of
* @return the displayName to be set on a SourceContact
* which is to represent the ABPerson specified by values
*/
private String getDisplayName(Object[] values)
{
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;
}
/**
* Gets the value of the kABAIMInstantProperty constant.
*
* @return the value of the kABAIMInstantProperty constant
*/
private static native long kABAIMInstantProperty();
/**
* Gets the value of the kABEmailProperty constant.
*
* @return the value of the kABEmailProperty constant
*/
private static native long kABEmailProperty();
/**
* Gets the value of the kABFirstNameProperty constant.
*
* @return the value of the kABFirstNameProperty constant
*/
private static native long kABFirstNameProperty();
/**
* Gets the value of the kABFirstNamePhoneticProperty constant.
*
* @return the value of the kABFirstNamePhoneticProperty constant
*/
private static native long kABFirstNamePhoneticProperty();
/**
* Gets the value of the kABICQInstantProperty constant.
*
* @return the value of the kABICQInstantProperty constant
*/
private static native long kABICQInstantProperty();
/**
* Gets the value of the kABJabberInstantProperty constant.
*
* @return the value of the kABJabberInstantProperty constant
*/
private static native long kABJabberInstantProperty();
/**
* Gets the value of the kABLastNameProperty constant.
*
* @return the value of the kABLastNameProperty constant
*/
private static native long kABLastNameProperty();
/**
* Gets the value of the kABLastNamePhoneticProperty constant.
*
* @return the value of the kABLastNamePhoneticProperty constant
*/
private static native long kABLastNamePhoneticProperty();
/**
* Gets the value of the kABMiddleNameProperty constant.
*
* @return the value of the kABMiddleNameProperty constant
*/
private static native long kABMiddleNameProperty();
/**
* Gets the value of the kABMiddleNamePhoneticProperty constant.
*
* @return the value of the kABMiddleNamePhoneticProperty constant
*/
private static native long kABMiddleNamePhoneticProperty();
/**
* Gets the value of the kABMSNInstantProperty constant.
*
* @return the value of the kABMSNInstantProperty constant
*/
private static native long kABMSNInstantProperty();
/**
* Gets the value of the kABNicknameProperty constant.
*
* @return the value of the kABNicknameProperty constant
*/
private static native long kABNicknameProperty();
/**
* Gets the value of the kABPhoneProperty constant.
*
* @return the value of the kABPhoneProperty constant
*/
private static native long kABPhoneProperty();
/**
* Gets the value of the kABYahooInstantProperty constant.
*
* @return the value of the kABYahooInstantProperty constant
*/
private static native long kABYahooInstantProperty();
/**
* Determines whether an ABPerson represented by the values of its
* {@link #ABPERSON_PROPERTIES} matches {@link #query}.
*
* @param values the values of the ABPERSON_PROPERTIES which
* represent the ABPerson to be determined whether it matches
* query
* @return true if the ABPerson represented by the
* specified values matches query; otherwise,
* false
*/
private boolean matches(Object[] values)
{
for (Object value : values)
{
if (value instanceof String)
{
if (((String) value).toLowerCase().contains(query))
return true;
}
else if (value instanceof Object[])
{
for (Object subValue : (Object[]) value)
{
if ((subValue instanceof String)
&& ((String) subValue)
.toLowerCase().contains(query))
return true;
}
}
}
return false;
}
/**
* Notifies this MacOSXAddrBookContactQuery about a specific
* ABPerson.
*
* @param person a pointer to the ABPerson instance to notify about
* @return true if this MacOSXAddrBookContactQuery is to
* continue being called; otherwise, false
*/
private boolean onPerson(long person)
{
Object[] values
= ABRecord_valuesForProperties(person, ABPERSON_PROPERTIES);
if (matches(values))
{
String displayName = getDisplayName(values);
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);
}
/**
* Performs this AsyncContactQuery in a background Thread.
*
* @see AsyncContactQuery#run()
*/
protected void run()
{
foreachPerson(
query,
new PtrCallback()
{
public boolean callback(long person)
{
return onPerson(person);
}
});
}
}