/*
 * Copyright 2003,2004 The Apache Software Foundation
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.sf.cglib.transform;

import java.io.*;
import java.net.MalformedURLException;
import java.util.*;
import java.util.zip.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import net.sf.cglib.core.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ProjectComponent;
import org.objectweb.asm.*;

abstract public class AbstractTransformTask extends AbstractProcessTask {
    private static final int ZIP_MAGIC = 0x504B0304;

    private static final int CLASS_MAGIC = 0xCAFEBABE;

    private boolean verbose;

    public void setVerbose(boolean verbose) {
        this.verbose = verbose;
    }

    
returns transformation for source class
Params:
  • classInfo – class information class name := classInfo[ 0 ] super class name := classInfo[ 1 ] interfaces := classInfo[ >1 ]
/** * returns transformation for source class * * @param classInfo * class information * class name := classInfo[ 0 ] * super class name := classInfo[ 1 ] * interfaces := classInfo[ >1 ] */
abstract protected ClassTransformer getClassTransformer(String[] classInfo); protected Attribute[] attributes() { return null; } protected void processFile(File file) throws Exception { if (isClassFile(file)) { processClassFile(file); } else if (isJarFile(file)) { processJarFile(file); } else { log("ignoring " + file.toURI(), Project.MSG_WARN); } }
Params:
  • file –
Throws:
/** * @param file * @throws Exception * @throws FileNotFoundException * @throws IOException * @throws MalformedURLException */
private void processClassFile(File file) throws Exception, FileNotFoundException, IOException, MalformedURLException { ClassReader reader = getClassReader(file); String name[] = ClassNameReader.getClassInfo(reader); DebuggingClassWriter w = new DebuggingClassWriter(ClassWriter.COMPUTE_FRAMES); ClassTransformer t = getClassTransformer(name); if (t != null) { if (verbose) { log("processing " + file.toURI()); } new TransformingClassGenerator(new ClassReaderGenerator( getClassReader(file), attributes(), getFlags()), t) .generateClass(w); FileOutputStream fos = new FileOutputStream(file); try { fos.write(w.toByteArray()); } finally { fos.close(); } } } protected int getFlags() { return 0; } private static ClassReader getClassReader(File file) throws Exception { InputStream in = new BufferedInputStream(new FileInputStream(file)); try { ClassReader r = new ClassReader(in); return r; } finally { in.close(); } } protected boolean isClassFile(File file) throws IOException { return checkMagic(file, CLASS_MAGIC); } protected void processJarFile(File file) throws Exception { if (verbose) { log("processing " + file.toURI()); } File tempFile = File.createTempFile(file.getName(), null, new File(file .getAbsoluteFile().getParent())); try{ ZipInputStream zip = new ZipInputStream(new FileInputStream(file)); try { FileOutputStream fout = new FileOutputStream(tempFile); try{ ZipOutputStream out = new ZipOutputStream(fout); ZipEntry entry; while ((entry = zip.getNextEntry()) != null) { byte bytes[] = getBytes(zip); if (!entry.isDirectory()) { DataInputStream din = new DataInputStream( new ByteArrayInputStream(bytes) ); if (din.readInt() == CLASS_MAGIC) { bytes = process(bytes); } else { if (verbose) { log("ignoring " + entry.toString()); } } } ZipEntry outEntry = new ZipEntry(entry.getName()); outEntry.setMethod(entry.getMethod()); outEntry.setComment(entry.getComment()); outEntry.setSize(bytes.length); if(outEntry.getMethod() == ZipEntry.STORED){ CRC32 crc = new CRC32(); crc.update(bytes); outEntry.setCrc( crc.getValue() ); outEntry.setCompressedSize(bytes.length); } out.putNextEntry(outEntry); out.write(bytes); out.closeEntry(); zip.closeEntry(); } out.close(); }finally{ fout.close(); } } finally { zip.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(); } }
Params:
  • bytes –
Throws:
Returns:
/** * @param bytes * @return * @throws IOException * @throws Exception */
private byte[] process(byte[] bytes) throws Exception { ClassReader reader = new ClassReader(new ByteArrayInputStream(bytes)); String name[] = ClassNameReader.getClassInfo(reader); DebuggingClassWriter w = new DebuggingClassWriter(ClassWriter.COMPUTE_FRAMES); ClassTransformer t = getClassTransformer(name); if (t != null) { if (verbose) { log("processing " + name[0]); } new TransformingClassGenerator(new ClassReaderGenerator( new ClassReader(new ByteArrayInputStream(bytes)), attributes(), getFlags()), t).generateClass(w); ByteArrayOutputStream out = new ByteArrayOutputStream(); out.write(w.toByteArray()); return out.toByteArray(); } return bytes; }
Params:
  • zip –
Throws:
Returns:
/** * @param zip * @return * @throws IOException */
private byte[] getBytes(ZipInputStream zip) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); InputStream in = new BufferedInputStream(zip); int b; while ((b = in.read()) != -1) { bout.write(b); } return bout.toByteArray(); } private boolean checkMagic(File file, long magic) throws IOException { DataInputStream in = new DataInputStream(new FileInputStream(file)); try { int m = in.readInt(); return magic == m; } finally { in.close(); } } protected boolean isJarFile(File file) throws IOException { return checkMagic(file, ZIP_MAGIC); } }