/*
* Jitsi, 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 java.util.*;
import net.java.sip.communicator.service.protocol.event.*;
import org.osgi.framework.*;
/**
* Provides utilities to aid the manipulation of {@link AccountManager}.
*
* @author Lyubomir Marinov
*/
public final class AccountManagerUtils
{
private static AccountManager getAccountManager(BundleContext bundleContext)
{
return
bundleContext.getService(
bundleContext.getServiceReference(AccountManager.class));
}
/**
* Starts a specific Bundle
and waits for the
* AccountManager
available in a specific
* BundleContext
to load the stored accounts of a
* ProtocolProviderFactory
with a specific protocol name.
*
* @param bundleContextWithAccountManager
* the BundleContext
in which an
* AccountManager
service is registered
* @param bundleToStart
* the Bundle
to be started
* @param protocolNameToWait
* the protocol name of a ProtocolProviderFactory
to
* wait the end of the loading of the stored accounts for
* @throws BundleException
* @throws InterruptedException
* if any thread interrupted the current thread before or while
* the current thread was waiting for the loading of the stored
* accounts
*/
public static void startBundleAndWaitStoredAccountsLoaded(
BundleContext bundleContextWithAccountManager,
final Bundle bundleToStart,
final String protocolNameToWait)
throws BundleException,
InterruptedException
{
AccountManager accountManager
= getAccountManager(bundleContextWithAccountManager);
final boolean[] storedAccountsAreLoaded = new boolean[1];
AccountManagerListener listener = new AccountManagerListener()
{
public void handleAccountManagerEvent(AccountManagerEvent event)
{
if (AccountManagerEvent.STORED_ACCOUNTS_LOADED
!= event.getType())
return;
ProtocolProviderFactory factory = event.getFactory();
/*
* If the event is for a factory with a protocol name other than
* protocolNameToWait, it's not the one we're waiting for.
*/
if ((factory != null)
&& !protocolNameToWait
.equals(factory.getProtocolName()))
return;
/*
* If the event if for a factory which is no longer registered,
* then it's not the one we're waiting for because we're waiting
* for the specified bundle to start and register a factory.
*/
if (factory != null)
{
BundleContext bundleContext
= bundleToStart.getBundleContext();
/*
* If the specified bundle still hasn't started, the event
* cannot be the one we're waiting for.
*/
if (bundleContext == null)
return;
Collection> factoryRefs;
try
{
factoryRefs
= bundleContext.getServiceReferences(
ProtocolProviderFactory.class,
"("
+ ProtocolProviderFactory.PROTOCOL
+ "="
+ protocolNameToWait
+ ")");
}
catch (InvalidSyntaxException isex)
{
/*
* Not likely so ignore it and assume the event is for
* a valid factory.
*/
factoryRefs = null;
}
if ((factoryRefs != null) && !factoryRefs.isEmpty())
{
boolean factoryIsRegistered = false;
for (ServiceReference factoryRef
: factoryRefs)
{
if (factory == bundleContext.getService(factoryRef))
{
factoryIsRegistered = true;
break;
}
}
if (!factoryIsRegistered)
return;
}
}
synchronized (storedAccountsAreLoaded)
{
storedAccountsAreLoaded[0] = true;
storedAccountsAreLoaded.notify();
}
}
};
accountManager.addListener(listener);
try
{
bundleToStart.start();
while (true)
{
synchronized (storedAccountsAreLoaded)
{
if (storedAccountsAreLoaded[0])
{
break;
}
storedAccountsAreLoaded.wait();
}
}
}
finally
{
accountManager.removeListener(listener);
}
}
/**
* Prevents the creation of AccountManagerUtils
instances.
*/
private AccountManagerUtils()
{
}
}