diff options
author | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2008-09-20 20:36:27 +0000 |
---|---|---|
committer | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2008-09-20 20:36:27 +0000 |
commit | 182ada36e3a288d03fd7d6d96e88d1bb409dc983 (patch) | |
tree | dc3ecf63b2dcbcccf38c8a1018041382649629d2 /src/net/java/sip/communicator/service/protocol | |
parent | 7447c700b0414a077aff8ec7fea337dad1f4d11e (diff) | |
download | jitsi-182ada36e3a288d03fd7d6d96e88d1bb409dc983.zip jitsi-182ada36e3a288d03fd7d6d96e88d1bb409dc983.tar.gz jitsi-182ada36e3a288d03fd7d6d96e88d1bb409dc983.tar.bz2 |
When starting the applications, loads the stored accounts in the background in order to allow the UI to appear as soon as possible.
Diffstat (limited to 'src/net/java/sip/communicator/service/protocol')
6 files changed, 478 insertions, 187 deletions
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java index 2a7334e..5d1b414 100644 --- a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java +++ b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java @@ -29,7 +29,8 @@ public abstract class AbstractProtocolProviderService * A list of all listeners registered for * <tt>RegistrationStateChangeEvent</tt>s. */ - private final List registrationListeners = new ArrayList(); + private final List<RegistrationStateChangeListener> registrationListeners = + new ArrayList<RegistrationStateChangeListener>(); /** * Registers the specified listener with this provider so that it would @@ -73,16 +74,17 @@ public abstract class AbstractProtocolProviderService logger.debug("Dispatching " + event + " to " + registrationListeners.size()+ " listeners."); - Iterator listeners = null; + Iterator<RegistrationStateChangeListener> listeners = null; synchronized (registrationListeners) { - listeners = new ArrayList(registrationListeners).iterator(); + listeners = + new ArrayList<RegistrationStateChangeListener>( + registrationListeners).iterator(); } while (listeners.hasNext()) { - RegistrationStateChangeListener listener - = (RegistrationStateChangeListener) listeners.next(); + RegistrationStateChangeListener listener = listeners.next(); listener.registrationStateChanged(event); } diff --git a/src/net/java/sip/communicator/service/protocol/AccountManager.java b/src/net/java/sip/communicator/service/protocol/AccountManager.java new file mode 100644 index 0000000..6cdb8e3 --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/AccountManager.java @@ -0,0 +1,61 @@ +/*
+ * 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.protocol;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Represents a manager of accounts which contains the details about the format
+ * in which the accounts in question are stored (i.e. knows how to store and load
+ * them) and takes care of loading them on start-up.
+ *
+ * @author Lubomir Marinov
+ */
+public interface AccountManager
+{
+
+ /**
+ * Registers a specific listener to be notified about events fired by this
+ * <code>AccountManager</code>. If the <code>listener</code> is already
+ * registered, it will not be registered again.
+ *
+ * @param listener the listener to be registered for notification events
+ * fired by this <code>AccountManager</code>
+ */
+ void addListener(AccountManagerListener listener);
+
+ /**
+ * Determines whether the account store represented by this manager contains
+ * stored accounts.
+ *
+ * @return <tt>true</tt> if the account store represented by this manager
+ * contains stored accounts; <tt>false</tt>, otherwise
+ */
+ boolean hasStoredAccounts();
+
+ /**
+ * Unregisters a specific listener from this <code>AccountManager</code> so
+ * that it no longer received notifications about events fired by this
+ * manager.
+ *
+ * @param listener the listener to be unregistered from this
+ * <code>AccountManager</code> so that it no longer receives
+ * notifications about events fired by this manager
+ */
+ void removeListener(AccountManagerListener listener);
+
+ /**
+ * Stores an account represented in the form of an <code>AccountID</code>
+ * created by a specific <code>ProtocolProviderFactory</code>.
+ *
+ * @param factory the <code>ProtocolProviderFactory</code> which created the
+ * account to be stored
+ * @param accountID the account in the form of <code>AccountID</code> to be
+ * stored
+ */
+ void storeAccount(ProtocolProviderFactory factory, AccountID accountID);
+}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java index 3501cd5..82fdb82 100644 --- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java +++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java @@ -8,13 +8,11 @@ package net.java.sip.communicator.service.protocol; import java.util.*; +import org.osgi.framework.*; -import net.java.sip.communicator.impl.protocol.sip.*; import net.java.sip.communicator.service.configuration.*; import net.java.sip.communicator.util.*; -import org.osgi.framework.*; - /** * The ProtocolProviderFactory is what actually creates instances of a * ProtocolProviderService implementation. A provider factory would register, @@ -25,6 +23,7 @@ import org.osgi.framework.*; * would user account registered through the various services. * * @author Emil Ivov + * @author Lubomir Marinov */ public abstract class ProtocolProviderFactory { @@ -202,6 +201,48 @@ public abstract class ProtocolProviderFactory public static final String IS_PROTOCOL_HIDDEN = "IS_PROTOCOL_HIDDEN"; /** + * The <code>BundleContext</code> containing (or to contain) the service + * registration of this factory. + */ + private final BundleContext bundleContext; + + /** + * The name of the protocol this factory registers its + * <code>ProtocolProviderService</code>s with and to be placed in the + * properties of the accounts created by this factory. + */ + private final String protocolName; + + /** + * The table that we store our accounts in. + * <p> + * TODO Synchronize the access to the field which may in turn be better + * achieved by also hiding it from protected into private access. + * </p> + */ + protected final Hashtable<AccountID, ServiceRegistration> registeredAccounts = + new Hashtable<AccountID, ServiceRegistration>(); + + protected ProtocolProviderFactory(BundleContext bundleContext, + String protocolName) + { + this.bundleContext = bundleContext; + this.protocolName = protocolName; + } + + /** + * Gets the <code>BundleContext</code> containing (or to contain) the + * service registration of this factory. + * + * @return the <code>BundleContext</code> containing (or to contain) the + * service registration of this factory + */ + public BundleContext getBundleContext() + { + return bundleContext; + } + + /** * Initializes and creates an account corresponding to the specified * accountProperties and registers the resulting ProtocolProvider in the * <tt>context</tt> BundleContext parameter. Note that account @@ -254,7 +295,13 @@ public abstract class ProtocolProviderFactory * @return a copy of the list containing the <tt>AccountID</tt>s of all * accounts currently registered in this protocol provider. */ - public abstract ArrayList<AccountID> getRegisteredAccounts(); + public ArrayList<AccountID> getRegisteredAccounts() + { + synchronized (registeredAccounts) + { + return new ArrayList<AccountID>(registeredAccounts.keySet()); + } + } /** * Returns the ServiceReference for the protocol provider corresponding to @@ -264,8 +311,17 @@ public abstract class ProtocolProviderFactory * specified account id and null if the account id is unknown to the * provider factory. */ - public abstract ServiceReference getProviderForAccount( - AccountID accountID); + public ServiceReference getProviderForAccount(AccountID accountID) + { + ServiceRegistration registration; + + synchronized (registeredAccounts) + { + registration = + (ServiceRegistration) registeredAccounts.get(accountID); + } + return (registration == null) ? null : registration.getReference(); + } /** * Removes the specified account from the list of accounts that this @@ -279,121 +335,103 @@ public abstract class ProtocolProviderFactory * @return true if an account with the specified ID existed and was removed * and false otherwise. */ - public abstract boolean uninstallAccount(AccountID accountID); - - /** - * The method stores the specified account in the configuration service - * under the package name of the source factory. The restore and remove - * account methods are to be used to obtain access to and control the stored - * accounts. - * <p> - * In order to store all account properties, the method would create an - * entry in the configuration service corresponding (beginning with) the - * <tt>sourceFactory</tt>'s package name and add to it a unique identifier - * (e.g. the current miliseconds.) - * <p> - * @param bundleContext a currently valid bundle context. - * @param accountID the AccountID corresponding to the account that we would - * like to store. - */ - protected void storeAccount(BundleContext bundleContext, - AccountID accountID) + public boolean uninstallAccount(AccountID accountID) { - String sourcePackageName = getFactoryImplPackageName(); - - String accountNodeName = null; - - ServiceReference confReference - = bundleContext.getServiceReference( - ConfigurationService.class.getName()); - - ConfigurationService configurationService - = (ConfigurationService) bundleContext.getService(confReference); + // Unregister the protocol provider. + ServiceReference serRef = getProviderForAccount(accountID); - // First check if such accountID already exist in the configuration. - List accounts = configurationService - .getPropertyNamesByPrefix(sourcePackageName, true); - - Iterator accountsIter = accounts.iterator(); - - while(accountsIter.hasNext()) + if (serRef == null) { - String accountRootPropName - = (String) accountsIter.next(); + return false; + } - String accountIDString - = configurationService.getString( - accountRootPropName + ".ACCOUNT_UID"); + BundleContext bundleContext = getBundleContext(); + ProtocolProviderService protocolProvider = + (ProtocolProviderService) bundleContext.getService(serRef); - if(accountIDString.equals(accountID.getAccountUniqueID())) - { - accountNodeName - = configurationService.getString(accountRootPropName); - } + try + { + protocolProvider.unregister(); } - - //Create a unique node name of the properties node that will contain - //this account's properties. - if (accountNodeName == null) + catch (OperationFailedException ex) { - accountNodeName = "acc" + Long.toString(System.currentTimeMillis()); - - //set a value for the persistent node so that we could later - // retrieve it as a property - configurationService.setProperty( - sourcePackageName //prefix - + "." + accountNodeName, - accountNodeName); - - //register the account in the configuration service. - //we register all the properties in the following hierarchy - //net.java.sip.communicator.impl.protocol.PROTO_NAME.ACC_ID.PROP_NAME - configurationService.setProperty( - sourcePackageName//prefix - + "." + accountNodeName // node name for the account id - + "." + ACCOUNT_UID, // propname - accountID.getAccountUniqueID()); // value + logger + .error("Failed to unregister protocol provider for account : " + + accountID + " caused by: " + ex); } - //store the rest of the properties - Iterator accountPropKeys - = accountID.getAccountProperties().keySet().iterator(); + ServiceRegistration registration; - while (accountPropKeys.hasNext()) + synchronized (registeredAccounts) { - String propKey = - (String)accountPropKeys.next(); - String propValue = - (String)accountID.getAccountProperties().get(propKey); + registration = registeredAccounts.remove(accountID); + } + if (registration == null) + { + return false; + } - //if this is a password - encode it. - if(propKey.equals(PASSWORD)) - propValue = new String(Base64.encode(propValue.getBytes())); + // Kill the service. + registration.unregister(); - configurationService.setProperty( - sourcePackageName //prefix + return removeStoredAccount(bundleContext, accountID); + } - + "." + accountNodeName // a uniew node name for the account id - + "." + propKey, // propname - propValue); // value - } + /** + * The method stores the specified account in the configuration service + * under the package name of the source factory. The restore and remove + * account methods are to be used to obtain access to and control the stored + * accounts. + * <p> + * In order to store all account properties, the method would create an + * entry in the configuration service corresponding (beginning with) the + * <tt>sourceFactory</tt>'s package name and add to it a unique identifier + * (e.g. the current miliseconds.) + * </p> + * + * @param accountID the AccountID corresponding to the account that we would + * like to store. + */ + protected void storeAccount(AccountID accountID) + { + getAccountManager().storeAccount(this, accountID); + } - logger.debug("Stored account for id " + accountID.getAccountUniqueID() - + " for package " + getFactoryImplPackageName()); + /** + * Saves the password for the specified account after scrambling it a bit so + * that it is not visible from first sight. (The method remains highly + * insecure). + * + * @param accountID the AccountID for the account whose password we're + * storing + * @param password the password itself + * + * @throws IllegalArgumentException if no account corresponding to + * <code>accountID</code> has been previously stored + */ + public void storePassword(AccountID accountID, String password) + throws IllegalArgumentException + { + storePassword(getBundleContext(), accountID, password); } /** * Saves the password for the specified account after scrambling it a bit - * sot that it is not visible from first sight (Method remains highly + * so that it is not visible from first sight (Method remains highly * insecure). - * + * <p> + * TODO Delegate the implementation to {@link AccountManager} because it + * knows the format in which the password (among the other account + * properties) is to be saved. + * </p> + * * @param bundleContext a currently valid bundle context. * @param accountID the AccountID for the account whose password we're - * storing. + * storing. * @param password the password itself. - * - * @throws java.lang.IllegalArgumentException if no account corresponding - * to <tt>accountID</tt> has been previously stored. + * + * @throws IllegalArgumentException if no account corresponding to + * <tt>accountID</tt> has been previously stored. */ protected void storePassword(BundleContext bundleContext, AccountID accountID, @@ -431,11 +469,29 @@ public abstract class ProtocolProviderFactory /** * Returns the password last saved for the specified account. - * + * + * @param accountID the AccountID for the account whose password we're + * looking for + * + * @return a String containing the password for the specified accountID + */ + public String loadPassword(AccountID accountID) + { + return loadPassword(getBundleContext(), accountID); + } + + /** + * Returns the password last saved for the specified account. + * <p> + * TODO Delegate the implementation to {@link AccountManager} because it + * knows the format in which the password (among the other account + * properties) was saved. + * </p> + * * @param bundleContext a currently valid bundle context. * @param accountID the AccountID for the account whose password we're - * looking for.. - * + * looking for.. + * * @return a String containing the password for the specified accountID. */ protected String loadPassword(BundleContext bundleContext, @@ -465,103 +521,110 @@ public abstract class ProtocolProviderFactory return new String(Base64.decode(mangledPassword)); } - /** - * Restores all accounts stored for the package corresponding to - * sourceFactory and and installs everyone of them through the install - * account method. - * <p> - * @param bundleContext a currently valid bundle context. + * Initializes and creates an account corresponding to the specified + * accountProperties and registers the resulting ProtocolProvider in the + * <tt>context</tt> BundleContext parameter. This method has a persistent + * effect. Once created the resulting account will remain installed until + * removed through the uninstallAccount method. + * + * @param accountProperties a set of protocol (or implementation) specific + * properties defining the new account. + * @return the AccountID of the newly loaded account */ - protected void loadStoredAccounts(BundleContext bundleContext) + public AccountID loadAccount(Map accountProperties) { - String sourcePackageName = getFactoryImplPackageName(); + BundleContext bundleContext = getBundleContext(); + if (bundleContext == null) + throw new NullPointerException( + "The specified BundleContext was null"); - ServiceReference confReference - = bundleContext.getServiceReference( - ConfigurationService.class.getName()); - ConfigurationService configurationService - = (ConfigurationService) bundleContext.getService(confReference); + if (accountProperties == null) + throw new NullPointerException( + "The specified property map was null"); - //first retrieve all accounts that we've registered - List storedAccounts = configurationService.getPropertyNamesByPrefix( - sourcePackageName, true); - - logger.debug("Discovered " - + storedAccounts.size() - + " stored accounts"); + String userID = (String) accountProperties.get(USER_ID); + if (userID == null) + throw new NullPointerException( + "The account properties contained no user id."); - //load all accounts stored in the configuration service - Iterator storedAccountsIter = storedAccounts.iterator(); + String protocolName = getProtocolName(); + if (!accountProperties.containsKey(PROTOCOL)) + accountProperties.put(PROTOCOL, protocolName); - while (storedAccountsIter.hasNext()) - { - String accountRootPropName = (String) storedAccountsIter.next(); - logger.debug("Loading account " + accountRootPropName); + AccountID accountID = createAccountID(userID, accountProperties); - //get all properties that we've stored for this account and load - //them into the accountProperties table. + ProtocolProviderService service = createService(userID, accountID); - List storedAccPropNames = configurationService.getPropertyNamesByPrefix( - accountRootPropName, true); + Dictionary<String, String> properties = new Hashtable<String, String>(); + properties.put(PROTOCOL, protocolName); + properties.put(USER_ID, userID); - Iterator propNamesIter = storedAccPropNames.iterator(); - Map accountProperties = new Hashtable(); - while(propNamesIter.hasNext()) - { - String fullPropertyName = (String)propNamesIter.next(); - String storedPropertyValue - = configurationService.getString(fullPropertyName); + ServiceRegistration serviceRegistration = + bundleContext.registerService(ProtocolProviderService.class + .getName(), service, properties); - //strip the package prefix off the property name. - String propertyName = fullPropertyName.substring( - fullPropertyName.lastIndexOf('.')+1); + synchronized (registeredAccounts) + { + registeredAccounts.put(accountID, serviceRegistration); + } - //if this is a password - decode it first - if(propertyName.equals(PASSWORD)) - { - if(storedPropertyValue == null - || storedPropertyValue.length() == 0) - { - storedPropertyValue = ""; - } - else - { - storedPropertyValue = new String( - Base64.decode(storedPropertyValue)); - } - } + return accountID; + } - if(storedPropertyValue != null) - accountProperties.put(propertyName, storedPropertyValue); - } - try - { - loadAccount(accountProperties); - } - catch (Exception exc) - { - //catch any exception here so that one failing accoung does not - //cut the whole account reloading process - logger.error("Failed to reload account:" + accountProperties, - exc); - } - } + /** + * Creates a new <code>AccountID</code> instance with a specific user ID to + * represent a given set of account properties. + * <p> + * The method is a pure factory allowing implementers to specify the runtime + * type of the created <code>AccountID</code> and customize the instance. + * The returned <code>AccountID</code> will later be associated with a + * <code>ProtocolProviderService</code> by the caller (e.g. using + * {@link #createService(String, AccountID)}). + * </p> + * + * @param userID the user ID of the new instance + * @param accountProperties the set of properties to be represented by the + * new instance + * @return a new <code>AccountID</code> instance with the specified user ID + * representing the given set of account properties + */ + protected abstract AccountID createAccountID(String userID, + Map accountProperties); + + /** + * Gets the name of the protocol this factory registers its + * <code>ProtocolProviderService</code>s with and to be placed in the + * properties of the accounts created by this factory. + * + * @return the name of the protocol this factory registers its + * <code>ProtocolProviderService</code>s with and to be placed in + * the properties of the accounts created by this factory + */ + protected String getProtocolName() + { + return protocolName; } /** - * Initializes and creates an account corresponding to the specified - * accountProperties and registers the resulting ProtocolProvider in the - * <tt>context</tt> BundleContext parameter. This method has a persistent - * effect. Once created the resulting account will remain installed until - * removed through the uninstall account method. - * - * @param accountProperties a set of protocol (or implementation) - * specific properties defining the new account. - * - * @return the AccountID of the newly loaded account - */ - protected abstract AccountID loadAccount( Map accountProperties); + * Initializes a new <code>ProtocolProviderService</code> instance with a + * specific user ID to represent a specific <code>AccountID</code>. + * <p> + * The method is a pure factory allowing implementers to specify the runtime + * type of the created <code>ProtocolProviderService</code> and customize + * the instance. The caller will later register the returned service with + * the <code>BundleContext</code> of this factory. + * </p> + * + * @param userID the user ID to initialize the new instance with + * @param accountID the <code>AccountID</code> to be represented by the new + * instance + * @return a new <code>ProtocolProviderService</code> instance with the + * specific user ID representing the specified + * <code>AccountID</code> + */ + protected abstract ProtocolProviderService createService(String userID, + AccountID accountID); /** * Removes the account with <tt>accountID</tt> from the set of accounts @@ -691,4 +754,53 @@ public abstract class ProtocolProviderFactory return className.substring(0, className.lastIndexOf('.')); } + + /** + * Prepares the factory for bundle shutdown. + */ + public void stop() + { + logger.trace("Preparing to stop all protocol providers of" + this); + + synchronized (registeredAccounts) + { + for (Enumeration<ServiceRegistration> registrations = + registeredAccounts.elements(); registrations.hasMoreElements();) + { + ServiceRegistration reg = registrations.nextElement(); + + stop(reg); + + reg.unregister(); + } + + registeredAccounts.clear(); + } + } + + /** + * Shuts down the <code>ProtocolProviderService</code> representing an + * account registered with this factory. + * + * @param registeredAccount the <code>ServiceRegistration</code> of the + * <code>ProtocolProviderService</code> representing an account + * registered with this factory + */ + protected void stop(ServiceRegistration registeredAccount) + { + ProtocolProviderService protocolProviderService = + (ProtocolProviderService) getBundleContext().getService( + registeredAccount.getReference()); + + protocolProviderService.shutdown(); + } + + private AccountManager getAccountManager() + { + BundleContext bundleContext = getBundleContext(); + ServiceReference serviceReference = + bundleContext.getServiceReference(AccountManager.class.getName()); + + return (AccountManager) bundleContext.getService(serviceReference); + } } diff --git a/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java b/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java new file mode 100644 index 0000000..550b340 --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/event/AccountManagerEvent.java @@ -0,0 +1,84 @@ +/*
+ * 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.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Represents a notifying event fired by a specific {@link AccountManager}.
+ *
+ * @author Lubomir Marinov
+ */
+public class AccountManagerEvent
+ extends EventObject
+{
+
+ /**
+ * The type of event notifying that the loading of the stored accounts of a
+ * specific <code>ProtocolProviderFactory</code> has finished.
+ */
+ public static final int STORED_ACCOUNTS_LOADED = 1;
+
+ /**
+ * The <code>ProtocolProviderFactory</code> being worked on at the time this
+ * event has been fired.
+ */
+ private final ProtocolProviderFactory factory;
+
+ /**
+ * The (detail) type of this event which is one of
+ * {@link #STORED_ACCOUNTS_LOADED}.
+ */
+ private final int type;
+
+ /**
+ * Initializes a new <code>AccountManagerEvent</code> instance fired by a
+ * specific <code>AccountManager</code> in order to notify of an event of a
+ * specific type occurring while working on a specific
+ * <code>ProtocolProviderFactory</code>.
+ *
+ * @param accountManager the <code>AccountManager</code> issuing the
+ * notification i.e. the source of the event
+ * @param type
+ * @param factory the <code>ProtocolProviderFactory</code> being worked on
+ * at the time this event has been fired
+ */
+ public AccountManagerEvent(AccountManager accountManager, int type,
+ ProtocolProviderFactory factory)
+ {
+ super(accountManager);
+
+ this.type = type;
+ this.factory = factory;
+ }
+
+ /**
+ * Gets the <code>ProtocolProviderFactory</code> being worked on at the time
+ * this event has been fired.
+ *
+ * @return the <code>ProtocolProviderFactory</code> being worked on at the
+ * time this event has been fired
+ */
+ public ProtocolProviderFactory getFactory()
+ {
+ return factory;
+ }
+
+ /**
+ * Gets the (detail) type of this event which is one of
+ * <code>STORED_ACCOUNTS_LOADED</code>.
+ *
+ * @return the (detail) type of this event which is one of
+ * <code>STORED_ACCOUNTS_LOADED</code>
+ */
+ public int getType()
+ {
+ return type;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java b/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java new file mode 100644 index 0000000..ee03822 --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/event/AccountManagerListener.java @@ -0,0 +1,31 @@ +/*
+ * 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.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Represents a listener receiving notifications from {@link AccountManager}.
+ *
+ * @author Lubomir Marinov
+ */
+public interface AccountManagerListener
+ extends EventListener
+{
+
+ /**
+ * Notifies this listener about an event fired by a specific
+ * <code>AccountManager</code>.
+ *
+ * @param event the <code>AccountManagerEvent</code> describing the
+ * <code>AccountManager</code> firing the notification and the
+ * other details of the specific notification.
+ */
+ void handleAccountManagerEvent(AccountManagerEvent event);
+}
diff --git a/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf b/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf index 557bd2b..c2faf0c 100644 --- a/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf +++ b/src/net/java/sip/communicator/service/protocol/protocol.provider.manifest.mf @@ -1,3 +1,4 @@ +Bundle-Activator: net.java.sip.communicator.impl.protocol.ProtocolProviderActivator Bundle-Name: Protocol Provider Service Bundle-Description: Protocol Provider Service. Bundle-Vendor: sip-communicator.org |