1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.obfuscate; 22 23 import proguard.classfile.*; 24 import proguard.classfile.util.*; 25 import proguard.util.ListUtil; 26 27 28 /** 29 * This MappingKeeper applies the mappings that it receives to its class pool, 30 * so these mappings are ensured in a subsequent obfuscation step. 31 * 32 * @author Eric Lafortune 33 */ 34 public class MappingKeeper implements MappingProcessor 35 { 36 private final ClassPool classPool; 37 private final WarningPrinter warningPrinter; 38 39 // A field acting as a parameter. 40 private Clazz clazz; 41 42 43 /** 44 * Creates a new MappingKeeper. 45 * @param classPool the class pool in which class names and class 46 * member names have to be mapped. 47 * @param warningPrinter the optional warning printer to which warnings 48 * can be printed. 49 */ MappingKeeper(ClassPool classPool, WarningPrinter warningPrinter)50 public MappingKeeper(ClassPool classPool, 51 WarningPrinter warningPrinter) 52 { 53 this.classPool = classPool; 54 this.warningPrinter = warningPrinter; 55 } 56 57 58 // Implementations for MappingProcessor. 59 processClassMapping(String className, String newClassName)60 public boolean processClassMapping(String className, 61 String newClassName) 62 { 63 // Find the class. 64 String name = ClassUtil.internalClassName(className); 65 66 clazz = classPool.getClass(name); 67 if (clazz != null) 68 { 69 String newName = ClassUtil.internalClassName(newClassName); 70 71 // Print out a warning if the mapping conflicts with a name that 72 // was set before. 73 if (warningPrinter != null) 74 { 75 String currentNewName = ClassObfuscator.newClassName(clazz); 76 if (currentNewName != null && 77 !currentNewName.equals(newName)) 78 { 79 warningPrinter.print(name, 80 currentNewName, 81 "Warning: " + 82 className + 83 " is not being kept as '" + 84 ClassUtil.externalClassName(currentNewName) + 85 "', but remapped to '" + 86 newClassName + "'"); 87 } 88 } 89 90 ClassObfuscator.setNewClassName(clazz, newName); 91 92 // The class members have to be kept as well. 93 return true; 94 } 95 96 return false; 97 } 98 99 processFieldMapping(String className, String fieldType, String fieldName, String newFieldName)100 public void processFieldMapping(String className, 101 String fieldType, 102 String fieldName, 103 String newFieldName) 104 { 105 if (clazz != null) 106 { 107 // Find the field. 108 String name = fieldName; 109 String descriptor = ClassUtil.internalType(fieldType); 110 111 Field field = clazz.findField(name, descriptor); 112 if (field != null) 113 { 114 // Print out a warning if the mapping conflicts with a name that 115 // was set before. 116 if (warningPrinter != null) 117 { 118 String currentNewName = MemberObfuscator.newMemberName(field); 119 if (currentNewName != null && 120 !currentNewName.equals(newFieldName)) 121 { 122 warningPrinter.print(ClassUtil.internalClassName(className), 123 "Warning: " + 124 className + 125 ": field '" + fieldType + " " + fieldName + 126 "' is not being kept as '" + currentNewName + 127 "', but remapped to '" + newFieldName + "'"); 128 } 129 } 130 131 // Make sure the mapping name will be kept. 132 MemberObfuscator.setFixedNewMemberName(field, newFieldName); 133 } 134 } 135 } 136 137 processMethodMapping(String className, int firstLineNumber, int lastLineNumber, String methodReturnType, String methodName, String methodArguments, String newMethodName)138 public void processMethodMapping(String className, 139 int firstLineNumber, 140 int lastLineNumber, 141 String methodReturnType, 142 String methodName, 143 String methodArguments, 144 String newMethodName) 145 { 146 if (clazz != null) 147 { 148 // Find the method. 149 String descriptor = ClassUtil.internalMethodDescriptor(methodReturnType, 150 ListUtil.commaSeparatedList(methodArguments)); 151 152 Method method = clazz.findMethod(methodName, descriptor); 153 if (method != null) 154 { 155 // Print out a warning if the mapping conflicts with a name that 156 // was set before. 157 if (warningPrinter != null) 158 { 159 String currentNewName = MemberObfuscator.newMemberName(method); 160 if (currentNewName != null && 161 !currentNewName.equals(newMethodName)) 162 { 163 warningPrinter.print(ClassUtil.internalClassName(className), 164 "Warning: " + 165 className + 166 ": method '" + methodReturnType + " " + methodName + ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN + methodArguments + ClassConstants.EXTERNAL_METHOD_ARGUMENTS_CLOSE + 167 "' is not being kept as '" + currentNewName + 168 "', but remapped to '" + newMethodName + "'"); 169 } 170 } 171 172 // Make sure the mapping name will be kept. 173 MemberObfuscator.setFixedNewMemberName(method, newMethodName); 174 } 175 } 176 } 177 } 178