FileDocCategorySizeDatePackage
BasicInstrumentationTask.javaAPI DocHibernate 3.2.511793Thu Aug 03 15:35:26 BST 2006org.hibernate.tool.instrument

BasicInstrumentationTask

public abstract class BasicInstrumentationTask extends org.apache.tools.ant.Task
Super class for all Hibernate instrumentation tasks. Provides the basic templating of how instrumentation should occur.
author
Steve Ebersole

Fields Summary
private static final int
ZIP_MAGIC
private static final int
CLASS_MAGIC
protected final Logger
logger
private List
filesets
private Set
classNames
private boolean
extended
private boolean
verbose
Constructors Summary
Methods Summary
public voidaddFileset(org.apache.tools.ant.types.FileSet set)


	    
		this.filesets.add( set );
	
protected final booleancheckMagic(java.io.File file, long magic)

        DataInputStream in = new DataInputStream( new FileInputStream( file ) );
        try {
            int m = in.readInt();
            return magic == m;
        }
        finally {
            in.close();
        }
    
private voidcollectClassNames()

		logger.info( "collecting class names for extended instrumentation determination" );
		Project project = getProject();
		Iterator filesets = filesets();
		while ( filesets.hasNext() ) {
			FileSet fs = ( FileSet ) filesets.next();
			DirectoryScanner ds = fs.getDirectoryScanner( project );
			String[] includedFiles = ds.getIncludedFiles();
			File d = fs.getDir( project );
			for ( int i = 0; i < includedFiles.length; ++i ) {
				File file = new File( d, includedFiles[i] );
				try {
					collectClassNames( file );
				}
				catch ( Exception e ) {
					throw new BuildException( e );
				}
			}
		}
		logger.info( classNames.size() + " class(es) being checked" );
	
private voidcollectClassNames(java.io.File file)

	    if ( isClassFile( file ) ) {
			byte[] bytes = ByteCodeHelper.readByteCode( file );
			ClassDescriptor descriptor = getClassDescriptor( bytes );
		    classNames.add( descriptor.getName() );
	    }
	    else if ( isJarFile( file ) ) {
		    ZipEntryHandler collector = new ZipEntryHandler() {
			    public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
					if ( !entry.isDirectory() ) {
						// see if the entry represents a class file
						DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
						if ( din.readInt() == CLASS_MAGIC ) {
				            classNames.add( getClassDescriptor( byteCode ).getName() );
						}
					}
			    }
		    };
		    ZipFileProcessor processor = new ZipFileProcessor( collector );
		    processor.process( file );
	    }
	
public voidexecute()

		if ( isExtended() ) {
			collectClassNames();
		}
		logger.info( "starting instrumentation" );
		Project project = getProject();
		Iterator filesets = filesets();
		while ( filesets.hasNext() ) {
			FileSet fs = ( FileSet ) filesets.next();
			DirectoryScanner ds = fs.getDirectoryScanner( project );
			String[] includedFiles = ds.getIncludedFiles();
			File d = fs.getDir( project );
			for ( int i = 0; i < includedFiles.length; ++i ) {
				File file = new File( d, includedFiles[i] );
				try {
					processFile( file );
				}
				catch ( Exception e ) {
					throw new BuildException( e );
				}
			}
		}
	
protected final java.util.Iteratorfilesets()

		return filesets.iterator();
	
protected abstract org.hibernate.bytecode.util.ClassDescriptorgetClassDescriptor(byte[] byecode)

protected abstract org.hibernate.bytecode.ClassTransformergetClassTransformer(org.hibernate.bytecode.util.ClassDescriptor descriptor)

protected booleanisBeingIntrumented(java.lang.String className)

		logger.verbose( "checking to see if class [" + className + "] is set to be instrumented" );
		return classNames.contains( className );
	
protected final booleanisClassFile(java.io.File file)

        return checkMagic( file, CLASS_MAGIC );
    
public booleanisExtended()

		return extended;
	
protected final booleanisJarFile(java.io.File file)

        return checkMagic(file, ZIP_MAGIC);
    
public booleanisVerbose()

		return verbose;
	
protected voidprocessClassFile(java.io.File file)

		logger.verbose( "Starting class file : " + file.toURL() );
		byte[] bytes = ByteCodeHelper.readByteCode( file );
		ClassDescriptor descriptor = getClassDescriptor( bytes );
		ClassTransformer transformer = getClassTransformer( descriptor );
		if ( transformer == null ) {
			logger.verbose( "skipping file : " + file.toURL() );
			return;
		}

		logger.info( "processing class [" + descriptor.getName() + "]; file = " + file.toURL() );
		byte[] transformedBytes = transformer.transform(
				getClass().getClassLoader(),
				descriptor.getName(),
				null,
				null,
				descriptor.getBytes()
		);

		OutputStream out = new FileOutputStream( file );
		try {
			out.write( transformedBytes );
			out.flush();
		}
		finally {
			try {
				out.close();
			}
			catch ( IOException ignore) {
				// intentionally empty
			}
		}
	
protected voidprocessFile(java.io.File file)

	    if ( isClassFile( file ) ) {
	        processClassFile(file);
	    }
	    else if ( isJarFile( file ) ) {
	        processJarFile(file);
	    }
	    else {
		    logger.verbose( "ignoring " + file.toURL() );

	    }
	
protected voidprocessJarFile(java.io.File file)

		logger.verbose( "starting jar file : " + file.toURL() );

        File tempFile = File.createTempFile(
		        file.getName(),
		        null,
		        new File( file.getAbsoluteFile().getParent() )
        );

        try {
			FileOutputStream fout = new FileOutputStream( tempFile, false );
			try {
				final ZipOutputStream out = new ZipOutputStream( fout );
				ZipEntryHandler transformer = new ZipEntryHandler() {
					public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
								logger.verbose( "starting entry : " + entry.toString() );
								if ( !entry.isDirectory() ) {
									// see if the entry represents a class file
									DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
									if ( din.readInt() == CLASS_MAGIC ) {
										ClassDescriptor descriptor = getClassDescriptor( byteCode );
										ClassTransformer transformer = getClassTransformer( descriptor );
										if ( transformer == null ) {
											logger.verbose( "skipping entry : " + entry.toString() );
										}
										else {
											logger.info( "processing class [" + descriptor.getName() + "]; entry = " + file.toURL() );
											byteCode = transformer.transform(
													getClass().getClassLoader(),
													descriptor.getName(),
													null,
													null,
													descriptor.getBytes()
											);
										}
									}
									else {
										logger.verbose( "ignoring zip entry : " + entry.toString() );
									}
								}

								ZipEntry outEntry = new ZipEntry( entry.getName() );
								outEntry.setMethod( entry.getMethod() );
								outEntry.setComment( entry.getComment() );
								outEntry.setSize( byteCode.length );

								if ( outEntry.getMethod() == ZipEntry.STORED ){
									CRC32 crc = new CRC32();
									crc.update( byteCode );
									outEntry.setCrc( crc.getValue() );
									outEntry.setCompressedSize( byteCode.length );
								}
								out.putNextEntry( outEntry );
								out.write( byteCode );
								out.closeEntry();
					}
				};
				ZipFileProcessor processor = new ZipFileProcessor( transformer );
				processor.process( file );
				out.close();
			}
			finally{
				fout.close();
			}

            if ( file.delete() ) {
	            File newFile = new File( tempFile.getAbsolutePath() );
                if( !newFile.renameTo( file ) ) {
	                throw new IOException( "can not rename " + tempFile + " to " + file );
                }
            }
            else {
	            throw new IOException("can not delete " + file);
            }
        }
        finally {
	        tempFile.delete();
        }
	
public voidsetExtended(boolean extended)

		this.extended = extended;
	
public voidsetVerbose(boolean verbose)

		this.verbose = verbose;