Skip to content

Commit

Permalink
SOLDER-94 fix thread safety issue
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Mar 24, 2011
1 parent 55a075f commit 54f078f
Showing 1 changed file with 44 additions and 47 deletions.
Expand Up @@ -16,81 +16,81 @@
*/
package org.jboss.seam.solder.beanManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jboss.seam.solder.util.Sortable;
import org.jboss.seam.solder.util.service.ServiceLoader;

import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import javax.inject.Inject;

import org.jboss.seam.solder.util.Sortable;
import org.jboss.seam.solder.util.service.ServiceLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
* <p>
* A utility for use in non-managed classes, which are not able to obtain a
* reference to the {@link BeanManager} using injection.
* </p>
*
*
* <p>
* {@link BeanManagerProvider} is an SPI that may be implemented to allow third
* parties to register custom methods of looking up the BeanManager in an
* external context. This class will consult implementations according to
* precedence.
* </p>
*
*
* <p>
* <b>**WARNING**</b> This class is <b>NOT</b> a clever way to get the
* BeanManager, and should be <b>avoided at all costs</b>. If you need a handle
* to the {@link BeanManager} you should probably register an {@link Extension}
* instead of using this class; have you tried using @{@link Inject}?
* </p>
*
*
* <p>
* If you think you need to use this class, chat to the community and make sure
* you aren't missing a trick!
* </p>
*
*
* @see BeanManagerProvider
* @see BeanManagerAware
*
*
* @author Pete Muir
* @author Nicklas Karlsson
* @author <a href="http://community.jboss.org/people/dan.j.allen">Dan Allen</a>
* @author Stuart Douglas
*/
public class BeanManagerLocator
{
private BeanManager beanManager;

private boolean lookupPerformed = false;

private BeanManagerProvider locatingProvider;
private volatile BeanManager beanManager;

private volatile boolean lookupPerformed = false;

private List<BeanManagerProvider> providers;
private volatile BeanManagerProvider locatingProvider;

private volatile List<BeanManagerProvider> providers;

/**
* If a lookup has not yet been performed, consult registered
* {@link BeanManagerProvider} implementations to locate the
* {@link BeanManager} and return the result. If the {@link BeanManager}
* cannot be resolved, throw a {@link BeanManagerUnavailableException}.
*
*
* @throws BeanManagerUnavailableException if the BeanManager cannot be resolved
* @return the BeanManager for the current bean archive
*/
public BeanManager getBeanManager()
{
if (!lookupPerformed)
{
beanManager = lookupBeanManager();
lookupBeanManager();
}

if (beanManager == null)
{
throw new BeanManagerUnavailableException(providers);
}

return beanManager;
}

Expand All @@ -99,62 +99,59 @@ public BeanManager getBeanManager()
* {@link BeanManagerProvider} implementations to locate the
* {@link BeanManager} and return whether it was found, caching
* the result.
*
*
* @return <code>true</code> if the bean manager has been found, otherwise
* <code>false</code>
*/
public boolean isBeanManagerAvailable()
{
if (!lookupPerformed)
{
beanManager = lookupBeanManager();
lookupBeanManager();
}

return beanManager != null;
}

/**
* Return the {@link BeanManagerProvider} that was used to
* locate the BeanManager. This method will not attempt
* a lookup.
*
*
* @return the BeanManagerProvider implementation
*/
public BeanManagerProvider getLocatingProvider()
{
return locatingProvider;
}

private BeanManager lookupBeanManager()
private synchronized void lookupBeanManager()
{
BeanManager beanManager = null;
if (providers == null)
{
loadServices();
if(!lookupPerformed) {
final List<BeanManagerProvider> providers = loadServices();
Collections.sort(providers, new Sortable.Comparator());
}

for (BeanManagerProvider provider : providers)
{
beanManager = provider.getBeanManager();
if (beanManager != null)
for (BeanManagerProvider provider : providers)
{
locatingProvider = provider;
break;
beanManager = provider.getBeanManager();
if (beanManager != null)
{
locatingProvider = provider;
break;
}
}
this.providers = providers;
lookupPerformed = true;
}

lookupPerformed = true;
return beanManager;
}
private void loadServices()

private List<BeanManagerProvider> loadServices()
{
providers = new ArrayList<BeanManagerProvider>();
List<BeanManagerProvider> providers = new ArrayList<BeanManagerProvider>();

for (Iterator<BeanManagerProvider> it = ServiceLoader.load(BeanManagerProvider.class).iterator(); it.hasNext();)
{
providers.add(it.next());
}
return providers;
}
}

0 comments on commit 54f078f

Please sign in to comment.