/* * 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); } }); } }