KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > obfuscate > MappingReader


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 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 java.io.*;
24
25
26 /**
27  * This class can parse mapping files and invoke a processor for each of the
28  * mapping entries.
29  *
30  * @author Eric Lafortune
31  */

32 public class MappingReader
33 {
34     private File mappingFile;
35
36
37     public MappingReader(File mappingFile)
38     {
39         this.mappingFile = mappingFile;
40     }
41
42
43     /**
44      * Reads the mapping file, presenting all of the encountered mapping entries
45      * to the given processor.
46      */

47     public void pump(MappingProcessor mappingProcessor) throws IOException
48     {
49         LineNumberReader reader = new LineNumberReader(
50                                   new BufferedReader(
51                                   new FileReader(mappingFile)));
52         try
53         {
54             String JavaDoc className = null;
55
56             // Read the subsequent class mappings and class member mappings.
57
while (true)
58             {
59                 String JavaDoc line = reader.readLine();
60
61                 if (line == null)
62                 {
63                     break;
64                 }
65
66                 // The distinction between a class mapping and a class
67
// member mapping is the initial whitespace.
68
if (!line.startsWith(" "))
69                 {
70                     // Process the class mapping and remember the class's
71
// old name.
72
className = processClassMapping(line, mappingProcessor);
73                 }
74                 else if (className != null)
75                 {
76                     // Process the class member mapping, in the context of the
77
// current old class name.
78
processClassMemberMapping(className, line, mappingProcessor);
79                 }
80             }
81         }
82         catch (IOException ex)
83         {
84             throw new IOException("Can't process mapping file (" + ex.getMessage() + ")");
85         }
86         finally
87         {
88             try
89             {
90                 reader.close();
91             }
92             catch (IOException ex)
93             {
94             }
95         }
96     }
97
98
99     /**
100      * Parses the given line with a class mapping and processes the
101      * results with the given mapping processor. Returns the old class name,
102      * or null if any subsequent class member lines can be ignored.
103      */

104     private String JavaDoc processClassMapping(String JavaDoc line,
105                                        MappingProcessor mappingProcessor)
106     {
107         // See if we can parse "___ -> ___:", containing the original
108
// class name and the new class name.
109

110         line = line.trim();
111
112         int arrowIndex = line.indexOf("->");
113         if (arrowIndex < 0)
114         {
115             return null;
116         }
117
118         int colonIndex = line.indexOf(':', arrowIndex + 2);
119         if (colonIndex < 0)
120         {
121             return null;
122         }
123
124         // Extract the elements.
125
String JavaDoc className = line.substring(0, arrowIndex).trim();
126         String JavaDoc newClassName = line.substring(arrowIndex + 2, colonIndex).trim();
127
128         // Process this class name mapping.
129
boolean interested = mappingProcessor.processClassMapping(className, newClassName);
130
131         return interested ? className : null;
132     }
133
134
135     /**
136      * Parses the given line with a class member mapping and processes the
137      * results with the given mapping processor.
138      */

139     private void processClassMemberMapping(String JavaDoc className,
140                                            String JavaDoc line,
141                                            MappingProcessor mappingProcessor)
142     {
143         // See if we can parse " ___:___:___ ___ -> ___",
144
// containing the optional line numbers, the return type, the original
145
// field/method name (including arguments), and the new method name.
146

147         line = line.trim();
148
149         int colonIndex1 = line.indexOf(':');
150         int colonIndex2 = line.indexOf(':', colonIndex1 + 1);
151
152         int spaceIndex = line.indexOf(' ', colonIndex2 + 1);
153         if (spaceIndex < 0)
154         {
155             return;
156         }
157
158         int arrowIndex = line.indexOf("->", spaceIndex + 1);
159         if (arrowIndex < 1)
160         {
161             return;
162         }
163
164         int firstLineNumber = colonIndex1 < 0 ? 0 :
165             Integer.parseInt(line.substring(0, colonIndex1).trim());
166
167         int lastLineNumber = colonIndex1 < 0 ||
168                              colonIndex2 < 0 ? 0 :
169             Integer.parseInt(line.substring(colonIndex1 + 1, colonIndex2).trim());
170
171         // Extract the elements.
172
String JavaDoc type = line.substring(colonIndex2 + 1, spaceIndex).trim();
173         String JavaDoc name = line.substring(spaceIndex + 1, arrowIndex).trim();
174         String JavaDoc newName = line.substring(arrowIndex + 2).trim();
175
176         // Process this class member mapping.
177
if (type.length() > 0 && name.length() > 0)
178         {
179             if (name.charAt(name.length() - 1) != ')')
180             {
181                 mappingProcessor.processFieldMapping(className, type, name, newName);
182             }
183             else
184             {
185                 mappingProcessor.processMethodMapping(className, firstLineNumber, lastLineNumber, type, name, newName);
186             }
187         }
188     }
189 }
190
Popular Tags