mirror of https://github.com/sipwise/jitsi.git
parent
260fd209ae
commit
76767db08a
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* 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.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.configuration.*;
|
||||
import net.java.sip.communicator.service.contactsource.*;
|
||||
import net.java.sip.communicator.service.credentialsstorage.*;
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
import net.java.sip.communicator.service.gui.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.service.resources.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* Activates the Google Contacts Service
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleContactsActivator implements BundleActivator
|
||||
{
|
||||
/**
|
||||
* The <tt>Logger</tt> used by the <tt>GoogleContactsActivator</tt> class
|
||||
* and its instances for logging output.
|
||||
*/
|
||||
private final Logger logger = Logger.getLogger(
|
||||
GoogleContactsActivator.class);
|
||||
|
||||
/**
|
||||
* The OSGi <tt>ServiceRegistration</tt> of
|
||||
* <tt>GoogleContactsServiceImpl</tt>.
|
||||
*/
|
||||
private ServiceRegistration serviceRegistration = null;
|
||||
|
||||
/**
|
||||
* BundleContext from the OSGI bus.
|
||||
*/
|
||||
private static BundleContext bundleContext;
|
||||
|
||||
/**
|
||||
* Reference to the configuration service
|
||||
*/
|
||||
private static ConfigurationService configService;
|
||||
|
||||
/**
|
||||
* Reference to the credentials service
|
||||
*/
|
||||
private static CredentialsStorageService credentialsService;
|
||||
|
||||
/**
|
||||
* Reference to the resource management service
|
||||
*/
|
||||
private static ResourceManagementService resourceService;
|
||||
|
||||
/**
|
||||
* The cached reference to the <tt>PhoneNumberI18nService</tt> instance used
|
||||
* by the functionality of the Google Contacts plug-in and fetched from its
|
||||
* <tt>BundleContext</tt>.
|
||||
*/
|
||||
private static PhoneNumberI18nService phoneNumberI18nService;
|
||||
|
||||
/**
|
||||
* Google contacts service.
|
||||
*/
|
||||
private static GoogleContactsServiceImpl googleContactsService;
|
||||
|
||||
/**
|
||||
* List of contact source service registrations.
|
||||
*/
|
||||
private static Map<GoogleContactsSourceService, ServiceRegistration> cssList
|
||||
= new HashMap<GoogleContactsSourceService, ServiceRegistration>();
|
||||
|
||||
/**
|
||||
* Gets the <tt>PhoneNumberI18nService</tt> to be used by the functionality
|
||||
* of the addrbook plug-in.
|
||||
*
|
||||
* @return the <tt>PhoneNumberI18nService</tt> to be used by the
|
||||
* functionality of the addrbook plug-in
|
||||
*/
|
||||
public static PhoneNumberI18nService getPhoneNumberI18nService()
|
||||
{
|
||||
if (phoneNumberI18nService == null)
|
||||
{
|
||||
phoneNumberI18nService
|
||||
= ServiceUtils.getService(
|
||||
bundleContext,
|
||||
PhoneNumberI18nService.class);
|
||||
}
|
||||
return phoneNumberI18nService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a ConfigurationService implementation currently
|
||||
* registered in the bundle context or null if no such implementation was
|
||||
* found.
|
||||
*
|
||||
* @return a currently valid implementation of the ConfigurationService.
|
||||
*/
|
||||
public static ConfigurationService getConfigService()
|
||||
{
|
||||
if(configService == null)
|
||||
{
|
||||
ServiceReference confReference
|
||||
= bundleContext.getServiceReference(
|
||||
ConfigurationService.class.getName());
|
||||
configService
|
||||
= (ConfigurationService) bundleContext.getService(
|
||||
confReference);
|
||||
}
|
||||
return configService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a GoogleContactsService implementation currently
|
||||
* registered in the bundle context or null if no such implementation was
|
||||
* found.
|
||||
*
|
||||
* @return a currently valid implementation of the GoogleContactsService
|
||||
*/
|
||||
public static GoogleContactsServiceImpl getGoogleContactsService()
|
||||
{
|
||||
return googleContactsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a CredentialsStorageConfigurationService
|
||||
* implementation currently registered in the bundle context or null if no
|
||||
* such implementation was found.
|
||||
*
|
||||
* @return a currently valid implementation of the
|
||||
* CredentialsStorageService.
|
||||
*/
|
||||
public static CredentialsStorageService getCredentialsService()
|
||||
{
|
||||
if(credentialsService == null)
|
||||
{
|
||||
ServiceReference confReference
|
||||
= bundleContext.getServiceReference(
|
||||
CredentialsStorageService.class.getName());
|
||||
credentialsService
|
||||
= (CredentialsStorageService) bundleContext.getService(
|
||||
confReference);
|
||||
}
|
||||
return credentialsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to a ResourceManagementService implementation
|
||||
* currently registered in the bundle context or null if no such
|
||||
* implementation was found.
|
||||
*
|
||||
* @return a currently valid implementation of the
|
||||
* ResourceManagementService.
|
||||
*/
|
||||
public static ResourceManagementService getResourceManagementService()
|
||||
{
|
||||
if(resourceService == null)
|
||||
{
|
||||
ServiceReference confReference
|
||||
= bundleContext.getServiceReference(
|
||||
ResourceManagementService.class.getName());
|
||||
resourceService
|
||||
= (ResourceManagementService) bundleContext.getService(
|
||||
confReference);
|
||||
}
|
||||
return resourceService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Google Contacts service
|
||||
*
|
||||
* @param bundleContext BundleContext
|
||||
* @throws Exception if something goes wrong when starting service
|
||||
*/
|
||||
public void start(BundleContext bundleContext)
|
||||
throws Exception
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Started.");
|
||||
|
||||
GoogleContactsActivator.bundleContext = bundleContext;
|
||||
googleContactsService =
|
||||
new GoogleContactsServiceImpl();
|
||||
serviceRegistration =
|
||||
bundleContext.registerService(GoogleContactsService.class.getName(),
|
||||
googleContactsService, null);
|
||||
|
||||
/* registers the configuration form */
|
||||
Dictionary<String, String> properties =
|
||||
new Hashtable<String, String>();
|
||||
properties.put( ConfigurationForm.FORM_TYPE,
|
||||
ConfigurationForm.ADVANCED_TYPE);
|
||||
|
||||
bundleContext.registerService(
|
||||
ConfigurationForm.class.getName(),
|
||||
new LazyConfigurationForm(
|
||||
"net.java.sip.communicator.impl.googlecontacts.configform.GoogleContactsConfigForm",
|
||||
getClass().getClassLoader(),
|
||||
"impl.googlecontacts.PLUGIN_ICON",
|
||||
"impl.googlecontacts.CONFIG_FORM_TITLE",
|
||||
2000, true),
|
||||
properties);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Google Contacts Service ... [REGISTERED]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the Google Contacts service.
|
||||
*
|
||||
* @param bundleContext BundleContext
|
||||
* @throws Exception if something goes wrong when stopping service
|
||||
*/
|
||||
public void stop(BundleContext bundleContext)
|
||||
throws Exception
|
||||
{
|
||||
if (serviceRegistration != null)
|
||||
{
|
||||
serviceRegistration.unregister();
|
||||
serviceRegistration = null;
|
||||
}
|
||||
|
||||
/* remove contact source services */
|
||||
for(Map.Entry<GoogleContactsSourceService, ServiceRegistration> entry :
|
||||
cssList.entrySet())
|
||||
{
|
||||
if (entry.getValue() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
entry.getValue().unregister();
|
||||
}
|
||||
finally
|
||||
{
|
||||
entry.getKey().stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
cssList.clear();
|
||||
|
||||
GoogleContactsActivator.bundleContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable contact source service with specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param login login
|
||||
* @param password password
|
||||
*/
|
||||
public static void enableContactSource(String login, String password)
|
||||
{
|
||||
GoogleContactsSourceService css = new GoogleContactsSourceService(
|
||||
login, password);
|
||||
ServiceRegistration cssServiceRegistration = null;
|
||||
|
||||
try
|
||||
{
|
||||
cssServiceRegistration
|
||||
= bundleContext.registerService(
|
||||
ContactSourceService.class.getName(),
|
||||
css,
|
||||
null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (cssServiceRegistration == null)
|
||||
{
|
||||
css.stop();
|
||||
css = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
cssList.put(css, cssServiceRegistration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable contact source service with specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param cnx <tt>GoogleContactsConnection</tt>
|
||||
*/
|
||||
public static void enableContactSource(GoogleContactsConnection cnx)
|
||||
{
|
||||
GoogleContactsSourceService css = new GoogleContactsSourceService(
|
||||
cnx);
|
||||
ServiceRegistration cssServiceRegistration = null;
|
||||
|
||||
try
|
||||
{
|
||||
cssServiceRegistration
|
||||
= bundleContext.registerService(
|
||||
ContactSourceService.class.getName(),
|
||||
css,
|
||||
null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (cssServiceRegistration == null)
|
||||
{
|
||||
css.stop();
|
||||
css = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
cssList.put(css, cssServiceRegistration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable contact source service with specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param login login
|
||||
*/
|
||||
public static void disableContactSource(String login)
|
||||
{
|
||||
GoogleContactsSourceService found = null;
|
||||
|
||||
for(Map.Entry<GoogleContactsSourceService, ServiceRegistration> entry :
|
||||
cssList.entrySet())
|
||||
{
|
||||
String cssName =
|
||||
entry.getKey().getConnection().getLogin();
|
||||
|
||||
if(cssName.equals(login))
|
||||
{
|
||||
try
|
||||
{
|
||||
entry.getValue().unregister();
|
||||
}
|
||||
finally
|
||||
{
|
||||
entry.getKey().stop();
|
||||
}
|
||||
found = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found != null)
|
||||
{
|
||||
cssList.remove(found);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable contact source service with specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param cnx <tt>GoogleContactsConnection</tt>.
|
||||
*/
|
||||
public static void disableContactSource(GoogleContactsConnection cnx)
|
||||
{
|
||||
GoogleContactsSourceService found = null;
|
||||
|
||||
for(Map.Entry<GoogleContactsSourceService, ServiceRegistration> entry :
|
||||
cssList.entrySet())
|
||||
{
|
||||
String cssName =
|
||||
entry.getKey().getConnection().getLogin();
|
||||
String name = cnx.getLogin();
|
||||
if(cssName.equals(name))
|
||||
{
|
||||
try
|
||||
{
|
||||
entry.getValue().unregister();
|
||||
}
|
||||
finally
|
||||
{
|
||||
entry.getKey().stop();
|
||||
}
|
||||
found = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(found != null)
|
||||
{
|
||||
cssList.remove(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 com.google.gdata.client.contacts.*;
|
||||
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
|
||||
/**
|
||||
* Google Contacts credentials to connect to the service.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleContactsConnectionImpl
|
||||
implements GoogleContactsConnection
|
||||
{
|
||||
/**
|
||||
* Login.
|
||||
*/
|
||||
private final String login;
|
||||
|
||||
/**
|
||||
* Password.
|
||||
*/
|
||||
private final String password;
|
||||
|
||||
/**
|
||||
* If the connection is enabled.
|
||||
*/
|
||||
private boolean enabled = false;
|
||||
|
||||
/**
|
||||
* Google Contacts service.
|
||||
*/
|
||||
private final ContactsService googleService =
|
||||
new ContactsService("GoogleContacts service for Jitsi");
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param login the login to connect to the service
|
||||
* @param password the password to connect to the service
|
||||
* @throws Exception if something goes wrong during connection
|
||||
*/
|
||||
public GoogleContactsConnectionImpl(String login, String password)
|
||||
throws Exception
|
||||
{
|
||||
this.login = login;
|
||||
this.password = password;
|
||||
|
||||
googleService.setUserCredentials(login, password);
|
||||
googleService.useSsl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Google service.
|
||||
*
|
||||
* @return the Google service
|
||||
*/
|
||||
public ContactsService getGoogleService()
|
||||
{
|
||||
return googleService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get login.
|
||||
*
|
||||
* @return login to connect to the service
|
||||
*/
|
||||
public String getLogin()
|
||||
{
|
||||
return login;
|
||||
}
|
||||
|
||||
/**
|
||||
* get password.
|
||||
*
|
||||
* @return password to connect to the service
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the connection is enabled.
|
||||
*
|
||||
* @return true if connection is enabled, false otherwise
|
||||
*/
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection to be enabled or not.
|
||||
*
|
||||
* @param enabled value to set
|
||||
*/
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,527 @@
|
||||
/*
|
||||
* 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.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
|
||||
import com.google.gdata.data.*;
|
||||
import com.google.gdata.data.extensions.*;
|
||||
import com.google.gdata.data.contacts.ContactEntry; //disambiguation
|
||||
|
||||
/**
|
||||
* Google Contacts entry implementation.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleContactsEntryImpl
|
||||
implements GoogleContactsEntry
|
||||
{
|
||||
/**
|
||||
* Google Talk protocol type.
|
||||
*/
|
||||
private static final String GOOGLETALK_PROTOCOL =
|
||||
"http://schemas.google.com/g/2005#GOOGLE_TALK";
|
||||
|
||||
/**
|
||||
* Google Talk protocol type.
|
||||
*/
|
||||
private static final String YAHOO_PROTOCOL =
|
||||
"http://schemas.google.com/g/2005#YAHOO";
|
||||
|
||||
/**
|
||||
* Google Talk protocol type.
|
||||
*/
|
||||
private static final String AIM_PROTOCOL =
|
||||
"http://schemas.google.com/g/2005#AIM";
|
||||
|
||||
/**
|
||||
* Google Talk protocol type.
|
||||
*/
|
||||
private static final String MSN_PROTOCOL =
|
||||
"http://schemas.google.com/g/2005#MSN";
|
||||
|
||||
/**
|
||||
* Google Talk protocol type.
|
||||
*/
|
||||
private static final String ICQ_PROTOCOL =
|
||||
"http://schemas.google.com/g/2005#ICQ";
|
||||
|
||||
/**
|
||||
* Google Talk protocol type.
|
||||
*/
|
||||
private static final String JABBER_PROTOCOL =
|
||||
"http://schemas.google.com/g/2005#JABBER";
|
||||
|
||||
/**
|
||||
* Full name.
|
||||
*/
|
||||
private String fullName = null;
|
||||
|
||||
/**
|
||||
* Family name.
|
||||
*/
|
||||
private String familyName = null;
|
||||
|
||||
/**
|
||||
* Given name.
|
||||
*/
|
||||
private String givenName = null;
|
||||
|
||||
/**
|
||||
* Home mails list.
|
||||
*/
|
||||
private final List<String> homeMails = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Work mails list.
|
||||
*/
|
||||
private final List<String> workMails = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Home phones list.
|
||||
*/
|
||||
private final List<String> homePhones = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Work phones list.
|
||||
*/
|
||||
private final List<String> workPhones = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Mobile phones list.
|
||||
*/
|
||||
private final List<String> mobilePhones = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* IM addresses map.
|
||||
*/
|
||||
private final Map<String, IMProtocol> imAddresses =
|
||||
new HashMap<String, IMProtocol>();
|
||||
|
||||
/**
|
||||
* Photo link.
|
||||
*/
|
||||
private String photoLink = null;
|
||||
|
||||
/**
|
||||
* Google photo link.
|
||||
*/
|
||||
private Link googlePhotoLink = null;
|
||||
|
||||
/**
|
||||
* Get the full name.
|
||||
*
|
||||
* @return full name
|
||||
*/
|
||||
public String getFullName()
|
||||
{
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the family name.
|
||||
*
|
||||
* @return family name
|
||||
*/
|
||||
public String getFamilyName()
|
||||
{
|
||||
return familyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given name.
|
||||
*
|
||||
* @return given name
|
||||
*/
|
||||
public String getGivenName()
|
||||
{
|
||||
return givenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mails.
|
||||
*
|
||||
* @return mails
|
||||
*/
|
||||
public List<String> getAllMails()
|
||||
{
|
||||
List<String> mails = new ArrayList<String>();
|
||||
|
||||
for(String mail : homeMails)
|
||||
{
|
||||
mails.add(mail);
|
||||
}
|
||||
|
||||
for(String mail : workMails)
|
||||
{
|
||||
mails.add(mail);
|
||||
}
|
||||
|
||||
return mails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a home mail address.
|
||||
*
|
||||
* @param mail the mail address
|
||||
*/
|
||||
public void addHomeMail(String mail)
|
||||
{
|
||||
homeMails.add(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns home mail addresses.
|
||||
*
|
||||
* @return home mail addresses
|
||||
*/
|
||||
public List<String> getHomeMails()
|
||||
{
|
||||
return homeMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a work mail address.
|
||||
*
|
||||
* @param mail the mail address
|
||||
*/
|
||||
public void addWorkMails(String mail)
|
||||
{
|
||||
workMails.add(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns work mail addresses.
|
||||
*
|
||||
* @return work mail addresses
|
||||
*/
|
||||
public List<String> getWorkMails()
|
||||
{
|
||||
return workMails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns telephone numbers.
|
||||
*
|
||||
* @return telephone numbers
|
||||
*/
|
||||
public List<String> getAllPhones()
|
||||
{
|
||||
List<String> phones = new ArrayList<String>();
|
||||
|
||||
for(String phone : mobilePhones)
|
||||
{
|
||||
phones.add(phone);
|
||||
}
|
||||
|
||||
for(String phone : homePhones)
|
||||
{
|
||||
phones.add(phone);
|
||||
}
|
||||
|
||||
for(String phone : workPhones)
|
||||
{
|
||||
phones.add(phone);
|
||||
}
|
||||
|
||||
return phones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a work telephone number.
|
||||
*
|
||||
* @param telephoneNumber the work telephone number
|
||||
*/
|
||||
public void addWorkPhone(String telephoneNumber)
|
||||
{
|
||||
workPhones.add(telephoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns work telephone numbers.
|
||||
*
|
||||
* @return work telephone numbers
|
||||
*/
|
||||
public List<String> getWorkPhones()
|
||||
{
|
||||
return workPhones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mobile telephone numbers.
|
||||
*
|
||||
* @param telephoneNumber the mobile telephone number
|
||||
*/
|
||||
public void addMobilePhone(String telephoneNumber)
|
||||
{
|
||||
mobilePhones.add(telephoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mobile telephone numbers.
|
||||
*
|
||||
* @return mobile telephone numbers
|
||||
*/
|
||||
public List<String> getMobilePhones()
|
||||
{
|
||||
return mobilePhones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a home telephone numbers.
|
||||
*
|
||||
* @param telephoneNumber the home telephone number
|
||||
*/
|
||||
public void addHomePhone(String telephoneNumber)
|
||||
{
|
||||
homePhones.add(telephoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns home telephone numbers.
|
||||
*
|
||||
* @return home telephone numbers
|
||||
*/
|
||||
public List<String> getHomePhones()
|
||||
{
|
||||
return homePhones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the photo full URI.
|
||||
*
|
||||
* @return the photo URI or null if there isn't
|
||||
*/
|
||||
public String getPhoto()
|
||||
{
|
||||
return photoLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Google photo full URI.
|
||||
*
|
||||
* @return the Google photo URI or null if there isn't
|
||||
*/
|
||||
public Link getPhotoLink()
|
||||
{
|
||||
return googlePhotoLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns IM addresses.
|
||||
*
|
||||
* @return IM addresses
|
||||
*/
|
||||
public Map<String, IMProtocol> getIMAddresses()
|
||||
{
|
||||
return imAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an IM address.
|
||||
*
|
||||
* @param imAddress IM address
|
||||
*/
|
||||
public void addIMAddress(String imAddress, IMProtocol protocol)
|
||||
{
|
||||
imAddresses.put(imAddress, protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set information.
|
||||
*
|
||||
* @param contact Google Contacts's <tt>ContactEntry</tt>
|
||||
*/
|
||||
public void setField(ContactEntry contact)
|
||||
{
|
||||
Name name = contact.getName();
|
||||
|
||||
if(name != null)
|
||||
{
|
||||
if(name.hasFullName())
|
||||
{
|
||||
fullName = name.getFullName().getValue();
|
||||
}
|
||||
|
||||
if(name.hasFamilyName())
|
||||
{
|
||||
familyName = name.getFamilyName().getValue();
|
||||
}
|
||||
|
||||
if(name.hasGivenName())
|
||||
{
|
||||
givenName = name.getGivenName().getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
photoLink = contact.getContactPhotoLink().getHref();
|
||||
googlePhotoLink = contact.getContactPhotoLink();
|
||||
|
||||
for(Email mail : contact.getEmailAddresses())
|
||||
{
|
||||
if(mail.getRel().contains("#home"))
|
||||
{
|
||||
homeMails.add(mail.getAddress());
|
||||
}
|
||||
else if(mail.getRel().contains("#work"))
|
||||
{
|
||||
workMails.add(mail.getAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
homeMails.add(mail.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
for(PhoneNumber phone : contact.getPhoneNumbers())
|
||||
{
|
||||
if(phone.getRel().contains("#work"))
|
||||
{
|
||||
workPhones.add(phone.getPhoneNumber());
|
||||
}
|
||||
else if(phone.getRel().contains("#mobile"))
|
||||
{
|
||||
mobilePhones.add(phone.getPhoneNumber());
|
||||
}
|
||||
else if(phone.getRel().contains("#home"))
|
||||
{
|
||||
homePhones.add(phone.getPhoneNumber());
|
||||
}
|
||||
else
|
||||
{
|
||||
homePhones.add(phone.getPhoneNumber());
|
||||
}
|
||||
}
|
||||
|
||||
for(Im imAddress : contact.getImAddresses())
|
||||
{
|
||||
String protocol = imAddress.getProtocol();
|
||||
IMProtocol proto;
|
||||
|
||||
if(protocol.equals(GOOGLETALK_PROTOCOL))
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.GOOGLETALK;
|
||||
}
|
||||
else if(protocol.equals(YAHOO_PROTOCOL))
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.YAHOO;
|
||||
}
|
||||
else if(protocol.equals(AIM_PROTOCOL))
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.AIM;
|
||||
}
|
||||
else if(protocol.equals(MSN_PROTOCOL))
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.MSN;
|
||||
}
|
||||
else if(protocol.equals(ICQ_PROTOCOL))
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.ICQ;
|
||||
}
|
||||
else if(protocol.equals(JABBER_PROTOCOL))
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.JABBER;
|
||||
}
|
||||
else
|
||||
{
|
||||
proto = GoogleContactsEntry.IMProtocol.OTHER;
|
||||
}
|
||||
|
||||
imAddresses.put(imAddress.getAddress(), proto);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation of the <tt>GoogleContactsEntry</tt>.
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
if(fullName != null)
|
||||
{
|
||||
buffer.append("Full name: ");
|
||||
buffer.append(fullName);
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
if(givenName != null || familyName != null)
|
||||
{
|
||||
buffer.append("Display name: ");
|
||||
buffer.append(givenName != null ? givenName : "");
|
||||
buffer.append(" ");
|
||||
buffer.append(familyName != null ? familyName : "");
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
if(getAllMails().size() > 0)
|
||||
{
|
||||
buffer.append("Mail:\n");
|
||||
|
||||
for(String mail : getAllMails())
|
||||
{
|
||||
buffer.append("\t");
|
||||
buffer.append(mail);
|
||||
buffer.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(workPhones.size() > 0)
|
||||
{
|
||||
buffer.append("Work phones:\n");
|
||||
for(String phone : workPhones)
|
||||
{
|
||||
buffer.append("\t");
|
||||
buffer.append(phone);
|
||||
buffer.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(homePhones.size() > 0)
|
||||
{
|
||||
buffer.append("Home phones:\n");
|
||||
for(String phone : homePhones)
|
||||
{
|
||||
buffer.append("\t");
|
||||
buffer.append(phone);
|
||||
buffer.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(mobilePhones.size() > 0)
|
||||
{
|
||||
buffer.append("Mobile phones:\n");
|
||||
for(String phone : mobilePhones)
|
||||
{
|
||||
buffer.append("\t");
|
||||
buffer.append(phone);
|
||||
buffer.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(imAddresses.size() > 0)
|
||||
{
|
||||
buffer.append("IM addresses:\n");
|
||||
|
||||
for(Map.Entry<String, IMProtocol> entry : imAddresses.entrySet())
|
||||
{
|
||||
buffer.append("\t");
|
||||
buffer.append(entry.getKey());
|
||||
buffer.append(" (");
|
||||
buffer.append(entry.getValue());
|
||||
buffer.append(")\n");
|
||||
}
|
||||
}
|
||||
|
||||
buffer.append("\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,421 @@
|
||||
/*
|
||||
* 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.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
import net.java.sip.communicator.service.contactsource.*;
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
|
||||
/**
|
||||
* Implements <tt>ContactQuery</tt> for Google Contacts.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleContactsQuery
|
||||
extends AsyncContactQuery<GoogleContactsSourceService>
|
||||
{
|
||||
/**
|
||||
* Maximum results for Google Contacts query.
|
||||
*/
|
||||
public static final int GOOGLECONTACTS_MAX_RESULTS = 20;
|
||||
|
||||
/**
|
||||
* Maximum number of results for this instance.
|
||||
*/
|
||||
private final int count;
|
||||
|
||||
/**
|
||||
* The Google query.
|
||||
*/
|
||||
private GoogleQuery gQuery = null;
|
||||
|
||||
/**
|
||||
* Initializes a new <tt>GoogleContactsQuery</tt> instance which is to
|
||||
* perform a specific <tt>query</tt> on behalf of a specific
|
||||
* <tt>contactSource</tt>.
|
||||
*
|
||||
* @param contactSource the <tt>ContactSourceService</tt> which is to
|
||||
* perform the new <tt>ContactQuery</tt> instance
|
||||
* @param query the <tt>Pattern</tt> for which <tt>contactSource</tt> is
|
||||
* being queried
|
||||
* @param count maximum number of results
|
||||
*/
|
||||
protected GoogleContactsQuery(GoogleContactsSourceService
|
||||
contactSource, Pattern query, int count)
|
||||
{
|
||||
super(contactSource, query);
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a <tt>String</tt> phone number by converting alpha characters
|
||||
* to their respective digits on a keypad and then stripping non-digit
|
||||
* characters.
|
||||
*
|
||||
* @param phoneNumber a <tt>String</tt> which represents a phone number to
|
||||
* normalize
|
||||
* @return a <tt>String</tt> which is a normalized form of the specified
|
||||
* <tt>phoneNumber</tt>
|
||||
*/
|
||||
protected String normalizePhoneNumber(String phoneNumber)
|
||||
{
|
||||
PhoneNumberI18nService phoneNumberI18nService
|
||||
= GoogleContactsActivator.getPhoneNumberI18nService();
|
||||
|
||||
return
|
||||
(phoneNumberI18nService == null)
|
||||
? phoneNumber
|
||||
: phoneNumberI18nService.normalize(phoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a specific <tt>String</tt> phone number matches the
|
||||
* {@link #query} of this <tt>AsyncContactQuery</tt>.
|
||||
*
|
||||
* @param phoneNumber the <tt>String</tt> which represents the phone number
|
||||
* to match to the <tt>query</tt> of this <tt>AsyncContactQuery</tt>
|
||||
* @return <tt>true</tt> if the specified <tt>phoneNumber</tt> matches the
|
||||
* <tt>query</tt> of this <tt>AsyncContactQuery</tt>; otherwise,
|
||||
* <tt>false</tt>
|
||||
*/
|
||||
protected boolean phoneNumberMatches(String phoneNumber)
|
||||
{
|
||||
/*
|
||||
* PhoneNumberI18nService implements functionality to aid the parsing,
|
||||
* formatting and validation of international phone numbers so attempt to
|
||||
* use it to determine whether the specified phoneNumber matches the
|
||||
* query. For example, check whether the normalized phoneNumber matches
|
||||
* the query.
|
||||
*/
|
||||
|
||||
PhoneNumberI18nService phoneNumberI18nService
|
||||
= GoogleContactsActivator.getPhoneNumberI18nService();
|
||||
boolean phoneNumberMatches = false;
|
||||
|
||||
if (phoneNumberI18nService != null)
|
||||
{
|
||||
if (query
|
||||
.matcher(phoneNumberI18nService.normalize(phoneNumber))
|
||||
.find())
|
||||
{
|
||||
phoneNumberMatches = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The fact that the normalized form of the phoneNumber doesn't
|
||||
* match the query doesn't mean that, for example, it doesn't
|
||||
* match the normalized form of the query. The latter, though,
|
||||
* requires the query to look like a phone number as well. In
|
||||
* order to not accidentally start matching all queries to phone
|
||||
* numbers, it seems justified to normalize the query only when
|
||||
* it is a phone number, not whenever it looks like a piece of a
|
||||
* phone number.
|
||||
*/
|
||||
|
||||
String phoneNumberQuery = getPhoneNumberQuery();
|
||||
|
||||
if ((phoneNumberQuery != null)
|
||||
&& (phoneNumberQuery.length() != 0))
|
||||
{
|
||||
try
|
||||
{
|
||||
phoneNumberMatches
|
||||
= phoneNumberI18nService.phoneNumbersMatch(
|
||||
phoneNumberQuery,
|
||||
phoneNumber);
|
||||
}
|
||||
catch (IllegalArgumentException iaex)
|
||||
{
|
||||
/*
|
||||
* Ignore it, phoneNumberMatches will remain equal to
|
||||
* false.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return phoneNumberMatches;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a <tt>SourceContact</tt> from a <tt>GoogleContactsEntry</tt>.
|
||||
*
|
||||
* @param entry <tt>GoogleContactsEntry</tt>
|
||||
*/
|
||||
private void onGoogleContactsEntry(GoogleContactsEntry entry)
|
||||
{
|
||||
String displayName = entry.getFullName();
|
||||
if(displayName == null || displayName.length() == 0)
|
||||
{
|
||||
if((entry.getGivenName() == null ||
|
||||
entry.getGivenName().length() == 0) &&
|
||||
(entry.getFamilyName() == null ||
|
||||
entry.getFamilyName().length() == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
displayName = entry.getGivenName() + " " +
|
||||
entry.getFamilyName();
|
||||
}
|
||||
|
||||
List<ContactDetail> contactDetails = getContactDetails(entry);
|
||||
|
||||
if (!contactDetails.isEmpty())
|
||||
{
|
||||
GenericSourceContact sourceContact
|
||||
= new GenericSourceContact(
|
||||
getContactSource(),
|
||||
displayName,
|
||||
contactDetails);
|
||||
|
||||
try
|
||||
{
|
||||
byte img[] = GoogleContactsServiceImpl.downloadPhoto(
|
||||
((GoogleContactsEntryImpl)entry).getPhotoLink(),
|
||||
getContactSource().getConnection().
|
||||
getGoogleService());
|
||||
sourceContact.setImage(img);
|
||||
}
|
||||
catch (OutOfMemoryError oome)
|
||||
{
|
||||
// Ignore it, the image is not vital.
|
||||
}
|
||||
|
||||
addQueryResult(sourceContact);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs this <tt>AsyncContactQuery</tt> in a background <tt>Thread</tt>.
|
||||
*
|
||||
* @see AsyncContactQuery#run()
|
||||
*/
|
||||
@Override
|
||||
protected void run()
|
||||
{
|
||||
GoogleContactsServiceImpl service = (GoogleContactsServiceImpl)
|
||||
GoogleContactsActivator.getGoogleContactsService();
|
||||
gQuery = new GoogleQuery(query);
|
||||
|
||||
GoogleContactsConnection cnx = getContactSource().getConnection();
|
||||
|
||||
if(cnx == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
service.searchContact(
|
||||
cnx,
|
||||
gQuery,
|
||||
count,
|
||||
new GoogleEntryCallback()
|
||||
{
|
||||
public void callback(GoogleContactsEntry entry)
|
||||
{
|
||||
onGoogleContactsEntry(entry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <tt>contactDetails</tt> to be set on a <tt>SourceContact</tt>.
|
||||
*
|
||||
* @param entry <tt>GoogleContactsEntry</tt>
|
||||
* @return the <tt>contactDetails</tt> to be set on a <tt>SourceContact</tt>
|
||||
*/
|
||||
private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
|
||||
{
|
||||
List<ContactDetail> ret = new LinkedList<ContactDetail>();
|
||||
List<String> homeMails = entry.getHomeMails();
|
||||
List<String> workMails = entry.getWorkMails();
|
||||
List<String> mobilePhones = entry.getMobilePhones();
|
||||
List<String> homePhones = entry.getHomePhones();
|
||||
List<String> workPhones = entry.getWorkPhones();
|
||||
Map<String, GoogleContactsEntry.IMProtocol> ims =
|
||||
entry.getIMAddresses();
|
||||
ContactDetail detail = null;
|
||||
|
||||
for(String mail : homeMails)
|
||||
{
|
||||
detail = new ContactDetail(mail, ContactDetail.CATEGORY_EMAIL,
|
||||
new String[]{ContactDetail.LABEL_HOME});
|
||||
ret.add(detail);
|
||||
}
|
||||
for(String mail : workMails)
|
||||
{
|
||||
detail = new ContactDetail(mail, ContactDetail.CATEGORY_EMAIL,
|
||||
new String[]{ContactDetail.LABEL_WORK});
|
||||
ret.add(detail);
|
||||
}
|
||||
|
||||
for(String homePhone : homePhones)
|
||||
{
|
||||
List<Class<? extends OperationSet>> supportedOpSets
|
||||
= new ArrayList<Class<? extends OperationSet>>(1);
|
||||
|
||||
supportedOpSets.add(OperationSetBasicTelephony.class);
|
||||
homePhone = normalizePhoneNumber(homePhone);
|
||||
detail = new ContactDetail(homePhone,
|
||||
ContactDetail.CATEGORY_PHONE,
|
||||
new String[]{ContactDetail.LABEL_HOME});
|
||||
detail.setSupportedOpSets(supportedOpSets);
|
||||
ret.add(detail);
|
||||
}
|
||||
|
||||
for(String workPhone : workPhones)
|
||||
{
|
||||
List<Class<? extends OperationSet>> supportedOpSets
|
||||
= new ArrayList<Class<? extends OperationSet>>(1);
|
||||
|
||||
supportedOpSets.add(OperationSetBasicTelephony.class);
|
||||
workPhone = normalizePhoneNumber(workPhone);
|
||||
detail = new ContactDetail(workPhone,
|
||||
ContactDetail.CATEGORY_PHONE,
|
||||
new String[]{ContactDetail.LABEL_WORK});
|
||||
detail.setSupportedOpSets(supportedOpSets);
|
||||
ret.add(detail);
|
||||
}
|
||||
|
||||
for(String mobilePhone : mobilePhones)
|
||||
{
|
||||
List<Class<? extends OperationSet>> supportedOpSets
|
||||
= new ArrayList<Class<? extends OperationSet>>(1);
|
||||
|
||||
supportedOpSets.add(OperationSetBasicTelephony.class);
|
||||
mobilePhone = normalizePhoneNumber(mobilePhone);
|
||||
detail = new ContactDetail(mobilePhone,
|
||||
ContactDetail.CATEGORY_PHONE,
|
||||
new String[]{ContactDetail.LABEL_MOBILE});
|
||||
detail.setSupportedOpSets(supportedOpSets);
|
||||
ret.add(detail);
|
||||
}
|
||||
|
||||
for(Map.Entry<String, GoogleContactsEntry.IMProtocol> im :
|
||||
ims.entrySet())
|
||||
{
|
||||
if(im.getValue() != GoogleContactsEntry.IMProtocol.OTHER)
|
||||
{
|
||||
detail = new ContactDetail(im.getKey(),
|
||||
ContactDetail.CATEGORY_INSTANT_MESSAGING,
|
||||
new String[]{im.getValue().toString()});
|
||||
|
||||
setIMCapabilities(detail, im.getValue());
|
||||
ret.add(detail);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the IM capabilities of a specific <tt>ContactDetail</tt> (e.g.
|
||||
* <tt>supportedOpSets</tt>).
|
||||
*
|
||||
* @param contactDetail the <tt>ContactDetail</tt> to set the capabilities
|
||||
* of
|
||||
* @param protocol protocol
|
||||
* @return <tt>contactDetail</tt>
|
||||
*/
|
||||
private ContactDetail setIMCapabilities(
|
||||
ContactDetail contactDetail,
|
||||
GoogleContactsEntry.IMProtocol protocol)
|
||||
{
|
||||
List<Class<? extends OperationSet>> supportedOpSets
|
||||
= new LinkedList<Class<? extends OperationSet>>();
|
||||
Map<Class<? extends OperationSet>, String> preferredProtocols
|
||||
= new HashMap<Class<? extends OperationSet>, String>();
|
||||
|
||||
switch (protocol)
|
||||
{
|
||||
case GOOGLETALK:
|
||||
supportedOpSets.add(OperationSetBasicInstantMessaging.class);
|
||||
preferredProtocols.put(
|
||||
OperationSetBasicInstantMessaging.class,
|
||||
ProtocolNames.AIM);
|
||||
break;
|
||||
case ICQ:
|
||||
supportedOpSets.add(OperationSetBasicInstantMessaging.class);
|
||||
preferredProtocols.put(
|
||||
OperationSetBasicInstantMessaging.class,
|
||||
ProtocolNames.ICQ);
|
||||
break;
|
||||
case JABBER:
|
||||
supportedOpSets.add(OperationSetBasicInstantMessaging.class);
|
||||
preferredProtocols.put(
|
||||
OperationSetBasicInstantMessaging.class,
|
||||
ProtocolNames.JABBER);
|
||||
supportedOpSets.add(OperationSetBasicTelephony.class);
|
||||
preferredProtocols.put(
|
||||
OperationSetBasicTelephony.class,
|
||||
ProtocolNames.JABBER);
|
||||
break;
|
||||
case MSN:
|
||||
supportedOpSets.add(OperationSetBasicInstantMessaging.class);
|
||||
preferredProtocols.put(
|
||||
OperationSetBasicInstantMessaging.class,
|
||||
ProtocolNames.MSN);
|
||||
break;
|
||||
case YAHOO:
|
||||
supportedOpSets.add(OperationSetBasicInstantMessaging.class);
|
||||
preferredProtocols.put(
|
||||
OperationSetBasicInstantMessaging.class,
|
||||
ProtocolNames.YAHOO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
contactDetail.setSupportedOpSets(supportedOpSets);
|
||||
|
||||
if (!preferredProtocols.isEmpty())
|
||||
contactDetail.setPreferredProtocols(preferredProtocols);
|
||||
|
||||
return contactDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this <tt>GoogleContactsQuery</tt> that it has stopped performing
|
||||
* in the associated background <tt>Thread</tt>.
|
||||
*
|
||||
* @param completed <tt>true</tt> if this <tt>ContactQuery</tt> has
|
||||
* successfully completed, <tt>false</tt> if an error has been encountered
|
||||
* during its execution
|
||||
* @see AsyncContactQuery#stopped(boolean)
|
||||
*/
|
||||
@Override
|
||||
protected void stopped(boolean completed)
|
||||
{
|
||||
try
|
||||
{
|
||||
super.stopped(completed);
|
||||
}
|
||||
finally
|
||||
{
|
||||
getContactSource().stopped(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels this <tt>ContactQuery</tt>.
|
||||
*
|
||||
* @see ContactQuery#cancel()
|
||||
*/
|
||||
@Override
|
||||
public void cancel()
|
||||
{
|
||||
if(gQuery != null)
|
||||
{
|
||||
gQuery.cancel();
|
||||
}
|
||||
super.cancel();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
import net.java.sip.communicator.service.contactsource.*;
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Google Contacts connection.
|
||||
*/
|
||||
private GoogleContactsConnection cnx = null;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries this search source for the given <tt>searchPattern</tt>.
|
||||
*
|
||||
* @param queryPattern the pattern to search for
|
||||
* @return the created query
|
||||
*/
|
||||
public ContactQuery queryContactSource(Pattern queryPattern)
|
||||
{
|
||||
return queryContactSource(queryPattern,
|
||||
GoogleContactsQuery.GOOGLECONTACTS_MAX_RESULTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries this search source 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 queryContactSource(Pattern queryPattern, int count)
|
||||
{
|
||||
GoogleContactsQuery query = new GoogleContactsQuery(this, queryPattern,
|
||||
count);
|
||||
|
||||
synchronized (queries)
|
||||
{
|
||||
queries.add(query);
|
||||
}
|
||||
|
||||
boolean hasStarted = false;
|
||||
|
||||
try
|
||||
{
|
||||
query.start();
|
||||
hasStarted = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!hasStarted)
|
||||
{
|
||||
synchronized (queries)
|
||||
{
|
||||
if (queries.remove(query))
|
||||
queries.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
for(SRVRecord srv : srvRecords)
|
||||
{
|
||||
if(srv.getTarget().endsWith("google.com") ||
|
||||
srv.getTarget().endsWith("google.com."))
|
||||
{
|
||||
isGoogleAppsOrGmail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isGoogleAppsOrGmail)
|
||||
{
|
||||
if(cnx == null)
|
||||
{
|
||||
cnx = new GoogleContactsConnectionImpl(login, password);
|
||||
}
|
||||
}
|
||||
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 the identifier of this contact source. Some of the common
|
||||
* identifiers are defined here (For example the CALL_HISTORY identifier
|
||||
* should be returned by all call history implementations of this interface)
|
||||
* @return the identifier of this contact source
|
||||
*/
|
||||
public String getIdentifier()
|
||||
{
|
||||
return "GoogleContacts";
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries this search source for the given <tt>queryString</tt>.
|
||||
* @param query the string to search for
|
||||
* @return the created query
|
||||
*/
|
||||
public ContactQuery queryContactSource(String query)
|
||||
{
|
||||
return queryContactSource(
|
||||
Pattern.compile(query),
|
||||
GoogleContactsQuery.GOOGLECONTACTS_MAX_RESULTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries this search source 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 queryContactSource(String query, int contactCount)
|
||||
{
|
||||
return queryContactSource(Pattern.compile(query), contactCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* 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.configform;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.util.swing.*;
|
||||
import net.java.sip.communicator.impl.googlecontacts.*;
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
|
||||
/**
|
||||
* The page with hostname/port/encryption fields
|
||||
*
|
||||
* @author Sebastien Mazy
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class AccountSettingsForm
|
||||
extends SIPCommDialog
|
||||
implements ActionListener
|
||||
{
|
||||
/**
|
||||
* Serial version UID.
|
||||
*/
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
/**
|
||||
* component holding the name
|
||||
*/
|
||||
private JTextField nameField;
|
||||
|
||||
/**
|
||||
* the component holding the password
|
||||
*/
|
||||
private JPasswordField passwordField;
|
||||
|
||||
/**
|
||||
* Save button.
|
||||
*/
|
||||
private JButton saveBtn = new JButton(
|
||||
Resources.getString("impl.googlecontacts.SAVE"));
|
||||
|
||||
/**
|
||||
* Cancel button.
|
||||
*/
|
||||
private JButton cancelBtn = new JButton(
|
||||
Resources.getString("impl.googlecontacts.CANCEL"));
|
||||
|
||||
/**
|
||||
* Return code.
|
||||
*/
|
||||
private int retCode = 0;
|
||||
|
||||
/**
|
||||
* The Google Contacts connection.
|
||||
*/
|
||||
private GoogleContactsConnection cnx = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public AccountSettingsForm()
|
||||
{
|
||||
this.setTitle(Resources.getString(
|
||||
"impl.googlecontacts.CONFIG_FORM_TITLE"));
|
||||
getContentPane().add(getContentPanel());
|
||||
setMinimumSize(new Dimension(400, 200));
|
||||
setSize(new Dimension(400, 400));
|
||||
setPreferredSize(new Dimension(400, 200));
|
||||
pack();
|
||||
}
|
||||
|
||||
/**
|
||||
* the panel to display in the card layout of the wizard
|
||||
*
|
||||
* @return this page's panel
|
||||
*/
|
||||
public JPanel getContentPanel()
|
||||
{
|
||||
JPanel contentPanel = new TransparentPanel(new BorderLayout());
|
||||
JPanel mainPanel = new TransparentPanel();
|
||||
JPanel basePanel = new TransparentPanel(new GridBagLayout());
|
||||
JPanel btnPanel = new TransparentPanel(new FlowLayout(
|
||||
FlowLayout.RIGHT));
|
||||
BoxLayout boxLayout = new BoxLayout(mainPanel, BoxLayout.Y_AXIS);
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
|
||||
/* name text field */
|
||||
JLabel nameLabel = new JLabel(
|
||||
Resources.getString("impl.googlecontacts.ACCOUNT_NAME"));
|
||||
this.nameField = new JTextField();
|
||||
nameLabel.setLabelFor(nameField);
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
c.weightx = 0;
|
||||
c.weighty = 0;
|
||||
c.gridwidth = 1;
|
||||
c.insets = new Insets(2, 50, 0, 5);
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.anchor = GridBagConstraints.LINE_START;
|
||||
basePanel.add(nameLabel, c);
|
||||
c.gridx = 1;
|
||||
c.gridy = 0;
|
||||
c.weightx = 1;
|
||||
c.weighty = 0;
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
c.insets = new Insets(2, 5, 0, 50);
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.anchor = GridBagConstraints.LINE_END;
|
||||
basePanel.add(nameField, c);
|
||||
JLabel nameExampleLabel = new JLabel("myaccount@gmail.com");
|
||||
nameExampleLabel.setForeground(Color.GRAY);
|
||||
nameExampleLabel.setFont(nameExampleLabel.getFont().deriveFont(8));
|
||||
c.gridx = 1;
|
||||
c.gridy = 1;
|
||||
c.weightx = 1;
|
||||
c.weighty = 0;
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
c.insets = new Insets(0, 13, 2, 0);
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.anchor = GridBagConstraints.LINE_START;
|
||||
basePanel.add(nameExampleLabel, c);
|
||||
|
||||
JLabel passwordLabel = new JLabel(
|
||||
Resources.getString("impl.googlecontacts.PASSWORD"));
|
||||
this.passwordField = new JPasswordField();
|
||||
nameLabel.setLabelFor(passwordField);
|
||||
c.gridx = 0;
|
||||
c.gridy = 2;
|
||||
c.weightx = 0;
|
||||
c.weighty = 0;
|
||||
c.gridwidth = 1;
|
||||
c.insets = new Insets(2, 50, 0, 5);
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.anchor = GridBagConstraints.LINE_START;
|
||||
basePanel.add(passwordLabel, c);
|
||||
c.gridx = 1;
|
||||
c.gridy = 2;
|
||||
c.weightx = 1;
|
||||
c.weighty = 0;
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
c.insets = new Insets(2, 5, 0, 50);
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.anchor = GridBagConstraints.LINE_END;
|
||||
basePanel.add(passwordField, c);
|
||||
|
||||
mainPanel.setLayout(boxLayout);
|
||||
mainPanel.add(basePanel);
|
||||
|
||||
/* listeners */
|
||||
this.nameField.addActionListener(this);
|
||||
this.passwordField.addActionListener(this);
|
||||
this.saveBtn.addActionListener(this);
|
||||
this.cancelBtn.addActionListener(this);
|
||||
|
||||
btnPanel.add(saveBtn);
|
||||
btnPanel.add(cancelBtn);
|
||||
|
||||
contentPanel.add(mainPanel, BorderLayout.CENTER);
|
||||
contentPanel.add(btnPanel, BorderLayout.SOUTH);
|
||||
|
||||
return contentPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the information.
|
||||
*
|
||||
* @param cnx connection
|
||||
*/
|
||||
public void loadData(GoogleContactsConnection cnx)
|
||||
{
|
||||
if(cnx != null)
|
||||
{
|
||||
this.nameField.setText(cnx.getLogin());
|
||||
this.passwordField.setText(cnx.getPassword());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.nameField.setText("");
|
||||
this.passwordField.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of actionPerformed.
|
||||
*
|
||||
* @param e the ActionEvent triggered
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Object src = e.getSource();
|
||||
|
||||
if(src == saveBtn)
|
||||
{
|
||||
String login = nameField.getText();
|
||||
String password = new String(passwordField.getPassword());
|
||||
|
||||
cnx = GoogleContactsActivator.getGoogleContactsService().
|
||||
getConnection(login, password);
|
||||
|
||||
if(cnx == null)
|
||||
{
|
||||
JOptionPane.showMessageDialog(
|
||||
this,
|
||||
Resources.getString(
|
||||
"impl.googlecontacts.WRONG_CREDENTIALS",
|
||||
new String[]{login}),
|
||||
Resources.getString(
|
||||
"impl.googlecontacts.WRONG_CREDENTIALS",
|
||||
new String[]{login}),
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
retCode = 1;
|
||||
dispose();
|
||||
}
|
||||
else if(src == cancelBtn)
|
||||
{
|
||||
retCode = 0;
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connection.
|
||||
*
|
||||
* @return GoogleContactsConnection
|
||||
*/
|
||||
public GoogleContactsConnection getConnection()
|
||||
{
|
||||
return cnx;
|
||||
}
|
||||
|
||||
/**
|
||||
* All functions implemented in this method will be invoked when user
|
||||
* presses the Escape key.
|
||||
*
|
||||
* @param escaped <tt>true</tt> if this dialog has been closed by pressing
|
||||
* the Esc key; otherwise, <tt>false</tt>
|
||||
*/
|
||||
protected void close(boolean escaped)
|
||||
{
|
||||
cancelBtn.doClick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the dialog and returns if the user has modified something (create
|
||||
* or modify entry).
|
||||
*
|
||||
* @return true if the user has modified something (create
|
||||
* or modify entry), false otherwise.
|
||||
*/
|
||||
public int showDialog()
|
||||
{
|
||||
retCode = 0;
|
||||
|
||||
cnx = null;
|
||||
setVisible(true);
|
||||
|
||||
// this will block until user click on save/cancel/press escape/close
|
||||
// the window
|
||||
setVisible(false);
|
||||
return retCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name field enable or not
|
||||
*
|
||||
* @param enable parameter to set
|
||||
*/
|
||||
public void setNameFieldEnabled(boolean enable)
|
||||
{
|
||||
this.nameField.setEnabled(enable);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* 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.configform;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import net.java.sip.communicator.util.*;
|
||||
import net.java.sip.communicator.util.swing.*;
|
||||
import net.java.sip.communicator.impl.googlecontacts.*;
|
||||
import net.java.sip.communicator.service.configuration.*;
|
||||
import net.java.sip.communicator.service.credentialsstorage.*;
|
||||
import net.java.sip.communicator.service.gui.*;
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
|
||||
/**
|
||||
* This ConfigurationForm shows the list of Google Contacts account and allow
|
||||
* users to manage them.
|
||||
*
|
||||
* @author Sebastien Mazy
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleContactsConfigForm
|
||||
extends TransparentPanel
|
||||
implements ConfigurationForm,
|
||||
ActionListener,
|
||||
ListSelectionListener
|
||||
|
||||
{
|
||||
/**
|
||||
* Serial version UID.
|
||||
*/
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
/**
|
||||
* The logger for this class.
|
||||
*/
|
||||
private static Logger logger = Logger.getLogger(
|
||||
GoogleContactsConfigForm.class);
|
||||
|
||||
/**
|
||||
* Opens the new directory registration wizard
|
||||
*/
|
||||
private JButton newButton = new JButton("+");
|
||||
|
||||
/**
|
||||
* Opens a directory modification dialog
|
||||
*/
|
||||
private JButton modifyButton = new JButton(
|
||||
Resources.getString("impl.googlecontacts.EDIT"));
|
||||
|
||||
/**
|
||||
* Pops a directory deletion confirmation dialog
|
||||
*/
|
||||
private JButton removeButton = new JButton("-");
|
||||
|
||||
/**
|
||||
* Displays the registered Google Contacts account.
|
||||
*/
|
||||
private JTable accountTable = new JTable();
|
||||
|
||||
/**
|
||||
* Contains the new/modify/remove buttons
|
||||
*/
|
||||
private TransparentPanel buttonsPanel
|
||||
= new TransparentPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
/**
|
||||
* Contains the directoryTable
|
||||
*/
|
||||
private JScrollPane scrollPane = new JScrollPane();
|
||||
|
||||
/**
|
||||
* Contains the buttonsPanel,
|
||||
*/
|
||||
private JPanel rightPanel = new TransparentPanel(new BorderLayout());
|
||||
|
||||
/**
|
||||
* Contains listPanel and rightPanel
|
||||
*/
|
||||
private JPanel mainPanel = this;
|
||||
|
||||
/**
|
||||
* Model for the directoryTable
|
||||
*/
|
||||
private GoogleContactsTableModel tableModel =
|
||||
new GoogleContactsTableModel();
|
||||
|
||||
/**
|
||||
* Settings form.
|
||||
*/
|
||||
private final AccountSettingsForm settingsForm =
|
||||
new AccountSettingsForm();
|
||||
|
||||
/**
|
||||
* Path where to store the account settings
|
||||
*/
|
||||
private final static String CONFIGURATION_PATH =
|
||||
"net.java.sip.communicator.impl.googlecontacts";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public GoogleContactsConfigForm()
|
||||
{
|
||||
super(new BorderLayout());
|
||||
logger.trace("GoogleContacts configuration form.");
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a connection.
|
||||
*
|
||||
* @param cnx connection to save
|
||||
*/
|
||||
private void removeConfig(GoogleContactsConnection cnx)
|
||||
{
|
||||
ConfigurationService configService =
|
||||
GoogleContactsActivator.getConfigService();
|
||||
configService.removeProperty(CONFIGURATION_PATH + ".acc" +
|
||||
Math.abs(cnx.getLogin().hashCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save configuration.
|
||||
*
|
||||
* @param cnx connection to save
|
||||
*/
|
||||
private void saveConfig(GoogleContactsConnection cnx)
|
||||
{
|
||||
ConfigurationService configService =
|
||||
GoogleContactsActivator.getConfigService();
|
||||
CredentialsStorageService credentialsService =
|
||||
GoogleContactsActivator.getCredentialsService();
|
||||
String login = cnx.getLogin();
|
||||
String path = CONFIGURATION_PATH + ".acc" + Math.abs(login.hashCode());
|
||||
|
||||
configService.setProperty(
|
||||
path,
|
||||
login);
|
||||
configService.setProperty(
|
||||
path + ".account",
|
||||
login);
|
||||
configService.setProperty(
|
||||
path + ".enabled",
|
||||
((GoogleContactsConnectionImpl)cnx).isEnabled());
|
||||
credentialsService.storePassword(path, cnx.getPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits the swing components
|
||||
*/
|
||||
private void initComponents()
|
||||
{
|
||||
modifyButton.setEnabled(false);
|
||||
removeButton.setEnabled(false);
|
||||
|
||||
newButton.setSize(newButton.getMinimumSize());
|
||||
modifyButton.setSize(modifyButton.getMinimumSize());
|
||||
removeButton.setSize(removeButton.getMinimumSize());
|
||||
|
||||
accountTable.setRowHeight(22);
|
||||
accountTable.setSelectionMode(
|
||||
ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
accountTable.setShowHorizontalLines(false);
|
||||
accountTable.setShowVerticalLines(false);
|
||||
accountTable.setModel(tableModel);
|
||||
accountTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||
accountTable.addMouseListener(new MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
if(e.getClickCount() > 1)
|
||||
{
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
settingsForm.setModal(true);
|
||||
|
||||
/* consistency with the accounts config form */
|
||||
rightPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
rightPanel.add(buttonsPanel, BorderLayout.NORTH);
|
||||
|
||||
scrollPane.getViewport().add(accountTable);
|
||||
mainPanel.add(scrollPane, BorderLayout.CENTER);
|
||||
mainPanel.add(rightPanel, BorderLayout.SOUTH);
|
||||
|
||||
mainPanel.setPreferredSize(new Dimension(500, 400));
|
||||
|
||||
buttonsPanel.add(newButton);
|
||||
buttonsPanel.add(removeButton);
|
||||
buttonsPanel.add(modifyButton);
|
||||
|
||||
accountTable.getSelectionModel().addListSelectionListener(this);
|
||||
|
||||
newButton.setActionCommand("new");
|
||||
newButton.addActionListener(this);
|
||||
modifyButton.addActionListener(this);
|
||||
modifyButton.setActionCommand("modify");
|
||||
removeButton.addActionListener(this);
|
||||
removeButton.setActionCommand("remove");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see net.java.sip.communicator.service.gui.ConfigurationForm#getTitle
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return Resources.getString("impl.googlecontacts.CONFIG_FORM_TITLE");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see net.java.sip.communicator.service.gui.ConfigurationForm#getIcon
|
||||
*/
|
||||
public byte[] getIcon()
|
||||
{
|
||||
return Resources.getImageInBytes(
|
||||
"GOOGLECONTACTS_CONFIG_FORM_ICON");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see net.java.sip.communicator.service.gui.ConfigurationForm#getForm
|
||||
*/
|
||||
public Object getForm()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required by ConfirgurationForm interface
|
||||
*
|
||||
* Returns the index of this configuration form in the configuration window.
|
||||
* This index is used to put configuration forms in the desired order.
|
||||
* <p>
|
||||
* 0 is the first position
|
||||
* -1 means that the form will be put at the end
|
||||
* </p>
|
||||
* @return the index of this configuration form in the configuration window.
|
||||
*
|
||||
* @see net.java.sip.communicator.service.gui.ConfigurationForm#getIndex
|
||||
*/
|
||||
public int getIndex()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes buttons events (new, modify, remove)
|
||||
*
|
||||
* @see java.awt.event.ActionListener#actionPerformed
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
int row = accountTable.getSelectedRow();
|
||||
|
||||
if (e.getActionCommand().equals("new"))
|
||||
{
|
||||
settingsForm.setNameFieldEnabled(true);
|
||||
settingsForm.loadData(null);
|
||||
int ret = settingsForm.showDialog();
|
||||
|
||||
if(ret == 1)
|
||||
{
|
||||
GoogleContactsConnection cnx = settingsForm.getConnection();
|
||||
tableModel.addAccount(cnx, true);
|
||||
new RefreshContactSourceThread(null, cnx).start();
|
||||
saveConfig(cnx);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getActionCommand().equals("modify") && row != -1)
|
||||
{
|
||||
settingsForm.setNameFieldEnabled(false);
|
||||
GoogleContactsConnection cnx = tableModel.getAccountAt(row);
|
||||
settingsForm.loadData(cnx);
|
||||
|
||||
int ret = settingsForm.showDialog();
|
||||
|
||||
if(ret == 1)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getActionCommand().equals("remove") && row != -1)
|
||||
{
|
||||
GoogleContactsConnection cnx = tableModel.getAccountAt(row);
|
||||
tableModel.removeAccount(cnx.getLogin());
|
||||
removeConfig(cnx);
|
||||
new RefreshContactSourceThread(cnx, null).start();
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Required by ListSelectionListener. Enables the "modify"
|
||||
* button when a server is selected in the table
|
||||
*
|
||||
* @param e event triggered
|
||||
*/
|
||||
public void valueChanged(ListSelectionEvent e)
|
||||
{
|
||||
if(accountTable.getSelectedRow() == -1)
|
||||
{
|
||||
modifyButton.setEnabled(false);
|
||||
removeButton.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
else if(!e.getValueIsAdjusting())
|
||||
{
|
||||
modifyButton.setEnabled(true);
|
||||
removeButton.setEnabled(true);
|
||||
saveConfig(tableModel.getAccountAt(accountTable.getSelectedRow()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* refreshes the table display
|
||||
*/
|
||||
private void refresh()
|
||||
{
|
||||
tableModel.fireTableStructureChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this is an advanced configuration form.
|
||||
* @return <tt>true</tt> if this is an advanced configuration form,
|
||||
* otherwise it returns <tt>false</tt>
|
||||
*/
|
||||
public boolean isAdvanced()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread that will perform refresh of contact sources.
|
||||
*/
|
||||
public static class RefreshContactSourceThread
|
||||
extends Thread
|
||||
{
|
||||
/**
|
||||
* Old connection.
|
||||
*/
|
||||
private GoogleContactsConnection oldCnx = null;
|
||||
|
||||
/**
|
||||
* New connection.
|
||||
*/
|
||||
private GoogleContactsConnection newCnx = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param oldCnx old connection.
|
||||
* @param newCnx new connection.
|
||||
*/
|
||||
RefreshContactSourceThread(GoogleContactsConnection oldCnx,
|
||||
GoogleContactsConnection newCnx)
|
||||
{
|
||||
this.oldCnx = oldCnx;
|
||||
this.newCnx = newCnx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread entry point.
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
if(oldCnx != null)
|
||||
{
|
||||
GoogleContactsActivator.getGoogleContactsService().
|
||||
removeContactSource(oldCnx);
|
||||
}
|
||||
|
||||
if(newCnx != null)
|
||||
{
|
||||
GoogleContactsActivator.getGoogleContactsService().
|
||||
addContactSource(newCnx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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.configform;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.table.*;
|
||||
|
||||
import net.java.sip.communicator.service.googlecontacts.*;
|
||||
import net.java.sip.communicator.impl.googlecontacts.*;
|
||||
|
||||
|
||||
/**
|
||||
* A table model suitable for the directories list in
|
||||
* the configuration form. Takes its data in an LdapDirectorySet.
|
||||
*
|
||||
* @author Sebastien Mazy
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleContactsTableModel
|
||||
extends AbstractTableModel
|
||||
{
|
||||
/**
|
||||
* Serial version UID.
|
||||
*/
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
/**
|
||||
* Google Contacts service reference.
|
||||
*/
|
||||
private final GoogleContactsServiceImpl googleService =
|
||||
GoogleContactsActivator.getGoogleContactsService();
|
||||
|
||||
/**
|
||||
* Add account from table.
|
||||
*
|
||||
* @param cnx account
|
||||
* @param enabled if the account should be enabled
|
||||
*/
|
||||
public void addAccount(GoogleContactsConnection cnx, boolean enabled)
|
||||
{
|
||||
if(cnx != null)
|
||||
{
|
||||
((GoogleContactsConnectionImpl)cnx).setEnabled(enabled);
|
||||
googleService.getAccounts().add((GoogleContactsConnectionImpl)cnx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove account from table.
|
||||
*
|
||||
* @param login account login to remove
|
||||
*/
|
||||
public void removeAccount(String login)
|
||||
{
|
||||
Iterator<GoogleContactsConnectionImpl> it =
|
||||
googleService.getAccounts().iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
GoogleContactsConnection cnx = it.next();
|
||||
if(cnx.getLogin().equals(login))
|
||||
{
|
||||
it.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title for this column
|
||||
*
|
||||
* @param column the column
|
||||
*
|
||||
* @return the title for this column
|
||||
*
|
||||
* @see javax.swing.table.AbstractTableModel#getColumnName
|
||||
*/
|
||||
public String getColumnName(int column)
|
||||
{
|
||||
switch(column)
|
||||
{
|
||||
case 0:
|
||||
return Resources.getString("impl.googlecontacts.ENABLED");
|
||||
case 1:
|
||||
return Resources.getString("impl.googlecontacts.ACCOUNT_NAME");
|
||||
default:
|
||||
throw new IllegalArgumentException("column not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the table
|
||||
*
|
||||
* @return the number of rows in the table
|
||||
* @see javax.swing.table.AbstractTableModel#getRowCount
|
||||
*/
|
||||
public int getRowCount()
|
||||
{
|
||||
return googleService.getAccounts().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of column in the table
|
||||
*
|
||||
* @return the number of columns in the table
|
||||
*
|
||||
* @see javax.swing.table.AbstractTableModel#getColumnCount
|
||||
*/
|
||||
public int getColumnCount()
|
||||
{
|
||||
// 2 columns: "enable" and "account name"
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text for the given cell of the table
|
||||
*
|
||||
* @param row cell row
|
||||
* @param column cell column
|
||||
*
|
||||
* @see javax.swing.table.AbstractTableModel#getValueAt
|
||||
*/
|
||||
public Object getValueAt(int row, int column)
|
||||
{
|
||||
switch(column)
|
||||
{
|
||||
case 0:
|
||||
return new Boolean(getAccountAt(row).isEnabled());
|
||||
case 1:
|
||||
return getAccountAt(row).getLogin();
|
||||
default:
|
||||
throw new IllegalArgumentException("column not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the account credentials at the row 'row'
|
||||
*
|
||||
* @param row the row
|
||||
*
|
||||
* @return the login/password for the account
|
||||
*/
|
||||
public GoogleContactsConnectionImpl getAccountAt(int row)
|
||||
{
|
||||
if(row < 0 || row >= googleService.getAccounts().size())
|
||||
{
|
||||
throw new IllegalArgumentException("row not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
return googleService.getAccounts().get(row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a cell is editable. Only "enable" column (checkboxes)
|
||||
* is editable
|
||||
*
|
||||
* @param row row of the cell
|
||||
* @param col column of the cell
|
||||
*
|
||||
* @return whether the cell is editable
|
||||
*/
|
||||
public boolean isCellEditable(int row, int col)
|
||||
{
|
||||
if(col == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides a method that always returned Object.class
|
||||
* Now it will return Boolean.class for the first method,
|
||||
* letting the DefaultTableCellRenderer create checkboxes.
|
||||
*
|
||||
* @param columnIndex index of the column
|
||||
* @return Column class
|
||||
*/
|
||||
public Class<?> getColumnClass(int columnIndex)
|
||||
{
|
||||
return getValueAt(0, columnIndex).getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in an editable cell, that is to say
|
||||
* an enable/disable chekbox in colum 0
|
||||
*/
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
|
||||
{
|
||||
if(columnIndex != 0)
|
||||
throw new IllegalArgumentException("non editable column!");
|
||||
|
||||
GoogleContactsConfigForm.RefreshContactSourceThread th = null;
|
||||
GoogleContactsConnectionImpl cnx = getAccountAt(rowIndex);
|
||||
|
||||
if(cnx.isEnabled())
|
||||
{
|
||||
th = new GoogleContactsConfigForm.RefreshContactSourceThread(cnx,
|
||||
null);
|
||||
}
|
||||
else
|
||||
{
|
||||
th = new GoogleContactsConfigForm.RefreshContactSourceThread(null,
|
||||
cnx);
|
||||
}
|
||||
|
||||
cnx.setEnabled(!cnx.isEnabled());
|
||||
|
||||
th.start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.configform;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import net.java.sip.communicator.impl.googlecontacts.*;
|
||||
|
||||
/**
|
||||
* The <tt>Resources</tt> class manages the access to the internationalization
|
||||
* properties files and the image resources used in this plugin.
|
||||
*
|
||||
* @author Yana Stamcheva
|
||||
*/
|
||||
public class Resources
|
||||
{
|
||||
/**
|
||||
* Returns an internationalized string corresponding to the given key.
|
||||
*
|
||||
* @param key The key of the string.
|
||||
* @return An internationalized string corresponding to the given key.
|
||||
*/
|
||||
public static String getString(String key)
|
||||
{
|
||||
return GoogleContactsActivator.getResourceManagementService()
|
||||
.getI18NString(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an internationalized string corresponding to the given key.
|
||||
*
|
||||
* @param key The key of the string.
|
||||
* @param params additionnal parameters
|
||||
* @return An internationalized string corresponding to the given key.
|
||||
*/
|
||||
public static String getString(String key, String[] params)
|
||||
{
|
||||
return GoogleContactsActivator.getResourceManagementService()
|
||||
.getI18NString(key, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given image identifier.
|
||||
*
|
||||
* @param imageID The identifier of the image.
|
||||
* @return The image for the given identifier.
|
||||
*/
|
||||
public static ImageIcon getImage(String imageID)
|
||||
{
|
||||
return GoogleContactsActivator.getResourceManagementService().getImage(imageID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given image identifier.
|
||||
*
|
||||
* @param imageID The identifier of the image.
|
||||
* @return The image for the given identifier.
|
||||
*/
|
||||
public static byte[] getImageInBytes(String imageID)
|
||||
{
|
||||
return GoogleContactsActivator.getResourceManagementService().
|
||||
getImageInBytes(imageID);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
Bundle-Activator: net.java.sip.communicator.impl.googlecontacts.GoogleContactsActivator
|
||||
Bundle-Name: Google Contacts Service Implementation
|
||||
Bundle-Description: A bundle that offers access to Google Contacts
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
System-Bundle: yes
|
||||
Import-Package: org.osgi.framework,
|
||||
net.java.sip.communicator.service.configuration,
|
||||
net.java.sip.communicator.service.credentialsstorage,
|
||||
net.java.sip.communicator.service.contactsource,
|
||||
net.java.sip.communicator.service.gui,
|
||||
net.java.sip.communicator.service.resources,
|
||||
net.java.sip.communicator.service.protocol,
|
||||
net.java.sip.communicator.util,
|
||||
net.java.sip.communicator.util.swing,
|
||||
org.xml.sax,
|
||||
org.xml.sax.helpers,
|
||||
javax.xml.parsers,
|
||||
javax.xml,
|
||||
javax.swing,
|
||||
javax.swing.border,
|
||||
javax.swing.event,
|
||||
javax.swing.table,
|
||||
javax.swing.tree,
|
||||
javax.swing.text,
|
||||
Export-Package: net.java.sip.communicator.service.googlecontacts
|
||||
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.service.googlecontacts;
|
||||
|
||||
/**
|
||||
* Interface that define a Google Contacts connection.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public interface GoogleContactsConnection
|
||||
{
|
||||
/**
|
||||
* Get login.
|
||||
*
|
||||
* @return login to connect to the service
|
||||
*/
|
||||
public String getLogin();
|
||||
|
||||
/**
|
||||
* get password.
|
||||
*
|
||||
* @return password to connect to the service
|
||||
*/
|
||||
public String getPassword();
|
||||
}
|
||||
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.service.googlecontacts;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Entry of Google Contacts directory.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public interface GoogleContactsEntry
|
||||
{
|
||||
/**
|
||||
* The supported IM protocol
|
||||
*/
|
||||
public enum IMProtocol
|
||||
{
|
||||
/**
|
||||
* Google Talk protocol.
|
||||
*/
|
||||
GOOGLETALK,
|
||||
|
||||
/**
|
||||
* Yahoo protocol.
|
||||
*/
|
||||
YAHOO,
|
||||
|
||||
/**
|
||||
* AIM protocol.
|
||||
*/
|
||||
AIM,
|
||||
|
||||
/**
|
||||
* MSN protocol.
|
||||
*/
|
||||
MSN,
|
||||
|
||||
/**
|
||||
* ICQ protocol.
|
||||
*/
|
||||
ICQ,
|
||||
|
||||
/**
|
||||
* Jabber protocol.
|
||||
*/
|
||||
JABBER,
|
||||
|
||||
/**
|
||||
* Other protocol (i.e. not supported).
|
||||
*/
|
||||
OTHER,
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full name.
|
||||
*
|
||||
* @return full name
|
||||
*/
|
||||
public String getFullName();
|
||||
|
||||
/**
|
||||
* Get the family name.
|
||||
*
|
||||
* @return family name
|
||||
*/
|
||||
public String getFamilyName();
|
||||
|
||||
/**
|
||||
* Get the given name.
|
||||
*
|
||||
* @return given name
|
||||
*/
|
||||
public String getGivenName();
|
||||
|
||||
/**
|
||||
* Returns mails.
|
||||
*
|
||||
* @return mails
|
||||
*/
|
||||
public List<String> getAllMails();
|
||||
|
||||
/**
|
||||
* Adds a home mail address.
|
||||
*
|
||||
* @param mail the mail address
|
||||
*/
|
||||
public void addHomeMail(String mail);
|
||||
|
||||
/**
|
||||
* Returns home mail addresses.
|
||||
*
|
||||
* @return home mail addresses
|
||||
*/
|
||||
public List<String> getHomeMails();
|
||||
|
||||
/**
|
||||
* Adds a work mail address.
|
||||
*
|
||||
* @param mail the mail address
|
||||
*/
|
||||
public void addWorkMails(String mail);
|
||||
|
||||
/**
|
||||
* Returns work mail addresses.
|
||||
*
|
||||
* @return work mail addresses
|
||||
*/
|
||||
public List<String> getWorkMails();
|
||||
|
||||
/**
|
||||
* Returns telephone numbers.
|
||||
*
|
||||
* @return telephone numbers
|
||||
*/
|
||||
public List<String> getAllPhones();
|
||||
|
||||
/**
|
||||
* Adds a work telephone number.
|
||||
*
|
||||
* @param telephoneNumber the work telephone number
|
||||
*/
|
||||
public void addWorkPhone(String telephoneNumber);
|
||||
|
||||
/**
|
||||
* Returns work telephone numbers.
|
||||
*
|
||||
* @return work telephone numbers
|
||||
*/
|
||||
public List<String> getWorkPhones();
|
||||
|
||||
/**
|
||||
* Adds a mobile telephone numbers.
|
||||
*
|
||||
* @param telephoneNumber the mobile telephone number
|
||||
*/
|
||||
public void addMobilePhone(String telephoneNumber);
|
||||
|
||||
/**
|
||||
* Returns mobile telephone numbers.
|
||||
*
|
||||
* @return mobile telephone numbers
|
||||
*/
|
||||
public List<String> getMobilePhones();
|
||||
|
||||
/**
|
||||
* Adds a home telephone numbers.
|
||||
*
|
||||
* @param telephoneNumber the home telephone number
|
||||
*/
|
||||
public void addHomePhone(String telephoneNumber);
|
||||
|
||||
/**
|
||||
* Returns home telephone numbers.
|
||||
*
|
||||
* @return home telephone numbers
|
||||
*/
|
||||
public List<String> getHomePhones();
|
||||
|
||||
/**
|
||||
* Get the photo full URI.
|
||||
*
|
||||
* @return the photo URI or null if there isn't
|
||||
*/
|
||||
public String getPhoto();
|
||||
|
||||
/**
|
||||
* Returns IM addresses.
|
||||
*
|
||||
* @return Map where key is IM address and value is IM protocol (MSN, ...)
|
||||
*/
|
||||
public Map<String, IMProtocol> getIMAddresses();
|
||||
|
||||
/**
|
||||
* Adds an IM address.
|
||||
*
|
||||
* @param imAddress IM address
|
||||
* @param protocol IM protocol
|
||||
*/
|
||||
public void addIMAddress(String imAddress, IMProtocol protocol);
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.service.googlecontacts;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Google Contacts service.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public interface GoogleContactsService
|
||||
{
|
||||
/**
|
||||
* Perform a search for a contact using regular expression.
|
||||
*
|
||||
* @param cnx <tt>GoogleContactsConnection</tt> to perform the query
|
||||
* @param query 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 query, int count, GoogleEntryCallback callback);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Get the full contacts list.
|
||||
*
|
||||
* @return list of <tt>GoogleContactsEntry</tt>
|
||||
*/
|
||||
public List<GoogleContactsEntry> getContacts();
|
||||
|
||||
/**
|
||||
* Add a contact source service with the specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param login login
|
||||
* @param password password
|
||||
*/
|
||||
public void addContactSource(String login, String password);
|
||||
|
||||
/**
|
||||
* Add a contact source service with the specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param cnx <tt>GoogleContactsConnection</tt>.
|
||||
*/
|
||||
public void addContactSource(GoogleContactsConnection cnx);
|
||||
|
||||
/**
|
||||
* Remove a contact source service with the specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param cnx <tt>GoogleContactsConnection</tt>.
|
||||
*/
|
||||
public void removeContactSource(GoogleContactsConnection cnx);
|
||||
|
||||
/**
|
||||
* Remove a contact source service with the specified
|
||||
* <tt>GoogleContactsConnection</tt>.
|
||||
*
|
||||
* @param login login
|
||||
*/
|
||||
public void removeContactSource(String login);
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.service.googlecontacts;
|
||||
|
||||
/**
|
||||
* Defines the interface for a callback function which is called by the
|
||||
* <tt>GoogleContactsService</tt> when a new <tt>GoogleContactsEntry</tt> has
|
||||
* been found during a search.
|
||||
*/
|
||||
public interface GoogleEntryCallback
|
||||
{
|
||||
/**
|
||||
* Notifies this <tt>GoogleEntryCallback</tt> when a new
|
||||
* <tt>GoogleContactsEntry</tt> has been found.
|
||||
*
|
||||
* @param entry the <tt>GoogleContactsEntry</tt> found
|
||||
*/
|
||||
void callback(GoogleContactsEntry entry);
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.service.googlecontacts;
|
||||
|
||||
import java.util.regex.*;
|
||||
|
||||
/**
|
||||
* Describes a Google query.
|
||||
*
|
||||
* @author Sebastien Vincent
|
||||
*/
|
||||
public class GoogleQuery
|
||||
{
|
||||
/**
|
||||
* If the query is cancelled.
|
||||
*/
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* The query pattern.
|
||||
*/
|
||||
private Pattern query = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param query query string
|
||||
*/
|
||||
public GoogleQuery(Pattern query)
|
||||
{
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query pattern.
|
||||
*
|
||||
* @return query pattern
|
||||
*/
|
||||
public Pattern getQueryPattern()
|
||||
{
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the query.
|
||||
*/
|
||||
public void cancel()
|
||||
{
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the query has been cancelled.
|
||||
*
|
||||
* @return true If the query has been cancelled, false otherwise
|
||||
*/
|
||||
public boolean isCancelled()
|
||||
{
|
||||
return cancelled;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue