1 16 package net.sf.cglib.transform; 17 18 import java.io.*; 19 import java.net.MalformedURLException ; 20 import java.util.*; 21 import java.util.zip.*; 22 import java.util.zip.ZipEntry ; 23 import java.util.zip.ZipInputStream ; 24 25 import net.sf.cglib.core.*; 26 import org.apache.tools.ant.*; 27 import org.apache.tools.ant.BuildException; 28 import org.apache.tools.ant.ProjectComponent; 29 import org.objectweb.asm.*; 30 31 abstract public class AbstractTransformTask extends AbstractProcessTask { 32 private static final int ZIP_MAGIC = 0x504B0304; 33 34 private static final int CLASS_MAGIC = 0xCAFEBABE; 35 36 private boolean verbose; 37 38 public void setVerbose(boolean verbose) { 39 this.verbose = verbose; 40 } 41 42 51 abstract protected ClassTransformer getClassTransformer(String [] classInfo); 52 53 protected Attribute[] attributes() { 54 return null; 55 } 56 57 protected void processFile(File file) throws Exception { 58 59 if (isClassFile(file)) { 60 61 processClassFile(file); 62 63 } else if (isJarFile(file)) { 64 65 processJarFile(file); 66 67 } else { 68 69 log("ignoring " + file.toURL(), Project.MSG_WARN); 70 71 } 72 } 73 74 81 private void processClassFile(File file) throws Exception , 82 FileNotFoundException, IOException, MalformedURLException { 83 84 ClassReader reader = getClassReader(file); 85 String name[] = ClassNameReader.getClassInfo(reader); 86 ClassWriter w = new DebuggingClassWriter(true); 87 ClassTransformer t = getClassTransformer(name); 88 if (t != null) { 89 90 if (verbose) { 91 log("processing " + file.toURL()); 92 } 93 new TransformingClassGenerator(new ClassReaderGenerator( 94 getClassReader(file), attributes(), skipDebug()), t) 95 .generateClass(w); 96 FileOutputStream fos = new FileOutputStream(file); 97 try { 98 fos.write(w.toByteArray()); 99 } finally { 100 fos.close(); 101 } 102 103 } 104 105 } 106 107 protected boolean skipDebug() { 108 return false; 109 } 110 111 private static ClassReader getClassReader(File file) throws Exception { 112 InputStream in = new BufferedInputStream(new FileInputStream(file)); 113 try { 114 ClassReader r = new ClassReader(in); 115 return r; 116 } finally { 117 in.close(); 118 } 119 120 } 121 122 protected boolean isClassFile(File file) throws IOException { 123 124 return checkMagic(file, CLASS_MAGIC); 125 126 } 127 128 protected void processJarFile(File file) throws Exception { 129 130 if (verbose) { 131 log("processing " + file.toURL()); 132 } 133 134 File tempFile = File.createTempFile(file.getName(), null, new File(file 135 .getAbsoluteFile().getParent())); 136 try{ 137 138 ZipInputStream zip = new ZipInputStream (new FileInputStream(file)); 139 try { 140 FileOutputStream fout = new FileOutputStream(tempFile, false); 141 try{ 142 ZipOutputStream out = new ZipOutputStream(fout); 143 144 ZipEntry entry; 145 while ((entry = zip.getNextEntry()) != null) { 146 147 148 byte bytes[] = getBytes(zip); 149 150 if (!entry.isDirectory()) { 151 152 DataInputStream din = new DataInputStream( 153 new ByteArrayInputStream(bytes) 154 ); 155 156 if (din.readInt() == CLASS_MAGIC) { 157 158 bytes = process(bytes); 159 160 } else { 161 if (verbose) { 162 log("ignoring " + entry.toString()); 163 } 164 } 165 } 166 167 ZipEntry outEntry = new ZipEntry (entry.getName()); 168 outEntry.setMethod(entry.getMethod()); 169 outEntry.setComment(entry.getComment()); 170 outEntry.setSize(bytes.length); 171 172 173 if(outEntry.getMethod() == ZipEntry.STORED){ 174 CRC32 crc = new CRC32(); 175 crc.update(bytes); 176 outEntry.setCrc( crc.getValue() ); 177 outEntry.setCompressedSize(bytes.length); 178 } 179 out.putNextEntry(outEntry); 180 out.write(bytes); 181 out.closeEntry(); 182 zip.closeEntry(); 183 184 } 185 out.close(); 186 }finally{ 187 fout.close(); 188 } 189 } finally { 190 zip.close(); 191 } 192 193 194 if(file.delete()){ 195 196 File newFile = new File(tempFile.getAbsolutePath()); 197 198 if(!newFile.renameTo(file)){ 199 throw new IOException("can not rename " + tempFile + " to " + file); 200 } 201 202 }else{ 203 throw new IOException("can not delete " + file); 204 } 205 206 }finally{ 207 208 tempFile.delete(); 209 210 } 211 212 } 213 214 220 private byte[] process(byte[] bytes) throws Exception { 221 222 ClassReader reader = new ClassReader(new ByteArrayInputStream(bytes)); 223 String name[] = ClassNameReader.getClassInfo(reader); 224 ClassWriter w = new DebuggingClassWriter(true); 225 ClassTransformer t = getClassTransformer(name); 226 if (t != null) { 227 if (verbose) { 228 log("processing " + name[0]); 229 } 230 new TransformingClassGenerator(new ClassReaderGenerator( 231 new ClassReader(new ByteArrayInputStream(bytes)), 232 attributes(), skipDebug()), t).generateClass(w); 233 ByteArrayOutputStream out = new ByteArrayOutputStream(); 234 out.write(w.toByteArray()); 235 return out.toByteArray(); 236 } 237 return bytes; 238 } 239 240 245 private byte[] getBytes(ZipInputStream zip) throws IOException { 246 247 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 248 InputStream in = new BufferedInputStream(zip); 249 int b; 250 while ((b = in.read()) != -1) { 251 bout.write(b); 252 } 253 return bout.toByteArray(); 254 } 255 256 private boolean checkMagic(File file, long magic) throws IOException { 257 DataInputStream in = new DataInputStream(new FileInputStream(file)); 258 try { 259 int m = in.readInt(); 260 return magic == m; 261 } finally { 262 in.close(); 263 } 264 } 265 266 protected boolean isJarFile(File file) throws IOException { 267 return checkMagic(file, ZIP_MAGIC); 268 } 269 270 } | Popular Tags |