FileDocCategorySizeDatePackage
StaticWeaveProcessor.javaAPI DocGlassfish v2 API15409Tue May 22 16:54:56 BST 2007oracle.toplink.essentials.weaving

StaticWeaveProcessor

public class StaticWeaveProcessor extends Object

Description: The StaticWeaveProcessor controls the static weaving process. It is invoked by both the command line StaticWeave class and the StaticWeaveAntTask.

Responsibilities:Process the source classes, performs weaving as necessary out outputs to the target

Fields Summary
private URL
source
private URL
target
private URL
persistenceInfo
private Writer
logWriter
private ClassLoader
classLoader
private int
logLevel
Constructors Summary
public StaticWeaveProcessor(String source, String target)
Constructs an instance of StaticWeaveProcessor

param
source the name of the location to be weaved
param
target the name of the location to be weaved to
throws
MalformedURLException

 
    
                                     
        
        if (source!=null){
            this.source=new File(source).toURL();
        }
        if (target!=null){
            this.target=new File(target).toURL();
        }
    
public StaticWeaveProcessor(File source, File target)
Constructs an instance of StaticWeaveProcessor

param
source the File object of the source to be weaved
param
target the File object of the target to be weaved to
throws
MalformedURLException

        this.source=source.toURL();
        this.target=target.toURL();
    
public StaticWeaveProcessor(URL source, URL target)
Constructs an instance of StaticWeaveProcessor

param
source the URL of the source to be weaved
param
target the URL of the target to be weaved to

        this.source=source;
        this.target=target;
    
Methods Summary
public static java.lang.StringgetDirectoryFromEntryName(java.lang.String entryName)

        String result="";
        if (entryName==null ) {
            return result;
        }
        if(entryName.lastIndexOf("/")>=0){
            result=entryName.substring(0, entryName.lastIndexOf("/"))+File.separator;
        } 
        return result;
    
private java.net.URL[]getURLs()

        if((this.source!=null) && (this.persistenceInfo!=null)){
            return new URL[]{this.persistenceInfo,this.source};
        } else if(this.source!=null){
            return new URL[]{this.source};
        } else if (this.persistenceInfo!=null){
            return new URL[]{this.persistenceInfo};
        }
        return new URL[]{};
    
private booleanisDirectory(java.net.URL url)

        File file = new File(url.toURI());
        if (file.isDirectory()) {
            return true;
        }else{
            return false;
        }
    
public voidperformWeaving()
This method performs weaving function on the class individually from the specified source.

throws
Exception.

        preProcess();
        process();
    
private voidpreProcess()

        //Instantiate default session log
        AbstractSessionLog.getLog().setLevel(this.logLevel);
        if(logWriter!=null){
            ((DefaultSessionLog)AbstractSessionLog.getLog()).setWriter(logWriter);
        }

        //Make sure the source is existing
        if(!(new File(source.toURI())).exists()){
            throw StaticWeaveException.missingSource();
        }
        
        //Verification target and source, two use cases create warning or exception.
        //1. If source is directory and target is jar - 
        //   This will lead unkown outcome, user attempt to use this tool to pack outcome into a Jar. 
        //   Warning message will be logged, this is can be workarounded by other utilities.
        //2. Both source and target are specified as a same jar -  
        //   User was tryint to perform waving in same Jar which is not support, Exception will be thrown.
        if(isDirectory(source) && target.toURI().toString().endsWith(".jar")){
            AbstractSessionLog.getLog().log(SessionLog.WARNING, ToStringLocalization.buildMessage("staticweave_processor_unknown_outcome", new Object[]{null}));
        }
        
        if(!isDirectory(source) && target.toString().equals(source.toString())){
            throw StaticWeaveException.weaveInplaceForJar(source.toString());
        }
        
        //pre-create target if it is directory and dose not exsit.
        //Using the method File.isDirectory() is not enough to determine what the type(dir or jar) 
        //of the target(specified by URL)that user want to create. File.isDirectory() will return false in 
        //two possibilities, the location either is not directory or the location dose not exist. 
        //Therefore pre-build of the directory target is required. Pre-build for the file(JAR) target 
        //is not required since it gets built automically by opening outputstream.  
        if(!(new File(target.toURI())).exists()){
            if(!target.toURI().toString().endsWith(".jar")){
                (new File(target.toURI())).mkdirs();
                //if directory fails to build, which may leads to unknown outcome since it will 
                //be treated as single file in the class StaticWeaveHandler and automicatlly gets built
                //by outputstream.

                //re-assign URL.
                target = (new File(target.toURI())).toURL();
            }
        }
    
private voidprocess()

        //Instantiate output handler
        AbstractStaticWeaveOutputHandler swoh;
        if(isDirectory(this.target)){
            swoh= new StaticWeaveDirectoryOutputHandler(this.source,this.target);
        }else{
            swoh= new StaticWeaveJAROutputHandler(new JarOutputStream(new FileOutputStream(new File(this.target.toURI()))));
        }
        
        //Instantiate classloader
        this.classLoader = (this.classLoader == null)? Thread.currentThread().getContextClassLoader():this.classLoader;
        this.classLoader = new URLClassLoader(getURLs(), this.classLoader);
        
        //Instantiate the classtransformer, we check if the persistenceinfo URL has been specified.
        StaticWeaveClassTransformer classTransformer=null;
        if(persistenceInfo!=null){
            classTransformer = new StaticWeaveClassTransformer(persistenceInfo, this.classLoader,this.logWriter,this.logLevel);
        } else{
            classTransformer = new StaticWeaveClassTransformer(source, this.classLoader,this.logWriter,this.logLevel);
        }

        //Starting process...
        Archive sourceArchive =(new ArchiveFactoryImpl()).createArchive(source);
        Iterator entries = sourceArchive.getEntries();
        while (entries.hasNext()){
            String entryName = (String)entries.next();
            InputStream entryInputStream = sourceArchive.getEntry(entryName);
            String className = PersistenceUnitProcessor.buildClassNameFromEntryString(entryName) ;
            
            //Add a directory entry
            swoh.addDirEntry(getDirectoryFromEntryName(entryName));
            
            //Add a regular entry
            JarEntry newEntry = new JarEntry(entryName);
            
            byte[] originalClassBytes=null;
            byte[] transferredClassBytes=null;
            try {
                Class thisClass = this.classLoader.loadClass(className);
                //if the class is not in the classpath, we simply copy the entry
                //to the target(no weaving).
                if (thisClass == null){
                    swoh.addEntry(entryInputStream, newEntry);
                    continue;
                }
                
                //Try to read the loaded class bytes, the class bytes is required for
                //classtransformer to perform transfer. Simply copy entry to the target(no weaving)
                //if the class bytes can't be read.
                InputStream is = this.classLoader.getResourceAsStream(entryName);
                if (is!=null){
                    originalClassBytes = new byte[is.available()];
                    is.read(originalClassBytes);
                }else{
                    swoh.addEntry(entryInputStream, newEntry);
                    continue;
                }
                
                //If everything is OK so far, we perform the weaving. we need three paramteres in order to
                //class to perform weaving for that class, the class name,the class object and class bytes.
                transferredClassBytes = classTransformer.transform(className.replace('.", '/"), thisClass, originalClassBytes);
                
                //if transferredClassBytes is null means the class dose not get woven.
                if(transferredClassBytes!=null){
                    swoh.addEntry(newEntry, transferredClassBytes);
                } else{
                    swoh.addEntry(entryInputStream, newEntry);
                }
            } catch (IllegalClassFormatException e) {
                //Anything went wrong, we need log a warning message, copy the entry to the target and
                //process next entry.
                swoh.addEntry(entryInputStream, newEntry);
                continue;
            } catch (ClassNotFoundException e){
                swoh.addEntry(entryInputStream, newEntry);
                continue;
            }finally{
                //need close the inputstream for current entry before processing next one. 
                entryInputStream.close();
            }
        }
        swoh.closeOutputStream();
    
public voidsetClassLoader(java.lang.ClassLoader classLoader)
Set the user classloader.

param
classLoader

        this.classLoader=classLoader;
    
public voidsetLog(java.io.Writer logWriter)
The method allows user to specify the ouput for the log message.

param
log writer - the lcation where the log message writes to. the default value is standardout

        this.logWriter= logWriter;
    
public voidsetLogLevel(int level)
The method allows user to define nine levels toplink logging.

param
level - the integer value of log level. default is OFF.

        this.logLevel=level;
    
public voidsetPersistenceInfo(java.net.URL persistenceInfo)
Set an explicitly identified URL of the location containing persistence.xml.

param
persistenceInfo the URL of the location containing persistence.xml, the URL must point to the root of META-INF/persistence.xml

             this.persistenceInfo = persistenceInfo;
    
public voidsetPersistenceInfo(java.lang.String persistenceInfoPath)
Set an explicitly identified the location containing persistence.xml.

param
persistenceinfo the path of the location containing persistence.xml, the path must point to the root of META-INF/persistence.xml

        if (persistenceInfoPath!=null){
            this.persistenceInfo=new File(persistenceInfoPath).toURL();
        }
    
public voidsetPersistenceInfo(java.io.File persistenceInfoFile)
Set an explicitly identified the location containing persistence.xml.

param
persistenceinfo the file containing persistence.xml, the file should contain META-INF/persistence.xml

        if (persistenceInfoFile!=null){
            this.persistenceInfo=persistenceInfoFile.toURL();
        }