1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.javaflow.utils;
18
19 import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer;
20 import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.util.jar.JarEntry;
33 import java.util.jar.JarInputStream;
34 import java.util.jar.JarOutputStream;
35
36 public final class RewritingUtils {
37
38 private final static Log log = LogFactory.getLog(RewritingUtils.class);
39
40 public interface Matcher {
41 boolean isMatching( final String name );
42 }
43
44 private final static Matcher MATCH_ALL = new Matcher() {
45 public boolean isMatching(final String pName) {
46 return true;
47 }
48 };
49
50
51
52
53 public static void rewriteClassFile(
54 final File pInput,
55 final ResourceTransformer transformer,
56 final File pOutput
57 ) throws IOException {
58
59 final byte[] original = toByteArray(pInput);
60 byte[] transformed = transformer.transform(original);
61 final FileOutputStream os = new FileOutputStream(pOutput);
62 os.write(transformed);
63 os.close();
64 }
65
66 public static boolean rewriteJar(
67 final JarInputStream pInput,
68 final ResourceTransformer transformer,
69 final JarOutputStream pOutput
70 ) throws IOException {
71 return rewriteJar(pInput, transformer, pOutput, MATCH_ALL);
72 }
73
74 public static boolean rewriteJar(
75 final JarInputStream pInput,
76 final ResourceTransformer transformer,
77 final JarOutputStream pOutput,
78 final Matcher pMatcher
79 ) throws IOException {
80
81 boolean changed = false;
82
83 while(true) {
84 final JarEntry entry = pInput.getNextJarEntry();
85
86 if (entry == null) {
87 break;
88 }
89
90 if (entry.isDirectory()) {
91 pOutput.putNextEntry(new JarEntry(entry));
92 continue;
93 }
94
95 final String name = entry.getName();
96
97 pOutput.putNextEntry(new JarEntry(name));
98
99 if (name.endsWith(".class")) {
100 if (pMatcher.isMatching(name)) {
101
102 if (log.isDebugEnabled()) {
103 log.debug("transforming " + name);
104 }
105
106 final byte[] original = toByteArray(pInput);
107
108 byte[] transformed = transformer.transform(original);
109
110 pOutput.write(transformed);
111
112 changed |= transformed.length != original.length;
113
114 continue;
115 }
116 } else if (name.endsWith(".jar")
117 || name.endsWith(".ear")
118 || name.endsWith(".zip")
119 || name.endsWith(".war")) {
120
121 changed |= rewriteJar(
122 new JarInputStream(pInput),
123 transformer,
124 new JarOutputStream(pOutput),
125 pMatcher
126 );
127
128 continue;
129 }
130
131 int length = copy(pInput,pOutput);
132
133 log.debug("copied " + name + "(" + length + ")");
134 }
135
136 pInput.close();
137 pOutput.close();
138
139 return changed;
140 }
141
142 public static byte[] toByteArray(File f) throws IOException {
143 InputStream in = new FileInputStream(f);
144 try {
145 return toByteArray(in);
146 } finally {
147 in.close();
148 }
149 }
150
151 public static byte[] toByteArray(InputStream in) throws IOException {
152 ByteArrayOutputStream baos = new ByteArrayOutputStream();
153 copy(in,baos);
154 return baos.toByteArray();
155 }
156
157
158
159
160
161
162
163 public static int copy(InputStream in, OutputStream out) throws IOException {
164 byte[] buf = new byte[8192];
165 int n;
166 int total = 0;
167 while ((n = in.read(buf)) >= 0) {
168 out.write(buf, 0, n);
169 total += n;
170 }
171 return total;
172 }
173
174
175 public static void main(final String[] args) throws FileNotFoundException, IOException {
176 ResourceTransformer transformer = new BcelClassTransformer();
177
178 for (int i=0; i<args.length; i+=2) {
179 System.out.println("rewriting " + args[i]);
180
181 RewritingUtils.rewriteJar(
182 new JarInputStream(new FileInputStream(args[i])),
183 transformer,
184 new JarOutputStream(new FileOutputStream(args[i+1]))
185 );
186 }
187
188 System.out.println("done");
189
190 }
191 }