diff options
author | Sebastien Vincent <seb@jitsi.org> | 2011-03-22 16:23:01 +0000 |
---|---|---|
committer | Sebastien Vincent <seb@jitsi.org> | 2011-03-22 16:23:01 +0000 |
commit | 76767db08a34b0bdff9217111d680acce62d40dd (patch) | |
tree | dd5e7acd9e437df2e506a5b85c957289712289cb /src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java | |
parent | 260fd209ae9a458309d4825740085e04ed75cf2c (diff) | |
download | jitsi-76767db08a34b0bdff9217111d680acce62d40dd.zip jitsi-76767db08a34b0bdff9217111d680acce62d40dd.tar.gz jitsi-76767db08a34b0bdff9217111d680acce62d40dd.tar.bz2 |
Initial support for Google Contacts as contact source.
Diffstat (limited to 'src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java')
-rw-r--r-- | src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java new file mode 100644 index 0000000..77efe3c --- /dev/null +++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsServiceImpl.java @@ -0,0 +1,427 @@ +/* + * 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.impl.googlecontacts; + +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.regex.*; + +import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.service.credentialsstorage.*; +import net.java.sip.communicator.service.googlecontacts.*; +import net.java.sip.communicator.util.*; + +import com.google.gdata.client.Service.*; +import com.google.gdata.client.contacts.*; +import com.google.gdata.data.*; +import com.google.gdata.data.contacts.ContactFeed; +import com.google.gdata.data.contacts.ContactEntry; +import com.google.gdata.data.extensions.*; + +/** + * Implementation of Google Contacts service. + * We first get {@link #MAX_RESULT} contacts from Google Contacts then + * we filter it to get {@link #MAX_RESULT} that matched our query. + * If {@link #MAX_RESULT} is not reach, we try with additional + * contacts (if there are more than {@link #MAX_RESULT} contacts). + * + * @author Sebastien Vincent + */ +public class GoogleContactsServiceImpl + implements GoogleContactsService +{ + /** + * Logger. + */ + private static final Logger logger = + Logger.getLogger(GoogleContactsServiceImpl.class); + + /** + * Google Contacts feed URL string. + */ + private static final String feedURL = + "https://www.google.com/m8/feeds/contacts/default/full"; + + /** + * Maximum number of results for a query. + */ + public static final int MAX_RESULT = 20; + + /** + * Maximum number of contacts retrieved for a query. + */ + public static final int MAX_NUMBER = 1000; + + /** + * List of Google Contacts account. + */ + private final List<GoogleContactsConnectionImpl> accounts = + new ArrayList<GoogleContactsConnectionImpl>(); + + /** + * Path where to store the account settings + */ + private final static String CONFIGURATION_PATH = + "net.java.sip.communicator.impl.googlecontacts"; + + /** + * Constructor. + */ + public GoogleContactsServiceImpl() + { + loadConfig(); + } + + /** + * Get list of stored connections. + * + * @return list of connections + */ + public List<GoogleContactsConnectionImpl> getAccounts() + { + return accounts; + } + + /** + * Loads configuration. + */ + private void loadConfig() + { + ConfigurationService configService = + GoogleContactsActivator.getConfigService(); + CredentialsStorageService credentialsService = + GoogleContactsActivator.getCredentialsService(); + + List<String> list = configService.getPropertyNamesByPrefix( + CONFIGURATION_PATH, true); + + for(Object configEntry : list) + { + String path = configEntry.toString(); + Object oen = configService.getProperty(path + ".enabled"); + boolean enabled = Boolean.parseBoolean((String)oen); + String login = + (String)configService.getProperty(path + ".account"); + String password = credentialsService.loadPassword(path); + + GoogleContactsConnectionImpl cnx = (GoogleContactsConnectionImpl) + getConnection(login, password); + cnx.setEnabled(enabled); + + if(cnx != null) + { + accounts.add(cnx); + /* register contact source */ + if(cnx.isEnabled()) + { + addContactSource(cnx); + } + } + } + } + + /** + * Perform a search for a contact using regular expression. + * + * @param cnx <tt>GoogleContactsConnection</tt> to perform the query + * @param gQuery Google query + * @param count maximum number of matched contacts + * @param callback object that will be notified for each new + * <tt>GoogleContactsEntry</tt> found + * @return list of <tt>GoogleContactsEntry</tt> + */ + public List<GoogleContactsEntry> searchContact( + GoogleContactsConnection cnx, GoogleQuery gQuery, int count, + GoogleEntryCallback callback) + { + URL url = null; + ContactFeed contactFeed = null; + ContactQuery query = null; + List<GoogleContactsEntry> ret = new ArrayList<GoogleContactsEntry>(); + boolean endOfContacts = false; + int matchedContacts = 0; + int index = 1; + GoogleContactsConnectionImpl cnxImpl = + (GoogleContactsConnectionImpl)cnx; + + if(count <= 0) + { + count = MAX_RESULT; + } + + try + { + url = new URL(feedURL); + } + catch(MalformedURLException e) + { + logger.info("Malformed URL", e); + return ret; + } + + if(gQuery.isCancelled()) + { + return ret; + } + + while(matchedContacts < count || endOfContacts) + { + query = new ContactQuery(url); + query.setStartIndex(index); + query.setMaxResults(MAX_NUMBER); + query.setSortOrder(ContactQuery.SortOrder.DESCENDING); + + if(gQuery.isCancelled()) + { + return ret; + } + + try + { + contactFeed = cnxImpl.getGoogleService().query( + query, ContactFeed.class); + } + catch(Exception e) + { + logger.info( + "Problem occurred during Google Contacts retrievment", + e); + return ret; + } + + if(contactFeed.getEntries().size() == 0) + { + endOfContacts = true; + break; + } + + for (int i = 0; i < contactFeed.getEntries().size(); i++) + { + if(gQuery.isCancelled()) + { + return ret; + } + + ContactEntry entry = contactFeed.getEntries().get(i); + + if(filter(entry, gQuery.getQueryPattern())) + { + GoogleContactsEntry gcEntry = null; + + gcEntry = getGoogleContactsEntry(entry); + matchedContacts++; + ret.add(gcEntry); + + if(callback != null) + { + callback.callback(gcEntry); + } + + if(matchedContacts >= count) + { + break; + } + } + } + + index += contactFeed.getEntries().size(); + } + return ret; + } + + /** + * Filter according to <tt>filter</tt>. + * + * @param entry <tt>ContactEntry</tt> + * @param filter regular expression + * @return true if entry match the filter, false otherwise + */ + private boolean filter(ContactEntry entry, Pattern filter) + { + Name name = entry.getName(); + + /* try to see if name, mail or phone match */ + + if(name != null) + { + if(name.hasFamilyName()) + { + Matcher m = filter.matcher(name.getFamilyName().getValue()); + if(m.matches()) + { + return true; + } + } + + if(name.hasGivenName()) + { + Matcher m = filter.matcher(name.getGivenName().getValue()); + if(m.find()) + { + return true; + } + } + + if(name.hasFullName()) + { + Matcher m = filter.matcher(name.getFullName().getValue()); + if(m.find()) + { + return true; + } + } + } + + for(Email mail : entry.getEmailAddresses()) + { + Matcher m = filter.matcher(mail.getAddress()); + + if(m.find()) + { + return true; + } + } + + for(PhoneNumber phone : entry.getPhoneNumbers()) + { + Matcher m = filter.matcher(phone.getPhoneNumber()); + + if(m.find()) + { + return true; + } + } + + return false; + } + + /** + * Get a <tt>GoogleContactsEntry</tt> from a <tt>ContactEntry</tt> + * + * @param entry <tt>ContactEntry</tt> + * @return <tt>GoogleContactsEntry</tt> + */ + private GoogleContactsEntry getGoogleContactsEntry(ContactEntry entry) + { + GoogleContactsEntryImpl ret = new GoogleContactsEntryImpl(); + + ret.setField(entry); + return ret; + } + + /** + * Get the full contacts list. + * + * @return list of <tt>GoogleContactsEntry</tt> + */ + public List<GoogleContactsEntry> getContacts() + { + return null; + } + + /** + * Get a <tt>GoogleContactsConnection</tt>. + * + * @param login login to connect to the service + * @param password password to connect to the service + * @return <tt>GoogleContactsConnection</tt>. + */ + public GoogleContactsConnection getConnection(String login, + String password) + { + try + { + return new GoogleContactsConnectionImpl(login, password); + } + catch(Exception e) + { + logger.info("Failed to authenticate Google Contacts", e); + return null; + } + } + + /** + * Add a contact source service with the specified. + * + * <tt>GoogleContactsConnection</tt>. + * @param cnx <tt>GoogleContactsConnection</tt>. + */ + public void addContactSource(GoogleContactsConnection cnx) + { + GoogleContactsActivator.enableContactSource(cnx); + } + + /** + * Add a contact source service with the specified + * <tt>GoogleContactsConnection</tt>. + * + * @param login login + * @param password password + */ + public void addContactSource(String login, String password) + { + GoogleContactsActivator.enableContactSource(login, password); + } + + /** + * Add a contact source service with the specified. + * + * <tt>GoogleContactsConnection</tt>. + * @param cnx <tt>GoogleContactsConnection</tt>. + */ + public void removeContactSource(GoogleContactsConnection cnx) + { + GoogleContactsActivator.disableContactSource(cnx); + } + + /** + * Remove a contact source service with the specified + * <tt>GoogleContactsConnection</tt>. + * + * @param login login + */ + public void removeContactSource(String login) + { + GoogleContactsActivator.disableContactSource(login); + } + + /** + * Retrieve photo of a contact. Adapted from Google sample. + * + * @param photoLink photo link + * @param service + * @return byte array containing image photo or null if problem happened + */ + public static byte[] downloadPhoto(ILink photoLink, + ContactsService service) + { + try + { + if (photoLink != null) + { + GDataRequest request = + service.createLinkQueryRequest(photoLink); + request.execute(); + InputStream in = request.getResponseStream(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + + for (int read = 0 ; (read = in.read(buffer)) != -1; + out.write(buffer, 0, read)); + + return out.toByteArray(); + } + } + catch(Exception e) + { + logger.info("Failed to retrieve photo of the contact", e); + } + return null; + } +} |