Skip to content

Commit

Permalink
WELDSE-26: Some way towards plugability of URLScanner to handle arbit…
Browse files Browse the repository at this point in the history
…rary URLs in various environments. Existing file-system based scanning code has been extracted into a built-in plugin (FileSystemClassHandler) which is automatically registered to handle file:// and jar:// URLs. Custom implementations of ClassHandler can be created and registered programatically by subclassinf Weld and overriding customiseClassHandlers(...).
  • Loading branch information
peteroyle committed May 17, 2010
1 parent d4e9455 commit e91ce1c
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 198 deletions.
36 changes: 32 additions & 4 deletions src/main/java/org/jboss/weld/environment/se/Weld.java
Expand Up @@ -24,7 +24,10 @@
import org.jboss.weld.context.api.BeanStore;
import org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore;
import org.jboss.weld.environment.se.beans.InstanceManager;
import org.jboss.weld.environment.se.discovery.SEBeanDeploymentArchive;
import org.jboss.weld.environment.se.discovery.SEWeldDeployment;
import org.jboss.weld.environment.se.discovery.SEWeldDiscovery;
import org.jboss.weld.environment.se.discovery.URLScanner;
import org.jboss.weld.environment.se.util.WeldManagerUtils;
import org.jboss.weld.manager.api.WeldManager;
import org.jboss.weld.resources.DefaultResourceLoader;
Expand All @@ -50,6 +53,8 @@ public class Weld
private Bootstrap bootstrap;
private BeanStore applicationBeanStore;
private WeldManager manager;
private SEWeldDiscovery discovery;
private SEBeanDeploymentArchive beanDeploymentArchive;

public Weld()
{
Expand Down Expand Up @@ -77,7 +82,13 @@ public WeldContainer initialize()
throw new IllegalStateException("Error loading Weld bootstrap, check that Weld is on the classpath", ex);
}

deployment.scan();
final ResourceLoader resourceLoader = deployment.getServices().get(ResourceLoader.class);
URLScanner scanner = new URLScanner(resourceLoader, discovery);
configureClassHandlers(scanner, resourceLoader, discovery);
scanner.scanResources(new String[]
{
"META-INF/beans.xml"
});

bootstrap.startContainer(Environments.SE, deployment, this.applicationBeanStore);
final BeanDeploymentArchive mainBeanDepArch = deployment.getBeanDeploymentArchives().get(0);
Expand All @@ -94,11 +105,28 @@ public WeldContainer initialize()

}

/**
* Clients can subclass and override this method to add custom class handlers
* before weld boots up. For example, to set a custom class handler for OSGi bundles,
* you would subclass Weld like so:
* <code>
* public class MyWeld extends Weld {
* @Override
* public void configureClassHandlers(URLScanner scanner, ResourceLoader resourceLoader, SEWeldDiscovery discovery)
* scanner.setClassHandler("bundle", new MyOSGiClassHandler(bundleClassLoader));
* }
* }
* </code>
*/
public void configureClassHandlers(URLScanner scanner, ResourceLoader resourceLoader, SEWeldDiscovery discovery)
{
}

private SEWeldDeployment initDeployment()
{
SEWeldDeployment deployment = new SEWeldDeployment()
{
};
discovery = new SEWeldDiscovery();
beanDeploymentArchive = new SEBeanDeploymentArchive(discovery);
SEWeldDeployment deployment = new SEWeldDeployment(beanDeploymentArchive);
configureDeployment(deployment);
// configure a ResourceLoader if one hasn't been already
if (deployment.getServices().get(ResourceLoader.class) == null)
Expand Down
Expand Up @@ -16,63 +16,36 @@
*/
package org.jboss.weld.environment.se.discovery;

import java.net.URL;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Abstract base class for {@link Scanner} providing common functionality
*
* This class provides file-system orientated scanning
*
* @author Pete Muir
*
*
* @author Peter Royle
*/
public abstract class AbstractScanner implements Scanner
{

private static final Logger log = LoggerFactory.getLogger(Scanner.class);
private final ResourceLoader resourceLoader;
private final SEWeldDiscovery webBeanDiscovery;
private final SEWeldDiscovery weldDiscovery;

public AbstractScanner(ResourceLoader resourceLoader, SEWeldDiscovery webBeanDiscovery)
{
this.resourceLoader = resourceLoader;
this.webBeanDiscovery = webBeanDiscovery;
this.weldDiscovery = webBeanDiscovery;
}

protected void handle(String name, URL url)
{
if (name.endsWith(".class"))
{
String className = filenameToClassname(name);
try
{
webBeanDiscovery.getWbClasses().add(getResourceLoader().classForName(className));
}
catch (NoClassDefFoundError e)
{
log.error("Error loading " + name, e);
}
}
else if (name.endsWith("beans.xml"))
{
webBeanDiscovery.getWbUrls().add(url);
}
}

public ResourceLoader getResourceLoader()
{
return resourceLoader;
}

/**
* Convert a path to a class file to a class name
* @return the webBeanDiscovery
*/
public static String filenameToClassname(String filename)
public SEWeldDiscovery getWebBeanDiscovery()
{
return filename.substring(0, filename.lastIndexOf(".class")).replace('/', '.').replace('\\', '.');
return weldDiscovery;
}

}
Expand Up @@ -24,7 +24,6 @@
import org.jboss.weld.bootstrap.api.ServiceRegistry;
import org.jboss.weld.bootstrap.api.helpers.SimpleServiceRegistry;
import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.ejb.spi.EjbDescriptor;

/**
Expand All @@ -43,21 +42,14 @@ public class SEBeanDeploymentArchive implements BeanDeploymentArchive
/**
* @param deployment Used to gain access to the ResourceLoader, in case one is defined.
*/
public SEBeanDeploymentArchive(Deployment deployment)
public SEBeanDeploymentArchive(SEWeldDiscovery discovery)
{
this.wbDiscovery = new SEWeldDiscovery(deployment)
this.wbDiscovery = discovery;
{
};
this.serviceRegistry = new SimpleServiceRegistry();
}

/**
* Perform the class scanning.
*/
public void scan() {
wbDiscovery.scan();
}

/**
* @return a collection of all Bean classes on the classpath.
*/
Expand Down
Expand Up @@ -27,25 +27,18 @@
*
* @author Peter Royle
*/
public abstract class SEWeldDeployment implements Deployment
public class SEWeldDeployment implements Deployment
{
private final SEBeanDeploymentArchive beanDeploymentArchive;
private final List<BeanDeploymentArchive> archInCollection;

public SEWeldDeployment()
public SEWeldDeployment(SEBeanDeploymentArchive beanDeploymentArchive)
{
this.beanDeploymentArchive = new SEBeanDeploymentArchive(this);
this.beanDeploymentArchive = beanDeploymentArchive;
this.archInCollection = new ArrayList<BeanDeploymentArchive>(1);
this.archInCollection.add(this.beanDeploymentArchive);
}

/**
* Perform the class scanning.
*/
public void scan() {
this.beanDeploymentArchive.scan();
}

/**
* {@inheritDoc}
*
Expand Down
Expand Up @@ -22,8 +22,6 @@
import java.util.HashSet;
import java.util.Set;

import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.resources.spi.ResourceLoader;

/**
* The means by which beans are discovered on the classpath. This will only
Expand All @@ -33,16 +31,14 @@
* @author Pete Muir
* @author Ales Justin
*/
public abstract class SEWeldDiscovery
public class SEWeldDiscovery
{

private final Deployment deployment;
private final Set<Class<?>> wbClasses;
private final Set<URL> wbUrls;

public SEWeldDiscovery(Deployment deployment)
public SEWeldDiscovery()
{
this.deployment = deployment;
this.wbClasses = new HashSet<Class<?>>();
this.wbUrls = new HashSet<URL>();
}
Expand All @@ -67,10 +63,4 @@ public Set<URL> getWbUrls()
return wbUrls;
}

public void scan()
{
Scanner scanner = new URLScanner(deployment.getServices().get(ResourceLoader.class), this);
scanner.scanResources(new String[] { "META-INF/beans.xml" });
}

}

0 comments on commit e91ce1c

Please sign in to comment.