01: /*
02: * ProGuard -- shrinking, optimization, obfuscation, and preverification
03: * of Java bytecode.
04: *
05: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
06: *
07: * This program is free software; you can redistribute it and/or modify it
08: * under the terms of the GNU General Public License as published by the Free
09: * 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.io;
22:
23: import proguard.classfile.*;
24:
25: import java.io.IOException;
26:
27: /**
28: * This DataEntryReader delegates to another DataEntryReader, renaming the
29: * data entries based on the renamed classes in the given ClassPool.
30: *
31: * @author Eric Lafortune
32: */
33: public class DataEntryRenamer implements DataEntryReader {
34: private final ClassPool classPool;
35: private final DataEntryReader dataEntryReader;
36:
37: public DataEntryRenamer(ClassPool classPool,
38: DataEntryReader dataEntryReader) {
39: this .classPool = classPool;
40: this .dataEntryReader = dataEntryReader;
41: }
42:
43: // Implementations for DataEntryReader.
44:
45: public void read(DataEntry dataEntry) throws IOException {
46: // Delegate to the actual data entry reader.
47: dataEntryReader.read(renamedDataEntry(dataEntry));
48: }
49:
50: /**
51: * Create a renamed data entry, if possible.
52: */
53: private DataEntry renamedDataEntry(DataEntry dataEntry) {
54: String dataEntryName = dataEntry.getName();
55:
56: // Try to find a corresponding class name by removing increasingly
57: // long suffixes,
58: for (int suffixIndex = dataEntryName.length() - 1; suffixIndex > 0; suffixIndex--) {
59: char c = dataEntryName.charAt(suffixIndex);
60: if (!Character.isJavaIdentifierPart(c)) {
61: // Stop looking at the first package separator.
62: if (c == ClassConstants.INTERNAL_PACKAGE_SEPARATOR) {
63: break;
64: }
65:
66: // Chop off the suffix.
67: String className = dataEntryName.substring(0,
68: suffixIndex);
69:
70: // Is there a class corresponding to the data entry?
71: Clazz clazz = classPool.getClass(className);
72: if (clazz != null) {
73: // Did the class get a new name?
74: String newClassName = clazz.getName();
75: if (!className.equals(newClassName)) {
76: // Return a renamed data entry.
77: String newDataEntryName = suffixIndex > 0 ? newClassName
78: + dataEntryName.substring(suffixIndex)
79: : newClassName;
80:
81: return new RenamedDataEntry(dataEntry,
82: newDataEntryName);
83: }
84:
85: // Otherwise stop looking.
86: break;
87: }
88: }
89: }
90:
91: return dataEntry;
92: }
93: }
|