FileDocCategorySizeDatePackage
ByteCodeEnhancerHelper.javaAPI DocGlassfish v2 API10429Fri May 04 22:34:26 BST 2007com.sun.jdo.api.persistence.enhancer

ByteCodeEnhancerHelper

public class ByteCodeEnhancerHelper extends Object
This is a helper-class to perform some useful operations outside a byte code enhancer and delegate the real work to the enhancer.

Fields Summary
Constructors Summary
Methods Summary
private static final voidcopyZipEntry(java.io.InputStream in, java.io.OutputStream out)
Copies a zip entry from one stream to another.

param
in The inout stream.
param
out The output stream.
exception
IOException If the stream access failed.


        int b;
        while ((in.available () > 0)  &&  (b = in.read ()) > -1)
        {
            out.write (b);
        }

    
public static final booleanenhanceClassFile(ByteCodeEnhancer enhancer, java.io.InputStream in, java.io.OutputStream out)
Enhances a classfile.

param
enhancer The enhancer to delegate the work to.
param
in The input stream with the Java class.
param
out The output stream to write the enhanced class to.
return
Has the input stream been enhanced?
exception
EnhancerUserException If something went wrong.
exception
EnhancerFatalError If something went wrong.
see
ByteCodeEnhancer#enhanceClassFile


        return enhancer.enhanceClassFile (in, new OutputStreamWrapper (out));

    
public static final booleanenhanceZipFile(ByteCodeEnhancer enhancer, java.util.zip.ZipInputStream zip_in, java.util.zip.ZipOutputStream zip_out)
Enhances a zip file. The zip file is given as a uip input stream. It's entries are read and - if necessary - individually enhanced. The output stream has the same compression (if any) as the input stream.

param
enhancer The enhancer.
param
zip_in The zip input stream.
param
zip_out The zip output stream.
param
true if at least one entry of the zip file has been enhanced, false otherwise.
exception
EnhancerUserException If something went wrong.
exception
EnhancerFatalError If something went wrong.
see
ByteCodeEnhancer#enhanceClassFile


        boolean enhanced = false;
        try
        {
            CRC32 crc32 = new CRC32 ();
            ZipEntry entry;
            while ((entry = zip_in.getNextEntry ()) != null)
            {
                InputStream in = zip_in;
                ZipEntry    out_entry = new ZipEntry (entry);

                //try to enhance
                if  (isClassFileEntry (entry))  //enhance the classfile
                {
                    //we have to copy the classfile, because if it won't be enhanced,
                    //the OutputStream is empty and we have to re-read the InputStream,
                    //which is impossiblewith a ZipInputStream (no mark/reset)
                    in = openZipEntry (zip_in);
                    in.mark (Integer.MAX_VALUE);
                    ByteArrayOutputStream tmp = new ByteArrayOutputStream ();
                    if  (enhancer.enhanceClassFile (in, tmp))
                    {
                        enhanced = true;
                        byte [] bytes = tmp.toByteArray ();
                        tmp.close ();
                        in.close ();
                        modifyZipEntry (out_entry, bytes, crc32);
                        in = new ByteArrayInputStream (bytes);
                    }
                    else
                    {
                        //the classfile has not been enhanced
                        in.reset ();
                    }
                }

                //copy the entry
                zip_out.putNextEntry (out_entry);
                copyZipEntry (in, zip_out);
                zip_out.closeEntry ();

                if  (in != zip_in)
                {
                    in.close ();
                }
            }
        }
        catch (IOException ex)
        {
            throw new EnhancerFatalError (ex);
        }

        return enhanced;

    
private static final booleanisClassFileEntry(java.util.zip.ZipEntry entry)
Determines if a given entry represents a classfile.

return
Does the given entry represent a classfile?


        return entry.getName ().endsWith (".class");

    
private static final voidmodifyZipEntry(java.util.zip.ZipEntry entry, byte[] bytes, java.util.zip.CRC32 crc32)
Modifies the given zip entry so that it can be added to zip file. The given zip entry represents an enhanced class, so the zip entry has to get the correct size and checksum (but only it the entry won't be compressed).

param
entry The zip entry to modify.
param
bytes The uncompressed byte representation of the classfile.
param
crc32 The checksum evaluator.


        entry.setSize (bytes.length);
        if  (entry.getMethod () == 0) //no compression (ZipInputStream.STORED - not accessible)
        {
            crc32.reset ();
            crc32.update (bytes);
            entry.setCrc (crc32.getValue ());
            entry.setCompressedSize (bytes.length);
        }

    
private static final java.io.InputStreamopenZipEntry(java.util.zip.ZipInputStream in)
Opens the next zip entry of a zip input stream and copies it to a java.io.ByteArrayOutputStream. It's byte array is made available via an java.io.ByteArrayInputStream which is returned.

param
in The zip input stream.
return
The newly created input stream with the next zip entry.
exception
IOException If an I/O operation failed.


        ByteArrayOutputStream out = new ByteArrayOutputStream ();
        copyZipEntry (in, out);

        return new ByteArrayInputStream (out.toByteArray ());