/*
 * See LICENSE.TXT.
 */
package org.apachextras.camel.jboss;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Set;

import org.apache.camel.impl.DefaultPackageScanClassResolver;
import org.apache.camel.spi.PackageScanFilter;
import org.jboss.vfs.VFS;
import org.jboss.vfs.VirtualFile;
import org.jboss.vfs.VisitorAttributes;
import org.jboss.vfs.util.AbstractVirtualFileVisitor;

/**
 * JBoss specific package scan classloader to be used when Camel is running
 * inside JBoss Application Server.
 */
public class JBossPackageScanClassResolver extends DefaultPackageScanClassResolver {

    @Override
    protected void find(PackageScanFilter test, String packageName, ClassLoader loader, Set<Class<?>> classes) {
        if (log.isTraceEnabled()) {
            log.trace("Searching for: " + test + " in package: " + packageName
                    + " using classloader: " + loader.getClass().getName());
        }

        Enumeration<URL> urls;
        try {
            urls = getResources(loader, packageName);
            if (!urls.hasMoreElements()) {
                log.trace("No URLs returned by classloader");
            }
        } catch (IOException ioe) {
            log.warn("Could not read package: " + packageName, ioe);
            return;
        }

        while (urls.hasMoreElements()) {
            URL url = null;
            try {
                url = urls.nextElement();
                if (log.isTraceEnabled()) {
                    log.trace("URL from classloader: " + url);
                }
                VirtualFile packageNode = VFS.getChild(url.toURI());
                packageNode.visit(new MatchingClassVisitor(test, classes));
            } catch (IOException ioe) {
                log.warn("Could not read entries in url: " + url, ioe);
            } catch (URISyntaxException use) {
                log.warn("Could not read entries in url: " + url, use);
            }
        }
    }

    private final class MatchingClassVisitor extends AbstractVirtualFileVisitor {
        private PackageScanFilter _filter;
        private Set<Class<?>> _classes;

        private MatchingClassVisitor(PackageScanFilter filter, Set<Class<?>> classes) {
            super(VisitorAttributes.RECURSE_LEAVES_ONLY);
            this._filter = filter;
            this._classes = classes;
        }

        public void visit(VirtualFile file) {
            if (file.getName().endsWith(".class")) {
                String fqn = file.getPathName();
                String qn;
                if (fqn.indexOf("jar/") != -1) {
                    qn = fqn.substring(fqn.indexOf("jar/") + 4);
                } else {
                    qn = fqn.substring(fqn.indexOf("/") + 1);
                }

                addIfMatching(_filter, qn, _classes);
            }
        }
    }

}

@@ -301,24 +301,25 @@
 ScanFilter;%0A
+%0A
 import org.j
@@ -908,36 +908,16 @@
 kageName
-%0A                   
  + %22 usi
@@ -933,16 +933,36 @@
 oader: %22
+%0A                   
  + loade
@@ -1266,37 +1266,34 @@
      log.warn(%22C
-ould 
+an
 not read package
@@ -1414,54 +1414,8 @@
 rl =
- null;%0A            try %7B%0A                url =
  url
@@ -1427,28 +1427,25 @@
 tElement();%0A
-    
+%0A
             
@@ -1480,36 +1480,32 @@
                 
-   
- 
 log.trace(%22URL f
@@ -1528,32 +1528,42 @@
  %22 + url);%0A     
+       %7D%0A%0A
            %7D%0A   
@@ -1549,33 +1549,95 @@
   %7D%0A%0A           
-%7D
+ if (url.toString().startsWith(%22vfs:%22)) %7B%0A                try %7B
 %0A               
@@ -1637,16 +1637,20 @@
         
+    
 VirtualF
@@ -1690,24 +1690,28 @@
 l.toURI());%0A
+    
             
@@ -1778,32 +1778,36 @@
 ));%0A            
+   
+ 
 %7D catch (IOExcep
@@ -1810,32 +1810,36 @@
 xception ioe) %7B%0A
+    
                 
@@ -1898,32 +1898,36 @@
 e);%0A            
+    
 %7D catch (URISynt
@@ -1953,32 +1953,36 @@
                 
+ 
+   
 log.warn(%22Could 
@@ -2017,24 +2017,42 @@
  url, use);%0A
+                %7D%0A
             

Add AS6 container testing