Package org.jboss.seam.deployment

Source Code of org.jboss.seam.deployment.Scanner

//$Id: Scanner.java,v 1.29 2007/06/21 05:27:27 gavin Exp $
package org.jboss.seam.deployment;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
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 javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.annotation.MemberValue;

import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;

/**
* Abstract class for scanning archives in the
* Seam classpath.
*
* @author Thomas Heute
* @author Gavin King
* @author Norman Richards
*
*/
public abstract class Scanner
{
    private static final LogProvider log = Logging.getLogProvider(Scanner.class);

    protected String resourceName;
    protected ClassLoader classLoader;
  
   public Scanner(String resourceName)
   {
      this( resourceName, Thread.currentThread().getContextClassLoader() );
   }
  
   public Scanner(String resourceName, ClassLoader classLoader)
   {
      this.resourceName = resourceName;
      this.classLoader = classLoader;
      ClassFile.class.getPackage(); //to force loading of javassist, throwing an exception if it is missing
   }
  
   public static String filenameToClassname(String filename)
   {
      return filename.substring( 0, filename.lastIndexOf(".class") )
            .replace('/', '.').replace('\\', '.');
   }
  
   public static String filenameToPackage(String filename)
   {
      return filename.substring( 0, filename.lastIndexOf(".class") )
            .replace('/', '.').replace('\\', '.');
   }

    protected void scan()
    {
      Set<String> paths = new HashSet<String>();
      if (resourceName==null)
      {
         for ( URL url: getURLsFromClassLoader() )
         {
            String urlPath = url.getFile();
            if ( urlPath.endsWith("/") )
            {
               urlPath = urlPath.substring( 0, urlPath.length()-1 );
            }
            paths.add( urlPath );
         }
      }
      else
      {
         try
         {
            Enumeration<URL> urlEnum = classLoader.getResources(resourceName);
            while ( urlEnum.hasMoreElements() )
            {
               String urlPath = urlEnum.nextElement().getFile();
               urlPath = URLDecoder.decode(urlPath, "UTF-8");
               if ( urlPath.startsWith("file:") )
               {
                  // On windows urlpath looks like file:/C: on Linux file:/home
                  // substring(5) works for both
                  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);
            }
         }
         catch (IOException ioe)
         {
            log.warn("could not read: " + resourceName, ioe);
            return;
         }
      }
     
      for ( String urlPath: paths )
      {
         try
         {
            log.info("scanning: " + urlPath);
            File file = new File(urlPath);
            if ( file.isDirectory() )
            {
               handleDirectory(file, null);
            }
            else
            {
               handleArchive(file);
            }
         }
         catch (IOException ioe)
         {
            log.warn("could not read entries", ioe);
         }
      }
   }

   protected URL[] getURLsFromClassLoader()
   {
      return ( (URLClassLoader) classLoader ).getURLs();
   }


   private void handleArchive(File file) throws ZipException, IOException
   {
      log.debug("archive: " + file);
      ZipFile zip = new ZipFile(file);
      Enumeration<? extends ZipEntry> entries = zip.entries();
      while ( entries.hasMoreElements() )
      {
         ZipEntry entry = entries.nextElement();
         String name = entry.getName();
         log.debug("found: " + name);
         handleItem(name);
      }
   }

   private void handleDirectory(File file, String path)
   {
      log.debug("directory: " + file);
      for ( File child: file.listFiles() )
      {
         String newPath = path==null ?
                  child.getName() : path + '/' + child.getName();
         if ( child.isDirectory() )
         {
            handleDirectory(child, newPath);
         }
         else
         {
            handleItem(newPath);
         }
      }
   }

   abstract void handleItem(String name);

   protected ClassFile getClassFile(String name) throws IOException
   {
      InputStream stream = classLoader.getResourceAsStream(name);
      DataInputStream dstream = new DataInputStream(stream);

      try
      {
         return new ClassFile(dstream);
      }
      finally
      {
         dstream.close();
         stream.close();
      }
   }
  
   protected boolean hasAnnotation(ClassFile cf, Class<? extends Annotation> annotationType)
   {
      AnnotationsAttribute visible = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag );
      if ( visible != null )
      {
         return visible.getAnnotation( annotationType.getName() ) != null;
      }
      return false;
   }

   protected String getAnnotationValue(ClassFile cf, Class<? extends Annotation> annotationType, String memberName)
   {
      AnnotationsAttribute visible = (AnnotationsAttribute) cf.getAttribute( AnnotationsAttribute.visibleTag );
      if ( visible != null )
      {
         javassist.bytecode.annotation.Annotation annotation = visible.getAnnotation( annotationType.getName() );
         if (annotation==null)
         {
            return null;
         }
         else
         {
            MemberValue memberValue = annotation.getMemberValue(memberName);
            return memberValue==null ? null : memberValue.toString(); //TODO: toString() here is probably Bad ;-)
         }
      }
      else
      {
         return null;
      }
   }

   public static String componentFilename(String name)
   {
      return name.substring( 0, name.lastIndexOf(".class") ) + ".component.xml";
   }

}
TOP

Related Classes of org.jboss.seam.deployment.Scanner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.