xref: /aosp_15_r20/external/apache-commons-bcel/src/examples/patchclass.java (revision 0c56280ab0842982c46a149f7b9eaa497e31e292)
1*0c56280aSSorin Basca /*
2*0c56280aSSorin Basca  * Licensed to the Apache Software Foundation (ASF) under one or more
3*0c56280aSSorin Basca  * contributor license agreements.  See the NOTICE file distributed with
4*0c56280aSSorin Basca  * this work for additional information regarding copyright ownership.
5*0c56280aSSorin Basca  * The ASF licenses this file to You under the Apache License, Version 2.0
6*0c56280aSSorin Basca  * (the "License"); you may not use this file except in compliance with
7*0c56280aSSorin Basca  * the License.  You may obtain a copy of the License at
8*0c56280aSSorin Basca  *
9*0c56280aSSorin Basca  *      http://www.apache.org/licenses/LICENSE-2.0
10*0c56280aSSorin Basca  *
11*0c56280aSSorin Basca  *  Unless required by applicable law or agreed to in writing, software
12*0c56280aSSorin Basca  *  distributed under the License is distributed on an "AS IS" BASIS,
13*0c56280aSSorin Basca  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*0c56280aSSorin Basca  *  See the License for the specific language governing permissions and
15*0c56280aSSorin Basca  *  limitations under the License.
16*0c56280aSSorin Basca  *
17*0c56280aSSorin Basca  */
18*0c56280aSSorin Basca 
19*0c56280aSSorin Basca import org.apache.bcel.classfile.ClassParser;
20*0c56280aSSorin Basca import org.apache.bcel.classfile.Constant;
21*0c56280aSSorin Basca import org.apache.bcel.classfile.ConstantUtf8;
22*0c56280aSSorin Basca import org.apache.bcel.classfile.JavaClass;
23*0c56280aSSorin Basca 
24*0c56280aSSorin Basca /**
25*0c56280aSSorin Basca  * Patch all Utf8 constants in the given class file <em>file</em>.class
26*0c56280aSSorin Basca  * and save the result in _<em>file</em>.class.
27*0c56280aSSorin Basca  *
28*0c56280aSSorin Basca  * Usage: patch <oldstring> <newstring> files
29*0c56280aSSorin Basca  *
30*0c56280aSSorin Basca  * @version $Id$
31*0c56280aSSorin Basca  */
32*0c56280aSSorin Basca public class patchclass {
33*0c56280aSSorin Basca 
main(String[] argv)34*0c56280aSSorin Basca     public static void main(String[] argv) throws Exception {
35*0c56280aSSorin Basca         String[] file_name = new String[argv.length];
36*0c56280aSSorin Basca         int files = 0;
37*0c56280aSSorin Basca 
38*0c56280aSSorin Basca         if (argv.length < 3) {
39*0c56280aSSorin Basca             System.err.println("Usage: patch <oldstring> <newstring> file1.class ...");
40*0c56280aSSorin Basca             System.exit(-1);
41*0c56280aSSorin Basca         }
42*0c56280aSSorin Basca 
43*0c56280aSSorin Basca         for (int i = 2; i < argv.length; i++) {
44*0c56280aSSorin Basca             file_name[files++] = argv[i];
45*0c56280aSSorin Basca         }
46*0c56280aSSorin Basca 
47*0c56280aSSorin Basca         for (int i = 0; i < files; i++) {
48*0c56280aSSorin Basca             ClassParser parser = new ClassParser(file_name[i]);
49*0c56280aSSorin Basca             JavaClass java_class = parser.parse();
50*0c56280aSSorin Basca 
51*0c56280aSSorin Basca             patchIt(argv[0], argv[1], java_class.getConstantPool().getConstantPool());
52*0c56280aSSorin Basca 
53*0c56280aSSorin Basca             // Dump the changed class to a new file
54*0c56280aSSorin Basca             java_class.dump("_" + file_name[i]);
55*0c56280aSSorin Basca             System.out.println("Results saved in: _" + file_name[i]);
56*0c56280aSSorin Basca         }
57*0c56280aSSorin Basca     }
58*0c56280aSSorin Basca 
59*0c56280aSSorin Basca     /*
60*0c56280aSSorin Basca      * Replace all occurences of string "<em>old</em>" with
61*0c56280aSSorin Basca      * "<em>replacement</em>" in all Utf8 constants
62*0c56280aSSorin Basca      */
patchIt(String old, String replacement, Constant[] constant_pool)63*0c56280aSSorin Basca     private static void patchIt(String old, String replacement, Constant[] constant_pool) {
64*0c56280aSSorin Basca         ConstantUtf8 c;
65*0c56280aSSorin Basca         String str;
66*0c56280aSSorin Basca         int index, old_index;
67*0c56280aSSorin Basca         StringBuffer buf;
68*0c56280aSSorin Basca 
69*0c56280aSSorin Basca         // Loop through constant pool
70*0c56280aSSorin Basca         for (short i = 0; i < constant_pool.length; i++) {
71*0c56280aSSorin Basca             if (constant_pool[i] instanceof ConstantUtf8) { // Utf8 string found
72*0c56280aSSorin Basca                 try {
73*0c56280aSSorin Basca                     c = (ConstantUtf8) constant_pool[i]; // Get the string
74*0c56280aSSorin Basca                     str = c.getBytes();
75*0c56280aSSorin Basca 
76*0c56280aSSorin Basca                     if ((index = str.indexOf(old)) != -1) { // `old' found in str
77*0c56280aSSorin Basca                         buf = new StringBuffer();           // target buffer
78*0c56280aSSorin Basca                         old_index = 0;                      // String start offset
79*0c56280aSSorin Basca 
80*0c56280aSSorin Basca                         // While we have something to replace
81*0c56280aSSorin Basca                         while ((index = str.indexOf(old, old_index)) != -1) {
82*0c56280aSSorin Basca                             buf.append(str.substring(old_index, index)); // append prefix
83*0c56280aSSorin Basca                             buf.append(replacement);                     // append `replacement'
84*0c56280aSSorin Basca 
85*0c56280aSSorin Basca                             old_index = index + old.length(); // Skip `old'.length chars
86*0c56280aSSorin Basca                         }
87*0c56280aSSorin Basca 
88*0c56280aSSorin Basca                         buf.append(str.substring(old_index)); // append rest of string
89*0c56280aSSorin Basca                         str = buf.toString();
90*0c56280aSSorin Basca 
91*0c56280aSSorin Basca                         // Finally push the new string back to the constant pool
92*0c56280aSSorin Basca                         c = new ConstantUtf8(str);
93*0c56280aSSorin Basca                         constant_pool[i] = c;
94*0c56280aSSorin Basca                     }
95*0c56280aSSorin Basca                 } catch (StringIndexOutOfBoundsException e) { // Should not occur
96*0c56280aSSorin Basca                     System.err.println(e);
97*0c56280aSSorin Basca                 }
98*0c56280aSSorin Basca             }
99*0c56280aSSorin Basca         }
100*0c56280aSSorin Basca     }
101*0c56280aSSorin Basca }
102