KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > cglib > transform > AbstractTransformTask


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

16 package net.sf.cglib.transform;
17
18 import java.io.*;
19 import java.net.MalformedURLException JavaDoc;
20 import java.util.*;
21 import java.util.zip.*;
22 import java.util.zip.ZipEntry JavaDoc;
23 import java.util.zip.ZipInputStream JavaDoc;
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     /**
43      * returns transformation for source class
44      *
45      * @param classInfo
46      * class information
47      * class name := classInfo[ 0 ]
48      * super class name := classInfo[ 1 ]
49      * interfaces := classInfo[ >1 ]
50      */

51     abstract protected ClassTransformer getClassTransformer(String JavaDoc[] classInfo);
52
53     protected Attribute[] attributes() {
54         return null;
55     }
56
57     protected void processFile(File file) throws Exception JavaDoc {
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     /**
75      * @param file
76      * @throws Exception
77      * @throws FileNotFoundException
78      * @throws IOException
79      * @throws MalformedURLException
80      */

81     private void processClassFile(File file) throws Exception JavaDoc,
82             FileNotFoundException, IOException, MalformedURLException JavaDoc {
83
84         ClassReader reader = getClassReader(file);
85         String JavaDoc 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 JavaDoc {
112         InputStream JavaDoc 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 JavaDoc {
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 JavaDoc zip = new ZipInputStream JavaDoc(new FileInputStream(file));
139             try {
140                 FileOutputStream fout = new FileOutputStream(tempFile, false);
141                 try{
142                  ZipOutputStream out = new ZipOutputStream(fout);
143                                 
144                     ZipEntry JavaDoc 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 JavaDoc outEntry = new ZipEntry JavaDoc(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     /**
215      * @param bytes
216      * @return
217      * @throws IOException
218      * @throws Exception
219      */

220     private byte[] process(byte[] bytes) throws Exception JavaDoc {
221
222         ClassReader reader = new ClassReader(new ByteArrayInputStream(bytes));
223         String JavaDoc 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     /**
241      * @param zip
242      * @return
243      * @throws IOException
244      */

245     private byte[] getBytes(ZipInputStream JavaDoc zip) throws IOException {
246
247         ByteArrayOutputStream bout = new ByteArrayOutputStream();
248         InputStream JavaDoc 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