[weld-commits] Weld SVN: r6234 - in java-se/trunk/src/main/java/org/jboss/weld/environment/se: discovery and 2 other directories.

weld-commits at lists.jboss.org weld-commits at lists.jboss.org
Mon May 17 09:06:05 EDT 2010


Author: peteroyle
Date: 2010-05-17 09:06:04 -0400 (Mon, 17 May 2010)
New Revision: 6234

Added:
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/AbstractClassHandler.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/ClassHandler.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/FileSystemClassHandler.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/exceptions/
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/exceptions/ClasspathScanningException.java
Modified:
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/Weld.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/AbstractScanner.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEBeanDeploymentArchive.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDeployment.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDiscovery.java
   java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/URLScanner.java
Log:
WELDSE-26: Some way towards plugability of URLScanner to handle arbitrary 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(...).

Modified: java-se/trunk/src/main/java/org/jboss/weld/environment/se/Weld.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/Weld.java	2010-05-16 08:35:10 UTC (rev 6233)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/Weld.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -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;
@@ -50,6 +53,8 @@
    private Bootstrap bootstrap;
    private BeanStore applicationBeanStore;
    private WeldManager manager;
+   private SEWeldDiscovery discovery;
+   private SEBeanDeploymentArchive beanDeploymentArchive;
 
    public Weld()
    {
@@ -77,7 +82,13 @@
          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);
@@ -94,11 +105,28 @@
 
    }
 
+   /**
+    * 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)

Modified: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/AbstractScanner.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/AbstractScanner.java	2010-05-16 08:35:10 UTC (rev 6233)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/AbstractScanner.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -16,51 +16,24 @@
  */
 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()
    {
@@ -68,11 +41,11 @@
    }
 
    /**
-    * 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;
    }
 
 }

Modified: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEBeanDeploymentArchive.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEBeanDeploymentArchive.java	2010-05-16 08:35:10 UTC (rev 6233)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEBeanDeploymentArchive.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -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;
 
 /**
@@ -43,22 +42,15 @@
    /**
     * @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.
     */
    public Collection<Class<?>> getBeanClasses()

Modified: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDeployment.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDeployment.java	2010-05-16 08:35:10 UTC (rev 6233)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDeployment.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -27,26 +27,19 @@
  * 
  * @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}
     * 
     * @return A collection containing the singular logical BeanDeploymentArchive

Modified: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDiscovery.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDiscovery.java	2010-05-16 08:35:10 UTC (rev 6233)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/SEWeldDiscovery.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -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
@@ -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>();
    }
@@ -67,10 +63,4 @@
       return wbUrls;
    }
 
-   public void scan()
-   {
-      Scanner scanner = new URLScanner(deployment.getServices().get(ResourceLoader.class), this);
-      scanner.scanResources(new String[] { "META-INF/beans.xml" });
-   }
-   
 }

Modified: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/URLScanner.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/URLScanner.java	2010-05-16 08:35:10 UTC (rev 6233)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/URLScanner.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -16,19 +16,19 @@
  */
 package org.jboss.weld.environment.se.discovery;
 
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
 import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
+import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLDecoder;
 import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
+import java.util.HashMap;
+import java.util.Map;
+import org.jboss.weld.environment.se.discovery.handlers.ClassHandler;
+import org.jboss.weld.environment.se.discovery.handlers.FileSystemClassHandler;
+import org.jboss.weld.environment.se.exceptions.ClasspathScanningException;
 import org.jboss.weld.resources.spi.ResourceLoader;
 
 import org.slf4j.Logger;
@@ -41,162 +41,91 @@
  * @author Gavin King
  * @author Norman Richards
  * @author Pete Muir
+ * @author Peter Royle
  * 
  */
 public class URLScanner extends AbstractScanner
 {
+
+   private static final String FILE = "file";
+   private static final String JAR = "jar";
+   private final Map<String, ClassHandler> classHandlers = new HashMap<String, ClassHandler>();
    private static final Logger log = LoggerFactory.getLogger(URLScanner.class);
 
-   public URLScanner(ResourceLoader resourceLoader, SEWeldDiscovery webBeanDiscovery)
+   public URLScanner(ResourceLoader resourceLoader, SEWeldDiscovery weldDiscovery)
    {
-      super(resourceLoader, webBeanDiscovery);
+      super(resourceLoader, weldDiscovery);
+      ClassHandler fileSysHandler = new FileSystemClassHandler(resourceLoader, weldDiscovery);
+      classHandlers.put(FILE, fileSysHandler);
+      classHandlers.put(JAR, fileSysHandler);
    }
 
+   public void setClassHandler(String type, ClassHandler handler)
+   {
+      classHandlers.put(type, handler);
+   }
+
    public void scanDirectories(File[] directories)
    {
       for (File directory : directories)
       {
-         handleDirectory(directory, null);
+         // can only use a file-based scanner to scan directories
+         classHandlers.get(FILE).handleDirectory(directory);
       }
    }
 
    public void scanResources(String[] resources)
    {
-      Set<String> paths = new HashSet<String>();
-
+      Multimap<String, String> paths = HashMultimap.create();
       for (String resourceName : resources)
       {
-         try
+         // grab all the URLs for this resource
+         Collection<URL> urlEnum = getResourceLoader().getResources(resourceName);
+         for (URL url : urlEnum)
          {
-            Collection<URL> urlEnum = getResourceLoader().getResources(resourceName);
 
-            for (URL url : urlEnum)
+            String urlPath;
+            try
             {
-               String urlPath = url.getFile();
-               urlPath = URLDecoder.decode(urlPath, "UTF-8");
-
-               if (urlPath.startsWith("file:"))
-               {
-                  urlPath = urlPath.substring(5);
-               }
-
-               if (urlPath.indexOf('!') > 0)
-               {
-                  urlPath = urlPath.substring(0, urlPath.indexOf('!'));
-               }
-               else
-               {
-                  File dirOrArchive = new File(urlPath);
-
-                  if ((resourceName != null) && (resourceName.lastIndexOf('/') > 0))
-                  {
-                     // for META-INF/components.xml
-                     dirOrArchive = dirOrArchive.getParentFile();
-                  }
-
-                  urlPath = dirOrArchive.getParent();
-               }
-
-               paths.add(urlPath);
+               urlPath = URLDecoder.decode(url.toExternalForm(), "UTF-8");
+            } catch (UnsupportedEncodingException ex)
+            {
+               throw new ClasspathScanningException("Error decoding URL using UTF-8");
             }
-         }
-         catch (IOException ioe)
-         {
-            log.warn("could not read: " + resourceName, ioe);
-         }
-      }
-
-      handle(paths);
-   }
-
-   protected void handle(Set<String> paths)
-   {
-      for (String urlPath : paths)
-      {
-         try
-         {
-            log.trace("scanning: " + urlPath);
-
-            File file = new File(urlPath);
-
-            if (file.isDirectory())
+            String urlType = "file";
+            int colonIndex = urlPath.indexOf(":");
+            if (colonIndex != -1)
             {
-               handleDirectory(file, null);
+               urlType = urlPath.substring(0, colonIndex);
             }
-            else
+
+            // hack for /META-INF/beans.xml
+            if (urlPath.indexOf('!') == -1)
             {
-               handleArchiveByFile(file);
+               File dirOrArchive = new File(urlPath);
+               if ((resourceName != null) && (resourceName.lastIndexOf('/') > 0))
+               {
+                  dirOrArchive = dirOrArchive.getParentFile();
+               }
+               urlPath = dirOrArchive.getParent();
             }
-         }
-         catch (IOException ioe)
-         {
-            log.warn("could not read entries", ioe);
-         }
-      }
-   }
 
-   private void handleArchiveByFile(File file) throws IOException
-   {
-      try
-      {
-         log.trace("archive: " + file);
+            log.debug("URL Type: " + urlType);
 
-         String archiveUrl = "jar:" + file.toURI().toURL().toExternalForm() + "!/";
-         ZipFile zip = new ZipFile(file);
-         Enumeration<? extends ZipEntry> entries = zip.entries();
-
-         while (entries.hasMoreElements())
-         {
-            ZipEntry entry = entries.nextElement();
-            String name = entry.getName();
-            handle(name, new URL(archiveUrl + name));
+            paths.put(urlType, urlPath);
          }
       }
-      catch (ZipException e)
+      for (String urlType : paths.keySet())
       {
-         throw new RuntimeException("Error handling file " + file, e);
-      }
-   }
-
-   private void handleDirectory(File file, String path)
-   {
-      handleDirectory(file, path, new File[0]);
-   }
-
-   private void handleDirectory(File file, String path, File[] excludedDirectories)
-   {
-      for (File excludedDirectory : excludedDirectories)
-      {
-         if (file.equals(excludedDirectory))
+         Collection<String> urlPaths = paths.get(urlType);
+         ClassHandler handler = classHandlers.get(urlType);
+         if (handler == null)
          {
-            log.trace("skipping excluded directory: " + file);
-
-            return;
-         }
-      }
-
-      log.trace("handling directory: " + file);
-
-      for (File child : file.listFiles())
-      {
-         String newPath = (path == null) ? child.getName() : (path + '/' + child.getName());
-
-         if (child.isDirectory())
+            throw new ClasspathScanningException("No handler defined for URL type: " + urlType);
+         } else
          {
-            handleDirectory(child, newPath, excludedDirectories);
+            handler.handle(urlPaths);
          }
-         else
-         {
-            try
-            {
-               handle(newPath, child.toURI().toURL());
-            }
-            catch (MalformedURLException e)
-            {
-               log.error("Error loading file " + newPath);
-            }
-         }
       }
    }
-
 }

Added: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/AbstractClassHandler.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/AbstractClassHandler.java	                        (rev 0)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/AbstractClassHandler.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -0,0 +1,54 @@
+/**
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.environment.se.discovery.handlers;
+
+import org.jboss.weld.environment.se.discovery.SEWeldDiscovery;
+import org.jboss.weld.resources.spi.ResourceLoader;
+
+/**
+ *
+ * @author Peter Royle
+ */
+public abstract class AbstractClassHandler implements ClassHandler
+{
+
+   private final ResourceLoader resourceLoader;
+   private final SEWeldDiscovery weldDiscovery;
+
+   public AbstractClassHandler(ResourceLoader resourceLoader, SEWeldDiscovery webBeanDiscovery)
+   {
+      this.resourceLoader = resourceLoader;
+      this.weldDiscovery = webBeanDiscovery;
+   }
+
+   /**
+    * @return the resourceLoader
+    */
+   public ResourceLoader getResourceLoader()
+   {
+      return resourceLoader;
+   }
+
+   /**
+    * @return the webBeanDiscovery
+    */
+   public SEWeldDiscovery getWeldDiscovery()
+   {
+      return weldDiscovery;
+   }
+   
+}

Added: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/ClassHandler.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/ClassHandler.java	                        (rev 0)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/ClassHandler.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -0,0 +1,32 @@
+/**
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.environment.se.discovery.handlers;
+
+import java.io.File;
+import java.util.Collection;
+
+/**
+ * Interface for handling class resolving.
+ * @author Peter Royle
+ */
+public interface ClassHandler {
+
+   void handle(Collection<String> paths);
+
+   void handleDirectory(File file);
+
+}

Copied: java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/FileSystemClassHandler.java (from rev 6232, java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/AbstractScanner.java)
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/FileSystemClassHandler.java	                        (rev 0)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/discovery/handlers/FileSystemClassHandler.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -0,0 +1,175 @@
+/**
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.environment.se.discovery.handlers;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import org.jboss.weld.environment.se.discovery.SEWeldDiscovery;
+import org.jboss.weld.environment.se.discovery.Scanner;
+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
+ * 
+ */
+public class FileSystemClassHandler extends AbstractClassHandler
+{
+
+   private static final Logger log = LoggerFactory.getLogger(FileSystemClassHandler.class);
+
+   public FileSystemClassHandler(ResourceLoader resourceLoader, SEWeldDiscovery webBeanDiscovery)
+   {
+      super(resourceLoader, webBeanDiscovery);
+   }
+
+   public void handle(Collection<String> paths)
+   {
+      for (String urlPath : paths)
+      {
+         try
+         {
+            FileSystemClassHandler.log.trace("scanning: " + urlPath);
+
+            if (urlPath.startsWith("file:"))
+            {
+               urlPath = urlPath.substring(5);
+            }
+            if (urlPath.indexOf('!') > 0)
+            {
+               urlPath = urlPath.substring(0, urlPath.indexOf('!'));
+            }
+
+            File file = new File(urlPath);
+            if (file.isDirectory())
+            {
+               handleDirectory(file, null);
+            } else
+            {
+               handleArchiveByFile(file);
+            }
+         } catch (IOException ioe)
+         {
+            FileSystemClassHandler.log.warn("could not read entries", ioe);
+         }
+      }
+   }
+
+   private void handleArchiveByFile(File file) throws IOException
+   {
+      try
+      {
+         log.trace("archive: " + file);
+
+         String archiveUrl = "jar:" + file.toURI().toURL().toExternalForm() + "!/";
+         ZipFile zip = new ZipFile(file);
+         Enumeration<? extends ZipEntry> entries = zip.entries();
+
+         while (entries.hasMoreElements())
+         {
+            ZipEntry entry = entries.nextElement();
+            String name = entry.getName();
+            handle(name, new URL(archiveUrl + name));
+         }
+      } catch (ZipException e)
+      {
+         throw new RuntimeException("Error handling file " + file, e);
+      }
+   }
+
+   public void handleDirectory(File file)
+   {
+      handleDirectory(file, null);
+   }
+
+   protected void handleDirectory(File file, String path)
+   {
+      handleDirectory(file, path, new File[0]);
+   }
+
+   private void handleDirectory(File file, String path, File[] excludedDirectories)
+   {
+      for (File excludedDirectory : excludedDirectories)
+      {
+         if (file.equals(excludedDirectory))
+         {
+            log.trace("skipping excluded directory: " + file);
+
+            return;
+         }
+      }
+
+      log.trace("handling directory: " + file);
+
+      for (File child : file.listFiles())
+      {
+         String newPath = (path == null) ? child.getName() : (path + '/' + child.getName());
+
+         if (child.isDirectory())
+         {
+            handleDirectory(child, newPath, excludedDirectories);
+         } else
+         {
+            try
+            {
+               handle(newPath, child.toURI().toURL());
+            } catch (MalformedURLException e)
+            {
+               log.error("Error loading file " + newPath);
+            }
+         }
+      }
+   }
+
+   protected void handle(String name, URL url)
+   {
+      if (name.endsWith(".class"))
+      {
+         String className = filenameToClassname(name);
+         try
+         {
+            getWeldDiscovery().getWbClasses().add(getResourceLoader().classForName(className));
+         } catch (NoClassDefFoundError e)
+         {
+            log.error("Error loading " + name, e);
+         }
+      } else if (name.endsWith("beans.xml"))
+      {
+         getWeldDiscovery().getWbUrls().add(url);
+      }
+   }
+
+   /**
+    * Convert a path to a class file to a class name
+    */
+   public static String filenameToClassname(String filename)
+   {
+      return filename.substring(0, filename.lastIndexOf(".class")).replace('/', '.').replace('\\', '.');
+   }
+}

Added: java-se/trunk/src/main/java/org/jboss/weld/environment/se/exceptions/ClasspathScanningException.java
===================================================================
--- java-se/trunk/src/main/java/org/jboss/weld/environment/se/exceptions/ClasspathScanningException.java	                        (rev 0)
+++ java-se/trunk/src/main/java/org/jboss/weld/environment/se/exceptions/ClasspathScanningException.java	2010-05-17 13:06:04 UTC (rev 6234)
@@ -0,0 +1,38 @@
+/**
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.environment.se.exceptions;
+
+/**
+ * @author Peter Royle
+ */
+public class ClasspathScanningException extends RuntimeException {
+
+    /**
+     * Creates a new instance of <code>ClasspathScanningException</code> without detail message.
+     */
+    public ClasspathScanningException() {
+    }
+
+
+    /**
+     * Constructs an instance of <code>ClasspathScanningException</code> with the specified detail message.
+     * @param msg the detail message.
+     */
+    public ClasspathScanningException(String msg) {
+        super(msg);
+    }
+}



More information about the weld-commits mailing list