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