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 */ 21package proguard.obfuscate; 22 23import proguard.classfile.*; 24import proguard.classfile.util.*; 25import proguard.classfile.visitor.*; 26 27import java.io.PrintStream; 28 29 30/** 31 * This ClassVisitor prints out the renamed classes and class members with 32 * their old names and new names. 33 * 34 * @see ClassRenamer 35 * 36 * @author Eric Lafortune 37 */ 38public class MappingPrinter 39extends SimplifiedVisitor 40implements ClassVisitor, 41 MemberVisitor 42{ 43 private final PrintStream ps; 44 45 46 /** 47 * Creates a new MappingPrinter that prints to <code>System.out</code>. 48 */ 49 public MappingPrinter() 50 { 51 this(System.out); 52 } 53 54 55 /** 56 * Creates a new MappingPrinter that prints to the given stream. 57 * @param printStream the stream to which to print 58 */ 59 public MappingPrinter(PrintStream printStream) 60 { 61 this.ps = printStream; 62 } 63 64 65 // Implementations for ClassVisitor. 66 67 public void visitProgramClass(ProgramClass programClass) 68 { 69 String name = programClass.getName(); 70 String newName = ClassObfuscator.newClassName(programClass); 71 72 ps.println(ClassUtil.externalClassName(name) + 73 " -> " + 74 ClassUtil.externalClassName(newName) + 75 ":"); 76 77 // Print out the class members. 78 programClass.fieldsAccept(this); 79 programClass.methodsAccept(this); 80 } 81 82 83 public void visitLibraryClass(LibraryClass libraryClass) 84 { 85 } 86 87 88 // Implementations for MemberVisitor. 89 90 public void visitProgramField(ProgramClass programClass, ProgramField programField) 91 { 92 String newName = MemberObfuscator.newMemberName(programField); 93 if (newName != null) 94 { 95 ps.println(" " + 96 //lineNumberRange(programClass, programField) + 97 ClassUtil.externalFullFieldDescription( 98 0, 99 programField.getName(programClass), 100 programField.getDescriptor(programClass)) + 101 " -> " + 102 newName); 103 } 104 } 105 106 107 public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) 108 { 109 // Special cases: <clinit> and <init> are always kept unchanged. 110 // We can ignore them here. 111 String name = programMethod.getName(programClass); 112 if (name.equals(ClassConstants.INTERNAL_METHOD_NAME_CLINIT) || 113 name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)) 114 { 115 return; 116 } 117 118 String newName = MemberObfuscator.newMemberName(programMethod); 119 if (newName != null) 120 { 121 ps.println(" " + 122 lineNumberRange(programClass, programMethod) + 123 ClassUtil.externalFullMethodDescription( 124 programClass.getName(), 125 0, 126 programMethod.getName(programClass), 127 programMethod.getDescriptor(programClass)) + 128 " -> " + 129 newName); 130 } 131 } 132 133 134 // Small utility methods. 135 136 /** 137 * Returns the line number range of the given class member, followed by a 138 * colon, or just an empty String if no range is available. 139 */ 140 private static String lineNumberRange(ProgramClass programClass, ProgramMember programMember) 141 { 142 String range = programMember.getLineNumberRange(programClass); 143 return range != null ? 144 (range + ":") : 145 ""; 146 } 147} 148