/** * Implements <tt>ContactSourceService</tt> for Google Contacts. * * @author Sebastien Vincent */ public class GoogleContactsSourceService implements ExtendedContactSourceService { /** Logger. */ private static final Logger logger = Logger.getLogger(GoogleContactsSourceService.class); /** * The <tt>List</tt> of <tt>GoogleContactsQuery</tt> instances which have been started and haven't * stopped yet. */ private final List<GoogleContactsQuery> queries = new LinkedList<GoogleContactsQuery>(); /** Login. */ private final String login; /** Password. */ private final String password; /** The prefix for all google contact phone numbers. */ private String phoneNumberprefix; /** Google Contacts connection. */ private GoogleContactsConnection cnx = null; /** The account settings form. */ private AccountSettingsForm settings = null; /** If the account has been created using GoogleTalk wizard or via external Google Contacts. */ private boolean googleTalk = false; /** * Constructor. * * @param login login * @param password password */ public GoogleContactsSourceService(String login, String password) { super(); this.login = login; this.password = password; } /** * Constructor. * * @param cnx connection */ public GoogleContactsSourceService(GoogleContactsConnection cnx) { super(); this.cnx = cnx; this.login = cnx.getLogin(); this.password = cnx.getPassword(); this.phoneNumberprefix = cnx.getPrefix(); } /** * Returns login. * * @return login */ public String getLogin() { return login; } /** * Set whether or not the account has been created via GoogleTalk wizard or external Google * contacts. * * @param googleTalk value to set */ public void setGoogleTalk(boolean googleTalk) { this.googleTalk = googleTalk; } /** * Returns whether or not the account has been created via GoogleTalk wizard or via external * Google Contacts. * * @return true if account has been created via GoogleTalk wizard or via external Google Contacts. */ public boolean isGoogleTalk() { return googleTalk; } /** * Creates query for the given <tt>searchPattern</tt>. * * @param queryPattern the pattern to search for * @return the created query */ public ContactQuery createContactQuery(Pattern queryPattern) { return createContactQuery(queryPattern, GoogleContactsQuery.GOOGLECONTACTS_MAX_RESULTS); } /** * Creates query for the given <tt>searchPattern</tt>. * * @param queryPattern the pattern to search for * @param count maximum number of contact returned * @return the created query */ public ContactQuery createContactQuery(Pattern queryPattern, int count) { GoogleContactsQuery query = new GoogleContactsQuery(this, queryPattern, count); synchronized (queries) { queries.add(query); } return query; } /** * Removes query from the list of queries. * * @param query the query that will be removed. */ public synchronized void removeQuery(ContactQuery query) { if (queries.remove(query)) queries.notify(); } /** * Returns the Google Contacts connection. * * @return Google Contacts connection */ public GoogleContactsConnectionImpl getConnection() { int s = login.indexOf('@'); boolean isGoogleAppsOrGmail = false; if (s == -1) { return null; } String domain = login.substring((s + 1)); try { SRVRecord srvRecords[] = NetworkUtils.getSRVRecords("xmpp-client", "tcp", domain); if (srvRecords != null) { // To detect that account is a google ones, we try following: // - lookup in SRV and see if it is google.com; // - if the account has been created with GoogleTalk form; // - if it is an "external" google contact. // SRV checks for (SRVRecord srv : srvRecords) { if (srv.getTarget().endsWith("google.com") || srv.getTarget().endsWith("google.com.")) { isGoogleAppsOrGmail = true; break; } } } // GoogleTalk based account or external Google Contacts ? if (!isGoogleAppsOrGmail) { isGoogleAppsOrGmail = googleTalk; } if (isGoogleAppsOrGmail) { if (cnx == null) { cnx = new GoogleContactsConnectionImpl(login, password); if (cnx.connect() == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) { synchronized (this) { if (settings != null) { cnx = null; return null; } else { settings = new AccountSettingsForm(); } } settings.setModal(true); settings.loadData(cnx); int ret = settings.showDialog(); if (ret == 1) { cnx = settings.getConnection(); GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx); } else { cnx = null; } } } else if (cnx.connect() == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) { synchronized (this) { if (settings != null) { cnx = null; return null; } else { settings = new AccountSettingsForm(); } } settings.setModal(true); settings.loadData(cnx); int ret = settings.showDialog(); if (ret == 1) { cnx = settings.getConnection(); GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx); } else { cnx = null; } } } else { cnx = null; } } catch (Exception e) { logger.info("GoogleContacts connection error", e); return null; } return (GoogleContactsConnectionImpl) cnx; } /** * Returns a user-friendly string that identifies this contact source. * * @return the display name of this contact source */ public String getDisplayName() { return login; } /** * Returns SEARCH_TYPE to indicate that this contact source * * @return the identifier of this contact source */ public int getType() { return SEARCH_TYPE; } /** * Queries this search source for the given <tt>queryString</tt>. * * @param query the string to search for * @return the created query */ public ContactQuery createContactQuery(String query) { return createContactQuery(query, GoogleContactsQuery.GOOGLECONTACTS_MAX_RESULTS); } /** * Creates query for the given <tt>queryString</tt>. * * @param query the string to search for * @param contactCount the maximum count of result contacts * @return the created query */ public ContactQuery createContactQuery(String query, int contactCount) { Pattern pattern = null; try { pattern = Pattern.compile(query); } catch (PatternSyntaxException pse) { pattern = Pattern.compile(Pattern.quote(query)); } if (pattern != null) { return createContactQuery(pattern, contactCount); } return null; } /** * Stops this <tt>ContactSourceService</tt> implementation and prepares it for garbage collection. * * @see AsyncContactSourceService#stop() */ public void stop() { boolean interrupted = false; synchronized (queries) { while (!queries.isEmpty()) { queries.get(0).cancel(); try { queries.wait(); } catch (InterruptedException iex) { interrupted = true; } } } if (interrupted) Thread.currentThread().interrupt(); } /** * Notifies this <tt>GoogleContactsSourceService</tt> that a specific <tt>GoogleContactsQuery</tt> * has stopped. * * @param query the <tt>GoogleContactsQuery</tt> which has stopped */ void stopped(GoogleContactsQuery query) { synchronized (queries) { if (queries.remove(query)) queries.notify(); } } /** * Returns the phoneNumber prefix for all phone numbers. * * @return the phoneNumber prefix for all phone numbers */ public String getPhoneNumberPrefix() { return phoneNumberprefix; } /** * Sets the phone number prefix. * * @param phoneNumberprefix the phone number prefix to set */ public void setPhoneNumberPrefix(String phoneNumberprefix) { this.phoneNumberprefix = phoneNumberprefix; } /** * Returns the index of the contact source in the result list. * * @return the index of the contact source in the result list */ public int getIndex() { return -1; } }
/** * Returns the Google Contacts connection. * * @return Google Contacts connection */ public GoogleContactsConnectionImpl getConnection() { int s = login.indexOf('@'); boolean isGoogleAppsOrGmail = false; if (s == -1) { return null; } String domain = login.substring((s + 1)); try { SRVRecord srvRecords[] = NetworkUtils.getSRVRecords("xmpp-client", "tcp", domain); if (srvRecords != null) { // To detect that account is a google ones, we try following: // - lookup in SRV and see if it is google.com; // - if the account has been created with GoogleTalk form; // - if it is an "external" google contact. // SRV checks for (SRVRecord srv : srvRecords) { if (srv.getTarget().endsWith("google.com") || srv.getTarget().endsWith("google.com.")) { isGoogleAppsOrGmail = true; break; } } } // GoogleTalk based account or external Google Contacts ? if (!isGoogleAppsOrGmail) { isGoogleAppsOrGmail = googleTalk; } if (isGoogleAppsOrGmail) { if (cnx == null) { cnx = new GoogleContactsConnectionImpl(login, password); if (cnx.connect() == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) { synchronized (this) { if (settings != null) { cnx = null; return null; } else { settings = new AccountSettingsForm(); } } settings.setModal(true); settings.loadData(cnx); int ret = settings.showDialog(); if (ret == 1) { cnx = settings.getConnection(); GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx); } else { cnx = null; } } } else if (cnx.connect() == GoogleContactsConnection.ConnectionStatus.ERROR_INVALID_CREDENTIALS) { synchronized (this) { if (settings != null) { cnx = null; return null; } else { settings = new AccountSettingsForm(); } } settings.setModal(true); settings.loadData(cnx); int ret = settings.showDialog(); if (ret == 1) { cnx = settings.getConnection(); GoogleContactsActivator.getGoogleContactsService().saveConfig(cnx); } else { cnx = null; } } } else { cnx = null; } } catch (Exception e) { logger.info("GoogleContacts connection error", e); return null; } return (GoogleContactsConnectionImpl) cnx; }